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

Remove 0.24.0 deprecations #1907

Merged
merged 9 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(bell)

# 3. Execute using the Sampler primitive
sampler = Sampler(backend=backend)
sampler = Sampler(mode=backend)
sampler.options.default_shots = 1024 # Options can be set using auto-complete.
job = sampler.run([isa_circuit])
print(f"Job ID is {job.job_id()}")
Expand Down Expand Up @@ -296,8 +296,8 @@ backend1 = service.backend("ibmq_manila")
# Optional: Specify the instance at the backend level, which overwrites the service-level specification when this backend is used.
backend2 = service.backend("ibmq_manila", instance="hub2/group2/project2")

sampler1 = Sampler(backend=backend1) # this will use hub1/group1/project1
sampler2 = Sampler(backend=backend2) # this will use hub2/group2/project2
sampler1 = Sampler(mode=backend1) # this will use hub1/group1/project1
sampler2 = Sampler(mode=backend2) # this will use hub2/group2/project2
```

If you do not specify an instance, then the code will select one in the following order:
Expand Down
32 changes: 5 additions & 27 deletions qiskit_ibm_runtime/base_primitive.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,17 @@
from dataclasses import asdict, replace
import warnings

from pydantic import ValidationError

from qiskit.primitives.containers.estimator_pub import EstimatorPub
from qiskit.primitives.containers.sampler_pub import SamplerPub
from qiskit.providers.backend import BackendV1, BackendV2

from .options.options import BaseOptions, OptionsV2
from .options.utils import merge_options, merge_options_v2
from .options.utils import merge_options_v2
from .runtime_job_v2 import RuntimeJobV2
from .ibm_backend import IBMBackend
from .utils import validate_isa_circuits, validate_no_dd_with_dynamic_circuits
from .utils.default_session import get_cm_session
from .utils.deprecation import issue_deprecation_msg, deprecate_function
from .utils.deprecation import issue_deprecation_msg
from .utils.utils import is_simulator
from .constants import DEFAULT_DECODERS
from .qiskit_runtime_service import QiskitRuntimeService
Expand Down Expand Up @@ -184,7 +182,7 @@ def _run(self, pubs: Union[list[EstimatorPub], list[SamplerPub]]) -> RuntimeJobV

# Batch or Session
if self._mode:
return self._mode.run(
return self._mode._run(
program_id=self._program_id(),
inputs=primitive_inputs,
options=runtime_options,
Expand All @@ -198,7 +196,7 @@ def _run(self, pubs: Union[list[EstimatorPub], list[SamplerPub]]) -> RuntimeJobV
runtime_options["instance"] = self._backend._instance

if isinstance(self._service, QiskitRuntimeService):
return self._service.run(
return self._service._run(
program_id=self._program_id(),
options=runtime_options,
inputs=primitive_inputs,
Expand All @@ -212,16 +210,6 @@ def _run(self, pubs: Union[list[EstimatorPub], list[SamplerPub]]) -> RuntimeJobV
inputs=primitive_inputs,
)

@property
def session(self) -> Optional[Session]:
"""Return session used by this primitive.

Returns:
Session used by this primitive, or ``None`` if session is not used.
"""
deprecate_function("session", "0.24.0", "Please use the 'mode' property instead.")
return self._mode

@property
def mode(self) -> Optional[Session | Batch]:
"""Return the execution mode used by this primitive.
Expand All @@ -242,17 +230,7 @@ def _set_options(self, options: Optional[Union[Dict, OptionsT]] = None) -> None:
self._options = self._options_class()
elif isinstance(options, dict):
default_options = self._options_class()
try:
self._options = self._options_class(**merge_options_v2(default_options, options))
except ValidationError:
self._options = self._options_class(**merge_options(default_options, options))
issue_deprecation_msg(
"Specifying options without the full dictionary structure is deprecated",
"0.24.0",
"Instead, pass in a fully structured dictionary. For example, use "
"{'environment': {'log_level': 'INFO'}} instead of {'log_level': 'INFO'}.",
4,
)
self._options = self._options_class(**merge_options_v2(default_options, options))
ptristan3 marked this conversation as resolved.
Show resolved Hide resolved

elif isinstance(options, self._options_class):
self._options = replace(options)
Expand Down
14 changes: 0 additions & 14 deletions qiskit_ibm_runtime/base_runtime_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,20 +374,6 @@ def primitive_id(self) -> str:
"""
return self._program_id

@property
def program_id(self) -> str:
"""Program ID.

Returns:
ID of the program this job is for.
"""
issue_deprecation_msg(
msg="The Job.program_id property is deprecated",
version="0.24.0",
remedy="Use Job.primitive_id instead.",
)
return self._program_id

@property
def creation_date(self) -> Optional[datetime]:
"""Job creation date in local time.
Expand Down
41 changes: 4 additions & 37 deletions qiskit_ibm_runtime/estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from .runtime_job_v2 import RuntimeJobV2
from .options.estimator_options import EstimatorOptions
from .base_primitive import BasePrimitiveV2
from .utils.deprecation import deprecate_arguments, issue_deprecation_msg
from .utils.deprecation import issue_deprecation_msg
from .utils.qctrl import validate_v2 as qctrl_validate_v2
from .utils import validate_estimator_pubs

Expand Down Expand Up @@ -87,7 +87,7 @@ class EstimatorV2(BasePrimitiveV2[EstimatorOptions], Estimator, BaseEstimatorV2)
isa_psi = pm.run(psi)
isa_observables = hamiltonian.apply_layout(isa_psi.layout)

estimator = Estimator(backend=backend)
estimator = Estimator(mode=backend)

# calculate [ <psi(theta1)|hamiltonian|psi(theta)> ]
job = estimator.run([(isa_psi, isa_observables, [theta])])
Expand All @@ -102,8 +102,6 @@ class EstimatorV2(BasePrimitiveV2[EstimatorOptions], Estimator, BaseEstimatorV2)
def __init__(
self,
mode: Optional[Union[BackendV1, BackendV2, Session, Batch, str]] = None,
backend: Optional[Union[str, BackendV1, BackendV2]] = None,
session: Optional[Session] = None,
options: Optional[Union[Dict, EstimatorOptions]] = None,
):
"""Initializes the Estimator primitive.
Expand All @@ -119,52 +117,21 @@ def __init__(
`Qiskit Runtime documentation <https://docs.quantum.ibm.com/guides/execution-modes>`_.
for more information about the ``Execution modes``.

