-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Consistent identity removal for ConsolidateBlocks
#16082
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -100,6 +100,7 @@ def __init__( | |||||
| super().__init__() | ||||||
| self.basis_gates = None | ||||||
| self.basis_gate_name = None | ||||||
| self.approximation_degree = approximation_degree | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just for good measure even though it's not documented so not public I'd still make this
Suggested change
just so it's abundantly clear. |
||||||
| # Bypass target if it doesn't contain any basis gates (i.e. it's a _FakeTarget), as this | ||||||
| # not part of the official target model. | ||||||
| self.target = target if target is not None and len(target.operation_names) > 0 else None | ||||||
|
|
@@ -158,6 +159,7 @@ def run(self, dag): | |||||
| blocks=blocks, | ||||||
| runs=runs, | ||||||
| qubit_map=qubit_map, | ||||||
| approximation_degree=self.approximation_degree, | ||||||
| ) | ||||||
| dag = self._handle_control_flow_ops(dag, qubit_map) | ||||||
|
|
||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,8 @@ | ||||||
| --- | ||||||
| fixes: | ||||||
| - | | ||||||
| Fixed an inconsistency in :class:`.ConsolidateBlocks`, which removed identity-equivalent | ||||||
| sequences differently to how :class:`.RemoveIdentityEquiv` and the remainder of the stack does. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| This has been fixed and these passes now behave consistently by using the average gate | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| fidelity to check whether a sequence is close to the identity. This implies that also | ||||||
| sequences that are equivalent to the identity up to global phase are now being removed. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Functionally this would happen later anyway when we run |
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -415,6 +415,18 @@ def test_identity_unitary_is_removed(self): | |
| pm = PassManager([Collect2qBlocks(), ConsolidateBlocks()]) | ||
| self.assertEqual(QuantumCircuit(5), pm.run(qc)) | ||
|
|
||
| def test_identity_unitary_is_removed_up_to_phase(self): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does it's also worth checking the approximation_degree parameter? |
||
| """Test that a 2q identity (up to phase) unitary is removed.""" | ||
| qc = QuantumCircuit(5) | ||
| qc.h(0) | ||
| qc.cx(0, 1) | ||
| qc.rz(2 * np.pi, 1) | ||
| qc.cx(0, 1) | ||
| qc.h(0) | ||
|
|
||
| pm = PassManager([Collect2qBlocks(), ConsolidateBlocks()]) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You technically don't need the |
||
| self.assertEqual(QuantumCircuit(5, global_phase=np.pi), pm.run(qc)) | ||
|
|
||
| def test_identity_1q_unitary_is_removed(self): | ||
| """Test that a 1q identity unitary is removed without a basis.""" | ||
| qc = QuantumCircuit(5) | ||
|
|
@@ -425,6 +437,15 @@ def test_identity_1q_unitary_is_removed(self): | |
| pm = PassManager([Collect2qBlocks(), Collect1qRuns(), ConsolidateBlocks()]) | ||
| self.assertEqual(QuantumCircuit(5), pm.run(qc)) | ||
|
|
||
| def test_identity_1q_unitary_is_removed_up_to_phase(self): | ||
| """Test that a 1q identity unitary is removed without a basis.""" | ||
| qc = QuantumCircuit(5) | ||
| qc.h(0) | ||
| qc.rz(2 * np.pi, 0) | ||
| qc.h(0) | ||
| pm = PassManager([Collect2qBlocks(), Collect1qRuns(), ConsolidateBlocks()]) | ||
| self.assertEqual(QuantumCircuit(5, global_phase=np.pi), pm.run(qc)) | ||
|
|
||
| def test_descent_into_control_flow(self): | ||
| """Test consolidation in blocks when control flow op is the same as at top level.""" | ||
|
|
||
|
|
||
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.
Neither here nor there but you could simplify this a bit to: