Repository: Qiskit/qiskit

Issue:
Swap mapper fails with certain inputs
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Informations

- **Qiskit Terra version**: master
- **Python version**:
- **Operating system**:

### What is the current behavior?
Mapper issue reported by @maikatakita 

```python
circuit = QuantumCircuit(qr,cr,name='test')
circuit.h(qr[0])
circuit.cx(qr[0],qr[1])
circuit.cx(qr[1],qr[2])
circuit.cx(qr[2],qr[3])
circuit.measure(qr[0],cr[0])
circuit.measure(qr[1],cr[1])
circuit.measure(qr[2],cr[2])
circuit.measure(qr[3],cr[3])
```

```python
from qiskit import compile, Aer
qobj=compile(circuit,
             backend=Aer.get_backend('qasm_simulator'),
             coupling_map = [[1, 0], [1, 2], [2, 3], [4, 3], [4, 10], [5, 4],
                             [5, 6], [5, 9], [6, 8], [7, 8], [9, 8], [9, 10],
                             [11, 3], [11, 10], [11, 12], [12, 2], [13, 1], [13, 12]],
            initial_layout={(qr.name, 0): ('q', 1),
                            (qr.name, 1): ('q', 2),
                            (qr.name, 2): ('q', 3),
                            (qr.name, 3): ('q', 5)})
```

Yields:
```python
MapperError: 'swap_mapper failed: layer 3, sublayer 0, "cx q[3],q[5];\n"'
```




Discussion:
Is this an issue you still get? I can't seem to recreate it locally.
@ajavadia can you confirm?
I was able to reproduce (or maybe a similar error) on the same circuit on master / 5f4102a8065ebf1772cde0acf69f2010b970d569 , `len(qr)==len(cr)==4`,  python3.5 .

Error is `MapperError: 'swap_mapper failed: layer 3, sublayer 0'` from https://github.com/Qiskit/qiskit-terra/blob/5f4102a8065ebf1772cde0acf69f2010b970d569/qiskit/mapper/mapping.py#L374 .

Resolving patch:
diff --git a/qiskit/transpiler/transpiler.py b/qiskit/transpiler/transpiler.py
--- a/qiskit/transpiler/transpiler.py
+++ b/qiskit/transpiler/transpiler.py
@@ -26,6 +26,8 @@
 from .passes.mapping.cx_direction import CXDirection
 from .passes.mapping.dense_layout import DenseLayout
 from .passes.mapping.trivial_layout import TrivialLayout
+from .passes.mapping.enlarge_with_ancilla import EnlargeWithAncilla
+from .passes.mapping.extend_layout import ExtendLayout
 
 from .exceptions import TranspilerError
 
