Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InstructionDurations from BackendV2 #11528

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 30 additions & 21 deletions qiskit/transpiler/instruction_durations.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import qiskit.circuit
from qiskit.circuit import Barrier, Delay, Instruction, ParameterExpression
from qiskit.circuit.duration import duration_in_dt
from qiskit.providers import Backend, BackendV1, BackendV2
from qiskit.providers import Backend
from qiskit.providers.backend import BackendV2
from qiskit.transpiler.exceptions import TranspilerError
Expand Down Expand Up @@ -71,33 +72,41 @@ def from_backend(cls, backend: Backend):

Returns:
InstructionDurations: The InstructionDurations constructed from backend.

Raises:
TranspilerError: If dt and dtm is different in the backend.
"""

# All durations in seconds in gate_length
if isinstance(backend, BackendV2):
return backend.target.durations()

instruction_durations = []
backend_properties = backend.properties()
if hasattr(backend_properties, "_gates"):
for gate, insts in backend_properties._gates.items():
for qubits, props in insts.items():
if "gate_length" in props:
gate_length = props["gate_length"][0] # Throw away datetime at index 1
instruction_durations.append((gate, qubits, gate_length, "s"))
for q, props in backend.properties()._qubits.items():
if "readout_length" in props:
readout_length = props["readout_length"][0] # Throw away datetime at index 1
instruction_durations.append(("measure", [q], readout_length, "s"))

try:
dt = backend.configuration().dt
except AttributeError:
dt = None

return cls(instruction_durations, dt=dt)
return_durations = None

# Logic to handle if backend is sub-class of old BackendV1
if isinstance(backend, BackendV1):
backend_properties = backend.properties()
if hasattr(backend_properties, "_gates"):
for gate, insts in backend_properties._gates.items():
for qubits, props in insts.items():
if "gate_length" in props:
gate_length = props["gate_length"][0] # Ignore datetime at index 1
instruction_durations.append((gate, qubits, gate_length, "s"))
for q, props in backend.properties()._qubits.items():
if "readout_length" in props:
readout_length = props["readout_length"][0] # Ignore datetime at index 1
instruction_durations.append(("measure", [q], readout_length, "s"))

try:
dt = backend.configuration().dt
except AttributeError:
dt = None

return_durations = cls(instruction_durations, dt=dt)

# Logic to handle if backend is sub-class is BackendV2
elif isinstance(backend, BackendV2):
return_durations = backend.target.durations()

return return_durations

def update(self, inst_durations: "InstructionDurationsType" | None, dt: float = None):
"""Update self with inst_durations (inst_durations overwrite self).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
features:
- |
Support for :class:`.BackendV2` in :meth:`.InstructionDurations.from_backend` is added.

Users can have an object of :class:`.InstructionDurations` using :class:`.BackendV2`
from :meth:`.InstructionDurations.from_backend` with followig code.

.. code-block:: python

from qiskit.providers.fake_provider import FakePerth
from qiskit.transpiler import InstructionDurations
backendV2 = FakePerth()

inst_dur = InstructionDurations.from_backend(backendV2)
15 changes: 2 additions & 13 deletions test/python/transpiler/test_instruction_durations.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
# pylint: disable=missing-function-docstring

"""Test InstructionDurations class."""

from copy import deepcopy
from qiskit.circuit import Delay, Parameter
from qiskit.providers.fake_provider import Fake7QPulseV1, GenericBackendV2
from qiskit.providers.fake_provider import Fake27QPulseV1
from qiskit.providers.fake_provider import GenericBackendV2
from qiskit.transpiler.exceptions import TranspilerError
Expand Down Expand Up @@ -61,21 +62,9 @@ def test_update_with_parameters(self):
durations = InstructionDurations(
[("rzx", (0, 1), 150, (0.5,)), ("rzx", (0, 1), 300, (1.0,))]
)

self.assertEqual(durations.get("rzx", [0, 1], parameters=[0.5]), 150)
self.assertEqual(durations.get("rzx", [0, 1], parameters=[1.0]), 300)

def _find_gate_with_length(self, backend):
"""Find a gate that has gate length."""
props = backend.properties()
for gate in props.gates:
try:
if props.gate_length(gate.gate, 0):
return gate.gate
except Exception: # pylint: disable=broad-except
pass
raise ValueError("Unable to find a gate with gate length.")

def test_can_get_unbounded_duration_without_unit_conversion(self):
param = Parameter("t")
parameterized_delay = Delay(param, "dt")
Expand Down
Loading