Re-analyse saved results
Get everything a bundle can tell you without a board attached. You will learn to verify a bundle’s integrity, read its verdict and numbers through the typed loaders, compare two saved bundles, and turn a comparison into a pass or fail.
Hardware and wiring
Section titled “Hardware and wiring”None. Every step runs on the host against two saved, current-format profile bundles.
Software prerequisites
Section titled “Software prerequisites”Install hpx and collect two profile bundles with the current release. In the
examples below, baseline and candidate are their result directories.
Both must contain a published result manifest and a current hpx.run-summary
summary. Older bundles require the HPX release that wrote them; current
readers, including load_run_summary and hpx compare, refuse older versions.
Do not change a bundle’s version field to make it load. The
Run-summary schema reference explains
reader boundaries and historical changes to field meaning.
Config file
Section titled “Config file”None for the loaders. The regression step uses a comparison profile,
written inline below; save it as regression-profile.json beside the
bundles. The bundles’ own configs are recorded in each
run_metadata.json under config.
hpx results inspect baselinehpx results inspect candidatehpx compare baseline candidate --output-dir comparisonFor a verified native record and its portable observations:
from helia_profiler.api import inspect_result, load_result, observations, export_result
checked = inspect_result("baseline")if checked.result is None: raise ValueError(f"{checked.code}: {checked.message}")record = load_result("baseline")view = observations(record)export_result(record, "portable-result.json")To examine the typed summary after verifying the bundle:
from pathlib import Pathfrom helia_profiler.results.run_summary import load_run_summary
summary = load_run_summary(Path("baseline/summary.json"))print(summary.validity, summary.issues)print(summary.engine, summary.layers, summary.total_cycles)if summary.latency is not None: print(summary.latency.device_clean_infer_avg_cycles)Expected output
Section titled “Expected output”inspect returns a structured result or a refusal with a reason. A valid
comparison prints metric and configuration differences and writes
compare_summary.json and layer_diff.csv into comparison. Values depend
on the captured models, engines, and target configuration.
How to read it
Section titled “How to read it”- Check validity and issues before using measurements. Verified failed runs remain failed results.
total_cyclesis the instrumented per-layer sum. Clean invocation timing is a separate measurement (Latency and per-layer).- Missing optional measurements remain unknown. Reading a summary directly
checks its format but does not verify the enclosing bundle’s hashes; use
inspect_resultorload_resultfor that verification.
Variations
Section titled “Variations”Portable ordinary-profile view
Section titled “Portable ordinary-profile view”For ordinary profile bundles of the current summary schema, the offline reader verifies publication, artifact paths, sizes and hashes, and agreement of retained issues and overlapping summary/metadata/comparability identities before returning a native record. Missing identity facts remain unknown; contradictory recorded facts are refused. It refuses summaries of another version. Read historical bundles with the HPX release that wrote them; there is no archival-reader fallback.
from helia_profiler.api import inspect_result, load_result, observations, export_result
checked = inspect_result("my-profile/results")if checked.result is None: raise ValueError(f"{checked.code}: {checked.message}")record = load_result("my-profile/results")view = observations(record)export_result(record, "portable-result.json") # refuses an existing destinationThe same reader is available without loading device drivers:
hpx results inspect my-profile/resultshpx results show my-profile/resultshpx results export my-profile/results --output portable-result.jsonFor programmatic CLI execution use helia_profiler.cli.main. If you need the
full Typer application, import app from helia_profiler.cli.app; the
package-level helia_profiler.cli.app attribute can also name the implementation
module depending on import order. The full application loads operational
dependencies; the offline hpx results route does not.
inspect emits a structured envelope and exits nonzero for incomplete,
unsupported or invalid evidence. A verified failed run remains a failed
result; it does not become a successful measurement. Missing manifests and
publication markers are refusals, without a legacy fallback.
The portable view uses the draft result contract maintained in helia-benchmark’s result-contract work. It maps profiled Invoke timing, explicitly recorded restore-plus-Invoke timing, arena capacity/allocation and linked data/BSS as distinct facts. Unknown values and provenance remain null. Byte counts remain integers; timing converted from microseconds retains its source pointer and conversion. Reported and observed clocks are evidence, not external calibration.
The same entry points read a saved run result (result.json from hpx run,
or its evidence directory) and map it as hpx-run-1: per-invoke latency,
rail energy when measured, and arena use
(A saved run result). Neither
mapping covers per-layer attribution.
It does not replace the existing native loaders or hpx compare, and it
does not qualify numerical correctness or authenticate a result. All summary readers require the current format.
- Regression gate in CI: save the profile below and run
hpx compare baseline candidate --profile regression-profile.json; a regression beyond the tolerance exits non-zero.
{ "schema": "hpx.comparison-profile", "schema_version": 1, "name": "kws-apollo510", "required_dimensions": ["board", "cpu_clock"], "metrics": { "total_cycles": {"direction": "smaller", "unit": "cycles", "max_regression_pct": 3.0} }}- Per-layer table in a spreadsheet or pandas:
profile_results.csvhas one row per operator with the counter columns,cycles,cycles_pct,macs,opsandcycles_per_mac(Parsing outputs). - From Python,
hpx.Session().compare(baseline_dir, candidate_dir, output_dir=...)returns the sameCompareResultthe CLI prints. - Two current-format bundles from different boards:
hpx comparereportsboard,socandcpu_clockas differing dimensions and still shows the totals; a cycles-per-inference comparison across a Cortex-M4 and a Cortex-M55 is an architecture comparison, not an engine one.
Validated on
Section titled “Validated on”Host-only reader and comparison regression tests cover current-format acceptance and unsupported-format refusal. The commands above require your own current profile bundles; this revision does not claim a new hardware capture.
Historical examples
Section titled “Historical examples”The bundles under examples/results/hardware-validation-2026-09-16/ were
written by hpx 0.1.6 with summary schema 5. They are historical evidence,
not inputs for this walkthrough with the current release. Use their
producing release to reproduce their original analysis.