I'm trying to create a custom stim surface code circuit where I measure both x and z stabilizers each round. This is different from the default stim surface code circuits since the default circuits only measure one stabilizer type in the first and last round (whichever is the logical operator). Measuring both types in the last round is no problem, but when trying to measure both stabilizer types in the first round, issues occur when converting the circuit to a detector error model (DEM).
Each time I try to measure the x-stabilizers in the first round, a ValueError is raised reporting "The circuit contains non-deterministic detectors," and goes on to say some detectors anti-commute. The exact collapse that causes this depends on the CX ordering (tracebacks below). This can be worked around by removing the x-stabilizer measurements in the first round of measurements, like in the default circuit provided by stim, but I don't understand why the DEM acts this way. In my looking at these circuits and the corresponding tableaus, I just can't see why the either a data qubit is detected as a detector, or stabilizers are seen to anti-commute. While the workaround is workable, I'd like to understand why this is happening.
As added context, at the bottom I will copy and paste a circuit that follows the default circuit CX ordering for a distance 3 surface code. Using this and a couple other CX orderings, the last x-stabilizer in the first round is reported to anti-commute with the last data qubit. Here is the traceback:
ValueError: The circuit contains non-deterministic detectors.
(To allow non-deterministic detectors, use the `allow_gauge_detectors` option.)
This was discovered while analyzing a Z-basis reset (R) on:
qubit 8 [coords (5, 5)]
The collapse anti-commuted with these detectors/observables:
D7 [coords (4, 6, 0)]
The backward-propagating error sensitivity for D7 was:
X5 [coords (3, 5)]
X8 [coords (5, 5)]
Circuit stack trace:
during TICK layer #1 of 16
at instruction #18 [which is R 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
While with any other CX ordering (at least the several I tried), the last Z and X stabilizers are reported to anti-commute:
ValueError: The circuit contains non-deterministic detectors.
(To allow non-deterministic detectors, use the `allow_gauge_detectors` option.)
This was discovered while analyzing a Z-basis demolition measurement (MR) on:
qubit 16 [coords (4, 6)]
The collapse anti-commuted with these detectors/observables:
D10 [coords (4, 4, 1)]
The backward-propagating error sensitivity for D10 was:
Z4 [coords (3, 3)]
Z5 [coords (3, 5)]
Z7 [coords (5, 3)]
Z8 [coords (5, 5)]
Z11 [coords (4, 4)]
X14 [coords (2, 4)]
X15 [coords (4, 2)]
X16 [coords (4, 6)]
Circuit stack trace:
during TICK layer #8 of 16
at instruction #41 [which is MR 9 10 11 12 13 14 15 16]
And as promised, here is the circuit (with the default CX ordering). Indexes 0-8 are data qubits, 9-12 z-stabilizers, and 13-16 x-stabilizers:
QUBIT_COORDS(1, 1) 0
QUBIT_COORDS(1, 3) 1
QUBIT_COORDS(1, 5) 2
QUBIT_COORDS(3, 1) 3
QUBIT_COORDS(3, 3) 4
QUBIT_COORDS(3, 5) 5
QUBIT_COORDS(5, 1) 6
QUBIT_COORDS(5, 3) 7
QUBIT_COORDS(5, 5) 8
QUBIT_COORDS(0, 4) 9
QUBIT_COORDS(2, 2) 10
QUBIT_COORDS(4, 4) 11
QUBIT_COORDS(6, 2) 12
QUBIT_COORDS(2, 0) 13
QUBIT_COORDS(2, 4) 14
QUBIT_COORDS(4, 2) 15
QUBIT_COORDS(4, 6) 16
R 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
X_ERROR(0.001) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
TICK
DEPOLARIZE1(0.001) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
H 13 14 15 16
DEPOLARIZE1(0.001) 13 14 15 16
TICK
CX 2 9 4 10 8 11 13 3 14 5 15 7
DEPOLARIZE2(0.001) 2 9 4 10 8 11 13 3 14 5 15 7
TICK
CX 1 9 3 10 7 11 13 0 14 2 15 4
DEPOLARIZE2(0.001) 1 9 3 10 7 11 13 0 14 2 15 4
TICK
CX 1 10 5 11 7 12 14 4 15 6 16 8
DEPOLARIZE2(0.001) 1 10 5 11 7 12 14 4 15 6 16 8
TICK
CX 0 10 4 11 6 12 14 1 15 3 16 5
DEPOLARIZE2(0.001) 0 10 4 11 6 12 14 1 15 3 16 5
TICK
H 13 14 15 16
DEPOLARIZE1(0.001) 13 14 15 16
TICK
X_ERROR(0.001) 9 10 11 12 13 14 15 16
MR 9 10 11 12 13 14 15 16
X_ERROR(0.001) 9 10 11 12 13 14 15 16
TICK
DETECTOR(0, 4, 0) rec[-8]
DETECTOR(2, 2, 0) rec[-7]
DETECTOR(4, 4, 0) rec[-6]
DETECTOR(6, 2, 0) rec[-5]
DETECTOR(2, 0, 0) rec[-4]
DETECTOR(2, 4, 0) rec[-3]
DETECTOR(4, 2, 0) rec[-2]
DETECTOR(4, 6, 0) rec[-1]
REPEAT 2 {
DEPOLARIZE1(0.001) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
H 13 14 15 16
DEPOLARIZE1(0.001) 13 14 15 16
TICK
CX 2 9 4 10 8 11 13 3 14 5 15 7
DEPOLARIZE2(0.001) 2 9 4 10 8 11 13 3 14 5 15 7
TICK
CX 1 9 3 10 7 11 13 0 14 2 15 4
DEPOLARIZE2(0.001) 1 9 3 10 7 11 13 0 14 2 15 4
TICK
CX 1 10 5 11 7 12 14 4 15 6 16 8
DEPOLARIZE2(0.001) 1 10 5 11 7 12 14 4 15 6 16 8
TICK
CX 0 10 4 11 6 12 14 1 15 3 16 5
DEPOLARIZE2(0.001) 0 10 4 11 6 12 14 1 15 3 16 5
TICK
H 13 14 15 16
DEPOLARIZE1(0.001) 13 14 15 16
TICK
X_ERROR(0.001) 9 10 11 12 13 14 15 16
MR 9 10 11 12 13 14 15 16
X_ERROR(0.001) 9 10 11 12 13 14 15 16
TICK
SHIFT_COORDS(0, 0, 1)
DETECTOR(0, 4, 0) rec[-8] rec[-16]
DETECTOR(2, 2, 0) rec[-7] rec[-15]
DETECTOR(4, 4, 0) rec[-6] rec[-14]
DETECTOR(6, 2, 0) rec[-5] rec[-13]
DETECTOR(2, 0, 0) rec[-4] rec[-12]
DETECTOR(2, 4, 0) rec[-3] rec[-11]
DETECTOR(4, 2, 0) rec[-2] rec[-10]
DETECTOR(4, 6, 0) rec[-1] rec[-9]
}
X_ERROR(0.001) 0 1 2 3 4 5 6 7 8
M 0 1 2 3 4 5 6 7 8
OBSERVABLE_INCLUDE(0) rec[-3] rec[-6] rec[-9]