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

VF2 Layout : The layout allocation as a subgraph isomorphism problem #6620

Merged
merged 44 commits into from
Nov 2, 2021
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d483ad5
VF2 initial commit
1ucian0 Jun 22, 2021
13edf19
Update qiskit/transpiler/passes/layout/vf2_layout.py
1ucian0 Jun 23, 2021
9ee2e8d
test
1ucian0 Jun 23, 2021
97c9946
direction
1ucian0 Jun 23, 2021
8a80f6c
test
1ucian0 Jun 23, 2021
937fa0f
some tests
1ucian0 Jun 23, 2021
13319cc
done with test
1ucian0 Jun 23, 2021
4cbf628
reno
1ucian0 Jun 23, 2021
442264c
Merge branch 'main' into vf2layout
1ucian0 Jun 23, 2021
8d68f7c
Update releasenotes/notes/vf2layout-4cea88087c355769.yaml
1ucian0 Jun 23, 2021
53b735c
Merge branch 'main' of github.com:Qiskit/qiskit-terra into vf2layout
1ucian0 Jun 24, 2021
add603c
induced subraph test
1ucian0 Jun 24, 2021
7454e15
Update qiskit/transpiler/passes/layout/vf2_layout.py
1ucian0 Jun 24, 2021
7073047
adapt tests
1ucian0 Jun 24, 2021
5d554e8
Merge branch 'main' into vf2layout
1ucian0 Jun 24, 2021
b8e6066
Merge branch 'main' of github.com:Qiskit/qiskit-terra into vf2layout
1ucian0 Jul 4, 2021
1d11d1d
dynamic id_order selection
1ucian0 Jul 6, 2021
e01717e
lint
1ucian0 Jul 6, 2021
9663116
Merge branch 'main' of github.com:Qiskit/qiskit-terra into vf2layout
1ucian0 Jul 8, 2021
398ca2d
black
1ucian0 Jul 8, 2021
44e2d91
remove dynamic id_order
1ucian0 Jul 9, 2021
e5c1a68
Merge branch 'main' into vf2layout
mtreinish Aug 27, 2021
c5da7ac
Merge branch 'main' of github.com:Qiskit/qiskit-terra into vf2layout
1ucian0 Aug 30, 2021
ab3139e
iter instead of dict
1ucian0 Aug 30, 2021
8d9571b
iter instead of dict
1ucian0 Aug 30, 2021
d3275f5
remove id_order arg
1ucian0 Aug 30, 2021
5754917
Merge branch 'main' of github.com:Qiskit/qiskit-terra into vf2layout
1ucian0 Oct 11, 2021
98a6b9e
Merge branch 'main' into vf2layout
mtreinish Oct 18, 2021
8c9a6b7
Update qiskit/transpiler/passes/layout/vf2_layout.py
1ucian0 Oct 28, 2021
5a250b9
Update releasenotes/notes/vf2layout-4cea88087c355769.yaml
1ucian0 Oct 28, 2021
3af5e18
Update releasenotes/notes/vf2layout-4cea88087c355769.yaml
1ucian0 Oct 28, 2021
790f0d3
Update qiskit/transpiler/passes/layout/vf2_layout.py
1ucian0 Oct 28, 2021
b22c86f
Merge branch 'main' into vf2layout
1ucian0 Oct 28, 2021
4cbf21e
Update qiskit/transpiler/passes/layout/vf2_layout.py
1ucian0 Oct 28, 2021
4cc866e
Merge branch 'main' of github.com:Qiskit/qiskit-terra into vf2layout
1ucian0 Oct 29, 2021
90020ec
vf2_mapping
1ucian0 Oct 29, 2021
20f044d
Update test/python/transpiler/test_vf2_layout.py
1ucian0 Nov 2, 2021
528ca34
Update test/python/transpiler/test_vf2_layout.py
1ucian0 Nov 2, 2021
f8b0041
from_hexagonal_lattice
1ucian0 Nov 2, 2021
b7eb52c
dag.two_qubit_ops bites again
1ucian0 Nov 2, 2021
5ae94e7
dag.two_qubit_ops bites again
1ucian0 Nov 2, 2021
7ef6530
Merge branch 'main' of github.com:Qiskit/qiskit-terra into vf2layout
1ucian0 Nov 2, 2021
fafab89
Update vf2layout docstrings
mtreinish Nov 2, 2021
f20b175
Fix lint
mtreinish Nov 2, 2021
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
2 changes: 2 additions & 0 deletions qiskit/transpiler/passes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
NoiseAdaptiveLayout
SabreLayout
CSPLayout
VF2Layout
ApplyLayout
Layout2qDistance
EnlargeWithAncilla
Expand Down Expand Up @@ -151,6 +152,7 @@
from .layout import NoiseAdaptiveLayout
from .layout import SabreLayout
from .layout import CSPLayout
from .layout import VF2Layout
from .layout import ApplyLayout
from .layout import Layout2qDistance
from .layout import EnlargeWithAncilla
Expand Down
1 change: 1 addition & 0 deletions qiskit/transpiler/passes/layout/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from .noise_adaptive_layout import NoiseAdaptiveLayout
from .sabre_layout import SabreLayout
from .csp_layout import CSPLayout
from .vf2_layout import VF2Layout
from .apply_layout import ApplyLayout
from .layout_2q_distance import Layout2qDistance
from .enlarge_with_ancilla import EnlargeWithAncilla
Expand Down
96 changes: 96 additions & 0 deletions qiskit/transpiler/passes/layout/vf2_layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# 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.

