Skip to content

Add experimental Stim MPP rewriter#246

Open
masa10-f wants to merge 1 commit into
mainfrom
feature/stim-mpp-rewriter
Open

Add experimental Stim MPP rewriter#246
masa10-f wants to merge 1 commit into
mainfrom
feature/stim-mpp-rewriter

Conversation

@masa10-f

Copy link
Copy Markdown
Collaborator

Summary

Adds an experimental module graphqomb.stim_mpp_rewriter that rewrites noiseless gate-level syndrome-extraction circuits into abstract MPP measurements:

from graphqomb.stim_mpp_rewriter import rewrite_to_mpp

result = rewrite_to_mpp("R 4\nH 4\nCX 4 0 4 1 4 2 4 3\nH 4\nM 4")
# result.circuit == "R 4\nMPP X0*X1*X2*X3"

How it works

  • Flattens the circuit, then splits it into segments of the standard extraction shape (resets → Clifford body → measurements).
  • Conjugates each measurement Pauli backwards through the segment body (stim.PauliString.before, i.e. U† P U) and substitutes +1 for stabilizers of freshly initialized, measured-out ancillas. Stripping is restricted to qubits measured out within the same segment, so round-1 data resets are kept in the inferred products.
  • Keeps a 1:1 measurement-record correspondence: DETECTOR/OBSERVABLE_INCLUDE are copied verbatim, MR splits into MPP + reset, and trivial data measurements pass through unchanged.
  • Returns a CheckMapping sidecar linking every record to its inferred signed Pauli product, segment index, and source ancilla, for downstream MBQC lowering.

Verification

By default every rewritten segment is verified against its source segment by cross-checking flow_generators() in both directions (with measured-out ancillas reset in both copies to discard the intentionally different post-measurement states). This catches residual data-qubit unitaries hidden in the extraction body, which per-product has_flow checks alone would miss. Pass verify=False to skip.

Scope

  • Noise instructions, noisy measurement arguments, classical feedback, and reuse of unreset measurement post-states are rejected with UnsupportedSyndromeCircuitError.
  • REPEAT blocks are flattened (bakes SHIFT_COORDS into detector coordinates); preserving them is future work, as is a GF(2) record-transform stage for flag/cat-state circuits.

Validation

  • surface_code:rotated_memory_z/x and repetition_code:memory (stim-generated, noiseless) round-trip with identical measurement counts, detector counts, and reference_detector_and_observable_signs(); middle rounds infer exactly the code stabilizers.
  • The emitted MPP layer feeds directly into the existing qec.stim_mpp.stabilizer_code_from_stim_text importer.
  • Performance with verification: d=5×5 rounds ≈ 0.4 s, d=7×7 rounds ≈ 1.8 s (≤ 0.05 s without).

Test plan

  • 24 new tests in tests/test_stim_mpp_rewriter.py (gadgets in all bases, MR splitting, detector/observable preservation, generated-circuit round trips, tag preservation, and rejection/verification-failure paths)
  • Full suite passes (828 passed, 1 skipped)
  • ruff (select ALL), ruff format, mypy strict, pyright all clean

🤖 Generated with Claude Code

Add graphqomb.stim_mpp_rewriter.rewrite_to_mpp, which rewrites noiseless
gate-level syndrome-extraction circuits into abstract MPP measurements.
Each measurement Pauli is conjugated backwards through its segment's
Clifford body via stim.PauliString.before, stabilizers of freshly
initialized measured-out ancillas are substituted by +1, and the
inferred data product replaces the measurement at the same record
position so DETECTOR and OBSERVABLE_INCLUDE annotations copy verbatim.
MR splits into MPP plus a reset, and a CheckMapping sidecar links every
record to its inferred product.

By default every rewritten segment is verified against its source by
cross-checking stabilizer-flow generators with measured-out ancillas
reset in both copies, so residual data-qubit unitaries raise
MppRewriteVerificationError. Noise, classical feedback, and reuse of
unreset measurement post-states raise UnsupportedSyndromeCircuitError.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.05502% with 40 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.57%. Comparing base (a3d035d) to head (3f77905).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #246      +/-   ##
==========================================
+ Coverage   86.55%   86.57%   +0.02%     
==========================================
  Files          31       32       +1     
  Lines        5264     5573     +309     
  Branches      937      997      +60     
==========================================
+ Hits         4556     4825     +269     
- Misses        499      524      +25     
- Partials      209      224      +15     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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