code wiki / _hdl_build / nx_faithdiff.nx
nx_faithdiff.nx source
↩ module page · 182 lines · 10644 B
1// nx_faithdiff.nx -- THE WAT-FAITHFULNESS DIFFERENTIAL DEBUGGER (operator 2026-07-06: "build the tool that
2// can troubleshoot this in one step in <10s so we can eat the debt and grow"). ONE command:
3// nx_sov_build_run nx_faithdiff
4// It (1) compiles nx_faithdiff_probe.nx -> wasm via the two sovereign compilers, (2) loads it in the
5// sovereign wasm-VM, (3) runs EACH probe function in the VM AND natively over an input battery, (4) reports
6// the FIRST function+input where VM != native. That pin is the exact WAT-lowering (or VM-interp) bug --
7// no more manual bisect-by-rebuild. To debug any new module: paste its suspect funcs into the probe + run.
8// license_tier: ORIGINAL
9import "nx_syscalls.nx"
10import "nx_wasm_vm.nx"
11import "nx_faithdiff_probe.nx" // the SAME functions, compiled NATIVE (the authority)
12const K_MAGIC_262144: i64 = 262144
13const K_MAGIC_65535: i64 = 65535
14
15const CWAT: *u8 = "/tmp/nx_compile_wat.sov.elf"
16const WATC: *u8 = "/tmp/nx_wat_compiler.sov.elf"
17const SRC: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/runtime/_hdl_build/nx_faithdiff_probe.nx"
18const WAT: *u8 = "/tmp/nx_faithdiff_probe.wat"
19const WASM: *u8 = "/tmp/nx_faithdiff_probe.wasm"
20
21func fw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
22func fn(v: i64) -> i64 {
23 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m}
24 let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}
25 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 }
26
27func run_elf(elf: *u8, a1: *u8, a2: *u8) -> i64 {
28 let pid: i64 = sys_fork()
29 if pid == 0 {
30 let argv: *i64 = sys_mmap(64) as *i64
31 argv[0] = elf as i64; var ai: i64 = 1
32 if (a1 as i64) != 0 { argv[ai] = a1 as i64; ai = ai + 1 }
33 if (a2 as i64) != 0 { argv[ai] = a2 as i64; ai = ai + 1 }
34 argv[ai] = 0
35 let envp: *i64 = sys_mmap(16) as *i64; envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0
36 sys_execve(elf, argv, envp); sys_exit(127)
37 }
38 let st: *i64 = sys_mmap(16) as *i64; sys_wait4(pid, st, 0)
39 return (st[0] >> 8) & 0xff }
40
41// realistic block content (gradient + edge + texture) matching the codec's actual frames -- so the MAD test
42// hits the same division/accumulation values the real encode does, not just uniform noise.
43func fill_block(cur: *u8, seed: i64) -> i64 {
44 var i: i64 = 0
45 while i < 256 {
46 let x: i64 = i & 15; let y: i64 = i >> 4
47 var v: i64 = (x + y) * 7 + (seed & 63)
48 if x > 7 { v = v + 60 }
49 v = v + ((x * y) % 5) * 9 + ((seed * (i + 1)) / 16 & 15)
50 if v < 0 { v = 0 } if v > 255 { v = 255 }
51 cur[i] = v as u8; i = i + 1 }
52 return 0 }
53
54func main() -> i64 {
55 fw("=== nx_faithdiff: WAT-faithfulness differential (VM vs native, per function) ===\n" as *u8)
56 let probe: i64 = sys_openat_rd(CWAT)
57 if probe < 0 { fw(" build compilers first: nx_sov_build_run nx_compile_wat --build-only + nx_wat_compiler --build-only\n" as *u8); sys_exit(2); return 2 }
58 sys_close(probe)
59 fw(" [1] .nx -> .wat -> .wasm ..." as *u8)
60 run_elf(CWAT, SRC, WAT); run_elf(WATC, WAT, WASM)
61 let box: *i64 = sys_mmap(16) as *i64
62 let wasm: *u8 = sys_read_file(WASM, box)
63 if (wasm as i64) == 0 { fw(" FAIL read wasm\n" as *u8); sys_exit(3); return 3 }
64 fw(" wasm=" as *u8); fn(box[0]); fw("B\n" as *u8)
65 let mod: *WasmMod = wm_new(wasm, box[0])
66 if wm_parse(mod) != 0 { fw(" FAIL wasm parse\n" as *u8); sys_exit(4); return 4 }
67 mod.mem = sys_mmap(K_MAGIC_262144) as *u8 // 256K: room for the full-codec roundtrip buffers at RTBASE
68
69 var fails: i64 = 0
70
71 // ---- vc_aq_level (1 arg) ----
72 fw(" [vc_aq_level] " as *u8)
73 let mads: *i64 = sys_mmap(8*12) as *i64
74 mads[0]=0; mads[1]=3; mads[2]=4; mads[3]=9; mads[4]=10; mads[5]=21; mads[6]=22; mads[7]=50; mads[8]=100; mads[9]=255; let nm: i64=10
75 var li: i64=0; var lbad: i64=0
76 while li < nm {
77 let nat: i64 = vc_aq_level(mads[li])
78 let vm: i64 = wm_run(mod, "vc_aq_level" as *u8, mads[li], 0, 0, 0, 0, 1)
79 if nat != vm { lbad=1; fw("\n DIVERGE mad=" as *u8); fn(mads[li]); fw(" native=" as *u8); fn(nat); fw(" VM=" as *u8); fn(vm) }
80 li = li + 1 }
81 if lbad==1 { fw("\n -> vc_aq_level UNFAITHFUL\n" as *u8); fails=fails+1 } else { fw("faithful\n" as *u8) }
82
83 // ---- vc_aq_qp (2 args) ----
84 fw(" [vc_aq_qp] " as *u8)
85 let qps: *i64 = sys_mmap(8*8) as *i64; qps[0]=8; qps[1]=16; qps[2]=24; qps[3]=32; qps[4]=40; let nq: i64=5
86 var qbad: i64=0; var qi: i64=0
87 while qi < nq { var lv: i64=0
88 while lv < 4 {
89 let nat: i64 = vc_aq_qp(qps[qi], lv)
90 let vm: i64 = wm_run(mod, "vc_aq_qp" as *u8, qps[qi], lv, 0, 0, 0, 2)
91 if nat != vm { qbad=1; fw("\n DIVERGE qp=" as *u8); fn(qps[qi]); fw(" level=" as *u8); fn(lv); fw(" native=" as *u8); fn(nat); fw(" VM=" as *u8); fn(vm) }
92 lv = lv + 1 }
93 qi = qi + 1 }
94 if qbad==1 { fw("\n -> vc_aq_qp UNFAITHFUL\n" as *u8); fails=fails+1 } else { fw("faithful\n" as *u8) }
95
96 // ---- vc_mb_mad (pointer + 3 args): identical block native + in VM linear memory ----
97 fw(" [vc_mb_mad] " as *u8)
98 let natblk: *u8 = sys_mmap(256)
99 let seeds: *i64 = sys_mmap(8*8) as *i64; seeds[0]=1; seeds[1]=7; seeds[2]=42; seeds[3]=200; seeds[4]=1000; seeds[5]=K_MAGIC_65535; let ns: i64=6
100 var mbad: i64=0; var si: i64=0
101 while si < ns {
102 fill_block(natblk, seeds[si])
103 var c: i64=0; while c < 256 { mod.mem[c] = natblk[c]; c = c + 1 } // copy the SAME block into VM memory at offset 0
104 let nat: i64 = vc_mb_mad(natblk, 16, 0, 0)
105 let vm: i64 = wm_run(mod, "vc_mb_mad" as *u8, 0, 16, 0, 0, 0, 4) // cur=offset 0
106 if nat != vm { mbad=1; fw("\n DIVERGE seed=" as *u8); fn(seeds[si]); fw(" native=" as *u8); fn(nat); fw(" VM=" as *u8); fn(vm) }
107 si = si + 1 }
108 if mbad==1 { fw("\n -> vc_mb_mad UNFAITHFUL\n" as *u8); fails=fails+1 } else { fw("faithful\n" as *u8) }
109
110 // ---- fd_tile (2 args): the tfy-unpack + variable-compare pattern from the block loop ----
111 fw(" [fd_tile] " as *u8)
112 var tbad: i64=0; var tfy2: i64=0
113 while tfy2 < 4 { var sy2: i64=0
114 while sy2 < 40 {
115 let nat: i64 = fd_tile(tfy2, sy2)
116 let vm: i64 = wm_run(mod, "fd_tile" as *u8, tfy2, sy2, 0, 0, 0, 2)
117 if nat != vm { tbad=1; fw("\n DIVERGE tfy=" as *u8); fn(tfy2); fw(" sy=" as *u8); fn(sy2); fw(" native=" as *u8); fn(nat); fw(" VM=" as *u8); fn(vm) }
118 sy2 = sy2 + 8 }
119 tfy2 = tfy2 + 1 }
120 if tbad==1 { fw("\n -> fd_tile (tfy/ytop compare) UNFAITHFUL\n" as *u8); fails=fails+1 } else { fw("faithful\n" as *u8) }
121
122 // ---- fd_roundtrip: the FULL codec encode->decode (AQ+tile+deblock+transform+entropy), VM vs native ----
123 fw(" [fd_roundtrip] " as *u8)
124 let RTBASE: i64 = 0x20000
125 let natbase: *u8 = sys_mmap(K_MAGIC_262144)
126 var rbad: i64=0; var rs: i64=0
127 while rs < 5 {
128 let sd: i64 = rs*97 + 13
129 let nat: i64 = fd_roundtrip(natbase as i64, sd)
130 let vm: i64 = wm_run(mod, "fd_roundtrip" as *u8, RTBASE, sd, 0, 0, 0, 2)
131 if nat != vm { rbad=1; fw("\n DIVERGE seed=" as *u8); fn(sd); fw(" native=" as *u8); fn(nat); fw(" VM=" as *u8); fn(vm) }
132 rs = rs + 1 }
133 if rbad==1 { fw("\n -> FULL-CODEC roundtrip UNFAITHFUL\n" as *u8); fails=fails+1 } else { fw("faithful (full encode->decode VM==native)\n" as *u8) }
134
135 // ---- fd_band_roundtrip: the TILE-PARALLEL band path, VM vs native ----
136 fw(" [fd_band] " as *u8)
137 var bbad: i64=0; var bs: i64=0
138 while bs < 5 {
139 let sd: i64 = bs*61 + 7
140 let nat: i64 = fd_band_roundtrip(natbase as i64, sd)
141 let vm: i64 = wm_run(mod, "fd_band_roundtrip" as *u8, RTBASE, sd, 0, 0, 0, 2)
142 if nat != vm { bbad=1; fw("\n DIVERGE seed=" as *u8); fn(sd); fw(" native=" as *u8); fn(nat); fw(" VM=" as *u8); fn(vm) }
143 bs = bs + 1 }
144 if bbad==1 { fw("\n -> BAND (tile-parallel) roundtrip UNFAITHFUL\n" as *u8); fails=fails+1 } else { fw("faithful (banded encode->decode VM==native)\n" as *u8) }
145
146 // ---- fd_rc_roundtrip: the RANGE-CODED full frame (task #31), VM vs native ----
147 fw(" [fd_rc] " as *u8)
148 var rcbad: i64=0; var rcs: i64=0
149 while rcs < 5 {
150 let sd: i64 = rcs*53 + 11
151 let nat: i64 = fd_rc_roundtrip(natbase as i64, sd)
152 let vm: i64 = wm_run(mod, "fd_rc_roundtrip" as *u8, RTBASE, sd, 0, 0, 0, 2)
153 if nat != vm { rcbad=1; fw("\n DIVERGE seed=" as *u8); fn(sd); fw(" native=" as *u8); fn(nat); fw(" VM=" as *u8); fn(vm) }
154 rcs = rcs + 1 }
155 if rcbad==1 { fw("\n -> RANGE-CODED roundtrip UNFAITHFUL\n" as *u8); fails=fails+1 } else { fw("faithful (range encode->decode VM==native)\n" as *u8) }
156
157 // ---- fd_t8_roundtrip: VARIABLE-TRANSFORM key+P (task #46 rung 2, 8x8 intra+inter in the VM) ----
158 fw(" [fd_t8] " as *u8)
159 var t8bad: i64=0; var t8s: i64=0
160 while t8s < 5 {
161 let sd: i64 = t8s*41 + 5
162 let nat: i64 = fd_t8_roundtrip(natbase as i64, sd)
163 let vm: i64 = wm_run(mod, "fd_t8_roundtrip" as *u8, RTBASE, sd, 0, 0, 0, 2)
164 if nat != vm { t8bad=1; fw("\n DIVERGE seed=" as *u8); fn(sd); fw(" native=" as *u8); fn(nat); fw(" VM=" as *u8); fn(vm) }
165 t8s = t8s + 1 }
166 if t8bad==1 { fw("\n -> T8 (variable-transform) roundtrip UNFAITHFUL\n" as *u8); fails=fails+1 } else { fw("faithful (t8 key+P encode->decode VM==native)\n" as *u8) }
167
168 // ---- fd_rct8_roundtrip: RANGE + variable-transform composition ----
169 fw(" [fd_rct8] " as *u8)
170 var rt8bad: i64=0; var rt8s: i64=0
171 while rt8s < 5 {
172 let sd: i64 = rt8s*29 + 3
173 let nat: i64 = fd_rct8_roundtrip(natbase as i64, sd)
174 let vm: i64 = wm_run(mod, "fd_rct8_roundtrip" as *u8, RTBASE, sd, 0, 0, 0, 2)
175 if nat != vm { rt8bad=1; fw("\n DIVERGE seed=" as *u8); fn(sd); fw(" native=" as *u8); fn(nat); fw(" VM=" as *u8); fn(vm) }
176 rt8s = rt8s + 1 }
177 if rt8bad==1 { fw("\n -> RCT8 (range+t8) roundtrip UNFAITHFUL\n" as *u8); fails=fails+1 } else { fw("faithful (rct8 encode->decode VM==native)\n" as *u8) }
178
179 fw("=== FAITHDIFF: " as *u8); fn(fails); fw(" unfaithful function(s) ===\n" as *u8)
180 if fails==0 { fw(" all probe funcs VM==native -> the bug is in the INTEGRATION (wiring/signal order), not these funcs\n" as *u8); return 0 }
181 fw(" ^ THAT function is the WAT-lowering bug. Fix it (rewrite the op it mislowers) and re-run.\n" as *u8)
182 return 1 }