Skip to content

Conversation

@adnathanail
Copy link
Contributor

@adnathanail adnathanail commented Jan 19, 2026

Description

Adds Shor's 9 Qubit Code as a benchmark

Fixes #790

Checklist:

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.
  • I 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.
  • I have reviewed my own code changes.

@github-project-automation github-project-automation bot moved this to In Progress in MQT Applications Jan 19, 2026
@adnathanail adnathanail force-pushed the shors-9-qubit-code branch 2 times, most recently from 6a4e96c to 81b22da Compare January 19, 2026 14:55
@adnathanail adnathanail marked this pull request as ready for review January 19, 2026 17:03
@coderabbitai
Copy link

coderabbitai bot commented Jan 19, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added Shor's 9 Qubit Code benchmark, supporting multiple logical qubits with flexible circuit sizes.
  • Tests

    • Enhanced test coverage with structure validation and multi-qubit circuit testing for the new benchmark.
  • Improvements

    • Optimized transpilation handling for Clifford+T gate synthesis.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds a new Shor's 9 Qubit Code benchmark and tests, introduces a CustomSolovayKitaev transpiler pass, and wires the pass into benchmark native-gate synthesis for Clifford+T targets. Changelog updated with the new benchmark entry and PR link.

Changes

Cohort / File(s) Summary
Changelog
CHANGELOG.md
Added Unreleased "Added" entry for "Shor's 9 Qubit Code benchmark" and PR link [#803].
Shor benchmark
src/mqt/bench/benchmarks/shors_nine_qubit_code.py
New benchmark module: helpers for encoding/decoding, syndrome extraction, correction; builds single-logical-qubit circuit (17 qubits), validates num_qubits (≥17, divisible by 17), supports multiple logical qubits, adds barrier and measure_all, registers create_circuit(num_qubits).
Tests
tests/test_bench.py
Added SPECIAL_QUBIT_COUNTS["shors_nine_qubit_code"] = 17. New tests test_shors_nine_qubit_code_circuit_structure and test_shors_nine_qubit_code_multiple_logical_qubits. Extended test_wrong_circuit_size with Shor case and added runtime skip in test_quantumcircuit_levels for devices with insufficient qubits. Imported IfElseOp for assertions.
Custom Solovay–Kitaev pass
src/mqt/bench/custom_solovay_kitaev.py
New CustomSolovayKitaev class (subclass of Qiskit SolovayKitaev) overriding run to synthesize non-parameterized single-qubit gates in-DAG, skipping unsupported ops and replacing nodes with approximation DAGs.
Benchmark generation wiring
src/mqt/bench/benchmark_generation.py
Switched from Qiskit's SolovayKitaev to local CustomSolovayKitaev when target.description == "clifford+t" in native-gate synthesis path.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant BenchmarkGen as BenchmarkGeneration
    participant PassMgr as PassManager
    participant CSVK as CustomSolovayKitaev
    participant Transpiler as Transpiler/DAG
    User->>BenchmarkGen: request native-gate synthesis (clifford+t)
    BenchmarkGen->>PassMgr: create PassManager with CustomSolovayKitaev
    PassMgr->>CSVK: run pass on DAG
    CSVK->>Transpiler: inspect op nodes, call internal SK to synthesize approximations
    CSVK->>Transpiler: replace op nodes with approximation DAGs
    PassMgr->>BenchmarkGen: return transformed DAG/circuit
    BenchmarkGen->>User: return native-gate circuit
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰
Nine qubits curl beneath my paw,
I sniff each stitch, then hop and draw,
Mid-circuit measures, fixes true,
I nudge a Z, a clever X too,
Hooray — the benchmark blooms anew 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning All changes are directly related to implementing Shor's 9 Qubit Code. However, a CustomSolovayKitaev pass was introduced which appears unrelated to the core benchmark implementation. Clarify why CustomSolovayKitaev was added and whether it relates to the Shor's code benchmark or represents a separate enhancement. If unrelated, consider splitting into a separate PR.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: implementing Shor's 9 Qubit Code as a new benchmark.
Description check ✅ Passed The PR description follows the template structure with a description summary, issue reference (#790), and a completed checklist matching the required sections.
Linked Issues check ✅ Passed The PR fully addresses issue #790's requirements: implements Shor's 9-qubit code with 9 physical qubits, demonstrates mid-circuit measurement-based error detection/correction, and applies corrective gates after measurement.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@adnathanail adnathanail marked this pull request as draft January 19, 2026 23:55
@adnathanail adnathanail marked this pull request as ready for review January 20, 2026 00:29
@codecov
Copy link

codecov bot commented Jan 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Fix all issues with AI agents
In `@src/mqt/bench/benchmarks/shors_nine_qubit_code.py`:
- Around line 260-263: Fix the typo in the encoding docstring by replacing the
incorrect ket string "|--->⟩" with the correct "|---⟩" in the Encoding section;
locate the docstring that describes "Phase-flip encoding" (the text containing
"|0⟩ → |+++⟩ and |1⟩ → |--->⟩") and edit that string to remove the extra ">" so
it reads "|0⟩ → |+++⟩ and |1⟩ → |---⟩".
- Around line 84-110: The phase-flip syndrome circuit in
_get_nine_qubit_shors_code_phase_flip_syndrome_extraction_circuit uses
ancilla-controlled CNOTs but lacks an explicit note of which X‑parity
stabilizers are being measured; update the function docstring or add a brief
inline comment near the uses of phase_flip_syndrome and logical_qubit to state
that the circuit measures X⊗X⊗X parity on each 3‑qubit block (qubits 0–2, 3–5,
6–8) using ancillas phase_flip_syndrome[0] and phase_flip_syndrome[1], and
clarify the ancilla measurement mapping (01 → block 1, 10 → block 2, 11 → block
3, 00 → no error) so the CX patterns are immediately understandable.
- Around line 113-144: Update the docstring of
_apply_nine_qubit_shors_code_bit_flip_correction to explicitly state the assumed
Qiskit little-endian bit order (ClassicalRegister index 0 = least-significant
bit) and explain how the integer syndrome patterns (e.g., 0b000001, 0b000010,
etc.) map to the three-bit syndrome values for each 3-qubit block so future
maintainers understand the mapping and conditional X corrections.

In `@src/mqt/bench/custom_solovay_kitaev.py`:
- Around line 62-63: Fix the awkward comment in
src/mqt/bench/custom_solovay_kitaev.py by rephrasing the sentence that currently
reads "as we know it comes from a Qiskit gate, as this we know it will generate"
to a single clear clause; for example, change the comment inside the
input-matrix check block to: "we do not check the input matrix because it comes
from a Qiskit gate and therefore will be a valid SU(2) matrix" so it reads
grammatically correct and unambiguous.
- Around line 52-54: The docstring in src/mqt/bench/custom_solovay_kitaev.py
incorrectly states that TranspilerError is raised when a gate lacks to_matrix,
but the implementation silently continues for such gates; update the docstring
(or remove the Raises section) to reflect the actual behavior by removing the
TranspilerError claim and explaining that gates without a to_matrix method are
skipped, referencing the to_matrix check and TranspilerError symbol so reviewers
can locate the change.
- Around line 68-72: The code directly accesses the private attribute self._sk
and calls self._sk.run(...) then uses dag.substitute_node_with_dag(...); add a
clear FIXME comment above this usage that explains why accessing self._sk is
necessary (e.g., to call the Solovay–Kitaev implementation for approximation)
and include a removal trigger note "Remove once qiskit minimum version is bumped
to 2.0.0" so future maintainers know when to refactor; keep the comment adjacent
to the lines invoking self._sk, reference self._sk, _sk.run, recursion_degree
and dag.substitute_node_with_dag in the comment, and don’t change behavior—this
is purely documentation for the fragile private-attribute dependency.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/mqt/bench/benchmarks/shors_nine_qubit_code.py`:
- Around line 306-313: The current validation only checks divisibility by 17 and
allows invalid values like 0 or negative multiples; update the guard around
num_qubits so it requires num_qubits to be a positive multiple of 17 (e.g.,
num_qubits >= 17 and num_qubits % 17 == 0) and raise a clear ValueError
otherwise; adjust the existing validation block that computes num_logical_qubits
and calls _create_single_logical_qubit_circuit to rely on this stricter check.

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.

✨ Shor's 9-qubit code

1 participant