Skip to content

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

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

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

Conversation

@Felix-Gundlach

@Felix-Gundlach Felix-Gundlach commented Jun 13, 2026 •

Copy link
Copy Markdown

Description

Adds an error correction module that encodes benchmark circuits into logical circuits using the 7-qubit Steane code or the 9-qubit Shor code. Encoding is exposed via a new encoding parameter on get_benchmark() and get_benchmark_alg(), accepting "", "steane", or "shor":

qc = get_benchmark(benchmark="ghz", level=BenchmarkLevel.ALG, circuit_size=3, encoding="steane")

error_correction/ec_transpiler.py holds the code-agnostic ECTranspiler base class. It decomposes the circuit into the code's basis, replaces every logical qubit with a data register plus syndrome ancillas, substitutes each gate by its logical equivalent, and appends a syndrome extraction and correction cycle after every logical operation. SteaneTranspiler and ShorTranspiler only declare their code parameters and supply the encoding, decoding, and syndrome circuits.

Since MQT Bench targets circuit structure rather than exact behaviour, gates without a fault-tolerant transversal realization (t/tdg for both codes, plus h for Shor) are emitted as opaque placeholder instructions named {code}_ideal_logical_{gate} rather than as full magic-state constructions.

The encoding, decoding, syndrome, and correction circuits shared with the existing seven_qubit_steane_code and shors_nine_qubit_code benchmarks moved into a new components module.

Dependencies: requires Qiskit >= 2.4.0 (up from 2.0.0) for the transpilation to the Clifford+T basis. Noted in the changelog and the upgrade guide.

Limitations: encoding is only applied at BenchmarkLevel.ALG (a UserWarning is raised otherwise), control-flow operations are rejected with a ValueError, and basis decomposition uses approximation_degree=0.95, so encoded circuits are approximations.