"""A pass for choosing a Layout of a circuit onto a Coupling graph, as a
a subgraph isomorphism problem, solved by VF2++. If a solution is found
that means no further swap is needed. If no solution is
found, no ``property_set['layout']`` is set. The stopping reason is set in
``property_set['VF2Layout_stop_reason']``.
"""
import random
from retworkx import PyGraph, PyDiGraph, vf2_mapping
from qiskit.transpiler.layout import Layout
from qiskit.transpiler.basepasses import AnalysisPass
from qiskit.transpiler.exceptions import TranspilerError


class VF2Layout(AnalysisPass):
"""If possible, chooses a Layout as a Subgraph Isomorphism Problem, using VF2."""
1ucian0 marked this conversation as resolved.
Show resolved Hide resolved

def __init__(self, coupling_map, strict_direction=False, seed=None):
"""If possible, chooses a Layout as a Subgraph Isomorphism Probrem, using VF2.

If not possible, does not set the layout property. In all the cases,
the property `VF2Layout_stop_reason` will be added with one of the
following values:

* solution found: If a perfect layout was found.
* nonexistent solution: If no perfect layout was found.

Args:
coupling_map (CouplingMap): Directed graph representing a coupling map.
strict_direction (bool): If True, considers the direction of the coupling map.
Default is False.
seed (int): Sets the seed of the PRNG. -1 Means no node shuffling.
"""
mtreinish marked this conversation as resolved.
Show resolved Hide resolved
super().__init__()
self.coupling_map = coupling_map
self.strict_direction = strict_direction
self.seed = seed

def run(self, dag):
"""run the layout method"""
qubits = dag.qubits
qubit_indices = {qubit: index for index, qubit in enumerate(qubits)}

interactions = []
for node in dag.op_nodes(include_directives=False):
len_args = len(node.qargs)
if len_args == 2:
interactions.append((qubit_indices[node.qargs[0]], qubit_indices[node.qargs[1]]))
if len_args >= 3:
raise TranspilerError(
"VF2Layout only can handle 2-qubit gates or less. Node "
f"{node.name} ({node}) is {len_args}-qubit"
)

if self.strict_direction:
cm_graph = self.coupling_map.graph
im_graph = PyDiGraph(multigraph=False)
else:
cm_graph = self.coupling_map.graph.to_undirected()
im_graph = PyGraph(multigraph=False)

cm_nodes = list(cm_graph.node_indexes())
if self.seed != -1:
random.Random(self.seed).shuffle(cm_nodes)
shuffled_cm_graph = type(cm_graph)()
shuffled_cm_graph.add_nodes_from(cm_nodes)
new_edges = [(cm_nodes[edge[0]], cm_nodes[edge[1]]) for edge in cm_graph.edge_list()]
shuffled_cm_graph.add_edges_from_no_data(new_edges)
cm_nodes = [k for k, v in sorted(enumerate(cm_nodes), key=lambda item: item[1])]
cm_graph = shuffled_cm_graph
im_graph.add_nodes_from(range(len(qubits)))
mtreinish marked this conversation as resolved.
Show resolved Hide resolved
im_graph.add_edges_from_no_data(interactions)

mappings = vf2_mapping(cm_graph, im_graph, subgraph=True, id_order=False, induced=False)
try:
mapping = next(mappings)
stop_reason = "solution found"
layout = Layout({qubits[im_i]: cm_nodes[cm_i] for cm_i, im_i in mapping.items()})
self.property_set["layout"] = layout
for reg in dag.qregs.values():
self.property_set["layout"].add_register(reg)
except StopIteration:
stop_reason = "nonexistent solution"

self.property_set["VF2Layout_stop_reason"] = stop_reason
7 changes: 7 additions & 0 deletions releasenotes/notes/vf2layout-4cea88087c355769.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
features:
- |
A new pass :class:`qiskit.transpiler.passes.VF2Layout` is
introduced. This pass models the layout allocation problem as a subgraph
isomorphism problem. For this, it uses VF2, a state of the art heuristic to find
subgraphs. The pass works very much like :class:`qiskit.transpiler.passes.CSPLayout`.
Loading