Skip to content
heliaEstimator
User guide
HELIA HUB

Acquisition lifecycle

This is the coordinated pre-v1 breaking contract tracked in #136. It does not announce a v1 product release. New native results use schema 4 and new frozen plans / compiled builds use format 2. Earlier formats are unsupported; create a new plan, build and capture. There is no archival reader or conversion fallback, and no existing files are deleted.

All three runtimes accept the same typed policy:

defaults:
fvp:
enabled: true
acquisition:
state: carry
warmup_invokes: 2
measured_invokes: 3

carry keeps one initialized instance across warmups and measurement. Resource variables persist. Inputs are filled with zeros by default, or with the fixed bytes in tensor_io, before every invoke; filling inputs is not resetting state. single permits one invoke on an initialized instance, with no warmup. An explicit warmup count greater than zero is rejected with single state, as is a measured count other than one.

For LiteRT and heliaRT, AllocateTensors runs before invokes, while CALL_ONCE initialization runs inside the first invoke when present. Automatic warmup is one for a runner model containing CALL_ONCE and zero otherwise. An explicit zero measures the first invoke, including its CALL_ONCE work.

For AOT, model_init runs once before invokes and outside PMU capture. Automatic warmup is zero. Explicit warmups run model_run on the same context; they do not repeat model_init. An AOT receipt makes no CALL_ONCE claim about the source model.

PMU capture stays disabled through warmups, and counters reset before the each measured inference. The reported scope is NPU callbacks within that inference, not application/CPU wall time. The AOT CPU wall timer starts after warmups. The default remains one measured inference. Carry supports a positive measured count on one initialized instance. Each sample has independently reset counters; warmups and output serialization are excluded. A complete ordered sequence is required before a result is published. Explicit policies with bus tracing or per-layer fencing remain unsupported.

Every executed runner must emit one current helx.acquisition receipt:

  • version: protocol version 1, with the required schema identifier.
  • state, warmup_invokes, measured_invokes: actual lifecycle/counts.
  • initialization: interpreter_allocate_and_first_invoke or before_measurement.
  • call_once_present: an observed runner-model boolean for interpreters, null for generated AOT code. This is not proof of all possible initialization work.

The bundle retains it as artifacts/acquisition.json, covered by its manifest. Missing, duplicate, unsupported or contradictory receipts fail execution before publication. A mismatch against the native UART warmup count also fails.

from helia_estimator.api import acquisition_facts, load_result, run_identity
result = load_result("results/my-run")
facts = acquisition_facts(result) # None only when the FVP stage did not execute
if facts is not None:
print(facts.state, facts.warmup_invokes, facts.initialization, facts.timing_scope)
identity = run_identity(result)

The reader verifies the receipt’s manifest bytes, completed stage, runtime, native warmup count and UART receipt when retained. An executed bundle without lifecycle facts is invalid. Build-only and Vela-only results legitimately have no execution facts. A new result may still have unavailable provider versions or other unestablished facts; those are never fabricated from the current host.

Policy is compiled into the runner and captured by freeze/build. Every current compiled build binds its CMake acquisition controls to the captured request. Changing the policy requires a new build. Run-build uses the retained executable without recompiling and checks its actual receipt before publication. Current plans and builds remain portable and integrity checked; earlier saved formats are rejected explicitly.

The portable view retains verified lifecycle facts under extensions["helia-estimator"].acquisition, with a manifest-bound receipt reference in evidence. Non-executed results have a null acquisition value.

Comparison fact HELX meaning
first_invoke_initializer False for AOT’s before_measurement initialization; otherwise the observed call_once_present boolean
first_invoke_window warmup when warmups are nonzero; otherwise measured
instance_boundary boot: one runner instance per FVP execution
counter_scope npu_callbacks: NPU counter coverage within the measured invocation
cpu_timing_scope invoke_only: when enabled, the runner CPU timer covers the invocation, excluding input refill and warmups

AOT’s null call_once_present means the operator fact is not applicable to the generated runtime. Its initialization boundary is known: model_init() runs before the first model_run(). It must not be mapped to an unknown first-invoke initializer. The interpreter boolean describes the runner model’s CALL_ONCE operator, not every possible source of lazy initialization.

Counter coverage and CPU timing scope are distinct comparison dimensions. npu_callbacks must not be compared directly with HPX’s invoke_only or restore_and_invoke CPU timing labels.

Native inference fields live in measurements.samples[i]: cycles, traffic_beats, latency_s, port_utilization, utilization_fraction, energy, sanity, and output signatures. Index zero is the first measured invoke. A signature is an output-byte fingerprint, not a numerical accuracy verdict. The reader requires the count to agree with the acquisition receipt and verifies that stored statistics reproduce the samples.

measurements.statistics includes counter count/sum/min/max, exact mean and population-variance numerator/denominator pairs, and approximate population standard deviation. Latency and total modeled energy have floating-point population statistics. No missing sample is dropped: a missing metric makes its statistic unavailable. For one sample the deviation is zero. Utilization and port occupancy remain per-sample ratios; no batch ratio is implied.

from helia_estimator.api import load_result, measurement_samples, measurement_statistics
result = load_result("results/my-run")
for sample in measurement_samples(result):
print(sample.index, sample.cycles, sample.energy)
stats = measurement_statistics(result) # None for an unexecuted result
if stats is not None:
total = stats.counters["cycles.total"]
if total is not None:
print(total.count, total.mean.numerator, total.mean.denominator)

helx show labels every measured sample. The native run_summary.csv and helx export emit one indexed row per sample. Explicit aggregate export is:

Terminal window
helx export results/my-run --fields statistics --format json

The portable draft emits one observation per sample with sample_count: 1, its native sample index, and a source pointer into the sample. It retains the full native statistics in the HELX extension rather than inventing shared aggregate fields. Multi-inference measured per-layer/viewer attribution is omitted with a reason until an explicit sample selection is supported; single-inference tracing/fencing is unchanged.

See Tensor inputs and numerical verification for fixed input bytes, per-sample output artifacts and explicit reference/tolerance policies.