From 5a62b71b386a1202f0a392def319247cbd0b3b16 Mon Sep 17 00:00:00 2001 From: kevin-tian Date: Tue, 13 Feb 2024 16:57:48 -0500 Subject: [PATCH 1/4] Add abstract circuit warning --- qiskit_ibm_runtime/base_primitive.py | 4 +++ qiskit_ibm_runtime/utils/utils.py | 43 ++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/qiskit_ibm_runtime/base_primitive.py b/qiskit_ibm_runtime/base_primitive.py index c7bb67fb9..7bcbd80d9 100644 --- a/qiskit_ibm_runtime/base_primitive.py +++ b/qiskit_ibm_runtime/base_primitive.py @@ -29,6 +29,7 @@ from .runtime_job import RuntimeJob from .ibm_backend import IBMBackend from .utils.default_session import get_cm_session +from .utils.utils import validate_isa_circuits from .constants import DEFAULT_DECODERS from .qiskit_runtime_service import QiskitRuntimeService @@ -137,6 +138,9 @@ def _run_primitive(self, primitive_inputs: Dict, user_kwargs: Dict) -> RuntimeJo Returns: Submitted job. """ + if self._backend and hasattr(self._backend, "target"): + validate_isa_circuits(primitive_inputs["circuits"], self._backend.target) + combined = Options._merge_options(self._options, user_kwargs) if self._backend: diff --git a/qiskit_ibm_runtime/utils/utils.py b/qiskit_ibm_runtime/utils/utils.py index 23831b2f6..69f677031 100644 --- a/qiskit_ibm_runtime/utils/utils.py +++ b/qiskit_ibm_runtime/utils/utils.py @@ -17,19 +17,62 @@ import os import re import hashlib +import warnings from queue import Queue from threading import Condition from typing import List, Optional, Any, Dict, Union, Tuple from urllib.parse import urlparse +from collections.abc import Sequence import requests from ibm_cloud_sdk_core.authenticators import ( # pylint: disable=import-error IAMAuthenticator, ) from ibm_platform_services import ResourceControllerV2 # pylint: disable=import-error +from qiskit.circuit import QuantumCircuit +from qiskit.transpiler import Target from qiskit_ibm_runtime.exceptions import IBMInputValueError +def is_isa_circuit(circuit: QuantumCircuit, target: Target) -> bool: + """Checks if the circuit is an ISA circuit, meaning that it has a layout and that it + only uses instructions that exist in the target. + Args: + circuit: A single QuantumCircuit + target: A Qiskit Target + Returns: + Boolean True if the circuit is an ISA circuit + """ + if circuit.layout is None: + return False + for instruction in circuit.data: + name = instruction.operation.name + qargs = tuple(circuit.find_bit(x).index for x in instruction.qubits) + if not target.instruction_supported(name, qargs) and name != "barrier": + return False + return True + + +def validate_isa_circuits(circuits: Sequence[QuantumCircuit], target: Target) -> None: + """Validate if all circuits are ISA circuits + Args: + circuits: A list of QuantumCircuits + target: A Qiskit Target + Raises: + NonISACircuitsError if some of the circuits are not ISA circuits + """ + if not all(is_isa_circuit(circuit, target) for circuit in circuits): + warnings.warn( + "Circuits that do not match the target hardware definition will no longer be supported " + "after March 1, 2024. See the transpilation documentation " + "(https://docs.quantum.ibm.com/transpile) for instructions to transform circuits and " + "the primitive examples (https://docs.quantum.ibm.com/run/primitives-examples) to see " + "this coupled with operator transformations.", + DeprecationWarning, + stacklevel=6, + ) + + def validate_job_tags(job_tags: Optional[List[str]]) -> None: """Validates input job tags. From bb58a5ef573900306d08d23e6aa0e0dc107a124a Mon Sep 17 00:00:00 2001 From: kevin-tian Date: Tue, 13 Feb 2024 17:04:08 -0500 Subject: [PATCH 2/4] add reno --- .../deprecate-abstract-circuits-d9bdc94b2be7ea21.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 releasenotes/notes/deprecate-abstract-circuits-d9bdc94b2be7ea21.yaml diff --git a/releasenotes/notes/deprecate-abstract-circuits-d9bdc94b2be7ea21.yaml b/releasenotes/notes/deprecate-abstract-circuits-d9bdc94b2be7ea21.yaml new file mode 100644 index 000000000..666ce3e4b --- /dev/null +++ b/releasenotes/notes/deprecate-abstract-circuits-d9bdc94b2be7ea21.yaml @@ -0,0 +1,7 @@ +--- +deprecations: + - | + Circuits that do not match the target hardware definition will no longer be supported after March 1, 2024. + See the transpilation documentation (https://docs.quantum.ibm.com/transpile) for instructions to + transform circuits and the primitive examples (https://docs.quantum.ibm.com/run/primitives-examples) + to see this coupled with operator transformations. \ No newline at end of file From b1e1eb16a946efb6ee77a6cd182a2812d9557f48 Mon Sep 17 00:00:00 2001 From: kevin-tian Date: Tue, 13 Feb 2024 17:07:20 -0500 Subject: [PATCH 3/4] use correct Sequence import --- qiskit_ibm_runtime/utils/utils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qiskit_ibm_runtime/utils/utils.py b/qiskit_ibm_runtime/utils/utils.py index 69f677031..0108a8474 100644 --- a/qiskit_ibm_runtime/utils/utils.py +++ b/qiskit_ibm_runtime/utils/utils.py @@ -20,9 +20,8 @@ import warnings from queue import Queue from threading import Condition -from typing import List, Optional, Any, Dict, Union, Tuple +from typing import List, Optional, Any, Dict, Union, Tuple, Sequence from urllib.parse import urlparse -from collections.abc import Sequence import requests from ibm_cloud_sdk_core.authenticators import ( # pylint: disable=import-error From d3751ebfa54383decd3061a41eacafb68954d395 Mon Sep 17 00:00:00 2001 From: kevin-tian Date: Thu, 15 Feb 2024 11:27:08 -0500 Subject: [PATCH 4/4] unit tests --- qiskit_ibm_runtime/base_primitive.py | 7 ++++++- qiskit_ibm_runtime/utils/backend_decoder.py | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/qiskit_ibm_runtime/base_primitive.py b/qiskit_ibm_runtime/base_primitive.py index 7bcbd80d9..33c928d30 100644 --- a/qiskit_ibm_runtime/base_primitive.py +++ b/qiskit_ibm_runtime/base_primitive.py @@ -138,7 +138,12 @@ def _run_primitive(self, primitive_inputs: Dict, user_kwargs: Dict) -> RuntimeJo Returns: Submitted job. """ - if self._backend and hasattr(self._backend, "target"): + if ( + self._backend + and isinstance(self._backend, IBMBackend) + and isinstance(self._backend._service, QiskitRuntimeService) + and hasattr(self._backend, "target") + ): validate_isa_circuits(primitive_inputs["circuits"], self._backend.target) combined = Options._merge_options(self._options, user_kwargs) diff --git a/qiskit_ibm_runtime/utils/backend_decoder.py b/qiskit_ibm_runtime/utils/backend_decoder.py index d02fb90fb..369be0791 100644 --- a/qiskit_ibm_runtime/utils/backend_decoder.py +++ b/qiskit_ibm_runtime/utils/backend_decoder.py @@ -95,15 +95,16 @@ def properties_from_server_data(properties: Dict) -> BackendProperties: Returns: A ``BackendProperties`` instance. """ - properties["last_update_date"] = dateutil.parser.isoparse(properties["last_update_date"]) - for qubit in properties["qubits"]: - for nduv in qubit: - nduv["date"] = dateutil.parser.isoparse(nduv["date"]) - for gate in properties["gates"]: - for param in gate["parameters"]: - param["date"] = dateutil.parser.isoparse(param["date"]) - for gen in properties["general"]: - gen["date"] = dateutil.parser.isoparse(gen["date"]) + if isinstance(properties["last_update_date"], str): + properties["last_update_date"] = dateutil.parser.isoparse(properties["last_update_date"]) + for qubit in properties["qubits"]: + for nduv in qubit: + nduv["date"] = dateutil.parser.isoparse(nduv["date"]) + for gate in properties["gates"]: + for param in gate["parameters"]: + param["date"] = dateutil.parser.isoparse(param["date"]) + for gen in properties["general"]: + gen["date"] = dateutil.parser.isoparse(gen["date"]) properties = utc_to_local_all(properties) return BackendProperties.from_dict(properties)