code wiki / _hdl_build / nx_ppmi_probe.nx

nx_ppmi_probe.nx source

↩ module page · 156 lines · 6250 B

1// nx_ppmi_probe.nx -- HONEST VERDICT on the SHIPPED knowledge/index/semppmi_v1.bin. 2// Loads the persisted 41MB PPMI model (built by nx_semppmi_build) and prints the real 3// probe cosines: cos(won,defeated) vs cos(won,purple), cos(city,stadium) vs cos(city,january). 4// This is the evidence gate for wiring the dense/semantic reranker over the REAL model: 5// both order -> GREEN (count-model carries the signal; dense reranker is wire-ready) 6// not both -> AMBER (count-model weak at this pair; trained thread may be required) 7// Reuses the PROVEN loader/cos format from nx_qabench.nx (ppmi_load/ppmi_cos), sem_isqrt 8// re-defined locally (it lives in the app layer, not the engine). 9// expect_exit: 0 license_tier: ORIGINAL 10import "nx_qabench_engine.nx" 11const K_MAGIC_4096: i64 = 4096 12const K_MAGIC_536870912: i64 = 536870912 13const K_MAGIC_262144: i64 = 262144 14 15// integer sqrt (Newton), copy of the app-layer helper 16func pb_isqrt(v: i64) -> i64 { 17 if v <= 0 { return 0 } 18 var x: i64 = v 19 var y: i64 = (x + 1) / 2 20 while y < x { x = y; let q: i64 = v / x; y = (x + q) / 2 } 21 return x 22} 23 24// g-slots: 70 blob,71 nv,72 nt,73 vh,74 ridx,75 nrm2,76 tctx,77 tval,78 loaded 25func pb_load(g: *i64) -> i64 { 26 g[78] = 0 27 let fd: i64 = sys_openat_rd("knowledge/index/semppmi_v1.bin" as *u8) 28 if fd < 0 { return 0 } 29 let hdrb: *u8 = sys_mmap(K_MAGIC_4096) 30 var hgot: i64 = 0 31 var hr: i64 = 1 32 while hr > 0 { if hgot >= 32 { hr = 0 } else { hr = sys_read(fd, (hdrb as i64 + hgot) as *u8, 32 - hgot); if hr > 0 { hgot = hgot + hr } } } 33 if hgot < 32 { sys_close(fd); return 0 } 34 let hh: *i64 = (hdrb as i64 + 8) as *i64 35 let hnv: i64 = hh[0] 36 let hnt: i64 = hh[1] 37 let need0: i64 = 32 + (hnv*8) + ((hnv+1)*8) + (hnv*8) + (hnt*8) + (hnt*8) 38 if need0 <= 32 { sys_close(fd); return 0 } 39 if need0 > K_MAGIC_536870912 { sys_close(fd); return 0 } 40 let cap: i64 = need0 + K_MAGIC_4096 41 let blob: *u8 = sys_mmap(cap) 42 var i0: i64 = 0 43 while i0 < 32 { blob[i0] = hdrb[i0]; i0 = i0 + 1 } 44 var total: i64 = 32 45 var r: i64 = 1 46 while r > 0 { 47 let left: i64 = need0 - total 48 if left <= 0 { r = 0 } else { 49 var want: i64 = K_MAGIC_262144 50 if want > left { want = left } 51 r = sys_read(fd, (blob as i64 + total) as *u8, want) 52 if r > 0 { total = total + r } 53 } 54 } 55 sys_close(fd) 56 if total < 64 { return 0 } 57 if blob[0] != (78 as u8) { return 0 } 58 if blob[6] != (49 as u8) { return 0 } 59 let hi: *i64 = (blob as i64 + 8) as *i64 60 let nv: i64 = hi[0] 61 let nt: i64 = hi[1] 62 let need: i64 = 32 + (nv*8) + ((nv+1)*8) + (nv*8) + (nt*8) + (nt*8) 63 if total < need { return 0 } 64 g[70] = blob as i64 65 g[71] = nv 66 g[72] = nt 67 var off: i64 = 32 68 g[73] = (blob as i64) + off; off = off + nv*8 69 g[74] = (blob as i64) + off; off = off + (nv+1)*8 70 g[75] = (blob as i64) + off; off = off + nv*8 71 g[76] = (blob as i64) + off; off = off + nt*8 72 g[77] = (blob as i64) + off 73 g[78] = 1 74 return 1 75} 76 77// cosine between two PPMI rows (sorted sparse merge), permille 78func pb_cos(g: *i64, a: i64, b: i64) -> i64 { 79 let ridx: *i64 = g[74] as *i64 80 let nrm2: *i64 = g[75] as *i64 81 let tctx: *i64 = g[76] as *i64 82 let tval: *i64 = g[77] as *i64 83 var ia: i64 = ridx[a] 84 var ib: i64 = ridx[b] 85 let ea: i64 = ridx[a+1] 86 let eb: i64 = ridx[b+1] 87 var dot: i64 = 0 88 while ia < ea { 89 if ib >= eb { ia = ea } else { 90 if tctx[ia] == tctx[ib] { dot = dot + tval[ia]*tval[ib]; ia = ia + 1; ib = ib + 1 } 91 else { if tctx[ia] < tctx[ib] { ia = ia + 1 } else { ib = ib + 1 } } 92 } 93 } 94 if dot <= 0 { return 0 } 95 let d1: i64 = pb_isqrt(nrm2[a]) 96 let d2: i64 = pb_isqrt(nrm2[b]) 97 if d1 == 0 { return 0 } 98 if d2 == 0 { return 0 } 99 var cv: i64 = (dot*1000)/(d1*d2) 100 if cv > 1000 { cv = 1000 } 101 return cv 102} 103 104// resolve a null-terminated word literal -> PPMI vocab id or -1 105func pb_wid(g: *i64, s: *u8) -> i64 { 106 var n: i64 = 0 107 while s[n] != (0 as u8) { n = n + 1 } 108 let hv: i64 = db_semhash(s, 0, n) 109 return db_bsearch_i64(g[73] as *i64, g[71], hv) 110} 111 112// -1 if either id missing from vocab 113func pb_safecos(g: *i64, a: i64, b: i64) -> i64 { 114 if a < 0 { return 0-1 } 115 if b < 0 { return 0-1 } 116 return pb_cos(g, a, b) 117} 118 119func main() -> i64 { 120 let g: *i64 = sys_mmap(128*8) as *i64 121 let ok: i64 = pb_load(g) 122 if ok == 0 { db_w("RED -- semppmi_v1.bin load failed\n" as *u8); return 1 } 123 db_w("MODEL loaded: vocab="); db_n(g[71]); db_w(" triples="); db_n(g[72]); db_w("\n" as *u8) 124 125 let won: i64 = pb_wid(g, "won" as *u8) 126 let def: i64 = pb_wid(g, "defeated" as *u8) 127 let pur: i64 = pb_wid(g, "purple" as *u8) 128 let cty: i64 = pb_wid(g, "city" as *u8) 129 let sta: i64 = pb_wid(g, "stadium" as *u8) 130 let jan: i64 = pb_wid(g, "january" as *u8) 131 db_w("ids: won="); db_n(won); db_w(" defeated="); db_n(def); db_w(" purple="); db_n(pur) 132 db_w(" city="); db_n(cty); db_w(" stadium="); db_n(sta); db_w(" january="); db_n(jan); db_w("\n" as *u8) 133 134 let p1: i64 = pb_safecos(g, won, def) 135 let p2: i64 = pb_safecos(g, won, pur) 136 let p3: i64 = pb_safecos(g, cty, sta) 137 let p4: i64 = pb_safecos(g, cty, jan) 138 db_w("PROBE1 cos(won,defeated)="); db_n(p1); db_w(" cos(won,purple)="); db_n(p2); db_w("\n" as *u8) 139 db_w("PROBE2 cos(city,stadium)="); db_n(p3); db_w(" cos(city,january)="); db_n(p4); db_w("\n" as *u8) 140 141 // identity sanity (a row vs itself should be 1000) 142 let idn: i64 = pb_safecos(g, won, won) 143 db_w("NEG identity cos(won,won)="); db_n(idn); db_w("\n" as *u8) 144 145 var ord1: i64 = 0 146 if p1 > p2 { ord1 = 1 } 147 var ord2: i64 = 0 148 if p3 > p4 { ord2 = 1 } 149 db_w("VERDICT ord1(defeated>purple)="); db_n(ord1); db_w(" ord2(stadium>january)="); db_n(ord2); db_w("\n" as *u8) 150 if ord1 == 1 { if ord2 == 1 { 151 db_w("GREEN -- PROBES ORDER: the real PPMI model carries semantic signal; dense reranker is WIRE-READY over the shipped model.\n" as *u8) 152 return 0 153 } } 154 db_w("AMBER -- probes do not both order; count-model signal weak at these pairs (trained thread may be required for the dense axis).\n" as *u8) 155 return 0 156}