Constructing Cliffords from quantum circuits with other Cliffords#9169
Conversation
|
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 the following people are requested to review this:
|
Pull Request Test Coverage Report for Build 3961011878
💛 - Coveralls |
|
|
|
Luciano: no, this is precisely against the data model. Code that assumes that's the type of circuit and dag elements shouldn't, because it isn't any more. That's the point of |
Clifford ops|
One more comment. Once the PR #9157 gets merged, it would make sense to extend constructing Cliffords from quantum circuits with permutations. |
…it with various clifford-like objects
ShellyGarion
left a comment
There was a problem hiding this comment.
LGTM! Thanks!
We still need a code owner approval to get it merged.
ikkoham
left a comment
There was a problem hiding this comment.
Thank you. Overall LGTM. I have one minor question.
jakelishman
left a comment
There was a problem hiding this comment.
This looks pretty solid to me, thanks. I just had a couple of minor points on the tests, but that's it.
For posterity: this PR isn't intended to fix all the issues raised by #9159, just a couple of them. We're still working on all of #9159, but it will likely require a lot more overhauls to how inverses, controls and some other attributes are applied to gates.
| op1 = Operator(qc) | ||
| op2 = Operator(qct) | ||
| self.assertTrue(op1.equiv(op2)) |
There was a problem hiding this comment.
These tests use equiv rather than == - the former normalises global phase, so == is a strong condition. Do we need the global-phase fuzziness here? If so, it seems a bit unnerving, since the transpiler is supposed to maintain the global phase entirely.
(Comment repeats for all the tests here.)
There was a problem hiding this comment.
Ouch, your comment points to a real problem with OptimizeCliffords transpiler pass, that I should have but did not think about.
The problem is that Cliffords are only defined up to a global phase: while "in the real world" XY = iZ, when using Clifford's stabilizer/destabilizer tableaus, the multiplication by i get dropped, i.e. "in the Clifford world" XY=Z. This is also the reason why most of the tests that construct an Operator out of Clifford in test_clifford.py check for equiv and not for ==.
The above in code:
qc = QuantumCircuit(1)
qc.x(0)
qc.y(0)
print(Operator(Clifford(qc)) == Operator(qc))
print the value False.
So right now replacing a block of Clifford gates by a Clifford may drop the global phase, which is indeed the problem to "the transpiler maintaining the global phase". That is, the OptimizeCliffords transpiler pass can only guarantee equivalence up to a global phase.
Note: I do believe that when optimizing Cliffords over a subset of qubits the problem is still only with global and not local phases.
BTW, I thought there was an effort to incorporate the full phase into the Clifford class, maybe @ShellyGarion or @ikkoham can comment? This would immediately solve our problems here.
There was a problem hiding this comment.
So I don't think we should replace equiv by == in these tests. However, we should see if there is already a solution for maintaining the global phase. And if not we should clearly document this caveat in the documentation for OptimizeCliffords transpiler pass. What do you think?
There was a problem hiding this comment.
That sounds like a sensible plan to me. If the phase non-equivalence is already in the pass and in Terra 0.22, then there's no massive rush to fix it now before the release, and anyway, we can treat it as a bug fix. Let's open a new issue and discuss the right way forwards.
jakelishman
left a comment
There was a problem hiding this comment.
Potential global-phase issues aside, which are for another issue, this looks good to merge to me.
|
@Mergifyio requeue |
✅ The queue state of this pull request has been cleaned. It can be re-embarked automatically |
|
@Mergifyio requeue |
✅ The queue state of this pull request has been cleaned. It can be re-embarked automatically |
|
@Mergifyio unqueue |
✅ The pull request has been removed from the queue |
|
@Mergifyio requeue |
✅ The queue state of this pull request has been cleaned. It can be re-embarked automatically |
Summary (updated)
In #7966 we started adding
Cliffordsto quantum circuits natively, without explicitly converting them toInstructions. Unfortunately, this also broke some of the functionality for circuits containing Cliffords, see #9159. This PR fixes the problem of constructing a Clifford from a quantum circuit that contains other Cliffords. Moreover, the performance of doing so is greatly increased as the code now uses Clifford'scomposefunction instead of decomposing the inner clifford into simple gates.In addition, the
CollectCliffordstranspiler pass has been upgraded to collect and combine "clifford gates", where the "clifford gates" may now also include objects of typeLinearFunction,Clifford, andPauliGate.Question: are there any other Clifford-like gates that can also be treated here?
Details and comments
Bug fix and performance improvement.
The code snippet
attempts to create a Clifford object from a quantum circuit that contains another clifford
cliff(created byrandom_clifford). I have experimented with two possible fixes for this: convertingcliffto circuit (as would have been done previously when convertingcliffto instruction and using itsdefinition) vs. directly using the Clifford'scomposefunction (which is possible becausecliffis of typeCliffordand notInstruction). The second approach seems to be considerably faster, for example on my laptop the following codetakes 4.15 seconds using
composeand 25.88 seconds usingto_circuit. This is not surprising, since Clifford synthesis is time-consuming for large cliffords.Update: with #7483 merged (
Clifford.composebecoming incredibly faster), the above code now takes 0.14 seconds!Extending the
CollectCliffordstranspiler pass.This was very simple as the current code for
Clifford(circuit)(inclifford_circuits.py) can already construct Cliffords from quantum circuit with linear functions and pauli gates.