Summary
The SLR Stim backend compiles an If statement by emitting its body
unconditionally. The condition is discarded. For a body containing quantum
gates this is a silent miscompile: the generated Stim circuit applies gates
that the source program applies only on some measurement outcomes.
_process_if in python/quantum-pecos/src/pecos/slr/ast/codegen/stim.py:403
appends a TICK, then processes every statement in the then-body, then, if an
else-body exists, appends another TICK and processes every statement in that
too. So an if/else emits both arms.
Why this is wrong rather than a documented limitation
Three things make the current behaviour indefensible as a limitation.
The adjacent handler was deliberately changed to fail loud for exactly this
reason. _process_while, fifteen lines below at stim.py:416, raises
NotImplementedError and its docstring states the reasoning: "The previous
'process body once + TICK' silently dropped the loop condition and all
iterations -- a miscompile. Fail LOUD instead." The if handler is the same
class of defect, left in place.
The premise in the code comment is false. The comment reads "Stim doesn't
directly support conditionals". Stim supports measurement-conditioned Pauli
gates through record targets, which is the dominant real use of a conditional
in a QEC program. Confirmed by execution:
import stim
c = stim.Circuit("R 0 1\nH 0\nM 0\nCX rec[-1] 1\nM 1")
rows = c.compile_sampler().sample(shots=8)
# every row has m0 == m1: the X on qubit 1 fires only when m0 is 1
So for a Pauli body conditioned on a measurement the backend could compile
faithfully rather than approximate.
A sibling backend already does it properly. The QIR backend's
_process_if at qir.py:1028 evaluates the predicate and emits a real
if_else branch.
The test pins the defect
test_if_statement_adds_tick in
python/quantum-pecos/tests/pecos/slr/ast_tests/test_ast_codegen_stim.py:250
asserts both "TICK" in code and "H 0" in code. The second assertion locks
in the unconditional emission, and the docstring repeats the false premise:
"conditionals unsupported in Stim". Any fix has to reclassify that
expectation.
Impact
A measurement-conditioned Pauli correction is the standard shape of a
teleportation byproduct correction, a Knill or Steane QEC cycle correction,
and an injection correction. Compiled through this backend, every such
correction is applied on all shots, so it is wrong on roughly half of them.
Nothing warns.
Suggested resolution
Compile the case the format supports, and refuse the rest loudly rather than
approximating it. A then-body of Pauli gates conditioned on a measurement
comparison lowers to Stim's classically controlled Paulis with the appropriate
record target. Anything else, including a non-Pauli body or an else-body,
takes the _process_while treatment and raises.
Found while reviewing where an injection correction should be applied, as part
of the surface gadget library work. It is independent of that question.
Summary
The SLR Stim backend compiles an
Ifstatement by emitting its bodyunconditionally. The condition is discarded. For a body containing quantum
gates this is a silent miscompile: the generated Stim circuit applies gates
that the source program applies only on some measurement outcomes.
_process_ifinpython/quantum-pecos/src/pecos/slr/ast/codegen/stim.py:403appends a
TICK, then processes every statement in the then-body, then, if anelse-body exists, appends another
TICKand processes every statement in thattoo. So an
if/elseemits both arms.Why this is wrong rather than a documented limitation
Three things make the current behaviour indefensible as a limitation.
The adjacent handler was deliberately changed to fail loud for exactly this
reason.
_process_while, fifteen lines below atstim.py:416, raisesNotImplementedErrorand its docstring states the reasoning: "The previous'process body once + TICK' silently dropped the loop condition and all
iterations -- a miscompile. Fail LOUD instead." The
ifhandler is the sameclass of defect, left in place.
The premise in the code comment is false. The comment reads "Stim doesn't
directly support conditionals". Stim supports measurement-conditioned Pauli
gates through record targets, which is the dominant real use of a conditional
in a QEC program. Confirmed by execution:
So for a Pauli body conditioned on a measurement the backend could compile
faithfully rather than approximate.
A sibling backend already does it properly. The QIR backend's
_process_ifatqir.py:1028evaluates the predicate and emits a realif_elsebranch.The test pins the defect
test_if_statement_adds_tickinpython/quantum-pecos/tests/pecos/slr/ast_tests/test_ast_codegen_stim.py:250asserts both
"TICK" in codeand"H 0" in code. The second assertion locksin the unconditional emission, and the docstring repeats the false premise:
"conditionals unsupported in Stim". Any fix has to reclassify that
expectation.
Impact
A measurement-conditioned Pauli correction is the standard shape of a
teleportation byproduct correction, a Knill or Steane QEC cycle correction,
and an injection correction. Compiled through this backend, every such
correction is applied on all shots, so it is wrong on roughly half of them.
Nothing warns.
Suggested resolution
Compile the case the format supports, and refuse the rest loudly rather than
approximating it. A then-body of Pauli gates conditioned on a measurement
comparison lowers to Stim's classically controlled Paulis with the appropriate
record target. Anything else, including a non-Pauli body or an else-body,
takes the
_process_whiletreatment and raises.Found while reviewing where an injection correction should be applied, as part
of the surface gadget library work. It is independent of that question.