Skip to content

Preserve exact rotations in Clifford+T rebasing - #429

Merged
TheGupta2012 merged 3 commits into
qBraid:mainfrom
danielgaskins:fix/clifford-t-rotations
Sep 24, 2026
Merged

TheGupta2012 merged 3 commits into
qBraid:mainfrom
danielgaskins:fix/clifford-t-rotations

Conversation

@danielgaskins

Copy link
Copy Markdown
Contributor

Closes #428

Summary of changes

  • Decompose rx, ry, and rz rotations at multiples of π/4 into exact Clifford+T sequences
  • Raise RebaseError for unsupported angles instead of silently dropping the gate
  • Add QASM 2 and QASM 3 coverage for positive, negative, periodic, zero, unsupported, and conditional rotations

Signed-off-by: Daniel Gaskins <danielgaskins99@gmail.com>
@argus-eye

argus-eye Bot commented Sep 20, 2026

Copy link
Copy Markdown

Argus review

Auto-review is off for this repo. Tick the box below to run a review on this PR.

  • Trigger Argus review

Estimated cost

  • Files changed: 3
  • Diff lines (±): 182
  • Historical avg: ~317.3k tokens · ~$1.35 · across last 12 review(s)

Tip: you can also comment @argus-eye review at any time.

@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: qBraid/pyqasm/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: a4a7811f-436d-47d9-8b58-d8c5f738d6a3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@ryanhill1 ryanhill1 left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this — I checked the decompositions numerically: rx/ry/rz across n = -16..16 quarter-turns all match the exact rotation up to global phase, and crx/cry stay correct through the controlled path, where that global phase would otherwise become a relative one. Suite, pylint, mypy, black and isort green locally; CI green.

Two notes. N1 is inline.

N2 — please add a CHANGELOG entry under Fixed, referencing #428. It's user-visible in both directions: gates that were silently dropped now decompose, and angles that previously produced output now raise RebaseError — anyone upgrading needs the second half.

Comment thread src/pyqasm/decomposer.py
if normalized_turns == 0:
return []

if normalized_turns <= 4:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

N1 — the two-gate branches here are never exercised.

I instrumented _get_clifford_t_rotation and ran the suite: normalized_turns only ever takes 0, 1, 2 and 7. That leaves 3, 4, 5 and 6 untested — including both composite sequences, n=3 -> s; t; and n=5 -> sdg; tdg;, which is exactly where an off-by-one in the // 2 / % 2 split would hide. Every currently tested case is single-gate or empty. Could you add rz(3*pi/4) and rz(5*pi/4)?

Separately, the tests assert gate strings rather than equivalence — swap s for sdg in the ry sequence and the suite still passes once the expected string is edited to match. One test that reconstructs the unitary and compares it to the exact rotation up to global phase would guard the whole table at once, and numpy is already a dependency. I verified the table is correct today (99/99 over n = -16..16, plus crx/cry through the controlled path), so this is about keeping it that way rather than anything being wrong now.

@danielgaskins

Copy link
Copy Markdown
Contributor Author

Thanks for checking this. I added the rz(3*pi/4) and rz(5*pi/4) cases, plus a numerical check of all eight quarter turns for rx, ry, and rz. I also added the changelog entry for #428. The full test suite and lint checks pass.

@ryanhill1 ryanhill1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good from my end. I'll let @TheGupta2012 give final sign off before merge.

@TheGupta2012
TheGupta2012 merged commit a48b431 into qBraid:main Sep 24, 2026
14 checks passed
TheGupta2012 added a commit that referenced this pull request Sep 25, 2026
v1.2.1 shipped on 23 September 2026 carrying five Unreleased entries: three
under Added (#370, #368, #427) and two under Other (#419). Those are removed
and v1.2.1 joins the Past Release Notes list.

Two entries stay, because they merged after the v1.2.1 tag and have not
shipped: the `end;` statement support from #424 under Added, and the Clifford+T
rotation fix from #429 under Fixed. They belong to the next release.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

[BUG] rebase(BasisSet.CLIFFORD_T) silently drops rx/ry/rz gates

4 participants