Skip to content

Fail loudly on unknown gate types in with_noise and Stim export; add RXYXY2Q - #809

Open
ciaranra wants to merge 1 commit into
devfrom
python-gate-wildcards-fail-loud
Open

ciaranra wants to merge 1 commit into
devfrom
python-gate-wildcards-fail-loud

Conversation

@ciaranra

Copy link
Copy Markdown
Member

Closes #802.

Problem

Two Python-facing gate classifiers ended in a wildcard that silently ignored any gate type not on a hand-written list:

  • TickCircuit.with_noise (dag_circuit_bindings.rs) gave no two-qubit noise to RXYXY2Q, RXXRYYRZZ, U2q, CH, and no preparation noise to PX.
  • tick_circuit_to_stim dropped unknown gates from the exported Stim circuit, so the Stim DEM described a different circuit from the one simulated. Exporting RXYXY2Q(pi, 0) produced an empty program.

Change

  • New GateNoiseKind and gate_noise_kind in pecos-qec's propagator.rs, next to the predicates they read (is_supported_prep_gate, is_supported_noop_or_metadata_gate, GateType::is_single_qubit / is_two_qubit, consumes_measurement_record). Buckets: Prep, Single, Two, Measurement, Transparent, Error. I and Idle keep their single-qubit noise; Custom and CCX are Error.
  • with_noise classifies through it and raises ValueError on an Error gate whenever any rate is non-zero. PX preparation noise is a Z flip (Dephasing), matching mem_builder.rs; PZ/QAlloc keep BitFlip.
  • is_supported_noop_or_metadata_gate is exposed to Python, and _gate_to_stim uses it for its transparent set, raises on anything else unknown, and lowers Clifford RXYXY2Q (SQRT_XX/SQRT_YY, their daggers, and X X/Y Y at theta = pi, all with one two-qubit noise channel).
  • An exhaustive u8 test over GateType pins every variant to exactly one bucket, so a future variant that fits none fails. It lives in pecos-qec because pecos-rslib unit tests are excluded from CI (pecos-rslib Rust unit tests are excluded from CI and 11 of them fail on dev #806).

Behaviour changes for existing circuits, all intended: PX gains Z preparation noise; CH, RXXRYYRZZ, U2q, RXYXY2Q gain two-qubit noise; CCX and Custom raise when noise is active (with all rates zero they still pass through). The core rule that a circuit already containing channel operations is rejected by with_noise is unchanged.

Tests

39 new Python tests in tests/qec/test_tick_circuit_gate_classification.py plus the exhaustive Rust guard. Mutation-checked: restoring either wildcard, routing CCX to Two, swapping the Stim axis or SQRT/DAG, and accepting a non-Clifford phi each fail a test.

Verification

cargo test -p pecos-qec (1101 passed), cargo clippy --locked -p pecos-qec -p pecos-rslib --all-targets -- -D warnings, cargo fmt --check, just python-ci-build-test, the new test file (39 passed) plus the wider -k "stim or with_noise or tick_circuit or rxyxy2q" selection (237 passed), and just python-ci-lint, all clean.

How this was produced

Implemented by OpenAI gpt-6-astra (Codex CLI 0.154.0) from a task packet written by Claude Fable 5.1 in Claude Code; Claude reviewed every hunk, re-ran all verification itself, and sent findings back for fix rounds. An independent Codex review arm with no access to the implementation session also reviewed the diff. Posted at the maintainer's request.

@ciaranra
ciaranra force-pushed the python-gate-wildcards-fail-loud branch from d15b5b0 to 2f5d9b9 Compare September 20, 2026 05:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python noise and Stim-export wildcards silently drop unknown gate types (RXYXY2Q, RXXRYYRZZ, U2q)

1 participant