AI assistance: this description was drafted by an LLM from the current diff and reviewed by us. Various docstrings were generated by an LLM and reviewed & edited by us.

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:

  • Any agent that created, edited, or submitted GitHub content was explicitly authorized for that scope, as required by our [AI Usage Guidelines](https://github.com/munich-quantum-toolkit/bench/blob/main/docs/ai_usage.md).
  • Every agent-authored or agent-edited public text body begins with the visible disclosure 🤖 *AI text below* 🤖 (titles are exempt).
  • We have disclosed AI assistance in the PR description.
  • We confirm that we have personally reviewed and understood all AI-generated content, and accept full responsibility for it.

SalehAlsherif and others added 30 commits June 6, 2026 10:43
….com/emilkanic0909/MQT_Bench_ErrorCorrectionCodes into feature/ErrorCorrection_Verification

# Conflicts:
#	tests/test_error_correction.py
…rection_SubMain

# Conflicts:
#	src/mqt/bench/benchmark_generation.py
…lkanic0909/MQT_Bench_ErrorCorrectionCodes into feature/ErrorCorrection_Verification
…c0909/MQT_Bench_ErrorCorrectionCodes into feature/ErrorCorrection_SubMain
…c0909/MQT_Bench_ErrorCorrectionCodes into feature/ErrorCorrection_SubMain
…c0909/MQT_Bench_ErrorCorrectionCodes into feature/ErrorCorrection_SubMain
+ early gate_counts.json, counts for steane are not yet correct

@simon1hofmann simon1hofmann left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The early return in get_benchmark_alg() now skips encoding when generate_mirror_circuit=True. A two-qubit GHZ mirror stays at 2 qubits with either encoding, instead of 26 for Steane or 34 for Shor. Please assign the mirror to qc rather than returning, then continue through the encoding block. A small regression test combining mirroring and encoding would catch this.

@Felix-Gundlach

Copy link
Copy Markdown
Author

The early return in get_benchmark_alg() now skips encoding when generate_mirror_circuit=True. A two-qubit GHZ mirror stays at 2 qubits with either encoding, instead of 26 for Steane or 34 for Shor. Please assign the mirror to qc rather than returning, then continue through the encoding block. A small regression test combining mirroring and encoding would catch this.

My bad. Good catch.

@emilkanic0909
emilkanic0909 force-pushed the feature/ErrorCorrection_MergePrep branch from 5091caf to c6e296f Compare October 22, 2026 20:51
@simon1hofmann

simon1hofmann commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

We fixed the problems with Clifford+T synthesis in #1081 and #1093.
This has been done in way such that the minimum Qiskit version can stay at 'v2.2.3' while Qiskit versions above v2.4.2 will use the improved synthesis approach. Could you add a conditional check like that in your PR as well so we don't have to raise the minimum Qiskit version?

@emilkanic0909

emilkanic0909 commented Oct 24, 2026 •

Copy link
Copy Markdown

We fixed the problems with Clifford+T synthesis in #1081 and #1093. This has been done in way such that the minimum Qiskit version can stay at 'v2.2.3' while Qiskit versions above v2.4.2 will use the improved synthesis approach. Could you add a conditional check like that in your PR as well so we don't have to raise the minimum Qiskit version?

Thanks for info, We will try

Felix-Gundlach and others added 5 commits October 24, 2026 19:07
Signed-off-by: Felix Gundlach <67263641+Felix-Gundlach@users.noreply.github.com>
The EC transpiler now checks the Qiskit version, so the minimum stays at 2.2.3.

- Qiskit 2.5.0 and newer: Qiskit's Clifford+T compilation with `approximation_degree=0.95` (unchanged output).
- Older versions: each RZ rotation is replaced by Solovay-Kitaev at recursion degree 0 (at most 12 H/T/Tdg gates), with only RZ gates changed.

The threshold is 2.5.0 instead of 2.4.2 because gridsynth in Qiskit 2.4.0–2.4.2 panics for about a third of rotation angles at this approximation degree. Only its default precision works there, and that makes encoded circuits 40–80x larger. The EC tests pass on every Qiskit release from 2.2.3 to 2.6.1.
@Felix-Gundlach

Copy link
Copy Markdown
Author

Because I should've put this as a comment, not a commit message, in the first place:

🤖 AI text below 🤖

The EC transpiler now checks the Qiskit version, so the minimum stays at 2.2.3.

  • Qiskit 2.5.0 and newer: Qiskit's Clifford+T compilation with approximation_degree=0.95 (unchanged output).
  • Older versions: each RZ rotation is replaced by Solovay-Kitaev at recursion degree 0 (at most 12 H/T/Tdg gates), with only RZ gates changed.

The threshold is 2.5.0 instead of 2.4.2 because gridsynth in Qiskit 2.4.0–2.4.2 panics for about a third of rotation angles at this approximation degree. Only its default precision works there, and that makes encoded circuits 40–80x larger. The EC tests pass on every Qiskit release from 2.2.3 to 2.6.1.

@Felix-Gundlach

Copy link
Copy Markdown
Author

@simon1hofmann We no use different transpilation passes depending on qiskit version as requested. While not quite the same as the switch quoted in #930 now on main, they work well with the tests. Some oddities may remain™.

Apart from the currently failing test case ("changes can be cleanly merged"...), is there anything else we can still help with?

@simon1hofmann

Copy link
Copy Markdown
Collaborator

Hey @Felix-Gundlach

A few things still need fixing before merging:

  1. Preserve metadata when encoding. ✨ Improve CLI generation and make file exports atomic #1115 added generation settings to circuit metadata and export headers. get_benchmark_alg() records them before replacing the circuit with the encoded result, losing the seed, mirror flag, and caller metadata. Please preserve that metadata and record the encoding name as well.

  2. Fix the CI test input. 🐛 Validate benchmark inputs and document factory options #1108 added the minimum-size check for Bernstein–Vazirani. test_get_benchmark_alg_encoding_parameters still requests one qubit. Use two and check the resulting width: 26 for Steane and 34 for Shor.

  3. Remove the obsolete Qiskit upgrade note. ✨ Add fractional Heron compilation targets #1087 established the current minimum of Qiskit 2.2.3. This PR now retains that support through its fallback, so the new “Qiskit 2.4 minimum” section and the corresponding PR-description claim can be removed.

Please also finish the documentation cleanup:

  • Correct the Steane docstring that still mentions SWAP/DCX/CY.
  • In the changelog, define the [#930] link.
  • Document that circuits containing opaque logical gadgets require QPY export: Shor-encoded GHZ currently fails QASM 3 export, while QPY round-trips successfully.

This branch has not been deployed

No deployments
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.

6 participants