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}