# High logical error rates when implementing Lattice Surgery with Stim

I'm facing a strange issue with the logical error rate after implementing Lattice Surgery in Stim. For $$d=3$$ (I have some custom error annotations in the circuit),

Logical error rate of X-basis Lattice Surgery, XX-Observable: 0.06361
Logical error rate of X-basis Lattice Surgery, Z1-Observable: 0.00737
Logical error rate of X-basis Lattice Surgery, Z2-Observable: 0.00705
Logical error rate of X-basis Lattice Surgery, ZZ-Observable: 0.01417


There is a significant difference between these cases, and I can't understand why that would be the case. I followed all the directions in How to implement lattice surgery in stim? for the right detector annotations and for both cases, stim.Circuit.shortest_graphlike_error() returns the same value (3). I've manually gone through the circuit and made sure all detectors have been included too.

What's a good way of debugging this?

• How do your estimates vary with respect to the physical error rate? Does setting the physical error rate 10x lower changes the estimates the same way for the 4 estimates?
– AG47
Commented Apr 16 at 15:32

• Set your physical error rate very low, like 1e-4 or 1e-5, then record shots until you get one that fails. Use stim.Circuit.explain_detector_error_model_errors to look at what circuit failures caused it. This will tend to give you a low weight error, which can reveal the core of the problem.

• Increase the distance. People's instinct is to start with small cases, but in small codes everything is an edge condition and there's no slack to catch things going half-wrong vs all-wrong. Your decoder losing 1 code distance, vs losing half code distance, looks identical at $$d=3$$ but is easily differentiated at $$d=9$$.

• Asymmetrically increase distances. If you make the lattice surgery stays stitched for 10 rounds instead of 3 rounds, does the problem get better? Worse? This can reveal whether the issue is a timelike error or a spacelike error.

• Draw a detslice diagram of the observable (circuit.diagram("detslice", filter_coords=["L0"])), and just look for weird things. Is it going where you expect?

• You say shortest graphlike error has length 3. Is that actually correct, or was it correct at some point and maybe you made some "obviously safe" changes since that time? Have unit tests, that you can rerun after every change, that verify things like the graphlike distance being what is expected. I also find it a bit strange that you're only listing two observables: two-qubit parity measurements have 4 stabilizer flow generators (Z1 -> Z1, Z2 -> Z2, XX -> XX, and ZZ -> rec[0]), so you should be checking 4 things not 2 things.

• Thanks, I'll try these suggestions. I've updated the question with all 4 flow generators and I rechecked the shortest graphlike error -- it's still 3 for $d=3$. Commented Apr 16 at 15:24
• @controlfreak You still aren't checking enough things. You have two different lattice surgery operations (MXX and MZZ). MXX has has four generators, and MZZ has its own four generators. So there should be eight logical error rates. Commented Apr 16 at 15:27
• Yes, I'm only showing the error rates for the XX−>XX and the Z1−>Z1 generators for MXX. I can modify my code to check the others too, but do you think that will help figuring out what's going on? Commented Apr 16 at 17:14
• @controlfreak Yes, in general that will help. It won't always help, but it often helps. For example, given the flows you described, you currently aren't checking if the logical measurement result is correct or not. Commented Apr 16 at 17:48
• I'm sampling errors from the circuit and passing them through the explain_detector_error_model_errors() method and I'm getting this explanation for some but not all the errors: [no single circuit error had these exact symptoms]. What does this mean exactly? Commented Apr 17 at 3:17