Repository: Qiskit/qiskit

Issue:
BasicSwap cannot handle move_measurements.qasm
In the process to understand #1575, I noticed that `BasicSwap` also fails with that example (in which `move_measurements.qasm` tries to be mapped). I managed to extract a minimal example:
```
        coupling = CouplingMap([[0, 1], [1, 2]])

        qr0 = QuantumRegister(1, 'q0')
        qr1 = QuantumRegister(1, 'q1')
        qr2 = QuantumRegister(1, 'q2')
        circuit = QuantumCircuit(qr0, qr1, qr2)
        circuit.cx(qr1[0], qr2[0])
        dag = circuit_to_dag(circuit)
        layout = Layout([(qr1, 0), (qr0, 0), (qr2, 0)])

        pass_ = BasicSwap(coupling, initial_layout=layout)
        after = pass_.run(dag)
```
This fails with `qiskit.dagcircuit.exceptions.DAGCircuitError: 'invalid wire mapping key q2[0]'`.


Discussion:

Resolving patch:
diff --git a/qiskit/mapper/_layout.py b/qiskit/mapper/_layout.py
--- a/qiskit/mapper/_layout.py
+++ b/qiskit/mapper/_layout.py
@@ -118,6 +118,14 @@ def add_register(self, reg):
         for bit in reg:
             self.add(bit)
 
+    def get_registers(self):
+        """
+        Returns the registers in the layout [QuantumRegister(2, 'qr0'), QuantumRegister(3, 'qr1')]
+        Returns:
+            List: A list of Register in the layout
+        """
+        return list(self.get_virtual_bits().keys())
+
     def set_length(self, amount_of_physical_bits):
         """
         Extends the layout length to `amount_of_physical_bits`.
diff --git a/qiskit/transpiler/passes/mapping/basic_swap.py b/qiskit/transpiler/passes/mapping/basic_swap.py
--- a/qiskit/transpiler/passes/mapping/basic_swap.py
+++ b/qiskit/transpiler/passes/mapping/basic_swap.py
@@ -79,11 +79,10 @@ def run(self, dag):
                         qubit_1 = current_layout[connected_wire_1]
                         qubit_2 = current_layout[connected_wire_2]
 
-                        # create the involved registers
-                        if qubit_1[0] not in swap_layer.qregs.values():
-                            swap_layer.add_qreg(qubit_1[0])
-                        if qubit_2[0] not in swap_layer.qregs.values():
-                            swap_layer.add_qreg(qubit_2[0])
+                        # create qregs
+                        for qreg in current_layout.get_registers():
+                            if qreg[0] not in swap_layer.qregs.values():
+                                swap_layer.add_qreg(qreg[0])
 
                         # create the swap operation
                         swap_layer.add_basis_element('swap', 2, 0, 0)


Test patch:
diff --git a/test/python/transpiler/test_basic_swap.py b/test/python/transpiler/test_basic_swap.py
--- a/test/python/transpiler/test_basic_swap.py
+++ b/test/python/transpiler/test_basic_swap.py
@@ -9,7 +9,7 @@
 
 import unittest
 from qiskit.transpiler.passes import BasicSwap
-from qiskit.mapper import CouplingMap
+from qiskit.mapper import CouplingMap, Layout
 from qiskit.converters import circuit_to_dag
 from qiskit import QuantumRegister, QuantumCircuit
 from qiskit.test import QiskitTestCase
@@ -333,6 +333,75 @@ def test_swap_between_qregs(self):
 
         self.assertEqual(circuit_to_dag(expected), after)
 
+    def test_initial_layout(self):
+        """ Using an initial_layout
+         0:q1:--(+)--
+                 |
+         1:q0:---|---
+                 |
+         2:q2:---.---
+
+         CouplingMap map: [0]--[1]--[2]
+
+         0:q1:--X-------
+                |
+         1:q0:--X---.---
+                    |
+         2:q2:-----(+)--
+
+        """
+        coupling = CouplingMap([[0, 1], [1, 2]])
+
+        qr = QuantumRegister(3, 'q')
+        circuit = QuantumCircuit(qr)
+        circuit.cx(qr[1], qr[2])
+        dag = circuit_to_dag(circuit)
+        layout = Layout([(qr, 1), (qr, 0), (qr, 2)])
+
+        expected = QuantumCircuit(qr)
+        expected.swap(qr[1], qr[0])
+        expected.cx(qr[0], qr[2])
+
+        pass_ = BasicSwap(coupling, initial_layout=layout)
+        after = pass_.run(dag)
+
+        self.assertEqual(circuit_to_dag(expected), after)
+
+    def test_initial_layout_in_different_qregs(self):
+        """ Using an initial_layout, and with several qregs
+         0:q1_0:--(+)--
+                   |
+         1:q0_0:---|---
+                   |
+         2:q2_0:---.---
+
+         CouplingMap map: [0]--[1]--[2]
+
+         0:q1_0:--X-------
+                  |
+         1:q0_0:--X---.---
+                      |
+         2:q2_0:-----(+)--
+        """
+        coupling = CouplingMap([[0, 1], [1, 2]])
+
+        qr0 = QuantumRegister(1, 'q0')
+        qr1 = QuantumRegister(1, 'q1')
+        qr2 = QuantumRegister(1, 'q2')
+        circuit = QuantumCircuit(qr0, qr1, qr2)
+        circuit.cx(qr1[0], qr2[0])
+        dag = circuit_to_dag(circuit)
+        layout = Layout([(qr1, 0), (qr0, 0), (qr2, 0)])
+
+        expected = QuantumCircuit(qr0, qr1, qr2)
+        expected.swap(qr1[0], qr0[0])
+        expected.cx(qr0[0], qr2[0])
+
+        pass_ = BasicSwap(coupling, initial_layout=layout)
+        after = pass_.run(dag)
+
+        self.assertEqual(circuit_to_dag(expected), after)
+
 
 if __name__ == '__main__':
     unittest.main()