code wiki / _hdl_build / nx_beir_eval.nx

nx_beir_eval.nx source

↩ module page · 2118 lines · 118813 B

1// nx_beir_eval.nx -- SOVEREIGN BEIR harness: real external ground truth (BEIR/nfcorpus) scored by our own 2// integer BM25 -> mean nDCG@10 (the standard BEIR metric). The HONEST external row the maturity ladder is 3// gated on (F236): real 3633-doc corpus + 323 test queries + 12335 graded qrels, vs the published BEIR BM25 4// baseline (nfcorpus nDCG@10 ~0.32, Anserini). BM25 k1=0.9 b=0.4 (BEIR defaults). IDF=log2 (ranking-invariant 5// vs ln -> identical nDCG). Integer/fixed-point throughout (no float) = bit-reproducible. Forward index 6// (per-doc sorted term,tf). Tokenizer = lowercase [a-z0-9] runs -> PORTER STEM via nx_stem_lib (2026-08-13), NO stopwords (the stemming rung LANDED -- was the 7// named gap to the stemmed 0.32 Anserini baseline). 8// 9// R0d be_bright (2026-09-14): `--set <root>` scores ANY BEIR-shaped set root (<root>/corpus.tsv, queries.tsv, 10// qrels/test.tsv and, when present, excluded.tsv: BRIGHT lists each query's own source documents there and the benchmark 11// removes them from that query's ranking, so this harness marks them unrankable for that query and counts them). Every 12// capacity is now DERIVED from the files (sys_read_file sizes the buffer, newline counts size the tables, the longest line 13// sizes the token scratch): the old 64 MiB file cap and 4096-document cap would have dropped 99 percent of BRIGHT's 14// leetcode split in silence, which is the cap class this estate refuses. `--bm25-only` skips the rerank arms (their models 15// were trained on the web corpus; BRIGHT's published floor is plain BM25, 14.5 average nDCG at 10 on the leaderboard page 16// read 2026-09-14, search.refs bright). `--bright <root>` is be_bright: this binary runs itself once per split through 17// tr_run_capture_to (one hour each, the largest split bounds it), prints one JSON row per split, the average over twelve of 18// twelve (never over a partial set), and writes the estate's row into search.leaderboard beside the published rows with 19// its rank DERIVED from their scores. The positional grammar is unchanged: [model.safetensors config.json vocab.txt 20// [max_len [depth [workers]]]] after the flags; workers is the cross-encoder pool width (0 = serial). 21// expect_exit: 0 license_tier: ORIGINAL 22import "nx_qabench_engine.nx" 23import "nx_ppmi_lib.nx" 24import "nx_stem.nx" 25import "nx_ltr_lib.nx" // R0 learned rerank arm: coordinate-ascent LTR (Metzler-Croft), 5-fold CV over the stored candidates 26import "nx_dr_densejudge.nx" // R0 trained-dense representation (embed_v1.bin via dj_maxsim*) -- the lever DR-13 named after learned fusion over PPMI was measured a dead end 27import "nx_wordpiece_lib.nx" // R0 cross-encoder arm: WordPiece over the model's own vocab 28import "nx_bert_ce_lib.nx" // R0 cross-encoder arm: the sovereign BERT encoder over a licensed data asset 29import "nx_thread_pool.nx" 30import "nx_tool_run.nx" // be_bright: this binary runs itself once per split and captures the JSON 31import "nx_timefmt.nx" // the leaderboard row's date (civil_from_days, Hinnant) 32import "nx_intlog.nx" // S5 BM25Q (2026-09-15): idf_bm25q, THE ONE query-side saturation -- composed here, never a second copy 33import "nx_beir_arms_lib.nx" // R0f (2026-09-16): THE ONE CHOOSER of the arm the BRIGHT sweep writes to the leaderboard 34const BE_ASCII_ZERO: i64 = 48 35const BE_ASCII_NINE: i64 = 57 36const BE_DECIMAL: i64 = 10 37const BE_MAGIC_1024: i64 = 1024 38const BE_MAGIC_1000000: i64 = 1000000 39// seq1494 RERANK ARM: BM25 retrieves a shortlist, the PPMI late-interaction model re-orders it, and BOTH 40// nDCG@10 values are printed FROM THE SAME RUN so the delta cannot be confounded by corpus/qrel/tokeniser 41// drift. The BM25 arm is untouched: top[0..9] keeps its exact BM25 order, we merely widen the candidate 42// selection past 10 so the reranker has something to re-order. 43// derived: 50 candidates is the standard first-stage depth for late-interaction reranking -- deep enough 44// that recall@50 >> recall@10 (so the reranker CAN win) and shallow enough to stay O(50) maxsim per query. 45const BE_KCAND: i64 = 50 46// sized: query/doc PPMI id buffers; nfcorpus docs are abstracts, far under this 47const BE_IDCAP: i64 = 4096 48const K_MAGIC_1024: i64 = 1024 49const K_MAGIC_4096: i64 = 4096 50const K_MAGIC_1900: i64 = 1900 51// ---- R0d: set roots, flags, derived capacities, the twelve splits, the leaderboard row ---- 52const BE_FLAG_SET: *u8 = "--set" 53const BE_FLAG_BRIGHT: *u8 = "--bright" 54const BE_CE_POOL_WORKERS_DEFAULT: i64 = 0 // 0 = every forward on the calling thread; the 6th positional sets the pool width, and since 2026-09-15 the pool's unit of work is ONE WHOLE PAIR (a forward), never a band of one matmul: the forward inside a task is the serial path, so a pooled run scores every pair identically to a serial run and only the wall clock moves (per-matmul banding was measured as NO speedup, search.plan row 1789456036) 55const BE_CE_TASK_BYTES: i64 = 96 // BeCeTask: 12 i64 fields; one task record and one scratch set PER CANDIDATE so no two tasks ever share a buffer 56// the progress stamp is DERIVED from the run's own queries path (2026-09-15): two concurrent runs (a BRIGHT sweep and an 57// nfcorpus arm) wrote one constant path over each other, and a constant stamp path is the forgeable-heartbeat class this 58// estate already named -- every run stamps a path only its own arguments can produce 59const BE_PROGRESS_DIR: *u8 = "knowledge/status/beir_eval." 60const BE_PROGRESS_SFX: *u8 = ".progress" 61const BE_PROGRESS_SFX_TMP: *u8 = ".progress.tmp" 62const BE_SLASH: i64 = 47 63const BE_DOT: i64 = 46 64const BE_USCORE: i64 = 95 65const BE_PROGRESS_BYTES: i64 = 640 66const BE_FLAG_BM25ONLY: *u8 = "--bm25-only" 67// R0h (2026-09-16): an ALTERNATE query file inside each set root (the dataset's published reasoning-query sets). A run on an 68// alternate query set is a REFEREE REPLAY: its receipt names the file and the sweep never writes the estate's leaderboard row 69// from it, because a query another model wrote is not the estate's system. 70const BE_FLAG_QUERIES: *u8 = "--queries" 71const BE_ROOT_DEFAULT: *u8 = "knowledge/beir/nfcorpus" 72const BE_ROOT_DEFAULT_TMP: *u8 = "/tmp/beir/nfcorpus" 73const BE_DATASET_DEFAULT: *u8 = "BEIR/nfcorpus" 74const BE_F_CORPUS: *u8 = "/corpus.tsv" 75const BE_F_QRELS: *u8 = "/qrels/test.tsv" 76const BE_F_QUERIES: *u8 = "/queries.tsv" 77const BE_F_EXCLUDED: *u8 = "/excluded.tsv" 78const BE_SEP: *u8 = "/" 79const BE_PATH_CAP: i64 = 1024 80const BE_POS_CAP: i64 = 16 81const BE_NL: i64 = 10 82const BE_TAB: i64 = 9 83const BE_PIPE: i64 = 124 84const BE_DOT: i64 = 46 85const BE_MINUS: i64 = 45 86const BE_I64: i64 = 8 87const BE_G_SLOTS: i64 = 8 88const BE_TOK_BYTES: i64 = 2 // a token needs one byte and a separator, so tokens <= bytes / 2 + lines 89const BE_PERMIL_DIGITS: i64 = 10 // the board writes nDCG x 100 with one decimal; permil / 10 . permil % 10 90const BE_BRIGHT_N: i64 = 12 91const BE_PT_TF_MOD: i64 = 1048576 // posting word radix (2^20): doc * radix + tf; a tf at or past it is clamped and COUNTED, never silently wrapped 92const BE_BRIGHT_BM25_PUBLISHED_PERMIL: i64 = 145 // the leaderboard page's plain BM25 row, read 2026-09-14 (search.refs bright) 93// S5: the per-split receipt keys the sweep reads back (each is the FIRST occurrence in that split's JSON; the two 94// ndcg keys are prefixed by the field that precedes them so the plain arm's key is never mistaken for them) 95const BE_JSON_BQ_KEY: *u8 = "k_q10\":1228,\"ndcg_at_10_permil\":" 96const BE_JSON_FQ_KEY: *u8 = "bm25q-rank, same 50 candidates\",\"ndcg_at_10_permil\":" 97const BE_JSON_LONGN_KEY: *u8 = "\"long_n\":" 98const BE_JSON_LONGD_KEY: *u8 = "\"long_bm25_permil\":" 99const BE_JSON_LONGQ_KEY: *u8 = "\"long_bm25q_permil\":" 100const BE_JSON_LONGF_KEY: *u8 = "\"long_fusion_permil\":" 101const BE_JSON_NOREP_KEY: *u8 = "\"norepeat_n\":" 102const BE_JSON_NOREPSAME_KEY: *u8 = "\"norepeat_top10_identical\":" 103const BE_JSON_REP_KEY: *u8 = "\"queries_with_repeated_term\":" 104// R0f: the reranker keys the sweep reads back (each spelled once in a split receipt) 105const BE_JSON_CEM_KEY: *u8 = "\"ce_measured\":" 106const BE_JSON_CE_KEY: *u8 = "\"ce_ndcg_at_10_permil\":" 107const BE_JSON_CEF_KEY: *u8 = "\"cefusion_ndcg_at_10_permil\":" 108const BE_JSON_PRF_KEY: *u8 = "\"prf_ndcg_at_10_permil\":" 109// R0g PRF ARM (2026-09-16): RM3-style pseudo-relevance feedback. The three parameters are Anserini's RM3 defaults 110// (fbDocs 10, fbTerms 10, originalQueryWeight 0.5), named here so the receipt can print them; the top cut is the nDCG cutoff. 111const BE_PRF_FB_DOCS: i64 = 10 112const BE_PRF_FB_TERMS: i64 = 10 113const BE_PRF_ORIG_PERMIL: i64 = 500 114const BE_PRF_TOP: i64 = 10 115const BE_JSON_CAP: i64 = 65536 // a per-split JSON receipt is a few KB; a capture that fills this is REFUSED, never averaged 116const BE_SPLIT_TIMEOUT_MS: i64 = 3600000 // one hour per split: leetcode (413932 documents) bounds it 117const BE_LB_A: *u8 = "buildroot/knowledge/compare/search.leaderboard" 118const BE_LB_B: *u8 = "knowledge/compare/search.leaderboard" 119const BE_LB_TMP: *u8 = ".tmp" 120const BE_LB_ROW: *u8 = "lb|bright|" 121const BE_LB_SYSTEM: *u8 = "nishi-search" 122// S5: the row names the arm it scores. The fused arm is written only when its own pre-declared rule held in the SAME 123// sweep (fusion beat plain on the long subset, no-repeat queries identical) and its twelve-split average is at least 124// the plain arm's -- the measuring organ chooses from its own receipt, never a hand. 125const BE_LB_URL: *u8 = "https://nishifamily.com/compare/search" 126const BE_LB_F_SYSTEM: i64 = 3 127const BE_LB_F_SCORE: i64 = 5 128const BE_LB_SLACK: i64 = 512 129const BE_JSON_NDCG_KEY: *u8 = "\"ndcg_at_10_permil\":" 130const BE_JSON_NQ_KEY: *u8 = "\"test_queries_scored\":" 131const BE_JSON_DOCS_KEY: *u8 = "\"docs\":" 132const BE_SECS_PER_DAY: i64 = 86400 133const BE_CLOCK_WORDS: i64 = 2 134const BE_DATE_LEN: i64 = 10 135const BE_SPLIT_0: *u8 = "biology" 136const BE_SPLIT_1: *u8 = "earth_science" 137const BE_SPLIT_2: *u8 = "economics" 138const BE_SPLIT_3: *u8 = "psychology" 139const BE_SPLIT_4: *u8 = "robotics" 140const BE_SPLIT_5: *u8 = "stackoverflow" 141const BE_SPLIT_6: *u8 = "sustainable_living" 142const BE_SPLIT_7: *u8 = "leetcode" 143const BE_SPLIT_8: *u8 = "pony" 144const BE_SPLIT_9: *u8 = "aops" 145const BE_SPLIT_10: *u8 = "theoremqa_questions" 146const BE_SPLIT_11: *u8 = "theoremqa_theorems" 147 148// read a whole file, sized from the file itself (sys_read_file cannot short-read); returns bytes or -1 when absent 149func be_read(path: *u8, slot: *i64) -> i64 { 150 let lenp: *i64 = sys_mmap(BE_I64) as *i64 151 lenp[0] = 0 152 let buf: *u8 = sys_read_file(path, lenp) 153 if (buf as i64) == 0 { return 0 - 1 } 154 if lenp[0] <= 0 { return 0 - 1 } 155 slot[0] = buf as i64 156 return lenp[0] 157} 158 159// read pathA, else fall back to pathB (NAS stable path first, local /tmp second) 160func be_read_fb(pa: *u8, pb: *u8, slot: *i64) -> i64 { 161 let n: i64 = be_read(pa, slot) 162 if n > 0 { return n } 163 return be_read(pb, slot) 164} 165 166func be_slen(s: *u8) -> i64 { 167 var n: i64 = 0 168 while (s[n] & 0xff) as i64 != 0 { n = n + 1 } 169 return n 170} 171func be_streq(a: *u8, b: *u8) -> i64 { 172 var i: i64 = 0 173 var go: i64 = 1 174 while go == 1 { 175 let ca: i64 = (a[i] & 0xff) as i64 176 let cb: i64 = (b[i] & 0xff) as i64 177 if ca != cb { return 0 } 178 if ca == 0 { go = 0 } 179 i = i + 1 180 } 181 return 1 182} 183func be_count_byte(buf: *u8, n: i64, ch: i64) -> i64 { 184 var c: i64 = 0 185 var i: i64 = 0 186 while i < n { if (buf[i] & 0xff) as i64 == ch { c = c + 1 } i = i + 1 } 187 return c 188} 189// the longest line in buf (bytes between newlines) 190func be_maxline(buf: *u8, n: i64) -> i64 { 191 var best: i64 = 0 192 var cur: i64 = 0 193 var i: i64 = 0 194 while i < n { 195 if (buf[i] & 0xff) as i64 == BE_NL { if cur > best { best = cur } cur = 0 } else { cur = cur + 1 } 196 i = i + 1 197 } 198 if cur > best { best = cur } 199 return best 200} 201// dst = a + b (+ c when c is not null), NUL-terminated; returns the length or -1 when it would not fit 202// R0h: the queries path of a set root: the default queries.tsv, or root / qfile when an alternate query file is named 203func be_qpath(dst: *u8, root: *u8, qfile: *u8) -> i64 { 204 if (qfile as i64) == 0 { return be_path(dst, root, BE_F_QUERIES) } 205 return be_path3(dst, root, BE_SEP, qfile) 206} 207func be_path3(dst: *u8, a: *u8, b: *u8, c: *u8) -> i64 { 208 let la: i64 = be_slen(a) 209 let lb: i64 = be_slen(b) 210 var lc: i64 = 0 211 if (c as i64) != 0 { lc = be_slen(c) } 212 if la + lb + lc + 1 > BE_PATH_CAP { return 0 - 1 } 213 var i: i64 = 0 214 while i < la { dst[i] = a[i]; i = i + 1 } 215 var j: i64 = 0 216 while j < lb { dst[la + j] = b[j]; j = j + 1 } 217 var k: i64 = 0 218 while k < lc { dst[la + lb + k] = c[k]; k = k + 1 } 219 dst[la + lb + lc] = 0 as u8 220 return la + lb + lc 221} 222func be_path(dst: *u8, a: *u8, b: *u8) -> i64 { return be_path3(dst, a, b, 0 as *u8) } 223// the integer after the FIRST occurrence of key in buf[0..n), or -1 when the key is absent 224func be_json_int(buf: *u8, n: i64, key: *u8) -> i64 { 225 let m: i64 = be_slen(key) 226 var i: i64 = 0 227 while i + m <= n { 228 var j: i64 = 0 229 var ok: i64 = 1 230 while j < m { if (buf[i + j] & 0xff) as i64 != (key[j] & 0xff) as i64 { ok = 0; j = m } else { j = j + 1 } } 231 if ok == 1 { 232 var p: i64 = i + m 233 var neg: i64 = 0 234 if p < n { if (buf[p] & 0xff) as i64 == BE_MINUS { neg = 1; p = p + 1 } } 235 var v: i64 = 0 236 var any: i64 = 0 237 var go: i64 = 1 238 while go == 1 { 239 if p >= n { go = 0 } else { 240 let ch: i64 = (buf[p] & 0xff) as i64 241 if ch >= BE_ASCII_ZERO { if ch <= BE_ASCII_NINE { v = v * BE_DECIMAL + (ch - BE_ASCII_ZERO); any = 1; p = p + 1 } else { go = 0 } } else { go = 0 } 242 } 243 } 244 if any == 0 { return 0 - 1 } 245 if neg == 1 { return 0 - v } 246 return v 247 } 248 i = i + 1 249 } 250 return 0 - 1 251} 252func be_split_name(i: i64) -> *u8 { 253 if i == 0 { return BE_SPLIT_0 } 254 if i == 1 { return BE_SPLIT_1 } 255 if i == 2 { return BE_SPLIT_2 } 256 if i == 3 { return BE_SPLIT_3 } 257 if i == 4 { return BE_SPLIT_4 } 258 if i == 5 { return BE_SPLIT_5 } 259 if i == 6 { return BE_SPLIT_6 } 260 if i == 7 { return BE_SPLIT_7 } 261 if i == 8 { return BE_SPLIT_8 } 262 if i == 9 { return BE_SPLIT_9 } 263 if i == 10 { return BE_SPLIT_10 } 264 return BE_SPLIT_11 265} 266// two decimal digits, zero-padded, into dst at off 267func be_put2(dst: *u8, off: i64, v: i64) -> i64 { 268 dst[off] = (BE_ASCII_ZERO + (v / BE_DECIMAL) % BE_DECIMAL) as u8 269 dst[off + 1] = (BE_ASCII_ZERO + v % BE_DECIMAL) as u8 270 return off + 2 271} 272// today's civil date as YYYY-MM-DD (UTC) from the clock, NUL-terminated 273func be_today(dst: *u8) -> i64 { 274 let ts: *i64 = sys_mmap(BE_CLOCK_WORDS * BE_I64) as *i64 275 ts[0] = 0 276 sys_clock_gettime_real(ts) 277 let y: *i64 = sys_mmap(BE_I64) as *i64 278 let m: *i64 = sys_mmap(BE_I64) as *i64 279 let d: *i64 = sys_mmap(BE_I64) as *i64 280 civil_from_days(ts[0] / BE_SECS_PER_DAY, y, m, d) 281 var o: i64 = be_put2(dst, 0, y[0] / 100) 282 o = be_put2(dst, o, y[0] % 100) 283 dst[o] = BE_MINUS as u8 284 o = be_put2(dst, o + 1, m[0]) 285 dst[o] = BE_MINUS as u8 286 o = be_put2(dst, o + 1, d[0]) 287 dst[o] = 0 as u8 288 return o 289} 290// the k-th pipe field of the line buf[s..e) -> start offset (len in lenp), or -1 291func be_field(buf: *u8, s: i64, e: i64, k: i64, lenp: *i64) -> i64 { 292 var f: i64 = 0 293 var p: i64 = s 294 var st: i64 = s 295 while p <= e { 296 var atsep: i64 = 0 297 if p == e { atsep = 1 } else { if (buf[p] & 0xff) as i64 == BE_PIPE { atsep = 1 } } 298 if atsep == 1 { 299 if f == k { lenp[0] = p - st; return st } 300 f = f + 1 301 st = p + 1 302 } 303 p = p + 1 304 } 305 return 0 - 1 306} 307// a board score like 66.9 -> 669 permil (whole x 10 + first decimal); -1 when it does not parse 308func be_score_permil(buf: *u8, s: i64, n: i64) -> i64 { 309 var v: i64 = 0 310 var i: i64 = 0 311 var any: i64 = 0 312 while i < n { 313 let ch: i64 = (buf[s + i] & 0xff) as i64 314 if ch >= BE_ASCII_ZERO && ch <= BE_ASCII_NINE { v = v * BE_DECIMAL + (ch - BE_ASCII_ZERO); any = 1; i = i + 1 } else { 315 if ch == BE_DOT { i = i + 1; if i < n { let dch: i64 = (buf[s + i] & 0xff) as i64; if dch >= BE_ASCII_ZERO && dch <= BE_ASCII_NINE { return v * BE_PERMIL_DIGITS + (dch - BE_ASCII_ZERO) } } return v * BE_PERMIL_DIGITS } 316 i = n 317 } 318 } 319 if any == 0 { return 0 - 1 } 320 return v * BE_PERMIL_DIGITS 321} 322func be_starts_at(buf: *u8, s: i64, e: i64, pre: *u8) -> i64 { 323 let m: i64 = be_slen(pre) 324 if e - s < m { return 0 } 325 var i: i64 = 0 326 while i < m { if (buf[s + i] & 0xff) as i64 != (pre[i] & 0xff) as i64 { return 0 } i = i + 1 } 327 return 1 328} 329func be_field_is(buf: *u8, s: i64, e: i64, k: i64, want: *u8) -> i64 { 330 let lp: *i64 = sys_mmap(BE_I64) as *i64 331 let fs: i64 = be_field(buf, s, e, k, lp) 332 if fs < 0 { return 0 } 333 if lp[0] != be_slen(want) { return 0 } 334 return be_starts_at(buf, fs, fs + lp[0], want) 335} 336// write the estate's row into search.leaderboard: rank derived from the published rows' scores, the old 337// nishi-search row dropped, the file rewritten through .tmp + rename. Returns the rank, or a negative refusal. 338func be_lb_write(permil: i64, today: *u8, org: *u8) -> i64 { 339 let slot: *i64 = sys_mmap(BE_I64) as *i64 340 var path: *u8 = BE_LB_A 341 var n: i64 = be_read(path, slot) 342 if n < 0 { path = BE_LB_B; n = be_read(path, slot) } 343 if n < 0 { return 0 - 1 } 344 let buf: *u8 = slot[0] as *u8 345 let out: *u8 = sys_mmap(n + BE_LB_SLACK + be_slen(org) + be_slen(BE_LB_URL)) 346 var o: i64 = 0 347 var rank: i64 = 1 348 let lp: *i64 = sys_mmap(BE_I64) as *i64 349 var p: i64 = 0 350 while p < n { 351 let e: i64 = be_find(buf, p, n, BE_NL) 352 var keep: i64 = 1 353 if be_starts_at(buf, p, e, BE_LB_ROW) == 1 { 354 if be_field_is(buf, p, e, BE_LB_F_SYSTEM, BE_LB_SYSTEM) == 1 { keep = 0 } else { 355 let fs: i64 = be_field(buf, p, e, BE_LB_F_SCORE, lp) 356 if fs >= 0 { if be_score_permil(buf, fs, lp[0]) > permil { rank = rank + 1 } } 357 } 358 } 359 if keep == 1 { 360 var i: i64 = p 361 while i < e { out[o] = buf[i]; o = o + 1; i = i + 1 } 362 if e < n { out[o] = BE_NL as u8; o = o + 1 } 363 } 364 p = e + 1 365 } 366 if o > 0 { if (out[o - 1] & 0xff) as i64 != BE_NL { out[o] = BE_NL as u8; o = o + 1 } } 367 // lb|bright|<rank>|nishi-search|<org>|<score>|<date>|<url> 368 var i2: i64 = 0 369 let row: *u8 = BE_LB_ROW 370 while i2 < be_slen(row) { out[o] = row[i2]; o = o + 1; i2 = i2 + 1 } 371 let numb: *u8 = sys_mmap(BE_DATE_LEN + BE_DATE_LEN) 372 var nn: i64 = 0 373 var rv: i64 = rank 374 if rv == 0 { numb[0] = BE_ASCII_ZERO as u8; nn = 1 } 375 while rv > 0 { numb[nn] = (BE_ASCII_ZERO + rv % BE_DECIMAL) as u8; rv = rv / BE_DECIMAL; nn = nn + 1 } 376 while nn > 0 { nn = nn - 1; out[o] = numb[nn]; o = o + 1 } 377 out[o] = BE_PIPE as u8 378 o = o + 1 379 var i3: i64 = 0 380 while i3 < be_slen(BE_LB_SYSTEM) { out[o] = BE_LB_SYSTEM[i3]; o = o + 1; i3 = i3 + 1 } 381 out[o] = BE_PIPE as u8 382 o = o + 1 383 var i4: i64 = 0 384 while i4 < be_slen(org) { out[o] = org[i4]; o = o + 1; i4 = i4 + 1 } 385 out[o] = BE_PIPE as u8 386 o = o + 1 387 // the score: permil -> whole.decimal 388 let whole: i64 = permil / BE_PERMIL_DIGITS 389 nn = 0 390 rv = whole 391 if rv == 0 { numb[0] = BE_ASCII_ZERO as u8; nn = 1 } 392 while rv > 0 { numb[nn] = (BE_ASCII_ZERO + rv % BE_DECIMAL) as u8; rv = rv / BE_DECIMAL; nn = nn + 1 } 393 while nn > 0 { nn = nn - 1; out[o] = numb[nn]; o = o + 1 } 394 out[o] = BE_DOT as u8 395 o = o + 1 396 out[o] = (BE_ASCII_ZERO + permil % BE_PERMIL_DIGITS) as u8 397 o = o + 1 398 out[o] = BE_PIPE as u8 399 o = o + 1 400 var i5: i64 = 0 401 while i5 < be_slen(today) { out[o] = today[i5]; o = o + 1; i5 = i5 + 1 } 402 out[o] = BE_PIPE as u8 403 o = o + 1 404 var i6: i64 = 0 405 while i6 < be_slen(BE_LB_URL) { out[o] = BE_LB_URL[i6]; o = o + 1; i6 = i6 + 1 } 406 out[o] = BE_NL as u8 407 o = o + 1 408 let tmp: *u8 = sys_mmap(BE_PATH_CAP) 409 if be_path(tmp, path, BE_LB_TMP) < 0 { return 0 - 2 } 410 let fd: i64 = sys_openat_wr(tmp, MODE_0644) 411 if fd < 0 { return 0 - 3 } 412 var off: i64 = 0 413 while off < o { 414 let w: i64 = sys_write(fd, ((out as i64) + off) as *u8, o - off) 415 if w <= 0 { sys_close(fd); return 0 - 4 } 416 off = off + w 417 } 418 sys_close(fd) 419 if sys_renameat(tmp, path) != 0 { return 0 - 5 } 420 return rank 421} 422// R0e (2026-09-16): the per-split deadline. The bm25 hour bounds the plain arm (leetcode, 413,932 documents); a rerank sweep 423// adds the split's PAIRS (queries x depth) times the slowest MEASURED full-length forward over the pool width, so a slow 424// box is never killed mid-split while a hung child still is -- a hang guard, never a speed bar. queries are counted from the 425// split's own queries.tsv; a split whose queries cannot be read keeps the bm25 hour and the child reports the miss itself. 426const BE_CE_PAIR_CEILING_MS: i64 = 134000 // T11 nx_bert_ce_gate 2026-09-15: one 512-position pair, SERIAL, on the loaded NAS = 133,787,252 us 427func be_split_deadline_ms(setp: *u8, bm25_only: i64, pos: *i64, npos: i64, qfile: *u8) -> i64 { 428 if bm25_only == 1 { return BE_SPLIT_TIMEOUT_MS } 429 var depth: i64 = BE_KCAND 430 if npos >= 5 { depth = be_atoi(pos[4] as *u8) } 431 if depth > BE_KCAND { depth = BE_KCAND } 432 var workers: i64 = BE_CE_POOL_WORKERS_DEFAULT 433 if npos >= 6 { workers = be_atoi(pos[5] as *u8) } 434 if workers < 1 { workers = 1 } 435 let pq: *u8 = sys_mmap(BE_PATH_CAP) 436 be_qpath(pq, setp, qfile) 437 let sz: *i64 = sys_mmap(BE_I64) as *i64 438 let buf: *u8 = sys_read_file(pq, sz) 439 var nq: i64 = 0 440 if (buf as i64) != 0 { if sz[0] > 0 { nq = be_count_byte(buf, sz[0], BE_NL) } } 441 return BE_SPLIT_TIMEOUT_MS + nq * depth * BE_CE_PAIR_CEILING_MS / workers 442} 443// be_bright: this binary once per split, the twelve receipts, the average over twelve of twelve, the board row 444func be_bright(root: *u8, self: *u8, bm25_only: i64, pos: *i64, npos: i64, qfile: *u8) -> i64 { 445 let out: *u8 = sys_mmap(BE_JSON_CAP) 446 let outlen: *i64 = sys_mmap(BE_I64) as *i64 447 let av: *i64 = sys_mmap((BE_G_SLOTS + BE_POS_CAP) * BE_I64) as *i64 // R0e: the flag slots plus every forwarded positional 448 let setp: *u8 = sys_mmap(BE_PATH_CAP) 449 let corp: *u8 = sys_mmap(BE_PATH_CAP) 450 let today: *u8 = sys_mmap(BE_DATE_LEN + BE_DATE_LEN) 451 be_today(today) 452 var scored: i64 = 0 453 var missing: i64 = 0 454 var refused: i64 = 0 455 var sum: i64 = 0 456 var qsum: i64 = 0 457 var dsum: i64 = 0 458 // S5 BM25Q across the sweep (2026-09-15): every split's own bm25q block is read back from its captured receipt and the 459 // long-query subset is aggregated WEIGHTED by each split's long_n, so the sweep-level verdict is the same rule the 460 // per-set receipt declares, over the twelve reasoning-query sets the rung was written for 461 var bq_sum: i64 = 0 462 var fq_sum: i64 = 0 463 var ce_n: i64 = 0 // R0f: splits whose receipt measured the reranker 464 var ce_sum: i64 = 0 465 var cef_sum: i64 = 0 466 var prf_n: i64 = 0 // R0g: splits whose receipt carried the PRF arm 467 var prf_sum: i64 = 0 468 var lq_n: i64 = 0 469 var lq_d: i64 = 0 470 var lq_q: i64 = 0 471 var lq_f: i64 = 0 472 var nr_n: i64 = 0 473 var nr_s: i64 = 0 474 var rep_sum: i64 = 0 475 db_w("{\"tool\":\"nx_beir_eval\",\"mode\":\"be_bright\",\"root\":\"" as *u8); db_w(root) 476 db_w("\",\"self\":\"" as *u8); db_w(self) 477 db_w("\",\"bm25_only\":" as *u8); db_n(bm25_only) 478 db_w(",\"forwarded_positionals\":" as *u8); db_n(npos) 479 db_w(",\"queries_file\":\"" as *u8); if (qfile as i64) == 0 { db_w("queries.tsv" as *u8) } else { db_w(qfile) } db_w("\"" as *u8) 480 db_w(",\"date\":\"" as *u8); db_w(today) 481 db_w("\",\"splits\":[" as *u8) 482 var i: i64 = 0 483 while i < BE_BRIGHT_N { 484 let name: *u8 = be_split_name(i) 485 be_path3(setp, root, BE_SEP, name) 486 be_path(corp, setp, BE_F_CORPUS) 487 if i > 0 { db_w("," as *u8) } 488 db_w("{\"split\":\"" as *u8); db_w(name); db_w("\"" as *u8) 489 let fd: i64 = sys_openat_rd(corp) 490 if fd < 0 { missing = missing + 1; db_w(",\"state\":\"MISSING (no corpus.tsv under the split; run nx_bright_prep)\"}" as *u8) } else { 491 sys_close(fd) 492 av[0] = self as i64 493 av[1] = BE_FLAG_SET as i64 494 av[2] = setp as i64 495 var an: i64 = 3 496 if bm25_only == 1 { av[an] = BE_FLAG_BM25ONLY as i64; an = an + 1 } 497 if (qfile as i64) != 0 { av[an] = BE_FLAG_QUERIES as i64; an = an + 1; av[an] = qfile as i64; an = an + 1 } 498 // R0e (2026-09-16): every positional the caller gave (model, config, vocab, max_len, depth, workers) is forwarded 499 // to the split child. The sweep used to launch each split BARE, so a cross-encoder sweep ran every split at the 500 // defaults -- SERIAL, whatever pool width the caller asked for -- and nothing in its receipt said so. 501 var ap: i64 = 0 502 while ap < npos { av[an] = pos[ap]; an = an + 1; ap = ap + 1 } 503 av[an] = 0 504 outlen[0] = 0 505 let rc: i64 = tr_run_capture_to(self, av, out, BE_JSON_CAP, outlen, be_split_deadline_ms(setp, bm25_only, pos, npos, qfile)) 506 let n: i64 = outlen[0] 507 db_w(",\"rc\":" as *u8); db_n(rc) 508 db_w(",\"capture_bytes\":" as *u8); db_n(n) 509 if n >= BE_JSON_CAP { refused = refused + 1; db_w(",\"state\":\"REFUSED (the capture filled BE_JSON_CAP; nothing averaged from a truncated receipt)\"}" as *u8) } else { 510 let nd: i64 = be_json_int(out, n, BE_JSON_NDCG_KEY) 511 let nq: i64 = be_json_int(out, n, BE_JSON_NQ_KEY) 512 let docs: i64 = be_json_int(out, n, BE_JSON_DOCS_KEY) 513 db_w(",\"docs\":" as *u8); db_n(docs) 514 db_w(",\"queries\":" as *u8); db_n(nq) 515 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(nd) 516 let bq: i64 = be_json_int(out, n, BE_JSON_BQ_KEY) 517 let fq: i64 = be_json_int(out, n, BE_JSON_FQ_KEY) 518 let ln: i64 = be_json_int(out, n, BE_JSON_LONGN_KEY) 519 let ld: i64 = be_json_int(out, n, BE_JSON_LONGD_KEY) 520 let lq: i64 = be_json_int(out, n, BE_JSON_LONGQ_KEY) 521 let lf: i64 = be_json_int(out, n, BE_JSON_LONGF_KEY) 522 let nrn: i64 = be_json_int(out, n, BE_JSON_NOREP_KEY) 523 let nrs: i64 = be_json_int(out, n, BE_JSON_NOREPSAME_KEY) 524 let rpn: i64 = be_json_int(out, n, BE_JSON_REP_KEY) 525 let cem: i64 = be_json_int(out, n, BE_JSON_CEM_KEY) 526 let cen: i64 = be_json_int(out, n, BE_JSON_CE_KEY) 527 let cefv: i64 = be_json_int(out, n, BE_JSON_CEF_KEY) 528 let prfv: i64 = be_json_int(out, n, BE_JSON_PRF_KEY) 529 if rc == 0 && nd >= 0 && nq > 0 { if prfv >= 0 { prf_n = prf_n + 1; prf_sum = prf_sum + prfv } } 530 if rc == 0 && nd >= 0 && nq > 0 { if cem == 1 { ce_n = ce_n + 1; ce_sum = ce_sum + cen; cef_sum = cef_sum + cefv } } 531 db_w(",\"bm25q_permil\":" as *u8); db_n(bq) 532 db_w(",\"bm25q_fusion_permil\":" as *u8); db_n(fq) 533 db_w(",\"prf_permil\":" as *u8); db_n(prfv) 534 db_w(",\"crossenc_permil\":" as *u8); db_n(cen) 535 db_w(",\"cefusion_permil\":" as *u8); db_n(cefv) 536 db_w(",\"long_n\":" as *u8); db_n(ln) 537 db_w(",\"long_bm25_permil\":" as *u8); db_n(ld) 538 db_w(",\"long_bm25q_permil\":" as *u8); db_n(lq) 539 db_w(",\"long_fusion_permil\":" as *u8); db_n(lf) 540 db_w(",\"norepeat_n\":" as *u8); db_n(nrn) 541 db_w(",\"norepeat_identical\":" as *u8); db_n(nrs) 542 db_w(",\"queries_with_repeated_term\":" as *u8); db_n(rpn) 543 if rc == 0 && nd >= 0 && nq > 0 { if ln > 0 { lq_n = lq_n + ln; lq_d = lq_d + ld * ln; lq_q = lq_q + lq * ln; lq_f = lq_f + lf * ln } if bq >= 0 { bq_sum = bq_sum + bq } if fq >= 0 { fq_sum = fq_sum + fq } if nrn > 0 { nr_n = nr_n + nrn; nr_s = nr_s + nrs } if rpn > 0 { rep_sum = rep_sum + rpn } } 544 if rc == 0 && nd >= 0 && nq > 0 { scored = scored + 1; sum = sum + nd; qsum = qsum + nq; dsum = dsum + docs; db_w(",\"state\":\"SCORED\"}" as *u8) } else { refused = refused + 1; db_w(",\"state\":\"REFUSED (non-zero exit or no score in the receipt)\"}" as *u8) } 545 } 546 } 547 i = i + 1 548 } 549 db_w("],\"splits_declared\":" as *u8); db_n(BE_BRIGHT_N) 550 db_w(",\"scored\":" as *u8); db_n(scored) 551 db_w(",\"missing\":" as *u8); db_n(missing) 552 db_w(",\"refused\":" as *u8); db_n(refused) 553 db_w(",\"queries_total\":" as *u8); db_n(qsum) 554 db_w(",\"docs_total\":" as *u8); db_n(dsum) 555 var avg: i64 = 0 - 1 556 if scored == BE_BRIGHT_N { avg = sum / BE_BRIGHT_N } 557 db_w(",\"average_ndcg_at_10_permil\":" as *u8); db_n(avg) 558 db_w(",\"published_bm25_average_permil\":" as *u8); db_n(BE_BRIGHT_BM25_PUBLISHED_PERMIL) 559 var bq_avg: i64 = 0 - 1 560 var fq_avg: i64 = 0 - 1 561 if scored == BE_BRIGHT_N { bq_avg = bq_sum / BE_BRIGHT_N; fq_avg = fq_sum / BE_BRIGHT_N } 562 var ce_avg: i64 = 0 - 1 563 var cef_avg: i64 = 0 - 1 564 if ce_n == BE_BRIGHT_N { ce_avg = ce_sum / BE_BRIGHT_N; cef_avg = cef_sum / BE_BRIGHT_N } 565 var prf_avg: i64 = 0 - 1 566 if prf_n == BE_BRIGHT_N { prf_avg = prf_sum / BE_BRIGHT_N } 567 var lqd: i64 = 0 568 var lqq: i64 = 0 569 var lqf: i64 = 0 570 if lq_n > 0 { lqd = lq_d / lq_n; lqq = lq_q / lq_n; lqf = lq_f / lq_n } 571 db_w(",\"bm25q\":{\"average_ndcg_at_10_permil\":" as *u8); db_n(bq_avg) 572 db_w(",\"fusion_average_ndcg_at_10_permil\":" as *u8); db_n(fq_avg) 573 db_w(",\"crossenc_splits_measured\":" as *u8); db_n(ce_n) 574 db_w(",\"crossenc_average_ndcg_at_10_permil\":" as *u8); db_n(ce_avg) 575 db_w(",\"cefusion_average_ndcg_at_10_permil\":" as *u8); db_n(cef_avg) 576 db_w(",\"prf_splits_measured\":" as *u8); db_n(prf_n) 577 db_w(",\"prf_average_ndcg_at_10_permil\":" as *u8); db_n(prf_avg) 578 db_w(",\"long_rule\":\"per split, query tokens above that split's mean; aggregated weighted by long_n\",\"long_n_total\":" as *u8); db_n(lq_n) 579 db_w(",\"long_bm25_permil\":" as *u8); db_n(lqd) 580 db_w(",\"long_bm25q_permil\":" as *u8); db_n(lqq) 581 db_w(",\"long_fusion_permil\":" as *u8); db_n(lqf) 582 db_w(",\"queries_with_repeated_term\":" as *u8); db_n(rep_sum) 583 db_w(",\"norepeat_n\":" as *u8); db_n(nr_n) 584 db_w(",\"norepeat_identical\":" as *u8); db_n(nr_s) 585 db_w(",\"accept_rule\":\"declared 2026-09-04 (search S5): the FUSED arm must EXCEED plain BM25 on the long-query subset by nDCG at 10, and every no-repeat query must rank IDENTICALLY under both\",\"verdict\":\"" as *u8) 586 if lq_n > 0 { if lqf > lqd { if nr_s == nr_n { db_w("FUSION-BEATS-BM25-ON-LONG" as *u8) } else { db_w("IDENTITY-CONTROL-FAILED" as *u8) } } else { db_w("FUSION-DOES-NOT-BEAT-BM25-ON-LONG" as *u8) } } else { db_w("NO-LONG-QUERIES" as *u8) } 587 db_w("\"}" as *u8) 588 db_w(",\"delta_vs_published_bm25_permil\":" as *u8); if avg >= 0 { db_n(avg - BE_BRIGHT_BM25_PUBLISHED_PERMIL) } else { db_n(0 - 1) } 589 if avg >= 0 { 590 // S5: the row carries the BEST sovereign lexical arm this sweep measured, named on the row (see nx_beir_arms_lib, R0f) 591 // R0f: the arm is chosen by nx_beir_arms_lib from this sweep's own averages (plain, BM25Q fusion under its rule, the 592 // cross-encoder rerank and its RRF fusion when every split measured them and they exceed plain) 593 var fusion_ok: i64 = 0 594 if lq_n > 0 { if lqf > lqd { if nr_s == nr_n { fusion_ok = 1 } } } 595 let arm: i64 = be_lb_choose(avg, fq_avg, fusion_ok, prf_n, prf_avg, ce_n, ce_avg, cef_avg, BE_BRIGHT_N) 596 let lb_score: i64 = be_lb_arm_score(arm, avg, fq_avg, prf_avg, ce_avg, cef_avg) 597 let lb_org: *u8 = be_lb_arm_org(arm) 598 let lb_arm: *u8 = be_lb_arm_label(arm) 599 db_w(",\"leaderboard_arm\":\"" as *u8); db_w(lb_arm); db_w("\",\"leaderboard_score_permil\":" as *u8); db_n(lb_score) 600 if (qfile as i64) != 0 { 601 db_w(",\"leaderboard_row\":\"NOT-WRITTEN (a referee replay on an alternate query set; a query another model wrote is not the estate's system)\"" as *u8) 602 } else { 603 let rank: i64 = be_lb_write(lb_score, today, lb_org) 604 db_w(",\"leaderboard_row\":" as *u8) 605 if rank > 0 { db_w("\"WRITTEN rank=" as *u8); db_n(rank); db_w(" system=nishi-search\"" as *u8) } else { db_w("\"NOT-WRITTEN (leaderboard file refused, rc=" as *u8); db_n(rank); db_w(")\"" as *u8) } 606 } 607 } else { db_w(",\"leaderboard_row\":\"NOT-WRITTEN (twelve of twelve splits must score; a partial average is not a placement)\"" as *u8) } 608 db_w(",\"accept_rule\":\"declared BEFORE the run: every split scored, the partition scored+missing+refused = 12 printed, the average within its own tolerance of the published plain-BM25 average (14.5) before any arm above BM25 is claimed on this board\"}" as *u8) 609 db_w("\n" as *u8) 610 if scored == BE_BRIGHT_N { return 0 } 611 return 1 612} 613 614// index of byte ch in buf[from,limit), else limit 615func be_find(buf: *u8, from: i64, limit: i64, ch: i64) -> i64 { 616 var i: i64 = from 617 var res: i64 = limit 618 var go: i64 = 1 619 while go == 1 { 620 if i >= limit { go = 0 } else { 621 if buf[i] == (ch as u8) { res = i; go = 0 } else { i = i + 1 } 622 } 623 } 624 return res 625} 626 627// lowercase+hash [a-z0-9] tokens in buf[start,end); append hashes to out at noff[0]; return token count 628func be_tok(buf: *u8, start: i64, end: i64, out: *i64, noff: *i64, scr: *u8) -> i64 { 629 var i: i64 = start 630 var cnt: i64 = 0 631 var sl: i64 = 0 632 while i <= end { 633 var c: i64 = 0 634 if i < end { c = buf[i] as i64 } 635 var isc: i64 = 0 636 var lc: i64 = c 637 if c >= 65 { if c <= 90 { lc = c + 32; isc = 1 } } 638 if c >= 97 { if c <= 122 { isc = 1 } } 639 if c >= 48 { if c <= 57 { isc = 1 } } 640 if isc == 1 { 641 if sl < 500 { scr[sl] = lc as u8; sl = sl + 1 } 642 } else { 643 if sl > 0 { 644 sl = pst_stem(scr, sl) 645 out[noff[0]] = db_semhash(scr, 0, sl) 646 noff[0] = noff[0] + 1 647 cnt = cnt + 1 648 sl = 0 649 } 650 } 651 i = i + 1 652 } 653 return cnt 654} 655 656func be_qs1(a: *i64, lo: i64, hi: i64) -> i64 { 657 if lo >= hi { return 0 } 658 var i: i64 = lo 659 var j: i64 = hi 660 let p: i64 = a[(lo + hi) / 2] 661 while i <= j { 662 while a[i] < p { i = i + 1 } 663 while a[j] > p { j = j - 1 } 664 if i <= j { 665 let t: i64 = a[i]; a[i] = a[j]; a[j] = t 666 i = i + 1; j = j - 1 667 } 668 } 669 be_qs1(a, lo, j) 670 be_qs1(a, i, hi) 671 return 0 672} 673 674func be_qs2(key: *i64, pay: *i64, lo: i64, hi: i64) -> i64 { 675 if lo >= hi { return 0 } 676 var i: i64 = lo 677 var j: i64 = hi 678 let p: i64 = key[(lo + hi) / 2] 679 while i <= j { 680 while key[i] < p { i = i + 1 } 681 while key[j] > p { j = j - 1 } 682 if i <= j { 683 let t: i64 = key[i]; key[i] = key[j]; key[j] = t 684 let u: i64 = pay[i]; pay[i] = pay[j]; pay[j] = u 685 i = i + 1; j = j - 1 686 } 687 } 688 be_qs2(key, pay, lo, j) 689 be_qs2(key, pay, i, hi) 690 return 0 691} 692 693// log2(q) in 1/1024ths for q>=1 694func be_log2_1024(q: i64) -> i64 { 695 if q <= 1 { return 0 } 696 var bl: i64 = 0 697 var t: i64 = q 698 while t > 1 { t = t / 2; bl = bl + 1 } 699 var frac: i64 = 0 700 if bl >= 6 { frac = (q / (1 << (bl - 6))) - 64 } 701 if bl < 6 { frac = (q << (6 - bl)) - 64 } 702 if frac < 0 { frac = 0 } 703 return bl * K_MAGIC_1024 + frac * 16 704} 705 706func be_disc(r: i64) -> i64 { 707 if r == 1 { return 1000 } 708 if r == 2 { return 631 } 709 if r == 3 { return 500 } 710 if r == 4 { return 431 } 711 if r == 5 { return 387 } 712 if r == 6 { return 356 } 713 if r == 7 { return 333 } 714 if r == 8 { return 315 } 715 if r == 9 { return 301 } 716 if r == 10 { return 289 } 717 return 0 718} 719 720// R0 PROXIMITY FEATURES: tokenise a candidate doc's raw span and measure how TIGHTLY the query terms co-occur -- 721// the signal a bag-of-words BM25 cannot see. out[0] = the smallest token window covering every DISTINCT query term 722// present in the doc (-1 when fewer than two are present); out[1] = adjacent query-term pairs (phrase-ness). 723// bp = scratch box mmapped once by main and sized from the corpus: [0]=doc hashes [1]=match slot per token 724// [2]=present flag per query slot [3]=window counts per query slot [4]=count box. No per-call allocation. 725func be_prox(cbuf: *u8, ts: i64, te: i64, qh: *i64, nqh: i64, scr: *u8, bp: *i64, out: *i64) -> i64 { 726 let dh: *i64 = bp[0] as *i64 727 let mt: *i64 = bp[1] as *i64 728 let pr: *u8 = bp[2] as *u8 729 let cn: *i64 = bp[3] as *i64 730 let no: *i64 = bp[4] as *i64 731 no[0] = 0 732 be_tok(cbuf, ts, te, dh, no, scr) 733 let dn: i64 = no[0] 734 var j: i64 = 0 735 while j < nqh { pr[j] = 0 as u8; cn[j] = 0; j = j + 1 } 736 var i: i64 = 0 737 while i < dn { 738 var mj: i64 = 0 - 1 739 var jj: i64 = 0 740 while jj < nqh { if dh[i] == qh[jj] { mj = jj; jj = nqh } else { jj = jj + 1 } } 741 if mj >= 0 { pr[mj] = 1 as u8 } 742 mt[i] = mj 743 i = i + 1 744 } 745 var npres: i64 = 0 746 j = 0 747 while j < nqh { if pr[j] == (1 as u8) { npres = npres + 1 } j = j + 1 } 748 var big: i64 = 0 749 i = 0 750 while i + 1 < dn { if mt[i] >= 0 { if mt[i + 1] >= 0 { if mt[i + 1] != mt[i] { big = big + 1 } } } i = i + 1 } 751 var minwin: i64 = 0 - 1 752 if npres >= 2 { 753 var have: i64 = 0 754 var l: i64 = 0 755 var r: i64 = 0 756 minwin = dn 757 while r < dn { 758 let mr: i64 = mt[r] 759 if mr >= 0 { if cn[mr] == 0 { have = have + 1 } cn[mr] = cn[mr] + 1 } 760 while have == npres { 761 let wlen: i64 = r - l + 1 762 if wlen < minwin { minwin = wlen } 763 let ml: i64 = mt[l] 764 if ml >= 0 { cn[ml] = cn[ml] - 1; if cn[ml] == 0 { have = have - 1 } } 765 l = l + 1 766 } 767 r = r + 1 768 } 769 } 770 out[0] = minwin 771 out[1] = big 772 return 0 773} 774 775// decimal argv parse; stops at the first non-digit 776func be_atoi(s: *u8) -> i64 { 777 var v: i64 = 0 778 var i: i64 = 0 779 var go: i64 = 1 780 while go == 1 { 781 let c: i64 = s[i] as i64 782 if c >= BE_ASCII_ZERO { if c <= BE_ASCII_NINE { v = v * BE_DECIMAL + (c - BE_ASCII_ZERO); i = i + 1 } else { go = 0 } } else { go = 0 } 783 } 784 return v 785} 786 787// ONE CROSS-ENCODER PAIR AS ONE POOL TASK (2026-09-15). The pool's unit of work is the whole forward, never a band of 788// one matmul: per-matmul banding pays a submit and a wait for every one of the ~40 matmuls inside a forward and was 789// measured as no speedup (search.plan row 1789456036), while a pair-level task pays ONE sync per forward. The forward 790// inside stays the serial path (the encoder handle carries no pool), so a pooled run and a serial run produce the same 791// score for every pair BY CONSTRUCTION and only the wall clock moves. Every task owns its scratch (ids, types, doc 792// pieces); the encoder weights and the wordpiece table are read-only after load (neither wp_tokenize/wp_pair nor 793// bc_forward writes its table -- checked 2026-09-15), and bc_forward mmaps and unmaps its own activations per call. 794struct BeCeTask { 795 cg: i64, // *i64 the loaded encoder (read-only) 796 wg: i64, // *i64 the wordpiece table (read-only) 797 cbuf: i64, // *u8 the corpus bytes 798 ts: i64, // document span start 799 te: i64, // document span end 800 qtok: i64, // *i64 the query pieces (read-only, shared by the burst) 801 nqx: i64, 802 maxlen: i64, 803 dtok: i64, // *i64 THIS task's document-piece scratch 804 ids: i64, // *i64 THIS task's pair ids 805 types: i64, // *i64 THIS task's pair types 806 score: i64, // OUT: the relevance logit in micro units 807} 808func be_ce_task_at(tasks: *u8, i: i64) -> *BeCeTask { return ((tasks as i64) + i * BE_CE_TASK_BYTES) as *BeCeTask } 809func _be_ce_task(ctx_i: i64) -> i64 { 810 let t: *BeCeTask = ctx_i as *BeCeTask 811 let ndx: i64 = wp_tokenize(t.wg as *i64, t.cbuf as *u8, t.ts, t.te - t.ts, t.dtok as *i64) 812 let tx: i64 = wp_pair(t.wg as *i64, t.qtok as *i64, t.nqx, t.dtok as *i64, ndx, t.maxlen, t.ids as *i64, t.types as *i64) 813 t.score = bc_f32_micro(bc_forward(t.cg as *i64, t.ids as *i64, t.types as *i64, tx)) 814 return 0 815} 816// a decimal into dst at off (returns the new offset); a bare string copy without the terminator 817func be_dec(dst: *u8, off: i64, v: i64) -> i64 { 818 var o: i64 = off 819 var x: i64 = v 820 if x < 0 { dst[o] = 45 as u8; o = o + 1; x = 0 - x } 821 let t: *u8 = sys_mmap(24) 822 var n: i64 = 0 823 if x == 0 { t[0] = 48 as u8; n = 1 } 824 while x > 0 { t[n] = (48 + x % 10) as u8; x = x / 10; n = n + 1 } 825 while n > 0 { n = n - 1; dst[o] = t[n]; o = o + 1 } 826 sys_munmap(t, 24) 827 return o 828} 829func be_scat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64 = off; var i: i64 = 0; while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } return o } 830// THE PROGRESS ROW (2026-09-15): truncate-written (tmp + rename, so a reader never sees a torn row) after every query. 831// A run that prints only its final JSON is silent for hours, and a silent run is indistinguishable from a dead one: the 832// depth-50 NAS run of this date burned 23 CPU-hours with nobody able to say whether it was a third or nine tenths done. 833// Negative on any failure so the caller can COUNT the rows that did not land; it never refuses the run. 834// the stamp path for a queries path: knowledge/status/beir_eval.<queries path with / and . folded to _>.progress 835func be_progress_path(dst: *u8, qpath: *u8, tmp: i64) -> i64 { 836 var o: i64 = be_scat(dst, 0, BE_PROGRESS_DIR) 837 var qi: i64 = 0 838 while qpath[qi] != (0 as u8) { 839 if qi < BE_PATH_CAP { 840 var c: i64 = qpath[qi] as i64 841 if c == BE_SLASH { c = BE_USCORE } 842 if c == BE_DOT { c = BE_USCORE } 843 dst[o] = c as u8 844 o = o + 1 845 } 846 qi = qi + 1 847 } 848 if tmp == 1 { o = be_scat(dst, o, BE_PROGRESS_SFX_TMP) } else { o = be_scat(dst, o, BE_PROGRESS_SFX) } 849 dst[o] = 0 as u8 850 return o 851} 852func be_progress(qpath: *u8, done: i64, pairs: i64, workers: i64, depth: i64) -> i64 { 853 let cap: i64 = BE_PROGRESS_BYTES + BE_PATH_CAP 854 let b: *u8 = sys_mmap(cap) 855 var o: i64 = be_scat(b, 0, "ts=" as *u8); o = be_dec(b, o, sys_now_realtime_sec()) 856 o = be_scat(b, o, " queries_done=" as *u8); o = be_dec(b, o, done) 857 o = be_scat(b, o, " ce_pairs=" as *u8); o = be_dec(b, o, pairs) 858 o = be_scat(b, o, " ce_depth=" as *u8); o = be_dec(b, o, depth) 859 o = be_scat(b, o, " pool_workers=" as *u8); o = be_dec(b, o, workers) 860 o = be_scat(b, o, " queries=" as *u8) 861 var qi: i64 = 0 862 while qpath[qi] != (0 as u8) { if qi < BE_PATH_CAP { b[o] = qpath[qi]; o = o + 1 } qi = qi + 1 } 863 o = be_scat(b, o, " -- truncate-written by nx_beir_eval after every query; a ts that stops moving while the process lives is a hung run, not a slow one\n" as *u8) 864 let pp: *u8 = sys_mmap(BE_PATH_CAP * 2) 865 let pt: *u8 = sys_mmap(BE_PATH_CAP * 2) 866 be_progress_path(pp, qpath, 0) 867 be_progress_path(pt, qpath, 1) 868 let fd: i64 = sys_openat_wr(pt, MODE_0644) 869 if fd < 0 { sys_munmap(b, cap); return 0 - 1 } 870 var off: i64 = 0 871 while off < o { 872 let wv: i64 = sys_write(fd, ((b as i64) + off) as *u8, o - off) 873 if wv <= 0 { sys_close(fd); sys_munmap(b, cap); return 0 - 2 } 874 off = off + wv 875 } 876 sys_close(fd) 877 sys_munmap(b, cap) 878 if sys_renameat(pt, pp) != 0 { return 0 - 3 } 879 return 0 880} 881func main(argc: i64, argv: *i64) -> i64 { 882 let G: *i64 = sys_mmap(BE_G_SLOTS * BE_I64) as *i64 883 let scr: *u8 = sys_mmap(K_MAGIC_1024) 884 885 // ---------- flags (R0d): --set <root>, --bright <root>, --bm25-only; the rest stay positional ---------- 886 let pos: *i64 = sys_mmap(BE_POS_CAP * BE_I64) as *i64 887 var npos: i64 = 0 888 var root: *u8 = 0 as *u8 889 var bright_root: *u8 = 0 as *u8 890 var bm25_only: i64 = 0 891 var qfile: *u8 = 0 as *u8 892 var ai: i64 = 1 893 while ai < argc { 894 let a: *u8 = argv[ai] as *u8 895 var used_flag: i64 = 0 896 if be_streq(a, BE_FLAG_SET) == 1 { if ai + 1 < argc { root = argv[ai + 1] as *u8; ai = ai + 1 } used_flag = 1 } 897 if be_streq(a, BE_FLAG_BRIGHT) == 1 { if ai + 1 < argc { bright_root = argv[ai + 1] as *u8; ai = ai + 1 } used_flag = 1 } 898 if be_streq(a, BE_FLAG_BM25ONLY) == 1 { bm25_only = 1; used_flag = 1 } 899 // dash-less twins of the three flags: nx_sov_build_run's qualify lane treats ANY forwarded argument that starts 900 // with -- as one of its own build-lane flags and refuses the run (measured 2026-09-14), so a qualification run 901 // spells them set=<root>, bright=<root>, bm25only. Same parser, same variables, one spelling per lane. 902 let kv_set: *u8 = "set=" as *u8 903 let kv_bright: *u8 = "bright=" as *u8 904 let kv_bm25: *u8 = "bm25only" as *u8 905 if be_starts_at(a, 0, be_slen(a), kv_set) == 1 { root = ((a as i64) + be_slen(kv_set)) as *u8; used_flag = 1 } 906 if be_starts_at(a, 0, be_slen(a), kv_bright) == 1 { bright_root = ((a as i64) + be_slen(kv_bright)) as *u8; used_flag = 1 } 907 if be_streq(a, kv_bm25) == 1 { bm25_only = 1; used_flag = 1 } 908 if be_streq(a, BE_FLAG_QUERIES) == 1 { if ai + 1 < argc { qfile = argv[ai + 1] as *u8; ai = ai + 1 } used_flag = 1 } 909 let kv_queries: *u8 = "queries=" as *u8 910 if be_starts_at(a, 0, be_slen(a), kv_queries) == 1 { qfile = ((a as i64) + be_slen(kv_queries)) as *u8; used_flag = 1 } 911 if used_flag == 0 { if npos < BE_POS_CAP { pos[npos] = argv[ai]; npos = npos + 1 } } 912 ai = ai + 1 913 } 914 if (bright_root as i64) != 0 { return be_bright(bright_root, argv[0] as *u8, bm25_only, pos, npos, qfile) } 915 let pc: *u8 = sys_mmap(BE_PATH_CAP) 916 let pq: *u8 = sys_mmap(BE_PATH_CAP) 917 let pd: *u8 = sys_mmap(BE_PATH_CAP) 918 let px: *u8 = sys_mmap(BE_PATH_CAP) 919 920 // ---------- load corpus (the buffer is sized from the file; every table below is sized from the buffer) ---------- 921 var cn: i64 = 0 922 if (root as i64) == 0 { 923 be_path(pc, BE_ROOT_DEFAULT, BE_F_CORPUS) 924 be_path(px, BE_ROOT_DEFAULT_TMP, BE_F_CORPUS) 925 cn = be_read_fb(pc, px, G) 926 } else { 927 be_path(pc, root, BE_F_CORPUS) 928 cn = be_read(pc, G) 929 } 930 if cn <= 0 { db_w("{\"error\":\"corpus.tsv missing\",\"path\":\"" as *u8); db_w(pc); db_w("\"}\n" as *u8); return 1 } 931 let cbuf: *u8 = G[0] as *u8 932 let nd_cap: i64 = be_count_byte(cbuf, cn, BE_NL) + 1 933 let tok_cap: i64 = cn / BE_TOK_BYTES + nd_cap + 1 934 935 let thash: *i64 = sys_mmap(tok_cap * BE_I64) as *i64 936 let noff: *i64 = sys_mmap(BE_I64) as *i64 937 noff[0] = 0 938 let doc_start: *i64 = sys_mmap((nd_cap + 1) * BE_I64) as *i64 939 let doc_len: *i64 = sys_mmap(nd_cap * BE_I64) as *i64 940 let doc_idh: *i64 = sys_mmap(nd_cap * BE_I64) as *i64 941 // seq1494 RERANK ARM: keep each doc's RAW TEXT SPAN in cbuf. BM25 works on this harness's own hashed 942 // vocab, but the PPMI late-interaction model has its OWN word ids, so the reranker needs the original 943 // characters. Two i64 arrays is the whole cost of making rung 2 measurable instead of asserted. 944 let doc_ts: *i64 = sys_mmap(nd_cap * BE_I64) as *i64 945 let doc_te: *i64 = sys_mmap(nd_cap * BE_I64) as *i64 946 var nd: i64 = 0 947 var maxspan: i64 = 0 // longest raw doc span, derives the proximity token scratch (no guessed cap) 948 var maxdoctok: i64 = 0 // most tokens in one doc, derives the forward-index scratch (no guessed cap) 949 950 var p: i64 = 0 951 while p < cn { 952 let eol: i64 = be_find(cbuf, p, cn, BE_NL) 953 let tab: i64 = be_find(cbuf, p, eol, BE_TAB) 954 if tab < eol { if nd < nd_cap { 955 doc_idh[nd] = db_semhash(cbuf, p, tab - p) 956 doc_start[nd] = noff[0] 957 doc_ts[nd] = tab + 1 958 doc_te[nd] = eol 959 if eol - tab - 1 > maxspan { maxspan = eol - tab - 1 } 960 doc_len[nd] = be_tok(cbuf, tab + 1, eol, thash, noff, scr) 961 if doc_len[nd] > maxdoctok { maxdoctok = doc_len[nd] } 962 nd = nd + 1 963 } } 964 p = eol + 1 965 } 966 doc_start[nd] = noff[0] 967 let ntok: i64 = noff[0] 968 969 // ---------- vocab = sort+unique ---------- 970 let vocab: *i64 = sys_mmap((ntok + 1) * BE_I64) as *i64 971 var vi: i64 = 0 972 while vi < ntok { vocab[vi] = thash[vi]; vi = vi + 1 } 973 be_qs1(vocab, 0, ntok - 1) 974 var nv: i64 = 0 975 var k: i64 = 0 976 while k < ntok { 977 if nv == 0 { vocab[nv] = vocab[k]; nv = nv + 1 } 978 else { if vocab[k] != vocab[nv - 1] { vocab[nv] = vocab[k]; nv = nv + 1 } } 979 k = k + 1 980 } 981 982 // ---------- forward index + df ---------- 983 let dterm: *i64 = sys_mmap((ntok + 1) * BE_I64) as *i64 984 let dtf: *i64 = sys_mmap((ntok + 1) * BE_I64) as *i64 985 let doc_off: *i64 = sys_mmap((nd_cap + 1) * BE_I64) as *i64 986 let df: *i64 = sys_mmap((nv + 1) * BE_I64) as *i64 987 var z: i64 = 0 988 while z < nv { df[z] = 0; z = z + 1 } 989 let tmpcap: i64 = maxdoctok + 1 990 let tmp: *i64 = sys_mmap(tmpcap * BE_I64) as *i64 991 var dpos: i64 = 0 992 var d: i64 = 0 993 while d < nd { 994 let s0: i64 = doc_start[d] 995 let s1: i64 = doc_start[d + 1] 996 var m: i64 = 0 997 var q: i64 = s0 998 while q < s1 { 999 if m < tmpcap { tmp[m] = db_bsearch_i64(vocab, nv, thash[q]); m = m + 1 } 1000 q = q + 1 1001 } 1002 be_qs1(tmp, 0, m - 1) 1003 doc_off[d] = dpos 1004 var a: i64 = 0 1005 while a < m { 1006 var b: i64 = a + 1 1007 var go3: i64 = 1 1008 while go3 == 1 { if b < m { if tmp[b] == tmp[a] { b = b + 1 } else { go3 = 0 } } else { go3 = 0 } } 1009 if dpos < ntok { dterm[dpos] = tmp[a]; dtf[dpos] = b - a; dpos = dpos + 1 } 1010 df[tmp[a]] = df[tmp[a]] + 1 1011 a = b 1012 } 1013 d = d + 1 1014 } 1015 doc_off[nd] = dpos 1016 1017 // ---------- inverted postings (R0d DURABLE FIX, 2026-09-15): term -> (doc, tf), built ONCE from the forward index ---------- 1018 // The per-query loop used to binary-search EVERY doc for EVERY query term (O(nq * nqt * nd)): on leetcode 1019 // (413,932 docs) that outlived the per-split hour and the driver's two-hour wall, so the twelve-of-twelve 1020 // BRIGHT average could not be measured under load. df[t] is exactly the posting count of term t, so the 1021 // offsets are a prefix sum over df and the fill is one pass over the forward index in doc order -- every 1022 // term's postings come out doc-ascending, which the candidate pass relies on for identical tie order. 1023 // A posting packs doc and tf in one word (doc * BE_PT_TF_MOD + tf); a tf at or past the radix is clamped and COUNTED. 1024 let pt_off: *i64 = sys_mmap((nv + 2) * BE_I64) as *i64 1025 var pt_acc: i64 = 0 1026 var pt_t: i64 = 0 1027 while pt_t < nv { pt_off[pt_t] = pt_acc; pt_acc = pt_acc + df[pt_t]; pt_t = pt_t + 1 } 1028 pt_off[nv] = pt_acc 1029 let pt_fill: *i64 = sys_mmap((nv + 2) * BE_I64) as *i64 1030 pt_t = 0 1031 while pt_t <= nv { pt_fill[pt_t] = pt_off[pt_t]; pt_t = pt_t + 1 } 1032 let pt: *i64 = sys_mmap((pt_acc + 1) * BE_I64) as *i64 1033 var pt_clamped: i64 = 0 1034 var pt_d: i64 = 0 1035 while pt_d < nd { 1036 var pt_i: i64 = doc_off[pt_d] 1037 let pt_e: i64 = doc_off[pt_d + 1] 1038 while pt_i < pt_e { 1039 let pt_term: i64 = dterm[pt_i] 1040 var pt_tf: i64 = dtf[pt_i] 1041 if pt_tf >= BE_PT_TF_MOD { pt_tf = BE_PT_TF_MOD - 1; pt_clamped = pt_clamped + 1 } 1042 pt[pt_fill[pt_term]] = pt_d * BE_PT_TF_MOD + pt_tf 1043 pt_fill[pt_term] = pt_fill[pt_term] + 1 1044 pt_i = pt_i + 1 1045 } 1046 pt_d = pt_d + 1 1047 } 1048 1049 var totlen: i64 = 0 1050 z = 0 1051 while z < nd { totlen = totlen + doc_len[z]; z = z + 1 } 1052 var avgdl: i64 = 1 1053 if nd > 0 { avgdl = totlen / nd } 1054 if avgdl < 1 { avgdl = 1 } 1055 1056 // ---------- doc-id -> docidx (sorted idhash) ---------- 1057 let sidh: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64 1058 let sidx: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64 1059 z = 0 1060 while z < nd { sidh[z] = doc_idh[z]; sidx[z] = z; z = z + 1 } 1061 be_qs2(sidh, sidx, 0, nd - 1) 1062 1063 // ---------- qrels ---------- 1064 var qn: i64 = 0 1065 if (root as i64) == 0 { 1066 be_path(pq, BE_ROOT_DEFAULT, BE_F_QRELS) 1067 be_path(px, BE_ROOT_DEFAULT_TMP, BE_F_QRELS) 1068 qn = be_read_fb(pq, px, (G as i64 + BE_I64) as *i64) 1069 } else { 1070 be_path(pq, root, BE_F_QRELS) 1071 qn = be_read(pq, (G as i64 + BE_I64) as *i64) 1072 } 1073 if qn <= 0 { db_w("{\"error\":\"qrels test.tsv missing\",\"path\":\"" as *u8); db_w(pq); db_w("\"}\n" as *u8); return 1 } 1074 let qbuf: *u8 = G[1] as *u8 1075 let nj_cap: i64 = be_count_byte(qbuf, qn, BE_NL) + 1 1076 let j_qid: *i64 = sys_mmap(nj_cap * BE_I64) as *i64 1077 let j_doc: *i64 = sys_mmap(nj_cap * BE_I64) as *i64 1078 let j_scr: *i64 = sys_mmap(nj_cap * BE_I64) as *i64 1079 var nj: i64 = 0 1080 var qp: i64 = 0 1081 var hdr: i64 = 1 1082 while qp < qn { 1083 let e2: i64 = be_find(qbuf, qp, qn, BE_NL) 1084 if hdr == 1 { hdr = 0 } else { 1085 let t1: i64 = be_find(qbuf, qp, e2, BE_TAB) 1086 if t1 < e2 { 1087 let t2: i64 = be_find(qbuf, t1 + 1, e2, BE_TAB) 1088 if t2 < e2 { 1089 var sc: i64 = 0 1090 var sp: i64 = t2 + 1 1091 while sp < e2 { let dch: i64 = qbuf[sp] as i64; if dch >= 48 { if dch <= 57 { sc = sc * 10 + (dch - 48) } } sp = sp + 1 } 1092 let dh: i64 = db_semhash(qbuf, t1 + 1, t2 - t1 - 1) 1093 let dpos2: i64 = db_bsearch_i64(sidh, nd, dh) 1094 if dpos2 >= 0 { if nj < nj_cap { 1095 j_qid[nj] = db_semhash(qbuf, qp, t1 - qp) 1096 j_doc[nj] = sidx[dpos2] 1097 j_scr[nj] = sc 1098 nj = nj + 1 1099 } } 1100 } 1101 } 1102 } 1103 qp = e2 + 1 1104 } 1105 // sort judgments by qid, carrying an index permutation (so j_doc/j_scr stay addressable via jidx) 1106 let jidx: *i64 = sys_mmap((nj + 1) * BE_I64) as *i64 1107 z = 0 1108 while z < nj { jidx[z] = z; z = z + 1 } 1109 be_qs2(j_qid, jidx, 0, nj - 1) 1110 1111 // ---------- excluded (R0d): <root>/excluded.tsv, query id TAB doc id; absent for BEIR sets ---------- 1112 var xn: i64 = 0 1113 if (root as i64) == 0 { be_path(px, BE_ROOT_DEFAULT, BE_F_EXCLUDED) } else { be_path(px, root, BE_F_EXCLUDED) } 1114 xn = be_read(px, (G as i64 + 3 * BE_I64) as *i64) 1115 var nx: i64 = 0 1116 var x_qid: *i64 = 0 as *i64 1117 var x_doc: *i64 = 0 as *i64 1118 var x_unknown: i64 = 0 1119 if xn > 0 { 1120 let xbuf: *u8 = G[3] as *u8 1121 let x_cap: i64 = be_count_byte(xbuf, xn, BE_NL) + 1 1122 x_qid = sys_mmap(x_cap * BE_I64) as *i64 1123 x_doc = sys_mmap(x_cap * BE_I64) as *i64 1124 var xp: i64 = 0 1125 while xp < xn { 1126 let xe: i64 = be_find(xbuf, xp, xn, BE_NL) 1127 let xt: i64 = be_find(xbuf, xp, xe, BE_TAB) 1128 if xt < xe { 1129 let xdh: i64 = db_semhash(xbuf, xt + 1, xe - xt - 1) 1130 let xdp: i64 = db_bsearch_i64(sidh, nd, xdh) 1131 if xdp >= 0 { if nx < x_cap { x_qid[nx] = db_semhash(xbuf, xp, xt - xp); x_doc[nx] = sidx[xdp]; nx = nx + 1 } } else { x_unknown = x_unknown + 1 } 1132 } 1133 xp = xe + 1 1134 } 1135 be_qs2(x_qid, x_doc, 0, nx - 1) 1136 } 1137 var excluded_applied: i64 = 0 1138 1139 // ---------- per query ---------- 1140 var dqn: i64 = 0 1141 if (root as i64) == 0 { 1142 be_qpath(pd, BE_ROOT_DEFAULT, qfile) 1143 be_qpath(px, BE_ROOT_DEFAULT_TMP, qfile) 1144 dqn = be_read_fb(pd, px, (G as i64 + 2 * BE_I64) as *i64) 1145 } else { 1146 be_qpath(pd, root, qfile) 1147 dqn = be_read(pd, (G as i64 + 2 * BE_I64) as *i64) 1148 } 1149 if dqn <= 0 { db_w("{\"error\":\"queries.tsv missing\",\"path\":\"" as *u8); db_w(pd); db_w("\"}\n" as *u8); return 1 } 1150 let dbuf: *u8 = G[2] as *u8 1151 let nq_cap: i64 = be_count_byte(dbuf, dqn, BE_NL) + 1 1152 let qcap: i64 = be_maxline(dbuf, dqn) / BE_TOK_BYTES + 2 // tokens in the longest query line 1153 let score: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64 1154 let qtid: *i64 = sys_mmap(qcap * BE_I64) as *i64 1155 // S5 BM25Q ARM (2026-09-15): the query-side saturation arm shares the postings walk. Per query token: whether it is 1156 // the FIRST occurrence of its term and the term's query-term frequency; a second score array; the arm's own top-K; 1157 // the pool-fusion scratch; and one per-query record so the long-query subset and the identity control are DERIVED 1158 // after the loop from the data, never from a constant. 1159 let qfirst: *i64 = sys_mmap(qcap * BE_I64) as *i64 1160 let qcnt: *i64 = sys_mmap(qcap * BE_I64) as *i64 1161 let scoreq: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64 1162 let topq: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 1163 let topq_s: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 1164 let qrank: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 1165 let fsq: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 1166 let fqu: *u8 = sys_mmap(BE_KCAND + 1) 1167 let pq_tok: *i64 = sys_mmap(nq_cap * BE_I64) as *i64 1168 let pq_nd: *i64 = sys_mmap(nq_cap * BE_I64) as *i64 1169 let pq_ndq: *i64 = sys_mmap(nq_cap * BE_I64) as *i64 1170 let pq_ndf: *i64 = sys_mmap(nq_cap * BE_I64) as *i64 1171 let pq_rep: *i64 = sys_mmap(nq_cap * BE_I64) as *i64 1172 let pq_same: *i64 = sys_mmap(nq_cap * BE_I64) as *i64 1173 var pq_n: i64 = 0 1174 var sum_ndcg_q: i64 = 0 1175 var sum_ndcg_fq: i64 = 0 1176 let top: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 // seq1494 widened the shortlist to 50 but left this at 16 slots: top[16..49] overran 272B every query -- harmless while only WRITTEN (BM25 arm reads top[0..9]), FATAL once the rerank arm READ the trampled slots back as doc indices 1177 let goldsc: *i64 = sys_mmap((nj + 1) * BE_I64) as *i64 1178 let used: *u8 = sys_mmap(nd + 1) 1179 // R0d DURABLE FIX (2026-09-15): the candidate pass walks only the docs a query term touched (mark) and keeps the 1180 // shortlist in one bounded, index-ordered insertion (top_s) -- the 50 full-corpus scans it replaces were the 1181 // second half of the O(nq * nd) cost that kept the twelve-of-twelve BRIGHT run from finishing under load 1182 let mark: *u8 = sys_mmap(nd + 1) 1183 let top_s: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 1184 // R0g PRF buffers: the expanded score and mark per doc, the touched-doc list, feedback term weights over the vocab 1185 let scorep: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64 1186 let pmark: *u8 = sys_mmap(nd + 1) 1187 let plist: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64 1188 let tw: *i64 = sys_mmap((nv + 1) * BE_I64) as *i64 1189 let twl: *i64 = sys_mmap((nv + 1) * BE_I64) as *i64 1190 let ex_t: *i64 = sys_mmap(BE_PRF_FB_TERMS * BE_I64) as *i64 1191 let ex_w: *i64 = sys_mmap(BE_PRF_FB_TERMS * BE_I64) as *i64 1192 let ptop: *i64 = sys_mmap(BE_PRF_TOP * BE_I64) as *i64 1193 let ptop_s: *i64 = sys_mmap(BE_PRF_TOP * BE_I64) as *i64 1194 let qhbuf: *i64 = sys_mmap(qcap * BE_I64) as *i64 1195 let qnoff: *i64 = sys_mmap(BE_I64) as *i64 1196 1197 // seq1494: load the PPMI model ONCE. HONEST-ABSENT: if it is missing the rerank arm reports 1198 // UNAVAILABLE rather than silently scoring 0 -- an absent model must never read as "reranking is bad". 1199 // g-block for the PPMI lib: its contract uses slots 69..78 (byte 632), so 64 bytes was a 1200 // 560-byte arena overrun -- the seq1494 crash class (dark code, first armed 2026-08-13) 1201 let PG: *i64 = sys_mmap(BE_MAGIC_1024) as *i64 1202 var rr_ok: i64 = 0 1203 if bm25_only == 0 { rr_ok = ppl_load(PG, "knowledge/index/semppmi_v1.bin" as *u8) } 1204 // R0 TRAINED-DENSE ARM: embed_v1.bin (nx_embed_train, PPMI factorised = SGNS-class) through the SAME vocab 1205 // ids as the PPMI model; HONEST-ABSENT like it -- de_ok==0 leaves both dense slots constant (no vote). 1206 var de_ok: i64 = 0 1207 if bm25_only == 0 { de_ok = dj_load_embed(PG, "knowledge/index/embed_v1.bin" as *u8) } 1208 if de_ok == 1 { dj_build_mean(PG) } 1209 let dscore: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 1210 let escore: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 1211 // R0 CROSS-ENCODER ARM (2026-09-14): a pretrained cross-encoder held as a LICENSED DATA ASSET, run by the sovereign 1212 // encoder (nx_bert_ce_lib over nx_wordpiece_lib). positional: [0] model.safetensors [1] config.json [2] vocab.txt 1213 // [3] max sequence length (default the config's max_position_embeddings) [4] candidate depth (default BE_KCAND). 1214 // HONEST-ABSENT like the other arms: a model that does not load reports UNAVAILABLE, never a score of 0. 1215 var ce_model: *u8 = "knowledge/fetched/cmp_search_ce_minilm_model.safetensors" as *u8 1216 var ce_cfg: *u8 = "knowledge/fetched/cmp_search_ce_minilm_config.json" as *u8 1217 var ce_vocab: *u8 = "knowledge/fetched/cmp_search_ce_minilm_vocab.txt" as *u8 1218 if npos >= 3 { ce_model = pos[0] as *u8; ce_cfg = pos[1] as *u8; ce_vocab = pos[2] as *u8 } 1219 let CG: *i64 = sys_mmap(BC_G_BYTES) as *i64 1220 let WG: *i64 = sys_mmap(WP_G_BYTES) as *i64 1221 var ce_ok: i64 = 0 1222 if bm25_only == 0 { ce_ok = bc_load(CG, ce_model, ce_cfg) } else { CG[BC_G_MISSING] = ("skipped: --bm25-only" as *u8) as i64 } 1223 if ce_ok == 1 { if wp_load(WG, ce_vocab) != 1 { ce_ok = 0; CG[BC_G_MISSING] = ("vocab.txt" as *u8) as i64 } } 1224 var ce_maxlen: i64 = 0 1225 if ce_ok == 1 { ce_maxlen = CG[BC_G_MAXPOS] } 1226 if npos >= 4 { ce_maxlen = be_atoi(pos[3] as *u8) } 1227 if ce_ok == 1 { if ce_maxlen > CG[BC_G_MAXPOS] { ce_maxlen = CG[BC_G_MAXPOS] } } 1228 var ce_depth: i64 = BE_KCAND 1229 if npos >= 5 { ce_depth = be_atoi(pos[4] as *u8) } 1230 if ce_depth > BE_KCAND { ce_depth = BE_KCAND } 1231 var ce_workers: i64 = BE_CE_POOL_WORKERS_DEFAULT 1232 if npos >= 6 { ce_workers = be_atoi(pos[5] as *u8) } 1233 // PAIR-LEVEL FORK-JOIN (2026-09-15): ce_workers > 0 forks that many children per query burst, child w scoring the 1234 // candidates cx with cx % ce_workers == w through the SERIAL forward (CG[BC_G_POOL] stays 0, so a pair's score cannot 1235 // depend on the width), and the parent reaps them all before reading the scores. Processes, not the thread pool: 1236 // MEASURED the same day on WSL2, an 8-wide thread pool of whole forwards ran 5 s per forward against 1.6 s serial 1237 // (eight threads faulting fresh activation pages on ONE address space serialise on it), while a forked child owns its 1238 // address space and its faults. The task records live in SHARED memory so a child's score reaches the parent. 1239 let xscore: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 1240 let xused: *u8 = sys_mmap(BE_KCAND) 1241 let xrank: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 // R0f: the cross-encoder rank of each candidate 1242 let xfsc: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 // R0f: the RRF score over bm25-rank + crossenc-rank 1243 // one task record + one scratch set per candidate: pair ids/types bounded by max_len, document pieces by the longest span 1244 let ce_tasks: *u8 = sys_mmap_shared(BE_KCAND * BE_CE_TASK_BYTES) 1245 let ce_stp: *i64 = sys_mmap(BE_I64) as *i64 1246 var ci0: i64 = 0 1247 while ci0 < BE_KCAND { 1248 let tk0: *BeCeTask = be_ce_task_at(ce_tasks, ci0) 1249 tk0.ids = sys_mmap((ce_maxlen + 1) * BE_I64) as i64 1250 tk0.types = sys_mmap((ce_maxlen + 1) * BE_I64) as i64 1251 tk0.dtok = sys_mmap((maxspan + 1) * BE_I64) as i64 1252 tk0.score = 0 1253 ci0 = ci0 + 1 1254 } 1255 let ce_qtok: *i64 = sys_mmap((dqn + 1) * BE_I64) as *i64 // query pieces are bounded by the query file's bytes 1256 var progress_fail: i64 = 0 // progress rows that could not be written (announced in the JSON) 1257 var sum_ndcg_ce: i64 = 0 1258 var q_ce_improved: i64 = 0 1259 var q_ce_worsened: i64 = 0 1260 var sum_ndcg_cef: i64 = 0 1261 var q_cef_improved: i64 = 0 1262 var q_cef_worsened: i64 = 0 1263 var sum_ndcg_prf: i64 = 0 1264 var q_prf_improved: i64 = 0 1265 var q_prf_worsened: i64 = 0 1266 var prf_queries_expanded: i64 = 0 1267 var prf_expansions_total: i64 = 0 1268 var ce_pairs: i64 = 0 1269 let qids: *i64 = sys_mmap(BE_IDCAP * BE_I64) as *i64 1270 let dids: *i64 = sys_mmap(BE_IDCAP * BE_I64) as *i64 1271 let cscore: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 1272 let cused: *u8 = sys_mmap(BE_KCAND) 1273 // R1b fusion-arm buffers (2026-08-13): dense ranks, rrf scores, selection flags 1274 let drank: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 1275 let fsc: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 1276 let fuse_u: *u8 = sys_mmap(BE_KCAND) 1277 var sum_ndcg_rr: i64 = 0 1278 var sum_ndcg_fu: i64 = 0 1279 var q_fu_improved: i64 = 0 1280 var q_fu_worsened: i64 = 0 1281 var q_improved: i64 = 0 1282 var q_worsened: i64 = 0 1283 var q_same: i64 = 0 1284 var sum_ndcg: i64 = 0 1285 var nq: i64 = 0 1286 var n_noqrel: i64 = 0 1287 var n_noterm: i64 = 0 1288 var n_noidcg: i64 = 0 1289 // R0 LEARNED ARM storage: per-candidate features + gold + idcg + fold, filled during the BM25 pass, 1290 // read once after the loop by ltr_cv. Sized from the queries file (nq_cap), never a guessed bound. 1291 let ft_feat: *i64 = sys_mmap(nq_cap * BE_KCAND * LTR_NFEAT * BE_I64) as *i64 1292 let ft_gold: *i64 = sys_mmap(nq_cap * BE_KCAND * BE_I64) as *i64 1293 let ft_ncand: *i64 = sys_mmap(nq_cap * BE_I64) as *i64 1294 let ft_idcg: *i64 = sys_mmap(nq_cap * BE_I64) as *i64 1295 let ft_fold: *i64 = sys_mmap(nq_cap * BE_I64) as *i64 1296 var ft_nq: i64 = 0 1297 // proximity scratch, sized from the corpus: a token needs a byte and a separator, so tokens <= span/2 + 1 1298 let bp_tokcap: i64 = maxspan / BE_TOK_BYTES + 2 1299 let bp: *i64 = sys_mmap(48) as *i64 1300 bp[0] = sys_mmap(bp_tokcap * BE_I64) as i64 1301 bp[1] = sys_mmap(bp_tokcap * BE_I64) as i64 1302 bp[2] = sys_mmap(qcap + 1) as i64 1303 bp[3] = sys_mmap(qcap * BE_I64) as i64 1304 bp[4] = sys_mmap(BE_I64) as i64 1305 let proxout: *i64 = sys_mmap(16) as *i64 1306 var qpp: i64 = 0 1307 while qpp < dqn { 1308 let e3: i64 = be_find(dbuf, qpp, dqn, BE_NL) 1309 let tb: i64 = be_find(dbuf, qpp, e3, BE_TAB) 1310 if tb < e3 { 1311 let qh2: i64 = db_semhash(dbuf, qpp, tb - qpp) 1312 qnoff[0] = 0 1313 be_tok(dbuf, tb + 1, e3, qhbuf, qnoff, scr) 1314 var nqt: i64 = 0 1315 var qi: i64 = 0 1316 while qi < qnoff[0] { 1317 let tid2: i64 = db_bsearch_i64(vocab, nv, qhbuf[qi]) 1318 if tid2 >= 0 { if nqt < qcap { qtid[nqt] = tid2; nqt = nqt + 1 } } 1319 qi = qi + 1 1320 } 1321 let lo0: i64 = db_bsearch_i64(j_qid, nj, qh2) 1322 if lo0 < 0 { n_noqrel = n_noqrel + 1 } else { 1323 var jlo: i64 = lo0 1324 var g1: i64 = 1 1325 while g1 == 1 { if jlo > 0 { if j_qid[jlo - 1] == qh2 { jlo = jlo - 1 } else { g1 = 0 } } else { g1 = 0 } } 1326 var jhi: i64 = lo0 1327 var g2: i64 = 1 1328 while g2 == 1 { if jhi < nj - 1 { if j_qid[jhi + 1] == qh2 { jhi = jhi + 1 } else { g2 = 0 } } else { g2 = 0 } } 1329 1330 // gold + IDCG@10 FIRST (methodology: every query with relevant judgments is counted) 1331 var ng: i64 = 0 1332 var jjg: i64 = jlo 1333 while jjg <= jhi { if ng < nj { goldsc[ng] = j_scr[jidx[jjg]]; ng = ng + 1 } jjg = jjg + 1 } 1334 be_qs1(goldsc, 0, ng - 1) 1335 var idcg: i64 = 0 1336 var ri: i64 = 0 1337 while ri < 10 { if ri < ng { idcg = idcg + goldsc[ng - 1 - ri] * be_disc(ri + 1) } ri = ri + 1 } 1338 1339 if idcg <= 0 { n_noidcg = n_noidcg + 1 } else { 1340 var dcg: i64 = 0 1341 var dcg_q: i64 = 0 1342 var dcg_fq: i64 = 0 1343 var ncand_real_q: i64 = 0 // R0g: the plain arm's real candidate count, hoisted for the PRF pass 1344 // S5: a query with no term in the vocabulary ranks nothing under EITHER arm -- identical by vacuity, so the 1345 // identity control starts at 1 and the arm below overwrites it whenever it actually ranks (15 such queries 1346 // on nfcorpus read as non-identical on the first run, which was the initialiser, not the arm) 1347 var q_same10: i64 = 1 1348 var q_rep: i64 = 0 1349 if nqt <= 0 { n_noterm = n_noterm + 1 } else { 1350 z = 0 1351 while z < nd { score[z] = 0; z = z + 1 } 1352 // R0d DURABLE FIX: walk the term's postings (doc-ascending), never the corpus; the arithmetic per 1353 // (term, doc) is byte-for-byte the scan it replaces, so every score is identical 1354 // S5: first-occurrence flag and query-term frequency per token. The plain arm below stays 1355 // byte-identical (it adds once per OCCURRENCE, as it always has); the BM25Q arm adds once per 1356 // TERM with the saturated weight, so a query with no repeated term scores IDENTICALLY. 1357 var qa: i64 = 0 1358 while qa < nqt { 1359 var qcnt1: i64 = 0 1360 var firstq: i64 = 1 1361 var qb: i64 = 0 1362 while qb < nqt { if qtid[qb] == qtid[qa] { qcnt1 = qcnt1 + 1; if qb < qa { firstq = 0 } } qb = qb + 1 } 1363 qfirst[qa] = firstq 1364 qcnt[qa] = qcnt1 1365 qa = qa + 1 1366 } 1367 z = 0 1368 while z < nd { scoreq[z] = 0; z = z + 1 } 1369 var qt: i64 = 0 1370 while qt < nqt { 1371 let tid3: i64 = qtid[qt] 1372 let dfi: i64 = df[tid3] 1373 if dfi > 0 { 1374 let idf: i64 = be_log2_1024((2 * nd + 2) / (2 * dfi + 1)) 1375 let idfq: i64 = idf_bm25q(idf, qcnt[qt]) 1376 let addq: i64 = qfirst[qt] 1377 var pi: i64 = pt_off[tid3] 1378 let pe: i64 = pt_off[tid3 + 1] 1379 while pi < pe { 1380 let dd: i64 = pt[pi] / BE_PT_TF_MOD 1381 let tf: i64 = pt[pi] % BE_PT_TF_MOD 1382 let norm1000: i64 = 600 + (400 * doc_len[dd]) / avgdl 1383 let denom1000: i64 = tf * 1000 + (900 * norm1000) / 1000 1384 if denom1000 > 0 { score[dd] = score[dd] + (idf * tf * K_MAGIC_1900) / denom1000 } 1385 if addq == 1 { if denom1000 > 0 { scoreq[dd] = scoreq[dd] + (idfq * tf * K_MAGIC_1900) / denom1000 } } 1386 mark[dd] = 1 as u8 1387 pi = pi + 1 1388 } 1389 } 1390 qt = qt + 1 1391 } 1392 z = 0 1393 while z < nd { used[z] = 0 as u8; z = z + 1 } 1394 // R0d: the benchmark's own exclusions for this query are unrankable (BRIGHT excluded_ids) 1395 if nx > 0 { 1396 let xlo0: i64 = db_bsearch_i64(x_qid, nx, qh2) 1397 if xlo0 >= 0 { 1398 var xlo: i64 = xlo0 1399 var gx1: i64 = 1 1400 while gx1 == 1 { if xlo > 0 { if x_qid[xlo - 1] == qh2 { xlo = xlo - 1 } else { gx1 = 0 } } else { gx1 = 0 } } 1401 var xhi: i64 = xlo0 1402 var gx2: i64 = 1 1403 while gx2 == 1 { if xhi < nx - 1 { if x_qid[xhi + 1] == qh2 { xhi = xhi + 1 } else { gx2 = 0 } } else { gx2 = 0 } } 1404 var xk: i64 = xlo 1405 while xk <= xhi { used[x_doc[xk]] = 1 as u8; score[x_doc[xk]] = 0; scoreq[x_doc[xk]] = 0; excluded_applied = excluded_applied + 1; xk = xk + 1 } 1406 } 1407 } 1408 // R0d DURABLE FIX: the shortlist from ONE index-ordered pass over the touched docs (bounded, sorted 1409 // insertion; a strict compare keeps the lower index ahead on ties, exactly as the 50 full scans 1410 // did), then the zero-score fill in index order for a query touching fewer than BE_KCAND docs 1411 var ncand: i64 = 0 1412 var ncq: i64 = 0 1413 var dd2: i64 = 0 1414 while dd2 < nd { 1415 if mark[dd2] == (1 as u8) { 1416 mark[dd2] = 0 as u8 1417 // S5: the BM25Q arm's own shortlist from the same touched set, the same bounded insertion 1418 if used[dd2] == (0 as u8) { 1419 let scq2: i64 = scoreq[dd2] 1420 if scq2 > 0 { 1421 var slotq: i64 = 0 - 1 1422 if ncq < BE_KCAND { slotq = ncq; ncq = ncq + 1 } else { if scq2 > topq_s[BE_KCAND - 1] { slotq = BE_KCAND - 1 } } 1423 if slotq >= 0 { 1424 var kq: i64 = slotq 1425 while kq > 0 { if topq_s[kq - 1] < scq2 { topq[kq] = topq[kq - 1]; topq_s[kq] = topq_s[kq - 1]; kq = kq - 1 } else { break } } 1426 topq[kq] = dd2 1427 topq_s[kq] = scq2 1428 } 1429 } 1430 } 1431 if used[dd2] == (0 as u8) { 1432 let sc2: i64 = score[dd2] 1433 if sc2 > 0 { 1434 var slot: i64 = 0 - 1 1435 if ncand < BE_KCAND { slot = ncand; ncand = ncand + 1 } else { if sc2 > top_s[BE_KCAND - 1] { slot = BE_KCAND - 1 } } 1436 if slot >= 0 { 1437 var kk: i64 = slot 1438 while kk > 0 { if top_s[kk - 1] < sc2 { top[kk] = top[kk - 1]; top_s[kk] = top_s[kk - 1]; kk = kk - 1 } else { break } } 1439 top[kk] = dd2 1440 top_s[kk] = sc2 1441 } 1442 } 1443 } 1444 } 1445 dd2 = dd2 + 1 1446 } 1447 var rr: i64 = 0 1448 while rr < ncand { used[top[rr]] = 1 as u8; rr = rr + 1 } 1449 let ncand_real: i64 = ncand 1450 ncand_real_q = ncand_real 1451 var fd0: i64 = 0 1452 while ncand < BE_KCAND { 1453 if fd0 >= nd { top[ncand] = 0 - 1; ncand = ncand + 1 } else { 1454 if used[fd0] == (0 as u8) { top[ncand] = fd0; used[fd0] = 1 as u8; ncand = ncand + 1 } 1455 fd0 = fd0 + 1 1456 } 1457 } 1458 rr = 0 1459 while rr < 10 { 1460 let dpk: i64 = top[rr] 1461 var gv: i64 = 0 1462 if dpk >= 0 { 1463 var jj2: i64 = jlo 1464 while jj2 <= jhi { 1465 if j_doc[jidx[jj2]] == dpk { gv = j_scr[jidx[jj2]]; jj2 = jhi + 1 } else { jj2 = jj2 + 1 } 1466 } 1467 } 1468 dcg = dcg + gv * be_disc(rr + 1) 1469 rr = rr + 1 1470 } 1471 // S5 BM25Q ARM (pre-declared 2026-09-04, landed 2026-09-15): the same walk scored with the query-side 1472 // saturation (idf_bm25q), its own top-10 over the touched docs, and an RRF k=60 fusion of the plain 1473 // BM25 rank with the BM25Q rank over the SAME candidate pool (the R1b shape), so the delta cannot be 1474 // confounded by candidates the plain arm never saw. 1475 var rq: i64 = 0 1476 while rq < 10 { 1477 var gvq: i64 = 0 1478 if rq < ncq { 1479 let dpq: i64 = topq[rq] 1480 var jjq: i64 = jlo 1481 while jjq <= jhi { if j_doc[jidx[jjq]] == dpq { gvq = j_scr[jidx[jjq]]; jjq = jhi + 1 } else { jjq = jjq + 1 } } 1482 } 1483 dcg_q = dcg_q + gvq * be_disc(rq + 1) 1484 rq = rq + 1 1485 } 1486 var fq0: i64 = 0 1487 while fq0 < BE_KCAND { fqu[fq0] = 0 as u8; qrank[fq0] = BE_KCAND; fq0 = fq0 + 1 } 1488 var drq: i64 = 0 1489 while drq < BE_KCAND { 1490 var bq: i64 = 0 - 1 1491 var cq: i64 = 0 1492 while cq < BE_KCAND { 1493 if fqu[cq] == (0 as u8) { if top[cq] >= 0 { 1494 if bq < 0 { bq = cq } else { if scoreq[top[cq]] > scoreq[top[bq]] { bq = cq } } 1495 } } 1496 cq = cq + 1 1497 } 1498 if bq >= 0 { fqu[bq] = 1 as u8; qrank[bq] = drq } 1499 drq = drq + 1 1500 } 1501 var fq1: i64 = 0 1502 while fq1 < BE_KCAND { 1503 fsq[fq1] = 0 1504 if top[fq1] >= 0 { fsq[fq1] = BE_MAGIC_1000000 / (60 + fq1) + BE_MAGIC_1000000 / (60 + qrank[fq1]) } 1505 fq1 = fq1 + 1 1506 } 1507 var fq2: i64 = 0 1508 while fq2 < BE_KCAND { fqu[fq2] = 0 as u8; fq2 = fq2 + 1 } 1509 var rkq: i64 = 0 1510 while rkq < 10 { 1511 var bq3: i64 = 0 - 1 1512 var cq3: i64 = 0 1513 while cq3 < BE_KCAND { 1514 if fqu[cq3] == (0 as u8) { if top[cq3] >= 0 { 1515 if bq3 < 0 { bq3 = cq3 } else { if fsq[cq3] > fsq[bq3] { bq3 = cq3 } } 1516 } } 1517 cq3 = cq3 + 1 1518 } 1519 if bq3 >= 0 { 1520 fqu[bq3] = 1 as u8 1521 let dpq3: i64 = top[bq3] 1522 var gvq3: i64 = 0 1523 var jjq3: i64 = jlo 1524 while jjq3 <= jhi { if j_doc[jidx[jjq3]] == dpq3 { gvq3 = j_scr[jidx[jjq3]]; jjq3 = jhi + 1 } else { jjq3 = jjq3 + 1 } } 1525 dcg_fq = dcg_fq + gvq3 * be_disc(rkq + 1) 1526 } 1527 rkq = rkq + 1 1528 } 1529 // the anti-vacuity witness: a query with no repeated term must produce the SAME top-10 under both 1530 var same10: i64 = 1 1531 if ncand_real != ncq { same10 = 0 } 1532 var rs: i64 = 0 1533 while rs < 10 { if rs < ncq { if top[rs] != topq[rs] { same10 = 0 } } rs = rs + 1 } 1534 q_same10 = same10 1535 var qr: i64 = 0 1536 while qr < nqt { if qcnt[qr] > 1 { q_rep = 1 } qr = qr + 1 } 1537 } 1538 // ---- seq1494 RERANK ARM: re-order the SAME BM25 shortlist by PPMI late-interaction ---- 1539 // Identical qrels, identical idcg, identical candidate pool -> the ONLY difference is 1540 // the ordering function, which is what makes this a controlled comparison. 1541 var dcg_rr: i64 = dcg 1542 var dcg_fu: i64 = dcg 1543 if rr_ok == 1 { if nqt > 0 { 1544 // same (buf,len) fix on the query side: the query text is dbuf[tb+1 .. e3) 1545 let nqi: i64 = ppl_tokenize_ids(PG, ((dbuf as i64) + tb + 1) as *u8, e3 - tb - 1, qids, BE_IDCAP) 1546 var ci: i64 = 0 1547 while ci < BE_KCAND { 1548 cscore[ci] = 0 - 1 1549 dscore[ci] = 0 1550 escore[ci] = 0 1551 cused[ci] = 0 as u8 1552 let dpc: i64 = top[ci] 1553 if dpc >= 0 { 1554 let dsx: i64 = doc_ts[dpc] 1555 let dex: i64 = doc_te[dpc] 1556 // BUGFIX (caught by an EMPTY result file, not by a passing test): this took 1557 // (buf, len) but was handed (cbuf, dex) -- the corpus BASE and an ABSOLUTE 1558 // END offset -- so every candidate re-tokenised the WHOLE corpus from byte 0. 1559 // 323 queries x 50 candidates x 3633 docs never finished. Pass the doc's own 1560 // span. A silent non-finish is a LOUDER bug than a wrong number. 1561 let ndi: i64 = ppl_tokenize_ids(PG, ((cbuf as i64) + dsx) as *u8, dex - dsx, dids, BE_IDCAP) 1562 cscore[ci] = ppl_maxsim_idf(PG, qids, nqi, dids, ndi) 1563 if de_ok == 1 { dscore[ci] = dj_maxsim_centered(PG, qids, nqi, dids, ndi); escore[ci] = dj_maxsim(PG, qids, nqi, dids, ndi) } 1564 } 1565 ci = ci + 1 1566 } 1567 var dcg2: i64 = 0 1568 var rk: i64 = 0 1569 while rk < 10 { 1570 var bi: i64 = 0 - 1 1571 var cj: i64 = 0 1572 while cj < BE_KCAND { 1573 if cused[cj] == (0 as u8) { if top[cj] >= 0 { 1574 if bi < 0 { bi = cj } else { if cscore[cj] > cscore[bi] { bi = cj } } 1575 } } 1576 cj = cj + 1 1577 } 1578 if bi >= 0 { 1579 cused[bi] = 1 as u8 1580 let dpk2: i64 = top[bi] 1581 var gv2: i64 = 0 1582 var jj3: i64 = jlo 1583 while jj3 <= jhi { 1584 if j_doc[jidx[jj3]] == dpk2 { gv2 = j_scr[jidx[jj3]]; jj3 = jhi + 1 } else { jj3 = jj3 + 1 } 1585 } 1586 dcg2 = dcg2 + gv2 * be_disc(rk + 1) 1587 } 1588 rk = rk + 1 1589 } 1590 dcg_rr = dcg2 1591 // R1b FUSION ARM (pre-declared 2026-08-13): RRF k=60 over the BM25 order 1592 // (top[] index IS the bm25 rank) and the dense maxsim order (cscore). A doc 1593 // must rank in BOTH signals to top the fused list -- exactly what 1594 // nx_recall_fuse ships; measured on external ground truth BEFORE wiring. 1595 var du: i64 = 0 1596 while du < BE_KCAND { fuse_u[du] = 0 as u8; du = du + 1 } 1597 var dr: i64 = 0 1598 while dr < BE_KCAND { 1599 var bj: i64 = 0 - 1 1600 var cj2: i64 = 0 1601 while cj2 < BE_KCAND { 1602 if fuse_u[cj2] == (0 as u8) { if top[cj2] >= 0 { 1603 if bj < 0 { bj = cj2 } else { if cscore[cj2] > cscore[bj] { bj = cj2 } } 1604 } } 1605 cj2 = cj2 + 1 1606 } 1607 if bj >= 0 { fuse_u[bj] = 1 as u8; drank[bj] = dr } 1608 dr = dr + 1 1609 } 1610 var fi: i64 = 0 1611 while fi < BE_KCAND { 1612 fsc[fi] = 0 1613 if top[fi] >= 0 { fsc[fi] = BE_MAGIC_1000000 / (60 + fi) + BE_MAGIC_1000000 / (60 + drank[fi]) } 1614 fi = fi + 1 1615 } 1616 var fu2: i64 = 0 1617 while fu2 < BE_KCAND { fuse_u[fu2] = 0 as u8; fu2 = fu2 + 1 } 1618 var dcg3: i64 = 0 1619 var rk3: i64 = 0 1620 while rk3 < 10 { 1621 var b3: i64 = 0 - 1 1622 var c3: i64 = 0 1623 while c3 < BE_KCAND { 1624 if fuse_u[c3] == (0 as u8) { if top[c3] >= 0 { 1625 if b3 < 0 { b3 = c3 } else { if fsc[c3] > fsc[b3] { b3 = c3 } } 1626 } } 1627 c3 = c3 + 1 1628 } 1629 if b3 >= 0 { 1630 fuse_u[b3] = 1 as u8 1631 let dpk3: i64 = top[b3] 1632 var gv3: i64 = 0 1633 var jj4: i64 = jlo 1634 while jj4 <= jhi { 1635 if j_doc[jidx[jj4]] == dpk3 { gv3 = j_scr[jidx[jj4]]; jj4 = jhi + 1 } else { jj4 = jj4 + 1 } 1636 } 1637 dcg3 = dcg3 + gv3 * be_disc(rk3 + 1) 1638 } 1639 rk3 = rk3 + 1 1640 } 1641 dcg_fu = dcg3 1642 } } 1643 // R0 CROSS-ENCODER ARM: rerank the SAME shortlist by the sovereign encoder's logit (same qrels, idcg, pool) 1644 // R0g PRF ARM (2026-09-16): RM3-style pseudo-relevance feedback, the NON-reasoning expansion control the R0c 1645 // rewriter must beat. Feedback docs = the plain arm's top BE_PRF_FB_DOCS; a candidate expansion term's weight 1646 // is the sum over those docs of tf/doclen (permil) times idf; the BE_PRF_FB_TERMS best terms NOT in the query 1647 // expand it, each weighted by its share of the best weight; the expanded score is orig_permil x plain plus 1648 // (1000 - orig_permil) x the expansion terms' BM25, over every doc either walk touches; excluded docs stay 1649 // unrankable. Anserini's RM3 defaults (fbDocs 10, fbTerms 10, originalQueryWeight 0.5) are the bar's source. 1650 var dcg_prf: i64 = dcg 1651 var prf_nex: i64 = 0 1652 if nqt > 0 { if ncand_real_q > 0 { 1653 var ntw: i64 = 0 1654 var fbi: i64 = 0 1655 while fbi < BE_PRF_FB_DOCS { if fbi < ncand_real_q { 1656 let fbd: i64 = top[fbi] 1657 if fbd >= 0 { if doc_len[fbd] > 0 { 1658 var fi2: i64 = doc_off[fbd] 1659 let fe2: i64 = doc_off[fbd + 1] 1660 while fi2 < fe2 { 1661 let ft: i64 = dterm[fi2] 1662 if tw[ft] == 0 { twl[ntw] = ft; ntw = ntw + 1 } 1663 tw[ft] = tw[ft] + (dtf[fi2] * 1000) / doc_len[fbd] 1664 fi2 = fi2 + 1 1665 } 1666 } } 1667 } fbi = fbi + 1 } 1668 // the best expansion terms by weight x idf, skipping the query's own terms 1669 var ti: i64 = 0 1670 while ti < ntw { 1671 let t2: i64 = twl[ti] 1672 var inq: i64 = 0 1673 var qq: i64 = 0 1674 while qq < nqt { if qtid[qq] == t2 { inq = 1 } qq = qq + 1 } 1675 if inq == 0 { if df[t2] > 0 { 1676 let wt: i64 = tw[t2] * be_log2_1024((2 * nd + 2) / (2 * df[t2] + 1)) 1677 var slotp: i64 = 0 - 1 1678 if prf_nex < BE_PRF_FB_TERMS { slotp = prf_nex; prf_nex = prf_nex + 1 } else { if wt > ex_w[BE_PRF_FB_TERMS - 1] { slotp = BE_PRF_FB_TERMS - 1 } } 1679 if slotp >= 0 { 1680 var kp: i64 = slotp 1681 while kp > 0 { if ex_w[kp - 1] < wt { ex_t[kp] = ex_t[kp - 1]; ex_w[kp] = ex_w[kp - 1]; kp = kp - 1 } else { break } } 1682 ex_t[kp] = t2 1683 ex_w[kp] = wt 1684 } 1685 } } 1686 tw[t2] = 0 1687 ti = ti + 1 1688 } 1689 if prf_nex > 0 { if ex_w[0] > 0 { 1690 // the expanded score over every doc the original or an expansion term touches 1691 var np: i64 = 0 1692 var qo: i64 = 0 1693 while qo < nqt { 1694 let tq: i64 = qtid[qo] 1695 var po: i64 = pt_off[tq] 1696 let poe: i64 = pt_off[tq + 1] 1697 while po < poe { 1698 let dq: i64 = pt[po] / BE_PT_TF_MOD 1699 if pmark[dq] == (0 as u8) { pmark[dq] = 1 as u8; plist[np] = dq; np = np + 1; scorep[dq] = (score[dq] * BE_PRF_ORIG_PERMIL) / 1000 } 1700 po = po + 1 1701 } 1702 qo = qo + 1 1703 } 1704 var ei: i64 = 0 1705 while ei < prf_nex { 1706 let te: i64 = ex_t[ei] 1707 let wperm: i64 = (ex_w[ei] * 1000) / ex_w[0] 1708 let idfe: i64 = be_log2_1024((2 * nd + 2) / (2 * df[te] + 1)) 1709 var pe2: i64 = pt_off[te] 1710 let pee: i64 = pt_off[te + 1] 1711 while pe2 < pee { 1712 let de: i64 = pt[pe2] / BE_PT_TF_MOD 1713 let tfe: i64 = pt[pe2] % BE_PT_TF_MOD 1714 if pmark[de] == (0 as u8) { pmark[de] = 1 as u8; plist[np] = de; np = np + 1; scorep[de] = (score[de] * BE_PRF_ORIG_PERMIL) / 1000 } 1715 let norme: i64 = 600 + (400 * doc_len[de]) / avgdl 1716 let denome: i64 = tfe * 1000 + (900 * norme) / 1000 1717 if denome > 0 { scorep[de] = scorep[de] + (((1000 - BE_PRF_ORIG_PERMIL) * wperm) * ((idfe * tfe * K_MAGIC_1900) / denome)) / BE_MAGIC_1000000 } 1718 pe2 = pe2 + 1 1719 } 1720 ei = ei + 1 1721 } 1722 // the benchmark's exclusions stay unrankable under this arm too 1723 if nx > 0 { 1724 let plo0: i64 = db_bsearch_i64(x_qid, nx, qh2) 1725 if plo0 >= 0 { 1726 var plo: i64 = plo0 1727 var gp1: i64 = 1 1728 while gp1 == 1 { if plo > 0 { if x_qid[plo - 1] == qh2 { plo = plo - 1 } else { gp1 = 0 } } else { gp1 = 0 } } 1729 var phi: i64 = plo0 1730 var gp2: i64 = 1 1731 while gp2 == 1 { if phi < nx - 1 { if x_qid[phi + 1] == qh2 { phi = phi + 1 } else { gp2 = 0 } } else { gp2 = 0 } } 1732 var pk: i64 = plo 1733 while pk <= phi { scorep[x_doc[pk]] = 0; pk = pk + 1 } 1734 } 1735 } 1736 // the top ten by expanded score (bounded insertion, lower index ahead on ties), then their DCG 1737 var npt: i64 = 0 1738 var pl: i64 = 0 1739 while pl < np { 1740 let dp: i64 = plist[pl] 1741 let sp: i64 = scorep[dp] 1742 if sp > 0 { 1743 var slot2: i64 = 0 - 1 1744 if npt < BE_PRF_TOP { slot2 = npt; npt = npt + 1 } else { if sp > ptop_s[BE_PRF_TOP - 1] { slot2 = BE_PRF_TOP - 1 } } 1745 if slot2 >= 0 { 1746 var k2: i64 = slot2 1747 while k2 > 0 { if ptop_s[k2 - 1] < sp { ptop[k2] = ptop[k2 - 1]; ptop_s[k2] = ptop_s[k2 - 1]; k2 = k2 - 1 } else { break } } 1748 ptop[k2] = dp 1749 ptop_s[k2] = sp 1750 } 1751 } 1752 pmark[dp] = 0 as u8 1753 pl = pl + 1 1754 } 1755 var dcgp: i64 = 0 1756 var rp: i64 = 0 1757 while rp < npt { 1758 let dpp: i64 = ptop[rp] 1759 var gvp: i64 = 0 1760 var jjp: i64 = jlo 1761 while jjp <= jhi { if j_doc[jidx[jjp]] == dpp { gvp = j_scr[jidx[jjp]]; jjp = jhi + 1 } else { jjp = jjp + 1 } } 1762 dcgp = dcgp + gvp * be_disc(rp + 1) 1763 rp = rp + 1 1764 } 1765 dcg_prf = dcgp 1766 prf_queries_expanded = prf_queries_expanded + 1 1767 prf_expansions_total = prf_expansions_total + prf_nex 1768 } } 1769 } } 1770 if dcg_prf > dcg { q_prf_improved = q_prf_improved + 1 } else { if dcg_prf < dcg { q_prf_worsened = q_prf_worsened + 1 } } 1771 sum_ndcg_prf = sum_ndcg_prf + (dcg_prf * 1000) / idcg 1772 var dcg_ce: i64 = dcg 1773 var dcg_cef: i64 = dcg 1774 if ce_ok == 1 { if nqt > 0 { 1775 let nqx: i64 = wp_tokenize(WG, dbuf, tb + 1, e3 - tb - 1, ce_qtok) 1776 // every candidate pair is ONE task: tokenise, pair, forward (serial inside), score into its own record; 1777 // a forked burst spreads the tasks over ce_workers children, a serial run calls the same task body inline 1778 var cx: i64 = 0 1779 var submitted: i64 = 0 1780 while cx < BE_KCAND { 1781 xscore[cx] = 0 1782 xused[cx] = 0 as u8 1783 let dpx: i64 = top[cx] 1784 if cx < ce_depth { if dpx >= 0 { 1785 let tk: *BeCeTask = be_ce_task_at(ce_tasks, cx) 1786 tk.cg = CG as i64 1787 tk.wg = WG as i64 1788 tk.cbuf = cbuf as i64 1789 tk.ts = doc_ts[dpx] 1790 tk.te = doc_te[dpx] 1791 tk.qtok = ce_qtok as i64 1792 tk.nqx = nqx 1793 tk.maxlen = ce_maxlen 1794 tk.score = 0 1795 if ce_workers > 0 { submitted = submitted + 1 } else { _be_ce_task(tk as i64) } 1796 ce_pairs = ce_pairs + 1 1797 } } 1798 cx = cx + 1 1799 } 1800 if submitted > 0 { 1801 var fw: i64 = 0 1802 while fw < ce_workers { 1803 let fpid: i64 = sys_fork() 1804 if fpid == 0 { 1805 var cw: i64 = 0 1806 while cw < ce_depth { 1807 if cw % ce_workers == fw { if top[cw] >= 0 { _be_ce_task(be_ce_task_at(ce_tasks, cw) as i64) } } 1808 cw = cw + 1 1809 } 1810 sys_exit(0) 1811 } 1812 fw = fw + 1 1813 } 1814 var fd0: i64 = 0 1815 while fd0 < ce_workers { sys_wait4(0 - 1, ce_stp, 0); fd0 = fd0 + 1 } 1816 } 1817 cx = 0 1818 while cx < BE_KCAND { 1819 if cx < ce_depth { if top[cx] >= 0 { let tkr: *BeCeTask = be_ce_task_at(ce_tasks, cx); xscore[cx] = tkr.score } } 1820 cx = cx + 1 1821 } 1822 var dcgx: i64 = 0 1823 var rkx: i64 = 0 1824 while rkx < 10 { 1825 var bx: i64 = 0 - 1 1826 var cj5: i64 = 0 1827 while cj5 < ce_depth { 1828 if xused[cj5] == (0 as u8) { if top[cj5] >= 0 { 1829 if bx < 0 { bx = cj5 } else { if xscore[cj5] > xscore[bx] { bx = cj5 } } 1830 } } 1831 cj5 = cj5 + 1 1832 } 1833 if bx >= 0 { 1834 xused[bx] = 1 as u8 1835 let dpk5: i64 = top[bx] 1836 var gv5: i64 = 0 1837 var jj5: i64 = jlo 1838 while jj5 <= jhi { 1839 if j_doc[jidx[jj5]] == dpk5 { gv5 = j_scr[jidx[jj5]]; jj5 = jhi + 1 } else { jj5 = jj5 + 1 } 1840 } 1841 dcgx = dcgx + gv5 * be_disc(rkx + 1) 1842 } 1843 rkx = rkx + 1 1844 } 1845 // R0f CE-FUSION ARM (2026-09-16): RRF k=RRF_K_STD over the BM25 order (top index) and the cross-encoder 1846 // order, same candidates. The MS MARCO reranker is out of domain on reasoning queries, so a rank fusion 1847 // that needs a document to stand in BOTH orders is measured beside the pure rerank; the sweep chooses 1848 // between them from its own receipt (nx_beir_arms_lib), never a hand. 1849 var xr0: i64 = 0 1850 while xr0 < BE_KCAND { xused[xr0] = 0 as u8; xrank[xr0] = ce_depth; xr0 = xr0 + 1 } 1851 var xo: i64 = 0 1852 while xo < ce_depth { 1853 var bxr: i64 = 0 - 1 1854 var cxr: i64 = 0 1855 while cxr < ce_depth { 1856 if xused[cxr] == (0 as u8) { if top[cxr] >= 0 { if bxr < 0 { bxr = cxr } else { if xscore[cxr] > xscore[bxr] { bxr = cxr } } } } 1857 cxr = cxr + 1 1858 } 1859 if bxr >= 0 { xused[bxr] = 1 as u8; xrank[bxr] = xo } 1860 xo = xo + 1 1861 } 1862 var xf: i64 = 0 1863 while xf < BE_KCAND { 1864 xfsc[xf] = 0 1865 if xf < ce_depth { if top[xf] >= 0 { xfsc[xf] = BE_MAGIC_1000000 / (RRF_K_STD + xf) + BE_MAGIC_1000000 / (RRF_K_STD + xrank[xf]) } } 1866 xf = xf + 1 1867 } 1868 var xu: i64 = 0 1869 while xu < BE_KCAND { xused[xu] = 0 as u8; xu = xu + 1 } 1870 var dcgxf: i64 = 0 1871 var rkf: i64 = 0 1872 while rkf < 10 { 1873 var bf: i64 = 0 - 1 1874 var cf: i64 = 0 1875 while cf < ce_depth { 1876 if xused[cf] == (0 as u8) { if top[cf] >= 0 { if bf < 0 { bf = cf } else { if xfsc[cf] > xfsc[bf] { bf = cf } } } } 1877 cf = cf + 1 1878 } 1879 if bf >= 0 { 1880 xused[bf] = 1 as u8 1881 let dpkf: i64 = top[bf] 1882 var gvf: i64 = 0 1883 var jjf: i64 = jlo 1884 while jjf <= jhi { if j_doc[jidx[jjf]] == dpkf { gvf = j_scr[jidx[jjf]]; jjf = jhi + 1 } else { jjf = jjf + 1 } } 1885 dcgxf = dcgxf + gvf * be_disc(rkf + 1) 1886 } 1887 rkf = rkf + 1 1888 } 1889 dcg_cef = dcgxf 1890 dcg_ce = dcgx 1891 } } 1892 if dcg_ce > dcg { q_ce_improved = q_ce_improved + 1 } else { if dcg_ce < dcg { q_ce_worsened = q_ce_worsened + 1 } } 1893 sum_ndcg_ce = sum_ndcg_ce + (dcg_ce * 1000) / idcg 1894 if dcg_cef > dcg { q_cef_improved = q_cef_improved + 1 } else { if dcg_cef < dcg { q_cef_worsened = q_cef_worsened + 1 } } 1895 sum_ndcg_cef = sum_ndcg_cef + (dcg_cef * 1000) / idcg 1896 if dcg_rr > dcg { q_improved = q_improved + 1 } else { if dcg_rr < dcg { q_worsened = q_worsened + 1 } else { q_same = q_same + 1 } } 1897 if dcg_fu > dcg { q_fu_improved = q_fu_improved + 1 } else { if dcg_fu < dcg { q_fu_worsened = q_fu_worsened + 1 } } 1898 sum_ndcg_fu = sum_ndcg_fu + (dcg_fu * 1000) / idcg 1899 sum_ndcg_rr = sum_ndcg_rr + (dcg_rr * 1000) / idcg 1900 sum_ndcg = sum_ndcg + (dcg * 1000) / idcg 1901 // S5: the BM25Q arm's per-query record; the long-query subset and the identity control are derived after the loop 1902 sum_ndcg_q = sum_ndcg_q + (dcg_q * 1000) / idcg 1903 sum_ndcg_fq = sum_ndcg_fq + (dcg_fq * 1000) / idcg 1904 if pq_n < nq_cap { pq_tok[pq_n] = qnoff[0]; pq_nd[pq_n] = (dcg * 1000) / idcg; pq_ndq[pq_n] = (dcg_q * 1000) / idcg; pq_ndf[pq_n] = (dcg_fq * 1000) / idcg; pq_rep[pq_n] = q_rep; pq_same[pq_n] = q_same10; pq_n = pq_n + 1 } 1905 // R0 LEARNED ARM: store this query's shortlist for the post-loop 5-fold CV reranker. 1906 // Same candidate pool (top[]), same gold, same idcg as the arms above -> a controlled 1907 // comparison. nqt<=0 stores zero candidates so it scores 0 exactly as the BM25 arm does. 1908 if ft_nq < nq_cap { 1909 ft_idcg[ft_nq] = idcg 1910 ft_fold[ft_nq] = ft_nq - (ft_nq / LTR_FOLDS) * LTR_FOLDS 1911 var st_nc: i64 = 0 1912 if nqt > 0 { 1913 var ci2: i64 = 0 1914 while ci2 < BE_KCAND { 1915 let cdoc: i64 = top[ci2] 1916 if cdoc >= 0 { 1917 let fb: i64 = (ft_nq * BE_KCAND + st_nc) * LTR_NFEAT 1918 ft_feat[fb + 0] = score[cdoc] 1919 if rr_ok == 1 { ft_feat[fb + 1] = cscore[ci2] } else { ft_feat[fb + 1] = 0 } 1920 var cov: i64 = 0 1921 var covidf: i64 = 0 1922 var stf: i64 = 0 1923 var qz: i64 = 0 1924 while qz < nqt { 1925 let tt: i64 = qtid[qz] 1926 let od0: i64 = doc_off[cdoc] 1927 let od1: i64 = doc_off[cdoc + 1] 1928 let ppz: i64 = db_bsearch_i64((dterm as i64 + od0 * 8) as *i64, od1 - od0, tt) 1929 if ppz >= 0 { 1930 cov = cov + 1 1931 let dfz: i64 = df[tt] 1932 covidf = covidf + be_log2_1024((2 * nd + 2) / (2 * dfz + 1)) 1933 stf = stf + dtf[od0 + ppz] 1934 } 1935 qz = qz + 1 1936 } 1937 ft_feat[fb + 2] = cov 1938 ft_feat[fb + 3] = covidf 1939 ft_feat[fb + 4] = stf 1940 ft_feat[fb + 5] = doc_len[cdoc] 1941 var d6: i64 = 0 1942 var d7: i64 = 0 1943 if rr_ok == 1 { if de_ok == 1 { d6 = dscore[ci2]; d7 = escore[ci2] } } 1944 ft_feat[fb + 6] = d6 1945 ft_feat[fb + 7] = d7 1946 be_prox(cbuf, doc_ts[cdoc], doc_te[cdoc], qhbuf, qnoff[0], scr, bp, proxout) 1947 var f8: i64 = 0 1948 if proxout[0] > 0 { f8 = BE_MAGIC_1000000 / (proxout[0] + 1) } 1949 ft_feat[fb + 8] = f8 1950 ft_feat[fb + 9] = proxout[1] 1951 var gvv: i64 = 0 1952 var jz: i64 = jlo 1953 while jz <= jhi { if j_doc[jidx[jz]] == cdoc { gvv = j_scr[jidx[jz]]; jz = jhi + 1 } else { jz = jz + 1 } } 1954 ft_gold[ft_nq * BE_KCAND + st_nc] = gvv 1955 st_nc = st_nc + 1 1956 } 1957 ci2 = ci2 + 1 1958 } 1959 } 1960 ft_ncand[ft_nq] = st_nc 1961 ft_nq = ft_nq + 1 1962 } 1963 nq = nq + 1 1964 if be_progress(pd, nq, ce_pairs, ce_workers, ce_depth) < 0 { progress_fail = progress_fail + 1 } 1965 } 1966 } 1967 } 1968 qpp = e3 + 1 1969 } 1970 1971 var mean: i64 = 0 1972 if nq > 0 { mean = sum_ndcg / nq } 1973 // R0 LEARNED ARM: 5-fold cross-validated held-out nDCG over the stored candidate features. No test 1974 // label trains the weights that score it (each query is held out of its own fold's training). 1975 let ft_cnt: *i64 = sys_mmap(8) as *i64 1976 let cv_learned: i64 = ltr_cv(ft_feat, ft_gold, ft_fold, ft_nq, ft_ncand, BE_KCAND, ft_idcg, ft_cnt) 1977 let ctl_cnt: *i64 = sys_mmap(8) as *i64 1978 let cv_bm25ctrl: i64 = ltr_ndcg_single(ft_feat, ft_gold, ft_nq, ft_ncand, BE_KCAND, ft_idcg, 0, ctl_cnt) 1979 db_w("{\"tool\":\"nx_beir_eval\",\"dataset\":\"" as *u8) 1980 if (root as i64) == 0 { db_w(BE_DATASET_DEFAULT) } else { db_w(root) } 1981 db_w("\",\"queries_file\":\"" as *u8); if (qfile as i64) == 0 { db_w("queries.tsv" as *u8) } else { db_w(qfile) } 1982 db_w("\",\"docs\":" as *u8); db_n(nd) 1983 db_w(",\"vocab\":" as *u8); db_n(nv) 1984 db_w(",\"tokens\":" as *u8); db_n(ntok) 1985 db_w(",\"postings\":" as *u8); db_n(pt_acc) 1986 db_w(",\"postings_tf_clamped\":" as *u8); db_n(pt_clamped) 1987 db_w(",\"test_queries_scored\":" as *u8); db_n(nq) 1988 db_w(",\"dropped_no_qrels\":" as *u8); db_n(n_noqrel) 1989 db_w(",\"dropped_no_relevant\":" as *u8); db_n(n_noidcg) 1990 db_w(",\"counted_zero_no_query_term_match\":" as *u8); db_n(n_noterm) 1991 db_w(",\"excluded_pairs\":" as *u8); db_n(nx) 1992 db_w(",\"excluded_unknown_docs\":" as *u8); db_n(x_unknown) 1993 db_w(",\"excluded_applied\":" as *u8); db_n(excluded_applied) 1994 db_w(",\"bm25_only\":" as *u8); db_n(bm25_only) 1995 db_w(",\"avgdl\":" as *u8); db_n(avgdl) 1996 db_w(",\"bm25\":{\"k1x1000\":900,\"bx1000\":400,\"idf\":\"log2\",\"stemming\":\"porter\",\"stopwords\":false}" as *u8) 1997 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(mean) 1998 if (root as i64) == 0 { db_w(",\"published_bm25_baseline_permil\":320" as *u8) } else { db_w(",\"published_bm25_baseline\":\"per set: the board's sotabar row carries it (BRIGHT average 14.5)\"" as *u8) } 1999 // seq1494: the rerank arm, printed from the SAME run. UNAVAILABLE (not 0) when the model is absent. 2000 var mean_rr: i64 = 0 2001 if nq > 0 { mean_rr = sum_ndcg_rr / nq } 2002 db_w(",\"rerank\":{\"model\":" as *u8) 2003 if rr_ok == 1 { db_w("\"semppmi_v1 late-interaction maxsim(idf)\"" as *u8) } else { db_w("\"UNAVAILABLE -- semppmi_v1.bin did not load or --bm25-only; rerank arm NOT measured (this is not a score of 0)\"" as *u8) } 2004 db_w(",\"candidates\":" as *u8); db_n(BE_KCAND) 2005 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(mean_rr) 2006 db_w(",\"delta_permil\":" as *u8); db_n(mean_rr - mean) 2007 db_w(",\"queries_improved\":" as *u8); db_n(q_improved) 2008 db_w(",\"queries_worsened\":" as *u8); db_n(q_worsened) 2009 db_w(",\"queries_unchanged\":" as *u8); db_n(q_same) 2010 db_w(",\"accept_rule\":\"declared BEFORE the run: rerank must EXCEED the BM25 arm on these same queries or it does NOT get wired into search (seq1494)\"}" as *u8) 2011 var mean_fu: i64 = 0 2012 if nq > 0 { mean_fu = sum_ndcg_fu / nq } 2013 db_w(",\"fusion\":{\"method\":\"rrf k=60 over bm25-rank + maxsim-rank, same 50 candidates\",\"ndcg_at_10_permil\":" as *u8); db_n(mean_fu) 2014 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_fu - mean) 2015 db_w(",\"queries_improved\":" as *u8); db_n(q_fu_improved) 2016 db_w(",\"queries_worsened\":" as *u8); db_n(q_fu_worsened) 2017 db_w(",\"accept_rule\":\"declared BEFORE the run: FUSED must EXCEED the BM25 arm same-run or R1b stays unwired\"}" as *u8) 2018 // S5 BM25Q (2026-09-15): the query-side saturation arm and its pool fusion, the long-query subset DERIVED from the 2019 // set (tokens above the set's mean) and the identity control over every query with no repeated term 2020 var mean_q: i64 = 0 2021 var mean_fq: i64 = 0 2022 if nq > 0 { mean_q = sum_ndcg_q / nq; mean_fq = sum_ndcg_fq / nq } 2023 var tok_sum: i64 = 0 2024 var pi2: i64 = 0 2025 while pi2 < pq_n { tok_sum = tok_sum + pq_tok[pi2]; pi2 = pi2 + 1 } 2026 var tok_mean: i64 = 0 2027 if pq_n > 0 { tok_mean = tok_sum / pq_n } 2028 var long_n: i64 = 0 2029 var long_sd: i64 = 0 2030 var long_sq: i64 = 0 2031 var long_sf: i64 = 0 2032 var norep_n: i64 = 0 2033 var norep_same: i64 = 0 2034 var rep_n: i64 = 0 2035 pi2 = 0 2036 while pi2 < pq_n { 2037 if pq_tok[pi2] > tok_mean { long_n = long_n + 1; long_sd = long_sd + pq_nd[pi2]; long_sq = long_sq + pq_ndq[pi2]; long_sf = long_sf + pq_ndf[pi2] } 2038 if pq_rep[pi2] == 0 { norep_n = norep_n + 1; if pq_same[pi2] == 1 { norep_same = norep_same + 1 } } else { rep_n = rep_n + 1 } 2039 pi2 = pi2 + 1 2040 } 2041 var long_d: i64 = 0 2042 var long_q: i64 = 0 2043 var long_f: i64 = 0 2044 if long_n > 0 { long_d = long_sd / long_n; long_q = long_sq / long_n; long_f = long_sf / long_n } 2045 db_w(",\"bm25q\":{\"saturation\":\"robertson on query-term frequency (nx_intlog idf_bm25q, k_q10 below)\",\"k_q10\":" as *u8); db_n(BM25Q_K_Q10) 2046 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(mean_q) 2047 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_q - mean) 2048 db_w(",\"fusion\":{\"method\":\"rrf k=60 over bm25-rank + bm25q-rank, same 50 candidates\",\"ndcg_at_10_permil\":" as *u8); db_n(mean_fq) 2049 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_fq - mean); db_w("}" as *u8) 2050 db_w(",\"long_rule\":\"query tokens above the set mean\",\"mean_query_tokens\":" as *u8); db_n(tok_mean) 2051 db_w(",\"long_n\":" as *u8); db_n(long_n) 2052 db_w(",\"long_bm25_permil\":" as *u8); db_n(long_d) 2053 db_w(",\"long_bm25q_permil\":" as *u8); db_n(long_q) 2054 db_w(",\"long_fusion_permil\":" as *u8); db_n(long_f) 2055 db_w(",\"queries_with_repeated_term\":" as *u8); db_n(rep_n) 2056 db_w(",\"norepeat_n\":" as *u8); db_n(norep_n) 2057 db_w(",\"norepeat_top10_identical\":" as *u8); db_n(norep_same) 2058 db_w(",\"accept_rule\":\"declared 2026-09-04 (search S5): the FUSED arm must EXCEED plain BM25 on the long-query subset by nDCG at 10, and every no-repeat query must rank IDENTICALLY under both\",\"verdict\":\"" as *u8) 2059 if long_n > 0 { if long_f > long_d { if norep_same == norep_n { db_w("FUSION-BEATS-BM25-ON-LONG" as *u8) } else { db_w("IDENTITY-CONTROL-FAILED" as *u8) } } else { db_w("FUSION-DOES-NOT-BEAT-BM25-ON-LONG" as *u8) } } else { db_w("NO-LONG-QUERIES" as *u8) } 2060 db_w("\"}" as *u8) 2061 db_w(",\"learned\":{\"model\":\"coordinate-ascent LTR (Metzler-Croft: init bm25-only, step-halving line search on training-fold nDCG at 10), 5-fold CV\",\"features\":\"bm25 ppmi_maxsim cover covidf sumtf doclen dense_maxsim_centered dense_maxsim minwin bigram\",\"dense_model\":" as *u8) 2062 if de_ok == 1 { db_w("\"embed_v1 (nx_embed_train, PPMI-factorised; common component removed for the centered slot)\"" as *u8) } else { db_w("\"UNAVAILABLE -- embed_v1.bin did not load or --bm25-only; both dense slots constant (no vote), NOT a score of 0\"" as *u8) } 2063 db_w(",\"single_feature_controls_permil\":[" as *u8) 2064 var sfk: i64 = 0 2065 while sfk < LTR_NFEAT { if sfk > 0 { db_w("," as *u8) } db_n(ltr_ndcg_single(ft_feat, ft_gold, ft_nq, ft_ncand, BE_KCAND, ft_idcg, sfk, ctl_cnt)); sfk = sfk + 1 } 2066 db_w("],\"folds\":5,\"queries_scored\":" as *u8); db_n(ft_cnt[0]) 2067 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(cv_learned) 2068 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(cv_learned - mean) 2069 db_w(",\"bm25only_control_permil\":" as *u8); db_n(cv_bm25ctrl) 2070 db_w(",\"accept_rule\":\"the 5-fold cross-validated held-out mean must EXCEED the BM25 arm on these same queries -- no test label trains the weights that score it -- or nr_rerank stays UNWIRED\"}" as *u8) 2071 var mean_ce: i64 = 0 2072 if nq > 0 { mean_ce = sum_ndcg_ce / nq } 2073 db_w(",\"crossenc\":{\"model\":" as *u8) 2074 if ce_ok == 1 { db_w("\"" as *u8); db_w(ce_model); db_w("\"" as *u8) } else { db_w("\"UNAVAILABLE -- the cross-encoder did not load (" as *u8); db_w(CG[BC_G_MISSING] as *u8); db_w("); arm NOT measured, not a score of 0\"" as *u8) } 2075 db_w(",\"hidden\":" as *u8); db_n(CG[BC_G_HID]) 2076 db_w(",\"layers\":" as *u8); db_n(CG[BC_G_LAYERS]) 2077 db_w(",\"max_len\":" as *u8); db_n(ce_maxlen) 2078 db_w(",\"candidates\":" as *u8); db_n(ce_depth) 2079 db_w(",\"pairs_scored\":" as *u8); db_n(ce_pairs) 2080 db_w(",\"pool_workers\":" as *u8); db_n(ce_workers) 2081 db_w(",\"pool_unit\":\"one pair per task, serial forward inside\"" as *u8) 2082 let ppr: *u8 = sys_mmap(BE_PATH_CAP * 2) 2083 be_progress_path(ppr, pd, 0) 2084 db_w(",\"progress_file\":\"" as *u8); db_w(ppr); db_w("\",\"progress_rows_unwritten\":" as *u8); db_n(progress_fail) 2085 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(mean_ce) 2086 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_ce - mean) 2087 db_w(",\"queries_improved\":" as *u8); db_n(q_ce_improved) 2088 db_w(",\"queries_worsened\":" as *u8); db_n(q_ce_worsened) 2089 db_w(",\"accept_rule\":\"declared BEFORE the run: the cross-encoder arm must EXCEED the BM25 arm on these same queries or nr_rerank stays UNWIRED; wired only after it also clears the estate judged set\"}" as *u8) 2090 // R0f (2026-09-16): the keys the BRIGHT sweep reads back per split -- each spelled ONCE in this receipt so be_json_int's 2091 // first occurrence is the value; ce_measured says whether the reranker ran at all (an UNAVAILABLE arm is 0, never a score) 2092 var mean_cef: i64 = 0 2093 if nq > 0 { mean_cef = sum_ndcg_cef / nq } 2094 db_w(",\"ce_measured\":" as *u8); db_n(ce_ok) 2095 db_w(",\"ce_ndcg_at_10_permil\":" as *u8); db_n(mean_ce) 2096 db_w(",\"cefusion\":{\"method\":\"rrf k=RRF_K_STD over bm25-rank + crossenc-rank, same candidates\",\"queries_improved\":" as *u8); db_n(q_cef_improved) 2097 db_w(",\"queries_worsened\":" as *u8); db_n(q_cef_worsened) 2098 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_cef - mean) 2099 db_w(",\"accept_rule\":\"declared BEFORE the run (R0f): the fused arm is chosen for the row only when every split measured the reranker and it EXCEEDS plain BM25 and the best other arm; a tie keeps the pure rerank\"}" as *u8) 2100 db_w(",\"cefusion_ndcg_at_10_permil\":" as *u8); db_n(mean_cef) 2101 // R0g: the PRF arm's receipt, its sweep key spelled once 2102 var mean_prf: i64 = 0 2103 if nq > 0 { mean_prf = sum_ndcg_prf / nq } 2104 db_w(",\"prf\":{\"method\":\"rm3-style pseudo-relevance feedback\",\"fb_docs\":" as *u8); db_n(BE_PRF_FB_DOCS) 2105 db_w(",\"fb_terms\":" as *u8); db_n(BE_PRF_FB_TERMS) 2106 db_w(",\"orig_weight_permil\":" as *u8); db_n(BE_PRF_ORIG_PERMIL) 2107 db_w(",\"term_weight\":\"sum over feedback docs of tf/doclen permil x idf, query terms excluded, expansion weights as a share of the best\"" as *u8) 2108 db_w(",\"queries_expanded\":" as *u8); db_n(prf_queries_expanded) 2109 db_w(",\"expansion_terms_total\":" as *u8); db_n(prf_expansions_total) 2110 db_w(",\"queries_improved\":" as *u8); db_n(q_prf_improved) 2111 db_w(",\"queries_worsened\":" as *u8); db_n(q_prf_worsened) 2112 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_prf - mean) 2113 db_w(",\"accept_rule\":\"declared BEFORE the run (R0g): the PRF arm reaches the row only when its twelve-split average EXCEEDS plain BM25 and the best other arm; it is the non-reasoning expansion control the R0c rewriter must beat\"}" as *u8) 2114 db_w(",\"prf_ndcg_at_10_permil\":" as *u8); db_n(mean_prf) 2115 db_w(",\"note\":\"real external ground truth; integer/bit-reproducible; porter-stemmed via nx_stem_lib (rung landed 2026-08-13); no stopwords; capacities derived from the set's own files (R0d, 2026-09-14)\"}" as *u8) 2116 db_w("\n" as *u8) 2117 return 0 2118}