nx_costest_lib.nx source
↩ module page · 672 lines · 30849 B
1// nx_costest_lib.nx -- THE ONE COST ESTIMATOR (2026-09-16): three-point estimates (P10, P50, P90) in the boards'
2// own unit, their aggregation over components, the CALIBRATION of that unit against RECORDED ACTUALS, and the
3// compute-cost rules that turn a model size into hours at a measured rate.
4//
5// WHY. Operator 2026-09-16: "if we need 3rd party today then id like to know via the /compare capabilities what the
6// lift would be to replace a 3rd party we are using thats open source etc with our own in cost", and "if the
7// capability to estimate cost gets us to sota for our nishi analyst and other analysis systems like flipping cars
8// or investing then im fine investing". The estate already prices a car flip by its P10 downside (nx_carflip_lib
9// cf_score, nx_flip_score) and every board declares a cost per rung in u ("1 u = one measured session-leg", the
10// plan's own unit row) -- but nothing CALIBRATED u against what the boards themselves recorded, and nothing
11// aggregated a set of estimates honestly. Ranker rung PR7 (rk_cost_recal, "actuals write back") named this gap
12// on 2026-08-20 and it stayed _ABSENT_. This lib is that primitive, shared by the foreign-asset ledger
13// (nx_assets_lib), the ranker's cost model, the car-flip and investing lanes and the analyst.
14//
15// THE UNIT. Estimates are held as DECI-U (1.5 u is the integer 15), so the plan's "1.5" and "8.5" compare as
16// integers; hours are held as CENTI-HOURS (12.34 h is 1234). A calibration rate is centi-hours PER U.
17//
18// AGGREGATION (ces_agg3). Components estimated independently combine as: P50 = sum of medians; the lower and
19// upper half-widths (P50-P10, P90-P50) combine by root-sum-square, which is the three-point (PERT-class) rule
20// for independent uncertainties. The straight sums of P10 and P90 are returned BESIDE the RSS figures as the
21// fully-correlated bound, because a reader who sees only the RSS band will read it as the worst case and it is
22// not: when every component slips together, the correlated sum is the honest ceiling.
23//
24// CALIBRATION (ces_census_plan, ces_cal_*). The boards journal `log|<epoch>|<rung>|<kind>|<text>` rows and every
25// rung declares its cost in u. For a rung with at least one `land` row, the ACTUAL is the wall-clock from its
26// FIRST journal row of any kind to its LAST land row -- a ceiling on effort, since it includes waiting -- and the
27// ratio actual-hours per declared-u is one calibration sample. The quantiles of that sample (P10, P50, P90) are
28// the calibration; a rung whose land row is its first row (zero elapsed) or whose cost is absent is EXCLUDED
29// BY NAME and counted, never silently dropped, and the partition WITHLAND = CALIBRATED + EXCL_ZERO + EXCL_NOCOST
30// is printed so a reader can check it sums. The ledger line (ces_cal_line) is written and parsed by ONE grammar in
31// this file, so the writer (nx_costcal) and every reader (the compare emitter) cannot drift apart.
32//
33// QUANTILE RANK. index = permil * (n - 1) / 1000 (nearest rank, the same convention nx_bench_stats uses for its
34// p95). ces_cal_min_n derives the smallest n at which P10, P50 and P90 index THREE DISTINCT RANKS -- below it a
35// "P10" is the same sample as the median and the band is decoration. That bound is computed, not typed.
36//
37// COMPUTE RULES. Training costs about 6 * params * tokens FLOPs (forward and backward) and inference about
38// 2 * params * tokens (the standard 6ND / 2ND rules of the scaling-law literature); ces_seconds divides by a
39// MEASURED rate the caller passes in. The rate is data: the llm board measures the CPU engine at 819 ms per
40// token for a 7B model, and a GPU rate is a bar until the estate measures one.
41//
42// ces_isqrt duplicates gv_isqrt's Newton arithmetic on purpose: a lib the compare generators import cannot
43// import the gate base class.
44// license_tier: ORIGINAL No hw writes (Rule 26).
45import "nx_syscalls.nx"
46
47const CES_I64: i64 = 8
48const CES_NONE: i64 = 0 - 1 // malformed or unavailable
49const CES_ABSENT: i64 = 0 - 2 // the field is "-": declared absent, not malformed
50const CES_DECI: i64 = 10 // u held as deci-u
51const CES_CENTI: i64 = 100 // hours held as centi-hours
52const CES_PERMIL: i64 = 1000
53const CES_P10: i64 = 100
54const CES_P50: i64 = 500
55const CES_P90: i64 = 900
56const CES_SEC_PER_HOUR: i64 = 3600
57const CES_TRAIN_FLOPS_PER_PT: i64 = 6 // forward + backward per parameter per token (the 6ND rule)
58const CES_INFER_FLOPS_PER_PT: i64 = 2 // forward only
59const CES_CH_PIPE: i64 = 124
60const CES_CH_NL: i64 = 10
61const CES_CH_DOT: i64 = 46
62const CES_CH_DASH: i64 = 45
63const CES_CH_COLON: i64 = 58
64const CES_CH_0: i64 = 48
65const CES_CH_9: i64 = 57
66const CES_CH_HASH: i64 = 35
67const CES_NUM_CAP: i64 = 24
68// aggregate slots (ces_agg3 out)
69const CES_A_P10: i64 = 0
70const CES_A_P50: i64 = 1
71const CES_A_P90: i64 = 2
72const CES_A_SUM10: i64 = 3
73const CES_A_SUM50: i64 = 4
74const CES_A_SUM90: i64 = 5
75const CES_A_N: i64 = 6
76const CES_A_SLOTS: i64 = 8
77// calibration stats slots
78const CES_S_ASOF: i64 = 0
79const CES_S_BOARDS: i64 = 1
80const CES_S_RUNGS: i64 = 2
81const CES_S_LOGROWS: i64 = 3
82const CES_S_UNMATCHED: i64 = 4
83const CES_S_WITHLAND: i64 = 5
84const CES_S_CALIBRATED: i64 = 6
85const CES_S_EXCL_ZERO: i64 = 7
86const CES_S_EXCL_NOCOST: i64 = 8
87const CES_S_P10: i64 = 9
88const CES_S_P50: i64 = 10
89const CES_S_P90: i64 = 11
90const CES_S_MINN: i64 = 12
91const CES_S_OVERFLOW: i64 = 13 // samples or rows that did not fit their reserve: announced, never silent
92const CES_S_LANDEVENTS: i64 = 14 // land event rows written (EC56): every land on a declared rung, not only the calibrated ones
93const CES_S_RETRACTS: i64 = 15 // retract event rows written (EC56): the rework record
94const CES_S_OPEN: i64 = 16 // rungs with journal rows and NO land row: started, not landed (EC57 WIP)
95const CES_S_SLOTS: i64 = 24
96const CES_CAL_TAG: *u8 = "cal"
97const CES_CAL_NF: i64 = 14
98// plan grammar
99const CES_RUNG_TAG: *u8 = "rung"
100const CES_LOG_TAG: *u8 = "log"
101const CES_LAND: *u8 = "land"
102const CES_RETRACT: *u8 = "retract"
103// the ledger's EVENT rows (EC56, 2026-09-17): land|domain|rung|epoch|cost_deciu and retract|domain|rung|epoch, one per
104// journal land or retract row on a declared rung. The tag IS the journal kind, so one literal serves both sides.
105const CES_EV_F_DOM: i64 = 1
106const CES_EV_F_RUNG: i64 = 2
107const CES_EV_F_EPOCH: i64 = 3
108const CES_EV_F_COST: i64 = 4
109const CES_EV_LAND_NF: i64 = 5
110const CES_EV_RETRACT_NF: i64 = 4
111const CES_MIN_EVENT_ROW: i64 = 13 // "land|a|b|1|0" plus its newline: the shortest well-formed event row
112const CES_W_LAND_EVENTS: i64 = 0 // ces_events_window accumulator slots
113const CES_W_LANDED_RUNGS: i64 = 1
114const CES_W_RETRACTS: i64 = 2
115const CES_W_LANDED_DECIU: i64 = 3
116const CES_W_EVENTS_TOTAL: i64 = 4
117const CES_W_RELANDED: i64 = 5
118const CES_W_SLOTS: i64 = 8
119const CES_OPEN_TAG: *u8 = "open" // ledger WIP row (EC57): open|domain|rung|first_epoch|last_epoch|cost_deciu
120const CES_OPEN_NF: i64 = 6
121const CES_OPEN_F_FIRST: i64 = 3
122const CES_OPEN_F_LAST: i64 = 4
123const CES_WIP_ACTIVE_S: i64 = 604800 // seven days, the shift gauge's own window: touched inside it is in flight, outside it is stale
124const CES_WIP_TOP: i64 = 3 // the most recently touched open rungs a WIP line names
125const CES_O_OPEN: i64 = 0 // ces_open_summary accumulator slots
126const CES_O_ACTIVE: i64 = 1
127const CES_O_STALE: i64 = 2
128const CES_O_OLDEST: i64 = 3
129const CES_O_SLOTS: i64 = 8
130const CES_RUNG_F_ID: i64 = 1
131const CES_RUNG_F_COST: i64 = 6
132const CES_RUNG_NF: i64 = 8
133const CES_LOG_F_EPOCH: i64 = 1
134const CES_LOG_F_RUNG: i64 = 2
135const CES_LOG_F_KIND: i64 = 3
136const CES_LOG_NF: i64 = 5
137const CES_MIN_RUNG_ROW: i64 = 18 // "rung|a|b|c|d|e|1|-" plus its newline: the shortest well-formed rung row
138const CES_ROW_RESERVE: i64 = 256 // one ledger row: domain, rung and six numbers
139
140func ces_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
141func ces_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var oo: i64 = o; while s[i] != (0 as u8) { d[oo] = s[i]; oo = oo + 1; i = i + 1 } d[oo] = 0 as u8; return oo }
142
143// floor(sqrt(v)); 0 for v <= 0
144func ces_isqrt(v: i64) -> i64 {
145 if v <= 0 { return 0 }
146 if v < 4 { return 1 }
147 var x: i64 = v
148 var y: i64 = (x + 1) / 2
149 while y < x { x = y; y = (x + v / x) / 2 }
150 return x
151}
152
153// n independent components (p10[i] <= p50[i] <= p90[i]) -> out[CES_A_*]; returns n
154func ces_agg3(p10: *i64, p50: *i64, p90: *i64, n: i64, out: *i64) -> i64 {
155 var s10: i64 = 0
156 var s50: i64 = 0
157 var s90: i64 = 0
158 var lo2: i64 = 0
159 var hi2: i64 = 0
160 var i: i64 = 0
161 while i < n {
162 s10 = s10 + p10[i]; s50 = s50 + p50[i]; s90 = s90 + p90[i]
163 let dl: i64 = p50[i] - p10[i]
164 let dh: i64 = p90[i] - p50[i]
165 lo2 = lo2 + dl * dl
166 hi2 = hi2 + dh * dh
167 i = i + 1
168 }
169 out[CES_A_P50] = s50
170 out[CES_A_P10] = s50 - ces_isqrt(lo2)
171 out[CES_A_P90] = s50 + ces_isqrt(hi2)
172 out[CES_A_SUM10] = s10
173 out[CES_A_SUM50] = s50
174 out[CES_A_SUM90] = s90
175 out[CES_A_N] = n
176 return n
177}
178
179// line end: the first NL or NUL at or after p, or n
180func ces_line_end(buf: *u8, n: i64, p: i64) -> i64 {
181 var e: i64 = p
182 var go: i64 = 1
183 while go == 1 {
184 if e >= n { go = 0 } else {
185 if buf[e] == (CES_CH_NL as u8) { go = 0 } else { if buf[e] == (0 as u8) { go = 0 } else { e = e + 1 } }
186 }
187 }
188 return e
189}
190
191// field k of the pipe row [p,e): length, offset in off[0]; CES_NONE when the row has no field k
192func ces_field(buf: *u8, p: i64, e: i64, k: i64, off: *i64) -> i64 {
193 var i: i64 = p
194 var f: i64 = 0
195 var s: i64 = p
196 while i < e {
197 if buf[i] == (CES_CH_PIPE as u8) {
198 if f == k { off[0] = s; return i - s }
199 f = f + 1
200 s = i + 1
201 }
202 i = i + 1
203 }
204 if f == k { off[0] = s; return e - s }
205 return CES_NONE
206}
207
208func ces_nfields(buf: *u8, p: i64, e: i64) -> i64 {
209 if e <= p { return 0 }
210 var c: i64 = 1
211 var i: i64 = p
212 while i < e { if buf[i] == (CES_CH_PIPE as u8) { c = c + 1 } i = i + 1 }
213 return c
214}
215
216// the span [off, off+len) equals the NUL-terminated literal
217func ces_span_is(buf: *u8, off: i64, len: i64, lit: *u8) -> i64 {
218 if len < 0 { return 0 }
219 if ces_slen(lit) != len { return 0 }
220 var i: i64 = 0
221 while i < len { if buf[off + i] != lit[i] { return 0 } i = i + 1 }
222 return 1
223}
224
225func ces_span_eq(buf: *u8, aoff: i64, alen: i64, boff: i64, blen: i64) -> i64 {
226 if alen != blen { return 0 }
227 if alen < 0 { return 0 }
228 var i: i64 = 0
229 while i < alen { if buf[aoff + i] != buf[boff + i] { return 0 } i = i + 1 }
230 return 1
231}
232
233// digits only, len > 0 -> value; else CES_NONE
234func ces_parse_int(buf: *u8, off: i64, len: i64) -> i64 {
235 if len <= 0 { return CES_NONE }
236 var v: i64 = 0
237 var i: i64 = 0
238 while i < len {
239 let c: i64 = buf[off + i] as i64
240 if c < CES_CH_0 { return CES_NONE }
241 if c > CES_CH_9 { return CES_NONE }
242 v = v * 10 + (c - CES_CH_0)
243 i = i + 1
244 }
245 return v
246}
247
248// "12" -> 120, "1.5" -> 15, "0.5" -> 5, "-" -> CES_ABSENT; more than one fractional digit or any other byte -> CES_NONE
249func ces_parse_deciu(buf: *u8, off: i64, len: i64) -> i64 {
250 if len <= 0 { return CES_NONE }
251 if len == 1 { if buf[off] == (CES_CH_DASH as u8) { return CES_ABSENT } }
252 var whole: i64 = 0
253 var frac: i64 = 0
254 var seen_dot: i64 = 0
255 var frac_digits: i64 = 0
256 var digits: i64 = 0
257 var i: i64 = 0
258 while i < len {
259 let c: i64 = buf[off + i] as i64
260 if c == CES_CH_DOT {
261 if seen_dot == 1 { return CES_NONE }
262 seen_dot = 1
263 } else {
264 if c < CES_CH_0 { return CES_NONE }
265 if c > CES_CH_9 { return CES_NONE }
266 digits = digits + 1
267 if seen_dot == 0 { whole = whole * 10 + (c - CES_CH_0) } else {
268 frac_digits = frac_digits + 1
269 if frac_digits > 1 { return CES_NONE }
270 frac = c - CES_CH_0
271 }
272 }
273 i = i + 1
274 }
275 if digits == 0 { return CES_NONE }
276 if seen_dot == 1 { if frac_digits == 0 { return CES_NONE } }
277 return whole * CES_DECI + frac
278}
279
280func ces_fmt_int(dst: *u8, o: i64, v: i64) -> i64 {
281 var oo: i64 = o
282 var x: i64 = v
283 if x < 0 { dst[oo] = CES_CH_DASH as u8; oo = oo + 1; x = 0 - x }
284 let t: *u8 = sys_mmap(CES_NUM_CAP)
285 var k: i64 = 0
286 if x == 0 { t[0] = CES_CH_0 as u8; k = 1 }
287 while x > 0 { t[k] = (CES_CH_0 + (x - (x / 10) * 10)) as u8; k = k + 1; x = x / 10 }
288 while k > 0 { k = k - 1; dst[oo] = t[k]; oo = oo + 1 }
289 dst[oo] = 0 as u8
290 return oo
291}
292
293// deci-u -> "12" or "1.5" (a zero fractional digit is dropped, as the boards type their costs)
294func ces_fmt_deci(dst: *u8, o: i64, v: i64) -> i64 {
295 var oo: i64 = o
296 var x: i64 = v
297 if x < 0 { dst[oo] = CES_CH_DASH as u8; oo = oo + 1; x = 0 - x }
298 oo = ces_fmt_int(dst, oo, x / CES_DECI)
299 let f: i64 = x - (x / CES_DECI) * CES_DECI
300 if f > 0 { dst[oo] = CES_CH_DOT as u8; oo = oo + 1; dst[oo] = (CES_CH_0 + f) as u8; oo = oo + 1 }
301 dst[oo] = 0 as u8
302 return oo
303}
304
305// centi-hours -> "12.34" (always two decimals: one rounding rule, in the writer, never a second in the reader)
306func ces_fmt_centi(dst: *u8, o: i64, v: i64) -> i64 {
307 var oo: i64 = o
308 var x: i64 = v
309 if x < 0 { dst[oo] = CES_CH_DASH as u8; oo = oo + 1; x = 0 - x }
310 oo = ces_fmt_int(dst, oo, x / CES_CENTI)
311 let f: i64 = x - (x / CES_CENTI) * CES_CENTI
312 dst[oo] = CES_CH_DOT as u8; oo = oo + 1
313 dst[oo] = (CES_CH_0 + f / 10) as u8; oo = oo + 1
314 dst[oo] = (CES_CH_0 + (f - (f / 10) * 10)) as u8; oo = oo + 1
315 dst[oo] = 0 as u8
316 return oo
317}
318
319// ascending, in place (insertion: the incumbent nx_bench_stats' algorithm; n is the estate's rung count)
320func ces_sort(v: *i64, n: i64) -> i64 {
321 var i: i64 = 1
322 while i < n {
323 let key: i64 = v[i]
324 var j: i64 = i - 1
325 var go: i64 = 1
326 while go == 1 {
327 if j < 0 { go = 0 } else { if v[j] <= key { go = 0 } else { v[j + 1] = v[j]; j = j - 1 } }
328 }
329 v[j + 1] = key
330 i = i + 1
331 }
332 return n
333}
334
335func ces_qidx(n: i64, permil: i64) -> i64 {
336 if n <= 0 { return CES_NONE }
337 return (permil * (n - 1)) / CES_PERMIL
338}
339
340func ces_quantile(sorted: *i64, n: i64, permil: i64) -> i64 {
341 if n <= 0 { return CES_NONE }
342 return sorted[ces_qidx(n, permil)]
343}
344
345// the smallest n at which P10, P50 and P90 index three distinct ranks: below it the band is decoration
346func ces_cal_min_n() -> i64 {
347 var n: i64 = 1
348 var go: i64 = 1
349 while go == 1 {
350 let a: i64 = ces_qidx(n, CES_P10)
351 let b: i64 = ces_qidx(n, CES_P50)
352 let c: i64 = ces_qidx(n, CES_P90)
353 var distinct: i64 = 1
354 if a == b { distinct = 0 }
355 if b == c { distinct = 0 }
356 if distinct == 1 { go = 0 } else { n = n + 1 }
357 }
358 return n
359}
360
361// centi-hours for an estimate in deci-u at a rate of centi-hours per u
362func ces_hours_centi(deciu: i64, rate_centih: i64) -> i64 {
363 if deciu < 0 { return CES_NONE }
364 if rate_centih < 0 { return CES_NONE }
365 return (deciu * rate_centih) / CES_DECI
366}
367
368func ces_train_flops(params: i64, tokens: i64) -> i64 { return CES_TRAIN_FLOPS_PER_PT * params * tokens }
369func ces_infer_flops(params: i64, tokens: i64) -> i64 { return CES_INFER_FLOPS_PER_PT * params * tokens }
370// seconds at a measured rate; CES_NONE when the rate is not a measurement
371func ces_seconds(flops: i64, flops_per_s: i64) -> i64 {
372 if flops_per_s <= 0 { return CES_NONE }
373 return flops / flops_per_s
374}
375
376// ---- the ledger's EVENT rows: writer and reader side by side, so the wire has ONE grammar (EC56, 2026-09-17) ----
377// one event row: <tag>|<domain>|<rung>|<epoch>[|<cost_deciu>]. A cost below zero writes the four-field form.
378// Returns 1 written, 0 when the reserve is full (counted in CES_S_OVERFLOW: announced, never silent).
379func ces_event_row(rows: *u8, rcap: i64, ro: *i64, st: *i64, tag: *u8, dom: *u8, buf: *u8, goff: i64, gl: i64, epoch: i64, cost: i64) -> i64 {
380 if ro[0] + CES_ROW_RESERVE + gl + ces_slen(dom) > rcap { st[CES_S_OVERFLOW] = st[CES_S_OVERFLOW] + 1; return 0 }
381 var o: i64 = ro[0]
382 o = ces_cat(rows, o, tag)
383 rows[o] = CES_CH_PIPE as u8; o = o + 1
384 o = ces_cat(rows, o, dom)
385 rows[o] = CES_CH_PIPE as u8; o = o + 1
386 var q: i64 = 0
387 while q < gl { rows[o] = buf[goff + q]; o = o + 1; q = q + 1 }
388 rows[o] = CES_CH_PIPE as u8; o = o + 1
389 o = ces_fmt_int(rows, o, epoch)
390 if cost >= 0 { rows[o] = CES_CH_PIPE as u8; o = o + 1; o = ces_fmt_int(rows, o, cost) }
391 rows[o] = CES_CH_NL as u8; o = o + 1
392 rows[o] = 0 as u8
393 ro[0] = o
394 return 1
395}
396
397// the event rows inside [lo, hi): acc[CES_W_*] receives the land events, the DISTINCT landed rungs (domain and rung
398// together are the identity: two boards may both carry an R1), the retract events, the declared deci-u of the
399// distinct landed rungs, every land event in the ledger, and the rungs landed more than once inside the window.
400// Returns the distinct count. A row of the wrong field count is not an event row and is never half-read.
401func ces_events_window(buf: *u8, n: i64, lo: i64, hi: i64, acc: *i64) -> i64 {
402 let off: *i64 = sys_mmap(CES_I64) as *i64
403 var k: i64 = 0
404 while k < CES_W_SLOTS { acc[k] = 0; k = k + 1 }
405 if n <= 0 { return 0 }
406 let cap: i64 = n / CES_MIN_EVENT_ROW + 1
407 let ioff: *i64 = sys_mmap(cap * CES_I64) as *i64
408 let ilen: *i64 = sys_mmap(cap * CES_I64) as *i64
409 let icnt: *i64 = sys_mmap(cap * CES_I64) as *i64
410 var ni: i64 = 0
411 var p: i64 = 0
412 while p < n {
413 let e: i64 = ces_line_end(buf, n, p)
414 let l0: i64 = ces_field(buf, p, e, 0, off)
415 let t0: i64 = off[0]
416 let nf: i64 = ces_nfields(buf, p, e)
417 if ces_span_is(buf, t0, l0, CES_LAND) == 1 { if nf == CES_EV_LAND_NF {
418 acc[CES_W_EVENTS_TOTAL] = acc[CES_W_EVENTS_TOTAL] + 1
419 let el: i64 = ces_field(buf, p, e, CES_EV_F_EPOCH, off)
420 let epoch: i64 = ces_parse_int(buf, off[0], el)
421 if epoch >= lo { if epoch < hi {
422 acc[CES_W_LAND_EVENTS] = acc[CES_W_LAND_EVENTS] + 1
423 let dl: i64 = ces_field(buf, p, e, CES_EV_F_DOM, off)
424 let doff: i64 = off[0]
425 let gl: i64 = ces_field(buf, p, e, CES_EV_F_RUNG, off)
426 let idl: i64 = dl + 1 + gl
427 var seen: i64 = CES_NONE
428 var r: i64 = 0
429 while r < ni { if seen < 0 { if ces_span_eq(buf, ioff[r], ilen[r], doff, idl) == 1 { seen = r } } r = r + 1 }
430 if seen < 0 {
431 ioff[ni] = doff; ilen[ni] = idl; icnt[ni] = 1
432 ni = ni + 1
433 let cl: i64 = ces_field(buf, p, e, CES_EV_F_COST, off)
434 let c: i64 = ces_parse_int(buf, off[0], cl)
435 if c > 0 { acc[CES_W_LANDED_DECIU] = acc[CES_W_LANDED_DECIU] + c }
436 } else {
437 icnt[seen] = icnt[seen] + 1
438 if icnt[seen] == 2 { acc[CES_W_RELANDED] = acc[CES_W_RELANDED] + 1 }
439 }
440 } }
441 } }
442 if ces_span_is(buf, t0, l0, CES_RETRACT) == 1 { if nf == CES_EV_RETRACT_NF {
443 let el2: i64 = ces_field(buf, p, e, CES_EV_F_EPOCH, off)
444 let ep2: i64 = ces_parse_int(buf, off[0], el2)
445 if ep2 >= lo { if ep2 < hi { acc[CES_W_RETRACTS] = acc[CES_W_RETRACTS] + 1 } }
446 } }
447 p = e + 1
448 }
449 acc[CES_W_LANDED_RUNGS] = ni
450 return ni
451}
452
453// ---- the ledger's WIP rows (EC57): a rung the journal shows STARTED and never landed ---------------------------
454// one WIP row: open|<domain>|<rung>|<first_epoch>|<last_epoch>|<cost_deciu>
455func ces_open_row(rows: *u8, rcap: i64, ro: *i64, st: *i64, dom: *u8, buf: *u8, goff: i64, gl: i64, first: i64, last: i64, cost: i64) -> i64 {
456 if ro[0] + CES_ROW_RESERVE + gl + ces_slen(dom) > rcap { st[CES_S_OVERFLOW] = st[CES_S_OVERFLOW] + 1; return 0 }
457 var o: i64 = ro[0]
458 o = ces_cat(rows, o, CES_OPEN_TAG)
459 rows[o] = CES_CH_PIPE as u8; o = o + 1
460 o = ces_cat(rows, o, dom)
461 rows[o] = CES_CH_PIPE as u8; o = o + 1
462 var q: i64 = 0
463 while q < gl { rows[o] = buf[goff + q]; o = o + 1; q = q + 1 }
464 rows[o] = CES_CH_PIPE as u8; o = o + 1
465 o = ces_fmt_int(rows, o, first); rows[o] = CES_CH_PIPE as u8; o = o + 1
466 o = ces_fmt_int(rows, o, last); rows[o] = CES_CH_PIPE as u8; o = o + 1
467 o = ces_fmt_int(rows, o, cost)
468 rows[o] = CES_CH_NL as u8; o = o + 1
469 rows[o] = 0 as u8
470 ro[0] = o
471 return 1
472}
473
474// the WIP rows summarised at `now`: acc[CES_O_*] = open, active (touched within active_s), stale, and the oldest first
475// epoch (CES_NONE when nothing is open); toff/tlen receive the identity spans (domain|rung) of the CES_WIP_TOP most
476// recently touched, newest first. Returns how many were named. open = active + stale by construction.
477func ces_open_summary(buf: *u8, n: i64, now: i64, active_s: i64, acc: *i64, toff: *i64, tlen: *i64) -> i64 {
478 let off: *i64 = sys_mmap(CES_I64) as *i64
479 let tlast: *i64 = sys_mmap(CES_WIP_TOP * CES_I64) as *i64
480 var k: i64 = 0
481 while k < CES_O_SLOTS { acc[k] = 0; k = k + 1 }
482 k = 0
483 while k < CES_WIP_TOP { tlast[k] = CES_NONE; tlen[k] = 0; toff[k] = 0; k = k + 1 }
484 acc[CES_O_OLDEST] = CES_NONE
485 var named: i64 = 0
486 var p: i64 = 0
487 while p < n {
488 let e: i64 = ces_line_end(buf, n, p)
489 let l0: i64 = ces_field(buf, p, e, 0, off)
490 if ces_span_is(buf, off[0], l0, CES_OPEN_TAG) == 1 { if ces_nfields(buf, p, e) == CES_OPEN_NF {
491 let fl: i64 = ces_field(buf, p, e, CES_OPEN_F_FIRST, off)
492 let first: i64 = ces_parse_int(buf, off[0], fl)
493 let ll: i64 = ces_field(buf, p, e, CES_OPEN_F_LAST, off)
494 let last: i64 = ces_parse_int(buf, off[0], ll)
495 if first >= 0 { if last >= 0 {
496 acc[CES_O_OPEN] = acc[CES_O_OPEN] + 1
497 if now - last <= active_s { acc[CES_O_ACTIVE] = acc[CES_O_ACTIVE] + 1 } else { acc[CES_O_STALE] = acc[CES_O_STALE] + 1 }
498 if acc[CES_O_OLDEST] < 0 { acc[CES_O_OLDEST] = first } else { if first < acc[CES_O_OLDEST] { acc[CES_O_OLDEST] = first } }
499 let dl: i64 = ces_field(buf, p, e, CES_EV_F_DOM, off)
500 let doff: i64 = off[0]
501 let gl: i64 = ces_field(buf, p, e, CES_EV_F_RUNG, off)
502 let idl: i64 = dl + 1 + gl
503 var slot: i64 = CES_NONE
504 var s: i64 = 0
505 while s < CES_WIP_TOP { if slot < 0 { if last > tlast[s] { slot = s } } s = s + 1 }
506 if slot >= 0 {
507 var m: i64 = CES_WIP_TOP - 1
508 while m > slot { tlast[m] = tlast[m - 1]; toff[m] = toff[m - 1]; tlen[m] = tlen[m - 1]; m = m - 1 }
509 tlast[slot] = last; toff[slot] = doff; tlen[slot] = idl
510 if named < CES_WIP_TOP { named = named + 1 }
511 }
512 } }
513 } }
514 p = e + 1
515 }
516 return named
517}
518
519// ---- the calibration census over ONE plan buffer ------------------------------------------------------
520// samples: centi-hours per u, appended at sc[0] (cap scap); rows: ledger row lines appended at ro[0] (cap rcap);
521// st: the running stats (CES_S_*). Returns the rung rows parsed on this plan.
522func ces_census_plan(buf: *u8, n: i64, dom: *u8, samples: *i64, scap: i64, sc: *i64, st: *i64, rows: *u8, rcap: i64, ro: *i64) -> i64 {
523 let off: *i64 = sys_mmap(CES_I64) as *i64
524 let cap: i64 = n / CES_MIN_RUNG_ROW + 1
525 let roff: *i64 = sys_mmap(cap * CES_I64) as *i64
526 let rlen: *i64 = sys_mmap(cap * CES_I64) as *i64
527 let rcost: *i64 = sys_mmap(cap * CES_I64) as *i64
528 let rfirst: *i64 = sys_mmap(cap * CES_I64) as *i64
529 let rland: *i64 = sys_mmap(cap * CES_I64) as *i64
530 let rlast: *i64 = sys_mmap(cap * CES_I64) as *i64
531 var nr: i64 = 0
532 // pass 1: the rung rows and their declared cost
533 var p: i64 = 0
534 while p < n {
535 let e: i64 = ces_line_end(buf, n, p)
536 let l0: i64 = ces_field(buf, p, e, 0, off)
537 if ces_span_is(buf, off[0], l0, CES_RUNG_TAG) == 1 {
538 if ces_nfields(buf, p, e) >= CES_RUNG_NF { if nr < cap {
539 let il: i64 = ces_field(buf, p, e, CES_RUNG_F_ID, off)
540 roff[nr] = off[0]; rlen[nr] = il
541 let cl: i64 = ces_field(buf, p, e, CES_RUNG_F_COST, off)
542 var c: i64 = ces_parse_deciu(buf, off[0], cl)
543 if c < 0 { c = 0 }
544 rcost[nr] = c
545 rfirst[nr] = CES_NONE
546 rland[nr] = CES_NONE
547 rlast[nr] = CES_NONE
548 nr = nr + 1
549 } }
550 }
551 p = e + 1
552 }
553 // pass 2: the journal rows, matched to their rung by id
554 p = 0
555 while p < n {
556 let e: i64 = ces_line_end(buf, n, p)
557 let l0: i64 = ces_field(buf, p, e, 0, off)
558 if ces_span_is(buf, off[0], l0, CES_LOG_TAG) == 1 {
559 st[CES_S_LOGROWS] = st[CES_S_LOGROWS] + 1
560 if ces_nfields(buf, p, e) >= CES_LOG_NF {
561 let el: i64 = ces_field(buf, p, e, CES_LOG_F_EPOCH, off)
562 let epoch: i64 = ces_parse_int(buf, off[0], el)
563 let gl: i64 = ces_field(buf, p, e, CES_LOG_F_RUNG, off)
564 let goff: i64 = off[0]
565 let kl: i64 = ces_field(buf, p, e, CES_LOG_F_KIND, off)
566 let koff: i64 = off[0]
567 var idx: i64 = CES_NONE
568 var r: i64 = 0
569 while r < nr { if idx < 0 { if ces_span_eq(buf, roff[r], rlen[r], goff, gl) == 1 { idx = r } } r = r + 1 }
570 if idx < 0 { st[CES_S_UNMATCHED] = st[CES_S_UNMATCHED] + 1 } else { if epoch >= 0 {
571 if rfirst[idx] < 0 { rfirst[idx] = epoch } else { if epoch < rfirst[idx] { rfirst[idx] = epoch } }
572 if epoch > rlast[idx] { rlast[idx] = epoch }
573 if ces_span_is(buf, koff, kl, CES_RETRACT) == 1 { if ces_event_row(rows, rcap, ro, st, CES_RETRACT, dom, buf, goff, gl, epoch, CES_NONE) == 1 { st[CES_S_RETRACTS] = st[CES_S_RETRACTS] + 1 } }
574 if ces_span_is(buf, koff, kl, CES_LAND) == 1 {
575 if rland[idx] < 0 { rland[idx] = epoch } else { if epoch > rland[idx] { rland[idx] = epoch } }
576 if ces_event_row(rows, rcap, ro, st, CES_LAND, dom, buf, goff, gl, epoch, rcost[idx]) == 1 { st[CES_S_LANDEVENTS] = st[CES_S_LANDEVENTS] + 1 }
577 }
578 } }
579 } else { st[CES_S_UNMATCHED] = st[CES_S_UNMATCHED] + 1 }
580 }
581 p = e + 1
582 }
583 // the partition per rung with a land row
584 var r2: i64 = 0
585 while r2 < nr {
586 // EC57 WIP: journal rows and no land row = started, not landed; named in the ledger so no seat can miss it
587 if rland[r2] < 0 { if rfirst[r2] >= 0 {
588 if ces_open_row(rows, rcap, ro, st, dom, buf, roff[r2], rlen[r2], rfirst[r2], rlast[r2], rcost[r2]) == 1 { st[CES_S_OPEN] = st[CES_S_OPEN] + 1 }
589 } }
590 if rland[r2] >= 0 {
591 st[CES_S_WITHLAND] = st[CES_S_WITHLAND] + 1
592 if rcost[r2] <= 0 { st[CES_S_EXCL_NOCOST] = st[CES_S_EXCL_NOCOST] + 1 } else {
593 let elapsed: i64 = rland[r2] - rfirst[r2]
594 if elapsed <= 0 { st[CES_S_EXCL_ZERO] = st[CES_S_EXCL_ZERO] + 1 } else {
595 st[CES_S_CALIBRATED] = st[CES_S_CALIBRATED] + 1
596 let ratio: i64 = (elapsed * CES_PERMIL) / (CES_SEC_PER_HOUR * rcost[r2])
597 if sc[0] < scap { samples[sc[0]] = ratio; sc[0] = sc[0] + 1 } else { st[CES_S_OVERFLOW] = st[CES_S_OVERFLOW] + 1 }
598 if ro[0] + CES_ROW_RESERVE + rlen[r2] + ces_slen(dom) <= rcap {
599 var o: i64 = ro[0]
600 o = ces_cat(rows, o, "row|" as *u8)
601 o = ces_cat(rows, o, dom)
602 rows[o] = CES_CH_PIPE as u8; o = o + 1
603 var q: i64 = 0
604 while q < rlen[r2] { rows[o] = buf[roff[r2] + q]; o = o + 1; q = q + 1 }
605 rows[o] = CES_CH_PIPE as u8; o = o + 1
606 o = ces_fmt_int(rows, o, rcost[r2]); rows[o] = CES_CH_PIPE as u8; o = o + 1
607 o = ces_fmt_int(rows, o, rfirst[r2]); rows[o] = CES_CH_PIPE as u8; o = o + 1
608 o = ces_fmt_int(rows, o, rland[r2]); rows[o] = CES_CH_PIPE as u8; o = o + 1
609 o = ces_fmt_int(rows, o, elapsed); rows[o] = CES_CH_PIPE as u8; o = o + 1
610 o = ces_fmt_int(rows, o, ratio)
611 rows[o] = CES_CH_NL as u8; o = o + 1
612 rows[o] = 0 as u8
613 ro[0] = o
614 } else { st[CES_S_OVERFLOW] = st[CES_S_OVERFLOW] + 1 }
615 }
616 }
617 }
618 r2 = r2 + 1
619 }
620 st[CES_S_RUNGS] = st[CES_S_RUNGS] + nr
621 return nr
622}
623
624// the ledger line: cal|asof|boards|rungs|logrows|unmatched|withland|calibrated|excl_zero|excl_nocost|p10|p50|p90|min_n
625func ces_cal_line(dst: *u8, o: i64, st: *i64) -> i64 {
626 var oo: i64 = ces_cat(dst, o, CES_CAL_TAG)
627 var k: i64 = 0
628 while k < CES_S_MINN + 1 {
629 dst[oo] = CES_CH_PIPE as u8; oo = oo + 1
630 oo = ces_fmt_int(dst, oo, st[k])
631 k = k + 1
632 }
633 dst[oo] = CES_CH_NL as u8; oo = oo + 1
634 dst[oo] = 0 as u8
635 return oo
636}
637
638// find and parse the cal line: 1 found, 0 absent, CES_NONE malformed (a field that is not an integer)
639func ces_cal_parse(buf: *u8, n: i64, st: *i64) -> i64 {
640 let off: *i64 = sys_mmap(CES_I64) as *i64
641 var p: i64 = 0
642 while p < n {
643 let e: i64 = ces_line_end(buf, n, p)
644 let l0: i64 = ces_field(buf, p, e, 0, off)
645 if ces_span_is(buf, off[0], l0, CES_CAL_TAG) == 1 {
646 if ces_nfields(buf, p, e) != CES_CAL_NF { return CES_NONE }
647 var k: i64 = 0
648 while k < CES_S_MINN + 1 {
649 let l: i64 = ces_field(buf, p, e, k + 1, off)
650 let v: i64 = ces_parse_int(buf, off[0], l)
651 if v < 0 { return CES_NONE }
652 st[k] = v
653 k = k + 1
654 }
655 return 1
656 }
657 p = e + 1
658 }
659 return 0
660}
661
662// read the ledger at path: 1 present and parsed, 0 absent or empty, CES_NONE malformed
663func ces_cal_load(path: *u8, st: *i64) -> i64 {
664 let np: *i64 = sys_mmap(CES_I64) as *i64
665 np[0] = 0
666 let b: *u8 = sys_read_file(path, np)
667 let n: i64 = np[0]
668 if n <= 0 { sys_free_file(b, n); return 0 }
669 let r: i64 = ces_cal_parse(b, n, st)
670 sys_free_file(b, n)
671 return r
672}