code wiki / (root) / nx_i8dot32a_kat.nx

nx_i8dot32a_kat.nx source

↩ module page · 57 lines · 1999 B

1// nx_i8dot32a_kat.nx -- KAT for the AVX2 __f32_i8dot32a intrinsic. 2// __f32_i8dot32a(a:*i8[32], b:*f32[32]) = sum_{j<32} sext(a[j]) * b[j], with 3// 2-accumulator AVX2 summation. Exact-INTEGER inputs (int8 x small-int f32, 4// all products+sums exactly representable) so the result is order-INDEPENDENT 5// -> must equal BOTH the scalar reference AND the SSE __f32_i8dot32 exactly. 6// That proves the AVX2 codegen (vpmovsxbd/vcvtdq2ps/vmulps/vaddps + 2-acc 7// combine + hsum) computes the right values. expect_exit: 0 (77/78/79 fail) 8import "nx_syscalls.nx" 9import "nx_f32.nx" 10import "nx_f32_cvt.nx" 11 12func k_st4(p: *u8, idx: i64, bits: i64) -> i64 { 13 p[idx*4+0] = bits as u8 14 p[idx*4+1] = (bits>>8) as u8 15 p[idx*4+2] = (bits>>16) as u8 16 p[idx*4+3] = (bits>>24) as u8 17 return 0 18} 19 20func main() -> i64 { 21 let a: *u8 = sys_mmap(32) 22 let b: *u8 = sys_mmap(32 * 4) 23 var j: i64 = 0 24 while j < 32 { 25 a[j] = (j - 16) as u8 26 k_st4(b, j, nx_i32_to_f32((j % 3) + 1)) 27 j = j + 1 28 } 29 // scalar reference 30 var ref: i64 = 0 31 var k: i64 = 0 32 while k < 32 { 33 ref = __f32_add(ref, __f32_mul(nx_i32_to_f32(k - 16), nx_i32_to_f32((k % 3) + 1))) 34 k = k + 1 35 } 36 // AVX2 == scalar AND AVX2 == SSE (exact-int -> order-independent) 37 if __f32_i8dot32a(a, b) != ref { return 77 } 38 if __f32_i8dot32a(a, b) != __f32_i8dot32(a, b) { return 77 } 39 40 // all +1 41 var j2: i64 = 0 42 while j2 < 32 { a[j2] = 1 as u8; j2 = j2 + 1 } 43 var ref2: i64 = 0 44 var k2: i64 = 0 45 while k2 < 32 { ref2 = __f32_add(ref2, nx_i32_to_f32((k2 % 3) + 1)); k2 = k2 + 1 } 46 if __f32_i8dot32a(a, b) != ref2 { return 78 } 47 48 // negatives, all -2 49 var j3: i64 = 0 50 while j3 < 32 { a[j3] = (0 - 2) as u8; j3 = j3 + 1 } 51 var ref3: i64 = 0 52 var k3: i64 = 0 53 while k3 < 32 { ref3 = __f32_add(ref3, __f32_mul(nx_i32_to_f32(0 - 2), nx_i32_to_f32((k3 % 3) + 1))); k3 = k3 + 1 } 54 if __f32_i8dot32a(a, b) != ref3 { return 79 } 55 56 return 0 57}