nx_q5_0_to_f32_test.nx source
↩ module page · 57 lines · 2223 B
1// nx_q5_0_to_f32_test.nx -- smoke for nx_q5_0_to_f32.nx.
2//
3// Synthetic Q5_0 block per ggml convention:
4// d = 1.0 (f16=0x3C00)
5// qh = 0xFF (bits 0..7 set, so qh_bit_lo for j=0..7 is 1; qh_bit_hi
6// for j=0..7 (= positions 16..23) is bit(j+16)=0)
7// qs bytes: byte j has low nibble = j, high nibble = j+16
8// (chosen so that bit-exact verification is straightforward)
9//
10// Expected per-position values (after this commit's bug fix):
11// j in 0..7: value[j] = (qs_low | 16) - 16 = j -> f32(j)
12// j in 8..15: value[j] = qs_low - 16 = j - 16 -> negative
13// j in 0..15: value[j+16] = qs_high - 16 (qh_bit_hi=0)
14// with qs_high = (j+16): value = j + 16 - 16 = j -> f32(j)
15
16import "nx_syscalls.nx"
17import "nx_tier.nx"
18import "nx_le.nx"
19import "nx_f32.nx"
20import "nx_q5_0_to_f32.nx"
21
22func main() -> i64 {
23 let buf: *u8 = sys_mmap(64)
24 nx_le_write_u16(buf, 0, 0x3C00) // d = 1.0
25 nx_le_write_u32(buf, 2, 0xFF) // qh: bits 0..7 set
26
27 // qs: 16 bytes. Byte j has low nibble = j, high nibble = (j+16) & 0xF.
28 var j: i64 = 0
29 while j < 16 {
30 let lo: i64 = j & 0x0F // low nibble = j (0..15)
31 let hi: i64 = (j + 16) & 0x0F // high nibble = (j+16) mod 16
32 let packed: i64 = lo | (hi << 4)
33 buf[6 + j] = packed as u8
34 j = j + 1
35 }
36
37 let out: *i64 = sys_mmap(32 * 8) as *i64
38 nx_q5_0_to_f32(buf, 0, 32, out)
39
40 // For position j in [0,7]: qs_lo=j, qh_bit_lo=1 -> q5=j+16, signed=j
41 if out[0] != 0 { return 10 } // j=0 -> 0.0
42 if out[1] != 0x3F800000 { return 11 } // j=1 -> 1.0
43 if out[7] != 0x40E00000 { return 17 } // j=7 -> 7.0
44
45 // For position j in [8,15]: qs_lo=j, qh_bit_lo=0 -> q5=j, signed=j-16
46 if out[8] != 0xC1000000 { return 18 } // j=8 -> -8.0
47 if out[15] != 0xBF800000 { return 25 } // j=15 -> -1.0
48
49 // For position j+16 (j in [0,15]): qs_hi=(j+16)&0xF, qh_bit_hi = (qh>>(j+16))&1 = 0
50 // value = ((j+16) & 0xF) - 16
51 // j=0: qs_hi=0, signed=-16
52 // j=15: qs_hi=15, signed=-1
53 if out[16] != 0xC1800000 { return 26 } // -16.0
54 if out[31] != 0xBF800000 { return 41 } // -1.0
55
56 return 0
57}