code wiki / (root) / nx_placement_test.nx

nx_placement_test.nx source

↩ module page · 143 lines · 5075 B

1// nx_placement_test.nx -- smoke for nx_placement.nx. 2// 3// Two test classes: 4// A) Lazy lifecycle: build a synthetic Q8_0 block in a buffer; 5// create lazy NxPlacedTensor; verify storage_bytes==0 + is_live==0; 6// materialize; verify is_live==1, storage_bytes>0, values match; 7// demote; verify is_live==0; re-materialize; verify values match. 8// B) Owned: wrap a pre-built NxTensor; verify is_live==1 + storage 9// reflects it; demote refuses (NX_PT_ERR_BAD_PLACEMENT). 10 11import "nx_syscalls.nx" 12import "nx_tier.nx" 13import "nx_le.nx" 14import "nx_tensor.nx" 15import "nx_gguf.nx" 16import "nx_placement.nx" 17 18func main() -> i64 { 19 // ----- Verdict gate ----- 20 var vi: nx_int = 0 21 while vi < NX_PT_N_VERDICTS { 22 if nx_pt_verdict_is_valid(vi) != 1 { return 5 + vi } 23 vi = vi + 1 24 } 25 var vp: nx_int = 0 26 while vp < NX_PLACE_N { 27 if nx_place_is_valid(vp) != 1 { return 10 + vp } 28 vp = vp + 1 29 } 30 31 // ----- A) Lazy lifecycle with Q8_0 source ----- 32 // 33 // Build a 34-byte Q8_0 block at buffer offset 0: 34 // f16 scale at byte 0: 0.5 (0x3800) -> scale_q10 = 512 35 // int8 values at byte 2: qs[i] = i 36 // Dequant expected: out[i] = 512 * i. 37 let buf: *u8 = sys_mmap(64) 38 nx_le_write_u16(buf, 0, 0x3800) 39 var qi: nx_int = 0 40 while qi < 32 { 41 buf[2 + qi] = qi 42 qi = qi + 1 43 } 44 45 let shape: *i64 = sys_mmap(1 * 8) as *i64 46 shape[0] = 32 47 let lazy_p: *NxPlacedTensor = nx_placed_tensor_new_lazy( 48 buf, 0, NX_GGML_TYPE_Q8_0, 32, shape, 1) 49 50 if lazy_p.placement != NX_PLACE_MMAP { return 30 } 51 if nx_placed_tensor_is_live(lazy_p) != 0 { return 31 } 52 if nx_placed_tensor_storage_bytes(lazy_p) != 0 { return 32 } 53 if lazy_p.src_n_values != 32 { return 33 } 54 if lazy_p.src_ggml_type != NX_GGML_TYPE_Q8_0 { return 34 } 55 if lazy_p.shape_0 != 32 { return 35 } 56 57 // Materialize. 58 let v_m: nx_int = nx_placed_tensor_materialize(lazy_p) 59 if v_m != NX_PT_OK { return 40 + v_m } 60 if nx_placed_tensor_is_live(lazy_p) != 1 { return 50 } 61 if nx_placed_tensor_storage_bytes(lazy_p) != 32 * 8 { return 51 } 62 63 // Verify values. 64 let p1: *i64 = lazy_p.t.storage as *i64 65 var ki: nx_int = 0 66 while ki < 32 { 67 if p1[ki] != 512 * ki { return 60 + ki } 68 ki = ki + 1 69 } 70 71 // Materializing again is rejected (already live). 72 let v_m2: nx_int = nx_placed_tensor_materialize(lazy_p) 73 if v_m2 != NX_PT_ERR_ALREADY_LIVE { return 100 } 74 75 // Demote. 76 let v_d: nx_int = nx_placed_tensor_demote(lazy_p) 77 if v_d != NX_PT_OK { return 110 + v_d } 78 if nx_placed_tensor_is_live(lazy_p) != 0 { return 120 } 79 if nx_placed_tensor_storage_bytes(lazy_p) != 0 { return 121 } 80 81 // Demoting again is rejected (already lazy). 82 let v_d2: nx_int = nx_placed_tensor_demote(lazy_p) 83 if v_d2 != NX_PT_ERR_NOT_LIVE { return 130 } 84 85 // Re-materialize (idempotent contract). 86 let v_m3: nx_int = nx_placed_tensor_materialize(lazy_p) 87 if v_m3 != NX_PT_OK { return 140 + v_m3 } 88 let p2: *i64 = lazy_p.t.storage as *i64 89 var kj: nx_int = 0 90 while kj < 32 { 91 if p2[kj] != 512 * kj { return 150 + kj } 92 kj = kj + 1 93 } 94 95 // ----- B) Owned wrapper ----- 96 // 97 // Build a real NxTensor; wrap it as OWNED; verify lifecycle 98 // semantics differ (demote refused). 99 let sh: *i64 = sys_mmap(1 * 8) as *i64 100 sh[0] = 4 101 let err: *i64 = sys_mmap(8) as *i64 102 err[0] = 0 103 let raw_t: *NxTensor = nx_t_alloc(NX_DT_I64, sh, 1, err) 104 if err[0] != 0 { return 200 } 105 let pt: *i64 = raw_t.storage as *i64 106 pt[0] = 11; pt[1] = 22; pt[2] = 33; pt[3] = 44 107 108 let owned_p: *NxPlacedTensor = nx_placed_tensor_new_owned(raw_t) 109 if owned_p.placement != NX_PLACE_OWNED { return 210 } 110 if nx_placed_tensor_is_live(owned_p) != 1 { return 211 } 111 if nx_placed_tensor_storage_bytes(owned_p) != 4 * 8 { return 212 } 112 if owned_p.shape_0 != 4 { return 213 } 113 114 let v_dem_owned: nx_int = nx_placed_tensor_demote(owned_p) 115 if v_dem_owned != NX_PT_ERR_BAD_PLACEMENT { return 220 } 116 117 // On-demand get returns the live tensor without re-materializing. 118 let got: *NxTensor = nx_placed_tensor_get(owned_p) 119 if got != raw_t { return 230 } 120 121 // For lazy: nx_placed_tensor_get works even on a fresh lazy -- 122 // it triggers materialization automatically. Build a fresh 123 // lazy + call get + verify. 124 let buf2: *u8 = sys_mmap(64) 125 nx_le_write_u16(buf2, 0, 0x3800) 126 var qi2: nx_int = 0 127 while qi2 < 32 { 128 buf2[2 + qi2] = qi2 129 qi2 = qi2 + 1 130 } 131 let shape2: *i64 = sys_mmap(8) as *i64 132 shape2[0] = 32 133 let lazy2: *NxPlacedTensor = nx_placed_tensor_new_lazy( 134 buf2, 0, NX_GGML_TYPE_Q8_0, 32, shape2, 1) 135 if nx_placed_tensor_is_live(lazy2) != 0 { return 240 } 136 let auto_t: *NxTensor = nx_placed_tensor_get(lazy2) 137 if auto_t == (0 as *NxTensor) { return 241 } 138 if nx_placed_tensor_is_live(lazy2) != 1 { return 242 } 139 let pa: *i64 = auto_t.storage as *i64 140 if pa[5] != 512 * 5 { return 243 } 141 142 return 0 143}