code wiki / _hdl_build / nx_qmatvec.nx
nx_qmatvec.nx
buildroot/runtime/_hdl_build/nx_qmatvec.nx
about
nx_qmatvec.nx -- the FIRST real kernel toward beating ggml/llama.cpp: a sovereign block-
quantized DOT PRODUCT (the hot path of LLM decode), built bits-up. The roofline proved decode
is MEMORY-bound, so the lever is MOVING LESS DATA -- this kernel does exactly that, and the
ENGINEER verifies it 1:1 against the exact dot while the quality (error) is measured vs the
Council's floor. Integer-only by design (no fp dequant) -- a real efficiency edge for the
edge/energy north-star.
Scheme (ggml Q4_0/Q8_0 structure, integer scales): weights in blocks of B=32; each block has
ONE integer scale S = max|w| in the block; each weight becomes a signed code q in [-QMAX,QMAX]
(4-bit: -7..7, or 8-bit: -127..127). Dequant w' = q*S/QMAX. The block scale FACTORS OUT of the
inner loop (ggml's key trick): block_dot = (S/QMAX) * sum_i q_i*x_i, so the hot loop is pure
integer multiply-accumulate of small codes, and S applies once per block.
bytes moved (what DRAM must deliver, the memory-bound cost):
Q4: 4 bits/weight + 2 bytes scale per 32 = 4.5 bits/weight
Q8: 8 bits/weight + 2 bytes scale per 32 = 8.5 bits/weight vs int16 ref = 16 bits/weight
license_tier: ORIGINAL Refs: ggml Q4_0/Q8_0 block quantization; the memory-bound roofline.
dependencies 1 imports · 3 importers
imports: nx_syscalls.nx
imported by: nx_kquant.nxnx_qlayer.nxnx_qmatvec_test.nx
structs
| none |
consts
| 20 | const QMV_B: i64 = 32 // block size (ggml Q4_0/Q8_0) |
| 21 | const QMV_Q4MAX: i64 = 7 // 4-bit signed symmetric range -7..7 |
| 22 | const QMV_Q8MAX: i64 = 127 // 8-bit signed symmetric range -127..127 |
functions
| 24 | func qmv_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } called by 1: qmv_block_scale |
| 27 | func qmv_block_scale(w: *i64, off: i64, len: i64) -> i64 |
| 34 | func qmv_code(wv: i64, s: i64, qmax: i64) -> i64 |
| 48 | func qmv_dot_q(w: *i64, x: *i64, n: i64, qmax: i64) -> i64 |
| 62 | func qmv_dot_exact(w: *i64, x: *i64, n: i64) -> i64 called by 1: main |
| 69 | func qmv_bytes_q(n: i64, bits: i64) -> i64 called by 1: main |
| 73 | func qmv_bytes_ref16(n: i64) -> i64 { return n * 2 } // int16 (fp16-equivalent) baseline called by 1: main |
| 77 | func qmv_rel_error_permil(approx: i64, exact: i64) -> i64 called by 1: main |