Skip to content

Commit

Permalink
Remove 0.26.0 deprecations (#2027)
Browse files Browse the repository at this point in the history
* Remove 0.26.0 deprecations

* wip update unit tests

* Fix lint

* Update unit tests

* remove "service" param from Session/Batch

* run job in session if session open

* Update session logic

* Raise error if primitive backend != session backend

* Add release note & remove global service

* Update release note

* Update integration tests

* Update integration tests again

* Address comments

---------

Co-authored-by: ptristan3 <44805021+ptristan3@users.noreply.github.com>
  • Loading branch information
kt474 and ptristan3 authored Nov 25, 2024
1 parent 7c5e87c commit 639f307
Show file tree
Hide file tree
Showing 17 changed files with 83 additions and 237 deletions.
47 changes: 12 additions & 35 deletions qiskit_ibm_runtime/base_primitive.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from typing import Dict, Optional, Union, TypeVar, Generic, Type
import logging
from dataclasses import asdict, replace
import warnings

from qiskit.primitives.containers.estimator_pub import EstimatorPub
from qiskit.primitives.containers.sampler_pub import SamplerPub
Expand Down Expand Up @@ -48,7 +47,7 @@


def _get_mode_service_backend(
mode: Optional[Union[BackendV1, BackendV2, Session, Batch, str]] = None
mode: Optional[Union[BackendV1, BackendV2, Session, Batch]] = None
) -> tuple[
Union[Session, Batch, None],
Union[QiskitRuntimeService, QiskitRuntimeLocalService, None],
Expand All @@ -69,43 +68,21 @@ def _get_mode_service_backend(
return mode, mode.service, mode._backend
elif isinstance(mode, IBMBackend): # type: ignore[unreachable]
if get_cm_session():
warnings.warn(
(
"Passing a backend as the mode currently runs the job in job mode even "
"if inside of a session/batch context manager. As of qiskit-ibm-runtime "
"version 0.26.0, this behavior is deprecated and in a future "
"release no sooner than than 3 months "
"after the release date, the session/batch will take precendence and "
"the job will not run in job mode. To ensure that jobs are run in session/batch "
"mode, pass in the session/batch or leave the mode parameter emtpy."
),
DeprecationWarning,
stacklevel=4,
logger.warning(
"A backend was passed in as the mode but a session context manager "
"is open so this job will run inside this session/batch "
"instead of in job mode."
)
if get_cm_session()._backend != mode:
raise ValueError(
"The backend passed in to the primitive is different from the session backend. "
"Please check which backend you intend to use or leave the mode parameter "
"empty to use the session backend."
)
return get_cm_session(), mode.service, mode
return None, mode.service, mode
elif isinstance(mode, (BackendV1, BackendV2)):
return None, QiskitRuntimeLocalService(), mode
elif isinstance(mode, str):
if get_cm_session():
warnings.warn(
(
"Passing a backend as the mode currently runs the job in job mode even "
"if inside of a session/batch context manager. As of qiskit-ibm-runtime "
"version 0.26.0, this behavior is deprecated and in a future "
"release no sooner than than 3 months "
"after the release date, the session/batch will take precendence and "
"the job will not run in job mode. To ensure that jobs are run in session/batch "
"mode, pass in the session/batch or leave the mode parameter emtpy."
),
DeprecationWarning,
stacklevel=4,
)
service = (
QiskitRuntimeService()
if QiskitRuntimeService.global_service is None
else QiskitRuntimeService.global_service
)
return None, service, service.backend(mode)
elif mode is not None: # type: ignore[unreachable]
raise ValueError("mode must be of type Backend, Session, Batch or None")
elif get_cm_session():
Expand Down
30 changes: 3 additions & 27 deletions qiskit_ibm_runtime/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

from qiskit_ibm_runtime import QiskitRuntimeService
from .session import Session
from .utils.deprecation import issue_deprecation_msg


class Batch(Session):
Expand Down Expand Up @@ -87,19 +86,13 @@ class Batch(Session):

def __init__(
self,
service: Optional[QiskitRuntimeService] = None,
backend: Optional[Union[str, BackendV1, BackendV2]] = None,
backend: Optional[Union[BackendV1, BackendV2]] = None,
max_time: Optional[Union[int, str]] = None,
):
"""Batch constructor.
Args:
service: (DEPRECATED) Optional instance of the ``QiskitRuntimeService`` class.
If ``None``, the service associated with the backend, if known, is used.
Otherwise ``QiskitRuntimeService()`` is used to initialize
your default saved account.
backend: Instance of ``Backend`` class or backend string name. Note that passing a
backend name is deprecated.
backend: Instance of ``Backend`` class.
max_time:
Maximum amount of time a runtime session can be open before being
Expand All @@ -111,25 +104,8 @@ def __init__(
Raises:
ValueError: If an input value is invalid.
"""
if service:
issue_deprecation_msg(
msg="The service parameter is deprecated",
version="0.26.0",
remedy=(
"The service can be extracted from the backend object so "
"it is no longer necessary."
),
period="3 months",
)
if isinstance(backend, 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",
)

super().__init__(service=service, backend=backend, max_time=max_time)
super().__init__(backend=backend, max_time=max_time)

def _create_session(self) -> Optional[str]:
"""Create a session."""
Expand Down
8 changes: 0 additions & 8 deletions qiskit_ibm_runtime/estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
from .runtime_job_v2 import RuntimeJobV2
from .options.estimator_options import EstimatorOptions
from .base_primitive import BasePrimitiveV2
from .utils.deprecation import issue_deprecation_msg
from .utils import validate_estimator_pubs

# pylint: disable=unused-import,cyclic-import
Expand Down Expand Up @@ -121,13 +120,6 @@ def __init__(
"""
BaseEstimatorV2.__init__(self)
Estimator.__init__(self)
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",
)

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

Expand Down
3 changes: 0 additions & 3 deletions qiskit_ibm_runtime/qiskit_runtime_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@
class QiskitRuntimeService:
"""Class for interacting with the Qiskit Runtime service."""

global_service = None

def __new__(cls, *args, **kwargs): # type: ignore[no-untyped-def]
channel = kwargs.get("channel", None)
if channel == "local":
Expand Down Expand Up @@ -178,7 +176,6 @@ def __init__(
if not self._current_instance:
self._current_instance = self._get_hgp().name
logger.info("Default instance: %s", self._current_instance)
QiskitRuntimeService.global_service = self

def _discover_account(
self,
Expand Down
12 changes: 1 addition & 11 deletions qiskit_ibm_runtime/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
# pylint: disable=unused-import,cyclic-import
from .session import Session
from .batch import Batch
from .utils.deprecation import issue_deprecation_msg
from .utils import validate_classical_registers
from .options import SamplerOptions

Expand Down Expand Up @@ -61,7 +60,7 @@ class SamplerV2(BasePrimitiveV2[SamplerOptions], Sampler, BaseSamplerV2):

def __init__(
self,
mode: Optional[Union[BackendV1, BackendV2, Session, Batch, str]] = None,
mode: Optional[Union[BackendV1, BackendV2, Session, Batch]] = None,
options: Optional[Union[Dict, SamplerOptions]] = None,
):
"""Initializes the Sampler primitive.
Expand All @@ -84,15 +83,6 @@ def __init__(
BaseSamplerV2.__init__(self)
Sampler.__init__(self)

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",
stacklevel=2,
)

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

def run(self, pubs: Iterable[SamplerPubLike], *, shots: int | None = None) -> RuntimeJobV2:
Expand Down
46 changes: 5 additions & 41 deletions qiskit_ibm_runtime/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
from .utils.result_decoder import ResultDecoder
from .ibm_backend import IBMBackend
from .utils.default_session import set_cm_session
from .utils.deprecation import issue_deprecation_msg
from .utils.converters import hms_to_seconds
from .fake_provider.local_service import QiskitRuntimeLocalService

Expand Down Expand Up @@ -86,19 +85,13 @@ class Session:

def __init__(
self,
service: Optional[QiskitRuntimeService] = None,
backend: Optional[Union[str, BackendV1, BackendV2]] = None,
backend: Optional[Union[BackendV1, BackendV2]] = None,
max_time: Optional[Union[int, str]] = None,
): # pylint: disable=line-too-long
"""Session constructor.
Args:
service: (DEPRECATED) Optional instance of the ``QiskitRuntimeService`` class.
If ``None``, the service associated with the backend, if known, is used.
Otherwise ``QiskitRuntimeService()`` is used to initialize
your default saved account.
backend: Instance of ``Backend`` class or string name of backend. Note that passing a
backend name is deprecated.
backend: Instance of ``Backend`` class.
max_time:
Maximum amount of time, a runtime session can be open before being
Expand All @@ -115,43 +108,14 @@ def __init__(
self._active = True
self._session_id = None

if service:
issue_deprecation_msg(
msg="The service parameter is deprecated",
version="0.26.0",
remedy=(
"The service can be extracted from the backend object so "
"it is no longer necessary."
),
period="3 months",
)

self._service = service
if isinstance(backend, IBMBackend):
self._service = self._service or backend.service
self._service = backend.service
self._backend = backend
elif isinstance(backend, (BackendV1, BackendV2)):
self._service = QiskitRuntimeLocalService()
self._backend = backend
else:
if not self._service:
self._service = (
QiskitRuntimeService()
if QiskitRuntimeService.global_service is None
else QiskitRuntimeService.global_service
)
if isinstance(backend, 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",
)
self._backend = self._service.backend(backend)
elif backend is None:
raise ValueError('"backend" is required')
else:
raise ValueError(f"Invalid backend type {type(backend)}")
raise ValueError(f"Invalid backend type {type(backend)}")

self._max_time = (
max_time
Expand Down Expand Up @@ -378,7 +342,7 @@ def from_id(cls, session_id: str, service: QiskitRuntimeService) -> "Session":
)

cls._create_new_session = False
session = cls(service, backend)
session = cls(backend)
cls._create_new_session = True
if state == "closed":
session._active = False
Expand Down
11 changes: 11 additions & 0 deletions release-notes/unreleased/2027.other.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
The deprecations from the ``0.26.0`` release have been removed.

- Passing a backend as a string into ``Session``, ``Batch``,
``Sampler``, and ``Estimator`` is no longer valid. Use the actual backend
object instead.
- Passing a backend as the mode into ``SamplerV2`` or ``EstimatorV2`` used
to run jobs in job mode, even if a session context manager was open. These jobs will now
run inside of the open session. Additionally, if a backend that is different
from the session backend is passed in as the mode, an error will be raised.
- ``Service`` is no longer a valid parameter in ``Session`` and ``Batch``.

6 changes: 2 additions & 4 deletions test/integration/test_estimator_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

from qiskit_ibm_runtime import EstimatorV2, Session
from qiskit_ibm_runtime.fake_provider import FakeAuckland
from ..decorators import run_integration_test
from ..ibm_test_case import IBMIntegrationTestCase


Expand All @@ -33,8 +32,7 @@ def setUp(self) -> None:
super().setUp()
self._backend = self.service.backend(self.dependencies.qpu)

@run_integration_test
def test_estimator_v2_session(self, service):
def test_estimator_v2_session(self):
"""Verify correct results are returned"""
pass_mgr = generate_preset_pass_manager(backend=self._backend, optimization_level=1)

Expand All @@ -50,7 +48,7 @@ def test_estimator_v2_session(self, service):
theta2 = [0, 1, 1, 2, 3, 5, 8, 13]
theta3 = [1, 2, 3, 4, 5, 6]

with Session(service, self._backend) as session:
with Session(self._backend) as session:
estimator = EstimatorV2(mode=session)

job = estimator.run([(psi1, H1, [theta1])])
Expand Down
2 changes: 1 addition & 1 deletion test/integration/test_noise_learner.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def test_learner_plus_estimator(self, service): # pylint: disable=unused-argume

pubs = [(circuit, "Z" * circuit.num_qubits)]

with Session(service, self._backend) as session:
with Session(self._backend) as session:
learner = NoiseLearner(mode=session, options=options)
learner_job = learner.run(self.circuits)
noise_model = learner_job.result()
Expand Down
Loading

0 comments on commit 639f307

Please sign in to comment.