-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix post-oxidization change in ConsolidateBlocks
behavior
#13450
Conversation
One or more of the following people are relevant to this code:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, good catch.it was a change in behavior on my consolidate blocks pr not unitary synthesis. I remember changing that logic at the time and thinking it wouldn't impact anything. I was coming at it from the mindset that consolidate blocks is too likely to skip consolidation when it shouldn't.
Realistically we should be relying on the xx decomposer with the rzz in the basis gates list, but there isn't an interface in rust yet to tell us the estimated number of 2q basis gates needed for a unitary, which is why I changed the logic here. Also that is not really a good meteic anyway, just more reason for me to keep working on #13419 and introduce a better approach.
Changing the "default" to
|
Pull Request Test Coverage Report for Build 11898770714Details
💛 - Coveralls |
@@ -27,6 +29,7 @@ | |||
"cz": CZGate(), | |||
"iswap": iSwapGate(), | |||
"ecr": ECRGate(), | |||
"rxx": RXXGate(pi / 2), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is the angle here fixed to pi/2 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's because that's what UnitarySynthesis
uses if it's a basis_gates
only setup: https://github.com/Qiskit/qiskit/blob/main/qiskit/transpiler/passes/synthesis/unitary_synthesis.py#L98 the idea is that it's trying to match the decomposer used for estimating to what the synthesis pass will use later.
The whole logic between the passes is more than a bit hacky. ConsolidateBlocks
tries to guess how many 2q gates will be used to decide whether to consolidate the block into a unitary or not. This is strongly coupled to the behavior of UnitarySynthesis
because that's what actually does the synthesis later. But none of this actually takes into account multiple possible decomposers/synthesis methods being supported by a target, or the presence of a non-default plugin being used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I did some testing locally with this and in some cases using TwoQubitBasisDecomposer(RXXGate(pi/2))
under estimates what the XXDecomposer
estimates, 3 vs 4 gates. This might result in some blocks not getting consolidated which were before, but in practice I find it probably pretty unlikely since it only counts rzz gates when evaluating if the block's gates are more than the expected synthesis output.
I added a small refactoring on top of the previous changes to make the new implementation hopefully closer to the old one. Now:
I also added a comment that mentions the previous use of the XXDecomposer for the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with this it returns the previous state of logic. There might be some subtle differences in what gets consolidated or not with rzx based on differences between XXDecomposer.num_basis_gates
and TwoQubitBasisDecomposer
's logic, but it should be close enough to the 1.2.x state of the logic that I'm not worried.
I think this whole exercise reinforces for me how we need to improve the logic around block consolidation. #13419 will do this for the optimization loop, but we will need to think what makes the most sense for when we run ConsolidateBlocks
prior to layout in the init stage.
* Set decomposer to None if kak_gates not found during ConsolidateBlocks initialization. * Add test that reproduces issue * Re-add rzz to list of kak gates * Add path for rzx gate. (cherry picked from commit 94cea41)
…13453) * Set decomposer to None if kak_gates not found during ConsolidateBlocks initialization. * Add test that reproduces issue * Re-add rzz to list of kak gates * Add path for rzx gate. (cherry picked from commit 94cea41) Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
Summary
Fixes the behavioral difference introduced by #13368 that caused #13438.
The original implementation of the pass used to set the
ConsolidateBlocks
internal decomposer callingunitary_synthesis._decomposer_2q_from_basis_gates
, which, whenkak_basis
wasn't found, would returnNone
. During the oxidization efforts,unitary_synthesis._decomposer_2q_from_basis_gates
was replaced with inline code that didn't contemplate this path (always set a default decomposer), which in the reproducing example lead to a longer output circuit (the gates were collected into a unitary block and then decomposed differently).Details and comments
Technically not a bugfix because the change wasn't released yet.
Using the example shown in the issue ->
ConsolidateBlocks
output dag with 1.2.4:ConsolidateBlocks
output dag with 1.3.0rc1:ConsolidateBlocks
output dag after this fix: