Skip to content

✨ Add error correction module with Shor and Steane logical circuit transpilers - #930

Open
Felix-Gundlach wants to merge 172 commits into
munich-quantum-toolkit:mainfrom
emilkanic0909:feature/ErrorCorrection_MergePrep
Open

✨ Add error correction module with Shor and Steane logical circuit transpilers#930
Felix-Gundlach wants to merge 172 commits into
munich-quantum-toolkit:mainfrom
emilkanic0909:feature/ErrorCorrection_MergePrep

Conversation

@Felix-Gundlach

Copy link
Copy Markdown

Summary

This PR introduces a dedicated Error Correction Module for MQT Bench. It adds two high-level transpilers that encode standard benchmark circuits into fault-tolerant logical circuits using the 7-qubit Steane code and the 9-qubit Shor code, respectively. The module is designed to integrate cleanly with the existing benchmark_generation API.

Changes

New files

  • src/mqt/bench/error_correction/steane_transpiler.pySteaneTranspiler class: encodes logical qubits into 7-qubit Steane blocks, applies transversal Clifford gates (H, X, Z, S, CX, CZ), and handles T-gates via magic state injection with ancilla teleportation.
  • src/mqt/bench/error_correction/shor_transpiler.pyShorTranspiler class: encodes logical qubits into 9-qubit Shor blocks, implements the full logical Clifford gate set (including the non-transversal H via bit-swap), and supports S- and T-gates via magic state teleportation gadgets.
  • tests/test_error_correction.py — pytest suite covering gate-level equivalence (via MQT QCEC), correctness under injected bit- and phase-flip errors (via Hellinger fidelity with Aer), and circuit structure validation against pre-computed gate counts for GHZ, Bernstein–Vazirani, graph state, and QFT benchmarks.

How it works

Both transpilers follow the same three-phase pipeline:

  1. Encode — each logical qubit is replaced by a physical register (7 or 9 qubits) and initialized using the respective encoding circuit.
  2. Replace gates — the original circuit is scanned instruction by instruction and each gate is replaced with its logical equivalent. High-level gates (e.g. QFTGate) are first decomposed into the supported basis set {H, X, Z, S, T, CX, CZ}.
  3. Insert syndromes — after each logical operation, syndrome extraction and conditional correction cycles are appended using Qiskit's dynamic circuit if_test feature.

T-gates, which are non-transversal, are handled via a teleportation gadget: a magic state ancilla block is prepared, a logical CNOT is applied from the data qubit to the ancilla, the ancilla is decoded and measured, and a conditional logical S correction is applied on outcome 1.

Testing

  • Gate equivalence is verified using mqt.qcec for all single- and two-qubit Clifford gates.
  • Correctness under noise is verified by injecting a physical X or Z error after encoding and checking that the Hellinger fidelity between the corrected and uncorrected logical distributions is ≥ 0.99.
  • Circuit structure is validated against a reference gate_counts.json for qubit counts ranging from 3 to 9 across all supported algorithms.

Notes

  • QFT is currently excluded from the correctness simulation tests due to circuit depth making simulation infeasible.
  • Syndrome insertion can be toggled off via add_syndromes=False for lightweight structural or equivalence checks.

Checklist

  • The pull request only contains commits that are focused and relevant to this change.
  • We have added appropriate tests that cover the new/changed functionality.
  • We have updated the documentation to reflect these changes.
  • We have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.
  • We have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • We have reviewed our own code changes.

If PR contains AI-assisted content:

  • We have disclosed the use of AI tools in the PR description as per our AI Usage Guidelines.
  • AI-assisted commits include an Assisted-by: [Model Name] via [Tool Name] footer.
  • We confirm that We have personally reviewed and understood all AI-generated content, and accept full responsibility for it.

@emilkanic0909

Copy link
Copy Markdown

@flowerthrower Our current implementation does not allow for reuse of qubits after decoding (i.e. measuring). I will raise an error (/just add a warning?) if this is attempted for now. Alternatively, we could also re-encode the qubits when they are used again, but I've been told this won't be trivial. Do you have any preferences on how to handle this case?

@Felix-Gundlach Hi Felix, are you implementing lastest Patrick's notes or general quality improvements?

@Felix-Gundlach

Copy link
Copy Markdown
Author

@flowerthrower Our current implementation does not allow for reuse of qubits after decoding (i.e. measuring). I will raise an error (/just add a warning?) if this is attempted for now. Alternatively, we could also re-encode the qubits when they are used again, but I've been told this won't be trivial. Do you have any preferences on how to handle this case?

@Felix-Gundlach Hi Felix, are you implementing lastest Patrick's notes or general quality improvements?

Both commented features are general quality improvements. I've also quitely fixed and resolved some of the requested changes, like reverting our .gitignore changes.

@flowerthrower flowerthrower added the feature New feature or request label Aug 17, 2026
@flowerthrower

Copy link
Copy Markdown
Member

@flowerthrower Our current implementation does not allow for reuse of qubits after decoding (i.e. measuring). I will raise an error (/just add a warning?) if this is attempted for now. Alternatively, we could also re-encode the qubits when they are used again, but I've been told this won't be trivial. Do you have any preferences on how to handle this case?

Good point, lets raise an error for now. Since (measurement-based classical) control flow is already unsupported and regular benchmarks only use terminal measurements, re-encoding is not that necessary for now (only exception could be bv(dynamic=True)).

@emilkanic0909

emilkanic0909 commented Aug 22, 2026

Copy link
Copy Markdown

@flowerthrower Hi, I have fixed some issues because of gadget name in order to fix pipeline,

But I have noticed that some synthesis for QFT in different qiskit version is different, therefore amount of instructions grouped by types isnt exhaustive anymore. What should we do?

I am trying to made another structure for our tests for qft

@emilkanic0909

emilkanic0909 commented Aug 22, 2026

Copy link
Copy Markdown

@flowerthrower So for QFT we have made that it simple checks existence of some gate types and not exact amount. So all pipelines (excepting the codecov/patch) are green now.

E.g. Y gates and Z logical gates arent tested anywhere, and also generation without syndrome isnt tested. So we can add them when you confirm. Since our current tests are based on your project description, that we take bv, graphstate and qft. Maybe we could add more tests, for another circuits and parameters.

Which new tests do you recommend to add? to make codecov happy

@flowerthrower

flowerthrower commented Aug 25, 2026

Copy link
Copy Markdown
Member

Hi @emilkanic0909, thanks for your observation, the updated QFT test looks fine; checking gate presence instead of version-dependent counts resolves that issue. For the remaining coverage, please do not add more benchmark circuits just for Codecov. Instead:

  • I think we can safely remove swap, dcx, and cy from the target sets and their derived handling, since Qiskit already decomposes them into the remaining supported gates, using the same decompositions as the current implementation. Input circuits containing these gates will therefore remain supported, while we avoid duplicate decomposition logic.
  • Lets remove the unused add_syndromes=False path rather than testing it.
  • Keep and add focused (if necessary artificial) tests for directly implemented logical gates such as Y and Z.
  • Add focused tests for the public Shor and Steane generation paths and invalid encoding.

This should cover the meaningful functionality without introducing artificial tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants