Skip to content

feat(core): structured profile output with qubit lifetimes, injection impact, and enriched Monte Carlo fields#34

Merged
m2papierz merged 5 commits into
masterfrom
feat/output-completeness
Jun 19, 2026
Merged

feat(core): structured profile output with qubit lifetimes, injection impact, and enriched Monte Carlo fields#34
m2papierz merged 5 commits into
masterfrom
feat/output-completeness

Conversation

@m2papierz

Copy link
Copy Markdown
Contributor

What

Adds a ProfileOutput serialization layer that wraps ExecutionProfile into a structured JSON envelope, enriches ReplicaSummary with fixup/factory/injection tracking, and introduces qubit lifetime analysis.

Why

The raw ExecutionProfile leaked internal structure into the CLI JSON output - consumers had no metadata (version, circuit name, hardware model, seed) and missing derived metrics (injection error rate, error budget, qubit lifetimes). Monte Carlo replicas lacked critical-path extension and factory production counts, making it impossible to analyze fixup overhead or injection success rates across runs. Sensitivity analysis had no metrics for stall fraction, buffer-full rate, or space-time product.

How

  • ProfileOutput envelope (profile.rs): new output types (OutputMeta, TimelineData, ErrorBudget, InjectionImpact,
    QubitLifetimes, RoutingModelInfo, SimulationMode) that restructure ExecutionProfile fields into a stable external schema.
    ProfileOutput::from_profile() consumes the internal profile and produces the serialized form.
  • Qubit lifetime analysis (analyzer.rs): single O(n) trace scan over GateScheduled/GateCompleted events via a gate-to-qubit lookup map (build_gate_qubit_map). Computes per-qubit first-to-last active cycle, with mean/max/p95 aggregation. Uses select_nth_unstable for O(n) p95 without sorting.
  • Streaming hardening (streaming.rs): replaces bare += with saturating_add on all event counters. Shrinks fixup_starts SmallVec from 8 to 2 inline (typical concurrent fixup count). Adds total_factory_productions counter propagated through EngineResult.
  • ReplicaSummary enrichment (monte_carlo.rs): adds critical_path_extension, total_factory_productions, successful_injections. Replaces the positional ReplicaSummary::new() constructor with struct-literal syntax (compile-time field sync still enforced).
    SummaryAccumulator now tracks fixup durations and factory production counts. Five new OutputMetric variants for sensitivity analysis.
  • CLI emits ProfileOutput JSON instead of raw ExecutionProfile. Python bindings expose the three new ReplicaSummary and MonteCarloResult fields.

Testing

  • make ci passes locally (fmt + clippy + test + audit)
  • New behavior has tests
  • Hot-path changes have criterion benchmarks

Checklist

  • PR description explains why, not just what
  • No new unwrap()/expect() in production code
  • No new allocations in the simulation hot loop
  • Crate boundaries respected (pirx-core never imports from pirx-adapters)
  • New dependencies justified (not "it's popular" — what does it replace?)

Introduces the external API surface for profile output: ProfileOutput,
OutputMeta, TimelineData, ErrorBudget, InjectionImpact, QubitLifetimes,
RoutingModelInfo, and SimulationMode. Adds PartialEq to existing profile
types for roundtrip test support. ProfileOutput separates the serialized
JSON schema from internal ExecutionProfile, allowing the output format
to evolve independently.
Adds compute_qubit_lifetimes to ProfileAnalyzer: single O(n) scan over
GateScheduled/GateCompleted events to compute per-qubit first-to-last
active cycle durations, with mean/max/p95 aggregation. Includes
build_gate_qubit_map for OpId-to-qubit lookup from circuit IR. Covers
unit and proptest invariants (mean <= max, p95 <= max, zero-qubit edge).
Replaces bare += with saturating_add for all event counters in
StreamingAnalyzer (injection errors, fixups, buffer-full, decoder
stalls). Shrinks fixup_starts SmallVec inline capacity from 8 to 2
(typical concurrent fixup count). Adds total_factory_productions
counter and propagates it through EngineResult::Streaming.
…fields

Adds critical_path_extension, total_factory_productions, and
successful_injections to ReplicaSummary with corresponding Monte Carlo
distributions. Replaces ReplicaSummary::new() with struct-literal syntax
for compile-time field sync. Hardens SummaryAccumulator with
saturating_add and fixup duration tracking. Adds five OutputMetric
variants (StallFraction, CriticalPathExtension, BufferFullRate,
InjectionErrorRate, SpaceTimeProduct) for sensitivity analysis. Exposes
new fields in Python bindings.
Switches profile subcommand output from raw ExecutionProfile to the
structured ProfileOutput envelope with metadata, timeline, error budget,
qubit lifetimes, and injection impact sections. Updates integration tests
to deserialize ProfileOutput.
@codspeed-hq

codspeed-hq Bot commented Jun 19, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 27 untouched benchmarks


Comparing feat/output-completeness (5be515b) with master (13dacfe)

Open in CodSpeed

@m2papierz m2papierz merged commit 01ceac4 into master Jun 19, 2026
11 checks passed
@m2papierz m2papierz deleted the feat/output-completeness branch June 19, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant