code wiki / (root) / nx_swarm_pack.nx

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}