Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
13 changes: 8 additions & 5 deletions qiskit/transpiler/passes/routing/layout_transformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,14 @@ def __init__(self, coupling_map: CouplingMap,
How many randomized trials to perform, taking the best circuit as output.
"""
super().__init__()
self.coupling_map = coupling_map
self.from_layout = from_layout
self.to_layout = to_layout
graph = coupling_map.graph.to_undirected()
if coupling_map:
self.coupling_map = coupling_map
graph = coupling_map.graph.to_undirected()
else:
self.coupling_map = CouplingMap.from_full(len(to_layout))
graph = self.coupling_map.graph
self.token_swapper = ApproximateTokenSwapper(graph, seed)
self.trials = trials

Expand Down Expand Up @@ -100,7 +104,6 @@ def run(self, dag):

perm_circ = self.token_swapper.permutation_circuit(permutation, self.trials)

edge_map = {vqubit: dag.qubits[pqubit]
for (pqubit, vqubit) in perm_circ.inputmap.items()}
dag.compose(perm_circ.circuit, edge_map=edge_map)
qubits = [dag.qubits[i[0]] for i in sorted(perm_circ.inputmap.items(), key=lambda x: x[0])]
dag.compose(perm_circ.circuit, qubits=qubits)
return dag
61 changes: 48 additions & 13 deletions test/python/transpiler/test_layout_transformation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2018.
# (C) Copyright IBM 2017, 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
Expand All @@ -14,8 +14,6 @@

import unittest

import numpy as np

from qiskit import QuantumRegister, QuantumCircuit
from qiskit.converters import circuit_to_dag
from qiskit.test import QiskitTestCase
Expand All @@ -30,24 +28,61 @@ class TestLayoutTransformation(QiskitTestCase):

def test_three_qubit(self):
"""Test if the permutation {0->2,1->0,2->1} is implemented correctly."""
np.random.seed(0)
v = QuantumRegister(3, 'v') # virtual qubits
coupling = CouplingMap([[0, 1], [1, 2]])
from_layout = Layout({v[0]: 0, v[1]: 1, v[2]: 2})
to_layout = Layout({v[0]: 2, v[1]: 0, v[2]: 1})
ltpass = LayoutTransformation(coupling_map=coupling,
from_layout=from_layout,
to_layout=to_layout)
qc = QuantumCircuit(3) # input (empty) physical circuit
to_layout=to_layout, seed=42)
qc = QuantumCircuit(3)
dag = circuit_to_dag(qc)
output_dag = ltpass.run(dag)

expected = QuantumCircuit(3)
expected.swap(1, 0)
expected.swap(1, 2)

self.assertEqual(circuit_to_dag(expected), output_dag)

def test_four_qubit(self):
"""Test if the permutation {0->3,1->0,2->1,3->2} is implemented correctly."""
v = QuantumRegister(4, 'v') # virtual qubits
coupling = CouplingMap([[0, 1], [1, 2], [2, 3]])
from_layout = Layout({v[0]: 0, v[1]: 1, v[2]: 2, v[3]: 3})
to_layout = Layout({v[0]: 3, v[1]: 0, v[2]: 1, v[3]: 2})
ltpass = LayoutTransformation(coupling_map=coupling,
from_layout=from_layout,
to_layout=to_layout, seed=42)
qc = QuantumCircuit(4) # input (empty) physical circuit
dag = circuit_to_dag(qc)
q = dag.qubits
output_dag = ltpass.run(dag)
# output_dag.draw()
# Check that only two swaps were performed
self.assertCountEqual(["swap"] * 2, [op.name for op in output_dag.topological_op_nodes()])
# And check that the swaps were first performed on {q0,q1} then on {q1,q2}.
self.assertEqual([frozenset([q[0], q[1]]), frozenset([q[1], q[2]])],
[frozenset(op.qargs) for op in output_dag.topological_op_nodes()])

expected = QuantumCircuit(4)
expected.swap(1, 0)
expected.swap(1, 2)
expected.swap(2, 3)

self.assertEqual(circuit_to_dag(expected), output_dag)

def test_full_connected_coupling_map(self):
"""Test if the permutation {0->3,1->0,2->1,3->2} in a fully connected map."""
v = QuantumRegister(4, 'v') # virtual qubits
from_layout = Layout({v[0]: 0, v[1]: 1, v[2]: 2, v[3]: 3})
to_layout = Layout({v[0]: 3, v[1]: 0, v[2]: 1, v[3]: 2})
ltpass = LayoutTransformation(coupling_map=None,
from_layout=from_layout,
to_layout=to_layout, seed=42)
qc = QuantumCircuit(4) # input (empty) physical circuit
dag = circuit_to_dag(qc)
output_dag = ltpass.run(dag)

expected = QuantumCircuit(4)
expected.swap(1, 0)
expected.swap(2, 1)
expected.swap(3, 2)

self.assertEqual(circuit_to_dag(expected), output_dag)


if __name__ == '__main__':
Expand Down