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}