code wiki / _hdl_build / nx_search_race.nx

nx_search_race.nx source

↩ module page · 255 lines · 10966 B

1// nx_search_race.nx -- IM6b: THE BEAT-FTS5 SEARCH RACE (the full-text-search 2// EXCEED measurement on the REAL unified team-log corpus). 3// 4// Two lanes, SAME input (pm_plan_durable.log + cap_registry_durable.log, 5// unique non-empty lines), SAME 9-query set (6 terms + 3 ANDs) x 200 6// iterations, each lane self-timing ONLY its engine work: 7// SOV lane: /tmp/nx_race_search_worker.sov.elf (chunked fsync'd commits 8// w/ .keys+.terms/.post; handle + postings queries) 9// FTS5 lane: python3 sqlite3 FTS5 (the incumbent full-text engine; run as 10// an EXTERNAL COMPETITOR PROCESS, harness .py written to /tmp at 11// runtime -- the repo stays pure NishiLang) 12// 13// Verdict law: numbers are MEASURED and logged win or lose; every per-query 14// COUNT must match between lanes or the race is INVALID (correctness before 15// speed). Exit 0 only on SOV-WINS-BOTH. Durable: infomgmt_race.log. 16// license_tier: ORIGINAL 17 18import "nx_syscalls.nx" 19import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 20const K_MAGIC_8192: i64 = 8192 21const K_MAGIC_8000: i64 = 8000 22 23func sx_p(s: *u8) -> i64 { 24 var n: i64 = 0 25 while s[n] != (0 as u8) { n = n + 1 } 26 sys_write(1, s, n) 27 return 0 28} 29 30func sx_fp(fd: i64, s: *u8) -> i64 { 31 var n: i64 = 0 32 while s[n] != (0 as u8) { n = n + 1 } 33 sys_write(fd, s, n) 34 return 0 35} 36 37// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 38// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 39// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 40// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 41func sx_fn(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 } 42 43func sx_cat(dst: *u8, off: i64, s: *u8) -> i64 { 44 var i: i64 = 0 45 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 } 46 return off + i 47} 48 49func sx_catn(dst: *u8, off: i64, v: i64) -> i64 { 50 var m: i64 = v 51 var o: i64 = off 52 let t: *u8 = sys_mmap(28) 53 var k: i64 = 0 54 if m == 0 { t[0] = 48 as u8; k = 1 } 55 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 56 var i: i64 = 0 57 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 } 58 return o + k 59} 60 61func sx_run(path: *u8, a1: *u8, a2: *u8, a3: *u8, outpath: *u8) -> i64 { 62 let pid: i64 = sys_fork() 63 if pid == 0 { 64 let ofd: i64 = sys_openat_wr(outpath, 0x1a4) 65 if ofd >= 0 { sys_dup3(ofd, 1, 0) } 66 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 67 if dn >= 0 { sys_dup3(dn, 2, 0) } 68 let argv: *i64 = sys_mmap(8 * 6) as *i64 69 argv[0] = path as i64 70 var na: i64 = 1 71 if (a1 as i64) != 0 { argv[na] = a1 as i64; na = na + 1 } 72 if (a2 as i64) != 0 { argv[na] = a2 as i64; na = na + 1 } 73 if (a3 as i64) != 0 { argv[na] = a3 as i64; na = na + 1 } 74 argv[na] = 0 75 let envp: *i64 = sys_mmap(16) as *i64 76 envp[0] = 0 77 sys_execve(path, argv, envp) 78 sys_exit(127) 79 } 80 let st: *i64 = sys_mmap(16) as *i64 81 sys_wait4(pid, st, 0) 82 return st[0] 83} 84 85func sx_num_after(path: *u8, pat: *u8) -> i64 { 86 let fd: i64 = sys_openat_rd(path) 87 if fd < 0 { return 0 - 1 } 88 let b: *u8 = sys_mmap(K_MAGIC_8192) 89 let n: i64 = sys_read(fd, b, K_MAGIC_8000) 90 sys_close(fd) 91 if n <= 0 { return 0 - 1 } 92 var pl: i64 = 0 93 while pat[pl] != (0 as u8) { pl = pl + 1 } 94 var i: i64 = 0 95 while i + pl <= n { 96 var hit: i64 = 1 97 var k: i64 = 0 98 while k < pl { 99 if hit == 1 { if b[i + k] != pat[k] { hit = 0 } } 100 k = k + 1 101 } 102 if hit == 1 { 103 var v: i64 = 0 104 var p: i64 = i + pl 105 var any: i64 = 0 106 var go: i64 = 1 107 while go == 1 { 108 if p >= n { go = 0 } 109 if go == 1 { 110 let c: i64 = b[p] 111 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); any = 1; p = p + 1 } else { go = 0 } } else { go = 0 } 112 } 113 } 114 if any == 1 { return v } 115 return 0 - 1 116 } 117 i = i + 1 118 } 119 return 0 - 1 120} 121 122// the FTS5 competitor harness (.py) -- /tmp only, never the repo 123func sx_write_py(path: *u8) -> i64 { 124 let fd: i64 = sys_openat_wr(path, 0x1a4) 125 if fd < 0 { return 0 - 1 } 126 sx_fp(fd, "import sqlite3, time, sys\n" as *u8) 127 sx_fp(fd, "mode=sys.argv[1]; db=sys.argv[2]\n" as *u8) 128 sx_fp(fd, "docs=[]; seen=set()\n" as *u8) 129 sx_fp(fd, "for f in ('knowledge/status/pm_plan_durable.log','knowledge/status/cap_registry_durable.log'):\n" as *u8) 130 sx_fp(fd, " for L in open(f, encoding='utf-8', errors='replace'):\n" as *u8) 131 sx_fp(fd, " L=L.rstrip('\\n')\n" as *u8) 132 sx_fp(fd, " if L=='' or L in seen: continue\n" as *u8) 133 sx_fp(fd, " seen.add(L); docs.append(L)\n" as *u8) 134 sx_fp(fd, "QT=['infomgmt','compaction','postings','sovereign','capreg','gate']\n" as *u8) 135 sx_fp(fd, "QA=[('infomgmt','postings'),('sovereign','gate'),('compaction','archive')]\n" as *u8) 136 sx_fp(fd, "if mode=='write':\n" as *u8) 137 sx_fp(fd, " t0=time.monotonic_ns()\n" as *u8) 138 sx_fp(fd, " c=sqlite3.connect(db)\n" as *u8) 139 sx_fp(fd, " c.execute('CREATE VIRTUAL TABLE docs USING fts5(line)')\n" as *u8) 140 sx_fp(fd, " cur=c.cursor()\n" as *u8) 141 sx_fp(fd, " for d in docs: cur.execute('INSERT INTO docs VALUES(?)',(d,))\n" as *u8) 142 sx_fp(fd, " c.commit(); c.close()\n" as *u8) 143 sx_fp(fd, " t1=time.monotonic_ns()\n" as *u8) 144 sx_fp(fd, " print('SQLW us=%d count=%d' % ((t1-t0)//1000, len(docs)))\n" as *u8) 145 sx_fp(fd, "else:\n" as *u8) 146 sx_fp(fd, " t0=time.monotonic_ns()\n" as *u8) 147 sx_fp(fd, " c=sqlite3.connect(db)\n" as *u8) 148 sx_fp(fd, " qc=[0]*9\n" as *u8) 149 sx_fp(fd, " for it in range(200):\n" as *u8) 150 sx_fp(fd, " for i,t in enumerate(QT):\n" as *u8) 151 sx_fp(fd, " qc[i]=c.execute('SELECT count(*) FROM docs WHERE docs MATCH ?',(t,)).fetchone()[0]\n" as *u8) 152 sx_fp(fd, " for i,(a,b) in enumerate(QA):\n" as *u8) 153 sx_fp(fd, " qc[6+i]=c.execute('SELECT count(*) FROM docs WHERE docs MATCH ?',(a+' AND '+b,)).fetchone()[0]\n" as *u8) 154 sx_fp(fd, " c.close()\n" as *u8) 155 sx_fp(fd, " t1=time.monotonic_ns()\n" as *u8) 156 sx_fp(fd, " print('SQLQ us=%d %s count=%d' % ((t1-t0)//1000, ' '.join('q%d=%d'%(i,v) for i,v in enumerate(qc)), len(docs)))\n" as *u8) 157 sys_close(fd) 158 return 0 159} 160 161func main() -> i64 { 162 sx_p("=== IM6b SEARCH RACE: sovereign postings vs sqlite FTS5 (team-log corpus, 9 queries x 200) ===\n" as *u8) 163 let wpath: *u8 = "/tmp/nx_race_search_worker.sov.elf" as *u8 164 let probe: i64 = sys_openat_rd(wpath) 165 if probe >= 0 { sys_close(probe) } else { 166 sx_run("_offc/nx_sov_build_run.elf" as *u8, "nx_race_search_worker" as *u8, 0 as *u8, 0 as *u8, "/tmp/srace_build.out" as *u8) 167 } 168 169 let id: i64 = sys_now_us() 170 let sovpfx: *u8 = sys_mmap(128) 171 var o: i64 = 0 172 o = sx_cat(sovpfx, o, "/tmp/srsov" as *u8) 173 o = sx_catn(sovpfx, o, id) 174 o = sx_cat(sovpfx, o, "-" as *u8) 175 sovpfx[o] = 0 as u8 176 let dbp: *u8 = sys_mmap(128) 177 o = 0 178 o = sx_cat(dbp, o, "/tmp/srsql" as *u8) 179 o = sx_catn(dbp, o, id) 180 o = sx_cat(dbp, o, ".db" as *u8) 181 dbp[o] = 0 as u8 182 183 if sx_write_py("/tmp/srace_fts5.py" as *u8) != 0 { sx_p(" py harness write FAILED\n" as *u8); return 1 } 184 185 sx_run(wpath, "write" as *u8, sovpfx, 0 as *u8, "/tmp/srace_sw.out" as *u8) 186 sx_run(wpath, "query" as *u8, sovpfx, 0 as *u8, "/tmp/srace_sq.out" as *u8) 187 let py: *u8 = "/usr/bin/python3" as *u8 188 sx_run(py, "/tmp/srace_fts5.py" as *u8, "write" as *u8, dbp, "/tmp/srace_qw.out" as *u8) 189 sx_run(py, "/tmp/srace_fts5.py" as *u8, "query" as *u8, dbp, "/tmp/srace_qq.out" as *u8) 190 191 let sw: i64 = sx_num_after("/tmp/srace_sw.out" as *u8, "SOVW us=" as *u8) 192 let swc: i64 = sx_num_after("/tmp/srace_sw.out" as *u8, "count=" as *u8) 193 let sq: i64 = sx_num_after("/tmp/srace_sq.out" as *u8, "SOVQ us=" as *u8) 194 let sqc: i64 = sx_num_after("/tmp/srace_sq.out" as *u8, "count=" as *u8) 195 let qw: i64 = sx_num_after("/tmp/srace_qw.out" as *u8, "SQLW us=" as *u8) 196 let qwc: i64 = sx_num_after("/tmp/srace_qw.out" as *u8, "count=" as *u8) 197 let qq: i64 = sx_num_after("/tmp/srace_qq.out" as *u8, "SQLQ us=" as *u8) 198 let qqc: i64 = sx_num_after("/tmp/srace_qq.out" as *u8, "count=" as *u8) 199 200 // per-query correctness cross-check (q0..q8 must match pairwise) 201 var counts_ok: i64 = 0 202 if swc > 0 { if swc == sqc { if swc == qwc { if swc == qqc { counts_ok = 1 } } } } 203 let pat: *u8 = sys_mmap(16) 204 var qi: i64 = 0 205 while qi < 9 { 206 var po: i64 = 0 207 po = sx_cat(pat, po, "q" as *u8) 208 po = sx_catn(pat, po, qi) 209 po = sx_cat(pat, po, "=" as *u8) 210 pat[po] = 0 as u8 211 let a: i64 = sx_num_after("/tmp/srace_sq.out" as *u8, pat) 212 let b: i64 = sx_num_after("/tmp/srace_qq.out" as *u8, pat) 213 if a < 0 { counts_ok = 0 } 214 if a != b { counts_ok = 0 } 215 qi = qi + 1 216 } 217 var win_w: i64 = 0 218 if sw >= 0 { if qw >= 0 { if sw <= qw { win_w = 1 } } } 219 var win_q: i64 = 0 220 if sq >= 0 { if qq >= 0 { if sq <= qq { win_q = 1 } } } 221 222 let lfd: i64 = sys_openat_append("knowledge/status/infomgmt_race.log" as *u8, 0x1a4) 223 var fdi: i64 = 0 224 while fdi < 2 { 225 var fd: i64 = 1 226 if fdi == 1 { fd = lfd } 227 if fd > 0 { 228 sx_fp(fd, "RACE epoch=" as *u8) 229 sx_fn(fd, sys_now_realtime_sec()) 230 sx_fp(fd, " workload=logsearch docs=" as *u8) 231 sx_fn(fd, swc) 232 sx_fp(fd, " sov_index_us=" as *u8) 233 sx_fn(fd, sw) 234 sx_fp(fd, " fts5_index_us=" as *u8) 235 sx_fn(fd, qw) 236 sx_fp(fd, " sov_query_us=" as *u8) 237 sx_fn(fd, sq) 238 sx_fp(fd, " fts5_query_us=" as *u8) 239 sx_fn(fd, qq) 240 sx_fp(fd, " counts_ok=" as *u8) 241 sx_fn(fd, counts_ok) 242 if counts_ok == 1 { 243 if win_w == 1 { if win_q == 1 { sx_fp(fd, " verdict=SOV-WINS-BOTH\n" as *u8) } } 244 if win_w == 1 { if win_q == 0 { sx_fp(fd, " verdict=MIXED-QUERY-LOSS (optimization rung: bitpack/FST dict + segment merge)\n" as *u8) } } 245 if win_w == 0 { if win_q == 1 { sx_fp(fd, " verdict=MIXED-INDEX-LOSS (optimization rung: single-segment bulk build + batch fsync)\n" as *u8) } } 246 if win_w == 0 { if win_q == 0 { sx_fp(fd, " verdict=SOV-LOSES-BOTH (file defect: slow is a bug)\n" as *u8) } } 247 } 248 if counts_ok != 1 { sx_fp(fd, " verdict=INVALID (counts disagree -- correctness before speed)\n" as *u8) } 249 } 250 fdi = fdi + 1 251 } 252 if lfd > 0 { sys_close(lfd) } 253 if counts_ok == 1 { if win_w == 1 { if win_q == 1 { return 0 } } } 254 return 1 255}