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

[WIP] Refactor template matching #12351

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 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
ddeea5a
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Apr 16, 2024
eabb707
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 Apr 25, 2024
e92eaee
Initial setup
enavarro51 Apr 25, 2024
fdae191
Finish phase 1 of tempate_matching and forward_match
enavarro51 Apr 25, 2024
2b650b2
Finish phase 1 of backward match
enavarro51 Apr 25, 2024
1ec16af
Cleared all errors - next convert subst to v2
enavarro51 Apr 26, 2024
1c0ef7d
Finish errors
enavarro51 Apr 26, 2024
b3e0e36
Further cleanup and refactor
enavarro51 Apr 27, 2024
baa1922
Cleanup id vs objects and docs through forward, and add utils
enavarro51 Apr 30, 2024
a5a4ff6
More cleanup and finish backward
enavarro51 May 1, 2024
fe1533d
Finish substitution cleanup
enavarro51 May 1, 2024
4ae02e8
More optimizations
enavarro51 May 2, 2024
c2779dc
Even more efficiencies and cleanup
enavarro51 May 3, 2024
0aacd89
Implement lru_cache and testing
enavarro51 May 4, 2024
39de5e2
Adjust lru values
enavarro51 May 5, 2024
6b6fc83
Final testing and adjust caches
enavarro51 May 6, 2024
ee27daa
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into main
enavarro51 May 6, 2024
85da2ed
Merge branch 'main' into dag_dep_template_2
enavarro51 May 6, 2024
e47e274
Optimize successorstovisit
enavarro51 Jun 8, 2024
0e84a37
Up lru caches to 4k
enavarro51 Jun 14, 2024
b09c314
Lint
enavarro51 Jun 14, 2024
3f0b2bb
Merge branch 'main' into dag_dep_template_2
enavarro51 Jun 14, 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
87 changes: 29 additions & 58 deletions qiskit/dagcircuit/dagdependency_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ def __init__(self):
self.duration = None
self.unit = "dt"

self.leaves = set()

self.comm_checker = CommutationChecker()

@property
Expand Down Expand Up @@ -333,75 +335,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
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020.
#
# 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.

"""Module containing template matching methods."""

from .forward_match_v2 import ForwardMatch
from .backward_match_v2 import BackwardMatch, Match, MatchingScenarios, MatchingScenariosList
from .template_matching_v2 import TemplateMatching
from .maximal_matches_v2 import MaximalMatches
from .template_substitution_v2 import SubstitutionConfig, TemplateSubstitution
Loading
Loading