Skip to content

Test generality with Shor [[9, 1, 3]]#2928

Open
lillian542 wants to merge 161 commits into
mainfrom
test_shor913
Open

Test generality with Shor [[9, 1, 3]]#2928
lillian542 wants to merge 161 commits into
mainfrom
test_shor913

Conversation

@lillian542

@lillian542 lillian542 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Context:

The initial implementation is limited to CSS codes with k=1 (but written with extensibility to k>1 in mind). However, in-depth testing has focused on the Steane code, since we can define a complete Clifford+T gate set for this code, and it is small enough to run on lightning.qubit with noise and validate that everything is working.

Because of this, there is a risk that we've made assumptions that are specific to the Steane code. To identify these, we would like to test with another small k=1 CSS code.

The LUT decoder is hardcoded to [7, 1, 3] right now, so we can't validate executing a circuit now - that will come later. This PR focuses on validating that compilation works as expected.

Description of the Change:

We define Shor's 9-qubit repetition code in the QecCode registry, and test that compiling with it behaves as expected.

This identified two places where we've made incorrect assumptions:

  • in the QecCode definition, the format for defining the unitary encoder is not flexible enough; it currently assumes every enocder will consist of Hadamards followed by CNOTs, rather than allowing these gates to be interspersed (or allowing additional gates)
  • in the QEC code cycle, we allocate auxiliary qubits based on the number of rows in the X-tanner graph for every repetition (including Z checks). This fails for codes like the 9-qubit Shor code where a different number of auxiliary qubits is needed for X and Z checks.

These assumptions are corrected in this PR.

Benefits:

The generality of our implementation for k=1 CSS codes is tested to some extent.

Possible Drawbacks:

  • Any assumptions that are true for Shor and Steane will not be uncovered by this
  • This code doesn't have a transversal H or S gate. This means we can't test application of T gates (requires logical S for corrections in the protocol) in quantum-->qecl-->qecp compilation, and it also means that when we get it running end-to-end with the LUT decoder, we won't be able to test that phase-flip errors are caught and corrected as expected.

Here we balance a desire for additional validation with time constraints.

[sc-119895]

@lillian542 lillian542 marked this pull request as ready for review June 9, 2026 02:44
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Hello. You may have forgotten to update the changelog!
Please edit doc/releases/changelog-dev.md on your branch with:

  • A one-to-two sentence description of the change. You may include a small working example for new features.
  • A link back to this PR.
  • Your name (or GitHub username) in the contributors section.

@lillian542 lillian542 changed the base branch from lillian542/add_t_adjoint to generate_subroutines_conditionally June 9, 2026 16:19
@lillian542 lillian542 changed the title [WIP] Test extensibility with Shor [[9, 1, 3]] Test generality with Shor [[9, 1, 3]] Jun 10, 2026
Base automatically changed from generate_subroutines_conditionally to main June 18, 2026 21:06
@codecov

codecov Bot commented Jun 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.99%. Comparing base (e72933c) to head (565e260).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2928      +/-   ##
==========================================
+ Coverage   96.97%   96.99%   +0.02%     
==========================================
  Files         166      166              
  Lines       19209    19248      +39     
  Branches     1788     1799      +11     
==========================================
+ Hits        18628    18670      +42     
+ Misses        429      427       -2     
+ Partials      152      151       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@joeycarter

Copy link
Copy Markdown
Contributor

@lillian542 It turned out that some fairly large changes were required to support the Shor code in the QEC pipeline. Below is a quick summary to help navigate the three main changes I've made:

  • Needed to support non-uniform transversal gate definitions
    • Given that the logical Pauli X is ZIIZIIZII and the logical Pauli Z is XXXIIIIII in the Shor code, this means we can also define the logical Pauli Y as YXXZIIZII.
    • This logical Pauli Y is not compatible with the current system to define a transversal gate by a single gate and its indices in the codeblock, e.g. {"x": (qecp.PauliXOp, [4, 5, 6])}.
    • I wrote a new system to handle transversal gates with more flexibility, so now we can have, for example, {"y": ("Y", "X", "X", "Z", "I", "I", "Z", "I", "I")}. I added a helper method to translate these strings into their corresponding qecp ops.
  • Needed to support non-Pauli-Z ops in the logical Pauli Z observable for the transversal measurement protocol
    • Given that the logical Pauli Z is XXXIIIIII in the Shor code, this means that our current transversal measurement protocol, which measures all codeblock qubits in the computational basis, won't work.
    • Instead, what we should be doing is measuring each codeblock qubit in the basis given by the corresponding physical Pauli op in the logical Pauli observable definition. In other words, to measure logical Pauli Z, we should measure physical codeblock qubits 0, 1, and 2 in the X basis. To do so, I've gone the route of inserting diagonalizing gates before applying the physical computational-basis measurement ops.
    • I've also removed the measurement ops on the non-identity elements in the logical Pauli definition, since I think that strictly speaking, this is not correct. Really this amounts to a PPM on the codeblock, and a measurement in the I basis is equivalent to no measurement at all.
    • As an aside, this change should make it fairly easy to support logical Pauli X and Y terminal measurements, since the protocol is essentially the same as for Pauli Z, but just swap in the desired Pauli observable definition. I've left this for a future PR, though.
  • Updated the decode-physical-measurement subroutine
    • Since we're no longer measuring each codeblock qubit, but instead only the non-identity elements in the logical Pauli observable, I had to tweak the decode-physical-measurement subroutine.
    • Before we passed in the measurement results of every codeblock qubit and picked out the bits at the indices given by the logical Pauli Z definition. This is no longer necessary since the transversal-measurement subroutine now only returns these measurement results.
    • This means that the decode subroutine can be rewritten as an XOR op applied over every element of the input tensor of bits.
    • Instead of inlining all of the XOR ops explicitly, I used the MLIR linalg.reduce op to represent these operations more compactly.

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.

3 participants