From 9b76707e0457c96543b81f4b88d14d1ef92af819 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Tue, 8 Oct 2024 11:42:19 +0200 Subject: [PATCH] * Added final SWAP removal. --- .../transpilation/swap_cancellation_pass.py | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 qopt_best_practices/transpilation/swap_cancellation_pass.py diff --git a/qopt_best_practices/transpilation/swap_cancellation_pass.py b/qopt_best_practices/transpilation/swap_cancellation_pass.py new file mode 100644 index 0000000..0f2d7e7 --- /dev/null +++ b/qopt_best_practices/transpilation/swap_cancellation_pass.py @@ -0,0 +1,44 @@ +"""Pass to remove SWAP gates that are not needed.""" + +from qiskit.dagcircuit import DAGOutNode, DAGCircuit +from qiskit.transpiler import TransformationPass + + +class SwapToFinalMapping(TransformationPass): + """Absorb any redundent SWAPs in the final layout. + + This pass should be executed after a SWAPStrategy has been applied to a block + of commuting gates. It will remove any final redundent SWAP gates and absorb + them into the virtual layout. This effectively undoes any possibly redundent + SWAP gates that the SWAPStrategy may have inserted. + """ + + def run(self, dag: DAGCircuit): + """run the pass.""" + + qmap = self.property_set["virtual_permutation_layout"] + + qreg = dag.qregs["q"] + + # 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 + # be implemented here. + + done = False + + while not done: + permuted = False + for node in dag.topological_op_nodes(): + if node.op.name == "swap": + 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]] + dag.remove_op_node(node) + permuted = True + + done = not permuted + + return dag