nx_nofloat_w12a12_gate.nx source
↩ module page · 420 lines · 25794 B
1// nx_nofloat_w12a12_gate.nx -- the referee for the W12A12 decode matmul (search R0l attribution, 2026-09-16).
2//
3// SUBJECT: mm_pool_i8 in nx_nofloat_llm (the pooled SIMD matmul every decode projection goes through), driven
4// IN-PROCESS on synthetic data whose shape is the real one (in_dim 8960 = the Qwen2.5-1.5B ffn_down, the widest
5// projection, so the chunk bound is exercised at its limit) with activation OUTLIER channels planted, because a
6// per-tensor scale is exactly the quantiser an outlier defeats.
7// TEETH: the chunk bound is arithmetic (NF_CHUNK_K/8 * QMAX * QMAX <= i32 max) and 2048 is the planted bound-
8// breaker; the kernel's max relative error against the exact i64 dot is BELOW the old 8-bit per-tensor quantiser's
9// error on the same data (the old quantiser is re-implemented here as the CONTROL, so the improvement is measured,
10// never asserted); the kernel is exact on a row the quantisers cannot lose (all values on the grid); and the
11// chunked fold reproduces the unchunked sum on a short row (K < NF_CHUNK_K, one chunk).
12// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
13import "nx_syscalls.nx"
14import "nx_nofloat_llm.nx"
15import "nx_gate_verdict.nx"
16
17const WG_IN: i64 = 8960
18const WG_OUT: i64 = 64
19const WG_SHORT_IN: i64 = 896
20const WG_SEED: i64 = 20260916
21const WG_LCG_A: i64 = 6364136223846793005
22const WG_LCG_C: i64 = 1442695040888963407
23const WG_MASK63: i64 = 0x7FFFFFFFFFFFFFFF
24const WG_X_BODY: i64 = 65536 // typical Q16 activation magnitude (about 1.0)
25const WG_X_OUTLIER: i64 = 4194304 // 64x the body: the outlier channel every Qwen-class model carries
26const WG_OUTLIER_EVERY: i64 = 512
27const WG_W_MAG: i64 = 4096
28const WG_SHIFT: i64 = 16
29const WG_OLD_QMAX: i64 = 127
30const WG_PERMIL: i64 = 1000
31const WG_BREAKER_CHUNK: i64 = 2048
32// on-grid rows: x = j * WG_GRID_SX with |j| <= QMAX so max|x| = QMAX * WG_GRID_SX and the activation scale is EXACTLY
33// WG_GRID_SX (no floor slack, no clamp), and every weight row carries one WG_GRID_WMAX so its scale is exactly 1
34const WG_GRID_SX: i64 = 16
35const WG_GRID_SPAN: i64 = 8191 // 2*QMAX+1 values, j in [-4095, 4095]
36const WG_GRID_WMAX: i64 = 4095
37const WG_TAIL_IN: i64 = 912 // R0q: 14 x 64 + 16, a width whose last madd goes through the tail loop
38const WG_TIMING_REPS: i64 = 40 // R0q: repeats per task for the printed throughput values
39const WG_OUT_BIG: i64 = 1536 // R0q: the ffn down projection's output rows (27.5 MB of i16 weights per call)
40const WG_BIG_REPS: i64 = 6 // R0q: repeats on the big shape
41const WG_BYTE_SPAN: i64 = 256 // one byte of pseudo-random weight fill
42const WG_BATCH_M: i64 = 32 // R0r: activation rows per batched call (the engine's block)
43const WG_TAIL_M: i64 = 5 // R0r: an odd row count on the tail-width fixture
44const WG_DOT_N: i64 = 1024 // R0r-b: one full chunk of lanes for the builtin KAT
45const WG_DOT_HALF: i64 = 512 // R0r-b: centres the ramp so half the lanes are negative
46const WG_DOT_PLANT: i64 = 777 // R0r-b: the lane the neg-control raises by one
47const WG_DOT_REAL_N: i64 = 512 // R0r-b: lanes of real weight rows in the KAT (64 products per int32 lane, a 2^30 bound)
48const WG_I16_MOD: i64 = 65536
49const WG_I16_HALF: i64 = 32768
50const WG_BYTE: i64 = 256
51// R0r-b: i16 lanes written and read back as bytes, and the exact scalar reference the builtin must equal.
52func wg_put_i16(p: *u8, i: i64, v: i64) -> i64 { var u: i64 = v; if u < 0 { u = u + WG_I16_MOD } p[i*2] = (u % WG_BYTE) as u8; p[i*2+1] = ((u / WG_BYTE) % WG_BYTE) as u8; return 0 }
53func wg_get_i16(p: *u8, i: i64) -> i64 { var u: i64 = (p[i*2] as i64) + (p[i*2+1] as i64) * WG_BYTE; if u >= WG_I16_HALF { u = u - WG_I16_MOD } return u }
54func wg_dot_ref(a: *u8, b: *u8, n: i64) -> i64 { var s: i64 = 0; var i: i64 = 0; while i < n { s = s + wg_get_i16(a, i) * wg_get_i16(b, i); i = i + 1 } return s }
55
56func wg_lcg(st: *i64) -> i64 { st[0] = (st[0]*WG_LCG_A + WG_LCG_C) & WG_MASK63; return st[0] }
57func wg_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
58func wg_fill_x(x: *i64, n: i64, st: *i64) -> i64 {
59 var k: i64 = 0
60 while k < n {
61 var mag: i64 = WG_X_BODY
62 if (k % WG_OUTLIER_EVERY) == 0 { mag = WG_X_OUTLIER }
63 let r: i64 = wg_lcg(st) % (2*mag+1)
64 x[k] = r - mag
65 k = k + 1
66 }
67 return 0
68}
69func wg_fill_w(w: *i64, n: i64, st: *i64) -> i64 { var k: i64 = 0; while k < n { let r: i64 = wg_lcg(st) % (2*WG_W_MAG+1); w[k] = r - WG_W_MAG; k = k + 1 } return 0 }
70// the exact reference: i64 dot, then the same >> shift the kernel applies
71func wg_exact(x: *i64, w: *i64, ind: i64, out: i64, dst: *i64) -> i64 {
72 var o: i64 = 0
73 while o < out { var s: i64 = 0; var k: i64 = 0; while k < ind { s = s + x[k]*w[o*ind+k]; k = k + 1 } dst[o] = s >> WG_SHIFT; o = o + 1 }
74 return 0
75}
76// THE CONTROL: the pre-2026-09-16 quantiser, 8-bit per-tensor activation and 8-bit per-row weight, truncating
77func wg_old_path(x: *i64, w: *i64, ind: i64, out: i64, dst: *i64) -> i64 {
78 var xmx: i64 = 0; var k: i64 = 0
79 while k < ind { if wg_abs(x[k]) > xmx { xmx = wg_abs(x[k]) } k = k + 1 }
80 var sx: i64 = xmx / WG_OLD_QMAX; if sx < 1 { sx = 1 }
81 var o: i64 = 0
82 while o < out {
83 var rm: i64 = 0; k = 0
84 while k < ind { if wg_abs(w[o*ind+k]) > rm { rm = wg_abs(w[o*ind+k]) } k = k + 1 }
85 var sw: i64 = rm / WG_OLD_QMAX; if sw < 1 { sw = 1 }
86 var s: i64 = 0; k = 0
87 while k < ind { s = s + (x[k]/sx) * (w[o*ind+k]/sw); k = k + 1 }
88 dst[o] = ((sx*sw)*s) >> WG_SHIFT
89 o = o + 1
90 }
91 return 0
92}
93// max relative error in permil of `got` against `ref` over `n` rows (rows with |ref| below WG_PERMIL are skipped so a
94// near-zero reference cannot manufacture an infinite ratio; the count of scored rows is returned through `scored`)
95func wg_max_err_permil(ref: *i64, got: *i64, n: i64, scored: *i64) -> i64 {
96 var worst: i64 = 0; var o: i64 = 0; var c: i64 = 0
97 while o < n {
98 let r: i64 = wg_abs(ref[o])
99 if r >= WG_PERMIL {
100 let e: i64 = (wg_abs(got[o] - ref[o]) * WG_PERMIL) / r
101 if e > worst { worst = e }
102 c = c + 1
103 }
104 o = o + 1
105 }
106 scored[0] = c
107 return worst
108}
109func wg_quant_weights(w: *i64, ind: i64, out: i64, wi8: *u8, sw: *i64) -> i64 { return nf_quant_w_i8(w, wi8, sw, out, ind) }
110
111func main(argc: i64, argv: *i64) -> i64 {
112 let ctr: *i64 = gv_ctr()
113 gv_head("nx_nofloat_w12a12_gate -- the 12-bit decode matmul beats the 8-bit per-tensor quantiser it replaces, and its chunk bound is arithmetic" as *u8)
114 // ---- T1 the chunk bound ----
115 let lane_products: i64 = NF_CHUNK_K / NF_MADD_PER_LANE
116 let lane_max: i64 = lane_products * NF_X_QMAX * NF_W_QMAX
117 gv_check("T1 NF_CHUNK_K/8 * QMAX * QMAX fits an int32 lane" as *u8, (lane_max <= NF_I32_ACC_MAX) as i64, ctr)
118 gv_check("T1a NF_CHUNK_K is a multiple of 16 (one madd)" as *u8, ((NF_CHUNK_K % 16) == 0) as i64, ctr)
119 let breaker: i64 = (WG_BREAKER_CHUNK / NF_MADD_PER_LANE) * NF_X_QMAX * NF_W_QMAX
120 gv_check("T1b neg-control a 2048 chunk would overflow the lane" as *u8, (breaker > NF_I32_ACC_MAX) as i64, ctr)
121 gv_check("T1c the derived bound is the largest 16-multiple: NF_CHUNK_K + 16 overflows" as *u8, (((NF_CHUNK_K + 16) / NF_MADD_PER_LANE) * NF_X_QMAX * NF_W_QMAX > NF_I32_ACC_MAX) as i64, ctr)
122 gv_kv("lane_max_at_chunk" as *u8, lane_max)
123 gv_kv("i32_acc_max" as *u8, NF_I32_ACC_MAX)
124 // ---- T2 rounding ----
125 gv_check_eq("T2 round-to-nearest, positive (7/2 -> 4)" as *u8, nf_qround(7, 2, NF_X_QMAX), 4, ctr)
126 gv_check_eq("T2a round-to-nearest, negative (-7/2 -> -4)" as *u8, nf_qround(0 - 7, 2, NF_X_QMAX), 0 - 4, ctr)
127 gv_check_eq("T2b clamp at +qmax" as *u8, nf_qround(99999999, 1, NF_X_QMAX), NF_X_QMAX, ctr)
128 gv_check_eq("T2c clamp at -qmax" as *u8, nf_qround(0 - 99999999, 1, NF_X_QMAX), 0 - NF_X_QMAX, ctr)
129 // ---- T3 the kernel vs the exact dot vs the old quantiser, real widths, planted outliers ----
130 let st: *i64 = sys_mmap(8) as *i64; st[0] = WG_SEED
131 let x: *i64 = sys_mmap(WG_IN*8) as *i64
132 let w: *i64 = sys_mmap(WG_IN*WG_OUT*8) as *i64
133 wg_fill_x(x, WG_IN, st)
134 wg_fill_w(w, WG_IN*WG_OUT, st)
135 let exact: *i64 = sys_mmap(WG_OUT*8) as *i64
136 let old: *i64 = sys_mmap(WG_OUT*8) as *i64
137 let got: *i64 = sys_mmap(WG_OUT*8) as *i64
138 wg_exact(x, w, WG_IN, WG_OUT, exact)
139 wg_old_path(x, w, WG_IN, WG_OUT, old)
140 let wi8: *u8 = sys_mmap(WG_IN*WG_OUT*2)
141 let sw: *i64 = sys_mmap(WG_OUT*8) as *i64
142 wg_quant_weights(w, WG_IN, WG_OUT, wi8, sw)
143 mm_pool_i8(x, wi8, sw, got, WG_IN, WG_OUT, WG_SHIFT)
144 let sc: *i64 = sys_mmap(16) as *i64
145 let e_old: i64 = wg_max_err_permil(exact, old, WG_OUT, sc)
146 let rows_old: i64 = sc[0]
147 let e_new: i64 = wg_max_err_permil(exact, got, WG_OUT, sc)
148 let rows_new: i64 = sc[0]
149 gv_check("T3 the fixture reached the condition: every output row scored (|exact| above the permil floor)" as *u8, ((rows_old == WG_OUT) as i64) * ((rows_new == WG_OUT) as i64), ctr)
150 gv_check("T3a the planted outliers made the OLD 8-bit per-tensor path lose at least 10 permil somewhere" as *u8, (e_old >= 10) as i64, ctr)
151 gv_check("T3b W12A12 max relative error is BELOW the old path's" as *u8, (e_new < e_old) as i64, ctr)
152 // the grid is 32x finer (4095 vs 127 levels) so per-element rounding error falls 32x; the dot product's error
153 // falls less where the old errors happened to cancel, hence a conservative 8x bound rather than the theoretical 32x
154 gv_check("T3c W12A12 max relative error is at least 8x below the old path's (32x finer grid, 4x margin)" as *u8, (e_new * 8 < e_old) as i64, ctr)
155 gv_kv("old_w8a8_max_err_permil" as *u8, e_old)
156 gv_kv("new_w12a12_max_err_permil" as *u8, e_new)
157 // ---- T4 an on-grid row is EXACT through the kernel (nothing for either quantiser to lose) ----
158 var k: i64 = 0
159 while k < WG_IN { x[k] = ((wg_lcg(st) % WG_GRID_SPAN) - NF_X_QMAX) * WG_GRID_SX; k = k + 1 }
160 x[0] = NF_X_QMAX * WG_GRID_SX
161 k = 0
162 while k < WG_IN*WG_OUT { w[k] = (wg_lcg(st) % WG_GRID_SPAN) - NF_X_QMAX; k = k + 1 }
163 var o2: i64 = 0
164 while o2 < WG_OUT { w[o2*WG_IN] = WG_GRID_WMAX; o2 = o2 + 1 }
165 wg_exact(x, w, WG_IN, WG_OUT, exact)
166 wg_quant_weights(w, WG_IN, WG_OUT, wi8, sw)
167 mm_pool_i8(x, wi8, sw, got, WG_IN, WG_OUT, WG_SHIFT)
168 var same: i64 = 1; var o: i64 = 0
169 while o < WG_OUT { if got[o] != exact[o] { same = 0 } o = o + 1 }
170 gv_check("T4 an on-grid row is bit-exact through the chunked kernel (8960 wide, 9 chunks)" as *u8, same, ctr)
171 // ---- T5 a short row (one chunk) agrees with the exact dot the same way ----
172 let xs: *i64 = sys_mmap(WG_SHORT_IN*8) as *i64
173 let ws: *i64 = sys_mmap(WG_SHORT_IN*WG_OUT*8) as *i64
174 k = 0; while k < WG_SHORT_IN { xs[k] = ((wg_lcg(st) % WG_GRID_SPAN) - NF_X_QMAX) * WG_GRID_SX; k = k + 1 }
175 xs[0] = NF_X_QMAX * WG_GRID_SX
176 k = 0; while k < WG_SHORT_IN*WG_OUT { ws[k] = (wg_lcg(st) % WG_GRID_SPAN) - NF_X_QMAX; k = k + 1 }
177 o = 0
178 while o < WG_OUT { ws[o*WG_SHORT_IN] = WG_GRID_WMAX; o = o + 1 }
179 wg_exact(xs, ws, WG_SHORT_IN, WG_OUT, exact)
180 let wi8s: *u8 = sys_mmap(WG_SHORT_IN*WG_OUT*2)
181 wg_quant_weights(ws, WG_SHORT_IN, WG_OUT, wi8s, sw)
182 mm_pool_i8(xs, wi8s, sw, got, WG_SHORT_IN, WG_OUT, WG_SHIFT)
183 same = 1; o = 0
184 while o < WG_OUT { if got[o] != exact[o] { same = 0 } o = o + 1 }
185 gv_check("T5 a one-chunk row (896 wide) is bit-exact on the grid" as *u8, same, ctr)
186 // ---- T6 R0q: the four-accumulator task is bit-identical to the single-accumulator incumbent ----
187 wg_fill_x(x, WG_IN, st)
188 wg_fill_w(w, WG_IN*WG_OUT, st)
189 wg_quant_weights(w, WG_IN, WG_OUT, wi8, sw)
190 g_nf_i8_r4 = 0
191 mm_pool_i8(x, wi8, sw, old, WG_IN, WG_OUT, WG_SHIFT)
192 g_nf_i8_r4 = 1
193 mm_pool_i8(x, wi8, sw, got, WG_IN, WG_OUT, WG_SHIFT)
194 same = 1; o = 0
195 while o < WG_OUT { if got[o] != old[o] { same = 0 } o = o + 1 }
196 gv_check("T6 R0q four-accumulator task bit-identical to the incumbent (8960 wide, planted outliers, 9 chunks)" as *u8, same, ctr)
197 // T6a a width that is a multiple of 16 but not of 64 exercises the tail madd (912 = 14 x 64 + 16)
198 let xt: *i64 = sys_mmap(WG_TAIL_IN*8) as *i64
199 let wt: *i64 = sys_mmap(WG_TAIL_IN*WG_OUT*8) as *i64
200 wg_fill_x(xt, WG_TAIL_IN, st)
201 wg_fill_w(wt, WG_TAIL_IN*WG_OUT, st)
202 let wi8t: *u8 = sys_mmap(WG_TAIL_IN*WG_OUT*2)
203 wg_quant_weights(wt, WG_TAIL_IN, WG_OUT, wi8t, sw)
204 g_nf_i8_r4 = 0
205 mm_pool_i8(xt, wi8t, sw, old, WG_TAIL_IN, WG_OUT, WG_SHIFT)
206 g_nf_i8_r4 = 1
207 mm_pool_i8(xt, wi8t, sw, got, WG_TAIL_IN, WG_OUT, WG_SHIFT)
208 same = 1; o = 0
209 while o < WG_OUT { if got[o] != old[o] { same = 0 } o = o + 1 }
210 gv_check("T6a bit-identical on a 912-wide row (fourteen 64-steps plus one tail madd)" as *u8, same, ctr)
211 // T6b the fixture reached the condition: the tail loop ran (912 mod 64 = 16 = one madd)
212 gv_check_eq("T6b the tail width is exactly one madd" as *u8, WG_TAIL_IN % NF_R4_STRIDE, NF_MADD_W, ctr)
213 // ---- T7 throughput of the two tasks on the real ffn width, printed as values (a timing is never a tooth) ----
214 g_nf_i8_r4 = 0
215 let t0: i64 = sys_now_us()
216 var rep: i64 = 0
217 while rep < WG_TIMING_REPS { mm_pool_i8(x, wi8, sw, old, WG_IN, WG_OUT, WG_SHIFT); rep = rep + 1 }
218 let t1: i64 = sys_now_us()
219 g_nf_i8_r4 = 1
220 rep = 0
221 while rep < WG_TIMING_REPS { mm_pool_i8(x, wi8, sw, got, WG_IN, WG_OUT, WG_SHIFT); rep = rep + 1 }
222 let t2: i64 = sys_now_us()
223 gv_kv("incumbent_us_per_call" as *u8, (t1 - t0) / WG_TIMING_REPS)
224 gv_kv("r4_us_per_call" as *u8, (t2 - t1) / WG_TIMING_REPS)
225 var spd: i64 = 0
226 if t2 > t1 { spd = ((t1 - t0) * WG_PERMIL) / (t2 - t1) }
227 gv_kv("r4_speedup_permil" as *u8, spd)
228 gv_check("T7 the served default is the single-accumulator incumbent (the four-accumulator task measured slower on the decode shape)" as *u8, (NF_I8_R4_DEFAULT == 0) as i64, ctr)
229 // ---- T7b the decode SHAPE: 1536 output rows x 8960 (the ffn down projection), 27.5 MB of weights per call, so the
230 // per-call time is the kernel's own streaming rate and not the pool's dispatch cost on a 64-row fixture
231 let wbig: *u8 = sys_mmap(WG_IN*WG_OUT_BIG*2)
232 let swbig: *i64 = sys_mmap(WG_OUT_BIG*8) as *i64
233 let gotbig: *i64 = sys_mmap(WG_OUT_BIG*8) as *i64
234 var fb: i64 = 0
235 while fb < WG_IN*WG_OUT_BIG*2 { wbig[fb] = (wg_lcg(st) % WG_BYTE_SPAN) as u8; fb = fb + 1 }
236 fb = 0
237 while fb < WG_OUT_BIG { swbig[fb] = 1; fb = fb + 1 }
238 g_nf_i8_r4 = 0
239 let tb0: i64 = sys_now_us()
240 rep = 0
241 while rep < WG_BIG_REPS { mm_pool_i8(x, wbig, swbig, gotbig, WG_IN, WG_OUT_BIG, WG_SHIFT); rep = rep + 1 }
242 let tb1: i64 = sys_now_us()
243 g_nf_i8_r4 = 1
244 rep = 0
245 while rep < WG_BIG_REPS { mm_pool_i8(x, wbig, swbig, gotbig, WG_IN, WG_OUT_BIG, WG_SHIFT); rep = rep + 1 }
246 let tb2: i64 = sys_now_us()
247 let usb_old: i64 = (tb1 - tb0) / WG_BIG_REPS
248 let usb_r4: i64 = (tb2 - tb1) / WG_BIG_REPS
249 gv_kv("big_incumbent_us_per_call" as *u8, usb_old)
250 gv_kv("big_r4_us_per_call" as *u8, usb_r4)
251 if usb_old > 0 { gv_kv("big_incumbent_mb_per_s" as *u8, (WG_IN*WG_OUT_BIG*2) / usb_old) }
252 if usb_r4 > 0 { gv_kv("big_r4_mb_per_s" as *u8, (WG_IN*WG_OUT_BIG*2) / usb_r4) }
253 // ---- T8 R0r: the batched kernel (M rows, one weight pass) is bit-identical to M single calls, cell for cell ----
254 wg_quant_weights(w, WG_IN, WG_OUT, wi8, sw)
255 let xm: *i64 = sys_mmap(WG_BATCH_M*WG_IN*8) as *i64
256 wg_fill_x(xm, WG_BATCH_M*WG_IN, st)
257 let gotm: *i64 = sys_mmap(WG_BATCH_M*WG_OUT*8) as *i64
258 mm_pool_i8_m(xm, WG_BATCH_M, wi8, sw, gotm, WG_IN, WG_OUT, WG_SHIFT)
259 same = 1
260 var cells: i64 = 0
261 var mrow: i64 = 0
262 while mrow < WG_BATCH_M {
263 mm_pool_i8(((xm as i64)+mrow*WG_IN*8) as *i64, wi8, sw, old, WG_IN, WG_OUT, WG_SHIFT)
264 o = 0
265 while o < WG_OUT { if gotm[mrow*WG_OUT+o] != old[o] { same = 0 } cells = cells + 1; o = o + 1 }
266 mrow = mrow + 1
267 }
268 gv_kv("batch_cells_compared" as *u8, cells)
269 gv_check("T8 R0r batched kernel bit-identical to M single calls (8960 wide, 32 rows, 9 chunks)" as *u8, same, ctr)
270 // T8a an odd row count on the tail width (912 = fourteen 64-steps plus one madd)
271 wg_quant_weights(wt, WG_TAIL_IN, WG_OUT, wi8t, sw)
272 let xmt: *i64 = sys_mmap(WG_TAIL_M*WG_TAIL_IN*8) as *i64
273 wg_fill_x(xmt, WG_TAIL_M*WG_TAIL_IN, st)
274 let gotmt: *i64 = sys_mmap(WG_TAIL_M*WG_OUT*8) as *i64
275 mm_pool_i8_m(xmt, WG_TAIL_M, wi8t, sw, gotmt, WG_TAIL_IN, WG_OUT, WG_SHIFT)
276 same = 1
277 mrow = 0
278 while mrow < WG_TAIL_M {
279 mm_pool_i8(((xmt as i64)+mrow*WG_TAIL_IN*8) as *i64, wi8t, sw, old, WG_TAIL_IN, WG_OUT, WG_SHIFT)
280 o = 0
281 while o < WG_OUT { if gotmt[mrow*WG_OUT+o] != old[o] { same = 0 } o = o + 1 }
282 mrow = mrow + 1
283 }
284 gv_check("T8a batched kernel bit-identical on the 912-wide row with 5 activation rows" as *u8, same, ctr)
285 // T8b neg-control: the comparator fires on one planted cell
286 gotmt[WG_OUT+1] = gotmt[WG_OUT+1] + 1
287 var planted: i64 = 1
288 mrow = 0
289 while mrow < WG_TAIL_M {
290 mm_pool_i8(((xmt as i64)+mrow*WG_TAIL_IN*8) as *i64, wi8t, sw, old, WG_TAIL_IN, WG_OUT, WG_SHIFT)
291 o = 0
292 while o < WG_OUT { if gotmt[mrow*WG_OUT+o] != old[o] { planted = 0 } o = o + 1 }
293 mrow = mrow + 1
294 }
295 gv_check("neg-control-T8b the cell comparator reads a planted +1 as a difference" as *u8, (planted == 0) as i64, ctr)
296 // T8c the gate's row count is the engine's block (the fixture measures the shape the serve runs)
297 gv_check_eq("T8c the gate batch equals the engine's prefill block" as *u8, WG_BATCH_M, NF_PREFILL_M, ctr)
298 // ---- T8d the decode SHAPE per prompt row: 32 single calls against one 32-row call (values, never a tooth) ----
299 let gotbigm: *i64 = sys_mmap(WG_BATCH_M*WG_OUT_BIG*8) as *i64
300 let tc0: i64 = sys_now_us()
301 mrow = 0
302 while mrow < WG_BATCH_M { mm_pool_i8(((xm as i64)+mrow*WG_IN*8) as *i64, wbig, swbig, gotbig, WG_IN, WG_OUT_BIG, WG_SHIFT); mrow = mrow + 1 }
303 let tc1: i64 = sys_now_us()
304 mm_pool_i8_m(xm, WG_BATCH_M, wbig, swbig, gotbigm, WG_IN, WG_OUT_BIG, WG_SHIFT)
305 let tc2: i64 = sys_now_us()
306 gv_kv("batch_single_us_per_row" as *u8, (tc1 - tc0) / WG_BATCH_M)
307 gv_kv("batch_m_us_per_row" as *u8, (tc2 - tc1) / WG_BATCH_M)
308 var bspd: i64 = 0
309 if tc2 > tc1 { bspd = ((tc1 - tc0) * WG_PERMIL) / (tc2 - tc1) }
310 gv_kv("batch_speedup_permil" as *u8, bspd)
311 // ---- T8e R0r-c: the four-accumulator batched task is bit-identical to the single-accumulator batched task ----
312 let gotm4: *i64 = sys_mmap(WG_BATCH_M*WG_OUT*8) as *i64
313 g_nf_i8_r4m = 0
314 mm_pool_i8_m(xm, WG_BATCH_M, wi8, sw, gotm, WG_IN, WG_OUT, WG_SHIFT)
315 g_nf_i8_r4m = 1
316 mm_pool_i8_m(xm, WG_BATCH_M, wi8, sw, gotm4, WG_IN, WG_OUT, WG_SHIFT)
317 same = 1
318 var cm: i64 = 0
319 while cm < WG_BATCH_M*WG_OUT { if gotm4[cm] != gotm[cm] { same = 0 } cm = cm + 1 }
320 gv_check("T8e R0r-c four-accumulator batched task bit-identical to the single-accumulator batched task (32 rows, 8960 wide)" as *u8, same, ctr)
321 let gotmt4: *i64 = sys_mmap(WG_TAIL_M*WG_OUT*8) as *i64
322 g_nf_i8_r4m = 0
323 mm_pool_i8_m(xmt, WG_TAIL_M, wi8t, sw, gotmt, WG_TAIL_IN, WG_OUT, WG_SHIFT)
324 g_nf_i8_r4m = 1
325 mm_pool_i8_m(xmt, WG_TAIL_M, wi8t, sw, gotmt4, WG_TAIL_IN, WG_OUT, WG_SHIFT)
326 same = 1; cm = 0
327 while cm < WG_TAIL_M*WG_OUT { if gotmt4[cm] != gotmt[cm] { same = 0 } cm = cm + 1 }
328 gv_check("T8e2 bit-identical on the 912-wide row with 5 rows (the tail madd)" as *u8, same, ctr)
329 gv_check("T8e3 the served default is the single-accumulator batched task (the four-accumulator task measured a wash on the decode shape, 451 vs 448 us per row)" as *u8, (NF_I8_R4M_DEFAULT == 0) as i64, ctr)
330 // ---- T8f the decode SHAPE per prompt row, both batched tasks (values, never a tooth) ----
331 g_nf_i8_r4m = 0
332 let td0: i64 = sys_now_us()
333 mm_pool_i8_m(xm, WG_BATCH_M, wbig, swbig, gotbigm, WG_IN, WG_OUT_BIG, WG_SHIFT)
334 let td1: i64 = sys_now_us()
335 g_nf_i8_r4m = 1
336 mm_pool_i8_m(xm, WG_BATCH_M, wbig, swbig, gotbigm, WG_IN, WG_OUT_BIG, WG_SHIFT)
337 let td2: i64 = sys_now_us()
338 gv_kv("batch_m1_us_per_row" as *u8, (td1 - td0) / WG_BATCH_M)
339 gv_kv("batch_m4_us_per_row" as *u8, (td2 - td1) / WG_BATCH_M)
340 var m4spd: i64 = 0
341 if td2 > td1 { m4spd = ((td1 - td0) * WG_PERMIL) / (td2 - td1) }
342 gv_kv("batch_m4_speedup_permil" as *u8, m4spd)
343 // ---- T9 R0r-b: __i16_dot, the compiler's whole-chunk integer dot with the accumulator in a register ----
344 let da: *u8 = sys_mmap(WG_DOT_N*2)
345 let db: *u8 = sys_mmap(WG_DOT_N*2)
346 var di: i64 = 0
347 while di < WG_DOT_N { wg_put_i16(da, di, di + 1 - WG_DOT_HALF); wg_put_i16(db, di, WG_DOT_HALF - di); di = di + 1 }
348 let dref: i64 = wg_dot_ref(da, db, WG_DOT_N)
349 let dgot: i64 = __i16_dot(da, db, WG_DOT_N)
350 gv_check_eq("T9 R0r-b __i16_dot equals the exact scalar reference on a 1024-lane signed ramp" as *u8, dgot, dref, ctr)
351 gv_check("T9a the reference is not zero (a vacuous fixture cannot pass)" as *u8, (dref != 0) as i64, ctr)
352 gv_check_eq("T9b __i16_dot on the smallest legal call, one 16-lane trip" as *u8, __i16_dot(da, db, NF_MADD_W), wg_dot_ref(da, db, NF_MADD_W), ctr)
353 wg_put_i16(da, WG_DOT_PLANT, wg_get_i16(da, WG_DOT_PLANT) + 1)
354 gv_check_eq("neg-control-T9c a planted +1 in one lane of a moves the dot by exactly that lane of b" as *u8, __i16_dot(da, db, WG_DOT_N) - dgot, wg_get_i16(db, WG_DOT_PLANT), ctr)
355 let wrow1: *u8 = ((wi8 as i64) + WG_IN*2) as *u8
356 gv_check_eq("T9d __i16_dot over two real i16 weight rows equals the scalar reference" as *u8, __i16_dot(wi8, wrow1, WG_DOT_REAL_N), wg_dot_ref(wi8, wrow1, WG_DOT_REAL_N), ctr)
357 let gotmd: *i64 = sys_mmap(WG_BATCH_M*WG_OUT*8) as *i64
358 g_nf_i8_dot = 0
359 mm_pool_i8_m(xm, WG_BATCH_M, wi8, sw, gotm, WG_IN, WG_OUT, WG_SHIFT)
360 g_nf_i8_dot = 1
361 mm_pool_i8_m(xm, WG_BATCH_M, wi8, sw, gotmd, WG_IN, WG_OUT, WG_SHIFT)
362 same = 1; cm = 0
363 while cm < WG_BATCH_M*WG_OUT { if gotmd[cm] != gotm[cm] { same = 0 } cm = cm + 1 }
364 gv_check("T9e R0r-b the builtin batched kernel is bit-identical to the madd-loop batched kernel (32 rows, 8960 wide)" as *u8, same, ctr)
365 let gotmtd: *i64 = sys_mmap(WG_TAIL_M*WG_OUT*8) as *i64
366 g_nf_i8_dot = 0
367 mm_pool_i8_m(xmt, WG_TAIL_M, wi8t, sw, gotmt, WG_TAIL_IN, WG_OUT, WG_SHIFT)
368 g_nf_i8_dot = 1
369 mm_pool_i8_m(xmt, WG_TAIL_M, wi8t, sw, gotmtd, WG_TAIL_IN, WG_OUT, WG_SHIFT)
370 same = 1; cm = 0
371 while cm < WG_TAIL_M*WG_OUT { if gotmtd[cm] != gotmt[cm] { same = 0 } cm = cm + 1 }
372 gv_check("T9f bit-identical on the 912-wide row with 5 rows (one 912-lane call per cell)" as *u8, same, ctr)
373 gv_check("T9g the served default is the builtin batched kernel" as *u8, (NF_I8_DOT_DEFAULT == 1) as i64, ctr)
374 // ---- T10 R0s: the pool quantiser is byte-identical to the serial quantiser it replaces ----
375 g_nf_quant_serial = 1
376 nf_quant_rows_pool(xm, WG_BATCH_M, WG_IN)
377 let qs_us: i64 = g_nf_mm_us_quant
378 let qbytes: i64 = WG_BATCH_M*WG_IN*2
379 let qcopy: *u8 = sys_mmap(qbytes)
380 var qi: i64 = 0
381 while qi < qbytes { qcopy[qi] = g_nf_xi8m[qi]; qi = qi + 1 }
382 let scopy: *i64 = sys_mmap(WG_BATCH_M*8) as *i64
383 qi = 0; while qi < WG_BATCH_M { scopy[qi] = g_nf_sxm[qi]; qi = qi + 1 }
384 g_nf_quant_serial = 0
385 nf_quant_rows_pool(xm, WG_BATCH_M, WG_IN)
386 let qp_us: i64 = g_nf_mm_us_quant
387 var qsame: i64 = 1
388 qi = 0; while qi < qbytes { if qcopy[qi] != g_nf_xi8m[qi] { qsame = 0 } qi = qi + 1 }
389 var ssame: i64 = 1
390 qi = 0; while qi < WG_BATCH_M { if scopy[qi] != g_nf_sxm[qi] { ssame = 0 } qi = qi + 1 }
391 gv_check("T10 R0s pool-quantised rows byte-identical to the serial quantiser (32 rows, 8960 wide)" as *u8, qsame, ctr)
392 gv_check("T10a the per-row scales are identical" as *u8, ssame, ctr)
393 qcopy[WG_DOT_PLANT] = ((qcopy[WG_DOT_PLANT] as i64) + 1) as u8
394 var qdiff: i64 = 0
395 qi = 0; while qi < qbytes { if qcopy[qi] != g_nf_xi8m[qi] { qdiff = qdiff + 1 } qi = qi + 1 }
396 gv_check_eq("neg-control-T10b the byte comparator reads one planted byte as exactly one difference" as *u8, qdiff, 1, ctr)
397 gv_check("T10c the served default is the pool quantiser" as *u8, (NF_QUANT_SERIAL_DEFAULT == 0) as i64, ctr)
398 gv_kv("quant_serial_us" as *u8, qs_us)
399 gv_kv("quant_pool_us" as *u8, qp_us)
400 // ---- the decode SHAPE per prompt row, madd loop vs builtin (values, never a tooth: a loaded box makes timing flaky) ----
401 g_nf_i8_dot = 0
402 let te0: i64 = sys_now_us()
403 mm_pool_i8_m(xm, WG_BATCH_M, wbig, swbig, gotbigm, WG_IN, WG_OUT_BIG, WG_SHIFT)
404 let te1: i64 = sys_now_us()
405 g_nf_i8_dot = 1
406 mm_pool_i8_m(xm, WG_BATCH_M, wbig, swbig, gotbigm, WG_IN, WG_OUT_BIG, WG_SHIFT)
407 let te2: i64 = sys_now_us()
408 gv_kv("batch_madd_us_per_row" as *u8, (te1 - te0) / WG_BATCH_M)
409 gv_kv("batch_dot_us_per_row" as *u8, (te2 - te1) / WG_BATCH_M)
410 var dspd: i64 = 0
411 if te2 > te1 { dspd = ((te1 - te0) * WG_PERMIL) / (te2 - te1) }
412 gv_kv("batch_dot_speedup_permil" as *u8, dspd)
413 // the split of the LAST (builtin) call: the single-threaded quantisation of 32 rows vs the pool's matmul
414 gv_kv("batch_dot_quant_us" as *u8, g_nf_mm_us_quant)
415 gv_kv("batch_dot_pool_us" as *u8, g_nf_mm_us_pool)
416 gv_kv("batch_dot_pool_workers" as *u8, nf_pool().n_workers)
417 let rc: i64 = gv_verdict("NOFLOAT-W12A12-GATE" as *u8, ctr, "the chunk bound is arithmetic, the 12-bit kernel beats the 8-bit control on planted outliers and is exact on the grid" as *u8)
418 sys_exit_group(rc) // exit_group, not the raw thread exit: the pool workers parked in futex wait must die with the verdict
419 return rc
420}