code wiki / (root) / nx_gguf_load_test.nx

nx_gguf_load_test.nx source

↩ module page · 164 lines · 6372 B

1// nx_gguf_load_test.nx -- smoke for nx_gguf_load.nx. 2// 3// Builds a synthetic GGUF blob in memory with two tensors: 4// tensor[0] "score" : F32 shape [2,2] = {1.0, 2.0, 0.5, -1.0} 5// tensor[1] "weight" : Q8_0 shape [32] scale=0.5, qs={0,1,2,...,31} 6// => values {0, 0.5, 1.0, ..., 15.5} 7// 8// Verifies: 9// - parse + name lookup + not-found verdict 10// - format-helper bytes/values per block + total bytes 11// - f32 → Q10 unit conversions on canonical bit patterns 12// - f16 → Q10 unit conversions on canonical bit patterns 13// - end-to-end load + dequant for F32 and Q8_0 14 15import "nx_syscalls.nx" 16import "nx_tier.nx" 17import "nx_le.nx" 18import "nx_tensor.nx" 19import "nx_gguf.nx" 20import "nx_gguf_load.nx" 21 22func main() -> i64 { 23 // ----- Build synthetic GGUF ----- 24 let buf: *u8 = sys_mmap(1024) 25 26 // Header magic "GGUF" LE 27 buf[0] = 0x47; buf[1] = 0x47; buf[2] = 0x55; buf[3] = 0x46 28 buf[4] = 3; buf[5] = 0; buf[6] = 0; buf[7] = 0 29 nx_le_write_u64(buf, 8, 2) 30 nx_le_write_u64(buf, 16, 0) 31 32 // tensor[0] "score" F32 [2,2] 33 nx_le_write_u64(buf, 24, 5) 34 buf[32] = 0x73; buf[33] = 0x63; buf[34] = 0x6F; buf[35] = 0x72; buf[36] = 0x65 35 nx_le_write_u32(buf, 37, 2) 36 nx_le_write_u64(buf, 41, 2) 37 nx_le_write_u64(buf, 49, 2) 38 nx_le_write_u32(buf, 57, NX_GGML_TYPE_F32) 39 nx_le_write_u64(buf, 61, 0) 40 41 // tensor[1] "weight" Q8_0 [32] 42 let t1_off: i64 = 69 43 nx_le_write_u64(buf, t1_off + 0, 6) 44 buf[t1_off + 8 + 0] = 0x77 45 buf[t1_off + 8 + 1] = 0x65 46 buf[t1_off + 8 + 2] = 0x69 47 buf[t1_off + 8 + 3] = 0x67 48 buf[t1_off + 8 + 4] = 0x68 49 buf[t1_off + 8 + 5] = 0x74 50 nx_le_write_u32(buf, t1_off + 14, 1) 51 nx_le_write_u64(buf, t1_off + 18, 32) 52 nx_le_write_u32(buf, t1_off + 26, NX_GGML_TYPE_Q8_0) 53 nx_le_write_u64(buf, t1_off + 30, 16) 54 // End of tensor_info at offset = t1_off + 38 = 107. 55 // data_off = align_up(107, 32) = 128. 56 57 // ----- Write tensor data ----- 58 let data_off: i64 = 128 59 // F32 score values 60 nx_le_write_u32(buf, data_off + 0, 0x3F800000) // 1.0 61 nx_le_write_u32(buf, data_off + 4, 0x40000000) // 2.0 62 nx_le_write_u32(buf, data_off + 8, 0x3F000000) // 0.5 63 nx_le_write_u32(buf, data_off + 12, 0xBF800000) // -1.0 64 65 // Q8_0 block: f16 scale + 32 int8 values 66 let q8_off: i64 = data_off + 16 67 nx_le_write_u16(buf, q8_off + 0, 0x3800) // f16 0.5 68 var qi: nx_int = 0 69 while qi < 32 { 70 buf[q8_off + 2 + qi] = qi 71 qi = qi + 1 72 } 73 74 // ----- Parse the header ----- 75 let hdr_p: *NxGgufHeader = sys_mmap(NX_GGUF_HDR_BYTES) as *NxGgufHeader 76 let v_parse: nx_int = nx_gguf_parse(buf, 1024, hdr_p) 77 if v_parse != NX_GGUF_OK { return 10 + v_parse } 78 if hdr_p.n_tensors != 2 { return 19 } 79 if hdr_p.data_off != 128 { return 18 } 80 81 // ----- Verdict-range gate ----- 82 var vi: nx_int = 0 83 while vi < NX_GL_N_VERDICTS { 84 if nx_gl_verdict_is_valid(vi) != 1 { return 20 + vi } 85 vi = vi + 1 86 } 87 88 // ----- find_tensor + not-found ----- 89 let score_name: *u8 = sys_mmap(5) 90 score_name[0] = 0x73; score_name[1] = 0x63; score_name[2] = 0x6F 91 score_name[3] = 0x72; score_name[4] = 0x65 92 if nx_gguf_find_tensor(hdr_p, score_name, 5) != 0 { return 30 } 93 94 let weight_name: *u8 = sys_mmap(6) 95 weight_name[0] = 0x77; weight_name[1] = 0x65; weight_name[2] = 0x69 96 weight_name[3] = 0x67; weight_name[4] = 0x68; weight_name[5] = 0x74 97 if nx_gguf_find_tensor(hdr_p, weight_name, 6) != 1 { return 31 } 98 99 let missing: *u8 = sys_mmap(3) 100 missing[0] = 0x78; missing[1] = 0x78; missing[2] = 0x78 101 if nx_gguf_find_tensor(hdr_p, missing, 3) != (0 - 1) { return 32 } 102 103 // ----- Format helpers ----- 104 let ti0: *NxGgufTensorInfo = nx_gguf_tensor_at(hdr_p, 0) 105 if nx_gguf_ggml_values_per_block(ti0.ggml_type) != 1 { return 40 } 106 if nx_gguf_ggml_bytes_per_block(ti0.ggml_type) != 4 { return 41 } 107 if nx_gguf_tensor_n_values(ti0) != 4 { return 42 } 108 if nx_gguf_tensor_data_bytes(ti0) != 16 { return 43 } 109 110 let ti1: *NxGgufTensorInfo = nx_gguf_tensor_at(hdr_p, 1) 111 if nx_gguf_ggml_values_per_block(ti1.ggml_type) != 32 { return 50 } 112 if nx_gguf_ggml_bytes_per_block(ti1.ggml_type) != 34 { return 51 } 113 if nx_gguf_tensor_n_values(ti1) != 32 { return 52 } 114 if nx_gguf_tensor_data_bytes(ti1) != 34 { return 53 } 115 116 // ----- f32 → Q10 canonical bit-patterns ----- 117 if _gguf_f32_to_q10(0x3F800000) != 1024 { return 60 } 118 if _gguf_f32_to_q10(0x40000000) != 2048 { return 61 } 119 if _gguf_f32_to_q10(0x3F000000) != 512 { return 62 } 120 if _gguf_f32_to_q10(0xBF800000) != (0 - 1024) { return 63 } 121 if _gguf_f32_to_q10(0) != 0 { return 64 } 122 123 // ----- f16 → Q10 canonical bit-patterns ----- 124 if _gguf_f16_to_q10(0x3C00) != 1024 { return 70 } 125 if _gguf_f16_to_q10(0xBC00) != (0 - 1024) { return 71 } 126 if _gguf_f16_to_q10(0x3800) != 512 { return 72 } 127 if _gguf_f16_to_q10(0x4000) != 2048 { return 73 } 128 if _gguf_f16_to_q10(0) != 0 { return 74 } 129 130 // ----- Load "score" (F32) ----- 131 let err: *i64 = sys_mmap(8) as *i64 132 err[0] = 0 133 let score_t: *NxTensor = nx_gguf_load_tensor(buf, hdr_p, 134 score_name, 5, err) 135 if err[0] != NX_GL_OK { return 80 } 136 if score_t.numel != 4 { return 81 } 137 let sp: *i64 = score_t.storage as *i64 138 if sp[0] != 1024 { return 82 } 139 if sp[1] != 2048 { return 83 } 140 if sp[2] != 512 { return 84 } 141 if sp[3] != (0 - 1024) { return 85 } 142 143 // ----- Load "weight" (Q8_0) ----- 144 let weight_t: *NxTensor = nx_gguf_load_tensor(buf, hdr_p, 145 weight_name, 6, err) 146 if err[0] != NX_GL_OK { return 90 } 147 if weight_t.numel != 32 { return 91 } 148 let wp: *i64 = weight_t.storage as *i64 149 // scale_q10 = 512; qs[i] = i; dequant[i] = 512 * i. 150 var ki: nx_int = 0 151 while ki < 32 { 152 let expected: i64 = 512 * ki 153 if wp[ki] != expected { return 100 + ki } 154 ki = ki + 1 155 } 156 157 // ----- Negative path: not-found ----- 158 let bad: *u8 = sys_mmap(5) 159 bad[0] = 0x78; bad[1] = 0x78; bad[2] = 0x78; bad[3] = 0x78; bad[4] = 0x78 160 let _ng: *NxTensor = nx_gguf_load_tensor(buf, hdr_p, bad, 5, err) 161 if err[0] != NX_GL_ERR_NOT_FOUND { return 140 } 162 163 return 0 164}