code wiki / _hdl_build / nx_f32_hw_matmul.nx

nx_f32_hw_matmul.nx source

↩ module page · 67 lines · 2979 B

1// nx_f32_hw_matmul.nx -- HARDWARE-float GEMM (the rung above the software nx_f32_matmul). 2// 3// module: nishi-core.genealogy.f32_hw_matmul 4// capability: CORE_COMPUTE (escape the math perf lock via the SSE hardware-float rung) 5// 6// Same GEMM as nx_f32_matmul, but the inner MAC uses nx_f32_hw's f32_add/f32_mul -- which compile 7// to SSE addss/mulss on the real FPU (rung A, nx_f32_sse_kat_gate GREEN) -- instead of the bits-up 8// SOFTWARE f32. binary32 layout is identical, so results are bit-for-bit cross-checkable against the 9// software matmul (the gate's differential). This is the measured lever for the math/simd lock. 10// Sovereign: imports nx_f32_hw (-> __f32_* SSE intrinsics) + nx_syscalls. license_tier: ORIGINAL 11import "nx_f32_hw.nx" 12import "nx_syscalls.nx" 13 14const NX_HWMM_OK: i64 = 0 15const NX_HWMM_ERR: i64 = 1 16 17func hmm_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != 0 as u8 { n = n + 1 } sys_write(1, s, n); return 0 } 18func hmm_putn(v: i64) -> i64 { 19 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 20 var m: i64 = v 21 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 22 let d: *u8 = sys_mmap(24); var k: i64 = 0 23 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 24 var j: i64 = k - 1 25 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 } 26 return 0 27} 28 29// C[m,n] = A[m,k] @ B[k,n], row-major, hardware-float MAC. 30func nx_f32_hw_matmul(a: *i64, b: *i64, c: *i64, m: i64, k: i64, n: i64) -> i64 { 31 if m <= 0 { return NX_HWMM_ERR } 32 if k <= 0 { return NX_HWMM_ERR } 33 if n <= 0 { return NX_HWMM_ERR } 34 var i: i64 = 0 35 while i < m { 36 var j: i64 = 0 37 while j < n { 38 // hot loop uses the __f32_* intrinsics DIRECTLY (compiler emits addss/mulss INLINE) -- 39 // bit-identical to the f32_add/f32_mul wrappers but no per-MAC call overhead (~1.6x, 40 // measured in nx_f32_intrin_matmul). Differential gate stays bit-exact vs nx_f32_matmul. 41 var acc: i64 = __f32_from_i64(0) 42 var l: i64 = 0 43 while l < k { 44 acc = __f32_add(acc, __f32_mul(a[i * k + l], b[l * n + j])) 45 l = l + 1 46 } 47 c[i * n + j] = acc 48 j = j + 1 49 } 50 i = i + 1 51 } 52 return NX_HWMM_OK 53} 54 55func main() -> i64 { 56 hmm_puts("=== hardware-float GEMM demo (SSE addss/mulss) ===\n") 57 let A: *i64 = sys_mmap(4 * 8) as *i64 58 A[0] = f32_of(1); A[1] = f32_of(2); A[2] = f32_of(3); A[3] = f32_of(4) 59 let B: *i64 = sys_mmap(4 * 8) as *i64 60 B[0] = f32_of(5); B[1] = f32_of(6); B[2] = f32_of(7); B[3] = f32_of(8) 61 let C: *i64 = sys_mmap(4 * 8) as *i64 62 nx_f32_hw_matmul(A, B, C, 2, 2, 2) 63 hmm_puts(" [[1,2],[3,4]] @ [[5,6],[7,8]] = [[") 64 hmm_putn(f32_int(C[0])); hmm_puts(","); hmm_putn(f32_int(C[1])); hmm_puts("],[") 65 hmm_putn(f32_int(C[2])); hmm_puts(","); hmm_putn(f32_int(C[3])); hmm_puts("]] (expect [[19,22],[43,50]])\n") 66 sys_exit(0); return 0 67}