code wiki / _hdl_build / nx_bench_ingest.nx
nx_bench_ingest.nx source
↩ module page · 310 lines · 11867 B
1// nx_bench_ingest.nx -- THE GENERIC BENCHMARK INGEST (rule 15 DRY; the second half of nx_bench_fetch).
2//
3// WHY: nx_swebv_ingest and nx_gmmlu_ingest are ~90% the same body -- an escape-aware JSON row walker whose
4// only real difference is WHICH FIELD NAMES it pulls. Baking field names into source means a new organ per
5// benchmark, and (per the ~119 *_research_fetch family) every copy inherits the original's latent bugs.
6// Here the field names are ARGUMENTS, so a new card axis is a DATA row, not a new organ (rule 11).
7//
8// nx_bench_ingest <rawpath> <first_field> <id_field> <q_field> <opts_csv|-> <a_field> <taskpfx> <goldpfx>
9// first_field = the FIRST feature of the row object; the row anchor is "row":{"<first_field>":"
10// opts_csv = e.g. option_a,option_b,option_c,option_d (or `-` for a non-multiple-choice set)
11// emits taskpfx : id <TAB> question [<TAB> opt]... (NEVER the answer -- contamination split)
12// goldpfx : id <TAB> answer
13//
14// Same correctness core as the bespoke organs it replaces: escape-aware value end (terminating '"' = one
15// preceded by an EVEN run of backslashes, so text containing \" cannot mis-terminate a field), row search
16// BOUNDED to [row,next-row) so a malformed row cannot steal a sibling's fields, values stored JSON-escaped
17// verbatim (TAB/NEWLINE-safe by construction), truncations COUNTED not silent, and fail-closed: task==gold
18// and >0 or NEITHER store is touched.
19// expect_exit: 0 (GREEN) | 1 RED | 2 usage license_tier: ORIGINAL No hw writes (Rule 26).
20import "nx_store_seed_lib.nx"
21import "nx_seg_store.nx"
22import "nx_syscalls.nx"
23
24static g_t: *u8
25static g_to: i64
26static g_g: *u8
27static g_go: i64
28static g_rows: i64
29static g_gold: i64
30static g_ve: i64
31static g_trunc: i64
32static g_ord: i64
33static g_synth: i64
34
35const BI_FCAP: i64 = 8388608
36const BI_OCAP: i64 = 4194304
37const BI_FIELDCAP: i64 = 16384
38const BI_NDLCAP: i64 = 256
39const BI_SBCAP: i64 = 2048
40const BI_TAB: i64 = 9
41const BI_NL: i64 = 10
42const BI_Q: i64 = 34
43const BI_BSL: i64 = 92
44const BI_COMMA: i64 = 44
45const BI_STDERR: i64 = 2
46const BI_D0: i64 = 48
47const BI_B10: i64 = 10
48const BI_NUMB: i64 = 24
49const BI_EXIT_RED: i64 = 1
50const BI_EXIT_USAGE: i64 = 2
51const BI_ARGC: i64 = 9
52const BI_DASH: i64 = 45
53
54func bi_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
55func bi_werr(s: *u8) -> i64 { sys_write(BI_STDERR, s, bi_slen(s)); return 0 }
56func bi_read(path: *u8, buf: *u8, cap: i64) -> i64 {
57 let fd: i64 = sys_openat_rd(path)
58 if fd < 0 { return 0 - 1 }
59 var n: i64 = 0
60 var go: i64 = 1
61 while go == 1 {
62 let base: i64 = buf as i64
63 let r: i64 = sys_read(fd, (base + n) as *u8, cap - n)
64 if r <= 0 { go = 0 } else { n = n + r }
65 if n >= cap { go = 0 }
66 }
67 sys_close(fd)
68 return n
69}
70func bi_cat(d: *u8, off: i64, s: *u8) -> i64 {
71 var o: i64 = off
72 var j: i64 = 0
73 while s[j] != (0 as u8) { d[o] = s[j]; o = o + 1; j = j + 1 }
74 return o
75}
76func bi_catn(d: *u8, off: i64, v: i64) -> i64 {
77 var o: i64 = off
78 var m: i64 = v
79 if m == 0 { d[o] = BI_D0 as u8; return o + 1 }
80 if m < 0 { m = 0 - m }
81 let t: *u8 = sys_mmap(BI_NUMB)
82 var k: i64 = 0
83 while m > 0 { t[k] = (BI_D0 + (m % BI_B10)) as u8; m = m / BI_B10; k = k + 1 }
84 var i: i64 = 0
85 while i < k { d[o] = t[k - 1 - i]; o = o + 1; i = i + 1 }
86 return o
87}
88// build the needle "<field>":" into dst
89func bi_needle(dst: *u8, field: *u8) -> i64 {
90 dst[0] = BI_Q as u8
91 var o: i64 = bi_cat(dst, 1, field)
92 dst[o] = BI_Q as u8
93 o = o + 1
94 dst[o] = 58 as u8
95 o = o + 1
96 dst[o] = BI_Q as u8
97 o = o + 1
98 dst[o] = 0 as u8
99 return o
100}
101func bi_find(buf: *u8, needle: *u8, from: i64, limit: i64) -> i64 {
102 let m: i64 = bi_slen(needle)
103 if m == 0 { return 0 - 1 }
104 var i: i64 = from
105 while i + m <= limit {
106 var j: i64 = 0
107 var ok: i64 = 1
108 while j < m { if buf[i+j] != needle[j] { ok = 0; j = m } else { j = j + 1 } }
109 if ok == 1 { if i > 0 { if buf[i-1] == (BI_BSL as u8) { ok = 0 } } }
110 if ok == 1 { return i }
111 i = i + 1
112 }
113 return 0 - 1
114}
115func bi_vend(buf: *u8, vs: i64, limit: i64) -> i64 {
116 var i: i64 = vs
117 while i < limit {
118 if buf[i] == (BI_Q as u8) {
119 var b: i64 = 0
120 var j: i64 = i - 1
121 var g: i64 = 1
122 while g == 1 { if j < vs { g = 0 } else { if buf[j] == (BI_BSL as u8) { b = b + 1; j = j - 1 } else { g = 0 } } }
123 if b % 2 == 0 { return i }
124 }
125 i = i + 1
126 }
127 return limit
128}
129func bi_field(buf: *u8, needle: *u8, from: i64, limit: i64) -> i64 {
130 let p: i64 = bi_find(buf, needle, from, limit)
131 if p < 0 { return 0 - 1 }
132 let vs: i64 = p + bi_slen(needle)
133 g_ve = bi_vend(buf, vs, limit)
134 return vs
135}
136func bi_t_c(c: i64) -> i64 { if g_to < BI_OCAP - 2 { g_t[g_to] = c as u8; g_to = g_to + 1 } return 0 }
137func bi_g_c(c: i64) -> i64 { if g_go < BI_OCAP - 2 { g_g[g_go] = c as u8; g_go = g_go + 1 } return 0 }
138func bi_t_slice(buf: *u8, a: i64, b: i64) -> i64 {
139 var e: i64 = b
140 if b - a > BI_FIELDCAP { e = a + BI_FIELDCAP; g_trunc = g_trunc + 1 }
141 var i: i64 = a
142 while i < e { if g_to < BI_OCAP - 2 { g_t[g_to] = buf[i]; g_to = g_to + 1 } i = i + 1 }
143 return 0
144}
145func bi_g_slice(buf: *u8, a: i64, b: i64) -> i64 {
146 var i: i64 = a
147 while i < b { if g_go < BI_OCAP - 2 { g_g[g_go] = buf[i]; g_go = g_go + 1 } i = i + 1 }
148 return 0
149}
150// synthesized id: "r<ordinal>" -- for datasets that carry NO id field at all (e.g. SimpleQA). The /rows
151// envelope does carry row_idx, but it lives OUTSIDE the row object and is an unquoted number, so the
152// "field":" needle cannot reach it; a stable ordinal is the honest substitute.
153func bi_t_n(v: i64) -> i64 {
154 bi_t_c(114)
155 var m: i64 = v
156 if m == 0 { bi_t_c(BI_D0); return 0 }
157 let t: *u8 = sys_mmap(BI_NUMB)
158 var k: i64 = 0
159 while m > 0 { t[k] = (BI_D0 + (m % BI_B10)) as u8; m = m / BI_B10; k = k + 1 }
160 var i: i64 = 0
161 while i < k { bi_t_c(t[k - 1 - i] as i64); i = i + 1 }
162 return 0
163}
164func bi_g_n(v: i64) -> i64 {
165 bi_g_c(114)
166 var m: i64 = v
167 if m == 0 { bi_g_c(BI_D0); return 0 }
168 let t: *u8 = sys_mmap(BI_NUMB)
169 var k: i64 = 0
170 while m > 0 { t[k] = (BI_D0 + (m % BI_B10)) as u8; m = m / BI_B10; k = k + 1 }
171 var i: i64 = 0
172 while i < k { bi_g_c(t[k - 1 - i] as i64); i = i + 1 }
173 return 0
174}
175// emit one TASK column for field `f` from row [a,limit); 1 ok / 0 missing
176func bi_col(buf: *u8, f: *u8, a: i64, limit: i64) -> i64 {
177 let nd: *u8 = sys_mmap(BI_NDLCAP)
178 bi_needle(nd, f)
179 let vs: i64 = bi_field(buf, nd, a, limit)
180 if vs < 0 { return 0 }
181 let ve: i64 = g_ve
182 bi_t_c(BI_TAB)
183 bi_t_slice(buf, vs, ve)
184 return 1
185}
186// emit every option column named in the csv; 1 ok / 0 a name was missing
187func bi_opts(buf: *u8, csv: *u8, a: i64, limit: i64) -> i64 {
188 if csv[0] == (BI_DASH as u8) { return 1 }
189 let one: *u8 = sys_mmap(BI_NDLCAP)
190 var i: i64 = 0
191 var k: i64 = 0
192 var ok: i64 = 1
193 var go: i64 = 1
194 while go == 1 {
195 let c: i64 = csv[i]
196 if c == 0 {
197 go = 0
198 if k > 0 { one[k] = 0 as u8; if bi_col(buf, one, a, limit) == 0 { ok = 0 } }
199 } else {
200 if c == BI_COMMA {
201 one[k] = 0 as u8
202 if k > 0 { if bi_col(buf, one, a, limit) == 0 { ok = 0 } }
203 k = 0
204 } else {
205 if k < BI_NDLCAP - 2 { one[k] = c as u8; k = k + 1 }
206 }
207 i = i + 1
208 }
209 }
210 return ok
211}
212func bi_scan(buf: *u8, n: i64, anchor: *u8, idf: *u8, qf: *u8, optcsv: *u8, af: *u8) -> i64 {
213 let ndid: *u8 = sys_mmap(BI_NDLCAP)
214 bi_needle(ndid, idf)
215 let ndans: *u8 = sys_mmap(BI_NDLCAP)
216 bi_needle(ndans, af)
217 var p: i64 = 0
218 var go: i64 = 1
219 while go == 1 {
220 let a: i64 = bi_find(buf, anchor, p, n)
221 if a < 0 { go = 0 } else {
222 let nx: i64 = bi_find(buf, anchor, a + 1, n)
223 var limit: i64 = n
224 if nx >= 0 { limit = nx }
225 g_ord = g_ord + 1
226 var ivs: i64 = 0 - 1
227 var ive: i64 = 0 - 1
228 if g_synth == 0 { ivs = bi_field(buf, ndid, a, limit); ive = g_ve }
229 let avs: i64 = bi_field(buf, ndans, a, limit)
230 let ave: i64 = g_ve
231 var idok: i64 = 1
232 if g_synth == 0 { if ivs < 0 { idok = 0 } }
233 if idok == 1 { if avs >= 0 {
234 let mark: i64 = g_to
235 if g_synth == 1 { bi_t_n(g_ord) } else { bi_t_slice(buf, ivs, ive) }
236 var ok: i64 = 1
237 if bi_col(buf, qf, a, limit) == 0 { ok = 0 }
238 if bi_opts(buf, optcsv, a, limit) == 0 { ok = 0 }
239 if ok == 1 {
240 bi_t_c(BI_NL)
241 g_rows = g_rows + 1
242 if g_synth == 1 { bi_g_n(g_ord) } else { bi_g_slice(buf, ivs, ive) }
243 bi_g_c(BI_TAB)
244 bi_g_slice(buf, avs, ave)
245 bi_g_c(BI_NL)
246 g_gold = g_gold + 1
247 } else { g_to = mark }
248 } }
249 if nx < 0 { go = 0 } else { p = nx }
250 }
251 }
252 return 0
253}
254
255func main(argc: i64, argv: *i64) -> i64 {
256 if argc < BI_ARGC { bi_werr("usage: nx_bench_ingest <rawpath> <first_field> <id_field> <q_field> <opts_csv|-> <a_field> <taskpfx> <goldpfx>\n" as *u8); sys_exit(BI_EXIT_USAGE); return BI_EXIT_USAGE }
257 let raw: *u8 = argv[1] as *u8
258 let firstf: *u8 = argv[2] as *u8
259 let idf: *u8 = argv[3] as *u8
260 let qf: *u8 = argv[4] as *u8
261 let optcsv: *u8 = argv[5] as *u8
262 let af: *u8 = argv[6] as *u8
263 let taskpfx: *u8 = argv[7] as *u8
264 let goldpfx: *u8 = argv[8] as *u8
265
266 g_t = sys_mmap(BI_OCAP)
267 g_g = sys_mmap(BI_OCAP)
268 g_to = 0
269 g_go = 0
270 g_rows = 0
271 g_gold = 0
272 g_trunc = 0
273 g_ord = 0
274 // id_field `-` => the dataset carries no id; synthesize stable "r<ordinal>" ids instead
275 g_synth = 0
276 if idf[0] == (BI_DASH as u8) { g_synth = 1 }
277
278 // row anchor: "row":{"<first_field>":"
279 let anchor: *u8 = sys_mmap(BI_NDLCAP)
280 var ao: i64 = bi_cat(anchor, 0, "\"row\":{" as *u8)
281 let sub: *u8 = sys_mmap(BI_NDLCAP)
282 bi_needle(sub, firstf)
283 ao = bi_cat(anchor, ao, sub)
284 anchor[ao] = 0 as u8
285
286 let fbuf: *u8 = sys_mmap(BI_FCAP)
287 let n: i64 = bi_read(raw, fbuf, BI_FCAP)
288 if n <= 0 { bi_werr("BENCH-INGEST FAIL verdict=RED raw absent/empty\n" as *u8); sys_exit(BI_EXIT_RED); return BI_EXIT_RED }
289 bi_scan(fbuf, n, anchor, idf, qf, optcsv, af)
290 if g_rows <= 0 { bi_werr("BENCH-INGEST FAIL verdict=RED rows=0 (field-name or anchor mismatch?) stores untouched\n" as *u8); sys_exit(BI_EXIT_RED); return BI_EXIT_RED }
291 if g_rows != g_gold { bi_werr("BENCH-INGEST FAIL verdict=RED task/gold mismatch, stores untouched\n" as *u8); sys_exit(BI_EXIT_RED); return BI_EXIT_RED }
292 if sts_seed(taskpfx, g_t, g_to) < 0 { bi_werr("BENCH-INGEST FAIL verdict=RED task commit\n" as *u8); sys_exit(BI_EXIT_RED); return BI_EXIT_RED }
293 if sts_seed(goldpfx, g_g, g_go) < 0 { bi_werr("BENCH-INGEST FAIL verdict=RED gold commit\n" as *u8); sys_exit(BI_EXIT_RED); return BI_EXIT_RED }
294
295 let sb: *u8 = sys_mmap(BI_SBCAP)
296 var o: i64 = bi_cat(sb, 0, "BENCH-INGEST OK verdict=GREEN rows=" as *u8)
297 o = bi_catn(sb, o, g_rows)
298 o = bi_cat(sb, o, " gold=" as *u8)
299 o = bi_catn(sb, o, g_gold)
300 o = bi_cat(sb, o, " truncated=" as *u8)
301 o = bi_catn(sb, o, g_trunc)
302 o = bi_cat(sb, o, " task_bytes=" as *u8)
303 o = bi_catn(sb, o, g_to)
304 o = bi_cat(sb, o, " gold_bytes=" as *u8)
305 o = bi_catn(sb, o, g_go)
306 o = bi_cat(sb, o, " (generic: field names are ARGUMENTS; task plane carries NO answer column)\n" as *u8)
307 sys_write(BI_STDERR, sb, o)
308 sys_exit(0)
309 return 0
310}