-
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
Add pass to filter ops and label inserted barriers #10323
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
caae56f
Add pass to remove labeled ops and label inserted barriers
mtreinish b8cea23
Merge remote-tracking branch 'origin/main' into no-barrier-leakage
mtreinish b12cc3b
Fix rebase issues
mtreinish 29c1217
Handle pre-existing adjacent barriers
mtreinish 691d7d5
Generalize RemoveLabeledOps to FilterOpNodes
mtreinish a2a4eaf
Add release note
mtreinish bc3b5d5
Add tests for new pass
mtreinish f855a8e
Merge branch 'main' into no-barrier-leakage
mtreinish 1be3517
Add release note for new barrier pass kwarg
mtreinish 0c7cdc5
Fix type hint
mtreinish d1236ad
Fix docs typo
mtreinish f6df5be
Invert predicate usage
mtreinish 638b9d8
Update pass manager drawer reference images
mtreinish 77d54f8
Merge branch 'main' into no-barrier-leakage
mtreinish File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2023. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
|
||
"""Filter ops from a circuit""" | ||
|
||
from typing import Callable | ||
|
||
from qiskit.dagcircuit import DAGCircuit, DAGOpNode | ||
from qiskit.transpiler.basepasses import TransformationPass | ||
from qiskit.transpiler.passes.utils import control_flow | ||
|
||
|
||
class FilterOpNodes(TransformationPass): | ||
"""Remove all operations that match a filter function | ||
|
||
This transformation pass is used to remove any operations that matches a | ||
the provided filter function. | ||
|
||
Args: | ||
predicate: A given callable that will be passed the :class:`.DAGOpNode` | ||
for each node in the :class:`.DAGCircuit`. If the callable returns | ||
``True`` the :class:`.DAGOpNode` is retained in the circuit and if it | ||
returns ``False`` it is removed from the circuit. | ||
|
||
Example: | ||
|
||
Filter out operations that are labelled ``"foo"`` | ||
|
||
.. plot:: | ||
:include-source: | ||
|
||
from qiskit import QuantumCircuit | ||
from qiskit.transpiler.passes import FilterOpNodes | ||
|
||
circuit = QuantumCircuit(1) | ||
circuit.x(0, label='foo') | ||
circuit.barrier() | ||
circuit.h(0) | ||
|
||
circuit = FilterOpNodes( | ||
lambda node: getattr(node.op, "label") != "foo" | ||
)(circuit) | ||
circuit.draw('mpl') | ||
""" | ||
|
||
def __init__(self, predicate: Callable[[DAGOpNode], bool]): | ||
super().__init__() | ||
self.predicate = predicate | ||
|
||
@control_flow.trivial_recurse | ||
def run(self, dag: DAGCircuit) -> DAGCircuit: | ||
"""Run the RemoveBarriers pass on `dag`.""" | ||
for node in dag.op_nodes(): | ||
if not self.predicate(node): | ||
dag.remove_op_node(node) | ||
return dag |
This file contains 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
This file contains 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
16 changes: 16 additions & 0 deletions
16
releasenotes/notes/add-filter-op-nodes-aa024a0f1058e4b7.yaml
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
features: | ||
- | | ||
Added a new transpiler pass :class:`.FilterOpNodes` which is used to filter | ||
:class:`.DAGOpNode`\s in a :class:`.DAGCircuit`. | ||
- | | ||
Added a new keyword argument, ``label``, to the constructor on the | ||
:class:`.BarrierBeforeFinalMeasurements` transpiler pass. If specified the | ||
inserted barrier will be assigned the specified label. This also prevents | ||
the inserted barrier from being merged with any any other pre-existing | ||
adjacent barriers. | ||
other: | ||
- | | ||
The preset pass managers used by :func:`.transpile` and returned with | ||
:class:`.generate_preset_pass_manager` will no longer insert barriers | ||
before final measurements in the output circuits. |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2023 | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
|
||
"""FilterOpNodes pass testing""" | ||
|
||
|
||
from qiskit import QuantumCircuit | ||
from qiskit.transpiler.passes import FilterOpNodes | ||
from qiskit.test import QiskitTestCase | ||
|
||
|
||
class TestFilterOpNodes(QiskitTestCase): | ||
"""Tests for FilterOpNodes transformation pass.""" | ||
|
||
def test_empty_circuit(self): | ||
"""Empty DAG has does nothing.""" | ||
circuit = QuantumCircuit() | ||
self.assertEqual(FilterOpNodes(lambda x: False)(circuit), circuit) | ||
|
||
def test_remove_x_gate(self): | ||
"""Test filter removes matching gates.""" | ||
circuit = QuantumCircuit(2) | ||
circuit.x(0) | ||
circuit.x(1) | ||
circuit.cx(0, 1) | ||
circuit.cx(1, 0) | ||
circuit.cx(0, 1) | ||
circuit.measure_all() | ||
|
||
filter_pass = FilterOpNodes(lambda node: node.op.name != "x") | ||
|
||
expected = QuantumCircuit(2) | ||
expected.cx(0, 1) | ||
expected.cx(1, 0) | ||
expected.cx(0, 1) | ||
expected.measure_all() | ||
|
||
self.assertEqual(filter_pass(circuit), expected) | ||
|
||
def test_filter_exception(self): | ||
"""Test a filter function exception passes through.""" | ||
circuit = QuantumCircuit(2) | ||
circuit.x(0) | ||
circuit.x(1) | ||
circuit.cx(0, 1) | ||
circuit.cx(1, 0) | ||
circuit.cx(0, 1) | ||
circuit.measure_all() | ||
|
||
def filter_fn(node): | ||
raise TypeError("Failure") | ||
|
||
filter_pass = FilterOpNodes(filter_fn) | ||
with self.assertRaises(TypeError): | ||
filter_pass(circuit) | ||
|
||
def test_no_matches(self): | ||
"""Test the pass does nothing if there are no filter matches.""" | ||
circuit = QuantumCircuit(2) | ||
circuit.x(0) | ||
circuit.x(1) | ||
circuit.cx(0, 1) | ||
circuit.cx(1, 0) | ||
circuit.cx(0, 1) | ||
circuit.measure_all() | ||
|
||
filter_pass = FilterOpNodes(lambda node: node.op.name != "cz") | ||
|
||
self.assertEqual(filter_pass(circuit), circuit) |
This file contains 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
Oops, something went wrong.
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.
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.
Do we know why this changed? The actual barriers inserted before routing should have been the same, right, so it shouldn't have affected StochasticSwap? It's not really a problem, I just don't understand why it's changed.
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.
My assumption was because the input circuit has barriers in it that this was a side effect of not running merge adjacent barriers part of the barrier insertion. (this only changed with 29c1217 ). So, now we have multiple barriers followed by an all qubit barrier instead of it all getting merged into a single barrier. But I didn't look too closely at the internals of what was causing sabre to diverge internally.
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.
Just a heads up I did get to the bottom of this, it was basically what I thought. I pushed up #11295 to fix the behavior of Sabre with regards to barriers and had to revert this change in that PR: 93a3241