code wiki / (root) / nx_lowrank_attn.nx

nx_lowrank_attn.nx

buildroot/runtime/nx_lowrank_attn.nx

17040 B402 linesdepth 6pulls 9 transitivereach 0 importersview sourcekind tooltopic lowrank
docsdependenciesstructsconstsfunctions

about

nx_lowrank_attn.nx -- M3: low-rank KV through a REAL softmax-attention forward (end-to-end quality proof). module: nishi-core.ai.lowrank_attn capability: VRAM_REDUCTION (per-token low-rank KV, measured end-to-end) M0/M1 measured COVARIANCE fidelity (K^T K) of an FD sketch. But softmax attention needs PER-TOKEN scores Q.K[i], which an FD covariance sketch cannot give. The per-token low-rank compression that DOES work is Eigen-Attention / SVD-projection: find the top-r right singular basis V_r [r x d] of K (top-r eigenvectors of K^T K), store per-token coords[i] = K[i] @ V_r^T (n x r) + the shared basis (r x d), reconstruct K[i] ~= coords[i] @ V_r. This PRESERVES per-token identity -> usable in real attention. The eigen-extraction REUSES the M1 lesson: reorthogonalize (Gram-Schmidt twice) or the dominant direction leaks under f32. PROOF: compare the attention OUTPUT (after softmax + value mixing) full-KV vs compressed-KV. For genuinely rank-2 K/V, compressing to r>=2 reconstructs exactly -> output error ~0 (VRAM cut, quality kept end-to-end). Sovereign: nx_f32_hw (SSE arith) + nx_f32_sqrt + nx_f32_softmax (reused). no gcc. HONEST: reference-scale d=8.

dependencies 4 imports · 0 importers

nx_syscalls.nx nx_f32_hw.nx nx_f32.nx nx_f32_softmax.nx nx_lowrank_attn.nx

imports: nx_syscalls.nxnx_f32_hw.nxnx_f32.nxnx_f32_softmax.nx

imported by: nobody (leaf or entry point)

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

main g_puts sys_write la_strlen g_putn sys_write ↻ sys_mmap f32_div f32_of nx_f32_sqrt nx_f32_classify nx_f32_exp_field nx_f32_mant_field nx_f32_sign nx_f32_exp_field ↻ nx_f32_mant_field ↻ _f32_isqrt sys_mmap ↻ la_build_rankr sys_mmap ↻ f32frac f32_div ↻ f32_of ↻ la_lcg f32_add f32_mul f32frac ↻ la_lcg ↻ la_attention sys_mmap ↻ f32_add ↻ f32_mul ↻ nx_f32_softmax _f32_gt nx_f32_sub nx_f32_add nx_f32_classify ↻ nx_f32_sign ↻ nx_f32_mant_field ↻ nx_f32_exp_field ↻

structs

none

consts

19const LA_MAGIC_1103515245: i64 = 1103515245
20const LA_MAGIC_12345: i64 = 12345
21const LA_MAGIC_2048: i64 = 2048
22const LA_MAGIC_4096: i64 = 4096
23const LA_MAGIC_99991: i64 = 99991
24const LA_MAGIC_11003: i64 = 11003
25const LA_MAGIC_22013: i64 = 22013
26const LA_MAGIC_33029: i64 = 33029
27const LA_MAGIC_44039: i64 = 44039
28const LA_MAGIC_55049: i64 = 55049
29const LA_MAGIC_60061: i64 = 60061
30const LA_MAGIC_70067: i64 = 70067
31const LA_MAGIC_80071: i64 = 80071
33const LA_POWER_ITERS: i64 = 64

functions

36func la_strlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
called by 1: g_puts
37func g_puts(s: *u8) -> i64 { sys_write(1, s, la_strlen(s)); return 0 }
called by 1: main calls 2: sys_writela_strlen
38func g_putn(v: i64) -> i64
called by 1: main calls 2: sys_writesys_mmap
50func la_is_zero(x: i64) -> i64 { if (x & 0x7fffffff) == 0 { return 1 } return 0 }
52func f32frac(num: i64, den: i64) -> i64 { return f32_div(f32_of(num), f32_of(den)) }
55func la_lcg(st: *i64) -> i64 { st[0] = st[0] * LA_MAGIC_1103515245 + LA_MAGIC_12345; return (st[0] >> 20) & 0xfff }
58func la_build_rankr(M: *i64, n: i64, d: i64, r: i64, seed: i64) -> i64
83func la_dot(a: *i64, b: *i64, n: i64) -> i64
called by 1: la_normalize calls 2: f32_addf32_mul
90func la_normalize(v: *i64, n: i64) -> i64
102func la_gmatvec(G: *i64, v: *i64, d: i64, out: *i64) -> i64
called by 1: la_topr_basis calls 2: f32_addf32_mul
115func la_deflate_once(v: *i64, basis: *i64, found: i64, d: i64) -> i64
called by 1: la_reorth calls 3: f32_addf32_mulf32_sub
127func la_reorth(v: *i64, basis: *i64, found: i64, d: i64) -> i64
called by 1: la_topr_basis calls 1: la_deflate_once
132func la_topr_basis(G: *i64, d: i64, r: i64, basis: *i64) -> i64
165func la_gram(M: *i64, n: i64, d: i64, G: *i64) -> i64
183func la_compress_reconstruct(M: *i64, n: i64, d: i64, r: i64, Mout: *i64) -> i64
214func la_attention(Q: *i64, Km: *i64, Vm: *i64, n: i64, d: i64, scale: i64, out: *i64) -> i64
238func la_rel_permille(a: *i64, b: *i64, d: i64) -> i64
254func la_run_compressed(Q: *i64, K: *i64, V: *i64, n: i64, d: i64, r: i64, scale: i64, out_full: *i64) -> i64
265func la_build_approx(M: *i64, n: i64, d: i64, base: i64, noise_num: i64, seed: i64) -> i64
274func main() -> i64