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

Handle control flow instructions in Target generation #1443

Merged
merged 3 commits into from
Feb 28, 2024
Merged
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
10 changes: 10 additions & 0 deletions qiskit_ibm_runtime/utils/backend_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
ECRGate,
CZGate,
)
from qiskit.circuit.controlflow import CONTROL_FLOW_OP_NAMES
from qiskit.circuit import IfElseOp, WhileLoopOp, ForLoopOp, SwitchCaseOp
from qiskit.circuit.parameter import Parameter
from qiskit.circuit.delay import Delay
from qiskit.circuit.gate import Gate
Expand Down Expand Up @@ -56,6 +58,10 @@ def convert_to_target(
"reset": Reset(),
"ecr": ECRGate(),
"cz": CZGate(),
"if_else": IfElseOp,
"while_loop": WhileLoopOp,
"for_loop": ForLoopOp,
"switch_case": SwitchCaseOp,
}
custom_gates = {}
target = None
Expand Down Expand Up @@ -128,6 +134,10 @@ def convert_to_target(
target.min_length = configuration.timing_constraints.get("min_length")
target.pulse_alignment = configuration.timing_constraints.get("pulse_alignment")
target.acquire_alignment = configuration.timing_constraints.get("acquire_alignment")
supported_instructions = set(getattr(configuration, "supported_instructions", []))
control_flow_ops = CONTROL_FLOW_OP_NAMES.intersection(supported_instructions)
for op in control_flow_ops:
target.add_instruction(name_mapping[op], name=op)
# If pulse defaults exists use that as the source of truth
if defaults is not None:
faulty_qubits = set()
Expand Down
6 changes: 6 additions & 0 deletions releasenotes/notes/fix-control-flow-d5a61dd5647acb42.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
fixes:
- |
Fixed an issue with the :attr:`.IBMBackend.target` where it would
incorrectly exclude supported control flow operations (:class:`.IfElseOp`,
:class:`.WhileLoop`, etc.) if a given backend supported them.
25 changes: 23 additions & 2 deletions test/unit/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@
import warnings

from qiskit import transpile, qasm3, QuantumCircuit
from qiskit.providers.models import BackendStatus
from qiskit.circuit import IfElseOp
from qiskit.providers.models import (
BackendStatus,
BackendConfiguration,
BackendProperties,
PulseDefaults,
)

from qiskit_ibm_runtime.exceptions import IBMBackendValueError
from qiskit_ibm_runtime.fake_provider import FakeManila
from qiskit_ibm_runtime.fake_provider import FakeManila, FakeSherbrooke
from qiskit_ibm_runtime.ibm_backend import IBMBackend
from qiskit_ibm_runtime.utils.backend_converter import convert_to_target

from ..ibm_test_case import IBMTestCase
from ..utils import (
Expand Down Expand Up @@ -305,3 +312,17 @@ def test_too_many_circuits(self):
f"Number of circuits, {max_circs+1} exceeds the maximum for this backend, {max_circs}",
str(err.exception),
)

def test_control_flow_converter(self):
"""Test that control flow instructions are properly added to the target."""
backend = FakeSherbrooke()
backend._get_conf_dict_from_json()
backend._set_props_dict_from_json()
backend._set_defs_dict_from_json()
target = convert_to_target(
BackendConfiguration.from_dict(backend._conf_dict),
BackendProperties.from_dict(backend._props_dict),
PulseDefaults.from_dict(backend._defs_dict),
)
self.assertTrue(target.instruction_supported("if_else", ()))
self.assertTrue(target.instruction_supported(operation_class=IfElseOp))