nx_lw_cache_gate.nx source
↩ module page · 321 lines · 12318 B
1// nx_lw_cache_gate.nx -- gate for the packed dequant-once cache in
2// nx_f32_lazy_weight (the m=1 decode lever: stop re-dequanting the
3// same weights every token; cached matmuls are pure packed
4// __f32x4_dot bands).
5//
6// Exact-f32 regime construction as in nx_q4k_matmul_x4_gate (dense
7// d=1.0/sc=1 blocks -> integer dequant values 0..15; int A; all
8// |sums| < 2^24), so bit-exact comparison between the CACHED path
9// (x4 dot order) and the scalar streaming oracle is legitimate.
10//
11// Checks (8):
12// 1 scalar oracle OK (k=512, n=37, m=3)
13// 2 first dispatch fills + matches oracle; pk_state=1; used bytes exact
14// 3 second dispatch (new A) matches fresh oracle (cache reuse +
15// shared-pool delta-wait across fill+dot submissions)
16// 4 m=1 decode shape via dispatcher matches oracle
17// 5 budget refusal: fresh weight + tiny budget -> pk_state=-1 AND
18// result still matches oracle (streamed scalar-pool fallback)
19// 6 stale k=1 shape surfaces NX_LW_ERR_INNER (guard before cache)
20// 7 decode-shape speedup: cached reps vs streamed reps (same data,
21// bit-exact) -- floor cached >= 1.5x streamed; first-call fill
22// overhead printed for the honest record
23// 8 cached and streamed big-shape outputs bit-identical
24//
25// lineage_id: lw_cache_gate_v1
26
27import "nx_gate_verdict.nx"
28import "nx_f32_lazy_weight.nx"
29import "nx_fmt.nx"
30
31const LG_M: i64 = 3
32const LG_K: i64 = 512
33const LG_N: i64 = 37
34
35const LB_K: i64 = 1024
36const LB_N: i64 = 4864
37const LB_REPS: i64 = 3
38
39const LG_SPEEDUP_FLOOR_X100: i64 = 150
40
41func l_lcg(s: i64) -> i64 {
42 var v: i64 = s * 1103515245 + 12345
43 v = v & 2147483647
44 return v
45}
46
47func l_block_dense(buf: *u8, off: i64, seed: i64) -> i64 {
48 buf[off + 0] = 0x00 as u8
49 buf[off + 1] = 0x3C as u8
50 buf[off + 2] = 0 as u8
51 buf[off + 3] = 0 as u8
52 var i: i64 = 0
53 while i < 4 {
54 buf[off + 4 + i] = 0x01 as u8
55 buf[off + 8 + i] = 0x00 as u8
56 buf[off + 12 + i] = 0x01 as u8
57 i = i + 1
58 }
59 var s: i64 = seed
60 var z: i64 = 0
61 while z < 128 {
62 s = l_lcg(s)
63 buf[off + 16 + z] = (s & 255) as u8
64 z = z + 1
65 }
66 return off + 144
67}
68
69func l_fill_weights(buf: *u8, n_rows: i64, k: i64, seed: i64) -> i64 {
70 let bpr: i64 = (k / 256) * 144
71 var s: i64 = seed
72 var r: i64 = 0
73 while r < n_rows {
74 var b: i64 = 0
75 while b < k / 256 {
76 s = l_lcg(s)
77 l_block_dense(buf, r * bpr + b * 144, s)
78 b = b + 1
79 }
80 r = r + 1
81 }
82 return 0
83}
84
85func l_fill_a(p: *i64, count: i64, seed: i64, half: i64) -> i64 {
86 var s: i64 = seed
87 var i: i64 = 0
88 while i < count {
89 s = l_lcg(s)
90 let v: i64 = (s % (half + half)) - half
91 p[i] = nx_i32_to_f32(v)
92 i = i + 1
93 }
94 return 0
95}
96
97func l_poison(p: *i64, count: i64) -> i64 {
98 let pv: i64 = 0 - 777777
99 var i: i64 = 0
100 while i < count {
101 p[i] = pv
102 i = i + 1
103 }
104 return 0
105}
106
107func l_same(a: *i64, b: *i64, count: i64) -> i64 {
108 var i: i64 = 0
109 while i < count {
110 if a[i] != b[i] { return 0 }
111 i = i + 1
112 }
113 return 1
114}
115
116func l_nl() -> i64 {
117 fmt_puts("\n" as *u8)
118 return 0
119}
120
121func lwc_run() -> i64 {
122 let a_n: i64 = LG_M * LG_K
123 let b_n: i64 = LG_N * (LG_K / 256) * 144
124 let c_n: i64 = LG_M * LG_N
125 let A: *i64 = sys_mmap(a_n * 8) as *i64
126 let B: *u8 = sys_mmap(b_n)
127 let Cs: *i64 = sys_mmap(c_n * 8) as *i64
128 let Cd: *i64 = sys_mmap(c_n * 8) as *i64
129 l_fill_a(A, a_n, 20260708, 5)
130 l_fill_weights(B, LG_N, LG_K, 424242)
131
132 var pass: i64 = 0
133
134 // GATE REPAIR 2026-08-01: NX_LW_CACHE_BUDGET_DEFAULT is now 0 ("stream quantized weights",
135 // re-measured by the budget owner the same day). Under a 0 default, tooth 2's pk_state==1
136 // can never hold -- the gate was failing against the UNMODIFIED lib, for a reason unrelated
137 // to any kernel change. This gate's job is to prove the cache machinery CORRECT WHEN ENABLED,
138 // not to pin the production default (that is the budget owner's measured call), so the cache
139 // teeth run under an EXPLICIT test budget. Production keeps default=0 untouched.
140 nx_lw_set_cache_budget(1073741824)
141
142 // ---- 1: scalar oracle ----
143 let v1: nx_int = nx_f32_q4k_matmul(A, B, 0, Cs, LG_M, LG_K, LG_N)
144 if v1 != NX_FQ4M_OK { fmt_puts("LWC 1 ORACLE FAIL"); l_nl(); return 11 }
145 fmt_puts("LWC 1 ORACLE OK"); l_nl()
146 pass = pass + 1
147
148 // ---- 2: first dispatch fills the cache + matches ----
149 let W: *NxF32LazyWeight = nx_f32_lazy_weight_new_q4k(B, 0, LG_K, LG_N)
150 l_poison(Cd, c_n)
151 let v2: nx_int = nx_f32_lazy_matmul(A, W, Cd, LG_M, LG_K, LG_N)
152 var ok2: i64 = 0
153 if v2 == NX_LW_OK { if W.pk_state == 1 { ok2 = l_same(Cd, Cs, c_n) } }
154 let want_used: i64 = LG_N * LG_K * 4
155 if nx_lw_cache_used() != want_used { ok2 = 0 }
156 if ok2 != 1 { fmt_puts("LWC 2 FILL FAIL"); l_nl(); return 12 }
157 fmt_puts("LWC 2 FILL+MATCH OK used="); fmt_putn(nx_lw_cache_used()); l_nl()
158 pass = pass + 1
159
160 // ---- 3: cache reuse with new A ----
161 l_fill_a(A, a_n, 555008, 5)
162 let v3s: nx_int = nx_f32_q4k_matmul(A, B, 0, Cs, LG_M, LG_K, LG_N)
163 if v3s != NX_FQ4M_OK { return 13 }
164 l_poison(Cd, c_n)
165 let v3: nx_int = nx_f32_lazy_matmul(A, W, Cd, LG_M, LG_K, LG_N)
166 var ok3: i64 = 0
167 if v3 == NX_LW_OK { ok3 = l_same(Cd, Cs, c_n) }
168 if ok3 != 1 { fmt_puts("LWC 3 REUSE FAIL"); l_nl(); return 13 }
169 fmt_puts("LWC 3 REUSE OK"); l_nl()
170 pass = pass + 1
171
172 // ---- 4: m=1 decode shape ----
173 let c1s: *i64 = sys_mmap(LG_N * 8) as *i64
174 let c1d: *i64 = sys_mmap(LG_N * 8) as *i64
175 let v4s: nx_int = nx_f32_q4k_matmul(A, B, 0, c1s, 1, LG_K, LG_N)
176 l_poison(c1d, LG_N)
177 let v4: nx_int = nx_f32_lazy_matmul(A, W, c1d, 1, LG_K, LG_N)
178 var ok4: i64 = 0
179 if v4s == NX_FQ4M_OK { if v4 == NX_LW_OK { ok4 = l_same(c1d, c1s, LG_N) } }
180 if ok4 != 1 { fmt_puts("LWC 4 M1 FAIL"); l_nl(); return 14 }
181 fmt_puts("LWC 4 M1 OK"); l_nl()
182 pass = pass + 1
183
184 // ---- 5: budget refusal -> streamed fallback still correct ----
185 nx_lw_set_cache_budget(nx_lw_cache_used() + 1)
186 let W2: *NxF32LazyWeight = nx_f32_lazy_weight_new_q4k(B, 0, LG_K, LG_N)
187 l_poison(Cd, c_n)
188 let v5: nx_int = nx_f32_lazy_matmul(A, W2, Cd, LG_M, LG_K, LG_N)
189 var ok5: i64 = 0
190 if v5 == NX_LW_OK { if W2.pk_state == 0 - 1 { ok5 = l_same(Cd, Cs, c_n) } }
191 if ok5 != 1 { fmt_puts("LWC 5 BUDGET-REFUSE FAIL"); l_nl(); return 15 }
192 fmt_puts("LWC 5 BUDGET-REFUSE+STREAM OK"); l_nl()
193 pass = pass + 1
194
195 // ---- 6: stale k=1 shape surfaces ERR_INNER ----
196 let v6: nx_int = nx_f32_lazy_matmul(A, W, Cd, 1, 1, 256)
197 if v6 != NX_LW_ERR_INNER { fmt_puts("LWC 6 STALE-GUARD FAIL"); l_nl(); return 16 }
198 fmt_puts("LWC 6 STALE-GUARD OK"); l_nl()
199 pass = pass + 1
200
201 // ---- 7+8: decode-shape speedup, cached vs streamed ----
202 let bb_n: i64 = LB_N * (LB_K / 256) * 144
203 let BA: *i64 = sys_mmap(LB_K * 8) as *i64
204 let BB: *u8 = sys_mmap(bb_n)
205 let BCs: *i64 = sys_mmap(LB_N * 8) as *i64
206 let BCc: *i64 = sys_mmap(LB_N * 8) as *i64
207 l_fill_a(BA, LB_K, 7788, 512)
208 l_fill_weights(BB, LB_N, LB_K, 313373)
209
210 // streamed reference: force refusal with a tiny budget
211 nx_lw_set_cache_budget(1)
212 let Wstream: *NxF32LazyWeight = nx_f32_lazy_weight_new_q4k(BB, 0, LB_K, LB_N)
213 l_poison(BCs, LB_N)
214 let t0: i64 = sys_now_us()
215 var r0: i64 = 0
216 while r0 < LB_REPS {
217 let vs: nx_int = nx_f32_lazy_matmul(BA, Wstream, BCs, 1, LB_K, LB_N)
218 if vs != NX_LW_OK { return 21 }
219 r0 = r0 + 1
220 }
221 let us_stream: i64 = (sys_now_us() - t0) / LB_REPS
222 if Wstream.pk_state != 0 - 1 { return 21 }
223
224 // cached: restore the TEST budget (the DEFAULT is now 0 = stream-only; restoring it here
225 // would refuse the fill and break the tooth for a non-cache reason)
226 nx_lw_set_cache_budget(1073741824)
227 let Wcache: *NxF32LazyWeight = nx_f32_lazy_weight_new_q4k(BB, 0, LB_K, LB_N)
228 l_poison(BCc, LB_N)
229 let tf0: i64 = sys_now_us()
230 let vf: nx_int = nx_f32_lazy_matmul(BA, Wcache, BCc, 1, LB_K, LB_N)
231 let us_first: i64 = sys_now_us() - tf0
232 if vf != NX_LW_OK { return 22 }
233 if Wcache.pk_state != 1 { return 22 }
234 let t1: i64 = sys_now_us()
235 var r1: i64 = 0
236 while r1 < LB_REPS {
237 let vc: nx_int = nx_f32_lazy_matmul(BA, Wcache, BCc, 1, LB_K, LB_N)
238 if vc != NX_LW_OK { return 23 }
239 r1 = r1 + 1
240 }
241 let us_cached: i64 = (sys_now_us() - t1) / LB_REPS
242
243 var us_a: i64 = us_stream
244 if us_a < 1 { us_a = 1 }
245 var us_c: i64 = us_cached
246 if us_c < 1 { us_c = 1 }
247 let macs: i64 = LB_K * LB_N
248 fmt_puts("stream_us="); fmt_putn(us_a); fmt_puts(" mflops="); fmt_putn(2 * macs / us_a); l_nl()
249 fmt_puts("cache_fill_us="); fmt_putn(us_first); l_nl()
250 fmt_puts("cached_us="); fmt_putn(us_c); fmt_puts(" mflops="); fmt_putn(2 * macs / us_c); l_nl()
251 let sx100: i64 = us_a * 100 / us_c
252 fmt_puts("cached_vs_stream_x100="); fmt_putn(sx100); l_nl()
253
254 // 2026-08-01: the speed FLOOR is demoted to a PRINTED RECORD, not a tooth. The budget owner
255 // measured that streaming quantized weights beats the cache at decode (hence default=0): the
256 // cache reads 4 B/value while fused streaming reads the 0.56 B/value Q4_K bytes, so at the
257 // memory-bound m=1 shape the cache is no longer presumed faster. A PERF GATE IS NOT A
258 // CORRECTNESS GATE -- this gate's load-bearing claim is tooth 8's bit-equality; speed claims
259 // live in nx_q4k_fused_vs_x4_gate and the budget owner's re-measure.
260 fmt_puts("LWC 7 speedup_x100="); fmt_putn(sx100)
261 fmt_puts(" (record only; floor retired with cache-default-0)"); l_nl()
262 pass = pass + 1
263
264 let ok8: i64 = l_same(BCc, BCs, LB_N)
265 if ok8 != 1 {
266 fmt_puts("LWC 8 BIG-EXACT FAIL"); l_nl()
267 return 25
268 }
269 fmt_puts("LWC 8 BIG-EXACT OK"); l_nl()
270 pass = pass + 1
271
272 fmt_puts("LW_CACHE_GATE "); fmt_putn(pass); fmt_puts("/8 inner"); l_nl()
273 return 0
274}
275
276// D001 migration 2026-08-01 (hand-done; dry_apply cannot see this shape). lwc_run's early returns
277// carry DISTINCT ordered codes (11..16 for teeth 1-6, 21-23 bench infra + retired 24 for tooth 7,
278// 25 for tooth 8), so each tooth's true state is EXACTLY derivable from the rc: reaching code N
279// proves every earlier tooth passed. A tooth that never executed reports FAIL, never PASS.
280func main() -> i64 {
281 let ctr: *i64 = gv_ctr()
282 gv_head("nx_lw_cache_gate -- lazy-weight cache transparency: cached==streamed, budget honesty, Q24 domain" as *u8)
283 let rc: i64 = lwc_run()
284
285 var ok: i64 = 0
286 if rc != 11 { ok = 1 }
287 gv_check("T1 scalar oracle runs" as *u8, ok, ctr)
288 ok = 0
289 if rc == 0 { ok = 1 }
290 if rc > 12 { ok = 1 }
291 gv_check("T2 first dispatch fills the Q24 cache + bit-matches the oracle + exact byte accounting" as *u8, ok, ctr)
292 ok = 0
293 if rc == 0 { ok = 1 }
294 if rc > 13 { ok = 1 }
295 gv_check("T3 cache reuse with fresh activations bit-matches" as *u8, ok, ctr)
296 ok = 0
297 if rc == 0 { ok = 1 }
298 if rc > 14 { ok = 1 }
299 gv_check("T4 m=1 decode shape bit-matches" as *u8, ok, ctr)
300 ok = 0
301 if rc == 0 { ok = 1 }
302 if rc > 15 { ok = 1 }
303 gv_check("T5 budget refusal falls back to streaming, still bit-correct" as *u8, ok, ctr)
304 ok = 0
305 if rc == 0 { ok = 1 }
306 if rc > 16 { ok = 1 }
307 gv_check("T6 stale-shape guard surfaces ERR_INNER" as *u8, ok, ctr)
308 ok = 0
309 if rc == 0 { ok = 1 }
310 if rc > 24 { ok = 1 }
311 gv_check("T7 decode bench runs both lanes (speed = printed record, floor retired)" as *u8, ok, ctr)
312 ok = 0
313 if rc == 0 { ok = 1 }
314 gv_check("T8 BIG-EXACT: cached and streamed bit-identical on the big shape" as *u8, ok, ctr)
315
316 // NO sys_exit HERE: this gate holds a LIVE THREAD POOL, and a single-thread exit leaves the
317 // workers as the process -- both "wedged" runs were exactly this (verdict printed, process
318 // immortal, timeout 124). The KAT pattern's sys_exit is only safe in a threadless organ.
319 // Plain return = the pre-migration idiom; the runtime epilogue ends the whole process.
320 return gv_verdict("LW-CACHE-GATE" as *u8, ctr, "cache is a pure optimisation: one numeric domain on both sides" as *u8)
321}