Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug Report: Logical Error Rates with PAULI_CHANNEL_2 #103

Open
rsnegrin opened this issue Aug 27, 2024 · 0 comments
Open

Bug Report: Logical Error Rates with PAULI_CHANNEL_2 #103

rsnegrin opened this issue Aug 27, 2024 · 0 comments

Comments

@rsnegrin
Copy link

Description

I had an issue when using PyMatching decoder with circuits that include a PAULI_CHANNEL_2 gate in the Stim framework.

Code

Expand to see the code
import stim
import sinter
import os

p_r = 1e-6
p_cnot = 0.1
p2 = [
    p_cnot,  # p_ix
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
]

# Circuit with X_ERROR
circ1 = stim.Circuit()
circ1.append("R", range(3))
circ1.append("X_ERROR", range(3), p_r)
circ1.append("TICK")
circ1.append("CX", [0, 1])
circ1.append("X_ERROR", 1, p_cnot)
circ1.append("TICK")
circ1.append("CX", [2, 1])
circ1.append("X_ERROR", 1, p_cnot)
circ1.append("TICK")
circ1.append("M", range(3))

circ1.append("DETECTOR", [stim.target_rec(-3 + 1)], (1, 0))
circ1.append(
    "DETECTOR",
    [stim.target_rec(-3 + 0), stim.target_rec(-3 + 1), stim.target_rec(-3 + 2)],
    (0, 0),
)
circ1.append("OBSERVABLE_INCLUDE", [stim.target_rec(-1)], 0)

# Circuit with PAULI_CHANNEL_2
circ2 = stim.Circuit()
circ2.append("R", range(3))
circ2.append("X_ERROR", range(3), p_r)
circ1.append("TICK")
circ2.append("CX", [0, 1])
circ2.append("PAULI_CHANNEL_2", [0, 1], p2)
circ1.append("TICK")
circ2.append("CX", [2, 1])
circ2.append("PAULI_CHANNEL_2", [2, 1], p2)
circ1.append("TICK")
circ2.append("M", range(3))

circ2.append("DETECTOR", [stim.target_rec(-3 + 1)], (1, 0))
circ2.append(
    "DETECTOR",
    [stim.target_rec(-3 + 0), stim.target_rec(-3 + 1), stim.target_rec(-3 + 2)],
    (0, 0),
)
circ2.append("OBSERVABLE_INCLUDE", [stim.target_rec(-1)], 0)

tasks = [
    sinter.Task(circuit=circ, json_metadata={"i": i})
    for i, circ in enumerate([circ1, circ2])
]
results = sinter.collect(
    num_workers=os.cpu_count(),
    tasks=tasks,
    decoders=["pymatching"],
    max_shots=10_000_000,
    max_errors=None,
)
results.sort(key=lambda x: x.json_metadata["i"])

logical_error_rate1 = results[0].errors / results[0].shots
logical_error_rate2 = results[1].errors / results[1].shots
print(f"Logical error X_ERROR: {logical_error_rate1}")
print(f"Logical error PAULI_CHANNEL_2: {logical_error_rate2}")

Both circuits should be equivalent with the difference that one uses X_ERROR and the other PAULI_CHANNEL_2 to represent the same error.

Output

Here es an example of the output:

  • Logical error X_ERROR: 1.5e-06
  • Logical error PAULI_CHANNEL_2: 0.1799395

When using PAULI_CHANNEL_2 , I need to set approximate_disjoint_errors=True to be able to run the simulations. Sinter also sets decompose_errors=True as default (details).

Here is the detector error model when using the PAULI_CHANNEL_2:

circ2.detector_error_model(decompose_errors=True, approximate_disjoint_errors=True)

# Output:
stim.DetectorErrorModel('''
    error(1e-06) D0
    error(1e-06) D0 D1
    error(1e-06) D0 L0
    error(0.1) D1 L0 ^ D0 L0
    error(0.1) D1 ^ D0
    detector(1, 0) D0
    detector(0, 0) D1
''')

Other decoders like Fusion Blossom don’t have this problem and give similar results for both circuits. Also, the issue is not limited to X_ERROR, since I initially encountered this with Z_ERROR.

I'm not sure about the exact source of this problem, but it would be good to evaluate.
Thanks !

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

No branches or pull requests

1 participant