nx_q8_0_linear_verify.nx source
↩ module page · 83 lines · 2815 B
1// nx_q8_0_linear_verify.nx -- verify a full Q8_0 linear at REAL DiT scale vs a Python ggml golden.
2//
3// Reads the real Z-Image DiT layers.0.attention.out.weight (Q8_0, [3840,3840], dumped to dit_out_weight.q8)
4// and computes output rows 0..3 = W[o,:] . x with x[i]=(i%7)+1, confirming the row stride (120 blocks *
5// 34B = 4080B/row) + the Q8_0 dot at scale. Golden (Python): -20.6074, -1.0092, 22.8396, -16.1888.
6// out_q34 / 2^24 = out in Q10 = out*1024. Golden*1024 ~= -21102, -1033, 23388, -16577.
7// license_tier: ORIGINAL
8import "nx_syscalls.nx"
9import "nx_tier.nx"
10import "nx_le.nx"
11import "nx_strconv.nx"
12import "nx_gguf_load.nx"
13
14func q8v_dot(buf: *u8, block_off: i64, n_blocks: i64, col_q10: *i64) -> i64 {
15 var dot: i64 = 0
16 var blk: i64 = 0
17 while blk < n_blocks {
18 let bo: i64 = block_off + blk * 34
19 let d_q24: i64 = _gguf_f16_to_q24(nx_le_read_u16(buf, bo))
20 var i: i64 = 0
21 while i < 32 {
22 var q: i64 = nx_le_read_u8(buf, bo + 2 + i)
23 if q >= 128 { q = q - 256 }
24 dot = dot + (d_q24 * q) * col_q10[blk * 32 + i]
25 i = i + 1
26 }
27 blk = blk + 1
28 }
29 return dot
30}
31
32func q8v_emit(fd: i64, o: i64, v: i64) -> i64 {
33 let dec: *u8 = sys_mmap(32)
34 sys_write(fd, "row" as *u8, 3)
35 let nd0: i64 = nx_strconv_format_i64(o, dec)
36 sys_write(fd, dec, nd0)
37 sys_write(fd, "=" as *u8, 1)
38 let nd: i64 = nx_strconv_format_i64(v, dec)
39 sys_write(fd, dec, nd)
40 sys_write(fd, "\n" as *u8, 1)
41 return 0
42}
43
44func main() -> i64 {
45 let fd: i64 = sys_openat_rd("/mnt/c/Users/elder/nishi-core/nxc2/dit_out_weight.q8" as *u8)
46 if fd < 0 { return 30 }
47 let CAP: i64 = 15667200
48 let buf: *u8 = sys_mmap(CAP + 64)
49 var total: i64 = 0
50 var go: i64 = 1
51 while go == 1 {
52 let r: i64 = sys_read(fd, ((buf as i64) + total) as *u8, CAP - total)
53 if r <= 0 { go = 0 } else { total = total + r; if total >= CAP { go = 0 } }
54 }
55 sys_close(fd)
56 if total != CAP { return 31 }
57
58 let IN: i64 = 3840
59 let col: *i64 = sys_mmap(IN * 8) as *i64
60 var i: i64 = 0
61 while i < IN { col[i] = ((i - (i / 7) * 7) + 1) * 1024; i = i + 1 }
62
63 let gold: *i64 = sys_mmap(4 * 8) as *i64
64 gold[0] = 0 - 21102
65 gold[1] = 0 - 1033
66 gold[2] = 23388
67 gold[3] = 0 - 16577
68
69 let div: i64 = 1 << 24
70 let ofd: i64 = sys_openat_wr("/tmp/dit_linear.txt" as *u8, 0x1a4)
71 var o: i64 = 0
72 while o < 4 {
73 let dq34: i64 = q8v_dot(buf, o * 4080, 120, col)
74 let q10: i64 = dq34 / div
75 if ofd >= 0 { q8v_emit(ofd, o, q10) }
76 var diff: i64 = q10 - gold[o]
77 if diff < 0 { diff = 0 - diff }
78 if diff > 15 { if ofd >= 0 { sys_close(ofd) } return 40 + o }
79 o = o + 1
80 }
81 if ofd >= 0 { sys_close(ofd) }
82 return 0
83}