Skip to content

QASM export changes multi-qubit SympyCondition equality through classical bit order #8530

Open

Description

@haonanren888

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

  1. locked and limited conversation to collaborators on Nov 13, 2026
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

    triage/discussNeeds decision / discussion, bring these up during Cirq Cynque

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions