diff --git a/qiskit/compiler/transpiler.py b/qiskit/compiler/transpiler.py index 93a04b18ba..5514bb168f 100644 --- a/qiskit/compiler/transpiler.py +++ b/qiskit/compiler/transpiler.py @@ -24,6 +24,7 @@ from qiskit.circuit.quantumcircuit import QuantumCircuit from qiskit.circuit.quantumregister import Qubit from qiskit.dagcircuit import DAGCircuit from qiskit.providers.backend import Backend +from qiskit.providers.backend_compat import BackendV2Converter from qiskit.providers.models import BackendProperties from qiskit.pulse import Schedule, InstructionScheduleMap from qiskit.transpiler import Layout, CouplingMap, PropertySet @@ -316,6 +317,12 @@ def transpile( # pylint: disable=too-many-return-statements config = user_config.get_config() optimization_level = config.get("transpile_optimization_level", 1) + if backend is not None and getattr(backend, "version", 0) <= 1: + # This is a temporary conversion step to allow for a smoother transition + # to a fully target-based transpiler pipeline while maintaining the behavior + # of `transpile` with BackendV1 inputs. + backend = BackendV2Converter(backend) + if ( scheduling_method is not None and backend is None @@ -471,14 +478,8 @@ def _check_circuits_coupling_map(circuits, cmap, backend): if cmap is not None: max_qubits = cmap.size() elif backend is not None: - backend_version = getattr(backend, "version", 0) - if backend_version <= 1: - if not backend.configuration().simulator: - max_qubits = backend.configuration().n_qubits - else: - max_qubits = None - else: - max_qubits = backend.num_qubits + max_qubits = backend.num_qubits + for circuit in circuits: # If coupling_map is not None or num_qubits == 1 num_qubits = len(circuit.qubits) @@ -496,27 +497,15 @@ def _log_transpile_time(start_time, end_time): def _parse_inst_map(inst_map, backend): # try getting inst_map from user, else backend - if inst_map is None: - backend_version = getattr(backend, "version", 0) - if backend_version <= 1: - if hasattr(backend, "defaults"): - inst_map = getattr(backend.defaults(), "instruction_schedule_map", None) - else: - inst_map = backend.target.instruction_schedule_map() + if inst_map is None and backend is not None: + inst_map = backend.target.instruction_schedule_map() return inst_map def _parse_coupling_map(coupling_map, backend): # try getting coupling_map from user, else backend - if coupling_map is None: - backend_version = getattr(backend, "version", 0) - if backend_version <= 1: - if getattr(backend, "configuration", None): - configuration = backend.configuration() - if hasattr(configuration, "coupling_map") and configuration.coupling_map: - coupling_map = CouplingMap(configuration.coupling_map) - else: - coupling_map = backend.coupling_map + if coupling_map is None and backend is not None: + coupling_map = backend.coupling_map # coupling_map could be None, or a list of lists, e.g. [[0, 1], [2, 1]] if coupling_map is None or isinstance(coupling_map, CouplingMap): @@ -553,14 +542,8 @@ def _parse_instruction_durations(backend, inst_durations, dt, circuit): take precedence over backend durations, but be superceded by ``inst_duration``s. """ if not inst_durations: - backend_version = getattr(backend, "version", 0) - if backend_version <= 1: - backend_durations = InstructionDurations() - try: - backend_durations = InstructionDurations.from_backend(backend) - except AttributeError: - pass - else: + backend_durations = InstructionDurations() + if backend is not None: backend_durations = backend.instruction_durations circ_durations = InstructionDurations() @@ -629,13 +612,6 @@ def _parse_timing_constraints(backend, timing_constraints): return timing_constraints if backend is None and timing_constraints is None: timing_constraints = TimingConstraints() - else: - backend_version = getattr(backend, "version", 0) - if backend_version <= 1: - if timing_constraints is None: - # get constraints from backend - timing_constraints = getattr(backend.configuration(), "timing_constraints", {}) - timing_constraints = TimingConstraints(**timing_constraints) - else: - timing_constraints = backend.target.timing_constraints() + elif backend is not None: + timing_constraints = backend.target.timing_constraints() return timing_constraints diff --git a/qiskit/providers/backend_compat.py b/qiskit/providers/backend_compat.py index de57f3f09f..e567c330a9 100644 --- a/qiskit/providers/backend_compat.py +++ b/qiskit/providers/backend_compat.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2024. # # 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 @@ -57,7 +57,7 @@ def convert_to_target( A ``Target`` instance. """ - # importing pacakges where they are needed, to avoid cyclic-import. + # importing packages where they are needed, to avoid cyclic-import. # pylint: disable=cyclic-import from qiskit.transpiler.target import ( Target, @@ -82,7 +82,7 @@ def convert_to_target( "switch_case": SwitchCaseOp, } - in_data = {"num_qubits": configuration.n_qubits} + in_data = {"num_qubits": configuration.num_qubits} # Parse global configuration properties if hasattr(configuration, "dt"): @@ -97,7 +97,6 @@ def convert_to_target( all_instructions = set.union( basis_gates, set(required), supported_instructions.intersection(CONTROL_FLOW_OP_NAMES) ) - inst_name_map = {} # type: Dict[str, Instruction] faulty_ops = set() @@ -244,10 +243,8 @@ def convert_to_target( for name in inst_sched_map.instructions: for qubits in inst_sched_map.qubits_with_instruction(name): - if not isinstance(qubits, tuple): qubits = (qubits,) - if ( name not in all_instructions or name not in prop_name_map @@ -267,17 +264,18 @@ def convert_to_target( continue entry = inst_sched_map._get_calibration_entry(name, qubits) - try: prop_name_map[name][qubits].calibration = entry except AttributeError: + # if instruction properties are "None", add entry + prop_name_map[name].update({qubits: InstructionProperties(None, None, entry)}) logger.info( "The PulseDefaults payload received contains an instruction %s on " - "qubits %s which is not present in the configuration or properties payload.", + "qubits %s which is not present in the configuration or properties payload." + "A new properties entry will be added to include the new calibration data.", name, qubits, ) - # Add parsed properties to target target = Target(**in_data) for inst_name in all_instructions: @@ -384,7 +382,7 @@ class BackendV2Converter(BackendV2): super().__init__( provider=backend.provider, name=backend.name(), - description=self._config.description, + description=getattr(self._config, "description", None), online_date=getattr(self._config, "online_date", None), backend_version=self._config.backend_version, ) diff --git a/qiskit/providers/fake_provider/fake_1q.py b/qiskit/providers/fake_provider/fake_1q.py index 0758947614..09959620bc 100644 --- a/qiskit/providers/fake_provider/fake_1q.py +++ b/qiskit/providers/fake_provider/fake_1q.py @@ -32,7 +32,7 @@ class Fake1Q(FakeBackend): configuration = BackendProperties( backend_name="fake_1q", backend_version="0.0.0", - n_qubits=1, + num_qubits=1, basis_gates=["u1", "u2", "u3", "cx"], simulator=False, local=True, diff --git a/releasenotes/notes/use-target-in-transpile-7c04b14549a11f40.yaml b/releasenotes/notes/use-target-in-transpile-7c04b14549a11f40.yaml new file mode 100644 index 0000000000..8e385ba019 --- /dev/null +++ b/releasenotes/notes/use-target-in-transpile-7c04b14549a11f40.yaml @@ -0,0 +1,8 @@ +--- +upgrade: + - | + The :func:`.transpile` function has been upgraded to internally convert + `backend` inputs of type :class:`.BackendV1` to :class:`.BackendV2`, + which allows the transpilation pipeline to now access the backend + constraints through a :class:`.Target`. This change does not require any + user action. \ No newline at end of file diff --git a/test/python/transpiler/test_1q.py b/test/python/transpiler/test_1q.py index 31975456f3..50bdc7b246 100644 --- a/test/python/transpiler/test_1q.py +++ b/test/python/transpiler/test_1q.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2019. +# (C) Copyright IBM 2019, 2024. # # 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 @@ -17,6 +17,7 @@ from ddt import ddt from qiskit import QuantumCircuit from qiskit.compiler import transpile from qiskit.providers.fake_provider import Fake1Q +from qiskit.providers.basic_provider import BasicSimulator from qiskit.transpiler import TranspilerError from test import combine # pylint: disable=wrong-import-order from test import QiskitTestCase # pylint: disable=wrong-import-order @@ -76,9 +77,7 @@ class Test1QWorking(QiskitTestCase): name="{circuit.__name__}_level{level}_valid", ) def test_simulator(self, circuit, level): - """All the levels with all the 1Q simulator backend""" - # Set fake backend config to simulator - backend = Fake1Q() - backend._configuration.simulator = True + """All the levels with a simulator backend""" + backend = BasicSimulator() result = transpile(circuit(), backend=backend, optimization_level=level, seed_transpiler=42) self.assertIsInstance(result, QuantumCircuit) diff --git a/test/python/transpiler/test_preset_passmanagers.py b/test/python/transpiler/test_preset_passmanagers.py index ae1837bf11..247aa82ec0 100644 --- a/test/python/transpiler/test_preset_passmanagers.py +++ b/test/python/transpiler/test_preset_passmanagers.py @@ -324,7 +324,7 @@ class TestPassesInspection(QiskitTestCase): qc = QuantumCircuit(qr) qc.cx(qr[2], qr[4]) - backend = GenericBackendV2(num_qubits=14, coupling_map=MELBOURNE_CMAP) + backend = GenericBackendV2(num_qubits=14, coupling_map=MELBOURNE_CMAP, seed=42) _ = transpile(qc, backend, optimization_level=level, callback=self.callback) @@ -413,7 +413,7 @@ class TestPassesInspection(QiskitTestCase): """Custom post translation stage.""" return "custom_stage_for_test" - target = TargetBackend(num_qubits=7) + target = TargetBackend(num_qubits=7, seed=42) qr = QuantumRegister(2, "q") qc = QuantumCircuit(qr) qc.h(qr[0]) @@ -425,7 +425,7 @@ class TestPassesInspection(QiskitTestCase): def test_level1_runs_vf2post_layout_when_routing_required(self): """Test that if we run routing as part of sabre layout VF2PostLayout runs.""" - target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP) + target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42) qc = QuantumCircuit(5) qc.h(0) qc.cy(0, 1) @@ -448,7 +448,7 @@ class TestPassesInspection(QiskitTestCase): def test_level1_runs_vf2post_layout_when_routing_method_set_and_required(self): """Test that if we run routing as part of sabre layout VF2PostLayout runs.""" - target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP) + target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42) qc = QuantumCircuit(5) qc.h(0) qc.cy(0, 1) @@ -473,7 +473,10 @@ class TestPassesInspection(QiskitTestCase): def test_level1_not_runs_vf2post_layout_when_layout_method_set(self): """Test that if we don't run VF2PostLayout with custom layout_method.""" target = GenericBackendV2( - num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP + num_qubits=7, + basis_gates=["cx", "id", "rz", "sx", "x"], + coupling_map=LAGOS_CMAP, + seed=42, ) qc = QuantumCircuit(5) qc.h(0) @@ -495,7 +498,10 @@ class TestPassesInspection(QiskitTestCase): def test_level1_not_run_vf2post_layout_when_trivial_is_perfect(self): """Test that if we find a trivial perfect layout we don't run vf2post.""" target = GenericBackendV2( - num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP + num_qubits=7, + basis_gates=["cx", "id", "rz", "sx", "x"], + coupling_map=LAGOS_CMAP, + seed=42, ) qc = QuantumCircuit(2) qc.h(0) @@ -512,7 +518,10 @@ class TestPassesInspection(QiskitTestCase): def test_level1_not_run_vf2post_layout_when_vf2layout_is_perfect(self): """Test that if we find a vf2 perfect layout we don't run vf2post.""" target = GenericBackendV2( - num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP + num_qubits=7, + basis_gates=["cx", "id", "rz", "sx", "x"], + coupling_map=LAGOS_CMAP, + seed=42, ) qc = QuantumCircuit(4) qc.h(0) @@ -531,7 +540,10 @@ class TestPassesInspection(QiskitTestCase): def test_level1_runs_vf2post_layout_when_routing_required_control_flow(self): """Test that if we run routing as part of sabre layout VF2PostLayout runs.""" target = GenericBackendV2( - num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP + num_qubits=7, + basis_gates=["cx", "id", "rz", "sx", "x"], + coupling_map=LAGOS_CMAP, + seed=42, ) _target = target.target target._target.add_instruction(ForLoopOp, name="for_loop") @@ -558,7 +570,10 @@ class TestPassesInspection(QiskitTestCase): def test_level1_not_runs_vf2post_layout_when_layout_method_set_control_flow(self): """Test that if we don't run VF2PostLayout with custom layout_method.""" target = GenericBackendV2( - num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP + num_qubits=7, + basis_gates=["cx", "id", "rz", "sx", "x"], + coupling_map=LAGOS_CMAP, + seed=42, ) _target = target.target target._target.add_instruction(ForLoopOp, name="for_loop") @@ -584,7 +599,10 @@ class TestPassesInspection(QiskitTestCase): def test_level1_not_run_vf2post_layout_when_trivial_is_perfect_control_flow(self): """Test that if we find a trivial perfect layout we don't run vf2post.""" target = GenericBackendV2( - num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP + num_qubits=7, + basis_gates=["cx", "id", "rz", "sx", "x"], + coupling_map=LAGOS_CMAP, + seed=42, ) _target = target.target target._target.add_instruction(ForLoopOp, name="for_loop") @@ -604,7 +622,10 @@ class TestPassesInspection(QiskitTestCase): def test_level1_not_run_vf2post_layout_when_vf2layout_is_perfect_control_flow(self): """Test that if we find a vf2 perfect layout we don't run vf2post.""" target = GenericBackendV2( - num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP + num_qubits=7, + basis_gates=["cx", "id", "rz", "sx", "x"], + coupling_map=LAGOS_CMAP, + seed=42, ) _target = target.target target._target.add_instruction(ForLoopOp, name="for_loop") @@ -630,7 +651,7 @@ class TestInitialLayouts(QiskitTestCase): @data(0, 1, 2, 3) def test_layout_1711(self, level): - """Test that a user-given initial layout is respected, + """Test that a user-given initial layout is respected in the qobj. See: https://github.com/Qiskit/qiskit-terra/issues/1711 @@ -661,9 +682,7 @@ class TestInitialLayouts(QiskitTestCase): 14: ancilla[12], 15: qr[2], } - - backend = Fake20QV1() - backend.configuration().coupling_map = RUESCHLIKON_CMAP + backend = GenericBackendV2(num_qubits=16, coupling_map=RUESCHLIKON_CMAP, seed=42) qc_b = transpile(qc, backend, initial_layout=initial_layout, optimization_level=level) qobj = assemble(qc_b) @@ -672,7 +691,7 @@ class TestInitialLayouts(QiskitTestCase): compiled_ops = qobj.experiments[0].instructions for operation in compiled_ops: if operation.name == "cx": - self.assertIn(operation.qubits, backend.configuration().coupling_map) + self.assertIn(tuple(operation.qubits), backend.coupling_map) self.assertIn(operation.qubits, [[15, 0], [15, 2]]) @data(0, 1, 2, 3) @@ -711,10 +730,8 @@ class TestInitialLayouts(QiskitTestCase): 12: ancilla[7], 13: ancilla[8], } - backend = Fake20QV1() - backend.configuration().coupling_map = MELBOURNE_CMAP + backend = GenericBackendV2(num_qubits=14, coupling_map=MELBOURNE_CMAP, seed=42) qc_b = transpile(qc, backend, initial_layout=initial_layout, optimization_level=level) - self.assertEqual(qc_b._layout.initial_layout._p2v, final_layout) output_qr = qc_b.qregs[0] @@ -766,7 +783,6 @@ class TestInitialLayouts(QiskitTestCase): } backend = Fake20QV1() - qc_b = transpile(qc, backend, initial_layout=initial_layout, optimization_level=level) self.assertEqual(qc_b._layout.initial_layout._p2v, final_layout) @@ -796,50 +812,51 @@ class TestFinalLayouts(QiskitTestCase): qc.cx(qr1[2], qr2[0]) qc.cx(qr2[0], qr2[1]) + ancilla = QuantumRegister(15, "ancilla") trivial_layout = { - 0: Qubit(QuantumRegister(3, "qr1"), 0), - 1: Qubit(QuantumRegister(3, "qr1"), 1), - 2: Qubit(QuantumRegister(3, "qr1"), 2), - 3: Qubit(QuantumRegister(2, "qr2"), 0), - 4: Qubit(QuantumRegister(2, "qr2"), 1), - 5: Qubit(QuantumRegister(15, "ancilla"), 0), - 6: Qubit(QuantumRegister(15, "ancilla"), 1), - 7: Qubit(QuantumRegister(15, "ancilla"), 2), - 8: Qubit(QuantumRegister(15, "ancilla"), 3), - 9: Qubit(QuantumRegister(15, "ancilla"), 4), - 10: Qubit(QuantumRegister(15, "ancilla"), 5), - 11: Qubit(QuantumRegister(15, "ancilla"), 6), - 12: Qubit(QuantumRegister(15, "ancilla"), 7), - 13: Qubit(QuantumRegister(15, "ancilla"), 8), - 14: Qubit(QuantumRegister(15, "ancilla"), 9), - 15: Qubit(QuantumRegister(15, "ancilla"), 10), - 16: Qubit(QuantumRegister(15, "ancilla"), 11), - 17: Qubit(QuantumRegister(15, "ancilla"), 12), - 18: Qubit(QuantumRegister(15, "ancilla"), 13), - 19: Qubit(QuantumRegister(15, "ancilla"), 14), + 0: qr1[0], + 1: qr1[1], + 2: qr1[2], + 3: qr2[0], + 4: qr2[1], + 5: ancilla[0], + 6: ancilla[1], + 7: ancilla[2], + 8: ancilla[3], + 9: ancilla[4], + 10: ancilla[5], + 11: ancilla[6], + 12: ancilla[7], + 13: ancilla[8], + 14: ancilla[9], + 15: ancilla[10], + 16: ancilla[11], + 17: ancilla[12], + 18: ancilla[13], + 19: ancilla[14], } vf2_layout = { - 0: Qubit(QuantumRegister(15, "ancilla"), 0), - 1: Qubit(QuantumRegister(15, "ancilla"), 1), - 2: Qubit(QuantumRegister(15, "ancilla"), 2), - 3: Qubit(QuantumRegister(15, "ancilla"), 3), - 4: Qubit(QuantumRegister(15, "ancilla"), 4), - 5: Qubit(QuantumRegister(15, "ancilla"), 5), - 6: Qubit(QuantumRegister(15, "ancilla"), 6), - 7: Qubit(QuantumRegister(15, "ancilla"), 7), - 8: Qubit(QuantumRegister(3, "qr1"), 1), - 9: Qubit(QuantumRegister(15, "ancilla"), 8), - 10: Qubit(QuantumRegister(15, "ancilla"), 9), - 11: Qubit(QuantumRegister(15, "ancilla"), 10), - 12: Qubit(QuantumRegister(3, "qr1"), 0), - 13: Qubit(QuantumRegister(3, "qr1"), 2), - 14: Qubit(QuantumRegister(2, "qr2"), 1), - 15: Qubit(QuantumRegister(15, "ancilla"), 11), - 16: Qubit(QuantumRegister(15, "ancilla"), 12), - 17: Qubit(QuantumRegister(15, "ancilla"), 13), - 18: Qubit(QuantumRegister(15, "ancilla"), 14), - 19: Qubit(QuantumRegister(2, "qr2"), 0), + 0: ancilla[0], + 1: ancilla[1], + 2: ancilla[2], + 3: ancilla[3], + 4: ancilla[4], + 5: qr1[2], + 6: qr2[0], + 7: qr2[1], + 8: ancilla[5], + 9: ancilla[6], + 10: qr1[1], + 11: qr1[0], + 12: ancilla[7], + 13: ancilla[8], + 14: ancilla[9], + 15: ancilla[10], + 16: ancilla[11], + 17: ancilla[12], + 18: ancilla[13], + 19: ancilla[14], } # Trivial layout @@ -856,8 +873,8 @@ class TestFinalLayouts(QiskitTestCase): expected_layout_level2, expected_layout_level3, ] - backend = Fake20QV1() - backend.configuration().coupling_map = TOKYO_CMAP + + backend = GenericBackendV2(num_qubits=20, coupling_map=TOKYO_CMAP, seed=42) result = transpile(qc, backend, optimization_level=level, seed_transpiler=42) self.assertEqual(result._layout.initial_layout._p2v, expected_layouts[level]) @@ -904,64 +921,18 @@ class TestFinalLayouts(QiskitTestCase): 2: ancilla[2], 3: ancilla[3], 4: ancilla[4], - 5: qr[2], - 6: qr[1], - 7: ancilla[6], - 8: ancilla[7], - 9: ancilla[8], - 10: qr[3], - 11: qr[0], - 12: ancilla[9], - 13: ancilla[10], - 14: ancilla[11], - 15: ancilla[5], - 16: qr[4], - 17: ancilla[12], - 18: ancilla[13], - 19: ancilla[14], - } - - sabre_layout_lvl_2 = { - 0: ancilla[0], - 1: ancilla[1], - 2: ancilla[2], - 3: ancilla[3], - 4: ancilla[4], - 5: qr[2], - 6: qr[1], - 7: ancilla[6], - 8: ancilla[7], - 9: ancilla[8], - 10: qr[3], - 11: qr[0], - 12: ancilla[9], - 13: ancilla[10], - 14: ancilla[11], - 15: ancilla[5], - 16: qr[4], - 17: ancilla[12], - 18: ancilla[13], - 19: ancilla[14], - } - - sabre_layout_lvl_3 = { - 0: ancilla[0], - 1: ancilla[1], - 2: ancilla[2], - 3: ancilla[3], - 4: ancilla[4], - 5: qr[2], - 6: qr[1], - 7: ancilla[6], - 8: ancilla[7], - 9: ancilla[8], - 10: qr[3], - 11: qr[0], - 12: ancilla[9], - 13: ancilla[10], - 14: ancilla[11], - 15: ancilla[5], - 16: qr[4], + 5: qr[1], + 6: qr[0], + 7: qr[4], + 8: ancilla[6], + 9: ancilla[7], + 10: qr[2], + 11: qr[3], + 12: ancilla[5], + 13: ancilla[8], + 14: ancilla[9], + 15: ancilla[10], + 16: ancilla[11], 17: ancilla[12], 18: ancilla[13], 19: ancilla[14], @@ -969,8 +940,8 @@ class TestFinalLayouts(QiskitTestCase): expected_layout_level0 = trivial_layout expected_layout_level1 = sabre_layout - expected_layout_level2 = sabre_layout_lvl_2 - expected_layout_level3 = sabre_layout_lvl_3 + expected_layout_level2 = sabre_layout + expected_layout_level3 = sabre_layout expected_layouts = [ expected_layout_level0, @@ -978,9 +949,7 @@ class TestFinalLayouts(QiskitTestCase): expected_layout_level2, expected_layout_level3, ] - backend = Fake20QV1() - backend.configuration().coupling_map = TOKYO_CMAP - + backend = GenericBackendV2(num_qubits=20, coupling_map=TOKYO_CMAP, seed=42) result = transpile(qc, backend, optimization_level=level, seed_transpiler=42) self.assertEqual(result._layout.initial_layout._p2v, expected_layouts[level]) @@ -991,12 +960,10 @@ class TestFinalLayouts(QiskitTestCase): See: https://github.com/Qiskit/qiskit-terra/issues/5694 for more details """ - backend = Fake20QV1() - backend.configuration().coupling_map = TOKYO_CMAP - config = backend.configuration() + backend = GenericBackendV2(num_qubits=20, coupling_map=TOKYO_CMAP, seed=42) - rows = [x[0] for x in config.coupling_map] - cols = [x[1] for x in config.coupling_map] + rows = [x[0] for x in backend.coupling_map] + cols = [x[1] for x in backend.coupling_map] adjacency_matrix = np.zeros((20, 20)) adjacency_matrix[rows, cols] = 1 @@ -1255,7 +1222,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase): @data(0, 1, 2, 3) def test_with_no_backend(self, optimization_level): """Test a passmanager is constructed with no backend and optimization level.""" - target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP) + target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42) pm = generate_preset_pass_manager( optimization_level, coupling_map=target.coupling_map, @@ -1270,7 +1237,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase): @data(0, 1, 2, 3) def test_with_no_backend_only_target(self, optimization_level): """Test a passmanager is constructed with a manual target and optimization level.""" - target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP) + target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42) pm = generate_preset_pass_manager(optimization_level, target=target.target) self.assertIsInstance(pm, PassManager) @@ -1299,7 +1266,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase): """Custom post translation stage.""" return "custom_stage_for_test" - target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP) + target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42) pm = generate_preset_pass_manager(optimization_level, backend=target) self.assertIsInstance(pm, PassManager) @@ -1331,7 +1298,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase): """Custom post translation stage.""" return "custom_stage_for_test" - target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP) + target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42) pm = generate_preset_pass_manager(optimization_level, backend=target) self.assertIsInstance(pm, PassManager) @@ -1363,7 +1330,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase): """Custom post translation stage.""" return "custom_stage_for_test" - target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP) + target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42) pm = generate_preset_pass_manager(optimization_level, backend=target) self.assertIsInstance(pm, PassManager) @@ -1395,7 +1362,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase): """Custom post translation stage.""" return "custom_stage_for_test" - target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP) + target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42) pm = generate_preset_pass_manager(optimization_level, backend=target) self.assertIsInstance(pm, PassManager) diff --git a/test/python/transpiler/test_pulse_gate_pass.py b/test/python/transpiler/test_pulse_gate_pass.py index 8de8ceb66e..a11d4c4a6b 100644 --- a/test/python/transpiler/test_pulse_gate_pass.py +++ b/test/python/transpiler/test_pulse_gate_pass.py @@ -16,6 +16,7 @@ import ddt from qiskit import pulse, circuit, transpile from qiskit.providers.fake_provider import Fake27QPulseV1, GenericBackendV2 +from qiskit.providers.models import GateConfig from qiskit.quantum_info.random import random_unitary from test import QiskitTestCase # pylint: disable=wrong-import-order @@ -185,6 +186,12 @@ class TestPulseGate(QiskitTestCase): backend.defaults().instruction_schedule_map.add( "my_gate", (1,), self.my_gate_q1, arguments=["P0"] ) + # Add gate to backend configuration + backend.configuration().basis_gates.append("my_gate") + dummy_config = GateConfig( + name="my_gate", parameters=[], qasm_def="", coupling_map=[(0,), (1,)] + ) + backend.configuration().gates.append(dummy_config) # Remove timing constraints to avoid triggering # scheduling passes. backend.configuration().timing_constraints = {} @@ -212,6 +219,10 @@ class TestPulseGate(QiskitTestCase): backend.defaults().instruction_schedule_map.add( "my_gate", (0,), self.my_gate_q0, arguments=["P0"] ) + # Add gate to backend configuration + backend.configuration().basis_gates.append("my_gate") + dummy_config = GateConfig(name="my_gate", parameters=[], qasm_def="", coupling_map=[(0,)]) + backend.configuration().gates.append(dummy_config) # Remove timing constraints to avoid triggering # scheduling passes. backend.configuration().timing_constraints = {} @@ -237,6 +248,10 @@ class TestPulseGate(QiskitTestCase): backend.defaults().instruction_schedule_map.add( "my_gate", (0,), self.my_gate_q0, arguments=["P0"] ) + # Add gate to backend configuration + backend.configuration().basis_gates.append("my_gate") + dummy_config = GateConfig(name="my_gate", parameters=[], qasm_def="", coupling_map=[(0,)]) + backend.configuration().gates.append(dummy_config) # Remove timing constraints to avoid triggering # scheduling passes. backend.configuration().timing_constraints = {} @@ -263,6 +278,10 @@ class TestPulseGate(QiskitTestCase): backend.defaults().instruction_schedule_map.add( "my_gate", (0,), self.my_gate_q0, arguments=["P0"] ) + # Add gate to backend configuration + backend.configuration().basis_gates.append("my_gate") + dummy_config = GateConfig(name="my_gate", parameters=[], qasm_def="", coupling_map=[(0,)]) + backend.configuration().gates.append(dummy_config) # Remove timing constraints to avoid triggering # scheduling passes. backend.configuration().timing_constraints = {}