nx_q4k_simd2_gate.nx
buildroot/runtime/nx_q4k_simd2_gate.nx
about
nx_q4k_simd2_gate.nx -- the REFEREE for __q4k_unpack32s (the nx_cc intrinsic) and nx_q4k_dot_simd2 (2026-09-02, LM4c).
The intrinsic is proven at TWO levels. (1) LANE LEVEL: on packed bytes whose nibbles and scales are chosen so every
expected lane is known, out[k] must equal (byte_k & 15) * sc_lo and out[32+k] must equal (byte_k >> 4) * sc_hi for all
64 lanes, including the extreme lane value 15*63 = 945 (no lane carry) and a zero scale; and a run over 5000 pseudo-random
byte blocks must agree lane-for-lane with the scalar spread+multiply nx_q4k_dot_simd_lib already trusts (ds_spread4).
(2) DOT LEVEL: on 200 pseudo-random Q4_K super-block rows with real-shaped d, dmin, scales and mins, nx_q4k_dot_simd2 must
return EXACTLY what nx_q4k_dot_simd returns (both are exact integer functions of the same bytes) and exactly what the
scalar reference nx_q4k_dot_row_col returns. Neg-controls: a corrupted lane must NOT match (the lane tooth can fail) and a
flipped nibble byte must change the dot (the dot tooth can fail). A timing line reports simd2 vs simd over the same rows
(a number, never a verdict -- the decode benchmark is the speed ruler).
nx_q4k_simd2_gate (no args; needs a compiler that knows __q4k_unpack32s, else it does not build)
license_tier: ORIGINAL. Writes nothing. No hw writes.
dependencies 15 imports · 0 importers
diagram shows first 10 each side; +5 more imports, +0 more importers in the complete lists below.
imports: nx_syscalls.nxnx_tier.nxnx_le.nxnx_tensor.nxnx_gguf.nxnx_gguf_load.nxnx_dequant_iter.nxnx_q4k_matmul.nxnx_clock.nxnx_gate_verdict.nxnx_q4k_dot_simd_lib.nxnx_q4k_dot_simd2_lib.nxnx_thread_pool.nxnx_nofloat_llm.nxnx_nofloat_q4k.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 29 | const G2_LCG_A: i64 = 6364136223846793005 |
| 30 | const G2_LCG_C: i64 = 1442695040888963407 |
| 31 | const G2_LCG_MASK: i64 = 0x7FFFFFFFFFFFFFFF |
| 32 | const G2_LCG_SEED: i64 = 424242424242 |
| 33 | const G2_BYTES: i64 = 32 |
| 34 | const G2_LANES: i64 = 64 |
| 35 | const G2_LANE_MAX: i64 = 945 // 15 * 63 |
| 36 | const G2_SC_MAX: i64 = 63 |
| 37 | const G2_RAND_BLOCKS: i64 = 5000 |
| 38 | const G2_ROWS: i64 = 200 |
| 39 | const G2_NBLK: i64 = 14 // 3584-wide row: the 7B attention shape |
| 40 | const G2_SB: i64 = 144 |
| 41 | const G2_COL_MAX: i64 = 32767 |
| 42 | const G2_TIMING_ITERS: i64 = 2000 |
| 43 | const G2_QBUF_BYTES: i64 = 128 |
| 44 | const G2_NIBBLE_MASK: i64 = 15 |
| 45 | const G2_NIB_SHIFT: i64 = 4 |
| 46 | const G2_SC_HI_SHIFT: i64 = 16 |
functions
| 49 | func g2_lcg() -> i64 { g_g2_st = (g_g2_st*G2_LCG_A + G2_LCG_C) & G2_LCG_MASK; return g_g2_st >> 16 } |
| 52 | func g2_lane(p: *u8, k: i64) -> i64 { var v: i64 = nx_le_read_u16(p, k*2); if v >= 32768 { v = v - 65536 } return v } |
| 55 | func g2_lanes_ok(qs: *u8, out: *u8, sclo: i64, schi: i64) -> i64 |
| 68 | func g2_scalar_unpack(qs: *u8, out: *i64, sclo: i64, schi: i64) -> i64 |
| 82 | func g2_bufs_equal(a: *u8, b: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { if a[i] != b[i] { return 0 } i = i + 1 } return 1 } called by 1: main |
| 85 | func g2_fill_row(buf: *u8, nblk: i64) -> i64 |
| 112 | func main() -> i64 |