diff --git a/qiskit/transpiler/passes/layout/full_ancilla_allocation.py b/qiskit/transpiler/passes/layout/full_ancilla_allocation.py index db365a676be1..39944a6a4412 100644 --- a/qiskit/transpiler/passes/layout/full_ancilla_allocation.py +++ b/qiskit/transpiler/passes/layout/full_ancilla_allocation.py @@ -66,6 +66,7 @@ def run(self, dag): raise TranspilerError('FullAncillaAllocation pass requires property_set["layout"].') if layout: + FullAncillaAllocation.validate_layout(layout.get_registers(), set(dag.qregs.values())) layout_physical_qubits = list(range(max(layout.get_physical_bits()) + 1)) else: layout_physical_qubits = [] @@ -90,3 +91,13 @@ def run(self, dag): self.property_set['layout'][idle_q] = qreg[idx] return dag + + @staticmethod + def validate_layout(layout_qregs, dag_qregs): + """ + Checks if all the qregs in layout_qregs already exist in dag_qregs. Otherwise, raise. + """ + for qreg in layout_qregs: + if qreg not in dag_qregs: + raise TranspilerError('FullAncillaAllocation: The layout refers to a quantum ' + 'register that does not exist in circuit.') diff --git a/qiskit/transpiler/passes/layout/set_layout.py b/qiskit/transpiler/passes/layout/set_layout.py index 052475d9c44e..96e94139788a 100644 --- a/qiskit/transpiler/passes/layout/set_layout.py +++ b/qiskit/transpiler/passes/layout/set_layout.py @@ -41,5 +41,5 @@ def run(self, dag): Returns: DAGCircuit: the original DAG. """ - self.property_set['layout'] = self.layout + self.property_set['layout'] = None if self.layout is None else self.layout.copy() return dag diff --git a/test/python/compiler/test_transpiler.py b/test/python/compiler/test_transpiler.py index e7fed429a020..b4204242689c 100644 --- a/test/python/compiler/test_transpiler.py +++ b/test/python/compiler/test_transpiler.py @@ -30,7 +30,6 @@ from qiskit.circuit import Parameter, Gate from qiskit.compiler import transpile from qiskit.converters import circuit_to_dag -from qiskit.dagcircuit.exceptions import DAGCircuitError from qiskit.circuit.library import CXGate, U3Gate, U2Gate, U1Gate, RXGate, RYGate from qiskit.test import QiskitTestCase, Path from qiskit.test.mock import FakeMelbourne, FakeRueschlikon, FakeAlmaden @@ -423,8 +422,11 @@ def test_wrong_initial_layout(self): QuantumRegister(3, 'q')[1], QuantumRegister(3, 'q')[2]] - self.assertRaises(DAGCircuitError, transpile, - qc, backend, initial_layout=bad_initial_layout) + with self.assertRaises(TranspilerError) as cm: + transpile(qc, backend, initial_layout=bad_initial_layout) + + self.assertEqual("FullAncillaAllocation: The layout refers to a quantum register that does " + "not exist in circuit.", cm.exception.message) def test_parameterized_circuit_for_simulator(self): """Verify that a parameterized circuit can be transpiled for a simulator backend.""" diff --git a/test/python/transpiler/test_full_ancilla_allocation.py b/test/python/transpiler/test_full_ancilla_allocation.py index d5b6ef8ab9a2..86d5c22f8745 100644 --- a/test/python/transpiler/test_full_ancilla_allocation.py +++ b/test/python/transpiler/test_full_ancilla_allocation.py @@ -19,6 +19,7 @@ from qiskit.transpiler import CouplingMap, Layout from qiskit.transpiler.passes import FullAncillaAllocation from qiskit.test import QiskitTestCase +from qiskit.transpiler.exceptions import TranspilerError class TestFullAncillaAllocation(QiskitTestCase): @@ -146,6 +147,26 @@ def test_name_collision(self): self.assertEqual(len(other_reg), 2) self.assertRegex(other_reg.name, r'^ancilla\d+$') + def test_bad_layout(self): + """Layout referes to a register that do not exist in the circuit + """ + qr = QuantumRegister(3, 'q') + circ = QuantumCircuit(qr) + dag = circuit_to_dag(circ) + + initial_layout = Layout() + initial_layout[0] = QuantumRegister(4, 'q')[0] + initial_layout[1] = QuantumRegister(4, 'q')[1] + initial_layout[2] = QuantumRegister(4, 'q')[2] + + pass_ = FullAncillaAllocation(self.cmap5) + pass_.property_set['layout'] = initial_layout + + with self.assertRaises(TranspilerError) as cm: + pass_.run(dag) + self.assertEqual("FullAncillaAllocation: The layout refers to a quantum register that does " + "not exist in circuit.", cm.exception.message) + if __name__ == '__main__': unittest.main()