Fix OptimizeCliffordT producing non-unitarily-equivalent output when basis excludes sx/sxdg (backport #16729) - #16735
Merged
Conversation
…basis excludes sx/sxdg (#16729) * Replace S with Sdg and Sdg with S in optimization * Add regression test for OptimizeCliffordT Added regression test for OptimizeCliffordT to ensure unitary equivalence of transpiled circuits across optimization levels. * Fix bug in OptimizeCliffordT for specific basis gates Fixed a bug in OptimizeCliffordT that affected circuit equivalence for specific basis gates. The issue was due to a transcription error in the internal re-expression of a T-rotation. * Fix indentation for test_clifford_t_transpile espaçamento 196 * Shorten reno --------- Co-authored-by: Julien Gacon <gaconju@gmail.com> (cherry picked from commit 9499a6a)
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:
|
Cryoris
approved these changes
Aug 11, 2026
Cryoris
enabled auto-merge
August 11, 2026 08:20
Coverage Report for CI Build 31471417832Coverage increased (+0.009%) to 87.685%Details
Uncovered ChangesNo uncovered changes found. Coverage Regressions11 previously-covered lines in 4 files lost coverage.
Coverage Stats
💛 - Coveralls |
Ronaldoengenhariadacomputacao
approved these changes
Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
OptimizeCliffordT'sapply_tyclosure re-expresses a Y-axis T-rotation withoutsx/sxdgusingS, H, T(dg), H, Sdg-- butSandSdgare swapped relative to the correct decomposition. As a result, the pass can emit a circuit that is not unitarily equivalent to its input (not even up to global phase) wheneverbasis_gatesexcludessx/sxdg-- a normal, common Clifford+T target basis, not an edge case. No exception or warning is raised.Verified two ways, not just with a custom offdiag computation: Qiskit's own
Operator.equiv()(handles global phase correctly), andprocess_fidelity()(1.0 expected, 0.067-0.26 observed on affected cases).Root cause
In the non-
SXbranch ofapply_ty(see diff),SandSdgare swapped at the two ends of the sequence. Verified numerically:SX*T*SXdgmatchesSdg*H*T*H*S(offdiag 5.5e-17, correct) but notS*H*T*H*Sdg(offdiag 0.7071, wrong) -- and the same holds for theflip=true(Tdg) case.Affected versions
Introduced in #15625 (merged 2026-03-19), first released in 2.4.0rc1. Confirmed affected: 2.4.0, 2.4.1, 2.4.2, 2.5.0, 2.5.0rc1, 2.5.1, and
mainprior to this fix. Not affected: 2.3.1 and earlier (the basis-aware Clifford+T pipeline didn't exist yet).Fix verified end-to-end
Built from source (not just the algebraic argument) and re-ran every known reproduction at every
optimization_level(0-3): all now come outOperator.equiv() == True(previouslyFalseat levels 1, 2, and/or 3 depending on the circuit).Test plan
Added
test_clifford_t_transpile_is_unitarily_equivalenttotest_clifford_t_passmanager.py, parametrized over all four optimization levels, assertingOperator(qc).equiv(Operator(transpiled)). None of the existing tests in that file check unitary equivalence (only gate-set membership and T-count), which is consistent with how this went unnoticed across several releases.AI/LLM disclosure
This is an automatic backport of pull request #16729 done by [Mergify](https://mergify.com).