Skip to content

Add AlphaSyndrome measurement strategy (arXiv:2601.12509)#422

Merged
perlinm merged 84 commits intomainfrom
alphasyndrome
Mar 28, 2026
Merged

Add AlphaSyndrome measurement strategy (arXiv:2601.12509)#422
perlinm merged 84 commits intomainfrom
alphasyndrome

Conversation

@acasta-yhliu
Copy link
Copy Markdown
Collaborator

@acasta-yhliu acasta-yhliu commented Feb 19, 2026

This is a local merge request for #421 to make modifications easier.

I've implemented the AlphaSyndrome syndrome measurement scheduler. A few notes:

  • Implemented under src/qLDPC/circuits/alphasyndrome.py.
  • Implemented test
  • Multiprocessing is not introduced. I've encountered OOM because Python would copy the data of the parent process.

Some other things to be checked:

  • Copyright information
  • Coding style

@acasta-yhliu
Copy link
Copy Markdown
Collaborator Author

I've moved to a local branch to make changes easier.

uv.lock is removed.

Please check the pyproject.toml when merging.

@perlinm
Copy link
Copy Markdown
Collaborator

perlinm commented Mar 26, 2026

@acasta-yhliu maybe you know a nice example to show off in the notebook?

When building evaluation circuit with noise and invoke self.noise_model.noisy_circuit at line 181, immune_qubits set to data qubits will cause no noise appended to the circuit. This behavior is not expected.
@acasta-yhliu
Copy link
Copy Markdown
Collaborator Author

Ok, I've located the bug. At alpha_syndrome.py, lines 181-183:

Previously, the code was:

181 noisy_evaluation_circuit = self.noise_model.noisy_circuit(
182    evaluation_circuit, immune_qubits=range(code.num_qubits), insert_ticks=False
183 )

Notice immune_qubits are set to all data qubits. However, this causes all interaction gates with ancilla qubits to have no noise appended to them. As the only noise sources are $CX$ and $CZ$s, the circuit becomes noiseless. I've changed it to:

181 noisy_evaluation_circuit = self.noise_model.noisy_circuit(
182    evaluation_circuit, insert_ticks=False
183 )

But I still want to learn how to only make data qubits immune to noise, while performing $CX$ or $CZ$s, ancillas still get noise.

I've also changed the example to the Steane code. Seems on the surface code, the EdgeColoring already performs pretty well, even when I increase the code distance and AlphaSyndrome searching parameters.

@perlinm
Copy link
Copy Markdown
Collaborator

perlinm commented Mar 27, 2026

Good catch! While the example does show a benefit from AlphaSyndrome, it's a bit awkward that there is no pseudothreshold. I'll try with a different decoder...

In the meantime, regarding this:

But I still want to learn how to only make data qubits immune to noise, while performing CX or CZs, ancillas still get noise.

Unfortunately, I'm not sure this is possible at the moment. I filed it as a new issue. I see two avenues for supporting such capability:

  1. Allowing NoiseRule to depend on the target qubits of a gate (it currently only depends on the gate name).
  2. Replacing, say, DEPOLARIZE2 and PAULI_CHANNEL_2 noise with appropriate DEPOLARIZE1 and PAULI_CHANNEL_1 instructions.

Option 2 is nice because it allows users to still use built-in noise models. Option 1 is nice because it allows for, say, non-uniform noise models (e.g., if some qubits are noisier than others). So maybe we should have both capabilities.

@acasta-yhliu
Copy link
Copy Markdown
Collaborator Author

Yes, I think the only tricky thing is to decide the behavior of, for example:

q1 is immune, q2 is not, when performing CX q1 q2, what noise should we apply.

@perlinm
Copy link
Copy Markdown
Collaborator

perlinm commented Mar 27, 2026

q1 is immune, q2 is not, when performing CX q1 q2, what noise should we apply.

The easy answer (currently used by a NoiseModel in qLDPC) is to apply no noise after CX q1 q2. Another reasonable (and probably better) answer is to exclude Pauli errors that affect qubit q1. So DEPOLARIZE2(p) q1 q2 would become DEPOLARIZE1(p * 3 / 15) q2, where the rescaling of p -> p * 3 / 15 is to preserve the likelihood of single-qubit errors on q2. A PAULI_CHANNEL_2 would similarly become a PAULI_CHANNEL_1 that keeps only those errors that affect only qubit q2.

@acasta-yhliu
Copy link
Copy Markdown
Collaborator Author

The easy answer (currently used by a NoiseModel in qLDPC) is to apply no noise.

This is the current behavior.

Another reasonable (and probably better) answer is to exclude Pauli errors that affect qubit q1. So DEPOLARIZE2(p) q1 q2 would become DEPOLARIZE1(p * 3 / 15) q2, where the rescaling of p -> p * 3 / 15 is to preserve the likelihood of single-qubit errors on q2. A PAULI_CHANNEL_2 would similarly become a PAULI_CHANNEL_1 that keeps only those errors that affect only qubit q2.

I would prefer this one in the sense of software engineering, as it still allows the user to fully immunize both qubits q1 and q2 (by including both in the immune set)

@perlinm
Copy link
Copy Markdown
Collaborator

perlinm commented Mar 27, 2026

Fully agree that the second answer is preferred 🙂. Do you want to tackle #426?

@perlinm
Copy link
Copy Markdown
Collaborator

perlinm commented Mar 27, 2026

The Steane code example with MWPM seems to be unstable: it sometimes produces a DEM with a non-matchable Tanner graph. So we are still seeking a good example to showcase AlphaSyndrome.

If we really struggle to find a good example (in, say, a runtime of at most a few hours), we can merge without one. The example is desirable though because it would boost interest this feature (and in arxiv:2601.12509).

@acasta-yhliu
Copy link
Copy Markdown
Collaborator Author

I feel the Steane code is the only one I have found right now. I want to stick to MWPM to make the experiment short. Maybe when the immune_qubits behavior changes, things would get better. Right now, the evaluation circuit only calculates the logical error rate caused by the hook error, but appending noise to the data qubits may disturb this.

Comment thread examples/logical_error_rates/5_alpha_syndrome.ipynb Outdated
@perlinm
Copy link
Copy Markdown
Collaborator

perlinm commented Mar 27, 2026

Maybe when the immune_qubits behavior changes, things would get better.

I see. I added this as an addendum to #426 then.

@perlinm perlinm self-requested a review March 28, 2026 17:00
Copy link
Copy Markdown
Collaborator

@perlinm perlinm left a comment

Choose a reason for hiding this comment

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

Looks good! It would still be nice to have a more "real" example with a pseudothreshold, but it may be out of reach with small runtimes. Maybe #426 will help.

@perlinm perlinm merged commit 19ee7a8 into main Mar 28, 2026
3 checks passed
@perlinm perlinm deleted the alphasyndrome branch March 28, 2026 17:02
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.

2 participants