Results#
The typed data returned by profile(). Core measurement records
are frozen against field reassignment, while run metadata is enriched as the
pipeline executes. Dynamic nested collections such as counters, engine
extensions, power samples, and metadata remain mutable for compatibility and
efficient capture assembly. Treat collections on returned results as read-only.
ProfileResult
dataclass
#
ProfileResult(pmu: PmuResult, power: PowerResult | None = None, power_observation: PowerObservation | None = None, power_terminal: PowerTerminalRecord | None = None, on_device_power: OnDevicePowerSummary | None = None, metadata: RunMetadata = RunMetadata(), report_paths: list[Path] = list())
Complete profiling result — the public return type of hpx.profile().
This is the one object a programmatic user needs. It carries everything: PMU data, optional power data, run metadata, and report file paths.
PmuResult
dataclass
#
PmuResult(meta: FirmwareMeta, presets: dict[str, PresetResult] = dict(), layers: list[LayerResult] = list(), overflow_detected: bool = False, groups: dict[str, list[LayerResult]] = dict())
Complete PMU profiling result across all presets.
PresetResult
dataclass
#
PresetResult(name: str, header: list[str] = list(), iterations: list[list[LayerResult]] = list(), layers: list[LayerResult] = list())
Results for a single PMU counter preset (e.g. basic_cpu).
LayerResult
dataclass
#
LayerResult(id: int | str, op: str, counters: dict[str, float] = dict(), cycles: float | None = None, overflow: bool = False)
Profiling result for a single model layer (averaged across iterations).
FirmwareMeta
dataclass
#
FirmwareMeta(model_size: int | None = None, arena_size: int | None = None, allocated_arena: int | None = None, input_size: int | None = None, output_size: int | None = None, num_tensors: int | None = None, num_inputs: int | None = None, num_outputs: int | None = None, num_presets: int | None = None, system_clock_hz: int | None = None, profiled_infer_count: int | None = None, profiled_infer_total_us: int | None = None, profiled_infer_avg_us: int | None = None, clean_infer_count: int | None = None, clean_infer_total_cycles: int | None = None, clean_infer_avg_cycles: int | None = None, clean_infer_avg_us: int | None = None, clean_stalled_iters: int | None = None, clean_partial_iters: int | None = None, clean_ref_cycles: int | None = None, clean_dwt_rate_cyc: int | None = None, clean_dwt_rate_us: int | None = None, clean_attach_wait_us: int | None = None, psram: PsramInfo | None = None, presets: tuple[str, ...] = ())
Metadata reported by the profiler firmware at startup.
All fields are optional because older firmware versions may not report every field.
RunMetadata
dataclass
#
RunMetadata(hpx_version: str = '', run_id: str = '', timestamp: str = '', config_snapshot: dict[str, Any] = dict(), platform: PlatformInfo | None = None, model: ModelInfo | None = None, toolchain: ToolchainInfo | None = None, engine: EngineInfo | None = None, firmware: FirmwareMeta | None = None, memory_plan: 'MemoryPlan | None' = None, timing: TimingInfo | None = None, compatibility: CompatibilityResolution | None = None, dependencies: 'DependencyProvenance | None' = None)
Accumulated run metadata — enriched by stages, consumed by reports.
NsxModuleRef
dataclass
#
NsxModuleRef(name: str, path: Path, version: str = '', local: bool = True, project: str = '', ref: str = '')
Reference to an NSX module needed by the profiler firmware build.
A module is resolved one of two ways:
- Registry (
local=False) — NSX clones the module from its registered upstream (GitHub).projectis the registry project name andrefoptionally pins a tag/branch.pathis unused. - Local (
local=True) — hpx vendors the module on disk.pathis the source directory to copy into the app, andproject(when set) selects the registry-derived install location so NSX's registry-aware lock can find it.
PowerResult
dataclass
#
PowerResult(summary: PowerSummary, samples: list[PowerSample] = list(), gated_windows: list[GatedPowerWindow] = list(), per_layer: dict[str, Any] | None = None, metadata: PowerMetadata = PowerMetadata())
Complete result of a power capture.
metadata is the typed :class:~helia_profiler.power.metadata.PowerMetadata
(#154 Phase 2 breaking change — previously dict[str, Any]; the flat
dict view is metadata.to_metadata_dict()). The result is frozen but
its metadata is deliberately mutable: pipeline stages enrich it after
capture, like RunMetadata.
Result bundles#
The result manifest is a small stable envelope around open provenance, comparability, and extension data. Loading preserves unknown fields so newer producers can evolve additively without older tools silently deleting data.
load_result_manifest #
load_result_manifest(path: str | Path, *, verify: bool = False) -> ResultManifest
Load a result manifest and optionally verify its sibling artifacts.
ResultManifest
dataclass
#
ResultManifest(schema: str, schema_version: int, run_id: str, timestamp: str, hpx_version: str, status: RunStatus, validity: ResultValidity, issues: tuple[ResultIssue, ...], provenance: dict[str, Any], comparability: dict[str, Any], artifacts: tuple[ResultArtifact, ...], bundle_type: str | None = None, extensions: dict[str, Any] = dict(), extra: dict[str, Any] = dict())
Stable result envelope with open provenance and extension payloads.
verify #
Verify all declared artifact paths, sizes, and SHA-256 digests.
ResultArtifact
dataclass
#
ResultArtifact(path: str, media_type: str, size_bytes: int, sha256: str, role: str | None = None, name: str | None = None, schema: str | None = None, schema_version: int | None = None, producer: str | None = None, optional: bool | None = None, extra: dict[str, Any] = dict())
One content-addressed file in a result bundle.
ResultIssue
dataclass
#
ResultIssue(code: str, severity: str, message: str, context: dict[str, Any] = dict(), extra: dict[str, Any] = dict())
One stable machine-readable issue with optional open context.
RunStatus #
Bases: StrEnum
Publication status of a result bundle.
ResultValidity #
Bases: StrEnum
Whether measurements in a completed bundle are authoritative.
Dependency lock provenance#
read_dependency_lock_provenance() is a read-only provider for later
diagnostics collectors. Pass a prepared profiler_app, its nsx.lock or
hpx-dependencies.json, or the parent fingerprint workspace. It verifies the
exact lock SHA-256 and returns a frozen typed surface; it does not resolve,
synchronize, sanitize, or write files.
The stable join keys are baseline_fingerprint
(CompatibilityBaseline.fingerprint) and lock_sha256.
read_dependency_lock_provenance #
read_dependency_lock_provenance(app_or_workspace_path: str | Path) -> DependencyLockProvenance
Read typed lock provenance without mutating an app or workspace.
app_or_workspace_path may name profiler_app, its nsx.lock or
hpx-dependencies.json, or the parent fingerprint workspace containing
profiler_app. The exact on-disk lock digest is verified against the
recorded run state before a surface is returned.
DependencyLockProvenance
dataclass
#
DependencyLockProvenance(lock_path: Path, lock_sha256: str, registry_hash: str, requested_refs: tuple[DependencyRequest, ...], resolved: tuple[DependencyModule, ...], overrides: tuple[DependencyOverride, ...], qualification: QualificationState, baseline_fingerprint: str, workspace_fingerprint: str, lock_mode: DependencyLockMode, update_requested: bool)
Read-only lock provenance surface for later diagnostics collectors.
Field-diagnostics support bundle#
collect_support_bundle() is the diagnostics collector read_dependency_lock_provenance()
was reserved for: it gathers doctor checks/versions, the compatibility
baseline, the exact Stage 5 lock provenance (when workspace is given), a
module inventory, an optional sanitized resolved config, and optional
probe/port summaries — redacting absolute paths, credentialed URLs, tokens,
and device serials by default (see helia_profiler.redact) — into one
in-memory SupportBundleCollection. write_support_bundle() archives it
deterministically (stable member order and byte content for identical
inputs); verify_support_bundle() re-checks an archive's structure and
per-member digests, rejecting unsafe or disallowed member paths. Every
section is collected best-effort: a missing workspace, config, or optional
tool marks just that section unavailable with a reason instead of failing
the whole bundle.
SupportBundleOptions
dataclass
#
SupportBundleOptions(workspace: Path | None = None, config_path: Path | None = None, toolchain: Toolchain = ARM_NONE_EABI_GCC, transport: Transport = RTT, engine: EngineType = HELIA_RT, include_probes: bool = True, include_ports: bool = True, raw_probe_ids: bool = False)
What hpx doctor --bundle should collect.
Every section beyond the always-available doctor checks and compatibility baseline is optional and independently toggleable so a bundle can be built entirely offline with no attached hardware.
collect_support_bundle #
collect_support_bundle(options: SupportBundleOptions = SupportBundleOptions()) -> SupportBundleCollection
Gather every diagnostic section, redact it, and build the manifest.
Never raises for a missing optional dependency, tool, or workspace — every section catches its own typed failures and records a skip reason instead. Only truly unexpected internal errors propagate.
write_support_bundle #
Write collection as a deterministic ZIP archive and return its path.
output names the exact archive file when it ends in .zip;
otherwise it is treated as a directory (created if needed) and the
filename is derived from :func:content_fingerprint plus the HPX
version, so identical inputs always produce the same file name and the
same member bytes for every entry except manifest.json (only its
generated_at timestamp differs run to run).
Raises :class:~helia_profiler.errors.ReportError (not a raw
:class:OSError) if the destination cannot be created or written to
(permission denied, no space left, a path component that is itself a
file, ...), so CLI callers only ever need to catch HpxError.
verify_support_bundle #
verify_support_bundle(path: Path) -> SupportBundleManifest
Verify a support-bundle archive's structure, contents, and digests.
Rejects absolute member paths (POSIX, and Windows drive-letter paths in
either C:\... or C:/... form), ../empty path segments,
backslashes, NUL bytes, duplicate entries, and any file extension other
than .json/exactly nsx.lock — defense in depth against a
malformed or hostile archive (zip-slip, disguised binary payloads) even
though this module only ever writes archives matching that shape
itself.
SupportBundleManifest
dataclass
#
SupportBundleManifest(schema: str, schema_version: int, hpx_version: str, generated_at: str, host: dict[str, Any], sections: tuple[SupportBundleSection, ...], redaction: dict[str, Any], artifacts: tuple[ResultArtifact, ...], extra: dict[str, Any] = dict())
Stable envelope describing one support-bundle archive's contents.
verify #
Verify every declared artifact path, size, and SHA-256 digest.
Rejects absolute paths and any path that escapes bundle_dir so a hostile/corrupted manifest cannot be used to read or overwrite files outside the extracted bundle (zip-slip style attacks).
SupportBundleSection
dataclass
#
One diagnostic section the collector attempted.
available=False records why a section was skipped (missing
workspace, offline, optional tool absent, ...) rather than failing the
whole bundle — see docs/architecture/field-diagnostics.md.
Validity and comparability#
The same pure policy functions drive manifests, summary output, comparisons, and programmatic consumers. Invalid runs and model mismatches block run-level deltas. Topology differences suppress only per-layer deltas. Power scope, mode, firmware, or integrity differences suppress only power metrics, while intentional engine, toolchain, clock, board, transport, and placement changes remain informative comparison dimensions.
evaluate_run #
evaluate_run(ctx: PipelineContext) -> RunEvaluation
Evaluate captured results without mutating pipeline state.
RunEvaluation
dataclass
#
RunEvaluation(validity: ResultValidity, issues: tuple[ResultIssue, ...] = ())
Authoritative validity and structured issues for one completed run.
assess_comparability #
assess_comparability(baseline: RunArtifacts, candidate: RunArtifacts) -> ComparabilityAssessment
Compare identity, validity, topology, and intentional run dimensions.
ComparabilityAssessment
dataclass
#
ComparabilityAssessment(issues: tuple[ComparabilityIssue, ...] = ())
Whether run-level and per-layer deltas may be computed.
ComparabilityIssue
dataclass
#
ComparabilityIssue(code: str, severity: ComparabilitySeverity, message: str, context: dict[str, Any] = dict())
One machine-readable compatibility decision.
ComparabilitySeverity #
Bases: StrEnum
Effect of one comparability issue on comparison output.
Defined here so the comparability registry can bind severity to code
without importing from evaluation; evaluation.comparability
re-exports it, which remains the canonical public import path.
Regression profiles#
Versioned comparison profiles apply deterministic direction, unit, tolerance,
missing-metric, and required-dimension policy to an existing CompareResult.
They remain separate from the loose result-bundle schema.
ComparisonProfile
dataclass
#
ComparisonProfile(schema: str, schema_version: int, metrics: dict[str, MetricPolicy], missing: MissingMetricPolicy | None = None, required_dimensions: tuple[str, ...] = (), name: str | None = None, extra: dict[str, Any] = dict())
Open v1 profile selecting deterministic metric regression policies.
MetricPolicy
dataclass
#
MetricPolicy(direction: MetricDirection, unit: str, max_regression_pct: float | None = None, max_regression_abs: float | None = None, missing: MissingMetricPolicy | None = None, extra: dict[str, Any] = dict())
Tolerance and availability policy for one named comparison metric.
MetricDirection #
Bases: StrEnum
Preferred candidate direction for one metric.
MissingMetricPolicy #
Bases: StrEnum
Verdict when a selected metric is unavailable.
evaluate_comparison_profile #
evaluate_comparison_profile(result: CompareResult, profile: ComparisonProfile) -> ComparisonVerdict
Evaluate existing metric deltas against one versioned profile.
ComparisonVerdict
dataclass
#
ComparisonVerdict(status: VerdictStatus, metrics: tuple[MetricVerdict, ...], dimension_mismatches: tuple[str, ...] = (), profile_name: str | None = None, profile_schema: str = COMPARISON_PROFILE_SCHEMA, profile_schema_version: int = COMPARISON_PROFILE_SCHEMA_VERSION, profile_sha256: str = '')
Deterministic verdict for one result pair and profile.
MetricVerdict
dataclass
#
MetricVerdict(metric: str, status: VerdictStatus, message: str, baseline: float | None = None, candidate: float | None = None, regression: float | None = None, allowed_regression: float | None = None, unit: str = '')
Verdict and evidence for one selected metric.
VerdictStatus #
Bases: StrEnum
Regression policy outcome.