Sitelet https://github.com/PECOS-packages/PECOS/issues/978
Skip to content

SLR Stim backend compiles If by emitting the body unconditionally, discarding the condition #978

Description

@ciaranra

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpythonPull requests that update python codeseverity:criticalSilently wrong results, data loss, or security exposure

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions