code wiki / (root) / nx_nofloat_moe_gate.nx

nx_nofloat_moe_gate.nx source

↩ module page · 285 lines · 11364 B

1// nx_nofloat_moe_gate.nx -- gates the no-float MoE FFN layer (MoE rung 1, 2026-07-15). The lib does 2// router -> deterministic top-K -> fx_exp softmax -> K SwiGLU experts -> weighted mix, all Q16 integer. 3// Teeth (every one deterministic; an INDEPENDENT serial reference implementation lives in THIS file with 4// REVERSED reduction orders -- exact integer sums are order-free, so lib and reference must agree to the BIT): 5// T1 EXACT vs the independent reverse-order reference on 3 distinct inputs (0 mismatched cells) 6// T2 determinism: repeat call byte-identical (and T1's order-reversal already proves order-invariance) 7// T3 sparsity REAL + router alive: exactly K experts computed per forward (cnt), >=2 distinct experts 8// selected across the 3 inputs (the router discriminates; selections logged) 9// T4 NEG-CONTROLS: (a) corrupting one router row CHANGES a selection (routing is weight-driven, not 10// fabricated); (b) dense K=E output DIFFERS from sparse K=2 (sparsity has measurable effect) 11// T5 work happened: >= half the output cells nonzero on every input 12// Synthetic Q16 weights/inputs from a fixed integer formula (no randomness, no clock). Runs in ms. 13// expect_exit: 0 license_tier: ORIGINAL No hw writes (Rule 26). 14import "nx_syscalls.nx" 15import "nx_nofloat_moe.nx" 16import "nx_gate_verdict.nx" 17 18func mg_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 19func mg_n(v: i64) -> i64 { 20 var m: i64 = v 21 if m < 0 { mg_w("-" as *u8); m = 0 - m } 22 let t: *u8 = sys_mmap(24) 23 var k: i64 = 0 24 if m == 0 { t[0] = 48 as u8; k = 1 } 25 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 26 let o: *u8 = sys_mmap(24) 27 var i: i64 = 0 28 while i < k { o[i] = t[k - 1 - i]; i = i + 1 } 29 sys_write(1, o, k) 30 return 0 31} 32// deterministic synthetic Q16 value in [-4095, 4095] (~ +-0.0625) 33func mg_det(i: i64) -> i64 { return ((i * 2654435761) % 8191) - 4095 } 34 35// ---- INDEPENDENT serial reference (reverse-order reductions everywhere) ---- 36func mg_ref_dot_rev(a: *i64, W: *i64, o: i64, ind: i64) -> i64 { 37 var s: i64 = 0 38 var k: i64 = ind - 1 39 while k >= 0 { s = s + (a[k] * W[o*ind + k]); k = k - 1 } 40 return s >> 16 41} 42func mg_ref_forward(mp: *i64) -> i64 { 43 let x: *i64 = mp[0] as *i64 44 let Wr: *i64 = mp[1] as *i64 45 let Wg: *i64 = mp[2] as *i64 46 let Wu: *i64 = mp[3] as *i64 47 let Wd: *i64 = mp[4] as *i64 48 let out: *i64 = mp[5] as *i64 49 let D: i64 = mp[6] 50 let H: i64 = mp[7] 51 let E: i64 = mp[8] 52 let K: i64 = mp[9] 53 let cnt: *i64 = mp[10] as *i64 54 let scr: *i64 = mp[11] as *i64 55 let r: *i64 = scr 56 let sel: *i64 = ((scr as i64) + E*8) as *i64 57 let w: *i64 = ((sel as i64) + K*8) as *i64 58 let g: *i64 = ((w as i64) + K*8) as *i64 59 let u2: *i64 = ((g as i64) + H*8) as *i64 60 let h: *i64 = ((u2 as i64) + H*8) as *i64 61 let eo: *i64 = ((h as i64) + H*8) as *i64 62 var e: i64 = E - 1 63 while e >= 0 { r[e] = mg_ref_dot_rev(x, Wr, e, D); e = e - 1 } 64 var ki: i64 = 0 65 while ki < K { 66 var best: i64 = 0 - 1 67 var bestv: i64 = 0 68 e = 0 69 while e < E { 70 var taken: i64 = 0 71 var t: i64 = 0 72 while t < ki { if sel[t] == e { taken = 1 } t = t + 1 } 73 if taken == 0 { if best < 0 { best = e; bestv = r[e] } else { if r[e] > bestv { best = e; bestv = r[e] } } } 74 e = e + 1 75 } 76 sel[ki] = best 77 ki = ki + 1 78 } 79 var m: i64 = r[sel[0]] 80 var i: i64 = 1 81 while i < K { if r[sel[i]] > m { m = r[sel[i]] } i = i + 1 } 82 var sum: i64 = 0 83 i = 0 84 while i < K { let ev: i64 = fx_exp(r[sel[i]] - m); w[i] = ev; sum = sum + ev; i = i + 1 } 85 if sum < 1 { sum = 1 } 86 i = 0 87 while i < K { w[i] = (w[i] << 16) / sum; i = i + 1 } 88 var d: i64 = 0 89 while d < D { out[d] = 0; d = d + 1 } 90 i = K - 1 91 while i >= 0 { 92 let e2: i64 = sel[i] 93 cnt[e2] = cnt[e2] + 1 94 var j: i64 = H - 1 95 while j >= 0 { 96 g[j] = mg_ref_dot_rev(x, ((Wg as i64) + e2*H*D*8) as *i64, j, D) 97 u2[j] = mg_ref_dot_rev(x, ((Wu as i64) + e2*H*D*8) as *i64, j, D) 98 h[j] = qmul(silu(g[j]), u2[j]) 99 j = j - 1 100 } 101 d = D - 1 102 while d >= 0 { eo[d] = mg_ref_dot_rev(h, ((Wd as i64) + e2*D*H*8) as *i64, d, H); d = d - 1 } 103 d = 0 104 while d < D { out[d] = out[d] + qmul(w[i], eo[d]); d = d + 1 } 105 i = i - 1 106 } 107 return 0 108} 109 110func main() -> i64 { 111 mg_w("=== NX-NOFLOAT-MOE -- integer Mixture-of-Experts FFN: router -> top-K -> sparse SwiGLU mix ===\n" as *u8) 112 let D: i64 = 32 113 let H: i64 = 64 114 let E: i64 = 4 115 let K: i64 = 2 116 let Wr: *i64 = sys_mmap(E*D*8) as *i64 117 let Wg: *i64 = sys_mmap(E*H*D*8) as *i64 118 let Wu: *i64 = sys_mmap(E*H*D*8) as *i64 119 let Wd: *i64 = sys_mmap(E*D*H*8) as *i64 120 var i: i64 = 0 121 while i < E*D { Wr[i] = mg_det(i + 1000); i = i + 1 } 122 i = 0 123 while i < E*H*D { Wg[i] = mg_det(i + 2000); Wu[i] = mg_det(i + 3000); i = i + 1 } 124 i = 0 125 while i < E*D*H { Wd[i] = mg_det(i + 4000); i = i + 1 } 126 let xA: *i64 = sys_mmap(D*8) as *i64 127 let xB: *i64 = sys_mmap(D*8) as *i64 128 let xC: *i64 = sys_mmap(D*8) as *i64 129 i = 0 130 while i < D { xA[i] = mg_det(i + 7); xB[i] = mg_det(i*3 + 77); xC[i] = mg_det(i*5 + 777); i = i + 1 } 131 let out1: *i64 = sys_mmap(D*8) as *i64 132 let out2: *i64 = sys_mmap(D*8) as *i64 133 let scr1: *i64 = sys_mmap((E + 2*K + 3*H + D + 16)*8) as *i64 134 let scr2: *i64 = sys_mmap((E + 2*K + 3*H + D + 16)*8) as *i64 135 let cnt1: *i64 = sys_mmap(E*8) as *i64 136 let cnt2: *i64 = sys_mmap(E*8) as *i64 137 let mp: *i64 = sys_mmap(16*8) as *i64 138 mp[1] = Wr as i64 139 mp[2] = Wg as i64 140 mp[3] = Wu as i64 141 mp[4] = Wd as i64 142 mp[6] = D 143 mp[7] = H 144 mp[8] = E 145 mp[9] = K 146 147 // ---- T1: lib vs independent reverse-order reference, 3 inputs, exact ---- 148 var mism: i64 = 0 149 var nz_fail: i64 = 0 150 var usedmask: i64 = 0 151 var qi: i64 = 0 152 while qi < 3 { 153 var xp: *i64 = xA 154 if qi == 1 { xp = xB } 155 if qi == 2 { xp = xC } 156 var ci: i64 = 0 157 while ci < E { cnt1[ci] = 0; cnt2[ci] = 0; ci = ci + 1 } 158 mp[0] = xp as i64 159 mp[5] = out1 as i64 160 mp[10] = cnt1 as i64 161 mp[11] = scr1 as i64 162 nmoe_forward(mp) 163 mp[5] = out2 as i64 164 mp[10] = cnt2 as i64 165 mp[11] = scr2 as i64 166 mg_ref_forward(mp) 167 var d: i64 = 0 168 var nz: i64 = 0 169 while d < D { if out1[d] != out2[d] { mism = mism + 1 } if out1[d] != 0 { nz = nz + 1 } d = d + 1 } 170 if nz < D/2 { nz_fail = nz_fail + 1 } 171 // per-call sparsity: exactly K experts computed; accumulate the union mask; log the selection 172 var kc: i64 = 0 173 ci = 0 174 mg_w(" Q" as *u8); mg_n(qi + 1); mg_w(" experts:" as *u8) 175 while ci < E { if cnt1[ci] > 0 { kc = kc + 1; usedmask = usedmask | (1 << ci); mg_w(" " as *u8); mg_n(ci) } ci = ci + 1 } 176 if kc != K { mism = mism + 1000000 } 177 mg_w(" (nz " as *u8); mg_n(nz); mg_w("/" as *u8); mg_n(D); mg_w(")\n" as *u8) 178 qi = qi + 1 179 } 180 // distinct experts used across inputs 181 var distinct: i64 = 0 182 i = 0 183 while i < E { if (usedmask & (1 << i)) != 0 { distinct = distinct + 1 } i = i + 1 } 184 185 // ---- T2: repeat call byte-identical ---- 186 var ci2: i64 = 0 187 while ci2 < E { cnt1[ci2] = 0; ci2 = ci2 + 1 } 188 mp[0] = xA as i64 189 mp[5] = out2 as i64 190 mp[10] = cnt1 as i64 191 mp[11] = scr1 as i64 192 nmoe_forward(mp) 193 mp[5] = out1 as i64 194 nmoe_forward(mp) 195 var rep_mism: i64 = 0 196 var d2: i64 = 0 197 while d2 < D { if out1[d2] != out2[d2] { rep_mism = rep_mism + 1 } d2 = d2 + 1 } 198 199 // ---- T4a: corrupt router row 0 (negate) -> some selection must change ---- 200 let Wr2: *i64 = sys_mmap(E*D*8) as *i64 201 i = 0 202 while i < E*D { Wr2[i] = Wr[i]; i = i + 1 } 203 i = 0 204 while i < D { Wr2[i] = 0 - Wr2[i]; i = i + 1 } 205 var sel_changed: i64 = 0 206 qi = 0 207 while qi < 3 { 208 var xp2: *i64 = xA 209 if qi == 1 { xp2 = xB } 210 if qi == 2 { xp2 = xC } 211 var ci3: i64 = 0 212 while ci3 < E { cnt1[ci3] = 0; cnt2[ci3] = 0; ci3 = ci3 + 1 } 213 mp[0] = xp2 as i64 214 mp[5] = out1 as i64 215 mp[10] = cnt1 as i64 216 mp[11] = scr1 as i64 217 mp[1] = Wr as i64 218 nmoe_forward(mp) 219 mp[1] = Wr2 as i64 220 mp[5] = out2 as i64 221 mp[10] = cnt2 as i64 222 nmoe_forward(mp) 223 var ci4: i64 = 0 224 while ci4 < E { if cnt1[ci4] != cnt2[ci4] { sel_changed = 1 } ci4 = ci4 + 1 } 225 qi = qi + 1 226 } 227 mp[1] = Wr as i64 228 229 // ---- T4b: dense (K=E) differs from sparse (K=2) ---- 230 var ci5: i64 = 0 231 while ci5 < E { cnt1[ci5] = 0; ci5 = ci5 + 1 } 232 mp[0] = xA as i64 233 mp[5] = out2 as i64 234 mp[10] = cnt1 as i64 235 mp[11] = scr1 as i64 236 mp[9] = E 237 nmoe_forward(mp) 238 mp[9] = K 239 mp[5] = out1 as i64 240 var ci6: i64 = 0 241 while ci6 < E { cnt2[ci6] = 0; ci6 = ci6 + 1 } 242 mp[10] = cnt2 as i64 243 nmoe_forward(mp) 244 var dense_diff: i64 = 0 245 d2 = 0 246 while d2 < D { if out1[d2] != out2[d2] { dense_diff = dense_diff + 1 } d2 = d2 + 1 } 247 248 // ---- teeth ---- 249 var pass: i64 = 0 250 var ttl: i64 = 0 251 ttl = ttl + 1 252 let ok1: i64 = (mism == 0) as i64 253 mg_w(" T1 lib == independent reverse-order reference, 3 inputs, exact (mism " as *u8); mg_n(mism); mg_w("): " as *u8) 254 if ok1 == 1 { pass = pass + 1; mg_w("PASS\n" as *u8) } else { mg_w("FAIL\n" as *u8) } 255 ttl = ttl + 1 256 let ok2: i64 = (rep_mism == 0) as i64 257 mg_w(" T2 repeat call byte-identical: " as *u8) 258 if ok2 == 1 { pass = pass + 1; mg_w("PASS\n" as *u8) } else { mg_w("FAIL\n" as *u8) } 259 ttl = ttl + 1 260 let ok3: i64 = (distinct >= 2) as i64 261 mg_w(" T3 sparsity real + router discriminates (distinct experts " as *u8); mg_n(distinct); mg_w("/" as *u8); mg_n(E); mg_w("): " as *u8) 262 if ok3 == 1 { pass = pass + 1; mg_w("PASS\n" as *u8) } else { mg_w("FAIL\n" as *u8) } 263 ttl = ttl + 1 264 let ok4a: i64 = (sel_changed == 1) as i64 265 let ok4b: i64 = (dense_diff > 0) as i64 266 let ok4: i64 = ok4a & ok4b 267 mg_w(" T4 NEG-CONTROLS: corrupted router changes selection=" as *u8); mg_n(sel_changed) 268 mg_w(", dense-vs-sparse differing cells=" as *u8); mg_n(dense_diff); mg_w(": " as *u8) 269 if ok4 == 1 { pass = pass + 1; mg_w("PASS\n" as *u8) } else { mg_w("FAIL\n" as *u8) } 270 ttl = ttl + 1 271 let ok5: i64 = (nz_fail == 0) as i64 272 mg_w(" T5 output transformed on every input: " as *u8) 273 if ok5 == 1 { pass = pass + 1; mg_w("PASS\n" as *u8) } else { mg_w("FAIL\n" as *u8) } 274 275 mg_w("NX-NOFLOAT-MOE-GATE passed " as *u8); mg_n(pass); mg_w("/" as *u8); mg_n(ttl) 276 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 277 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 278 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 279 let ctr__dry: *i64 = gv_ctr() 280 ctr__dry[0] = pass 281 ctr__dry[1] = ttl 282 let rc__dry: i64 = gv_verdict("NOFLOAT-MOE-GATE" as *u8, ctr__dry, "sparse MoE FFN runs in deterministic integer: router routes, K of E compute, mix exact)" as *u8) 283 sys_exit(rc__dry) 284 return rc__dry 285}