code wiki / (root) / nx_nofloat_gemm.nx

nx_nofloat_gemm.nx source

↩ module page · 41 lines · 2204 B

1// nx_nofloat_gemm.nx -- canonical sovereign INTEGER SIMD GEMM (vpmaddwd / __i16x16_madd): 2// EXACT + DETERMINISTIC + fast = the no-float compute lever every Nishi model rides. Pure funcs, no main. 3// Extracted from nx_nofloat_gemm_gate for debt-free reuse (gate + nx_gpu_bench both import this). 4// __i16x16_madd accumulates 16 signed-int16 products into an int32x8 vector (vpmaddwd + vpaddd, proven VEX); 5// integer add is associative -> bit-exact + deterministic (the no-float exceed axis, unlike float cuBLAS). 6// license_tier: ORIGINAL 7import "nx_syscalls.nx" 8 9func pack2(buf: *u8, idx: i64, val: i64) -> i64 { buf[idx*2]=(val) as u8; buf[idx*2+1]=(val>>8) as u8; return 0 } 10// Horizontal sum of an int32x8 accumulator. vpmaddwd lanes are SIGNED int32; `p[i]` on a *i32 SIGN-extends 11// since the 2026-07-10 sext compiler fix (i32 annotations mint sext=1 -> movslq loads). History: loads used 12// to ZERO-extend (no signedness in the IR), which turned negative lanes into ~4e9 garbage -- caught by the 13// nofloat W8A8 decode, worked around 2026-07-09 with a manual branchless sign-extend, then ROOT-FIXED in the 14// compiler + nxasm and the workaround removed. The gate's T5 negative-lane KAT pins this forever. 15func i32x8_hsum(acc: *u8) -> i64 { let p: *i32 = acc as *i32; var s: i64=0; var i: i64=0; while i<8 { s = s + (p[i] as i64); i=i+1 } return s } 16 17func scalar_imm(ai: *i64, bi: *i64, c: *i64, M: i64, N: i64, K: i64) -> i64 { 18 var i: i64=0 19 while i<M { var j: i64=0 20 while j<N { var acc: i64=0; var k: i64=0 21 while k<K { acc = acc + ai[i*K+k]*bi[j*K+k]; k=k+1 } 22 c[i*N+j]=acc; j=j+1 } 23 i=i+1 } 24 return 0 25} 26func simd_imm(a16: *u8, b16: *u8, c: *i64, acc: *u8, M: i64, N: i64, K: i64) -> i64 { 27 let ab: i64=a16 as i64 28 let bb: i64=b16 as i64 29 let z: *i64 = acc as *i64 30 var i: i64=0 31 while i<M { var j: i64=0 32 while j<N { 33 z[0]=0; z[1]=0; z[2]=0; z[3]=0 34 let ar: i64 = ab + i*K*2 35 let br: i64 = bb + j*K*2 36 var k: i64=0 37 while k<K { __i16x16_madd(acc, (ar+k*2) as *u8, (br+k*2) as *u8); k=k+16 } 38 c[i*N+j]=i32x8_hsum(acc); j=j+1 } 39 i=i+1 } 40 return 0 41}