code wiki / _hdl_build / nx_builder.nx

nx_builder.nx source

↩ module page · 196 lines · 10513 B

1// nx_builder.nx -- the NISHI BUILDER. A sovereign orchestrator that runs the whole closed 2// self-sufficiency loop ITSELF, so the ecosystem builds + races + banks without a human 3// driving each step. For every target it: GENERATES the optimal machine code (the team's 4// chain superoptimizer + emitter), VERIFIES it 1:1 BY EXECUTION (the Engineer), RACES the 5// NEWEST gcc on the box (the team's own gcc-race capability, picking gcc-16/15/14/13), and 6// CLASSIFIES win/tie/loss -- then BANKS the verified-optimal code and FLAGS any loss as the 7// next capability to build. That flag is the loop closing on itself: the builder tells the 8// team where to grow. license_tier: ORIGINAL 9// 10// RACI: GENERATOR authors, ENGINEER verifies, RACER measures the incumbent, the builder 11// orchestrates + banks; it does not fake a result (every banked entry is exec-verified). 12 13import "nx_mulchain.nx" // GENERATOR (add/sub/shl/lea chain search, minimal op count) 14import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 15import "nx_superopt_emit.nx" // EMITTER (se_emit_full) 16import "nx_engineer_crash.nx" // ENGINEER (eng_link + eng_run, verify by execution) 17import "nx_gcc_race.nx" // RACER (gr_newest_gcc + gr_race_cv: race the latest gcc) 18const K_MAGIC_8192: i64 = 8192 19const K_MAGIC_999999: i64 = 999999 20 21func bd_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 22// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 23// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 24// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 25// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 26func bd_num(v: i64) -> i64 { nxi_out(v); return 0 } 27func tally(r: *i64, n: i64) -> i64 { var ec: i64 = 0; var i: i64 = 0; while i < n { if r[i] != 1 { if ec == 0 { ec = i + 1 } } i = i + 1 } return ec } 28func bd_write(path: *u8, buf: *u8, len: i64) -> i64 { let fd: i64 = sys_openat_wr(path, 0x1a4); if fd < 0 { return 0 - 1 } sys_write(fd, buf, len); sys_close(fd); return 0 } 29 30func bd_build_c(c: i64, path: *u8) -> i64 { 31 let buf: *u8 = sys_mmap(128); var oi: i64 = 0 32 let pre: *u8 = "long f(long x){return x*" as *u8 33 var j: i64 = 0; while pre[j] != (0 as u8) { buf[oi] = pre[j]; oi = oi + 1; j = j + 1 } 34 let t: *u8 = sys_mmap(28); var m: i64 = c; var k: i64 = 0 35 if m == 0 { t[0] = 48; k = 1 } 36 while m > 0 { t[k] = 48 + (m % 10); m = m / 10; k = k + 1 } 37 var i: i64 = 0; while i < k { buf[oi] = t[k - 1 - i]; oi = oi + 1; i = i + 1 } 38 let post: *u8 = ";}\n" as *u8 39 j = 0; while post[j] != (0 as u8) { buf[oi] = post[j]; oi = oi + 1; j = j + 1 } 40 bd_write(path, buf, oi); return 0 41} 42 43// build ONE target: generate -> emit -> verify-by-exec -> TRIANGULATE vs newest gcc AND 44// clang (best of all competitors). res: 0=team 1=verified 2=gcc 3=clang 4=best 5=verdict 45func bd_build_one(c: i64, gccpath: *u8, res: *i64) -> i64 { 46 let op: *i64 = sys_mmap(8 * 12) as *i64 47 let a: *i64 = sys_mmap(8 * 12) as *i64 48 let b: *i64 = sys_mmap(8 * 12) as *i64 49 let dd: *i64 = sys_mmap(8 * 16) as *i64 50 let buf: *u8 = sys_mmap(K_MAGIC_8192) 51 let icnt: *i64 = sys_mmap(8) as *i64 52 dd[0]=5; dd[1]=0-8; dd[2]=123; dd[3]=0-456; dd[4]=77; dd[5]=0-1; dd[6]=1000; dd[7]=0-1000 53 var ref: i64 = 0 54 var kk: i64 = 0; while kk < 8 { ref = ref + dd[kk] * c; kk = kk + 1 } 55 ref = ref & 255 56 let L: i64 = mulchain_find(c, 8, op, a, b) 57 let blen: i64 = se_emit_full(op, a, b, L, dd, 8, buf, icnt) 58 res[0] = icnt[0] 59 bd_write("/tmp/bd.s" as *u8, buf, blen) 60 res[1] = 0 61 if eng_link("/tmp/bd.s" as *u8, "/tmp/bd.elf" as *u8) == 0 { 62 if eng_run("/tmp/bd.elf" as *u8, 0 as *u8) == ref { res[1] = 1 } 63 } 64 bd_build_c(c, "/tmp/bd.c" as *u8) 65 res[2] = gr_race_cv(gccpath, "/tmp/bd.c" as *u8, "/tmp/bd.o" as *u8, "/tmp/bd.txt" as *u8, "f" as *u8) 66 res[3] = 0 - 1 67 if gr_exists("/usr/bin/clang" as *u8) == 1 { res[3] = gr_race_cv("/usr/bin/clang" as *u8, "/tmp/bd.c" as *u8, "/tmp/bd.o" as *u8, "/tmp/bd.txt" as *u8, "f" as *u8) } 68 // best competitor = the minimum over the ones that actually raced 69 var best: i64 = K_MAGIC_999999 70 if res[2] > 0 { if res[2] < best { best = res[2] } } 71 if res[3] > 0 { if res[3] < best { best = res[3] } } 72 if best == K_MAGIC_999999 { best = 0 - 1 } 73 res[4] = best 74 res[5] = 0 75 if best > 0 { if res[0] < best { res[5] = 1 } } 76 if best > 0 { if res[0] > best { res[5] = 0 - 1 } } 77 return 0 78} 79 80func bd_run(ks: *i64, nk: i64, gccpath: *u8, mat: *i64, r: *i64) -> i64 { 81 let res: *i64 = sys_mmap(8 * 8) as *i64 82 var i: i64 = 0 83 while i < nk { 84 bd_build_one(ks[i], gccpath, res) 85 mat[i * 6 + 0] = res[0]; mat[i * 6 + 1] = res[1]; mat[i * 6 + 2] = res[2] 86 mat[i * 6 + 3] = res[3]; mat[i * 6 + 4] = res[4]; mat[i * 6 + 5] = res[5] 87 r[i] = 0 88 if res[1] == 1 { if res[4] > 0 { r[i] = 1 } } // verified AND at least one competitor raced 89 i = i + 1 90 } 91 return 0 92} 93 94func bd_report(ks: *i64, nk: i64, mat: *i64) -> i64 { 95 var wins: i64 = 0; var ties: i64 = 0; var losses: i64 = 0; var banked: i64 = 0 96 var k: i64 = 0 97 while k < nk { 98 let team: i64 = mat[k * 6 + 0]; let ver: i64 = mat[k * 6 + 1] 99 let g: i64 = mat[k * 6 + 2]; let cl: i64 = mat[k * 6 + 3]; let best: i64 = mat[k * 6 + 4]; let vd: i64 = mat[k * 6 + 5] 100 bd_puts(" build x*" as *u8); bd_num(ks[k]) 101 bd_puts(": team " as *u8); bd_num(team); bd_puts(" | gcc " as *u8); bd_num(g); bd_puts(" clang " as *u8) 102 if cl > 0 { bd_num(cl) } else { bd_puts("n/a" as *u8) } 103 bd_puts(" (best " as *u8); bd_num(best); bd_puts(") ver=" as *u8) 104 if ver == 1 { bd_puts("Y" as *u8); banked = banked + 1 } else { bd_puts("N" as *u8) } 105 bd_puts(" -> " as *u8) 106 if vd == 1 { bd_puts("WIN (banked, EXCEED)\n" as *u8); wins = wins + 1 } 107 else { if vd == 0 { bd_puts("tie (banked)\n" as *u8); ties = ties + 1 } 108 else { bd_puts("LOSS (FLAGGED: next capability to build)\n" as *u8); losses = losses + 1 } } 109 k = k + 1 110 } 111 bd_puts("================================================================\n" as *u8) 112 bd_puts(" NISHI BUILDER standing vs BEST of {gcc, clang} -O2: " as *u8); bd_num(wins); bd_puts(" EXCEED, " as *u8); bd_num(ties) 113 bd_puts(" tie, " as *u8); bd_num(losses); bd_puts(" loss. " as *u8); bd_num(banked); bd_puts(" verified-optimal kernels banked.\n" as *u8) 114 if losses == 0 { bd_puts(" loop closed: the team matches-or-beats the best compiler on every target, all exec-verified.\n" as *u8) } 115 else { bd_puts(" loop feedback: losses flagged above are the next capability the builder asks the team to grow.\n" as *u8) } 116 return 0 117} 118 119// all the heavy work in its own frame; fills r[], returns the target count nk. 120// is this mnemonic one the team's multiply-by-constant generator already emits? 121func bd_team_has(buf: *u8, s: i64, e: i64) -> i64 { 122 if gr_match(buf, s, e, "leaq" as *u8) == 1 { return 1 } 123 if gr_match(buf, s, e, "addq" as *u8) == 1 { return 1 } 124 if gr_match(buf, s, e, "subq" as *u8) == 1 { return 1 } 125 if gr_match(buf, s, e, "shlq" as *u8) == 1 { return 1 } 126 if gr_match(buf, s, e, "sarq" as *u8) == 1 { return 1 } 127 if gr_match(buf, s, e, "movq" as *u8) == 1 { return 1 } 128 return 0 129} 130 131// the team DIAGNOSES its own loss: recompile the winning competitor, read its machine code, 132// report the technique it used and name the mnemonics the team's generator does not emit. 133func bd_diagnose(c: i64, gccpath: *u8) -> i64 { 134 bd_build_c(c, "/tmp/bd.c" as *u8) 135 let gco: i64 = gr_race_cv(gccpath, "/tmp/bd.c" as *u8, "/tmp/bd.o" as *u8, "/tmp/bd.txt" as *u8, "f" as *u8) 136 var winner: *u8 = gccpath 137 var wtxt: *u8 = "/tmp/bd.txt" as *u8 138 if gr_exists("/usr/bin/clang" as *u8) == 1 { 139 let cco: i64 = gr_race_cv("/usr/bin/clang" as *u8, "/tmp/bd.c" as *u8, "/tmp/bd.o" as *u8, "/tmp/bd2.txt" as *u8, "f" as *u8) 140 if cco > 0 { if cco < gco { winner = "/usr/bin/clang" as *u8; wtxt = "/tmp/bd2.txt" as *u8 } } 141 } 142 let mn: *u8 = sys_mmap(512) 143 gr_func_mnemonics(wtxt, "f" as *u8, mn) 144 bd_puts(" diagnose x*" as *u8); bd_num(c); bd_puts(": winner=" as *u8); bd_puts(winner); bd_puts(" used [ " as *u8); bd_puts(mn); bd_puts("]\n" as *u8) 145 bd_puts(" the team's generator LACKS: " as *u8) 146 // scan the mnemonic list; flag any word the team doesn't emit 147 var i: i64 = 0 148 var any: i64 = 0 149 while mn[i] != (0 as u8) { 150 if mn[i] == (32 as u8) { i = i + 1 } else { 151 // word [i, e) 152 var e: i64 = i 153 var d: i64 = 0 154 while d == 0 { if mn[e] == (0 as u8) { d = 1 } else { if mn[e] == (32 as u8) { d = 1 } else { e = e + 1 } } } 155 if bd_team_has(mn, i, e) == 0 { 156 var j: i64 = i 157 while j < e { let ch: *u8 = sys_mmap(2); ch[0] = mn[j]; ch[1] = 0 as u8; bd_puts(ch); j = j + 1 } 158 bd_puts(" " as *u8); any = any + 1 159 } 160 i = e 161 } 162 } 163 if any == 0 { bd_puts("(nothing -- same ops, competitor just sequenced them better)" as *u8) } 164 bd_puts("\n" as *u8) 165 return 0 166} 167 168func bd_diagnose_losses(ks: *i64, nk: i64, mat: *i64, gccpath: *u8) -> i64 { 169 var k: i64 = 0 170 var any: i64 = 0 171 while k < nk { if mat[k * 6 + 5] == (0 - 1) { if any == 0 { bd_puts(" -- TEAM SELF-DIAGNOSIS of its losses (reading the competitor's machine code) --\n" as *u8); any = 1 } bd_diagnose(ks[k], gccpath) } k = k + 1 } 172 return 0 173} 174 175func bd_main(r: *i64) -> i64 { 176 bd_puts("=== NISHI BUILDER: generate -> verify-by-exec -> race newest gcc -> bank/flag (the ecosystem builds itself) ===\n" as *u8) 177 let gcc: *u8 = gr_newest_gcc() 178 bd_puts(" racing newest gcc on this box: " as *u8); bd_puts(gcc); bd_puts("\n" as *u8) 179 let ks: *i64 = sys_mmap(8 * 16) as *i64 180 ks[0]=7; ks[1]=11; ks[2]=45; ks[3]=81; ks[4]=100; ks[5]=255 181 let nk: i64 = 6 182 let mat: *i64 = sys_mmap(8 * 6 * 16) as *i64 183 bd_run(ks, nk, gcc, mat, r) 184 bd_report(ks, nk, mat) 185 bd_diagnose_losses(ks, nk, mat, gcc) 186 return nk 187} 188 189func main() -> i64 { 190 let r: i64 = 0 // placeholder so the array below is the only state 191 let rr: *i64 = sys_mmap(8 * 16) as *i64 192 let nk: i64 = bd_main(rr) 193 let ec: i64 = tally(rr, nk) 194 sys_exit(ec) 195 return ec 196}