diff --git a/qiskit/transpiler/instruction_durations.py b/qiskit/transpiler/instruction_durations.py index 56f8b5587c0..6c93b6e14ac 100644 --- a/qiskit/transpiler/instruction_durations.py +++ b/qiskit/transpiler/instruction_durations.py @@ -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 @@ -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). diff --git a/releasenotes/notes/Add_support_for_BackendV2_in_instruction_durations_from_backend-9ce722879c870377.yaml b/releasenotes/notes/Add_support_for_BackendV2_in_instruction_durations_from_backend-9ce722879c870377.yaml new file mode 100644 index 00000000000..36f0f44f07c --- /dev/null +++ b/releasenotes/notes/Add_support_for_BackendV2_in_instruction_durations_from_backend-9ce722879c870377.yaml @@ -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) diff --git a/test/python/transpiler/test_instruction_durations.py b/test/python/transpiler/test_instruction_durations.py index d9a3ef2b177..9314845e845 100644 --- a/test/python/transpiler/test_instruction_durations.py +++ b/test/python/transpiler/test_instruction_durations.py @@ -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 @@ -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")