Skip to content
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

Optimized apply_operation_back for DAGDependencyV2 #12194

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
08a23c5
Fix typing-extensions
enavarro51 Jan 4, 2024
8d06451
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Jan 4, 2024
f70314a
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Jan 12, 2024
c179d5b
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Jan 31, 2024
83972c6
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Feb 2, 2024
e6d975c
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Feb 6, 2024
d698cac
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Feb 11, 2024
415504a
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Feb 14, 2024
b0e6690
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Feb 25, 2024
f0731e6
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Mar 5, 2024
e5c951b
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Mar 15, 2024
2de1ea6
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Mar 18, 2024
e815358
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Apr 9, 2024
8a3fff9
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Apr 16, 2024
b5e267d
Add new apply_operation_back
enavarro51 Apr 16, 2024
95f6063
Add optimized apply_operation_back
enavarro51 Apr 16, 2024
ddeea5a
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Apr 16, 2024
b4e2cef
Merge branch 'main' into dag_dep_apply
enavarro51 Apr 16, 2024
0be01ab
Lint
enavarro51 Apr 16, 2024
29cf681
Use Session Checker
enavarro51 Apr 17, 2024
5ba2569
Add comments
enavarro51 Apr 17, 2024
eabb707
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Apr 25, 2024
ee27daa
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 May 6, 2024
46085a7
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Jun 3, 2024
4eb3b78
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Jun 14, 2024
31b2535
Bump Rustworkx to support new features
jakelishman Jun 28, 2024
8f0823c
Merge remote-tracking branch 'ibm/main' into dag_dep_apply
jakelishman Jun 28, 2024
9abb225
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Jun 28, 2024
e33c57a
Merge branch 'main' into dag_dep_apply
enavarro51 Jun 28, 2024
02abff5
Merge branch 'dag_dep_apply' of github.com:enavarro51/qiskit-terra in…
enavarro51 Jun 28, 2024
1f2facb
Merge branch 'main' into dag_dep_apply
enavarro51 Jul 1, 2024
daab0fa
Merge branch 'main' into dag_dep_apply
enavarro51 Jul 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 35 additions & 60 deletions qiskit/dagcircuit/dagdependency_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from qiskit.circuit.bit import Bit
from qiskit.dagcircuit.dagnode import DAGOpNode
from qiskit.dagcircuit.exceptions import DAGDependencyError
from qiskit.circuit.commutation_checker import CommutationChecker
from qiskit.circuit.commutation_library import SessionCommutationChecker as scc


BitLocations = namedtuple("BitLocations", ("index", "registers"))
Expand Down Expand Up @@ -117,7 +117,13 @@ def __init__(self):
self.duration = None
self.unit = "dt"

self.comm_checker = CommutationChecker()
# The set of initial starting nodes for a reverse
# topological sort of the DAG
self.leaves = set()

# The commutation checker initialized with
# _standard_gates_commutations library
self.comm_checker = scc

@property
def global_phase(self):
Expand Down Expand Up @@ -333,75 +339,44 @@ def find_bit(self, bit: Bit) -> BitLocations:
) from err

def apply_operation_back(self, operation, qargs=(), cargs=()):
"""Add a DAGOpNode to the graph and update the edges.

Args:
operation (qiskit.circuit.Operation): operation as a quantum gate
qargs (list[~qiskit.circuit.Qubit]): list of qubits on which the operation acts
cargs (list[Clbit]): list of classical wires to attach to
"""
new_node = DAGOpNode(
op=operation,
qargs=qargs,
cargs=cargs,
dag=self,
)
new_node._node_id = self._multi_graph.add_node(new_node)
self._update_edges()
self._increment_op(new_node.op)

def _update_edges(self):
"""
Updates DagDependencyV2 by adding edges to the newly added node (max_node)
from the previously added nodes.
For each previously added node (prev_node), an edge from prev_node to max_node
is added if max_node is "reachable" from prev_node (this means that the two
Updates DagDependencyV2 by adding edges to the newly added node (new_node) from
the previously added nodes. This update assumes the new_node was added to the end of
the graph.
For each previously added node (prev_node), an edge from prev_node to new_node
is added if new_node is not "unreachable" from prev_node (this means that the two
nodes can be made adjacent by commuting them with other nodes), but the two nodes
themselves do not commute.

Currently. this function is only used when creating a new _DAGDependencyV2 from another
representation of a circuit, and hence there are no removed nodes (this is why
iterating over all nodes is fine).
"""
max_node_id = len(self._multi_graph) - 1
max_node = self._get_node(max_node_id)
order = rx.TopologicalSorter(
self._multi_graph,
check_cycle=False,
reverse=True,
initial=self.leaves,
check_args=False,
)

reachable = [True] * max_node_id
new_node = DAGOpNode(op=operation, qargs=qargs, cargs=cargs, dag=self)
new_node._node_id = self._multi_graph.add_node(new_node)

# Analyze nodes in the reverse topological order.
# An improvement to the original algorithm is to consider only direct predecessors
# and to avoid constructing the lists of forward and backward reachable predecessors
# for every node when not required.
for prev_node_id in range(max_node_id - 1, -1, -1):
if reachable[prev_node_id]:
prev_node = self._get_node(prev_node_id)
self.leaves.add(new_node._node_id)
self._increment_op(new_node.op)

if not self.comm_checker.commute(
while available := order.get_ready():
for prev_node_id in available:
prev_node = self._multi_graph[prev_node_id]
if self.comm_checker.commute(
prev_node.op,
prev_node.qargs,
prev_node.cargs,
max_node.op,
max_node.qargs,
max_node.cargs,
new_node.op,
new_node.qargs,
new_node.cargs,
):
# If prev_node and max_node do not commute, then we add an edge
# between the two, and mark all direct predecessors of prev_node
# as not reaching max_node.
self._multi_graph.add_edge(prev_node_id, max_node_id, {"commute": False})

predecessor_ids = sorted(
[node._node_id for node in self.predecessors(self._get_node(prev_node_id))]
)
for predecessor_id in predecessor_ids:
reachable[predecessor_id] = False
else:
# If prev_node cannot reach max_node, then none of its predecessors can
# reach max_node either.
predecessor_ids = sorted(
[node._node_id for node in self.predecessors(self._get_node(prev_node_id))]
)
for predecessor_id in predecessor_ids:
reachable[predecessor_id] = False
order.done(prev_node_id)
else:
self.leaves.discard(prev_node_id)
self._multi_graph.add_edge(prev_node_id, new_node._node_id, None)

def _get_node(self, node_id):
"""
Expand Down
4 changes: 4 additions & 0 deletions releasenotes/notes/bump-rustworkx-58a51151022dcfa6.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
upgrade:
- |
The minimum required version of Rustworkx is now 0.15.
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
rustworkx>=0.14.0
rustworkx>=0.15.0
numpy>=1.17,<3
scipy>=1.5
sympy>=1.3
Expand Down
Loading