@@ -135,13 +137,6 @@ def _transpilation(circuit, basis_gates=None, coupling_map=None,
             dense_layout.run(dag)
             initial_layout = dense_layout.property_set['layout']
 
-    # temporarily build old-style layout dict
-    # (TODO: remove after transition to StochasticSwap pass)
-    if isinstance(initial_layout, Layout):
-        layout = initial_layout.copy()
-        virtual_qubits = layout.get_virtual_bits()
-        initial_layout = {(v[0].name, v[1]): ('q', layout[v]) for v in virtual_qubits}
-
     final_dag = transpile_dag(dag, basis_gates=basis_gates,
                               coupling_map=coupling_map,
                               initial_layout=initial_layout,
@@ -172,19 +167,7 @@ def transpile_dag(dag, basis_gates=None, coupling_map=None,
 
             eg. [[0, 2], [1, 2], [1, 3], [3, 4]}
 
-        initial_layout (dict): A mapping of qubit to qubit::
-
-                              {
-                                ("q", start(int)): ("q", final(int)),
-                                ...
-                              }
-                              eg.
-                              {
-                                ("q", 0): ("q", 0),
-                                ("q", 1): ("q", 1),
-                                ("q", 2): ("q", 2),
-                                ("q", 3): ("q", 3)
-                              }
+        initial_layout (Layout): A layout object
         seed_mapper (int): random seed_mapper for the swap mapper
         pass_manager (PassManager): pass manager instance for the transpilation process
             If None, a default set of passes are run.
@@ -198,6 +181,7 @@ def transpile_dag(dag, basis_gates=None, coupling_map=None,
     # TODO: `coupling_map`, `initial_layout`, `seed_mapper` removed after mapper pass.
 
     # TODO: move this to the mapper pass
+
     num_qubits = sum([qreg.size for qreg in dag.qregs.values()])
     if num_qubits == 1:
         coupling_map = None
@@ -227,10 +211,26 @@ def transpile_dag(dag, basis_gates=None, coupling_map=None,
         if coupling_map:
             logger.info("pre-mapping properties: %s",
                         dag.properties())
-            # Insert swap gates
+
             coupling = CouplingMap(coupling_map)
-            logger.info("initial layout: %s", initial_layout)
 
+            # Extend and enlarge the the dag/layout with ancillas using the full coupling map
+            logger.info("initial layout: %s", initial_layout)
+            pass_ = ExtendLayout(coupling)
+            pass_.property_set['layout'] = initial_layout
+            pass_.run(dag)
+            initial_layout = pass_.property_set['layout']
+            pass_ = EnlargeWithAncilla(initial_layout)
+            dag = pass_.run(dag)
+            initial_layout = pass_.property_set['layout']
+            logger.info("initial layout (ancilla extended): %s", initial_layout)
+
+            # temporarily build old-style layout dict
+            # (TODO: remove after transition to StochasticSwap pass)
+            virtual_qubits = initial_layout.get_virtual_bits()
+            initial_layout = {(v[0].name, v[1]): ('q', initial_layout[v]) for v in virtual_qubits}
+
+            # Swap mapper
             dag, final_layout = swap_mapper(
                 dag, coupling, initial_layout, trials=20, seed=seed_mapper)
             logger.info("final layout: %s", final_layout)


Test patch:
diff --git a/test/python/compiler/test_compiler.py b/test/python/compiler/test_compiler.py
--- a/test/python/compiler/test_compiler.py
+++ b/test/python/compiler/test_compiler.py
@@ -24,6 +24,7 @@
 from qiskit.mapper.compiling import two_qubit_kak
 from qiskit.mapper.mapping import MapperError
 from qiskit.transpiler.passes import BarrierBeforeFinalMeasurements
+from qiskit.mapper import Layout
 
 
 class TestCompiler(QiskitTestCase):
@@ -630,10 +631,10 @@ def test_move_measurements(self):
             self._get_resource_path('move_measurements.qasm', Path.QASMS))
 
         dag_circuit = circuit_to_dag(circ)
-        lay = {('qa', 0): ('q', 0), ('qa', 1): ('q', 1), ('qb', 0): ('q', 15),
-               ('qb', 1): ('q', 2), ('qb', 2): ('q', 14), ('qN', 0): ('q', 3),
-               ('qN', 1): ('q', 13), ('qN', 2): ('q', 4), ('qc', 0): ('q', 12),
-               ('qNt', 0): ('q', 5), ('qNt', 1): ('q', 11), ('qt', 0): ('q', 6)}
+        lay = Layout({('qa', 0): ('q', 0), ('qa', 1): ('q', 1), ('qb', 0): ('q', 15),
+                      ('qb', 1): ('q', 2), ('qb', 2): ('q', 14), ('qN', 0): ('q', 3),
+                      ('qN', 1): ('q', 13), ('qN', 2): ('q', 4), ('qc', 0): ('q', 12),
+                      ('qNt', 0): ('q', 5), ('qNt', 1): ('q', 11), ('qt', 0): ('q', 6)})
         out_dag = transpile_dag(dag_circuit, initial_layout=lay, coupling_map=cmap)
         meas_nodes = out_dag.named_nodes('measure')
         for meas_node in meas_nodes:
@@ -660,7 +661,9 @@ def test_final_measurement_barrier_for_devices(self, mock_pass):
 
         circ = QuantumCircuit.from_qasm_file(self._get_resource_path('example.qasm', Path.QASMS))
         dag_circuit = circuit_to_dag(circ)
-        transpile_dag(dag_circuit, coupling_map=FakeRueschlikon().configuration().coupling_map)
+        layout = Layout.generate_trivial_layout(*circ.qregs)
+        transpile_dag(dag_circuit, coupling_map=FakeRueschlikon().configuration().coupling_map,
+                      initial_layout=layout)
 
         self.assertTrue(mock_pass.called)
 
diff --git a/test/python/transpiler/test_transpile.py b/test/python/transpiler/test_transpile.py
--- a/test/python/transpiler/test_transpile.py
+++ b/test/python/transpiler/test_transpile.py
@@ -9,12 +9,16 @@
 
 """Tests basic functionality of the transpile function"""
 
+import math
+
 from qiskit import QuantumRegister, QuantumCircuit
 from qiskit import compile, BasicAer
+from qiskit.extensions.standard import CnotGate
 from qiskit.transpiler import PassManager, transpile_dag, transpile
 from qiskit.compiler import assemble_circuits
 from qiskit.converters import circuit_to_dag
 from qiskit.test import QiskitTestCase
+from qiskit.test.mock import FakeMelbourne
 from qiskit.compiler import RunConfig
 
 
@@ -87,3 +91,62 @@ def test_transpile_basis_gates_no_backend_no_coupling_map(self):
         dag_circuit = circuit_to_dag(circuit2)
         resources_after = dag_circuit.count_ops()
         self.assertEqual({'u2': 2, 'cx': 4}, resources_after)
+
+    def test_transpile_non_adjacent_layout(self):
+        """Transpile pipeline can handle manual layout on non-adjacent qubits.
+
+        circuit:
+        qr0:-[H]--.------------  -> 1
+                  |
+        qr1:-----(+)--.--------  -> 2
+                      |
+        qr2:---------(+)--.----  -> 3
+                          |
+        qr3:-------------(+)---  -> 5
+
+        device:
+        0  -  1  -  2  -  3  -  4  -  5  -  6
+
+              |     |     |     |     |     |
+
+              13 -  12  - 11 -  10 -  9  -  8  -   7
+        """
+        qr = QuantumRegister(4, 'qr')
+        circuit = QuantumCircuit(qr)
+        circuit.h(qr[0])
+        circuit.cx(qr[0], qr[1])
+        circuit.cx(qr[1], qr[2])
+        circuit.cx(qr[2], qr[3])
+
+        coupling_map = FakeMelbourne().configuration().coupling_map
+        basis_gates = FakeMelbourne().configuration().basis_gates
+        initial_layout = [None, qr[0], qr[1], qr[2], None, qr[3]]
+
+        new_circuit = transpile(circuit,
+                                basis_gates=basis_gates,
+                                coupling_map=coupling_map,
+                                initial_layout=initial_layout)
+
+        for gate, qargs, _ in new_circuit.data:
+            if isinstance(gate, CnotGate):
+                self.assertIn([x[1] for x in qargs], coupling_map)
+
+    def test_transpile_qft_grid(self):
+        """Transpile pipeline can handle 8-qubit QFT on 14-qubit grid.
+        """
+        qr = QuantumRegister(8)
+        circuit = QuantumCircuit(qr)
+        for i, _ in enumerate(qr):
+            for j in range(i):
+                circuit.cu1(math.pi/float(2**(i-j)), qr[i], qr[j])
+            circuit.h(qr[i])
+
+        coupling_map = FakeMelbourne().configuration().coupling_map
+        basis_gates = FakeMelbourne().configuration().basis_gates
+        new_circuit = transpile(circuit,
+                                basis_gates=basis_gates,
+                                coupling_map=coupling_map)
+
+        for gate, qargs, _ in new_circuit.data:
+            if isinstance(gate, CnotGate):
+                self.assertIn([x[1] for x in qargs], coupling_map)