code wiki / (root) / nx_live_fire_gguf_test.nx

nx_live_fire_gguf_test.nx source

↩ module page · 247 lines · 9472 B

1// nx_live_fire_gguf_test.nx -- the live-fire smoke. 2 3import "nx_syscalls.nx" 4import "nx_tier.nx" 5import "nx_le.nx" 6import "nx_tensor.nx" 7import "nx_strconv.nx" 8import "nx_gguf.nx" 9import "nx_gguf_load.nx" 10import "nx_placement.nx" 11import "nx_gguf_load_lazy.nx" 12import "nx_live_fire_gguf.nx" 13 14// Write tensor_info entry; return new offset. 15func _write_ti(buf: *u8, off: i64, 16 name: *u8, name_len: i64, 17 n_dims: i64, dim_0: i64, dim_1: i64, 18 ggml_type: i64, data_offset: i64) -> i64 { 19 nx_le_write_u64(buf, off, name_len) 20 var o: i64 = off + 8 21 var i: i64 = 0 22 while i < name_len { buf[o + i] = name[i]; i = i + 1 } 23 o = o + name_len 24 nx_le_write_u32(buf, o, n_dims); o = o + 4 25 nx_le_write_u64(buf, o, dim_0); o = o + 8 26 if n_dims >= 2 { nx_le_write_u64(buf, o, dim_1); o = o + 8 } 27 nx_le_write_u32(buf, o, ggml_type); o = o + 4 28 nx_le_write_u64(buf, o, data_offset); o = o + 8 29 return o 30} 31 32func main() -> i64 { 33 // ----- PHASE 0: Build the GGUF in-memory ----- 34 // 35 // 3 top-level tensors so the test exercises a realistic structure: 36 // "score" F32 [2,2] = 16 bytes data 37 // "norm" F32 [4] = 16 bytes data 38 // "weight" Q8_0 [32] = 34 bytes data 39 let src: *u8 = sys_mmap(2048) 40 src[0]=0x47; src[1]=0x47; src[2]=0x55; src[3]=0x46 41 src[4]=3 42 nx_le_write_u64(src, 8, 3) 43 nx_le_write_u64(src, 16, 0) 44 45 let n_sc: *u8 = sys_mmap(5) 46 n_sc[0]=0x73; n_sc[1]=0x63; n_sc[2]=0x6F; n_sc[3]=0x72; n_sc[4]=0x65 47 48 let n_nm: *u8 = sys_mmap(4) 49 n_nm[0]=0x6E; n_nm[1]=0x6F; n_nm[2]=0x72; n_nm[3]=0x6D 50 51 let n_wt: *u8 = sys_mmap(6) 52 n_wt[0]=0x77; n_wt[1]=0x65; n_wt[2]=0x69; n_wt[3]=0x67; n_wt[4]=0x68; n_wt[5]=0x74 53 54 var p: i64 = 24 55 p = _write_ti(src, p, n_sc, 5, 2, 2, 2, NX_GGML_TYPE_F32, 0) 56 p = _write_ti(src, p, n_nm, 4, 1, 4, 1, NX_GGML_TYPE_F32, 16) 57 p = _write_ti(src, p, n_wt, 6, 1, 32, 1, NX_GGML_TYPE_Q8_0, 32) 58 let data_off: i64 = (p + 31) / 32 * 32 59 60 // score [2,2] F32: 1.0, 2.0, 0.5, -1.0 61 nx_le_write_u32(src, data_off + 0, 0x3F800000) 62 nx_le_write_u32(src, data_off + 4, 0x40000000) 63 nx_le_write_u32(src, data_off + 8, 0x3F000000) 64 nx_le_write_u32(src, data_off + 12, 0xBF800000) 65 // norm [4] F32: 1.0, 1.0, 1.0, 1.0 66 nx_le_write_u32(src, data_off + 16, 0x3F800000) 67 nx_le_write_u32(src, data_off + 20, 0x3F800000) 68 nx_le_write_u32(src, data_off + 24, 0x3F800000) 69 nx_le_write_u32(src, data_off + 28, 0x3F800000) 70 // weight [32] Q8_0: scale=0.5 (f16 0x3800), qs[i] = i 71 let q8_off: i64 = data_off + 32 72 nx_le_write_u16(src, q8_off + 0, 0x3800) 73 var qi: nx_int = 0 74 while qi < 32 { 75 src[q8_off + 2 + qi] = qi 76 qi = qi + 1 77 } 78 let total_bytes: i64 = data_off + 32 + 34 79 80 // ----- PHASE 1: WRITE to disk via sys_write ----- 81 let path: *u8 = sys_mmap(64) 82 path[0]=0x2F; path[1]=0x74; path[2]=0x6D; path[3]=0x70 // "/tmp" 83 path[4]=0x2F // "/" 84 path[5]=0x6E; path[6]=0x78; path[7]=0x5F // "nx_" 85 path[8]=0x6C; path[9]=0x69; path[10]=0x76; path[11]=0x65 // "live" 86 path[12]=0x5F; path[13]=0x66; path[14]=0x69; path[15]=0x72 87 path[16]=0x65; path[17]=0x2E; path[18]=0x67; path[19]=0x67 88 path[20]=0x75; path[21]=0x66 // "_fire.gguf" 89 path[22]=0 90 // Full path: "/tmp/nx_live_fire.gguf" 91 92 let t0_w: i64 = sys_now_ms() 93 let fd: i64 = sys_openat_wr(path, 0x1A4) // 0644 octal = 420 = 0x1A4 94 if fd < 0 { return 30 } 95 let n_w: i64 = sys_write(fd, src, total_bytes) 96 let v_cl: i64 = sys_close(fd) 97 let t1_w: i64 = sys_now_ms() 98 if n_w != total_bytes { return 31 } 99 if v_cl != 0 { return 32 } 100 let elapsed_w: i64 = t1_w - t0_w 101 if elapsed_w > NX_LF_WRITE_BUDGET_MS { return 33 } 102 103 // ----- PHASE 2: READ back via sys_read_file ----- 104 let t0_r: i64 = sys_now_ms() 105 let out_len: *i64 = sys_mmap(8) as *i64 106 out_len[0] = 0 107 let read_buf: *u8 = sys_read_file(path, out_len) 108 let t1_r: i64 = sys_now_ms() 109 if read_buf == (0 as *u8) { return 40 } 110 if out_len[0] != total_bytes { return 41 } 111 let elapsed_r: i64 = t1_r - t0_r 112 if elapsed_r > NX_LF_READ_BUDGET_MS { return 42 } 113 114 // Bit-exact compare against the source we wrote (proves the 115 // kernel didn't lose / reorder / pad anything). 116 var bi: i64 = 0 117 while bi < total_bytes { 118 if read_buf[bi] != src[bi] { return 50 } 119 bi = bi + 1 120 } 121 122 // ----- PHASE 3: parse the header ----- 123 let t0_p: i64 = sys_now_ms() 124 let hdr: *NxGgufHeader = sys_mmap(NX_GGUF_HDR_BYTES) as *NxGgufHeader 125 let v_parse: nx_int = nx_gguf_parse(read_buf, out_len[0], hdr) 126 let t1_p: i64 = sys_now_ms() 127 if v_parse != NX_GGUF_OK { return 60 + v_parse } 128 if hdr.n_tensors != 3 { return 70 } 129 let elapsed_p: i64 = t1_p - t0_p 130 if elapsed_p > NX_LF_PARSE_BUDGET_MS { return 71 } 131 132 // ----- PHASE 4: LAZY-load all 3 tensor handles ----- 133 let t0_l: i64 = sys_now_ms() 134 let err: *i64 = sys_mmap(8) as *i64 135 err[0] = 0 136 let lazy_score: *NxPlacedTensor = nx_gguf_load_tensor_lazy( 137 read_buf, hdr, n_sc, 5, err) 138 if err[0] != NX_GL_OK { return 80 } 139 err[0] = 0 140 let lazy_norm: *NxPlacedTensor = nx_gguf_load_tensor_lazy( 141 read_buf, hdr, n_nm, 4, err) 142 if err[0] != NX_GL_OK { return 81 } 143 err[0] = 0 144 let lazy_weight: *NxPlacedTensor = nx_gguf_load_tensor_lazy( 145 read_buf, hdr, n_wt, 6, err) 146 if err[0] != NX_GL_OK { return 82 } 147 let t1_l: i64 = sys_now_ms() 148 let elapsed_l: i64 = t1_l - t0_l 149 if elapsed_l > NX_LF_LAZY_LOAD_BUDGET_MS { return 83 } 150 151 // Quantitative claim: 3 lazy handles total 88*3 = 264 bytes 152 // regardless of tensor sizes. No dequantized storage yet. 153 if nx_placed_tensor_storage_bytes(lazy_score) != 0 { return 90 } 154 if nx_placed_tensor_storage_bytes(lazy_norm) != 0 { return 91 } 155 if nx_placed_tensor_storage_bytes(lazy_weight) != 0 { return 92 } 156 157 // ----- PHASE 5: MATERIALIZE on demand + verify values ----- 158 let t0_m: i64 = sys_now_ms() 159 let t_score: *NxTensor = nx_placed_tensor_get(lazy_score) 160 let t_norm: *NxTensor = nx_placed_tensor_get(lazy_norm) 161 let t_weight: *NxTensor = nx_placed_tensor_get(lazy_weight) 162 let t1_m: i64 = sys_now_ms() 163 if t_score == (0 as *NxTensor) { return 100 } 164 if t_norm == (0 as *NxTensor) { return 101 } 165 if t_weight == (0 as *NxTensor) { return 102 } 166 let elapsed_m: i64 = t1_m - t0_m 167 if elapsed_m > NX_LF_MATERIALIZE_BUDGET_MS { return 103 } 168 169 // Verify exact Q10 values match what we wrote. 170 let sp: *i64 = t_score.storage as *i64 171 if sp[0] != 1024 { return 110 } // 1.0 172 if sp[1] != 2048 { return 111 } // 2.0 173 if sp[2] != 512 { return 112 } // 0.5 174 if sp[3] != (0 - 1024) { return 113 } // -1.0 175 176 let np: *i64 = t_norm.storage as *i64 177 if np[0] != 1024 { return 120 } 178 if np[3] != 1024 { return 121 } 179 180 let wp: *i64 = t_weight.storage as *i64 181 // scale_q10 = 512; qs[i] = i; expected[i] = 512 * i 182 var ki: nx_int = 0 183 while ki < 32 { 184 if wp[ki] != 512 * ki { return 130 + ki } 185 ki = ki + 1 186 } 187 188 // ----- PHASE 6: write timing report to disk ----- 189 // 190 // Encode the elapsed values as a tiny TSV that the smoke wrapper 191 // can cat after PASS so the user sees real numbers. Format: 192 // "write_ms\tread_ms\tparse_ms\tlazy_ms\tmat_ms\ttotal_bytes\n" 193 let report_path: *u8 = sys_mmap(64) 194 report_path[0]=0x2F; report_path[1]=0x74; report_path[2]=0x6D; report_path[3]=0x70 195 report_path[4]=0x2F 196 report_path[5]=0x6E; report_path[6]=0x78; report_path[7]=0x5F 197 report_path[8]=0x6C; report_path[9]=0x69; report_path[10]=0x76; report_path[11]=0x65 198 report_path[12]=0x5F; report_path[13]=0x66; report_path[14]=0x69; report_path[15]=0x72 199 report_path[16]=0x65; report_path[17]=0x2E; report_path[18]=0x74; report_path[19]=0x73 200 report_path[20]=0x76 // ".tsv" 201 report_path[21]=0 202 // Full: "/tmp/nx_live_fire.tsv" 203 204 let line: *u8 = sys_mmap(256) 205 var lo: i64 = 0 206 let dec: *u8 = sys_mmap(32) 207 var n_dec: i64 = 0 208 209 // helper inline: write integer + tab to line 210 n_dec = nx_strconv_format_i64(elapsed_w, dec) 211 var k: i64 = 0 212 while k < n_dec { line[lo] = dec[k]; lo = lo + 1; k = k + 1 } 213 line[lo] = 0x09; lo = lo + 1 214 215 n_dec = nx_strconv_format_i64(elapsed_r, dec) 216 k = 0 217 while k < n_dec { line[lo] = dec[k]; lo = lo + 1; k = k + 1 } 218 line[lo] = 0x09; lo = lo + 1 219 220 n_dec = nx_strconv_format_i64(elapsed_p, dec) 221 k = 0 222 while k < n_dec { line[lo] = dec[k]; lo = lo + 1; k = k + 1 } 223 line[lo] = 0x09; lo = lo + 1 224 225 n_dec = nx_strconv_format_i64(elapsed_l, dec) 226 k = 0 227 while k < n_dec { line[lo] = dec[k]; lo = lo + 1; k = k + 1 } 228 line[lo] = 0x09; lo = lo + 1 229 230 n_dec = nx_strconv_format_i64(elapsed_m, dec) 231 k = 0 232 while k < n_dec { line[lo] = dec[k]; lo = lo + 1; k = k + 1 } 233 line[lo] = 0x09; lo = lo + 1 234 235 n_dec = nx_strconv_format_i64(total_bytes, dec) 236 k = 0 237 while k < n_dec { line[lo] = dec[k]; lo = lo + 1; k = k + 1 } 238 line[lo] = 0x0A; lo = lo + 1 // newline 239 240 let fd_rep: i64 = sys_openat_wr(report_path, 0x1A4) 241 if fd_rep < 0 { return 200 } 242 let nw_rep: i64 = sys_write(fd_rep, line, lo) 243 sys_close(fd_rep) 244 if nw_rep != lo { return 201 } 245 246 return 0 247}