Skip to content

Fix CommutativeCancellation dropping negative X-rotation sums#16605

Closed
ashishpatel26 wants to merge 1 commit into
Qiskit:mainfrom
ashishpatel26:fix/issue-16594-commutative-cancellation-sxdg
Closed

Fix CommutativeCancellation dropping negative X-rotation sums#16605
ashishpatel26 wants to merge 1 commit into
Qiskit:mainfrom
ashishpatel26:fix/issue-16594-commutative-cancellation-sxdg

Conversation

@ashishpatel26

@ashishpatel26 ashishpatel26 commented Jul 17, 2026

Copy link
Copy Markdown

Summary

Fixes #16594

CommutativeCancellation removed a commuting pair of sxdg gates as if they were the identity, even though sxdg·sxdg = X (up to global phase), producing wrong results at optimization_level ≥ 2.

Details and comments

Root cause: in crates/transpiler/src/passes/commutation_cancellation.rs, the sx resynthesis branch computes the number of SX gates to insert as (num_sx as i64) % 4. Rust's % returns a negative remainder for negative inputs (e.g. two sxdg give a combined angle of −π → num_sx = −2-2 % 4 == -2), so the insertion loop 0..-2 ran zero times and the rotation vanished.

Fix: use rem_euclid(4). Since SX⁴ == I exactly (RX(2π)·e^{iπ} = (−I)·(−1) = I), inserting num_sx.rem_euclid(4) gates is algebraically identical to inserting num_sx, and the existing global-phase bookkeeping stays exact. The neighbouring X branch is safe for negative angles: a single X with phase −π/2·num_x is exact for every odd num_x, positive or negative.

Added a regression test with the issue reproducer plus a parametrized test over other negative-sum sequences (sxdg×3, sxdg×4, sxdg·x·sxdg), and a release note.

Test evidence: issue reproducer now folds to sx×3 with Operator.equiv == True; full-transpile check equivalent at O1 and O3; test_commutative_cancellation.py 66 passed + 28 subtests; adjacent suites (test_commutation_analysis, test_commutative_inverse_cancellation, test_optimize_1q_decomposition) 191 passed; 300-circuit random fuzz over x/sx/sxdg/rx sequences with exact-π angles: 0 non-equivalent outputs.

When a set of commuting X-axis rotations summed to a negative angle that
was an odd multiple of pi/2 (or -pi), the sx resynthesis loop computed
the gate count with Rust's remainder operator, which returns a negative
value for negative inputs. The insertion loop then ran zero times and
the rotation was removed entirely, producing a non-equivalent circuit.
Use Euclidean remainder instead; SX**4 == I exactly, so inserting
num_sx.rem_euclid(4) gates is algebraically identical.

Fixes Qiskit#16594
@ashishpatel26
ashishpatel26 requested a review from a team as a code owner July 17, 2026 11:37
@ashishpatel26
ashishpatel26 requested a review from raynelfss July 17, 2026 11:37
@qiskit-bot qiskit-bot added the Community PR PRs from contributors that are not 'members' of the Qiskit repo label Jul 17, 2026
@qiskit-bot

Copy link
Copy Markdown
Collaborator

Thank you for opening a new pull request.

Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient.

While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone.

One or more of the following people are relevant to this code:

  • @Qiskit/terra-core

@jakelishman

Copy link
Copy Markdown
Member

Thanks for the interest. Unfortunately, this is a duplicate of #16599.

Also: please take care that you are following the contributing guide. I believe this to be an unsupervised LLM PR in violation of the guide. These are not useful to us.

@ashishpatel26
ashishpatel26 deleted the fix/issue-16594-commutative-cancellation-sxdg branch July 17, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Community PR PRs from contributors that are not 'members' of the Qiskit repo

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

CommutativeCancellation cancels an sxdg·sxdg pair that equals X, giving wrong results at optimization_level ≥ 2

3 participants