From f7ebdca559c011ec6cb4bb6045f108487b20dcc4 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 2 May 2022 11:12:32 -0400 Subject: [PATCH 1/3] Fix instruction durations in transpile() with BackendV2 (#8001) * Fix instruction durations in transpile() with BackendV2 When running transpile() with BackendV2 based backends the instruction durations property from the backend would not be processed correctly resulting in the absence of the default durations for instructions supported on the target backend. This commit fixes this by correctly handling BackendV2 based backends and using those instruction durations by default for transpile(). * Update test/python/compiler/test_transpiler.py Co-authored-by: Kevin Hartman Co-authored-by: Kevin Hartman Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 49f39e3a6c35922fc7cedf944936df902a1425dc) --- qiskit/compiler/transpiler.py | 14 +++++++++----- ...spile-backendv2-durations-dbc85688564cc271.yaml | 8 ++++++++ test/python/compiler/test_transpiler.py | 14 +++++++++++++- 3 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/fix-transpile-backendv2-durations-dbc85688564cc271.yaml diff --git a/qiskit/compiler/transpiler.py b/qiskit/compiler/transpiler.py index f322935fed7b..dab9bf4cb20d 100644 --- a/qiskit/compiler/transpiler.py +++ b/qiskit/compiler/transpiler.py @@ -938,11 +938,15 @@ def _parse_instruction_durations(backend, inst_durations, dt, circuits): take precedence over backend durations, but be superceded by ``inst_duration``s. """ if not inst_durations: - backend_durations = InstructionDurations() - try: - backend_durations = InstructionDurations.from_backend(backend) - except AttributeError: - pass + 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 = backend.instruction_durations durations = [] for circ in circuits: diff --git a/releasenotes/notes/fix-transpile-backendv2-durations-dbc85688564cc271.yaml b/releasenotes/notes/fix-transpile-backendv2-durations-dbc85688564cc271.yaml new file mode 100644 index 000000000000..00e7886468ba --- /dev/null +++ b/releasenotes/notes/fix-transpile-backendv2-durations-dbc85688564cc271.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Fixed an issue with the :func:`~.transpile` function when run with a + :class:`~.BackendV2` based backend and setting the ``scheduling_method`` + keyword argument. Previously, the function would not correctly process + the default durations of the instructions supported by the backend which + would lead to an error. diff --git a/test/python/compiler/test_transpiler.py b/test/python/compiler/test_transpiler.py index 3a6de35f49a7..83fa89503027 100644 --- a/test/python/compiler/test_transpiler.py +++ b/test/python/compiler/test_transpiler.py @@ -35,7 +35,7 @@ from qiskit.circuit.library import CXGate, U3Gate, U2Gate, U1Gate, RXGate, RYGate, RZGate, UGate from qiskit.circuit.measure import Measure from qiskit.test import QiskitTestCase -from qiskit.test.mock import FakeMelbourne, FakeRueschlikon, FakeAlmaden +from qiskit.test.mock import FakeMelbourne, FakeRueschlikon, FakeAlmaden, FakeMumbaiV2 from qiskit.transpiler import Layout, CouplingMap from qiskit.transpiler import PassManager from qiskit.transpiler.target import Target @@ -1242,6 +1242,18 @@ def test_delay_converts_to_dt(self): out = transpile(qc, dt=1e-9) self.assertEqual(out.data[0][0].unit, "dt") + def test_scheduling_backend_v2(self): + """Test that scheduling method works with Backendv2.""" + qc = QuantumCircuit(2) + qc.h(0) + qc.cx(0, 1) + qc.measure_all() + + backend = FakeMumbaiV2() + out = transpile([qc, qc], backend, scheduling_method="alap") + self.assertIn("delay", out[0].count_ops()) + self.assertIn("delay", out[1].count_ops()) + @data(1, 2, 3) def test_no_infinite_loop(self, optimization_level): """Verify circuit cost always descends and optimization does not flip flop indefinitely.""" From 40659fe22dd38c0f6b6d91d2367cc356e7fc4ed3 Mon Sep 17 00:00:00 2001 From: Jake Lishman Date: Tue, 3 May 2022 10:30:29 +0100 Subject: [PATCH 2/3] Handle still-supported BaseBackend for 0.20 --- qiskit/compiler/transpiler.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qiskit/compiler/transpiler.py b/qiskit/compiler/transpiler.py index dab9bf4cb20d..15743fb93515 100644 --- a/qiskit/compiler/transpiler.py +++ b/qiskit/compiler/transpiler.py @@ -939,6 +939,9 @@ def _parse_instruction_durations(backend, inst_durations, dt, circuits): """ if not inst_durations: backend_version = getattr(backend, "version", 0) + if not isinstance(backend_version, int): + # Legacy BaseBackend still has `version` as a method. + backend_version = backend_version() if backend_version <= 1: backend_durations = InstructionDurations() try: From ddbaad55f6f72a7f092ac03ff77fecb4be0b9a7f Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Wed, 4 May 2022 15:09:04 -0400 Subject: [PATCH 3/3] Fix handling of legacy base backend version --- qiskit/compiler/transpiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/compiler/transpiler.py b/qiskit/compiler/transpiler.py index 15743fb93515..00bedfee806d 100644 --- a/qiskit/compiler/transpiler.py +++ b/qiskit/compiler/transpiler.py @@ -941,7 +941,7 @@ def _parse_instruction_durations(backend, inst_durations, dt, circuits): backend_version = getattr(backend, "version", 0) if not isinstance(backend_version, int): # Legacy BaseBackend still has `version` as a method. - backend_version = backend_version() + backend_version = 0 if backend_version <= 1: backend_durations = InstructionDurations() try: