code wiki / (root) / nx_select_joint_test.nx

nx_select_joint_test.nx source

↩ module page · 208 lines · 8314 B

1// nx_select_joint_test.nx -- smoke for nx_select_joint SA-5 MVP. 2// 3// Demonstrates the LOAD-BEARING joint-DAG property: independent 4// argmin picks a locally-optimal pair that is layout-INCOMPATIBLE; 5// joint solver picks a globally-optimal pair that costs more locally 6// but composes through the edge. 7// 8// Two-node DAG: 9// 10// [node A: variant_class=100] --edge--> [node B: variant_class=200] 11// 12// Producer candidates (node A): 13// A_cheap_row : cost=100, out_layout=ROW_MAJOR 14// A_medium_col : cost=300, out_layout=COL_MAJOR 15// A_expensive_col: cost=900, out_layout=COL_MAJOR 16// 17// Consumer candidates (node B): 18// B_cheap_col : cost=100, in_layout=COL_MAJOR 19// B_expensive_row : cost=900, in_layout=ROW_MAJOR 20// 21// Per-node argmin (single-class): 22// node A picks A_cheap_row (cost=100) 23// node B picks B_cheap_col (cost=100) 24// But the edge A_cheap_row.out=ROW vs B_cheap_col.in=COL is INCOMPATIBLE. 25// 26// Joint argmin: 27// (A_cheap_row, B_expensive_row): row->row compatible; total=100+900=1000 28// (A_medium_col, B_cheap_col): col->col compatible; total=300+100=400 <- WIN 29// (A_expensive_col, B_cheap_col): col->col compatible; total=900+100=1000 30// 31// The joint solver must pick (A_medium_col, B_cheap_col) -- INDICES 32// (1, 0) -- demonstrating that the locally-suboptimal A_medium_col 33// is the globally-optimal choice given the edge constraint. 34// 35// SA-5 verification gate per NISHI_SELF_ASSEMBLY_ROADMAP.md ยง8: 36// "DAG composition smoke -- same algorithm, two layout choices, 37// joint solver picks bit-coherent layouts across nodes" 38 39import "nx_syscalls.nx" 40import "nx_probe.nx" 41import "nx_calibrate.nx" 42import "nx_select.nx" 43import "nx_select_joint.nx" 44 45func _make_probe_rv64() -> *NxProbeRecord { 46 let p: *NxProbeRecord = nx_probe_new() 47 p.actual_isa_family = NX_ISA_RV64 48 p.actual_endianness = NX_ENDIAN_LITTLE 49 p.actual_pointer_width_bits = 64 50 p.actual_page_size_bytes = 4096 51 p.actual_mmap_works = 1 52 p.actual_write_works = 1 53 p.actual_mono_clock_works = 1 54 return p 55} 56 57func main() -> i64 { 58 let probe: *NxProbeRecord = _make_probe_rv64() 59 let policy: *NxPolicy = nx_policy_throughput_default() 60 61 // ----- Node A candidates ----- 62 let a_cheap_row: *NxManifest = nx_manifest_new( 63 100, 1001, 64 nx_isa_bit(NX_ISA_RV64), 65 0, 4096, 66 NX_TIER_INF_MOBILE, NX_TIER_INF_HPC, 67 100, 0, 0, 0) 68 nx_manifest_set_layout(a_cheap_row, NX_LAYOUT_OPAQUE_PASS, NX_LAYOUT_ROW_MAJOR) 69 70 let a_medium_col: *NxManifest = nx_manifest_new( 71 100, 1002, 72 nx_isa_bit(NX_ISA_RV64), 73 0, 4096, 74 NX_TIER_INF_MOBILE, NX_TIER_INF_HPC, 75 300, 0, 0, 0) 76 nx_manifest_set_layout(a_medium_col, NX_LAYOUT_OPAQUE_PASS, NX_LAYOUT_COL_MAJOR) 77 78 let a_expensive_col: *NxManifest = nx_manifest_new( 79 100, 1003, 80 nx_isa_bit(NX_ISA_RV64), 81 0, 4096, 82 NX_TIER_INF_MOBILE, NX_TIER_INF_HPC, 83 900, 0, 0, 0) 84 nx_manifest_set_layout(a_expensive_col, NX_LAYOUT_OPAQUE_PASS, NX_LAYOUT_COL_MAJOR) 85 86 // ----- Node B candidates ----- 87 let b_cheap_col: *NxManifest = nx_manifest_new( 88 200, 2001, 89 nx_isa_bit(NX_ISA_RV64), 90 0, 4096, 91 NX_TIER_INF_MOBILE, NX_TIER_INF_HPC, 92 100, 0, 0, 0) 93 nx_manifest_set_layout(b_cheap_col, NX_LAYOUT_COL_MAJOR, NX_LAYOUT_OPAQUE_PASS) 94 95 let b_expensive_row: *NxManifest = nx_manifest_new( 96 200, 2002, 97 nx_isa_bit(NX_ISA_RV64), 98 0, 4096, 99 NX_TIER_INF_MOBILE, NX_TIER_INF_HPC, 100 900, 0, 0, 0) 101 nx_manifest_set_layout(b_expensive_row, NX_LAYOUT_ROW_MAJOR, NX_LAYOUT_OPAQUE_PASS) 102 103 // ----- Build node arrays ----- 104 let a_ptrs: *i64 = (sys_mmap(32)) as *i64 105 a_ptrs[0] = a_cheap_row as i64 106 a_ptrs[1] = a_medium_col as i64 107 a_ptrs[2] = a_expensive_col as i64 108 109 let b_ptrs: *i64 = (sys_mmap(32)) as *i64 110 b_ptrs[0] = b_cheap_col as i64 111 b_ptrs[1] = b_expensive_row as i64 112 113 let node_a: *NxJointNode = nx_joint_node_new(100, a_ptrs, 3) 114 let node_b: *NxJointNode = nx_joint_node_new(200, b_ptrs, 2) 115 116 // ----- 1. Single-class (independent) selection for sanity ----- 117 // Per-node argmin: should pick A_cheap_row (index 0) and B_cheap_col (index 0). 118 // These local optima are INCOMPATIBLE across the edge. 119 let solo_a: i64 = nx_select(a_ptrs, 3, probe, NX_TIER_INF_LAPTOP, 1048576, 0, policy) 120 if solo_a != 0 { return 1 } // single-class picks A_cheap_row locally 121 let solo_b: i64 = nx_select(b_ptrs, 2, probe, NX_TIER_INF_LAPTOP, 1048576, 0, policy) 122 if solo_b != 0 { return 2 } // single-class picks B_cheap_col locally 123 124 // Confirm the local pair is layout-incompatible. 125 let local_a: *NxManifest = a_ptrs[solo_a] as *NxManifest 126 let local_b: *NxManifest = b_ptrs[solo_b] as *NxManifest 127 if nx_layout_compatible(local_a.out_layout, local_b.in_layout) != 0 { return 3 } 128 129 // ----- 2. Joint selection ----- 130 let out_sel: *i64 = (sys_mmap(16)) as *i64 131 out_sel[0] = -99 132 out_sel[1] = -99 133 let rc: i64 = nx_select_joint_2node(node_a, node_b, probe, 134 NX_TIER_INF_LAPTOP, 1048576, 0, 135 policy, out_sel) 136 if rc != NX_SEL_JOINT_OK { return 4 } 137 138 // Expected: (A_medium_col=1, B_cheap_col=0) 139 if out_sel[0] != 1 { return 5 } 140 if out_sel[1] != 0 { return 6 } 141 142 // ----- 3. Compatibility verified end-to-end ----- 143 let picked_a: *NxManifest = a_ptrs[out_sel[0]] as *NxManifest 144 let picked_b: *NxManifest = b_ptrs[out_sel[1]] as *NxManifest 145 if picked_a.out_layout != NX_LAYOUT_COL_MAJOR { return 7 } 146 if picked_b.in_layout != NX_LAYOUT_COL_MAJOR { return 8 } 147 if nx_layout_compatible(picked_a.out_layout, picked_b.in_layout) != 1 { return 9 } 148 149 // ----- 4. Variant ID survives selection ----- 150 if picked_a.variant_id != 1002 { return 10 } // A_medium_col 151 if picked_b.variant_id != 2001 { return 11 } // B_cheap_col 152 153 // ----- 5. No-feasible-pair gate ----- 154 // Construct a no-overlap case: node A produces ONLY row; node B 155 // consumes ONLY col. No compatible pair exists. 156 let a_only_row: *NxManifest = nx_manifest_new( 157 100, 5001, 158 nx_isa_bit(NX_ISA_RV64), 159 0, 4096, 160 NX_TIER_INF_MOBILE, NX_TIER_INF_HPC, 161 100, 0, 0, 0) 162 nx_manifest_set_layout(a_only_row, NX_LAYOUT_OPAQUE_PASS, NX_LAYOUT_ROW_MAJOR) 163 164 let b_only_col: *NxManifest = nx_manifest_new( 165 200, 5002, 166 nx_isa_bit(NX_ISA_RV64), 167 0, 4096, 168 NX_TIER_INF_MOBILE, NX_TIER_INF_HPC, 169 100, 0, 0, 0) 170 nx_manifest_set_layout(b_only_col, NX_LAYOUT_COL_MAJOR, NX_LAYOUT_OPAQUE_PASS) 171 172 let arow_ptrs: *i64 = (sys_mmap(8)) as *i64 173 arow_ptrs[0] = a_only_row as i64 174 let bcol_ptrs: *i64 = (sys_mmap(8)) as *i64 175 bcol_ptrs[0] = b_only_col as i64 176 let arow_node: *NxJointNode = nx_joint_node_new(100, arow_ptrs, 1) 177 let bcol_node: *NxJointNode = nx_joint_node_new(200, bcol_ptrs, 1) 178 179 let out_no: *i64 = (sys_mmap(16)) as *i64 180 let rc_no: i64 = nx_select_joint_2node(arow_node, bcol_node, probe, 181 NX_TIER_INF_LAPTOP, 1048576, 0, 182 policy, out_no) 183 if rc_no != NX_SEL_JOINT_NO_FEASIBLE_PAIR { return 12 } 184 if out_no[0] != -1 { return 13 } 185 if out_no[1] != -1 { return 14 } 186 187 // ----- 6. OPAQUE_PASS wildcard ---------- 188 // A variant with OPAQUE_PASS on either side composes with anything. 189 let a_opaque: *NxManifest = nx_manifest_new( 190 100, 6001, 191 nx_isa_bit(NX_ISA_RV64), 192 0, 4096, 193 NX_TIER_INF_MOBILE, NX_TIER_INF_HPC, 194 50, 0, 0, 0) 195 // a_opaque has default OPAQUE_PASS layouts -- composes universally. 196 let aop_ptrs: *i64 = (sys_mmap(8)) as *i64 197 aop_ptrs[0] = a_opaque as i64 198 let aop_node: *NxJointNode = nx_joint_node_new(100, aop_ptrs, 1) 199 let out_op: *i64 = (sys_mmap(16)) as *i64 200 let rc_op: i64 = nx_select_joint_2node(aop_node, bcol_node, probe, 201 NX_TIER_INF_LAPTOP, 1048576, 0, 202 policy, out_op) 203 if rc_op != NX_SEL_JOINT_OK { return 15 } 204 if out_op[0] != 0 { return 16 } 205 if out_op[1] != 0 { return 17 } 206 207 return 0 208}