code wiki / (root) / nx_bright_prep.nx

nx_bright_prep.nx source

↩ module page · 346 lines · 15543 B

1// nx_bright_prep.nx -- BRIGHT (huggingface xlangai/BRIGHT, cc-by-4.0) reshaped into the BEIR layout nx_beir_eval reads 2// (search R0d be_bright). 3// 4// usage: nx_bright_prep <split> <examples.parquet> <documents.parquet> <outdir> 5// Writes, through the sovereign parquet reader (nx_parquet_lib): 6// <outdir>/corpus.tsv doc id TAB content (the documents file, id and content, via pq_tsv) 7// <outdir>/queries.tsv query id TAB query (the examples file) 8// <outdir>/qrels/test.tsv the BEIR header line, then query id TAB doc id TAB 1 for every gold_ids element 9// <outdir>/excluded.tsv query id TAB doc id for every excluded_ids element: BRIGHT lists the query's own 10// source documents there, so a retriever must not be credited for finding them 11// <outdir>/../LICENSE the dataset, its source and its licence beside the bytes (a data asset carries its 12// licence in the same directory, the estate's rule for foreign data) 13// Every file is staged as .tmp and renamed into place. Tabs, newlines and carriage returns inside a cell become 14// spaces. A row with a null id or query is COUNTED and skipped; a gold or excluded element whose row has no id is 15// COUNTED as an orphan. The known-answer test is the dataset card's num_examples per split (search.refs brightds26): 16// queries must equal it and corpus rows must equal the documents count. The work lives in bp_run so the gate drives 17// it in-process; main prints the receipt. Exit 0 OK, 1 REFUSED, 2 usage. 18// Measured 2026-09-14 on eleven splits: every count agrees with the card, orphans 0 (search.plan 1789433620). 19// license_tier: ORIGINAL No hw writes (Rule 26). 20import "nx_syscalls.nx" 21import "nx_parquet_lib.nx" 22 23const BP_OK: i64 = 0 24const BP_REFUSED: i64 = 1 25const BP_USAGE: i64 = 2 26const BP_STDOUT: i64 = 1 27const BP_MODE_DIR: i64 = 0x1ed 28const BP_PATH_CAP: i64 = 1024 29const BP_SLASH: i64 = 47 30const BP_TMP: *u8 = ".tmp" 31const BP_F_CORPUS: *u8 = "/corpus.tsv" 32const BP_F_QUERIES: *u8 = "/queries.tsv" 33const BP_D_QRELS: *u8 = "/qrels" 34const BP_F_QRELS: *u8 = "/qrels/test.tsv" 35const BP_F_EXCLUDED: *u8 = "/excluded.tsv" 36const BP_F_LICENSE: *u8 = "/LICENSE" 37const BP_COL_ID: *u8 = "id" 38const BP_COL_CONTENT: *u8 = "content" 39const BP_COL_QUERY: *u8 = "query" 40const BP_COL_GOLD: *u8 = "gold_ids" 41const BP_COL_EXCL: *u8 = "excluded_ids" 42const BP_H1: *u8 = "query-id" 43const BP_H2: *u8 = "corpus-id" 44const BP_H3: *u8 = "score" 45const BP_SCORE: *u8 = "1" 46const BP_LICENSE_TEXT: *u8 = "BRIGHT: A Realistic and Challenging Benchmark for Reasoning-Intensive Retrieval. Source: huggingface.co/datasets/xlangai/BRIGHT (the dataset card is pinned as search.refs brightds26, read 2026-09-14). Licence: Creative Commons Attribution 4.0 (cc-by-4.0), as declared on that card. The files under this directory are derived from the documents and examples parquet files of that dataset by the estate's own reader (nx_parquet_lib) and prep organ (nx_bright_prep), reshaped into the BEIR layout nx_beir_eval reads (corpus.tsv, queries.tsv, qrels/test.tsv, excluded.tsv per split); content is unchanged apart from tabs, newlines and carriage returns inside a cell becoming spaces. This file is written by nx_bright_prep on every run." 47// the receipt slots bp_run fills 48const BR_QUERIES: i64 = 0 49const BR_NULLQ: i64 = 1 50const BR_QDECL: i64 = 2 51const BR_QRELS: i64 = 3 52const BR_EXCL: i64 = 4 53const BR_ORPHANS: i64 = 5 54const BR_CORPUS_DECL: i64 = 6 55const BR_CORPUS_ROWS: i64 = 7 56const BR_CORPUS_WRITTEN: i64 = 8 57const BR_CORPUS_NULL: i64 = 9 58const BR_CORPUS_BYTES: i64 = 10 59const BR_STAGE: i64 = 11 // which stage refused (BR_ST_*), 0 when none 60const BR_WHAT: i64 = 12 // the reader's pq[PQ_WHAT] at the refusal 61const BR_SLOTS: i64 = 13 62// stages, named so a refusal says where 63const BR_ST_NONE: i64 = 0 64const BR_ST_LICENSE: i64 = 1 65const BR_ST_DOCS_OPEN: i64 = 2 66const BR_ST_DOCS_COLUMNS: i64 = 3 67const BR_ST_CORPUS: i64 = 4 68const BR_ST_EX_OPEN: i64 = 5 69const BR_ST_EX_COLUMNS: i64 = 6 70const BR_ST_OUTPUTS: i64 = 7 71const BR_ST_EX_READ: i64 = 8 72const BR_ST_ROWS: i64 = 9 73const BR_ST_FINISH: i64 = 10 74 75func bp_slen(s: *u8) -> i64 { 76 var n: i64 = 0 77 while (s[n] & PQ_BYTE) as i64 != 0 { n = n + 1 } 78 return n 79} 80// dst = base + tail, NUL-terminated; returns the length or PQ_E_CAPACITY 81func bp_path(dst: *u8, base: *u8, tail: *u8) -> i64 { 82 let bl: i64 = bp_slen(base) 83 let tl: i64 = bp_slen(tail) 84 if bl + tl + 1 > BP_PATH_CAP { return PQ_E_CAPACITY } 85 var i: i64 = 0 86 while i < bl { dst[i] = base[i]; i = i + 1 } 87 var j: i64 = 0 88 while j < tl { dst[bl + j] = tail[j]; j = j + 1 } 89 dst[bl + tl] = 0 as u8 90 return bl + tl 91} 92// the parent directory of a path (cut at the last slash) into dst; 0 when there is none 93func bp_parent(dst: *u8, path: *u8) -> i64 { 94 let n: i64 = bp_slen(path) 95 var cut: i64 = PQ_NONE 96 var i: i64 = 0 97 while i < n { if (path[i] & PQ_BYTE) as i64 == BP_SLASH { cut = i } i = i + 1 } 98 if cut <= 0 { return 0 } 99 var k: i64 = 0 100 while k < cut { dst[k] = path[k]; k = k + 1 } 101 dst[cut] = 0 as u8 102 return cut 103} 104// open <path>.tmp for writing; tmp receives the staged name; returns the fd or a refusal 105func bp_open_tmp(path: *u8, tmp: *u8) -> i64 { 106 if bp_path(tmp, path, BP_TMP) < 0 { return PQ_E_CAPACITY } 107 let fd: i64 = sys_openat_wr(tmp, MODE_0644) 108 if fd < 0 { return PQ_E_OPEN } 109 return fd 110} 111func bp_finish(w: *i64, fd: i64, tmp: *u8, path: *u8) -> i64 { 112 wb_flush(w) 113 sys_close(fd) 114 if w[WB_ERR] != 0 { return PQ_E_CAPACITY } 115 if sys_renameat(tmp, path) != 0 { return PQ_E_OPEN } 116 return 0 117} 118func bp_stage_name(st: i64) -> *u8 { 119 if st == BR_ST_LICENSE { return "LICENSE" as *u8 } 120 if st == BR_ST_DOCS_OPEN { return "documents-open" as *u8 } 121 if st == BR_ST_DOCS_COLUMNS { return "documents-columns (id, content)" as *u8 } 122 if st == BR_ST_CORPUS { return "corpus.tsv" as *u8 } 123 if st == BR_ST_EX_OPEN { return "examples-open" as *u8 } 124 if st == BR_ST_EX_COLUMNS { return "examples-columns (id, query, gold_ids, excluded_ids)" as *u8 } 125 if st == BR_ST_OUTPUTS { return "output-files" as *u8 } 126 if st == BR_ST_EX_READ { return "examples-read" as *u8 } 127 if st == BR_ST_ROWS { return "examples-id-and-query-row-counts" as *u8 } 128 if st == BR_ST_FINISH { return "finish (rename into place)" as *u8 } 129 return "none" as *u8 130} 131// the whole job: fills st[BR_*]; returns 0 or a refusal code with st[BR_STAGE] naming the stage 132func bp_run(exf: *u8, docf: *u8, outdir: *u8, st: *i64) -> i64 { 133 var s0: i64 = 0 134 while s0 < BR_SLOTS { st[s0] = 0; s0 = s0 + 1 } 135 st[BR_WHAT] = PQ_NONE 136 let p1: *u8 = sys_mmap(BP_PATH_CAP) 137 let p2: *u8 = sys_mmap(BP_PATH_CAP) 138 let p3: *u8 = sys_mmap(BP_PATH_CAP) 139 let t1: *u8 = sys_mmap(BP_PATH_CAP) 140 let t2: *u8 = sys_mmap(BP_PATH_CAP) 141 let t3: *u8 = sys_mmap(BP_PATH_CAP) 142 let parent: *u8 = sys_mmap(BP_PATH_CAP) 143 let pq: *i64 = sys_mmap(PQ_SLOTS * PQ_I64) as *i64 144 // directories (an existing one answers EEXIST, which is the state wanted) 145 if bp_parent(parent, outdir) > 0 { sys_mkdir(parent, BP_MODE_DIR) } 146 sys_mkdir(outdir, BP_MODE_DIR) 147 bp_path(p1, outdir, BP_D_QRELS) 148 sys_mkdir(p1, BP_MODE_DIR) 149 // the licence beside the bytes 150 if bp_parent(parent, outdir) > 0 { 151 bp_path(p1, parent, BP_F_LICENSE) 152 let lfd: i64 = bp_open_tmp(p1, t1) 153 if lfd < 0 { st[BR_STAGE] = BR_ST_LICENSE; return lfd } 154 let lw: *i64 = wb_new(lfd) 155 wb_puts(lw, BP_LICENSE_TEXT) 156 wb_byte(lw, PQ_NL) 157 let lrc: i64 = bp_finish(lw, lfd, t1, p1) 158 if lrc < 0 { st[BR_STAGE] = BR_ST_LICENSE; return lrc } 159 } 160 // corpus.tsv from the documents file 161 let rcd: i64 = pq_open(pq, docf) 162 if rcd < 0 { st[BR_STAGE] = BR_ST_DOCS_OPEN; st[BR_WHAT] = pq[PQ_WHAT]; return rcd } 163 let lid: i64 = pq_leaf_named(pq, BP_COL_ID) 164 let lct: i64 = pq_leaf_named(pq, BP_COL_CONTENT) 165 if lid < 0 || lct < 0 { st[BR_STAGE] = BR_ST_DOCS_COLUMNS; st[BR_WHAT] = lid; return PQ_E_ARG } 166 let stats: *i64 = sys_mmap(PT_SLOTS * PQ_I64) as *i64 167 bp_path(p1, outdir, BP_F_CORPUS) 168 let rct: i64 = pq_tsv(pq, lid, lct, p1, stats) 169 st[BR_CORPUS_ROWS] = stats[PT_ROWS] 170 st[BR_CORPUS_WRITTEN] = stats[PT_WRITTEN] 171 st[BR_CORPUS_NULL] = stats[PT_NULLROWS] 172 st[BR_CORPUS_BYTES] = stats[PT_BYTES] 173 st[BR_CORPUS_DECL] = pq[PQ_NROWS] 174 if rct < 0 { st[BR_STAGE] = BR_ST_CORPUS; st[BR_WHAT] = pq[PQ_WHAT]; return rct } 175 // the examples file 176 let pqe: *i64 = sys_mmap(PQ_SLOTS * PQ_I64) as *i64 177 let rce: i64 = pq_open(pqe, exf) 178 if rce < 0 { st[BR_STAGE] = BR_ST_EX_OPEN; st[BR_WHAT] = pqe[PQ_WHAT]; return rce } 179 st[BR_QDECL] = pqe[PQ_NROWS] 180 let eid: i64 = pq_leaf_named(pqe, BP_COL_ID) 181 let eq: i64 = pq_leaf_named(pqe, BP_COL_QUERY) 182 let eg: i64 = pq_leaf_named(pqe, BP_COL_GOLD) 183 let ex: i64 = pq_leaf_named(pqe, BP_COL_EXCL) 184 if eid < 0 || eq < 0 || eg < 0 || ex < 0 { st[BR_STAGE] = BR_ST_EX_COLUMNS; st[BR_WHAT] = eid; return PQ_E_ARG } 185 bp_path(p1, outdir, BP_F_QUERIES) 186 bp_path(p2, outdir, BP_F_QRELS) 187 bp_path(p3, outdir, BP_F_EXCLUDED) 188 let fq: i64 = bp_open_tmp(p1, t1) 189 if fq < 0 { st[BR_STAGE] = BR_ST_OUTPUTS; return fq } 190 let fr: i64 = bp_open_tmp(p2, t2) 191 if fr < 0 { st[BR_STAGE] = BR_ST_OUTPUTS; return fr } 192 let fx: i64 = bp_open_tmp(p3, t3) 193 if fx < 0 { st[BR_STAGE] = BR_ST_OUTPUTS; return fx } 194 let wq: *i64 = wb_new(fq) 195 let wr: *i64 = wb_new(fr) 196 let wx: *i64 = wb_new(fx) 197 wb_puts(wr, BP_H1) 198 wb_byte(wr, PQ_TAB) 199 wb_puts(wr, BP_H2) 200 wb_byte(wr, PQ_TAB) 201 wb_puts(wr, BP_H3) 202 wb_byte(wr, PQ_NL) 203 var r: i64 = 0 204 while r < pqe[PQ_NRG] { 205 let pid: *i64 = pr_alloc(pqe, r, eid) 206 let pqy: *i64 = pr_alloc(pqe, r, eq) 207 let pg: *i64 = pr_alloc(pqe, r, eg) 208 let px: *i64 = pr_alloc(pqe, r, ex) 209 let r1: i64 = pq_read_column(pqe, r, eid, pid) 210 if r1 < 0 { st[BR_STAGE] = BR_ST_EX_READ; st[BR_WHAT] = pqe[PQ_WHAT]; return r1 } 211 let r2: i64 = pq_read_column(pqe, r, eq, pqy) 212 if r2 < 0 { st[BR_STAGE] = BR_ST_EX_READ; st[BR_WHAT] = pqe[PQ_WHAT]; return r2 } 213 let r3: i64 = pq_read_column(pqe, r, eg, pg) 214 if r3 < 0 { st[BR_STAGE] = BR_ST_EX_READ; st[BR_WHAT] = pqe[PQ_WHAT]; return r3 } 215 let r4: i64 = pq_read_column(pqe, r, ex, px) 216 if r4 < 0 { st[BR_STAGE] = BR_ST_EX_READ; st[BR_WHAT] = pqe[PQ_WHAT]; return r4 } 217 if pid[PR_N] != pqy[PR_N] { st[BR_STAGE] = BR_ST_ROWS; return PQ_E_LEVELS } 218 let ida: *u8 = pid[PR_ARENA] as *u8 219 let ioff: *i64 = pid[PR_OFF] as *i64 220 let ilen: *i64 = pid[PR_LEN] as *i64 221 let qa: *u8 = pqy[PR_ARENA] as *u8 222 let qoff: *i64 = pqy[PR_OFF] as *i64 223 let qlen: *i64 = pqy[PR_LEN] as *i64 224 var i: i64 = 0 225 while i < pid[PR_N] { 226 if ioff[i] >= 0 && qoff[i] >= 0 { 227 wb_cell(wq, ida, ioff[i], ilen[i]) 228 wb_byte(wq, PQ_TAB) 229 wb_cell(wq, qa, qoff[i], qlen[i]) 230 wb_byte(wq, PQ_NL) 231 st[BR_QUERIES] = st[BR_QUERIES] + 1 232 } else { st[BR_NULLQ] = st[BR_NULLQ] + 1 } 233 i = i + 1 234 } 235 let ga: *u8 = pg[PR_ARENA] as *u8 236 let goff: *i64 = pg[PR_OFF] as *i64 237 let glen: *i64 = pg[PR_LEN] as *i64 238 let grow: *i64 = pg[PR_ROW] as *i64 239 var e: i64 = 0 240 while e < pg[PR_N] { 241 if goff[e] >= 0 { 242 let row: i64 = grow[e] 243 if row >= 0 && row < pid[PR_N] && ioff[row] >= 0 { 244 wb_cell(wr, ida, ioff[row], ilen[row]) 245 wb_byte(wr, PQ_TAB) 246 wb_cell(wr, ga, goff[e], glen[e]) 247 wb_byte(wr, PQ_TAB) 248 wb_puts(wr, BP_SCORE) 249 wb_byte(wr, PQ_NL) 250 st[BR_QRELS] = st[BR_QRELS] + 1 251 } else { st[BR_ORPHANS] = st[BR_ORPHANS] + 1 } 252 } 253 e = e + 1 254 } 255 let xa: *u8 = px[PR_ARENA] as *u8 256 let xoff: *i64 = px[PR_OFF] as *i64 257 let xlen: *i64 = px[PR_LEN] as *i64 258 let xrow: *i64 = px[PR_ROW] as *i64 259 var e2: i64 = 0 260 while e2 < px[PR_N] { 261 if xoff[e2] >= 0 { 262 let row2: i64 = xrow[e2] 263 if row2 >= 0 && row2 < pid[PR_N] && ioff[row2] >= 0 { 264 wb_cell(wx, ida, ioff[row2], ilen[row2]) 265 wb_byte(wx, PQ_TAB) 266 wb_cell(wx, xa, xoff[e2], xlen[e2]) 267 wb_byte(wx, PQ_NL) 268 st[BR_EXCL] = st[BR_EXCL] + 1 269 } else { st[BR_ORPHANS] = st[BR_ORPHANS] + 1 } 270 } 271 e2 = e2 + 1 272 } 273 pr_free(pid) 274 pr_free(pqy) 275 pr_free(pg) 276 pr_free(px) 277 r = r + 1 278 } 279 let f1: i64 = bp_finish(wq, fq, t1, p1) 280 if f1 < 0 { st[BR_STAGE] = BR_ST_FINISH; return f1 } 281 let f2: i64 = bp_finish(wr, fr, t2, p2) 282 if f2 < 0 { st[BR_STAGE] = BR_ST_FINISH; return f2 } 283 let f3: i64 = bp_finish(wx, fx, t3, p3) 284 if f3 < 0 { st[BR_STAGE] = BR_ST_FINISH; return f3 } 285 return 0 286} 287// the receipt's verdict: queries equal the file's declared rows, corpus written equals the documents file's rows, 288// no orphan 289func bp_verdict(st: *i64) -> i64 { 290 if st[BR_QUERIES] != st[BR_QDECL] { return 0 } 291 if st[BR_CORPUS_WRITTEN] != st[BR_CORPUS_DECL] { return 0 } 292 if st[BR_ORPHANS] != 0 { return 0 } 293 return 1 294} 295 296func main(argc: i64, argv: *i64) -> i64 { 297 let w: *i64 = wb_new(BP_STDOUT) 298 if argc < 5 { 299 wb_puts(w, "usage: nx_bright_prep <split> <examples.parquet> <documents.parquet> <outdir>" as *u8) 300 wb_byte(w, PQ_NL) 301 wb_flush(w) 302 sys_exit(BP_USAGE) 303 return BP_USAGE 304 } 305 let split: *u8 = argv[1] as *u8 306 let st: *i64 = sys_mmap(BR_SLOTS * PQ_I64) as *i64 307 let rc: i64 = bp_run(argv[2] as *u8, argv[3] as *u8, argv[4] as *u8, st) 308 wb_puts(w, "NX-BRIGHT-PREP split=" as *u8) 309 wb_puts(w, split) 310 wb_byte(w, PQ_SPACE) 311 wb_kv(w, "queries" as *u8, st[BR_QUERIES]) 312 wb_kv(w, "null_queries" as *u8, st[BR_NULLQ]) 313 wb_kv(w, "queries_declared" as *u8, st[BR_QDECL]) 314 wb_kv(w, "qrels" as *u8, st[BR_QRELS]) 315 wb_kv(w, "excluded" as *u8, st[BR_EXCL]) 316 wb_kv(w, "orphans" as *u8, st[BR_ORPHANS]) 317 wb_kv(w, "corpus_declared" as *u8, st[BR_CORPUS_DECL]) 318 wb_kv(w, "corpus_rows" as *u8, st[BR_CORPUS_ROWS]) 319 wb_kv(w, "corpus_written" as *u8, st[BR_CORPUS_WRITTEN]) 320 wb_kv(w, "corpus_null_rows" as *u8, st[BR_CORPUS_NULL]) 321 wb_kv(w, "corpus_bytes" as *u8, st[BR_CORPUS_BYTES]) 322 wb_puts(w, "outdir=" as *u8) 323 wb_puts(w, argv[4] as *u8) 324 wb_byte(w, PQ_SPACE) 325 if rc < 0 { 326 wb_puts(w, "REFUSED " as *u8) 327 wb_puts(w, bp_stage_name(st[BR_STAGE])) 328 wb_byte(w, PQ_SPACE) 329 wb_puts(w, pq_errname(rc)) 330 wb_byte(w, PQ_SPACE) 331 wb_kv(w, "code" as *u8, rc) 332 wb_kv(w, "what" as *u8, st[BR_WHAT]) 333 wb_puts(w, "verdict=REFUSED" as *u8) 334 wb_byte(w, PQ_NL) 335 wb_flush(w) 336 sys_exit(BP_REFUSED) 337 return BP_REFUSED 338 } 339 let ok: i64 = bp_verdict(st) 340 if ok == 1 { wb_puts(w, "verdict=OK" as *u8) } else { wb_puts(w, "verdict=REFUSED (counts disagree with the files' own declarations)" as *u8) } 341 wb_byte(w, PQ_NL) 342 wb_flush(w) 343 if ok == 1 { sys_exit(BP_OK); return BP_OK } 344 sys_exit(BP_REFUSED) 345 return BP_REFUSED 346}