From 65b2f27c312c9c451c62989360b5045de3075399 Mon Sep 17 00:00:00 2001 From: Tom Peham Date: Fri, 21 Oct 2022 10:06:15 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Sub-Architectures=20(#106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added functionality for computing sub-architectures for qubit mapping based on https://arxiv.org/abs/2210.09321. Signed-off-by: burgholzer Co-authored-by: burgholzer --- README.md | 4 + docs/source/Publications.rst | 1 + docs/source/library/Library.rst | 1 + docs/source/library/Subarchitectures.rst | 19 ++ docs/source/refs.bib | 8 + extern/LogicBlocks | 2 +- extern/qfr | 2 +- mqt/qmap/__init__.py | 2 + mqt/qmap/libs/ibm_guadalupe_16.pickle | Bin 0 -> 168150 bytes mqt/qmap/libs/rigetti_16.pickle | Bin 0 -> 336030 bytes mqt/qmap/subarchitectures.py | 323 +++++++++++++++++++++++ setup.py | 6 +- test/python/test_subarchitectures.py | 212 +++++++++++++++ 13 files changed, 577 insertions(+), 3 deletions(-) create mode 100644 docs/source/library/Subarchitectures.rst create mode 100644 mqt/qmap/libs/ibm_guadalupe_16.pickle create mode 100644 mqt/qmap/libs/rigetti_16.pickle create mode 100644 mqt/qmap/subarchitectures.py create mode 100644 test/python/test_subarchitectures.py diff --git a/README.md b/README.md index d32b769bc..2ad1bc04c 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,8 @@ _In Asia and South Pacific Design Automation Conference (ASP-DAC)_, 2021. L. Burgholzer, S. Schneider, and R. Wille. Limiting the Search Space in Optimal Quantum Circuit Mapping. _In Asia and South Pacific Design Automation Conference (ASP-DAC)_, 2022. +[[5]](https://arxiv.org/pdf/2210.09321.pdf) +T. Peham, L. Burgholzer, and R. Wille. On Optimal Subarchitectures for Quantum Circuit Mapping. +_arXiv:2210.09321_, 2022. + [^1]: The Munich Quantum Toolkit was formerly known under the acronym _JKQ_ and developed by the [Institute for Integrated Circuits](https://iic.jku.at/eda/) at the [Johannes Kepler University Linz](https://jku.at)). diff --git a/docs/source/Publications.rst b/docs/source/Publications.rst index 4985984dd..46ffc2345 100644 --- a/docs/source/Publications.rst +++ b/docs/source/Publications.rst @@ -8,6 +8,7 @@ Furthermore, if you use any of the particular algorithms such as - the heuristic mapping scheme using teleportation :cite:labelpar:`hillmichExlpoitingQuantumTeleportation2021` - the search space limitation techniques of the exact mapper (some of which are enabled per default) :cite:labelpar:`burgholzer2022limitingSearchSpace` +- the method for finding (near-)optimal subarchitectures :cite:labelpar:`peham2022OptimalSubarchitectures` please consider citing their respective papers as well. A full list of related papers is given below. diff --git a/docs/source/library/Library.rst b/docs/source/library/Library.rst index 8592018d7..6f7cb5d69 100644 --- a/docs/source/library/Library.rst +++ b/docs/source/library/Library.rst @@ -7,3 +7,4 @@ Library Mapping Architecture MappingResults + Subarchitectures diff --git a/docs/source/library/Subarchitectures.rst b/docs/source/library/Subarchitectures.rst new file mode 100644 index 000000000..ebdd58048 --- /dev/null +++ b/docs/source/library/Subarchitectures.rst @@ -0,0 +1,19 @@ +Optimal Subarchitectures +======================== + +To compute (near-)optimal subarchitectures of quantum computing architectures with restricted connectivity as described in :cite:labelpar:`peham2022OptimalSubarchitectures` the :code:`SubarchitectureOrder` class is provided. This class has functionality to compute the quasi-order that allows for fast computation of optimal subarchitectures. + +Note that the initial construction of the ordering might take a while for larger architectures. + + .. currentmodule:: mqt.qmap + .. autoclass:: SubarchitectureOrder + :members: + +QMAP also provides precomputed subarchitecture libraries. The available libraries are available via: + + .. autoattribute:: subarchitectures.precomputed_backends + +Convenience methods are provided to import these precomputed orderings: + + .. automethod:: subarchitectures.ibm_guadalupe_subarchitectures + .. automethod:: subarchitectures.rigetti_16_subarchitectures diff --git a/docs/source/refs.bib b/docs/source/refs.bib index 36de8fba9..5059df2f2 100644 --- a/docs/source/refs.bib +++ b/docs/source/refs.bib @@ -50,3 +50,11 @@ @inproceedings{boteaComplexityQuantumCircuit2018 author = {Botea, A. and Kishimoto, A. and Marinescu, Radu}, year = {2018}, } + +@inproceedings{peham2022OptimalSubarchitectures, + title = {On Optimal Subarchitectures for Quantum Circuit Mapping}, + author = {Peham, Tom and Burgholzer, Lukas and Wille, Robert}, + booktitle = {arXiv:2210.09321}, + year = {2022}, + url = {https://arxiv.org/pdf/2210.09321.pdf}, +} diff --git a/extern/LogicBlocks b/extern/LogicBlocks index 89d81d2ef..58c0daada 160000 --- a/extern/LogicBlocks +++ b/extern/LogicBlocks @@ -1 +1 @@ -Subproject commit 89d81d2efc5076c38c8d2a8e32d288d087bfafdc +Subproject commit 58c0daada76857cf98642584c25788d4ebdbfa59 diff --git a/extern/qfr b/extern/qfr index 76dfda69e..6e4924abd 160000 --- a/extern/qfr +++ b/extern/qfr @@ -1 +1 @@ -Subproject commit 76dfda69e0f55de1c3408b55fe94019b9ac1561f +Subproject commit 6e4924abd575c472b4fc1a029f1db531e18f362d diff --git a/mqt/qmap/__init__.py b/mqt/qmap/__init__.py index 5a8eef702..506fa0b59 100644 --- a/mqt/qmap/__init__.py +++ b/mqt/qmap/__init__.py @@ -28,6 +28,7 @@ Method, SwapReduction, ) +from mqt.qmap.subarchitectures import SubarchitectureOrder __all__ = [ "compile", @@ -41,4 +42,5 @@ "Configuration", "MappingResults", "Architecture", + "SubarchitectureOrder", ] diff --git a/mqt/qmap/libs/ibm_guadalupe_16.pickle b/mqt/qmap/libs/ibm_guadalupe_16.pickle new file mode 100644 index 0000000000000000000000000000000000000000..05426857fe1ad148644a0df706a07300ef9b15f5 GIT binary patch literal 168150 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 M#E##XgZ+#D3(S38=Kufz literal 0 HcmV?d00001 diff --git a/mqt/qmap/libs/rigetti_16.pickle b/mqt/qmap/libs/rigetti_16.pickle new file mode 100644 index 0000000000000000000000000000000000000000..58f21a3abb07bf0856168b34eaae7762d305c542 GIT binary patch literal 336030 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 literal 0 HcmV?d00001 diff --git a/mqt/qmap/subarchitectures.py b/mqt/qmap/subarchitectures.py new file mode 100644 index 000000000..866cd280a --- /dev/null +++ b/mqt/qmap/subarchitectures.py @@ -0,0 +1,323 @@ +""" +Functionality for computing good subarchitectures for quantum circuit mapping. + +This file implements the methods presented in https://arxiv.org/abs/2210.09321. +""" + +from __future__ import annotations + +import sys + +if sys.version_info < (3, 10, 0): + import importlib_resources as resources +else: + from importlib import resources + +import pickle +from itertools import combinations +from pathlib import Path +from typing import Dict, NewType, Set, Tuple + +import retworkx as rx +from matplotlib import figure +from mqt.qmap import Architecture + +from qiskit.providers import Backend + +PartialOrder = NewType("PartialOrder", Dict[Tuple[int, int], Set[Tuple[int, int]]]) + +#: Architectures for which precomputed orderings are available +precomputed_backends = ["rigetti_16", "ibm_guadalupe_16"] + + +class SubarchitectureOrder: + """Class representing partial order of Subarchitectures.""" + + __inactive_color: str = "#1f78b4" + __active_color: str = "#faf18e" + + def __init__(self) -> None: + """Construct SubarchitectureOrder with default fields.""" + self.arch: rx.PyGraph = rx.PyGraph() + self.subarch_order: PartialOrder = PartialOrder({}) + self.desirable_subarchitectures: PartialOrder = PartialOrder({}) + self.__isomorphisms: dict[tuple[int, int], dict[tuple[int, int], dict[int, int]]] = {} + + self.__compute_subarchs() + self.__compute_subarch_order() + self.__compute_desirable_subarchitectures() + return + + @classmethod + def from_retworkx_graph(cls, graph: rx.PyGraph) -> SubarchitectureOrder: + """Construct SubarchitectureOrder from retworkx graph.""" + so = SubarchitectureOrder() + so.arch = graph + + so.__compute_subarchs() + so.__compute_subarch_order() + so.__compute_desirable_subarchitectures() + return so + + @classmethod + def from_coupling_map(cls, coupling_map: set[tuple[int, int]] | list[tuple[int, int]]) -> SubarchitectureOrder: + """Construct SubarchitectureOrder from coupling map defined as set of tuples of connected qubits.""" + num_nodes = max(max(int(u), int(v)) for u, v in coupling_map) + graph = rx.PyGraph() + graph.add_nodes_from(list(range(num_nodes + 1))) + graph.add_edges_from_no_data([tuple(edge) for edge in coupling_map]) + + return cls.from_retworkx_graph(graph) + + @classmethod + def from_backend(cls, backend: Backend) -> SubarchitectureOrder: + """Construct SubarchitectureOrder from coupling map defined by qiskit backend.""" + coupling_map = {(a, b) for a, b in backend.configuration().coupling_map} + return cls.from_coupling_map(coupling_map) + + @classmethod + def from_qmap_architecture(cls, arch: Architecture) -> SubarchitectureOrder: + """Construct SubarchitectureOrder from qmap Architecture object.""" + return cls.from_coupling_map(arch.coupling_map) + + @classmethod + def from_library(cls, lib_name: str | Path) -> SubarchitectureOrder: + """Construct SubarchitectureOrder from stored library.""" + path = Path(lib_name).with_suffix(".pickle") + with path.open("rb") as f: + temp = pickle.load(f) + + so = SubarchitectureOrder() + so.__dict__.update(temp.__dict__) + + return so + + @classmethod + def from_string(cls, path: str) -> SubarchitectureOrder: + """Construct SubarchitectureOrder from library name.""" + if path in precomputed_backends: + ref = resources.files("mqt.qmap") / "libs" / (path + ".pickle") + with resources.as_file(ref) as lib_path: + return cls.from_library(lib_path) + return SubarchitectureOrder() + + def optimal_candidates(self, nqubits: int) -> list[rx.PyGraph]: + """Return optimal subarchitecture candidate. + + nqubits : int + size of circuit for which the optimal candidate should be given. + """ + if nqubits <= 0 or nqubits > self.arch.num_nodes(): + raise ValueError( + "Number of qubits must not be smaller or equal 0 or larger then number of physical qubits of architecture." + ) + + if nqubits == self.arch.num_nodes(): + return [self.arch] + + cands = self.__cand(nqubits) + trans_ord = self.__transitive_closure(self.subarch_order) + ref_ord = self.__reflexive_closure(trans_ord) + + opt_cands = set(ref_ord[next(iter(cands))]) + for cand in cands: + opt_cands = opt_cands.intersection(set(ref_ord[cand])) + + ordered_cands = list(opt_cands) + ordered_cands.sort() + for cand in ordered_cands: + opt_cands = opt_cands.difference(trans_ord[cand]) + + return [self.sgs[n][i] for (n, i) in opt_cands] + + def covering(self, nqubits: int, size: int) -> list[rx.PyGraph]: + """ + Return covering for nqubit circuits. + + The size of the covering is limited by size. + Note that a smaller covering might be found. + """ + cov = self.__cand(nqubits) + po_trans = self.__transitive_closure(self.subarch_order) + ref_trans_po = self.__reflexive_closure(po_trans) + queue = list({el for cand in cov for el in ref_trans_po[cand]}) + queue.sort(reverse=True) + + po_inv = self.__inverse_relation(po_trans) + + while len(cov) > size: + d = queue.pop() + cov_d = cov.intersection(po_inv[d]) + if len(cov_d) > 1: + cov = cov.difference(cov_d) + cov.add(d) + + return [self.sgs[n][i] for n, i in cov] + + def store_library(self, lib_name: str | Path) -> None: + """Store ordering.""" + path = Path(lib_name).with_suffix(".pickle") + with path.open("wb") as f: + pickle.dump(self, f) + + def draw_subarchitecture(self, subarchitecture: rx.PyGraph | tuple[int, int]) -> figure.Figure: + """Return matplotlib figure showing subarchitecture within the entire architecture. + + Nodes that are part of the subarchitecture are drawn yellow. + Nodes that are not part of the subarchitecture are drawn blue. + """ + if isinstance(subarchitecture, tuple): + subarchitecture = self.sgs[subarchitecture[0]][subarchitecture[1]] + colors = [SubarchitectureOrder.__inactive_color for node in range(self.arch.num_nodes())] + for node in subarchitecture.nodes(): + colors[node] = SubarchitectureOrder.__active_color + return rx.visualization.mpl_draw(subarchitecture, node_color=colors) + + def draw_subarchitectures(self, subarchitectures: list[rx.PyGraph] | list[tuple[int, int]]) -> list[figure.Figure]: + """Return matplotlib figures showing subarchitectures within the entire architecture. + + For each subarchitecture one figure is drawn. + Nodes that are part of the subarchitecture are drawn yellow. + Nodes that are not part of the subarchitecture are drawn blue. + """ + return [self.draw_subarchitecture(subarchitecture) for subarchitecture in subarchitectures] + + def __compute_subarchs(self) -> None: + self.sgs: list[list[rx.PyGraph]] = [[] for i in range(self.arch.num_nodes() + 1)] + + for i in range(1, self.arch.num_nodes() + 1): + node_combinations = combinations(range(self.arch.num_nodes()), i) + for sg in (self.arch.subgraph(selected_nodes) for selected_nodes in node_combinations): + if rx.is_connected(sg): + new_class = True + for g in self.sgs[i]: + if rx.is_isomorphic(g, sg): + new_class = False + break + if new_class: + self.sgs[i].append(sg) + # init orders + for n in range(self.arch.num_nodes() + 1): + for i in range(len(self.sgs[n])): + self.subarch_order[(n, i)] = set() + self.desirable_subarchitectures[(n, i)] = set() + self.__isomorphisms[(n, i)] = {} + + def __compute_subarch_order(self) -> None: + for n, sgs_n in enumerate(self.sgs[:-1]): + for i, sg in enumerate(sgs_n): + for j, parent_sg in enumerate(self.sgs[n + 1]): + matcher = rx.graph_vf2_mapping(parent_sg, sg, subgraph=True) + for iso in matcher: + self.subarch_order[(n, i)].add((n + 1, j)) + iso_rev = {} + for key, val in iso.items(): + iso_rev[val] = key + self.__isomorphisms[(n, i)][(n + 1, j)] = iso_rev + break # One isomorphism suffices + + def __complete_isos(self) -> None: + for n in reversed(range(1, len(self.sgs[:-1]))): + for i in range(len(self.sgs[n])): + for _, i_prime in self.subarch_order[(n, i)]: + self.__combine_iso_with_parent(n, i, i_prime) + + def __combine_iso_with_parent(self, n: int, i: int, j: int) -> None: + """Combine all isomorphisms from sgs[n][i] with those from sgs[n+1][j].""" + first = self.__isomorphisms[(n, i)][(n + 1, j)] + for (row, k), second in self.__isomorphisms[(n + 1, j)].items(): + self.__isomorphisms[(n, i)][(row, k)] = SubarchitectureOrder.__combine_isos(first, second) + + @staticmethod + def __combine_isos(first: dict[int, int], second: dict[int, int]) -> dict[int, int]: + combined = {} + for src, img in first.items(): + combined[src] = second[img] + return combined + + def __transitive_closure(self, po: PartialOrder) -> PartialOrder: + po_trans: PartialOrder = PartialOrder({}) + po_trans[self.arch.num_nodes(), 0] = set() + + for n in reversed(range(1, len(self.sgs[:-1]))): + for i in range(len(self.sgs[n])): + new_rel = set(po[(n, i)]) + po_trans[(n, i)] = new_rel.copy() + for n_prime, i_prime in po_trans[(n, i)]: + new_rel = new_rel.union(po_trans[(n_prime, i_prime)]) + po_trans[(n, i)] = new_rel + + return po_trans + + def __reflexive_closure(self, po: PartialOrder) -> PartialOrder: + po_ref = PartialOrder({}) + for k, v in po.items(): + v_copy = v.copy() + v_copy.add(k) + po_ref[k] = v_copy + return po_ref + + def __inverse_relation(self, po: PartialOrder) -> PartialOrder: + po_inv = PartialOrder({}) + for n in range(self.arch.num_nodes() + 1): + for i in range(len(self.sgs[n])): + po_inv[(n, i)] = set() + for k, v in po.items(): + for e in v: + po_inv[e].add(k) + return po_inv + + def __path_order_less(self, n: int, i: int, n_prime: int, i_prime: int) -> bool: + lhs = self.sgs[n][i] + rhs = self.sgs[n_prime][i_prime] + iso = self.__isomorphisms[(n, i)][(n_prime, i_prime)] + for v in range(lhs.num_nodes()): + for w in range(lhs.num_nodes()): + if v is w: + continue + if ( + rx.dijkstra_shortest_path_lengths(lhs, v, lambda x: 1, goal=w)[w] + > rx.dijkstra_shortest_path_lengths(rhs, iso[v], lambda x: 1, goal=iso[w])[iso[w]] + ): + return True + return False + + def __compute_desirable_subarchitectures(self) -> None: + self.__complete_isos() + for n in reversed(range(1, len(self.sgs[:-1]))): + for i in range(len(self.sgs[n])): + val = self.__isomorphisms[(n, i)] + for n_prime, i_prime in val.keys(): + if self.__path_order_less(n, i, n_prime, i_prime): + self.desirable_subarchitectures[(n, i)].add((n_prime, i_prime)) + des = list(self.desirable_subarchitectures[(n, i)]) + des.sort() + new_des: set[tuple[int, int]] = set() + for j, (n_prime, i_prime) in enumerate(reversed(des)): + j = len(des) - j - 1 + if not any([(n_prime, i_prime) in self.subarch_order[k] for k in des[:j]]): + new_des.add((n_prime, i_prime)) + + self.desirable_subarchitectures[(n, i)] = new_des + if len(self.desirable_subarchitectures[(n, i)]) == 0: + self.desirable_subarchitectures[(n, i)].add((n, i)) + self.desirable_subarchitectures[self.arch.num_nodes(), 0] = {(self.arch.num_nodes(), 0)} + + def __cand(self, nqubits: int) -> set[tuple[int, int]]: + return { + des for (n, i), desirables in self.desirable_subarchitectures.items() if n == nqubits for des in desirables + } + + +def ibm_guadalupe_subarchitectures() -> SubarchitectureOrder: + """Load the precomputed ibm guadalupe subarchitectures.""" + ref = resources.files("mqt.qmap") / "libs" / "ibm_guadalupe_16.pickle" + with resources.as_file(ref) as path: + return SubarchitectureOrder.from_library(path) + + +def rigetti_16_subarchitectures() -> SubarchitectureOrder: + """Load the precomputed rigetti subarchitectures.""" + ref = resources.files("mqt.qmap") / "libs" / "rigetti_16.pickle" + with resources.as_file(ref) as path: + return SubarchitectureOrder.from_library(path) diff --git a/setup.py b/setup.py index 1515e6c1e..99f12d9c7 100644 --- a/setup.py +++ b/setup.py @@ -103,7 +103,11 @@ def build_extension(self, ext): cmdclass={"build_ext": CMakeBuild}, zip_safe=False, packages=find_namespace_packages(include=["mqt.*"]), - install_requires=["qiskit-terra>=0.20.2,<0.23.0", "retworkx>=0.11.0,<0.12.0"], + install_requires=[ + "qiskit-terra>=0.20.2,<0.23.0", + "retworkx[all]>=0.11.0,<0.12.0", + "importlib_resources>=5.9; python_version < '3.10'", + ], extras_require={ "test": ["pytest>=7", "mqt.qcec~=2.0.0rc9"], "coverage": ["mqt.qmap[test]", "coverage[toml]>=6.4.2,<6.6.0", "pytest-cov>=3.0,<4.1"], diff --git a/test/python/test_subarchitectures.py b/test/python/test_subarchitectures.py new file mode 100644 index 000000000..748eabafb --- /dev/null +++ b/test/python/test_subarchitectures.py @@ -0,0 +1,212 @@ +from pathlib import Path + +import pytest +import retworkx as rx +from mqt.qmap import Architecture +from mqt.qmap.subarchitectures import ( + SubarchitectureOrder, + ibm_guadalupe_subarchitectures, + rigetti_16_subarchitectures, +) + +from qiskit.providers.fake_provider import FakeLondon + + +@pytest.fixture +def ibm_guadalupe() -> SubarchitectureOrder: + return SubarchitectureOrder.from_coupling_map( + [ + [0, 1], + [1, 2], + [2, 3], + [3, 5], + [1, 4], + [5, 8], + [4, 7], + [6, 7], + [8, 9], + [7, 10], + [8, 11], + [10, 12], + [12, 15], + [12, 13], + [13, 14], + [11, 14], + ] + ) + + +@pytest.fixture +def rigetti16() -> SubarchitectureOrder: + return SubarchitectureOrder.from_coupling_map( + [ + [0, 1], + [1, 2], + [2, 3], + [3, 4], + [4, 5], + [5, 6], + [6, 7], + [7, 8], + [8, 9], + [9, 10], + [10, 11], + [11, 12], + [12, 13], + [13, 14], + [14, 15], + [0, 15], + [3, 12], + [4, 11], + ] + ) + + +@pytest.fixture +def rigetti16_opt() -> rx.PyGraph: + cm = [ + [0, 1], + [1, 2], + [2, 3], + [3, 4], + [4, 5], + [5, 6], + [6, 7], + [7, 8], + [8, 9], + [9, 10], + [10, 11], + [11, 12], + [12, 13], + [3, 12], + [4, 11], + ] + + num_nodes = max(max(int(u), int(v)) for u, v in cm) + graph = rx.PyGraph() + graph.add_nodes_from(list(range(num_nodes + 1))) + graph.add_edges_from_no_data([tuple(edge) for edge in cm]) + return graph + + +@pytest.fixture +def singleton_graph() -> rx.PyGraph: + g = rx.PyGraph() + g.add_node(0) + return g + + +def test_singleton_graph(singleton_graph: rx.PyGraph) -> None: + """Verify that singleton graph has trivial ordering.""" + + order = SubarchitectureOrder.from_retworkx_graph(singleton_graph) + + assert len(order.sgs) == 2 + assert len(order.sgs[0]) == 0 + assert len(order.sgs[1]) == 1 + assert rx.is_isomorphic(order.optimal_candidates(1)[0], singleton_graph) + + +def test_two_node_graph(singleton_graph: rx.PyGraph) -> None: + """Verify ordering for graph with two nodes and one edge.""" + + order = SubarchitectureOrder.from_coupling_map([[0, 1]]) + assert len(order.sgs) == 3 + assert len(order.sgs[0]) == 0 + assert len(order.sgs[1]) == 1 + assert len(order.sgs[2]) == 1 + assert rx.is_isomorphic(order.optimal_candidates(2)[0], order.sgs[2][0]) + assert rx.is_isomorphic(order.optimal_candidates(1)[0], singleton_graph) + + +def test_ibm_guadalupe_opt(ibm_guadalupe: SubarchitectureOrder) -> None: + opt_cand_9 = ibm_guadalupe.optimal_candidates(9) + assert len(opt_cand_9) == 2 + assert opt_cand_9[0].num_nodes() == 15 + assert opt_cand_9[1].num_nodes() == 15 + assert not rx.is_isomorphic(opt_cand_9[0], opt_cand_9[1]) + + +def test_ibm_guadalupe_cov(ibm_guadalupe: SubarchitectureOrder) -> None: + cov = ibm_guadalupe.covering(9, 2) + assert 1 <= len(cov) <= 2 + + for sg in ibm_guadalupe.sgs[9]: + covered = False + for co in cov: + if rx.is_subgraph_isomorphic(co, sg): + covered = True + break + assert covered + + +def test_rigetti16_opt(rigetti16: SubarchitectureOrder, rigetti16_opt: rx.PyGraph) -> None: + opt = rigetti16.optimal_candidates(10) + assert len(opt) == 1 + + opt_cand = opt[0] + assert rx.is_isomorphic(opt_cand, rigetti16_opt) + + +def test_rigetti16_opt_library(rigetti16_opt: rx.PyGraph) -> None: + opt = rigetti_16_subarchitectures().optimal_candidates(10) + assert len(opt) == 1 + + opt_cand = opt[0] + assert rx.is_isomorphic(opt_cand, rigetti16_opt) + + +def test_rigetti16_opt_library_from_str(rigetti16_opt: rx.PyGraph) -> None: + opt = SubarchitectureOrder.from_string("rigetti_16").optimal_candidates(10) + assert len(opt) == 1 + + opt_cand = opt[0] + assert rx.is_isomorphic(opt_cand, rigetti16_opt) + + +def test_ibm_guadalupe_library() -> None: + opt_cand_9 = ibm_guadalupe_subarchitectures().optimal_candidates(9) + assert len(opt_cand_9) == 2 + assert opt_cand_9[0].num_nodes() == 15 + assert opt_cand_9[1].num_nodes() == 15 + assert not rx.is_isomorphic(opt_cand_9[0], opt_cand_9[1]) + + +def test_store_subarch(ibm_guadalupe: SubarchitectureOrder) -> None: + ibm_guadalupe.store_library("tmp") + + p = Path("tmp.pickle") + + loaded_tmp = SubarchitectureOrder.from_library(p) + + if p.exists(): + p.unlink() + + opt_origin = ibm_guadalupe.optimal_candidates(8) + opt_loaded = loaded_tmp.optimal_candidates(8) + + assert len(opt_origin) == len(opt_loaded) + for opt_cand_orig, opt_cand_load in zip(opt_origin, opt_loaded): + assert rx.is_isomorphic(opt_cand_load, opt_cand_orig) + + +def test_subarchitecture_from_qmap_arch() -> None: + cm = {(0, 1), (1, 0), (1, 2), (2, 1)} + arch = Architecture(3, cm) + so_arch = SubarchitectureOrder.from_qmap_architecture(arch) + so_cm = SubarchitectureOrder.from_coupling_map(cm) + + assert so_arch.subarch_order == so_cm.subarch_order + + +def test_subarchitecture_from_qiskit_backend() -> None: + arch = FakeLondon() + so_arch = SubarchitectureOrder.from_backend(arch) + so_cm = SubarchitectureOrder.from_coupling_map(arch.configuration().coupling_map) + + assert so_arch.subarch_order == so_cm.subarch_order + + +def test_invalid_opt_cand_arg(ibm_guadalupe: SubarchitectureOrder) -> None: + with pytest.raises(ValueError): + ibm_guadalupe.optimal_candidates(100)