code wiki / (root) / nx_q5_k_ggml_kat.nx

nx_q5_k_ggml_kat.nx source

↩ module page · 55 lines · 2553 B

1// nx_q5_k_ggml_kat.nx -- permanent golden KAT for nx_q5_k_to_f32 vs a ggml Q5_K oracle. 2// 3// Embeds the real 176-byte super-block 0 of blk.0.attn_v (Q5_K) from the Huihui Q4_K_M model (file offset 4// 1050331744) and asserts nx_q5k_block_to_f32 reproduces the ggml golden at POSITION-SENSITIVE points 5// (element0/32/64 + a non-uniform dot) -- so a wrong nibble/sub-block layout (the Q4_K failure mode) is 6// caught. Golden from a hand-rolled ggml dequantize_row_q5_K (scratchpad/q5k_golden.py): 7// element0=-0.004717 (bits 3147470080), element32=-0.049673 (3175839104), element64=-0.022964 (3166445568), 8// dot(sum y[i]*((i%5)+1))=-2.357033 (bits 3222722976). 9// license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "nx_tier.nx" 12import "nx_le.nx" 13import "nx_f32.nx" 14import "nx_f32_cvt.nx" 15import "nx_f32_div.nx" 16import "nx_q5_k_to_f32.nx" 17 18func kat_hexval(c: i64) -> i64 { 19 if c >= 48 { if c <= 57 { return c - 48 } } // '0'-'9' 20 if c >= 97 { if c <= 102 { return c - 87 } } // 'a'-'f' -> 10-15 21 return 0 22} 23 24func main() -> i64 { 25 let hex: *u8 = "82046f15fdf2eceaf3b5dfa56565ffef507dce3a4f59475b485ad67adf51a09d1a2e66ea649f53795b3abb32898066cb6f8dff9f44e8405cfdca236f97e20bf51ecf4c0bae2380a2d10f0d4deeffa056063f91a559cae694f08a53bc6a77f6304d34b4759101794638b36e94abdbf312d9222dcbaddaab104d50b290a0c86f148387702e2f4264f00f2a7f86dbe20db7c8c80200f5a63245f45553b0faeb686c3cf85b1ac435f183c067e82e572ffe53" as *u8 26 let buf: *u8 = sys_mmap(176) 27 var i: i64 = 0 28 while i < 176 { 29 let hi: i64 = kat_hexval((hex[i * 2]) as i64) 30 let lo: i64 = kat_hexval((hex[i * 2 + 1]) as i64) 31 buf[i] = ((hi << 4) | lo) as u8 32 i = i + 1 33 } 34 35 let out: *i64 = sys_mmap(256 * 8) as *i64 36 nx_q5k_block_to_f32(buf, 0, 256, out) 37 38 let tol: i64 = nx_f32_div(nx_i32_to_f32(1), nx_i32_to_f32(100000)) // 1e-5 (elements ~0.005-0.05) 39 if (nx_f32_sub(out[0], 3147470080) & 0x7FFFFFFF) >= tol { return 10 } 40 if (nx_f32_sub(out[32], 3175839104) & 0x7FFFFFFF) >= tol { return 11 } 41 if (nx_f32_sub(out[64], 3166445568) & 0x7FFFFFFF) >= tol { return 12 } 42 43 // non-uniform (position-sensitive) dot vs the ggml golden 44 var dot: i64 = 0 45 i = 0 46 while i < 256 { 47 let w: i64 = nx_i32_to_f32((i - (i / 5) * 5) + 1) 48 dot = nx_f32_add(dot, nx_f32_mul(out[i], w)) 49 i = i + 1 50 } 51 let dtol: i64 = nx_f32_div(nx_i32_to_f32(1), nx_i32_to_f32(100)) // 1e-2 (256-term f32 accumulation) 52 if (nx_f32_sub(dot, 3222722976) & 0x7FFFFFFF) >= dtol { return 20 } 53 54 return 0 55}