code wiki / _hdl_build / nx_sweepcheck.nx

nx_sweepcheck.nx source

↩ module page · 165 lines · 7447 B

1// nx_sweepcheck.nx -- MECHANISES THE MOST EXPENSIVE RECURRING ERROR OF THIS PROGRAM: reporting a result 2// from a parameter that never reached the code. 3// 4// WHY THIS EXISTS (measured, not theorised). Across one session the same defect class was hit repeatedly: 5// * a reference-weight sweep returned 523/517/518/523 -- flat, because the handler never parsed the 6// argument. I nearly concluded the model change had failed. 7// * an index-offset A/B read 504 vs 508 and was declared "noise". The knob was hardcoded downstream; 8// the 4-point difference was PROMPT TEXT, not the knob. 9// * a dilation sweep at reach 0 / 4 / 12 returned BYTE-IDENTICAL results and was written up as a 10// regression WITH AN INVENTED ROOT CAUSE. The verb had fallen through to a different code path. 11// In every case the tell was the same and free: A SWEPT PARAMETER THAT PRODUCES NO VARIATION IS NOT AN 12// INEFFECTIVE PARAMETER -- IT IS AN UNWIRED ONE. Analysing such results is worse than useless, because a 13// plausible story gets attached to numbers that mean nothing. 14// 15// Per the banked law "A SESSION MUST REMEMBER < A TOOL THAT CANNOT DO THE WRONG THING", the check is 16// mechanised here instead of trusted to discipline. Feed it the measurements from any sweep BEFORE 17// interpreting them; it refuses the ones that carry no information. 18// 19// nx_sweepcheck values <v1> <v2> ... -> GREEN if the sweep varies, RED if it is flat (unwired) 20// nx_sweepcheck selftest 21// expect_exit: 0 license_tier: ORIGINAL 22import "nx_syscalls.nx" 23import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 24 25const SW_MIN_SAMPLES: i64 = 2 26 27func sw_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 28// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 29// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 30// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 31// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 32func sw_n(v: i64) -> i64 { nxi_out(v); return 0 } 33func sw_streq(a: *u8, b: *u8) -> i64 { 34 var i: i64=0 35 while a[i]!=(0 as u8) { if a[i]!=b[i] { return 0 } i=i+1 } 36 if b[i]!=(0 as u8) { return 0 } 37 return 1 38} 39func sw_atoi(s: *u8) -> i64 { 40 var v: i64=0 41 var i: i64=0 42 var neg: i64=0 43 if s[0]==(45 as u8) { neg=1; i=1 } 44 while s[i]!=(0 as u8) { let c: i64=(s[i] as i64)&255; if c>=48 { if c<=57 { v=v*10+(c-48) } } i=i+1 } 45 if neg==1 { return 0-v } 46 return v 47} 48 49// How many DISTINCT values does the sweep contain? 1 = flat = the parameter did nothing at all. 50func sw_distinct(vals: *i64, n: i64) -> i64 { 51 var d: i64 = 0 52 var i: i64 = 0 53 while i < n { 54 var seen: i64 = 0 55 var j: i64 = 0 56 while j < i { if vals[j] == vals[i] { seen = 1 } j = j + 1 } 57 if seen == 0 { d = d + 1 } 58 i = i + 1 59 } 60 return d 61} 62 63func sw_spread(vals: *i64, n: i64) -> i64 { 64 if n <= 0 { return 0 } 65 var lo: i64 = vals[0] 66 var hi: i64 = vals[0] 67 var i: i64 = 1 68 while i < n { 69 if vals[i] < lo { lo = vals[i] } 70 if vals[i] > hi { hi = vals[i] } 71 i = i + 1 72 } 73 return hi - lo 74} 75 76// The verdict. 0 = the sweep carries information; 3 = FLAT, treat as unwired and do not interpret. 77func sw_verdict(vals: *i64, n: i64, emit: i64) -> i64 { 78 if n < SW_MIN_SAMPLES { 79 if emit==1 { sw_w("{\"verdict\":\"RED\",\"why\":\"a sweep needs at least two samples to say anything\"}\n" as *u8) } 80 return 2 81 } 82 let d: i64 = sw_distinct(vals, n) 83 let s: i64 = sw_spread(vals, n) 84 if emit==1 { 85 sw_w("{\"samples\":" as *u8); sw_n(n) 86 sw_w(",\"distinct\":" as *u8); sw_n(d) 87 sw_w(",\"spread\":" as *u8); sw_n(s) 88 if d <= 1 { 89 sw_w(",\"verdict\":\"RED\",\"reading\":\"FLAT -- every sample identical. Treat the parameter as UNWIRED, not ineffective: verify it reaches the code before interpreting anything. Do NOT attach a root cause to these numbers.\"}\n" as *u8) 90 } else { 91 sw_w(",\"verdict\":\"GREEN\",\"reading\":\"the sweep varies, so the parameter demonstrably reaches the code and the results carry information\"}\n" as *u8) 92 } 93 } 94 if d <= 1 { return 3 } 95 return 0 96} 97 98func sw_selftest() -> i64 { 99 var pass: i64 = 0 100 var total: i64 = 0 101 let v: *i64 = sys_mmap(64) as *i64 102 103 // T1 the REAL dilation sweep that fooled me: 371/371/371 must be REFUSED 104 v[0]=371; v[1]=371; v[2]=371 105 total=total+1 106 let a: i64 = sw_verdict(v, 3, 0) 107 if a == 3 { pass=pass+1; sw_w(" [PASS] " as *u8) } else { sw_w(" [FAIL] " as *u8) } 108 sw_w("T1 FLAT-IS-UNWIRED: the real 371/371/371 dilation sweep is REFUSED (rc=" as *u8); sw_n(a); sw_w(")\n" as *u8) 109 110 // T2 the same sweep AFTER the wiring fix: 620/620/622 must PASS (2 distinct is enough) 111 v[0]=620; v[1]=620; v[2]=622 112 total=total+1 113 let b: i64 = sw_verdict(v, 3, 0) 114 if b == 0 { pass=pass+1; sw_w(" [PASS] " as *u8) } else { sw_w(" [FAIL] " as *u8) } 115 sw_w("T2 REAL VARIATION PASSES: the post-fix 620/620/622 sweep is accepted (rc=" as *u8); sw_n(b); sw_w(")\n" as *u8) 116 117 // T3 the ref_weight flat sweep 523/517/518/523 -- NOT identical, so it must NOT be refused as flat. 118 // This is the honest boundary: this organ catches DEAD parameters, not weak ones. A weak-but-live 119 // parameter is a different question and must not be silently folded into "unwired". 120 v[0]=523; v[1]=517; v[2]=518; v[3]=523 121 total=total+1 122 let c: i64 = sw_verdict(v, 4, 0) 123 if c == 0 { pass=pass+1; sw_w(" [PASS] " as *u8) } else { sw_w(" [FAIL] " as *u8) } 124 sw_w("T3 SCOPE HONESTY: a varying-but-weak sweep is NOT called unwired (rc=" as *u8); sw_n(c); sw_w(") -- this tool detects DEAD parameters, not weak ones\n" as *u8) 125 126 // T4 too few samples is refused rather than guessed 127 v[0]=5 128 total=total+1 129 let e: i64 = sw_verdict(v, 1, 0) 130 if e == 2 { pass=pass+1; sw_w(" [PASS] " as *u8) } else { sw_w(" [FAIL] " as *u8) } 131 sw_w("T4 REFUSES A SINGLE SAMPLE: one measurement is not a sweep (rc=" as *u8); sw_n(e); sw_w(")\n" as *u8) 132 133 sw_w("\n=== nx_sweepcheck " as *u8); sw_n(pass); sw_w("/" as *u8); sw_n(total) 134 if pass==total { 135 sw_w(" verdict=GREEN -- refuses the exact flat sweep that produced an invented root cause, accepts the same sweep once wired, and does not overreach into calling a weak parameter dead.\n" as *u8) 136 return 0 137 } 138 sw_w(" verdict=RED\n" as *u8) 139 return 1 140} 141 142func main(argc: i64, argv: *i64) -> i64 { 143 if argc < 2 { 144 sw_w("usage: nx_sweepcheck values <v1> <v2> ... | selftest\n" as *u8) 145 return 2 146 } 147 let verb: *u8 = argv[1] as *u8 148 if sw_streq(verb, "selftest" as *u8)==1 { 149 let f: i64 = sw_selftest() 150 if f==0 { sys_exit(0); return 0 } 151 sys_exit(1); return 1 152 } 153 if sw_streq(verb, "values" as *u8)==1 { 154 let n: i64 = argc - 2 155 if n < 1 { sw_w("{\"verdict\":\"RED\",\"why\":\"no values given\"}\n" as *u8); sys_exit(2); return 2 } 156 let v: *i64 = sys_mmap((n+1)*8) as *i64 157 var i: i64 = 0 158 while i < n { v[i] = sw_atoi(argv[i+2] as *u8); i = i + 1 } 159 let rc: i64 = sw_verdict(v, n, 1) 160 sys_exit(rc) 161 return rc 162 } 163 sw_w("{\"error\":\"unknown verb (values|selftest)\"}\n" as *u8) 164 return 2 165}