From d2257c093fb6dcb6b386a4bba8d5a0074ceefba6 Mon Sep 17 00:00:00 2001 From: "Daniel J. Egger" <38065505+eggerdj@users.noreply.github.com> Date: Fri, 25 Oct 2024 16:22:14 +0200 Subject: [PATCH] Swap removal fix (#38) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --- .../transpilation/swap_cancellation_pass.py | 5 +-- test/test_qubit_selection.py | 15 +++---- test/test_swap_cancellation.py | 45 +++++++++++++++++++ 3 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 test/test_swap_cancellation.py diff --git a/qopt_best_practices/transpilation/swap_cancellation_pass.py b/qopt_best_practices/transpilation/swap_cancellation_pass.py index 431a4bf..ff9343d 100644 --- a/qopt_best_practices/transpilation/swap_cancellation_pass.py +++ b/qopt_best_practices/transpilation/swap_cancellation_pass.py @@ -18,8 +18,6 @@ def run(self, dag: DAGCircuit): qmap = self.property_set["virtual_permutation_layout"] - qreg = dag.qregs[next(iter(dag.qregs))] - # This will remove SWAP gates that are applied before anything else # This remove is executed multiple times until there are no more SWAP # gates left to remove. Note: a more inteligent DAG traversal could @@ -34,8 +32,7 @@ def run(self, dag: DAGCircuit): successors = list(dag.successors(node)) if len(successors) == 2: if all(isinstance(successors[idx], DAGOutNode) for idx in [0, 1]): - bits = [qreg.index(qubit) for qubit in node.qargs] - qmap[bits[0]], qmap[bits[1]] = qmap[bits[1]], qmap[bits[0]] + qmap.swap(node.qargs[0], node.qargs[1]) dag.remove_op_node(node) permuted = True diff --git a/test/test_qubit_selection.py b/test/test_qubit_selection.py index 80c5503..11d9cfb 100644 --- a/test/test_qubit_selection.py +++ b/test/test_qubit_selection.py @@ -4,7 +4,7 @@ import os from unittest import TestCase -from qiskit_ibm_runtime.fake_provider import FakeSherbrooke, FakeHanoi, FakeHanoiV2 +from qiskit_ibm_runtime.fake_provider import FakeSherbrooke, FakeHanoiV2 from qiskit.providers.fake_provider import GenericBackendV2 @@ -52,12 +52,9 @@ def test_qubit_selection(self): expected_path = [33, 39, 40, 72, 41, 81, 53, 60, 61, 62] self.assertEqual(set(path), set(expected_path)) - def test_qubit_selection_v1_v2(self): + def test_qubit_selection_v2(self): """Test backend evaluation for 10 qubit line""" - backends = [FakeHanoi(), FakeHanoiV2()] - - for backend in backends: - path_finder = BackendEvaluator(backend) - path, _, _ = path_finder.evaluate(len(self.mapped_graph)) - expected_path = [8, 9, 11, 12, 13, 14, 15, 18, 21, 23] - self.assertEqual(set(path), set(expected_path)) + path_finder = BackendEvaluator(FakeHanoiV2()) + path, _, _ = path_finder.evaluate(len(self.mapped_graph)) + expected_path = [8, 9, 11, 12, 13, 14, 15, 18, 21, 23] + self.assertEqual(set(path), set(expected_path)) diff --git a/test/test_swap_cancellation.py b/test/test_swap_cancellation.py new file mode 100644 index 0000000..1cd5d7b --- /dev/null +++ b/test/test_swap_cancellation.py @@ -0,0 +1,45 @@ +"""The the cancellation of unneeded SWAP gates.""" + + +from unittest import TestCase + +from qiskit import QuantumCircuit +from qiskit.converters import circuit_to_dag +from qiskit.transpiler import Layout + +from qopt_best_practices.transpilation.swap_cancellation_pass import SwapToFinalMapping + + +class TestSwapCancellation(TestCase): + """Test the swap cancellation pass.""" + + def test_simple(self): + """Simple test.""" + + qc = QuantumCircuit(4, 4) + qc.swap(3, 2) + qc.rzz(1.234, 1, 2) + qc.swap(1, 2) + + qreg = next(iter(qc.qregs)) + + swap_pass = SwapToFinalMapping() + layout = Layout( + { + 0: qreg[0], + 1: qreg[2], + 2: qreg[3], + 3: qreg[1], + } + ) + swap_pass.property_set["virtual_permutation_layout"] = layout + + dag = circuit_to_dag(qc) + _ = swap_pass.run(dag) + + new_layout = swap_pass.property_set["virtual_permutation_layout"] + + self.assertTrue(new_layout[0] == qreg[0]) + self.assertTrue(new_layout[1] == qreg[1]) + self.assertTrue(new_layout[2] == qreg[3]) + self.assertTrue(new_layout[3] == qreg[2])