code wiki / (root) / nx_simd_i32x8_test.nx

nx_simd_i32x8_test.nx source

↩ module page · 130 lines · 4729 B

1// nx_simd_i32x8_test.nx -- exercise the i32x8 SIMD intrinsics. 2// 3// Same scalar-vs-SIMD-bit-exact gate as nx_simd_test.nx but with 4// 8 i32 lanes per vector (double the throughput of i64x4 for 5// 32-bit workloads -- ML token IDs, image pixels, hashes). 6 7import "nx_kernel_v2.nx" 8import "nx_log.nx" 9 10// NX_MO_SEQ_CST is no longer declared here: it moved to nx_syscalls.nx on 2026-08-25 and this file 11// already imports it transitively. This was the third of three independent declarations of the same 12// value (corpus_complete=1), deleted rather than kept in sync. 13 14func t1_round_trip_load_store() -> i64 { 15 let a_raw: *u8 = sys_mmap(64) 16 let r_raw: *u8 = sys_mmap(64) 17 let a: *i64 = a_raw as *i64 18 let r: *i64 = r_raw as *i64 19 // Fill 8 i32 lanes as 4 i64 words (lane order LE: low-i32 first). 20 // Encode (10, 20, 30, 40, 50, 60, 70, 80) -> pack into i64s. 21 a[0] = (20 << 32) | 10 22 a[1] = (40 << 32) | 30 23 a[2] = (60 << 32) | 50 24 a[3] = (80 << 32) | 70 25 let v: i64 = __simd_vload_i32_x8(a as *i64) 26 __simd_vstore_i32_x8(v, r as *i64) 27 if r[0] != ((20 << 32) | 10) { return 1 } 28 if r[1] != ((40 << 32) | 30) { return 2 } 29 if r[2] != ((60 << 32) | 50) { return 3 } 30 if r[3] != ((80 << 32) | 70) { return 4 } 31 return 0 32} 33 34func t2_vadd() -> i64 { 35 let a_raw: *u8 = sys_mmap(64) 36 let b_raw: *u8 = sys_mmap(64) 37 let r_raw: *u8 = sys_mmap(64) 38 let a: *i64 = a_raw as *i64 39 let b: *i64 = b_raw as *i64 40 let r: *i64 = r_raw as *i64 41 a[0] = (20 << 32) | 10 42 a[1] = (40 << 32) | 30 43 a[2] = (60 << 32) | 50 44 a[3] = (80 << 32) | 70 45 b[0] = (2 << 32) | 1 46 b[1] = (4 << 32) | 3 47 b[2] = (6 << 32) | 5 48 b[3] = (8 << 32) | 7 49 let va: i64 = __simd_vload_i32_x8(a as *i64) 50 let vb: i64 = __simd_vload_i32_x8(b as *i64) 51 let vsum: i64 = __simd_vadd_i32_x8(va, vb) 52 __simd_vstore_i32_x8(vsum, r as *i64) 53 // (10+1, 20+2, 30+3, 40+4, 50+5, 60+6, 70+7, 80+8) = 54 // (11, 22, 33, 44, 55, 66, 77, 88) 55 if r[0] != ((22 << 32) | 11) { return 10 } 56 if r[1] != ((44 << 32) | 33) { return 11 } 57 if r[2] != ((66 << 32) | 55) { return 12 } 58 if r[3] != ((88 << 32) | 77) { return 13 } 59 return 0 60} 61 62func t3_vmul() -> i64 { 63 let a_raw: *u8 = sys_mmap(64) 64 let b_raw: *u8 = sys_mmap(64) 65 let r_raw: *u8 = sys_mmap(64) 66 let a: *i64 = a_raw as *i64 67 let b: *i64 = b_raw as *i64 68 let r: *i64 = r_raw as *i64 69 a[0] = (20 << 32) | 10 70 a[1] = (40 << 32) | 30 71 a[2] = (60 << 32) | 50 72 a[3] = (80 << 32) | 70 73 b[0] = (2 << 32) | 1 74 b[1] = (4 << 32) | 3 75 b[2] = (6 << 32) | 5 76 b[3] = (8 << 32) | 7 77 let va: i64 = __simd_vload_i32_x8(a as *i64) 78 let vb: i64 = __simd_vload_i32_x8(b as *i64) 79 let vp: i64 = __simd_vmul_i32_x8(va, vb) 80 __simd_vstore_i32_x8(vp, r as *i64) 81 // (10, 40, 90, 160, 250, 360, 490, 640) 82 if r[0] != ((40 << 32) | 10) { return 20 } 83 if r[1] != ((160 << 32) | 90) { return 21 } 84 if r[2] != ((360 << 32) | 250) { return 22 } 85 if r[3] != ((640 << 32) | 490) { return 23 } 86 return 0 87} 88 89func t4_vbroadcast() -> i64 { 90 let r_raw: *u8 = sys_mmap(64) 91 let r: *i64 = r_raw as *i64 92 let v: i64 = __simd_vbroadcast_i32_x8(7) 93 __simd_vstore_i32_x8(v, r as *i64) 94 if r[0] != ((7 << 32) | 7) { return 30 } 95 if r[1] != ((7 << 32) | 7) { return 31 } 96 if r[2] != ((7 << 32) | 7) { return 32 } 97 if r[3] != ((7 << 32) | 7) { return 33 } 98 return 0 99} 100 101func t5_vreduce_sum() -> i64 { 102 let a_raw: *u8 = sys_mmap(64) 103 let a: *i64 = a_raw as *i64 104 a[0] = (20 << 32) | 10 105 a[1] = (40 << 32) | 30 106 a[2] = (60 << 32) | 50 107 a[3] = (80 << 32) | 70 108 let v: i64 = __simd_vload_i32_x8(a as *i64) 109 let s: i64 = __simd_vreduce_sum_i32_x8(v) 110 // Sum (10+20+30+40+50+60+70+80) = 360 111 if s != 360 { return 40 } 112 return 0 113} 114 115func main() -> nx_exit { 116 println("=== nx_simd_i32x8 smoke (8 lanes of 32-bit) ===" as *u8) 117 if t1_round_trip_load_store() != 0 { println("FAIL T1" as *u8); return 1 } 118 println("T1 vload+vstore PASS 8-lane i32 round-trip" as *u8) 119 if t2_vadd() != 0 { println("FAIL T2" as *u8); return 2 } 120 println("T2 vadd PASS lanes (11..88) bit-exact" as *u8) 121 if t3_vmul() != 0 { println("FAIL T3" as *u8); return 3 } 122 println("T3 vmul PASS lanes (10,40,90,160,250,360,490,640)" as *u8) 123 if t4_vbroadcast() != 0 { println("FAIL T4" as *u8); return 4 } 124 println("T4 vbroadcast PASS all 8 lanes = 7" as *u8) 125 if t5_vreduce_sum() != 0 { println("FAIL T5" as *u8); return 5 } 126 println("T5 vreduce_sum PASS 10+20+...+80 = 360" as *u8) 127 println("" as *u8) 128 println("All i32x8 SIMD ops bit-exact vs scalar; 8-lane throughput proven." as *u8) 129 return 0 130}