code wiki / (root) / nx_batchscale_kat.nx

nx_batchscale_kat.nx

buildroot/runtime/nx_batchscale_kat.nx

6284 B136 linesdepth 10pulls 30 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_batchscale_kat.nx -- IS THE MATMUL PATH AMORTISING ACROSS m? The decisive perf question, answered WITHOUT loading a model, so it fits inside a bounded verifier run. WHY (2026-07-31): the sovereign embedder measures ~350-400ms/token against a 54.5ms roofline (491MB gguf model / 9011 MB/s measured bandwidth) = **~7x off floor** (ids 1785475195, 1785475543). The prime suspect is named by the codebase itself: nx_embed_bench exists to ask 'is prefill actually BATCHING?' and states the rule -- FLAT ms_per_token across m => prefill is NOT batching (wire the m>1 packed path in lazy_matmul); FALLING => batching works and the cost lives elsewhere. BUT nx_embed_bench CANNOT BE RUN: /api/gate_run executes VERIFIERS ONLY (correct never-brick bound) and its 491MB model load alone is 16554..20767ms against a 12000ms deadline (id 1785475610). So the decisive measurement was unreachable. THIS KAT REMOVES THE MODEL FROM THE QUESTION. Batching is a property of the MATMUL PATH, not of the weights: if C[m,n] = A[m,k] . W[k,n] costs the same per-row at m=8 as at m=1, then the weight bytes are being re-read per row and nothing is amortising -- which is exactly what a bandwidth-bound decode looks like when the m>1 path is unwired. Synthetic W at the real FFN inner dim (k=896, Qwen W_gate) makes the shape honest while keeping the run bounded. READING THE RESULT: us_per_row FLAT across m -> NOT amortising; each row re-streams W. Wire the m>1 packed path. us_per_row FALLING with m -> amortising; W is read once per tile and the 7x lives elsewhere. The ratio us_per_row(m=1) / us_per_row(m=8) IS the batching speedup, measured on this host. HONESTY: this measures the MATMUL path only. It does NOT prove end-to-end prefill batching (attention, rope and norms are excluded) -- it isolates the one layer the ecosystem's own note points at, and a FLAT result here is sufficient to act on because no amount of downstream work can amortise what this layer already re-read. Timings are one run on a shared NAS: ONE WINDOW IS NOT A RATE, so the KAT prints every m and lets the reader see the shape rather than trusting a single ratio. license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0

dependencies 4 imports · 0 importers

nx_f32_lazy_weight.nx nx_f32_matmul_t.nx nx_f32_cvt.nx nx_fmt.nx nx_batchscale_kat.nx

imports: nx_f32_lazy_weight.nxnx_f32_matmul_t.nxnx_f32_cvt.nxnx_fmt.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main bs_fill bs_lcg nx_i32_to_f32 nx_lw_shared_pool nx_pool_is_native fmt_puts fmt_puts_fd sys_write fmt_putn fmt_putn_fd sys_write ↻ bs_nl fmt_puts ↻ nx_f32_matmul_t_pool sys_mmap nx_pool_n_completed nx_atom_load_i64 nx_pool_submit nx_atom_faa_i64 nx_chan_send nx_chan_try_send _nx_chan_cell nx_thread_yield _pool_futex_wake_all sys_futex_wake nx_pool_wait nx_atom_load_i64 ↻ nx_thread_yield ↻ nx_atom_store_i64 _pool_futex_wait sys_futex_wait sys_munmap sys_now_us sys_mmap ↻ sys_clock_gettime_mono

structs

none

consts

36const BK: i64 = 896 // real Qwen FFN inner dim
37const BN: i64 = 1024 // reduced from 4864 so the sweep fits a bounded verifier run
38const BMAX: i64 = 8

functions

40func bs_lcg(s: i64) -> i64
called by 1: bs_fill
46func bs_fill(p: *i64, count: i64, seed: i64) -> i64
called by 1: main calls 2: bs_lcgnx_i32_to_f32
57func bs_nl() -> i64 { fmt_puts("\n" as *u8); return 0 }
called by 1: main calls 1: fmt_puts
59func main() -> i64