code wiki / (root) / nx_simd_i16x16_test.nx

nx_simd_i16x16_test.nx source

↩ module page · 118 lines · 4755 B

1// nx_simd_i16x16_test.nx -- exercise the i16x16 SIMD intrinsics. 2// 3// 16 lanes of 16-bit ints in 256-bit vectors. Same bit-exact-vs- 4// scalar gate as the i64x4 and i32x8 smokes. Useful for image 5// processing / audio / quantized ML weights at int16. 6 7import "nx_kernel_v2.nx" 8import "nx_log.nx" 9 10// Pack 4 i16 into one i64 (lane order LE: low-16 first). 11func pack4(a: i64, b: i64, c: i64, d: i64) -> i64 { 12 return (a & 0xFFFF) | ((b & 0xFFFF) << 16) | ((c & 0xFFFF) << 32) | ((d & 0xFFFF) << 48) 13} 14 15func t1_load_store() -> i64 { 16 let a_raw: *u8 = sys_mmap(64) 17 let r_raw: *u8 = sys_mmap(64) 18 let a: *i64 = a_raw as *i64 19 let r: *i64 = r_raw as *i64 20 a[0] = pack4(1, 2, 3, 4) 21 a[1] = pack4(5, 6, 7, 8) 22 a[2] = pack4(9, 10, 11, 12) 23 a[3] = pack4(13, 14, 15, 16) 24 let v: i64 = __simd_vload_i16_x16(a as *i64) 25 __simd_vstore_i16_x16(v, r as *i64) 26 if r[0] != pack4(1, 2, 3, 4) { return 1 } 27 if r[1] != pack4(5, 6, 7, 8) { return 2 } 28 if r[2] != pack4(9, 10, 11, 12) { return 3 } 29 if r[3] != pack4(13, 14, 15, 16) { return 4 } 30 return 0 31} 32 33func t2_vadd() -> i64 { 34 let a_raw: *u8 = sys_mmap(64) 35 let b_raw: *u8 = sys_mmap(64) 36 let r_raw: *u8 = sys_mmap(64) 37 let a: *i64 = a_raw as *i64 38 let b: *i64 = b_raw as *i64 39 let r: *i64 = r_raw as *i64 40 a[0] = pack4(10, 20, 30, 40); a[1] = pack4(50, 60, 70, 80) 41 a[2] = pack4(90, 100, 110, 120); a[3] = pack4(130, 140, 150, 160) 42 b[0] = pack4(1, 2, 3, 4); b[1] = pack4(5, 6, 7, 8) 43 b[2] = pack4(9, 10, 11, 12); b[3] = pack4(13, 14, 15, 16) 44 let va: i64 = __simd_vload_i16_x16(a as *i64) 45 let vb: i64 = __simd_vload_i16_x16(b as *i64) 46 let vsum: i64 = __simd_vadd_i16_x16(va, vb) 47 __simd_vstore_i16_x16(vsum, r as *i64) 48 // (11, 22, 33, 44, 55, 66, 77, 88, 99, 110, 121, 132, 143, 154, 165, 176) 49 if r[0] != pack4(11, 22, 33, 44) { return 10 } 50 if r[1] != pack4(55, 66, 77, 88) { return 11 } 51 if r[2] != pack4(99, 110, 121, 132) { return 12 } 52 if r[3] != pack4(143, 154, 165, 176) { return 13 } 53 return 0 54} 55 56func t3_vmul() -> i64 { 57 let a_raw: *u8 = sys_mmap(64) 58 let b_raw: *u8 = sys_mmap(64) 59 let r_raw: *u8 = sys_mmap(64) 60 let a: *i64 = a_raw as *i64 61 let b: *i64 = b_raw as *i64 62 let r: *i64 = r_raw as *i64 63 a[0] = pack4(10, 20, 30, 40); a[1] = pack4(50, 60, 70, 80) 64 a[2] = pack4(90, 100, 110, 120); a[3] = pack4(130, 140, 150, 160) 65 b[0] = pack4(1, 2, 3, 4); b[1] = pack4(5, 6, 7, 8) 66 b[2] = pack4(9, 10, 11, 12); b[3] = pack4(13, 14, 15, 16) 67 let va: i64 = __simd_vload_i16_x16(a as *i64) 68 let vb: i64 = __simd_vload_i16_x16(b as *i64) 69 let vp: i64 = __simd_vmul_i16_x16(va, vb) 70 __simd_vstore_i16_x16(vp, r as *i64) 71 // (10, 40, 90, 160, 250, 360, 490, 640, 810, 1000, 1210, 1440, 1690, 1960, 2250, 2560) 72 if r[0] != pack4(10, 40, 90, 160) { return 20 } 73 if r[1] != pack4(250, 360, 490, 640) { return 21 } 74 if r[2] != pack4(810, 1000, 1210, 1440) { return 22 } 75 if r[3] != pack4(1690, 1960, 2250, 2560) { return 23 } 76 return 0 77} 78 79func t4_vbroadcast() -> i64 { 80 let r_raw: *u8 = sys_mmap(64) 81 let r: *i64 = r_raw as *i64 82 let v: i64 = __simd_vbroadcast_i16_x16(42) 83 __simd_vstore_i16_x16(v, r as *i64) 84 if r[0] != pack4(42, 42, 42, 42) { return 30 } 85 if r[1] != pack4(42, 42, 42, 42) { return 31 } 86 if r[2] != pack4(42, 42, 42, 42) { return 32 } 87 if r[3] != pack4(42, 42, 42, 42) { return 33 } 88 return 0 89} 90 91func t5_vreduce_sum() -> i64 { 92 let a_raw: *u8 = sys_mmap(64) 93 let a: *i64 = a_raw as *i64 94 a[0] = pack4(10, 20, 30, 40); a[1] = pack4(50, 60, 70, 80) 95 a[2] = pack4(90, 100, 110, 120); a[3] = pack4(130, 140, 150, 160) 96 let v: i64 = __simd_vload_i16_x16(a as *i64) 97 let s: i64 = __simd_vreduce_sum_i16_x16(v) 98 // 10+20+...+160 = (10+160)*16/2 = 170*8 = 1360 99 if s != 1360 { return 40 } 100 return 0 101} 102 103func main() -> nx_exit { 104 println("=== nx_simd_i16x16 smoke (16 lanes of 16-bit) ===" as *u8) 105 if t1_load_store() != 0 { println("FAIL T1" as *u8); return 1 } 106 println("T1 vload+vstore PASS 16-lane i16 round-trip" as *u8) 107 if t2_vadd() != 0 { println("FAIL T2" as *u8); return 2 } 108 println("T2 vadd PASS lanes (11..176) bit-exact" as *u8) 109 if t3_vmul() != 0 { println("FAIL T3" as *u8); return 3 } 110 println("T3 vmul PASS lanes (10..2560) bit-exact" as *u8) 111 if t4_vbroadcast() != 0 { println("FAIL T4" as *u8); return 4 } 112 println("T4 vbroadcast PASS all 16 lanes = 42" as *u8) 113 if t5_vreduce_sum() != 0 { println("FAIL T5" as *u8); return 5 } 114 println("T5 vreduce_sum PASS 10+20+...+160 = 1360" as *u8) 115 println("" as *u8) 116 println("All i16x16 ops bit-exact; 16-lane throughput proven." as *u8) 117 return 0 118}