backend: (DEPRECATED) Backend to run the primitive. This can be a backend name
or an :class:`IBMBackend` instance. If a name is specified, the default account
(e.g. ``QiskitRuntimeService()``) is used.

session: (DEPRECATED) Session in which to call the primitive.

If both ``session`` and ``backend`` are specified, ``session`` takes precedence.
If neither is specified, and the primitive is created inside a
:class:`qiskit_ibm_runtime.Session` context manager, then the session is used.
Otherwise if IBM Cloud channel is used, a default backend is selected.

options: Estimator options, see :class:`EstimatorOptions` for detailed description.

Raises:
NotImplementedError: If "q-ctrl" channel strategy is used.
"""
BaseEstimatorV2.__init__(self)
Estimator.__init__(self)
if backend:
deprecate_arguments(
"backend",
"0.24.0",
"Please use the 'mode' parameter instead.",
)
if session:
deprecate_arguments(
"session",
"0.24.0",
"Please use the 'mode' parameter instead.",
)
if isinstance(mode, str) or isinstance(backend, str):
issue_deprecation_msg(
"The backend name as execution mode input has been deprecated.",
"0.24.0",
"A backend object should be provided instead. Get the backend directly from"
" the service using `QiskitRuntimeService().backend('ibm_backend')`",
3,
)
if isinstance(mode, str):
issue_deprecation_msg(
msg="Passing a backend as a string is deprecated",
version="0.26.0",
remedy="Use the actual backend object instead.",
period="3 months",
)
if mode is None:
mode = session if backend and session else backend if backend else session

BasePrimitiveV2.__init__(self, mode=mode, options=options)

def run(
Expand Down
6 changes: 3 additions & 3 deletions qiskit_ibm_runtime/noise_learner/noise_learner.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def run(self, circuits: Iterable[Union[QuantumCircuit, EstimatorPubLike]]) -> Ru

# Batch or Session
if self._mode:
return self._mode.run(
return self._mode._run(
program_id=self._program_id(),
inputs=inputs,
options=runtime_options,
Expand All @@ -202,15 +202,15 @@ def run(self, circuits: Iterable[Union[QuantumCircuit, EstimatorPubLike]]) -> Ru
runtime_options["instance"] = self._backend._instance

if isinstance(self._service, QiskitRuntimeService):
return self._service.run(
return self._service._run(
program_id=self._program_id(),
options=runtime_options,
inputs=inputs,
callback=options_dict.get("environment", {}).get("callback", None),
result_decoder=DEFAULT_DECODERS.get(self._program_id()),
)

return self._service.run( # type: ignore[attr-defined]
return self._service._run( # type: ignore[attr-defined]
program_id=self._program_id(), # type: ignore[arg-type]
options=runtime_options,
inputs=inputs,
Expand Down
4 changes: 2 additions & 2 deletions qiskit_ibm_runtime/options/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
estimator = EstimatorV2(backend=backend)
estimator = EstimatorV2(mode=backend)
estimator.options.resilience_level = 1

You can also use the ``update()`` method to do bulk update. For example::
Expand All @@ -38,7 +38,7 @@

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
estimator = EstimatorV2(backend=backend)
estimator = EstimatorV2(mode=backend)
estimator.options.update(resilience_level=1)

Refer to :class:`SamplerOptions` and :class:`EstimatorOptions` for V2 Sampler and
Expand Down
19 changes: 3 additions & 16 deletions qiskit_ibm_runtime/options/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,20 @@
import copy

from qiskit.transpiler import CouplingMap
from pydantic import Field, ValidationError
from pydantic import Field

from .utils import (
Dict,
UnsetType,
Unset,
remove_dict_unset_values,
merge_options,
merge_options_v2,
primitive_dataclass,
remove_empty_dict,
)
from .environment_options import EnvironmentOptions
from .simulator_options import SimulatorOptions
from ..runtime_options import RuntimeOptions
from ..utils.deprecation import issue_deprecation_msg


def _make_data_row(indent: int, name: str, value: Any, is_section: bool) -> Iterable[str]:
Expand Down Expand Up @@ -153,19 +151,8 @@ def _set_attr(_merged: dict) -> None:
if not key.startswith("_"):
setattr(self, key, val)

try:
merged = merge_options_v2(self, kwargs)
_set_attr(merged)
except ValidationError:
merged = merge_options(self, kwargs)
_set_attr(merged)
issue_deprecation_msg(
"Specifying options without the full dictionary structure is deprecated",
"0.24.0",
"Instead, pass in a fully structured dictionary. For example, use "
"{'environment': {'log_level': 'INFO'}} instead of {'log_level': 'INFO'}.",
2,
)
merged = merge_options_v2(self, kwargs)
_set_attr(merged)
ptristan3 marked this conversation as resolved.
Show resolved Hide resolved

@staticmethod
def _get_program_inputs(options: dict) -> dict:
Expand Down
34 changes: 4 additions & 30 deletions qiskit_ibm_runtime/qiskit_runtime_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

from qiskit_ibm_runtime import ibm_backend
from .proxies import ProxyConfiguration
from .utils.deprecation import issue_deprecation_msg, deprecate_function
from .utils.hgp import to_instance_format, from_instance_format
from .utils.backend_decoder import configuration_from_server_data

Expand Down Expand Up @@ -751,7 +750,7 @@ def saved_accounts(

def backend(
self,
name: str = None,
name: str,
instance: Optional[str] = None,
use_fractional_gates: bool = False,
) -> Backend:
Expand Down Expand Up @@ -779,33 +778,18 @@ def backend(
Raises:
QiskitBackendNotFoundError: if no backend could be found.
"""
# pylint: disable=arguments-differ, line-too-long
if not name:
warnings.warn(
(
"The `name` parameter will be required in a future release no sooner than "
"3 months after the release of qiskit-ibm-runtime 0.24.0 ."
),
DeprecationWarning,
stacklevel=2,
)
backends = self.backends(name, instance=instance, use_fractional_gates=use_fractional_gates)
if not backends:
cloud_msg_url = ""
if self._channel == "ibm_cloud":
cloud_msg_url = (
" Learn more about available backends here "
"https://cloud.ibm.com/docs/quantum-computing?topic=quantum-computing-choose-backend "
"https://cloud.ibm.com/docs/quantum-computing?topic=quantum-computing-choose-backend"
)
raise QiskitBackendNotFoundError("No backend matches the criteria." + cloud_msg_url)
return backends[0]

@deprecate_function("get_backend()", "0.24", "Please use backend() instead.", stacklevel=1)
def get_backend(self, name: str = None, **kwargs: Any) -> Backend:
"""Return a single backend matching the specified filtering."""
return self.backend(name, **kwargs)

def run(
def _run(
self,
program_id: str,
inputs: Dict,
Expand Down Expand Up @@ -844,13 +828,7 @@ def run(
RuntimeProgramNotFound: If the program cannot be found.
IBMRuntimeError: An error occurred running the program.
"""
issue_deprecation_msg(
msg="service.run is deprecated",
version="0.24.0",
remedy="service.run will instead be converted into a private method "
"since it should not be called directly.",
period="3 months",
)

qrt_options: RuntimeOptions = options
if options is None:
qrt_options = RuntimeOptions()
Expand Down Expand Up @@ -929,10 +907,6 @@ def run(
version=version,
)

def _run(self, *args: Any, **kwargs: Any) -> Union[RuntimeJob, RuntimeJobV2]:
"""Private run method"""
return self.run(*args, **kwargs)

def check_pending_jobs(self) -> None:
"""Check the number of pending jobs and wait for the oldest pending job if
the maximum number of pending jobs has been reached.
Expand Down
Loading