nx_swarm_pack.nx source
↩ module page · 578 lines · 31238 B
1// nx_swarm_pack.nx -- SWARM FABRIC heterogeneous MAX-UTILIZATION scheduler (SF-R-PACK): get the MOST out
2// of EVERY participant by exploiting ALL of its resources at once -- RAM, CPU cores, GPU, VRAM -- not routing
3// a job to one class (operator 2026-07-15: "gpu was just an example ... use the ram cpu gpu whatever is
4// available to get the most out of what participates in the supercomputer", the NIST/heterogeneous-compute
5// model). A single participant can host MANY demands using DIFFERENT resources concurrently; work spreads to
6// fill every participant's spare capacity.
7//
8// RESOURCE VECTOR (aligned to the beacon telemetry = the FEED): per participant
9// pcpu = spare CPU milli-cores (beacon: (1000-lpc)*ncpu) · pram = free RAM MB (beacon mem_avail_mb)
10// pgpu = GPU present 0/1 · pvram = free VRAM MB (the axis to wire from a GPU collector)
11// DEMAND VECTOR: per chunk dcpu (milli-cores) · dram (MB) · dgpu (needs GPU 0/1) · dvram (MB)
12//
13// COMPOSES (check-before-build 2026-07-15): nx_resource_arbiter ALREADY models VRAM/RAM/CPU/GPU/net/disk as
14// first-class allocatable kinds with fairness+preempt -- but is "fed by nothing". This packer IS that feed +
15// the placement loop; the fairness/preempt/treaty LAYER wires to nx_resource_arbiter (nx_ra_request/grant)
16// as the allocation policy SSOT. Hard-constraint classify = nx_swarm_coord. Telemetry = nx_node_beacon.
17//
18// ★★THE LIAR-KILLERS (the operator's principle, mechanized): (1) NO participant is ever over-allocated on ANY
19// resource (sum assigned <= supply, per axis). (2) a demand is NEVER placed on a participant that lacks its
20// REQUIRED resource -- a needs-GPU chunk never lands on a GPU-less node (GPU generalized to "whatever it
21// requires"). (3) packing beats naive round-robin on placed-count (measured). (4) HETEROGENEOUS EXPLOITATION
22// proven: one participant hosts DIFFERENT resource-type demands at once; no participant sits idle while a
23// demand it could serve is queued.
24//
25// pack <poolfile> <jobsfile> -- pool line "name cpu_milli ram_mb gpu vram_mb"; job line "id cpu ram gpu vram"
26// [gate] -- self-gate: the heterogeneous scenario + all four liar-killers
27// license_tier: ORIGINAL expect_exit:0
28import "nx_swarm_lib.nx"
29import "nx_swarm_gpu.nx"
30import "nx_readcap_lib.nx"
31const SK_MAGIC_8000: i64 = 8000
32const SK_MAGIC_16000: i64 = 16000
33const SK_MAGIC_12000: i64 = 12000
34const SK_MAGIC_3000: i64 = 3000
35const SK_MAGIC_32000: i64 = 32000
36const SK_MAGIC_4000: i64 = 4000
37const SK_MAGIC_5000: i64 = 5000
38const SK_MAGIC_20000: i64 = 20000
39const SK_MAGIC_2000: i64 = 2000
40const SK_MAGIC_65536: i64 = 65536
41const SK_MAGIC_8192: i64 = 8192
42const SK_MAGIC_1000000: i64 = 1000000
43
44const SK_MAXP: i64 = 256
45const SK_MAXD: i64 = 4096
46
47func sk_puts(s: *u8) -> i64 { sys_write(1, s, fa_len(s)); return 0 }
48
49// best-fit assign of demand j onto the participants; decrements the winner's vector. returns participant idx or -1.
50// FIT = supplies ALL of the demand's resources (hard constraint per axis). BEST = tightest CPU slack among fitting
51// (packs tightly, leaving big/flexible participants free for constrained demands) -- a participant with the
52// resource the demand needs is preferred to leave headroom elsewhere.
53func sk_place_one(pcpu: *i64, pram: *i64, pgpu: *i64, pvram: *i64, n: i64, dcpu: i64, dram: i64, dgpu: i64, dvram: i64) -> i64 {
54 var best: i64 = 0 - 1
55 var best_slack: i64 = 0
56 var i: i64 = 0
57 while i < n {
58 var fits: i64 = 1
59 if pcpu[i] < dcpu { fits = 0 }
60 if pram[i] < dram { fits = 0 }
61 if dgpu == 1 { if pgpu[i] == 0 { fits = 0 } } // ★ needs-GPU never fits a GPU-less node
62 if pvram[i] < dvram { fits = 0 }
63 if fits == 1 {
64 let slack: i64 = (pcpu[i] - dcpu) + (pram[i] - dram) // tightest combined slack = best fit
65 if best < 0 { best = i; best_slack = slack } else { if slack < best_slack { best = i; best_slack = slack } }
66 }
67 i = i + 1
68 }
69 if best >= 0 {
70 pcpu[best] = pcpu[best] - dcpu
71 pram[best] = pram[best] - dram
72 pvram[best] = pvram[best] - dvram
73 // GPU is a boolean CAPABILITY here (shareable across demands via time-slice); vram is the metered axis
74 }
75 return best
76}
77
78// pack all m demands onto n participants. Fills assign[j] = participant idx or -1 (queued).
79// Processes GPU-demands FIRST (scarcest hard constraint), then by descending RAM (big chunks first) --
80// best-fit-decreasing, the standard bin-packing heuristic for high utilization.
81func sk_pack(pcpu: *i64, pram: *i64, pgpu: *i64, pvram: *i64, n: i64,
82 dcpu: *i64, dram: *i64, dgpu: *i64, dvram: *i64, m: i64, assign: *i64) -> i64 {
83 var j: i64 = 0
84 while j < m { assign[j] = 0 - 1; j = j + 1 }
85 var placed: i64 = 0
86 // pass 1: GPU demands (hard-constrained -> place while GPU capacity exists)
87 j = 0
88 while j < m {
89 if dgpu[j] == 1 {
90 let w: i64 = sk_place_one(pcpu, pram, pgpu, pvram, n, dcpu[j], dram[j], 1, dvram[j])
91 if w >= 0 { assign[j] = w; placed = placed + 1 }
92 }
93 j = j + 1
94 }
95 // pass 2: non-GPU demands, biggest-RAM first (approximate BFD; a full sort is overkill for the demo)
96 var done: i64 = 0
97 while done == 0 {
98 var pick: i64 = 0 - 1
99 var pickram: i64 = 0 - 1
100 j = 0
101 while j < m {
102 if dgpu[j] == 0 { if assign[j] == (0 - 1) {
103 if dram[j] > pickram { pick = j; pickram = dram[j] }
104 } }
105 j = j + 1
106 }
107 if pick < 0 { done = 1 } else {
108 let w: i64 = sk_place_one(pcpu, pram, pgpu, pvram, n, dcpu[pick], dram[pick], 0, dvram[pick])
109 if w >= 0 { assign[pick] = w; placed = placed + 1; } else { assign[pick] = 0 - 2 } // -2 = tried, unplaceable
110 }
111 }
112 // normalize -2 back to -1 (queued)
113 j = 0
114 while j < m { if assign[j] == (0 - 2) { assign[j] = 0 - 1 } j = j + 1 }
115 return placed
116}
117
118// naive ROUND-ROBIN comparator: assign demand j to participant (j % n) iff it happens to fit; else queue.
119// (models the "spread evenly, ignore the resource vector" scheduler -- the anti-pattern.) returns placed count.
120func sk_naive(pcpu: *i64, pram: *i64, pgpu: *i64, pvram: *i64, n: i64,
121 dcpu: *i64, dram: *i64, dgpu: *i64, dvram: *i64, m: i64) -> i64 {
122 let c2: *i64 = sys_mmap(8 * n + 16) as *i64
123 let r2: *i64 = sys_mmap(8 * n + 16) as *i64
124 let v2: *i64 = sys_mmap(8 * n + 16) as *i64
125 var i: i64 = 0
126 while i < n { c2[i] = pcpu[i]; r2[i] = pram[i]; v2[i] = pvram[i]; i = i + 1 }
127 var placed: i64 = 0
128 var j: i64 = 0
129 while j < m {
130 let t: i64 = j - (j / n) * n // j % n
131 var fits: i64 = 1
132 if c2[t] < dcpu[j] { fits = 0 }
133 if r2[t] < dram[j] { fits = 0 }
134 if dgpu[j] == 1 { if pgpu[t] == 0 { fits = 0 } }
135 if v2[t] < dvram[j] { fits = 0 }
136 if fits == 1 { c2[t] = c2[t] - dcpu[j]; r2[t] = r2[t] - dram[j]; v2[t] = v2[t] - dvram[j]; placed = placed + 1 }
137 j = j + 1
138 }
139 return placed
140}
141
142func sk_report(names: *i64, pcpu0: *i64, pram0: *i64, pgpu: *i64, pcpu: *i64, pram: *i64, n: i64,
143 dcpu: *i64, dram: *i64, dgpu: *i64, m: i64, assign: *i64) -> i64 {
144 let t: *u8 = sys_mmap(512)
145 var i: i64 = 0
146 while i < n {
147 var o: i64 = 0
148 o = fa_cat(t, o, " participant " as *u8); o = fa_cat(t, o, names[i] as *u8)
149 o = fa_cat(t, o, ": cpu " as *u8); o = fa_catn(t, o, pcpu0[i] - pcpu[i]); o = fa_cat(t, o, "/" as *u8); o = fa_catn(t, o, pcpu0[i])
150 o = fa_cat(t, o, " mc, ram " as *u8); o = fa_catn(t, o, pram0[i] - pram[i]); o = fa_cat(t, o, "/" as *u8); o = fa_catn(t, o, pram0[i])
151 o = fa_cat(t, o, " mb, gpu=" as *u8); o = fa_catn(t, o, pgpu[i])
152 o = fa_cat(t, o, " hosts:" as *u8)
153 var j: i64 = 0
154 var cnt: i64 = 0
155 while j < m {
156 if assign[j] == i {
157 o = fa_cat(t, o, " d" as *u8); o = fa_catn(t, o, j)
158 if dgpu[j] == 1 { o = fa_cat(t, o, "[gpu]" as *u8) } else { if dram[j] >= SK_MAGIC_8000 { o = fa_cat(t, o, "[ram]" as *u8) } else { o = fa_cat(t, o, "[cpu]" as *u8) } }
159 cnt = cnt + 1
160 }
161 j = j + 1
162 }
163 if cnt == 0 { o = fa_cat(t, o, " (idle)" as *u8) }
164 o = fa_cat(t, o, "\n" as *u8)
165 sys_write(1, t, o)
166 i = i + 1
167 }
168 return 0
169}
170
171// count distinct resource-TYPE tags a participant hosts (cpu/ram/gpu) -> heterogeneity proof.
172func sk_types_on(part: i64, dram: *i64, dgpu: *i64, m: i64, assign: *i64) -> i64 {
173 var has_cpu: i64 = 0
174 var has_ram: i64 = 0
175 var has_gpu: i64 = 0
176 var j: i64 = 0
177 while j < m {
178 if assign[j] == part {
179 if dgpu[j] == 1 { has_gpu = 1 } else { if dram[j] >= SK_MAGIC_8000 { has_ram = 1 } else { has_cpu = 1 } }
180 }
181 j = j + 1
182 }
183 return has_cpu + has_ram + has_gpu
184}
185
186func sk_gate() -> i64 {
187 var pass: i64 = 0
188 var total: i64 = 0
189 let n: i64 = 3
190 let names: *i64 = sys_mmap(64) as *i64
191 names[0] = "laptop" as i64
192 names[1] = "nas" as i64
193 names[2] = "pi" as i64
194 // supply vectors (spare cpu milli-cores, free ram mb, gpu, free vram mb)
195 let pcpu0: *i64 = sys_mmap(64) as *i64
196 let pram0: *i64 = sys_mmap(64) as *i64
197 let pgpu: *i64 = sys_mmap(64) as *i64
198 let pvram0: *i64 = sys_mmap(64) as *i64
199 pcpu0[0] = SK_MAGIC_8000; pram0[0] = SK_MAGIC_16000; pgpu[0] = 1; pvram0[0] = SK_MAGIC_12000 // laptop: 8 cores, 16GB, RTX GPU 12GB
200 pcpu0[1] = SK_MAGIC_3000; pram0[1] = SK_MAGIC_32000; pgpu[1] = 0; pvram0[1] = 0 // nas: 3 cores, 32GB, no GPU
201 pcpu0[2] = SK_MAGIC_4000; pram0[2] = SK_MAGIC_4000; pgpu[2] = 0; pvram0[2] = 0 // pi: 4 cores, 4GB, no GPU
202 // working copies (decremented)
203 let pcpu: *i64 = sys_mmap(64) as *i64
204 let pram: *i64 = sys_mmap(64) as *i64
205 let pvram: *i64 = sys_mmap(64) as *i64
206 var i: i64 = 0
207 while i < n { pcpu[i] = pcpu0[i]; pram[i] = pram0[i]; pvram[i] = pvram0[i]; i = i + 1 }
208 // demands: 2 GPU gen, 1 big-RAM index, 4 CPU tiles
209 let m: i64 = 7
210 let dcpu: *i64 = sys_mmap(128) as *i64
211 let dram: *i64 = sys_mmap(128) as *i64
212 let dgpu: *i64 = sys_mmap(128) as *i64
213 let dvram: *i64 = sys_mmap(128) as *i64
214 dcpu[0]=500; dram[0]=1000; dgpu[0]=1; dvram[0]=SK_MAGIC_5000 // gen A (GPU)
215 dcpu[1]=500; dram[1]=1000; dgpu[1]=1; dvram[1]=SK_MAGIC_5000 // gen B (GPU)
216 dcpu[2]=1000; dram[2]=SK_MAGIC_20000; dgpu[2]=0; dvram[2]=0 // ram-index (big RAM -> only nas fits)
217 dcpu[3]=SK_MAGIC_2000; dram[3]=500; dgpu[3]=0; dvram[3]=0 // cpu tile
218 dcpu[4]=SK_MAGIC_2000; dram[4]=500; dgpu[4]=0; dvram[4]=0 // cpu tile
219 dcpu[5]=SK_MAGIC_2000; dram[5]=500; dgpu[5]=0; dvram[5]=0 // cpu tile
220 dcpu[6]=SK_MAGIC_2000; dram[6]=500; dgpu[6]=0; dvram[6]=0 // cpu tile
221 let assign: *i64 = sys_mmap(128) as *i64
222 let placed: i64 = sk_pack(pcpu, pram, pgpu, pvram, n, dcpu, dram, dgpu, dvram, m, assign)
223
224 sk_puts("--- heterogeneous pack (2 GPU gen, 1 RAM index, 4 CPU tiles over laptop/nas/pi) ---\n" as *u8)
225 sk_report(names, pcpu0, pram0, pgpu, pcpu, pram, n, dcpu, dram, dgpu, m, assign)
226
227 // T1 supply never exceeded (no participant over-allocated on any axis)
228 total = total + 1
229 var okcap: i64 = 1
230 i = 0
231 while i < n { if pcpu[i] < 0 { okcap = 0 } if pram[i] < 0 { okcap = 0 } if pvram[i] < 0 { okcap = 0 } i = i + 1 }
232 if okcap == 1 { pass = pass + 1; sk_puts("T1 no-overallocation OK\n" as *u8) }
233
234 // T2 ★ never-ignore-required-resource: every GPU demand landed on a gpu=1 participant (or queued), NEVER gpu=0
235 total = total + 1
236 var okgpu: i64 = 1
237 var j: i64 = 0
238 while j < m { if dgpu[j] == 1 { if assign[j] >= 0 { if pgpu[assign[j]] == 0 { okgpu = 0 } } } j = j + 1 }
239 if okgpu == 1 { pass = pass + 1; sk_puts("T2 gpu-demand-never-on-cpu-node OK\n" as *u8) }
240
241 // T3 the big-RAM index landed on nas (the only 32GB participant), never pi/laptop
242 total = total + 1
243 if assign[2] == 1 { pass = pass + 1; sk_puts("T3 ram-index->big-ram-node OK\n" as *u8) }
244
245 // T4 ★★HETEROGENEOUS EXPLOITATION: the laptop hosts >1 resource TYPE at once (GPU gen AND a CPU tile)
246 total = total + 1
247 if sk_types_on(0, dram, dgpu, m, assign) >= 2 { pass = pass + 1; sk_puts("T4 one-node-multi-resource-type OK\n" as *u8) }
248
249 // T5 NO idle participant while placeable demands exist (every participant does SOME work here)
250 total = total + 1
251 var idle: i64 = 0
252 i = 0
253 while i < n {
254 var hosts: i64 = 0
255 j = 0
256 while j < m { if assign[j] == i { hosts = 1 } j = j + 1 }
257 if hosts == 0 { idle = idle + 1 }
258 i = i + 1
259 }
260 if idle == 0 { pass = pass + 1; sk_puts("T5 every-participant-utilized OK\n" as *u8) }
261
262 // T6 MAX-UTILIZATION beats naive round-robin on placed-count (vector-aware > blind spread)
263 total = total + 1
264 // reset copies for naive
265 i = 0
266 while i < n { pcpu[i] = pcpu0[i]; pram[i] = pram0[i]; pvram[i] = pvram0[i]; i = i + 1 }
267 let naive: i64 = sk_naive(pcpu0, pram0, pgpu, pvram0, n, dcpu, dram, dgpu, dvram, m)
268 sk_puts(" packed=" as *u8); let tb: *u8 = sys_mmap(64); var to: i64 = fa_catn(tb, 0, placed); tb[to]=32 as u8; to=to+1; to=fa_cat(tb,to,"naive=" as *u8); to=fa_catn(tb,to,naive); tb[to]=10 as u8; sys_write(1,tb,to+1)
269 if placed >= naive { if placed >= 6 { pass = pass + 1; sk_puts("T6 max-utilization>=naive OK\n" as *u8) } }
270
271 // T7 queue-honest: any unplaced demand is assign=-1 (never misplaced) -- and here all 7 fit
272 total = total + 1
273 var okq: i64 = 1
274 j = 0
275 while j < m { if assign[j] < (0 - 1) { okq = 0 } j = j + 1 }
276 if okq == 1 { pass = pass + 1; sk_puts("T7 queue-honest OK\n" as *u8) }
277
278 // T8 DETERMINISM: repack -> identical placed count + assignment
279 total = total + 1
280 i = 0
281 while i < n { pcpu[i] = pcpu0[i]; pram[i] = pram0[i]; pvram[i] = pvram0[i]; i = i + 1 }
282 let assign2: *i64 = sys_mmap(128) as *i64
283 let placed2: i64 = sk_pack(pcpu, pram, pgpu, pvram, n, dcpu, dram, dgpu, dvram, m, assign2)
284 var okdet: i64 = 1
285 if placed2 != placed { okdet = 0 }
286 j = 0
287 while j < m { if assign2[j] != assign[j] { okdet = 0 } j = j + 1 }
288 if okdet == 1 { pass = pass + 1; sk_puts("T8 deterministic OK\n" as *u8) }
289
290 let t: *u8 = sys_mmap(128)
291 var to2: i64 = 0
292 to2 = fa_cat(t, to2, "SWARMPACKGATE " as *u8)
293 to2 = fa_catn(t, to2, pass)
294 to2 = fa_cat(t, to2, "/" as *u8)
295 to2 = fa_catn(t, to2, total)
296 if pass == total { to2 = fa_cat(t, to2, " verdict=GREEN\n" as *u8) } else { to2 = fa_cat(t, to2, " verdict=RED\n" as *u8) }
297 sys_write(1, t, to2)
298 if pass == total { return 0 }
299 return 1
300}
301
302// ---- LIVE pack: consume the beat-store snapshot (real beacon telemetry) + a jobs file ----
303func sk_skipsp(buf: *u8, n: i64, p: i64) -> i64 {
304 var i: i64 = p
305 var go: i64 = 1
306 while go == 1 { if i >= n { go = 0 } else { if (buf[i] as i64) == 32 { i = i + 1 } else { go = 0 } } }
307 return i
308}
309
310// is name[0..nl) a comma-field of the roster csv?
311func sk_roster_has(roster: *u8, name: *u8, nl: i64) -> i64 {
312 let rl: i64 = fa_len(roster)
313 if rl == 0 { return 0 }
314 var p: i64 = 0
315 while p < rl {
316 var q: i64 = p
317 var fend: i64 = rl
318 var scan: i64 = 1
319 while scan == 1 { if q >= rl { scan = 0 } else { if (roster[q] as i64) == 44 { fend = q; scan = 0 } else { q = q + 1 } } }
320 if fend - p == nl {
321 var k: i64 = 0
322 var same: i64 = 1
323 while k < nl { if roster[p+k] != name[k] { same = 0; k = nl } else { k = k + 1 } }
324 if same == 1 { return 1 }
325 }
326 p = fend + 1
327 }
328 return 0
329}
330
331// load participant vectors from a beat-store snapshot. names[i]=ptr; vector from live beacon fields.
332// pcpu = spare milli-cores = (1000-lpc)*ncpu ; pram = mem_avail_mb ; pgpu = name in roster ; pvram = 0 (wire).
333func sk_load_pool(snap: *u8, roster: *u8, names: *i64, pcpu: *i64, pram: *i64, pgpu: *i64, pvram: *i64, maxn: i64) -> i64 {
334 let buf: *u8 = sys_mmap(SK_MAGIC_65536)
335 let n: i64 = sb_read(snap, buf, SK_MAGIC_65536)
336 let namebuf: *u8 = sys_mmap(SK_MAGIC_8192)
337 var noff: i64 = 0
338 let f: *i64 = sys_mmap(128) as *i64
339 let nso: *i64 = sys_mmap(16) as *i64
340 let nlo: *i64 = sys_mmap(16) as *i64
341 let tso: *i64 = sys_mmap(16) as *i64
342 var cnt: i64 = 0
343 var i: i64 = 0
344 while i < n {
345 var e: i64 = i
346 var g: i64 = 1
347 while g == 1 { if e >= n { g = 0 } else { if (buf[e] as i64) == 10 { g = 0 } else { e = e + 1 } } }
348 if e > i { if cnt < maxn {
349 let line: *u8 = (buf as i64 + i) as *u8
350 let ln: i64 = e - i
351 if sb_fields(line, ln, f) == 1 {
352 sb_validate(line, ln, nso, nlo, tso)
353 let ns: i64 = nso[0]
354 let nl: i64 = nlo[0]
355 let np: i64 = noff
356 var k: i64 = 0
357 while k < nl { namebuf[noff] = line[ns+k]; noff = noff + 1; k = k + 1 }
358 namebuf[noff] = 0 as u8; noff = noff + 1
359 names[cnt] = namebuf as i64 + np
360 var spare: i64 = (1000 - f[3]) * f[2]
361 if spare < 0 { spare = 0 }
362 pcpu[cnt] = spare
363 pram[cnt] = f[5]
364 pgpu[cnt] = sk_roster_has(roster, (namebuf as i64 + np) as *u8, nl)
365 // VRAM not in the beacon yet (beacon-v3 wire): a GPU node advertises VRAM present-but-
366 // UNMETERED (large sentinel) so GPU demands fit; a non-GPU node stays 0 so they never do.
367 if pgpu[cnt] == 1 { pvram[cnt] = SK_MAGIC_1000000 } else { pvram[cnt] = 0 }
368 cnt = cnt + 1
369 }
370 } }
371 i = e + 1
372 }
373 return cnt
374}
375
376// load job demands: each line "cpu_milli ram_mb needs_gpu vram_mb" ('#' comment/blank skipped). returns m.
377func sk_load_jobs(jobs: *u8, dcpu: *i64, dram: *i64, dgpu: *i64, dvram: *i64, maxm: i64) -> i64 {
378 let buf: *u8 = sys_mmap(SK_MAGIC_65536)
379 let n: i64 = sb_read(jobs, buf, SK_MAGIC_65536)
380 let vout: *i64 = sys_mmap(16) as *i64
381 let pend: *i64 = sys_mmap(16) as *i64
382 var cnt: i64 = 0
383 var i: i64 = 0
384 while i < n {
385 var e: i64 = i
386 var g: i64 = 1
387 while g == 1 { if e >= n { g = 0 } else { if (buf[e] as i64) == 10 { g = 0 } else { e = e + 1 } } }
388 if e > i { if (buf[i] as i64) != 35 { if cnt < maxm {
389 var p: i64 = sk_skipsp(buf, e, i)
390 var vals: i64 = 0
391 if sb_pint(buf, e, p, vout, pend) == 1 { dcpu[cnt] = vout[0]; p = sk_skipsp(buf, e, pend[0]); vals = vals + 1 }
392 if sb_pint(buf, e, p, vout, pend) == 1 { dram[cnt] = vout[0]; p = sk_skipsp(buf, e, pend[0]); vals = vals + 1 }
393 if sb_pint(buf, e, p, vout, pend) == 1 { dgpu[cnt] = vout[0]; p = sk_skipsp(buf, e, pend[0]); vals = vals + 1 }
394 if sb_pint(buf, e, p, vout, pend) == 1 { dvram[cnt] = vout[0]; vals = vals + 1 }
395 if vals == 4 { cnt = cnt + 1 }
396 } } }
397 i = e + 1
398 }
399 return cnt
400}
401
402func sk_live(snap: *u8, jobs: *u8, roster: *u8) -> i64 {
403 let names: *i64 = sys_mmap(8 * SK_MAXP) as *i64
404 let pcpu0: *i64 = sys_mmap(8 * SK_MAXP) as *i64
405 let pram0: *i64 = sys_mmap(8 * SK_MAXP) as *i64
406 let pgpu: *i64 = sys_mmap(8 * SK_MAXP) as *i64
407 let pvram0: *i64 = sys_mmap(8 * SK_MAXP) as *i64
408 let n: i64 = sk_load_pool(snap, roster, names, pcpu0, pram0, pgpu, pvram0, SK_MAXP)
409 if n < 1 { sk_puts("SWARMPACK live: no participants in snapshot\n" as *u8); return 3 }
410 let dcpu: *i64 = sys_mmap(8 * SK_MAXD) as *i64
411 let dram: *i64 = sys_mmap(8 * SK_MAXD) as *i64
412 let dgpu: *i64 = sys_mmap(8 * SK_MAXD) as *i64
413 let dvram: *i64 = sys_mmap(8 * SK_MAXD) as *i64
414 let m: i64 = sk_load_jobs(jobs, dcpu, dram, dgpu, dvram, SK_MAXD)
415 if m < 1 { sk_puts("SWARMPACK live: no job demands\n" as *u8); return 3 }
416 let pcpu: *i64 = sys_mmap(8 * SK_MAXP) as *i64
417 let pram: *i64 = sys_mmap(8 * SK_MAXP) as *i64
418 let pvram: *i64 = sys_mmap(8 * SK_MAXP) as *i64
419 var i: i64 = 0
420 while i < n { pcpu[i] = pcpu0[i]; pram[i] = pram0[i]; pvram[i] = pvram0[i]; i = i + 1 }
421 let assign: *i64 = sys_mmap(8 * SK_MAXD) as *i64
422 let placed: i64 = sk_pack(pcpu, pram, pgpu, pvram, n, dcpu, dram, dgpu, dvram, m, assign)
423 sk_puts("--- LIVE heterogeneous pack over the fleet snapshot ---\n" as *u8)
424 sk_report(names, pcpu0, pram0, pgpu, pcpu, pram, n, dcpu, dram, dgpu, m, assign)
425 let t: *u8 = sys_mmap(128)
426 var o: i64 = fa_cat(t, 0, "SWARMPACK live placed=" as *u8)
427 o = fa_catn(t, o, placed); o = fa_cat(t, o, "/" as *u8); o = fa_catn(t, o, m)
428 o = fa_cat(t, o, " participants=" as *u8); o = fa_catn(t, o, n); o = fa_cat(t, o, "\n" as *u8)
429 sys_write(1, t, o)
430 // liar-killer even on live data: no GPU demand on a GPU-less participant
431 var okgpu: i64 = 1
432 var j: i64 = 0
433 while j < m { if dgpu[j] == 1 { if assign[j] >= 0 { if pgpu[assign[j]] == 0 { okgpu = 0 } } } j = j + 1 }
434 if okgpu == 0 { sk_puts("SWARMPACK LIVE VIOLATION: gpu demand on gpu-less node\n" as *u8); return 1 }
435 if placed == m { return 0 }
436 return 3
437}
438
439// Private pack-v2 measured pool contract. Existing pack API remains unchanged.
440const SK2_VERSION:i64=2
441const SK2_FIELDS:i64=10
442const SK2_NAME:i64=32
443const SK2_MAX:i64=9223372036854775807
444const SK2_UNIT:i64=1000000
445const SK2_UNKNOWN:i64=0
446const SK2_FRESH:i64=1
447const SK2_STALE:i64=2
448const SK2_REFUSED:i64=3
449const SK2_IO:i64=0-40
450const SK2_TRUNCATED:i64=0-41
451const SK2_FRAME:i64=0-42
452const SK2_ROW:i64=0-43
453const SK2_DUPLICATE:i64=0-44
454const SK2_CAPACITY:i64=0-45
455const SK2_POLICY:i64=0-46
456const SK2_MISSING:i64=0-47
457// Exact decimal preflight prevents the legacy validators' overflowing accumulators.
458func sk2_int(b:*u8,n:i64,p:i64,out:*i64)->i64{
459 var i:i64=p;var neg:i64=0;if i<n{if b[i]==(45 as u8){neg=1;i=i+1}}
460 var v:i64=0;var digits:i64=0
461 while i<n{let c:i64=b[i] as i64;if c<48||c>57{break};let d:i64=c-48
462 if v>(SK2_MAX-d)/10{return 0};v=v*10+d;i=i+1;digits=digits+1}
463 if digits==0{return 0};if neg==1{v=0-v};out[0]=v;out[1]=i;return 1
464}
465func sk2_row(b:*u8,n:i64,prefix:*u8,numbers:i64,values:*i64,name:*i64)->i64{
466 let plen:i64=fa_len(prefix);if n<=plen{return 0};var i:i64=0
467 while i<plen{if b[i]!=prefix[i]{return 0};i=i+1}
468 let start:i64=i;while i<n&&b[i]!=(32 as u8){let c:i64=b[i] as i64;if c<33||c==127{return 0};i=i+1}
469 if i-start<1||i-start>SK2_NAME{return 0};name[0]=start;name[1]=i-start
470 let parsed:*i64=sys_mmap(16) as *i64;var k:i64=0
471 while k<numbers{if i>=n||b[i]!=(32 as u8){return 0};i=i+1
472 if sk2_int(b,n,i,parsed)!=1{return 0};values[k]=parsed[0];i=parsed[1];k=k+1}
473 if i!=n{return 0};return 1
474}
475func sk2_read(path:*u8,b:*u8)->i64{
476 let fd:i64=sys_openat_rd(path);if fd==(0-2){return SK2_MISSING};if fd<0{return SK2_IO}
477 let st:*i64=sys_mmap(24) as *i64;let n:i64=rc_fill_file(fd,b,SK_MAGIC_65536,st);let closed:i64=sys_close(fd)
478 if st[0]==RC_FULL{return SK2_TRUNCATED};if rc_complete(st)!=1||closed!=0{return SK2_IO}
479 if n>0{if b[n-1]!=(10 as u8){return SK2_FRAME}};return n
480}
481func sk2_fresh(ts:i64,now:i64,window:i64,skew:i64)->i64{
482 if ts<=0{return SK2_REFUSED};if ts>now{if ts-now>skew{return SK2_REFUSED};return SK2_FRESH}
483 if now-ts>=window{return SK2_STALE};return SK2_FRESH
484}
485func sk2_name_equal(a:*u8,b:*u8,n:i64)->i64{var i:i64=0;while i<n{if a[i]!=b[i]{return 0};i=i+1};if a[n]!=(0 as u8){return 0};return 1}
486func sk2_copyname(b:*u8,start:i64,n:i64)->*u8{let p:*u8=sys_mmap(SK2_NAME+1);var i:i64=0;while i<n{p[i]=b[start+i];i=i+1};p[n]=0 as u8;return p}
487// Rows: name,cpu,ram,gpu,freeVRAM,nodeState,gpuState,nodeTs,gpuTs,totalVRAM.
488// meta: version,nodeRead,gpuRead,count. Negative GPU read/parse leaves CPU independently usable.
489func sk2_pool(nodes:*u8,gpus:*u8,now:i64,nwin:i64,gwin:i64,skew:i64,out:*i64,cap:i64,meta:*i64)->i64{
490 meta[0]=SK2_VERSION;meta[1]=0;meta[2]=0;meta[3]=0
491 if now<=0||nwin<=0||gwin<=0||skew<0{return SK2_POLICY}
492 if cap<1||cap>SK_MAXP{return SK2_CAPACITY}
493 var z:i64=0;while z<cap*SK2_FIELDS{out[z]=0;z=z+1}
494 let nb:*u8=sys_mmap(SK_MAGIC_65536);let gb:*u8=sys_mmap(SK_MAGIC_65536)
495 let nn:i64=sk2_read(nodes,nb);meta[1]=nn;if nn<0{return nn}
496 let f:*i64=sys_mmap(128) as *i64;let name:*i64=sys_mmap(16) as *i64
497 let nso:*i64=sys_mmap(16) as *i64;let nlo:*i64=sys_mmap(16) as *i64;let tso:*i64=sys_mmap(16) as *i64
498 var count:i64=0;var i:i64=0
499 while i<nn{var end:i64=i;while end<nn&&nb[end]!=(10 as u8){end=end+1}
500 if end>i{let line:*u8=((nb as i64)+i) as *u8;let len:i64=end-i
501 if sk2_row(line,len,"NODE " as *u8,11,f,name)!=1{return SK2_ROW}
502 if sb_fields(line,len,f)!=1{return SK2_ROW}
503 if f[2]<=0||f[2]>SK2_MAX/1000||f[3]<0||f[4]<0||f[5]<0||f[6]<=0||f[4]>100||f[5]>f[6]||f[8]<=0{return SK2_ROW}
504 var spare:i64=0;if f[3]<1000{spare=(1000-f[3])*f[2]};if spare>SK2_MAX-f[5]{return SK2_ROW}
505 var k:i64=0;while k<count{if sk2_name_equal(out[k*SK2_FIELDS] as *u8,((line as i64)+name[0]) as *u8,name[1])==1{return SK2_DUPLICATE};k=k+1}
506 if count>=cap{return SK2_CAPACITY};let r:i64=count*SK2_FIELDS
507 out[r]=sk2_copyname(line,name[0],name[1]) as i64;out[r+5]=sk2_fresh(f[8],now,nwin,skew);out[r+7]=f[8]
508 if out[r+5]==SK2_FRESH{out[r+1]=spare;out[r+2]=f[5]};count=count+1};i=end+1}
509 let gn:i64=sk2_read(gpus,gb);meta[2]=gn
510 var gstate:i64=SK2_UNKNOWN;if gn<0&&gn!=SK2_MISSING{gstate=SK2_REFUSED}
511 // Validate the entire GPU snapshot and uniqueness before crediting any GPU supply.
512 let gnames:*i64=sys_mmap(SK_MAXP*8) as *i64;let grows:*i64=sys_mmap(SK_MAXP*4*8) as *i64
513 let total:*i64=sys_mmap(16) as *i64;let free:*i64=sys_mmap(16) as *i64
514 var gc:i64=0;var invalid:i64=0;i=0
515 while i<gn{var end:i64=i;while end<gn&&gb[end]!=(10 as u8){end=end+1}
516 if end>i{let line:*u8=((gb as i64)+i) as *u8;let len:i64=end-i
517 if sk2_row(line,len,"GPU " as *u8,3,f,name)!=1{invalid=SK2_ROW;break}
518 if sg_validate(line,len,nso,nlo,total,free,tso)!=1{invalid=SK2_ROW;break}
519 if total[0]<=0||free[0]<0||free[0]>total[0]||tso[0]<=0{invalid=SK2_ROW;break}
520 var k:i64=0;while k<gc{if sk2_name_equal(gnames[k] as *u8,((line as i64)+name[0]) as *u8,name[1])==1{invalid=SK2_DUPLICATE};k=k+1}
521 if invalid!=0{break};if gc>=SK_MAXP{invalid=SK2_CAPACITY;break}
522 gnames[gc]=sk2_copyname(line,name[0],name[1]) as i64;grows[gc*4]=total[0];grows[gc*4+1]=free[0];grows[gc*4+2]=tso[0];grows[gc*4+3]=sk2_fresh(tso[0],now,gwin,skew);gc=gc+1};i=end+1}
523 if invalid!=0{meta[2]=invalid;gstate=SK2_REFUSED;gc=0}
524 i=0;while i<count{let r:i64=i*SK2_FIELDS;out[r+6]=gstate;var k:i64=0
525 while k<gc{if sg_eq(out[r] as *u8,gnames[k] as *u8)==1{out[r+6]=grows[k*4+3];out[r+8]=grows[k*4+2];out[r+9]=grows[k*4]
526 if out[r+5]==SK2_FRESH&&out[r+6]==SK2_FRESH{out[r+3]=1;out[r+4]=grows[k*4+1]}};k=k+1};i=i+1}
527 meta[3]=count;return count
528}
529func sk2_state(v:i64)->*u8{if v==SK2_FRESH{return "fresh" as *u8};if v==SK2_STALE{return "stale" as *u8};if v==SK2_REFUSED{return "refused" as *u8};return "unknown" as *u8}
530func sk2_jobs(path:*u8,cpu:*i64,ram:*i64,gpu:*i64,vram:*i64,cap:i64)->i64{
531 let b:*u8=sys_mmap(SK_MAGIC_65536);let n:i64=sk2_read(path,b);if n<0{return n}
532 let vals:*i64=sys_mmap(32) as *i64;let parsed:*i64=sys_mmap(16) as *i64;var i:i64=0;var count:i64=0
533 while i<n{var end:i64=i;while end<n&&b[end]!=(10 as u8){end=end+1}
534 if end>i&&b[i]!=(35 as u8){var p:i64=i;var k:i64=0
535 while k<4{if sk2_int(b,end,p,parsed)!=1{return SK2_ROW};vals[k]=parsed[0];p=parsed[1];k=k+1;if k<4{if p>=end||b[p]!=(32 as u8){return SK2_ROW};p=p+1}}
536 if p!=end||vals[0]<0||vals[1]<0||vals[2]<0||vals[2]>1||vals[3]<0||vals[0]>SK2_MAX-vals[1]{return SK2_ROW}
537 if count>=cap{return SK2_CAPACITY};cpu[count]=vals[0];ram[count]=vals[1];gpu[count]=vals[2];vram[count]=vals[3];count=count+1};i=end+1};return count
538}
539func sk2_live(nodes:*u8,gpus:*u8,jobs:*u8,now:i64,nwin:i64,gwin:i64,skew:i64)->i64{
540 let pool:*i64=sys_mmap(SK_MAXP*SK2_FIELDS*8) as *i64;let meta:*i64=sys_mmap(32) as *i64
541 let n:i64=sk2_pool(nodes,gpus,now,nwin,gwin,skew,pool,SK_MAXP,meta)
542 let t:*u8=sys_mmap(512);var o:i64=fa_cat(t,0,"SWARMPACK v=2 scope=planning-only execution_admission=unknown user_activity=unknown maintenance=unknown reserved_budgets=unknown node_read=" as *u8);o=fa_catn(t,o,meta[1]);o=fa_cat(t,o," gpu_read=" as *u8);o=fa_catn(t,o,meta[2]);o=fa_cat(t,o," pool_rc=" as *u8);o=fa_catn(t,o,n);o=fa_cat(t,o,"\n" as *u8);sys_write(1,t,o)
543 if n<1{return 3}
544 let pc:*i64=sys_mmap(SK_MAXP*8) as *i64;let pr:*i64=sys_mmap(SK_MAXP*8) as *i64;let pg:*i64=sys_mmap(SK_MAXP*8) as *i64;let pv:*i64=sys_mmap(SK_MAXP*8) as *i64
545 let map:*i64=sys_mmap(SK_MAXP*8) as *i64;var active:i64=0
546 var i:i64=0;while i<n{let r:i64=i*SK2_FIELDS
547 if pool[r+5]==SK2_FRESH{map[active]=i;pc[active]=pool[r+1];pr[active]=pool[r+2];pg[active]=pool[r+3];pv[active]=pool[r+4];active=active+1}
548 o=fa_cat(t,0,"POOL node=" as *u8);o=fa_cat(t,o,pool[r] as *u8);o=fa_cat(t,o," node_state=" as *u8);o=fa_cat(t,o,sk2_state(pool[r+5]));o=fa_cat(t,o," gpu_state=" as *u8);o=fa_cat(t,o,sk2_state(pool[r+6]));o=fa_cat(t,o," node_ts=" as *u8);o=fa_catn(t,o,pool[r+7]);o=fa_cat(t,o," gpu_ts=" as *u8);o=fa_catn(t,o,pool[r+8]);o=fa_cat(t,o," free_vram_mb=" as *u8);o=fa_catn(t,o,pool[r+4]);o=fa_cat(t,o,"\n" as *u8);sys_write(1,t,o);i=i+1}
549 let dc:*i64=sys_mmap(SK_MAXD*8) as *i64;let dr:*i64=sys_mmap(SK_MAXD*8) as *i64;let dg:*i64=sys_mmap(SK_MAXD*8) as *i64;let dv:*i64=sys_mmap(SK_MAXD*8) as *i64;let a:*i64=sys_mmap(SK_MAXD*8) as *i64
550 let m:i64=sk2_jobs(jobs,dc,dr,dg,dv,SK_MAXD);if m<1{return 3}
551 if active==0{return 3}
552 let placed:i64=sk_pack(pc,pr,pg,pv,active,dc,dr,dg,dv,m,a)
553 i=0;while i<m{o=fa_cat(t,0,"ASSIGN id=" as *u8);o=fa_catn(t,o,i);o=fa_cat(t,o," node=" as *u8);if a[i]>=0{o=fa_cat(t,o,pool[map[a[i]]*SK2_FIELDS] as *u8)}else{o=fa_cat(t,o,"queued" as *u8)};o=fa_cat(t,o,"\n" as *u8);sys_write(1,t,o);i=i+1}
554 if placed==m{return 0};return 3
555}
556
557func main(argc: i64, argv: *i64) -> i64 {
558 if argc >= 2 {
559 let verb: *u8 = argv[1] as *u8
560 if sg_eq(verb,"pack-v2" as *u8)==1{
561 if argc!=8{sk_puts("usage: pack-v2 <NODE.snap> <GPU.snap> <jobs.log> <node_window_s> <gpu_window_s> <future_skew_s>\n" as *u8);return 2}
562 if sb_path_ok(argv[2] as *u8)!=1||sb_path_ok(argv[3] as *u8)!=1||sb_path_ok(argv[4] as *u8)!=1{return 3}
563 let v:*i64=sys_mmap(16) as *i64;let policy:*i64=sys_mmap(24) as *i64;var k:i64=0
564 while k<3{let s:*u8=argv[5+k] as *u8;let n:i64=fa_len(s);if sk2_int(s,n,0,v)!=1||v[1]!=n||v[0]<0||v[0]>SK2_MAX/SK2_UNIT{return 2};policy[k]=v[0]*SK2_UNIT;k=k+1}
565 return sk2_live(argv[2] as *u8,argv[3] as *u8,argv[4] as *u8,sys_now_realtime_us(),policy[0],policy[1],policy[2])
566 }
567 var isp: i64 = 1
568 if verb[0] != (112 as u8) { isp = 0 } // 'p'
569 if isp == 1 {
570 if argc < 4 { sk_puts("usage: nx_swarm_pack pack <snap> <jobs> [gpu_roster_csv]\n" as *u8); return 2 }
571 if sb_path_ok(argv[2] as *u8) == 0 { sk_puts("SWARMPACK REFUSED (snap path law)\n" as *u8); return 3 }
572 var roster: *u8 = "" as *u8
573 if argc >= 5 { roster = argv[4] as *u8 }
574 return sk_live(argv[2] as *u8, argv[3] as *u8, roster)
575 }
576 }
577 return sk_gate()
578}