code wiki / (root) / nx_fieldfit_lib.nx

nx_fieldfit_lib.nx source

↩ module page · 519 lines · 22307 B

1// nx_fieldfit_lib.nx -- FIT A PARAMETRIC IMPLICIT FIELD TO A SCANNED ORACLE. The machinery nx_skullsdf's `tune` grew 2// (anatomy AN17, 2026-09-18/19), extracted so any anatomy field -- a skull, an arm, a foot, a muscle belly, a tissue 3// layer -- is fitted by ONE optimiser with ONE objective and ONE fit-file contract, and a defect fixed here is fixed for 4// every field at once. The consumer hands over three functions as VALUES (NishiLang func-pointer locals and fields, 5// indirect calls up to six arguments): 6// field(px, py, pz, a, b, P) -> signed distance at `fq` units per millimetre (negative inside) for parameter vector P, 7// with a and b the consumer's two policy knobs (the skull passes sex and robusticity) 8// region(x, y, z) -> 0 .. nreg-1, the named anatomical region a point belongs to 9// live(k) -> 1 for a station the field reads, 0 for a retired one (the descent skips it: two 10// evaluations spent on a dead station are a pass that cannot move anything) 11// 12// THE OBJECTIVE IS TWO-SIDED, AND IT HAS TO BE. A one-directional score -- how far is each ORACLE point from my surface -- 13// is trivially gamed by DELETING GEOMETRY: the skull's first tuning run shrank its orbits from 22 mm to 8 and its 14// maxilla from 30 mm to 13, improving the number 40 percent by filling in the eye sockets, because surface that does not 15// exist cannot be wrong. The REVERSE term charges every lattice point on OUR zero level its distance to the nearest 16// oracle sample, so a deleted feature is EXPENSIVE by construction. (The reverse term uses the nearest oracle VERTEX from 17// a spatial hash: an upper bound on the true point-to-surface distance -- it can overstate, never understate, the safe 18// direction for a penalty.) 19// THE OBJECTIVE IS REGION-BALANCED. A plain mean is dominated by whatever region has the most samples (the skull's vault 20// and base held 9,335 + 8,672 of ~31,000, so a 49 mm muzzle and 4 mm drilled orbits read as a 4 mm skull and the 21// surface objective fell 629 -> 531 while the chin moved +4 -> +19.6 mm). Each side is the mean of the PER-REGION means 22// (a region with no samples abstains), so the smallest region weighs what the largest does. No weight is typed: the 23// population decides. 24// THE DESCENT is coordinate descent: per live station try +step then -step, keep a move only if the MEASURED objective 25// falls; the step halves per pass, floor 1. No change is ever kept on the strength of looking better. 26// THE FIT FILE is newline-separated integers, loaded as a PREFIX: a file shorter than the vector applies to its first 27// entries and the rest keep their defaults, so growing a parametrisation never discards banked convergence; a file 28// shorter than `minlen` changes nothing (parsed into a temp and applied only when long enough, so a truncated write 29// cannot half-poison a field). Written whole by ff_save. 30// UNITS: objectives are reported in centi-millimetres; `lat` (the reverse lattice spacing), `ext` (the half-extent the 31// hash covers) and `dim` (cells per axis) are the consumer's, taken from the resource it fits. 32// LIB, no main. license_tier: ORIGINAL. No hw writes (Rule 26). 33import "nx_syscalls.nx" 34import "nx_atomic_rewrite.nx" 35 36const FF_I64: i64 = 8 37const FF_CENTI: i64 = 100 // objectives are centi-millimetres 38const FF_CTX_BYTES: i64 = 256 // FfCtx: 21 fields of 8 bytes, one page-rounded map 39const FF_LOAD_HDR: i64 = 16 // the two-word length record sys_read_file fills 40const FF_SAVE_DIGITS: i64 = 16 // bytes reserved per integer on save (sign + 19 digits fits a page-rounded map) 41const FF_SAVE_SLACK: i64 = 64 42const FF_MODE644: i64 = 420 43 44// THE THIRD TERM, OPTIONAL: `extra(P)` returns a further mean error in centi-millimetres the consumer derives from its 45// own stations against the ruler's ORACLE readings (a landmark term: where the field PLACES its features against 46// where the ruler FOUND them on the oracle). MEASURED NEED (skull, 2026-09-19): with the two surface terms alone the 47// descent closed the orbit sockets to 2 mm slits and deepened the aperture to a 35 mm tunnel, because a surface 48// objective cannot see an opening; the ruler read 4 of 15 quantities in band. With has_extra = 1 the objective is the 49// three-way mean of the three error means (all centi-mm, no weight typed); the consumer's REAL ruler still judges the 50// emitted mesh outside the loop, so the term is a surrogate with a stated error, never the verdict. 51struct FfCtx { field: func(i64,i64,i64,i64,i64,*i64) -> i64, region: func(i64,i64,i64) -> i64, live: func(i64) -> i64, RX: *i64, RY: *i64, RZ: *i64, RG: *i64, n: i64, head: *i64, next: *i64, ext: i64, dim: i64, lat: i64, a: i64, b: i64, fq: i64, nreg: i64, sum: *i64, cnt: *i64, np: i64, cap: i64, extra: func(*i64) -> i64, has_extra: i64 } 52 53// a context sized for `cap` oracle samples, `np` stations, `nreg` regions, a dim^3 hash over +/- ext mm, lattice lat mm 54func ff_ctx_new(np: i64, nreg: i64, cap: i64, ext: i64, dim: i64, lat: i64, fq: i64) -> *FfCtx { 55 let c: *FfCtx = (sys_mmap(FF_CTX_BYTES)) as *FfCtx 56 c.np = np; c.nreg = nreg; c.cap = cap; c.ext = ext; c.dim = dim; c.lat = lat; c.fq = fq 57 c.RX = sys_mmap(cap*FF_I64) as *i64 58 c.RY = sys_mmap(cap*FF_I64) as *i64 59 c.RZ = sys_mmap(cap*FF_I64) as *i64 60 c.RG = sys_mmap(cap*FF_I64) as *i64 61 c.next = sys_mmap(cap*FF_I64) as *i64 62 c.head = sys_mmap(dim*dim*dim*FF_I64) as *i64 63 c.sum = sys_mmap(nreg*FF_I64) as *i64 64 c.cnt = sys_mmap(nreg*FF_I64) as *i64 65 c.n = 0; c.a = 0; c.b = 0; c.has_extra = 0 66 return c 67} 68 69// ==== the spatial hash over the oracle samples ==== 70func ff_cell(c: *FfCtx, x: i64, y: i64, z: i64) -> i64 { 71 let d: i64 = c.dim 72 let e: i64 = c.ext 73 var i: i64 = (x + e) * d / (e*2) 74 var j: i64 = (y + e) * d / (e*2) 75 var k: i64 = (z + e) * d / (e*2) 76 if i < 0 { i = 0 } 77 if j < 0 { j = 0 } 78 if k < 0 { k = 0 } 79 if i >= d { i = d-1 } 80 if j >= d { j = d-1 } 81 if k >= d { k = d-1 } 82 return (i*d + j)*d + k 83} 84// bucket the oracle samples so the reverse term does not scan all of them per query 85func ff_bin(c: *FfCtx) -> i64 { 86 let d: i64 = c.dim 87 let head: *i64 = c.head 88 let next: *i64 = c.next 89 var q: i64 = 0 90 while q < d*d*d { head[q] = 0-1; q = q + 1 } 91 var i: i64 = 0 92 while i < c.n { 93 let h: i64 = ff_cell(c, c.RX[i], c.RY[i], c.RZ[i]) 94 next[i] = head[h] 95 head[h] = i 96 i = i + 1 97 } 98 return 0 99} 100// nearest oracle sample to (x,y,z) in whole millimetres, searching the home cell then one ring out; ext when none 101func ff_near(c: *FfCtx, x: i64, y: i64, z: i64) -> i64 { 102 let d: i64 = c.dim 103 let e: i64 = c.ext 104 let RX: *i64 = c.RX 105 let RY: *i64 = c.RY 106 let RZ: *i64 = c.RZ 107 let head: *i64 = c.head 108 let next: *i64 = c.next 109 var ci: i64 = (x + e) * d / (e*2) 110 var cj: i64 = (y + e) * d / (e*2) 111 var ck: i64 = (z + e) * d / (e*2) 112 var best: i64 = 0-1 113 var r: i64 = 0 114 while r <= 1 { 115 var di: i64 = 0 - r 116 while di <= r { 117 var dj: i64 = 0 - r 118 while dj <= r { 119 var dk: i64 = 0 - r 120 while dk <= r { 121 let ii: i64 = ci+di 122 let jj: i64 = cj+dj 123 let kk: i64 = ck+dk 124 if ii >= 0 { if ii < d { if jj >= 0 { if jj < d { if kk >= 0 { if kk < d { 125 var p: i64 = head[(ii*d + jj)*d + kk] 126 while p >= 0 { 127 let ddx: i64 = x-RX[p] 128 let ddy: i64 = y-RY[p] 129 let ddz: i64 = z-RZ[p] 130 let d2: i64 = ddx*ddx + ddy*ddy + ddz*ddz 131 if best < 0 { best = d2 } else { if d2 < best { best = d2 } } 132 p = next[p] 133 } 134 } } } } } } 135 dk = dk + 1 136 } 137 dj = dj + 1 138 } 139 di = di + 1 140 } 141 if best >= 0 { r = 2 } else { r = r + 1 } 142 } 143 if best < 0 { return e } 144 return ff_isqrt(best) 145} 146func ff_isqrt(v: i64) -> i64 { if v<=0 { return 0 } var x: i64=v; var y: i64=(x+1)/2; while y<x { x=y; y=(x+v/x)/2 } return x } 147 148// each oracle sample's region, classified ONCE per fit (the consumer's boxes may follow its loaded vector; they hold 149// for the run) 150func ff_regions(c: *FfCtx) -> i64 { 151 var i: i64 = 0 152 while i < c.n { c.RG[i] = c.region(c.RX[i], c.RY[i], c.RZ[i]); i = i + 1 } 153 return 0 154} 155 156// ==== the region tables: the mean of the per-region means ==== 157func ff_rtab_reset(c: *FfCtx) -> i64 { 158 var r: i64 = 0 159 while r < c.nreg { c.sum[r] = 0; c.cnt[r] = 0; r = r + 1 } 160 return 0 161} 162// centi-mm from sums carried at `fq` units per mm; no region at all is the worst answer (ext mm) 163func ff_rtab_mean(c: *FfCtx, fq: i64) -> i64 { 164 var acc: i64 = 0 165 var nr: i64 = 0 166 var r: i64 = 0 167 while r < c.nreg { 168 if c.cnt[r] > 0 { acc = acc + c.sum[r]*FF_CENTI/(c.cnt[r]*fq); nr = nr + 1 } 169 r = r + 1 170 } 171 if nr == 0 { return c.ext*FF_CENTI } 172 return acc/nr 173} 174// forward: each oracle sample's |field|, balanced over regions 175func ff_score_fwd(c: *FfCtx, P: *i64) -> i64 { 176 ff_rtab_reset(c) 177 var i: i64 = 0 178 while i < c.n { 179 var d: i64 = c.field(c.RX[i], c.RY[i], c.RZ[i], c.a, c.b, P) 180 if d < 0 { d = 0 - d } 181 let r: i64 = c.RG[i] 182 c.sum[r] = c.sum[r] + d 183 c.cnt[r] = c.cnt[r] + 1 184 i = i + 1 185 } 186 if c.n == 0 { return 0 } 187 return ff_rtab_mean(c, c.fq) 188} 189// reverse: every lattice point within half a step of our zero level, charged its distance to the nearest oracle sample 190func ff_score_rev(c: *FfCtx, P: *i64) -> i64 { 191 ff_rtab_reset(c) 192 let e: i64 = c.ext 193 let step: i64 = c.lat 194 let bq: i64 = step*c.fq 195 var cnt: i64 = 0 196 var x: i64 = 0 - e 197 while x <= e { 198 var y: i64 = 0 - e 199 while y <= e { 200 var z: i64 = 0 - e 201 while z <= e { 202 let d: i64 = c.field(x, y, z, c.a, c.b, P) 203 if d > 0 - bq { if d < bq { 204 let r: i64 = c.region(x, y, z) 205 c.sum[r] = c.sum[r] + ff_near(c, x, y, z) 206 c.cnt[r] = c.cnt[r] + 1 207 cnt = cnt + 1 208 } } 209 z = z + step 210 } 211 y = y + step 212 } 213 x = x + step 214 } 215 if cnt == 0 { return e*FF_CENTI } 216 return ff_rtab_mean(c, 1) 217} 218// the objective: the mean of both directions, so neither can be gamed alone; with a consumer's extra term, the mean 219// of the three (every term a mean error in centi-mm, so no weight is typed) 220func ff_score2(c: *FfCtx, P: *i64) -> i64 { 221 let f: i64 = ff_score_fwd(c, P) 222 let r: i64 = ff_score_rev(c, P) 223 if c.has_extra == 1 { 224 let e: i64 = c.extra(P) 225 return (f + r + e)/3 226 } 227 return (f + r)/2 228} 229func ff_live_count(c: *FfCtx) -> i64 { 230 var lv: i64 = 0 231 var k: i64 = 0 232 while k < c.np { lv = lv + c.live(k); k = k + 1 } 233 return lv 234} 235func ff_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 236func ff_pn(v: i64) -> i64 { 237 let b: *u8 = sys_mmap(32) 238 let o: i64 = ff_wint(b, 0, v) 239 sys_write(1, b, o) 240 return 0 241} 242// COORDINATE DESCENT from P: returns the best objective; P holds the accepted vector. Convergence is PRINTED per pass 243// when verbose ({"pass":k,"step":s,"best_centi":b}), never assumed 244func ff_descend(c: *FfCtx, P: *i64, passes: i64, step0: i64, verbose: i64) -> i64 { 245 var best: i64 = ff_score2(c, P) 246 var step: i64 = step0 247 if step < 1 { step = 8 } 248 var pass: i64 = 0 249 while pass < passes { 250 var k: i64 = 0 251 while k < c.np { 252 if c.live(k) == 1 { 253 let orig: i64 = P[k] 254 P[k] = orig + step 255 let up: i64 = ff_score2(c, P) 256 P[k] = orig - step 257 let dn: i64 = ff_score2(c, P) 258 P[k] = orig 259 if up < best { if up <= dn { best = up; P[k] = orig + step } } 260 if dn < best { if dn < up { best = dn; P[k] = orig - step } } 261 } 262 k = k + 1 263 } 264 if verbose == 1 { 265 ff_puts("{\x22pass\x22:" as *u8); ff_pn(pass) 266 ff_puts(",\x22step\x22:" as *u8); ff_pn(step) 267 ff_puts(",\x22best_centi\x22:" as *u8); ff_pn(best) 268 ff_puts("}\n" as *u8) 269 } 270 step = step/2 271 if step < 1 { step = 1 } 272 pass = pass + 1 273 } 274 return best 275} 276 277// ==== the fit file ==== 278// integer -> ascii into a buffer at offset o; returns the new offset (iterative, no allocation) 279func ff_wint(b: *u8, o: i64, v: i64) -> i64 { 280 var x: i64 = v 281 var oo: i64 = o 282 if x < 0 { b[oo] = 45 as u8; oo = oo + 1; x = 0 - x } 283 var tmp: i64 = x 284 var nd: i64 = 1 285 while tmp >= 10 { tmp = tmp/10; nd = nd + 1 } 286 var k: i64 = nd 287 while k > 0 { 288 var div: i64 = 1 289 var q: i64 = 1 290 while q < k { div = div*10; q = q + 1 } 291 b[oo] = (48 + (x/div) % 10) as u8 292 oo = oo + 1 293 k = k - 1 294 } 295 return oo 296} 297// load a PREFIX of P from a newline-separated integer file: returns the count applied (0 when absent or shorter than minlen) 298func ff_load_prefix(path: *u8, P: *i64, np: i64, minlen: i64) -> i64 { 299 let ln: *i64 = sys_mmap(FF_LOAD_HDR) as *i64 300 let buf: *u8 = sys_read_file(path, ln) 301 if (buf as i64) == 0 { return 0 } 302 let n: i64 = ln[0] 303 let T: *i64 = sys_mmap(np*FF_I64) as *i64 304 var i: i64 = 0 305 var got: i64 = 0 306 while i < n { 307 var c: i64 = buf[i] as i64 308 var neg: i64 = 0 309 if c == 45 { 310 neg = 1 311 i = i + 1 312 if i < n { c = buf[i] as i64 } else { c = 0 } 313 } 314 var isd: i64 = 0 315 if c >= 48 { if c <= 57 { isd = 1 } } 316 if isd == 1 { 317 var v: i64 = 0 318 var run: i64 = 1 319 while run == 1 { 320 v = v*10 + (c-48) 321 i = i + 1 322 if i < n { c = buf[i] as i64 } else { c = 0 } 323 var still: i64 = 0 324 if c >= 48 { if c <= 57 { still = 1 } } 325 if still == 0 { run = 0 } 326 } 327 if neg == 1 { v = 0-v } 328 if got < np { T[got] = v; got = got + 1 } 329 } else { 330 i = i + 1 331 } 332 } 333 if got >= minlen { 334 var lim: i64 = got 335 if lim > np { lim = np } 336 var q: i64 = 0 337 while q < lim { P[q] = T[q]; q = q + 1 } 338 return lim 339 } 340 return 0 341} 342// write the whole vector, one integer per line 343func ff_save(path: *u8, P: *i64, np: i64) -> i64 { 344 let fb: *u8 = sys_mmap(np*FF_SAVE_DIGITS + FF_SAVE_SLACK) 345 var fo: i64 = 0 346 var w: i64 = 0 347 while w < np { 348 fo = ff_wint(fb, fo, P[w]) 349 fb[fo] = 10 as u8 350 fo = fo + 1 351 w = w + 1 352 } 353 let fd: i64 = sys_openat_wr(path, FF_MODE644) 354 if fd < 0 { return 0 - 1 } 355 sys_write(fd, fb, fo) 356 sys_close(fd) 357 return fo 358} 359 360 361// Versioned checked path. Existing legacy entry points remain explicitly unverified. 362const FF_FIT_LEGACY_UNVERIFIED: i64 = 0 - 2 363const FF_FIT_CONTRACT_MISMATCH: i64 = 0 - 3 364const FF_FIT_MALFORMED: i64 = 0 - 4 365const FF_FIT_INVALID: i64 = 0 - 5 366const FF_FIT_IO: i64 = 0 - 6 367const FF_FIT_MAGIC_BYTES: i64 = 7 368const FF_FIT_I64_DIGITS: i64 = 21 369const FF_FIT_ATOMIC_PATH_CAP: i64 = 512 // nx_atomic_rewrite ar_syncdir buffer contract 370const FF_FIT_I64_POS_LIMIT: i64 = 9223372036854775807 371struct FfFitContract { header: *u8, header_bytes: i64, np: i64, valid: func(*i64,i64) -> i64 } 372// header is the caller's exact versioned schema/frame/producer/reference/objective identity. 373// It starts NXFFIT2 and ends newline; all identities are part of byte equality, never parsed as numbers. 374func ff_contract_ok(C: *FfFitContract) -> i64 { 375 if C.np <= 0 { return 0 } 376 if C.header_bytes < 0 { return 0 } 377 if C.header_bytes >= FF_FIT_I64_POS_LIMIT { return 0 } 378 if C.np > (FF_FIT_I64_POS_LIMIT - 1 - C.header_bytes) / FF_FIT_I64_DIGITS { return 0 } 379 if C.header_bytes <= FF_FIT_MAGIC_BYTES { return 0 } 380 let magic: *u8 = "NXFFIT2" as *u8 381 var i: i64 = 0 382 while i < FF_FIT_MAGIC_BYTES { if C.header[i] != magic[i] { return 0 } i = i + 1 } 383 if C.header[C.header_bytes - 1] != 10 { return 0 } 384 return 1 385} 386// INTERNAL: called only by ff_parse_verified after contract/header/count bounds. 387// External bytes must enter through ff_load_verified; this is not a standalone boundary API. 388func ff_values_verified(b: *u8, n: i64, T: *i64, C: *FfFitContract) -> i64 { 389 var i: i64 = C.header_bytes 390 var k: i64 = 0 391 while k < C.np { 392 if i >= n { return FF_FIT_MALFORMED } 393 var neg: i64 = 0 394 if b[i] == 45 { neg = 1; i = i + 1 } 395 var digits: i64 = 0 396 var v: i64 = 0 397 var run: i64 = 1 398 while run == 1 { 399 if i >= n { run = 0 } else { 400 let c: i64 = b[i] as i64 401 if c < 48 { run = 0 } else { if c > 57 { run = 0 } else { 402 let d: i64 = c - 48 403 if v > (FF_FIT_I64_POS_LIMIT - d) / 10 { return FF_FIT_MALFORMED } 404 v = v * 10 + d; digits = digits + 1; i = i + 1 405 } } 406 } 407 } 408 if digits == 0 { return FF_FIT_MALFORMED } 409 if i >= n { return FF_FIT_MALFORMED } 410 if b[i] != 10 { return FF_FIT_MALFORMED } 411 i = i + 1 412 if neg == 1 { v = 0 - v } 413 T[k] = v; k = k + 1 414 } 415 if i != n { return FF_FIT_MALFORMED } 416 if C.valid(T, C.np) != 1 { return FF_FIT_INVALID } 417 return C.np 418} 419// INTERNAL: ff_load_verified has validated the contract and bounded this owned buffer. 420// Generic callers must use ff_load_verified rather than bypass its external-input checks. 421func ff_parse_verified(b: *u8, n: i64, P: *i64, C: *FfFitContract) -> i64 { 422 if n < FF_FIT_MAGIC_BYTES { return FF_FIT_LEGACY_UNVERIFIED } 423 var i: i64 = 0 424 while i < FF_FIT_MAGIC_BYTES { if b[i] != C.header[i] { return FF_FIT_LEGACY_UNVERIFIED } i = i + 1 } 425 if n < C.header_bytes { return FF_FIT_CONTRACT_MISMATCH } 426 i = 0 427 while i < C.header_bytes { if b[i] != C.header[i] { return FF_FIT_CONTRACT_MISMATCH } i = i + 1 } 428 if C.np > (n - C.header_bytes) / 2 { return FF_FIT_MALFORMED } 429 let T: *i64 = sys_mmap_shared(C.np * FF_I64) as *i64 430 if (T as i64) <= 0 { return FF_FIT_IO } 431 let rc: i64 = ff_values_verified(b, n, T, C) 432 if rc == C.np { var k: i64 = 0; while k < C.np { P[k] = T[k]; k = k + 1 } } 433 sys_munmap_direct(T as *u8, C.np * FF_I64) 434 return rc 435} 436func ff_load_verified(path: *u8, P: *i64, C: *FfFitContract) -> i64 { 437 if ff_contract_ok(C) != 1 { return FF_FIT_CONTRACT_MISMATCH } 438 let fd: i64 = sys_openat_rd(path) 439 if fd < 0 { return FF_FIT_IO } 440 let n: i64 = sys_lseek(fd, 0, 2) 441 let limit: i64 = C.header_bytes + C.np * FF_FIT_I64_DIGITS 442 if n < 0 { sys_close(fd); return FF_FIT_IO } 443 if n > limit { sys_close(fd); return FF_FIT_MALFORMED } 444 if sys_lseek(fd, 0, 0) != 0 { sys_close(fd); return FF_FIT_IO } 445 let b: *u8 = sys_mmap_shared(n + 1) 446 if (b as i64) <= 0 { sys_close(fd); return FF_FIT_IO } 447 var total: i64 = 0 448 while total < n { 449 let got: i64 = sys_read(fd, ((b as i64) + total) as *u8, n - total) 450 if got <= 0 { sys_close(fd); sys_munmap_direct(b, n + 1); return FF_FIT_IO } 451 total = total + got 452 } 453 let extra: i64 = sys_read(fd, ((b as i64) + n) as *u8, 1) 454 sys_close(fd) 455 if extra != 0 { sys_munmap_direct(b, n + 1); return FF_FIT_MALFORMED } 456 let rc: i64 = ff_parse_verified(b, n, P, C) 457 sys_munmap_direct(b, n + 1) 458 return rc 459} 460func ff_save_verified(path: *u8, P: *i64, C: *FfFitContract) -> i64 { 461 if ff_contract_ok(C) != 1 { return FF_FIT_CONTRACT_MISMATCH } 462 if C.valid(P, C.np) != 1 { return FF_FIT_INVALID } 463 var plen: i64 = 0 464 while path[plen] != 0 { if plen >= FF_FIT_ATOMIC_PATH_CAP - 1 { return FF_FIT_IO } plen = plen + 1 } 465 let b: *u8 = sys_mmap_shared(C.header_bytes + C.np * FF_FIT_I64_DIGITS) 466 if (b as i64) <= 0 { return FF_FIT_IO } 467 var o: i64 = 0 468 while o < C.header_bytes { b[o] = C.header[o]; o = o + 1 } 469 var k: i64 = 0 470 while k < C.np { 471 if P[k] < (0 - FF_FIT_I64_POS_LIMIT) { sys_munmap_direct(b, C.header_bytes + C.np * FF_FIT_I64_DIGITS); return FF_FIT_MALFORMED } 472 o = ff_wint(b, o, P[k]); b[o] = 10 as u8; o = o + 1; k = k + 1 473 } 474 let rc: i64 = atomic_rewrite(path, b, o) 475 sys_munmap_direct(b, C.header_bytes + C.np * FF_FIT_I64_DIGITS) 476 if rc != 0 { return FF_FIT_IO } 477 return o 478} 479 480func ff_descend_checked(c: *FfCtx, P: *i64, passes: i64, step0: i64, verbose: i64, valid: func(*i64,i64) -> i64) -> i64 { 481 if valid(P, c.np) != 1 { return FF_FIT_INVALID } 482 if step0 <= 0 { return FF_FIT_INVALID } 483 if passes < 0 { return FF_FIT_INVALID } 484 var best: i64 = ff_score2(c, P) 485 var step: i64 = step0 486 var pass: i64 = 0 487 while pass < passes { 488 var k: i64 = 0 489 while k < c.np { 490 if c.live(k) == 1 { 491 let orig: i64 = P[k] 492 var up: i64 = best 493 if orig <= FF_FIT_I64_POS_LIMIT - step { 494 P[k] = orig + step 495 if valid(P, c.np) == 1 { up = ff_score2(c, P) } 496 } 497 var dn: i64 = best 498 if orig >= (0 - FF_FIT_I64_POS_LIMIT) + step { 499 P[k] = orig - step 500 if valid(P, c.np) == 1 { dn = ff_score2(c, P) } 501 } 502 P[k] = orig 503 if up < best { if up <= dn { best = up; P[k] = orig + step } } 504 if dn < best { if dn < up { best = dn; P[k] = orig - step } } 505 } 506 k = k + 1 507 } 508 if verbose == 1 { 509 ff_puts("{\x22pass\x22:" as *u8); ff_pn(pass) 510 ff_puts(",\x22step\x22:" as *u8); ff_pn(step) 511 ff_puts(",\x22best_centi\x22:" as *u8); ff_pn(best) 512 ff_puts("}\n" as *u8) 513 } 514 step = step/2 515 if step < 1 { step = 1 } 516 pass = pass + 1 517 } 518 return best 519}