Repository navigation
Description
Problem
Exporting an accepted multi-qubit measurement condition to OpenQASM 2 changes which branch executes. Cirq treats the first measured bit as the most significant bit of the measurement-key integer, while the exporter writes it to classical-register index 0, the least significant bit in OpenQASM 2. The equality constant is emitted unchanged.
Reproduction
import cirq
import sympy
from cirq.contrib.qasm_import import circuit_from_qasm
q0, q1, out = cirq.LineQubit.range(3)
circuit = cirq.Circuit(
cirq.X(q0),
cirq.measure(q0, q1, key="m"),
cirq.X(out).with_classical_controls(sympy.Eq(sympy.Symbol("m"), 2)),
cirq.measure(out, key="out"),
)
text = cirq.qasm(circuit)
print(text)
print("source:", cirq.Simulator().run(circuit).records["out"].tolist())
print("exported:", cirq.Simulator().run(circuit_from_qasm(text)).records["m_out_0"].tolist())Output includes:
measure q[0] -> m_m[0];
measure q[1] -> m_m[1];
if (m_m==2) x q[2];source: [[[1]]]
exported: [[[0]]]
The source measurement is [1, 0], so the Cirq condition m == 2 is true and the output should be 1. In the emitted QASM, m_m[0] = 1 and m_m[1] = 0 mean integer 1, making the emitted condition false. This is observable directly from the emitted text using the OpenQASM 2 specification, page 7, which defines index zero as the low-order bit; it does not require assuming general round-trip support.
Expected behavior and checks
The emitted program should preserve the accepted source condition's meaning, or explicitly reject an unsupported case.
I also checked the asymmetric [0, 1] / m == 1 case (source 1, exported 0), and [1, 0] / m == 1 (source 0, exported 1). The all-ones [1, 1] / m == 3 and a single-bit condition are preserved. Separately hand-written QASM with the same register assignments executes according to the specification in the importer, pointing to the export-side mapping.
MeasurementGate._qasm_ assigns measurement position i to register index i; SympyCondition._qasm_ emits the equality constant unchanged. These two source files on current main were inspected on 2026-11-13 and match the installed files. Current main as a whole was not executed.
Related #7624 concerns exporting an imported register condition represented by multiple Cirq keys. This example starts with one native multi-bit measurement and one supported SympyCondition, successfully exports it once, and changes the guard's meaning in that first output.
Environment: Cirq 1.8.0.dev20261111222613, Python 3.12.13, macOS arm64. AI assistance was used to prepare this report; the code above was executed in the stated environment. No patch is included.
Activity