Skip to content

Commit

Permalink
Add mode parameter (#1584)
Browse files Browse the repository at this point in the history
* add mode param and deprecate warning to session.

* replaced session by mode

* fix tests

* fix tests

* update method

* update mode value

* replaced backend and session params with mode

* Added mode param. Deprecated backend and session.

* Updated V2 tests using mode param.

* Updated _backend

* updated tests

* improve docstrings

* style fixes

* back backend param

* pylint fixes

* mypy fixes

* updated the backend for cm session

* ignore type

* added release notes

* update deprecation message

* Apply suggestions from code review

Co-authored-by: Jessie Yu <[email protected]>

* improve docstrings

* revert V1 changes

* Update from PR comments

* back to backend arg

* update release notes

* Update qiskit_ibm_runtime/sampler.py

Co-authored-by: Jessie Yu <[email protected]>

* Update qiskit_ibm_runtime/estimator.py

Co-authored-by: Jessie Yu <[email protected]>

* Update qiskit_ibm_runtime/sampler.py

Co-authored-by: Jessie Yu <[email protected]>

* Update qiskit_ibm_runtime/base_primitive.py

Co-authored-by: Jessie Yu <[email protected]>

* Update qiskit_ibm_runtime/base_primitive.py

Co-authored-by: Jessie Yu <[email protected]>

* updated from PR comments

* updated from PR comments

* update docstring

* Update qiskit_ibm_runtime/estimator.py

Co-authored-by: Jessie Yu <[email protected]>

* Update qiskit_ibm_runtime/sampler.py

Co-authored-by: Jessie Yu <[email protected]>

* Update qiskit_ibm_runtime/base_primitive.py

Co-authored-by: Jessie Yu <[email protected]>

* linter fixes

* split mode param tests

* merged manually

* add missing import

---------

Co-authored-by: Jessie Yu <[email protected]>
Co-authored-by: Kevin Tian <[email protected]>
  • Loading branch information
3 people authored Apr 18, 2024
1 parent 0e47fbe commit bc4d01c
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 67 deletions.
76 changes: 39 additions & 37 deletions qiskit_ibm_runtime/base_primitive.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@
from .runtime_job_v2 import RuntimeJobV2
from .ibm_backend import IBMBackend
from .utils.default_session import get_cm_session
from .utils.deprecation import issue_deprecation_msg
from .utils.deprecation import issue_deprecation_msg, deprecate_function
from .utils.utils import validate_isa_circuits, is_simulator, validate_no_dd_with_dynamic_circuits
from .constants import DEFAULT_DECODERS
from .qiskit_runtime_service import QiskitRuntimeService
from .fake_provider.local_service import QiskitRuntimeLocalService


# pylint: disable=unused-import,cyclic-import
from .session import Session
from .batch import Batch

logger = logging.getLogger(__name__)
OptionsT = TypeVar("OptionsT", bound=BaseOptions)
Expand All @@ -56,24 +56,17 @@ class BasePrimitiveV2(ABC, Generic[OptionsT]):

def __init__(
self,
backend: Optional[Union[str, BackendV1, BackendV2]] = None,
session: Optional[Session] = None,
mode: Optional[Union[BackendV1, BackendV2, Session, Batch, str]] = None,
options: Optional[Union[Dict, OptionsT]] = None,
):
"""Initializes the primitive.
Args:
mode: The execution mode used to make the primitive query. It can be
backend: Backend to run the primitive. This can be a backend name or a ``Backend``
instance. If a name is specified, the default account (e.g. ``QiskitRuntimeService()``)
is used.
session: 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.
* A :class:`Backend` if you are using job mode.
* A :class:`Session` if you are using session execution mode.
* A :class:`Batch` if you are using batch execution mode.
options: Primitive options, see :class:`qiskit_ibm_runtime.options.EstimatorOptions`
and :class:`qiskit_ibm_runtime.options.SamplerOptions` for detailed description
Expand All @@ -82,38 +75,36 @@ def __init__(
Raises:
ValueError: Invalid arguments are given.
"""
self._session: Optional[Session] = None
self._mode: Optional[Union[Session, Batch]] = None
self._service: QiskitRuntimeService | QiskitRuntimeLocalService = None
self._backend: Optional[BackendV1 | BackendV2] = None

self._set_options(options)

if isinstance(session, Session):
self._session = session
self._service = self._session.service
self._backend = self._session._backend
return
elif session is not None: # type: ignore[unreachable]
raise ValueError("session must be of type Session or None")

if isinstance(backend, IBMBackend): # type: ignore[unreachable]
self._service = backend.service
self._backend = backend
elif isinstance(backend, (BackendV1, BackendV2)):
if isinstance(mode, (Session, Batch)):
self._mode = mode
self._service = self._mode.service
self._backend = self._mode._backend
elif isinstance(mode, IBMBackend): # type: ignore[unreachable]
self._service = mode.service
self._backend = mode
elif isinstance(mode, (BackendV1, BackendV2)):
self._service = QiskitRuntimeLocalService()
self._backend = backend
elif isinstance(backend, str):
self._backend = mode
elif isinstance(mode, str):
self._service = (
QiskitRuntimeService()
if QiskitRuntimeService.global_service is None
else QiskitRuntimeService.global_service
)
self._backend = self._service.backend(backend)
self._backend = self._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():
self._session = get_cm_session()
self._service = self._session.service
self._backend = self._service.backend(
name=self._session.backend(), instance=self._session._instance
self._mode = get_cm_session()
self._service = self._mode.service
self._backend = self._service.backend( # type: ignore
name=self._mode.backend(), instance=self._mode._instance
)
else:
self._service = (
Expand Down Expand Up @@ -159,8 +150,9 @@ def _run(self, pubs: Union[list[EstimatorPub], list[SamplerPub]]) -> RuntimeJobV

logger.info("Submitting job using options %s", primitive_options)

if self._session:
return self._session.run(
# Batch or Session
if self._mode:
return self._mode.run(
program_id=self._program_id(),
inputs=primitive_inputs,
options=runtime_options,
Expand Down Expand Up @@ -195,7 +187,17 @@ def session(self) -> Optional[Session]:
Returns:
Session used by this primitive, or ``None`` if session is not used.
"""
return self._session
deprecate_function("session", "0.23.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.
Returns:
Mode used by this primitive, or ``None`` if an execution mode is not used.
"""
return self._mode

@property
def options(self) -> OptionsT:
Expand Down
40 changes: 38 additions & 2 deletions qiskit_ibm_runtime/estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,28 @@
import logging

from qiskit.circuit import QuantumCircuit
from qiskit.providers import BackendV1, BackendV2
from qiskit.quantum_info.operators.base_operator import BaseOperator
from qiskit.quantum_info.operators import SparsePauliOp
from qiskit.primitives import BaseEstimator
from qiskit.primitives.base import BaseEstimatorV2
from qiskit.primitives.containers import EstimatorPubLike
from qiskit.primitives.containers.estimator_pub import EstimatorPub

from .runtime_job import RuntimeJob
from .runtime_job_v2 import RuntimeJobV2
from .ibm_backend import IBMBackend
from .options import Options
from .options.estimator_options import EstimatorOptions
from .base_primitive import BasePrimitiveV1, BasePrimitiveV2
from .utils.deprecation import deprecate_arguments, issue_deprecation_msg
from .utils.qctrl import validate as qctrl_validate
from .utils.qctrl import validate_v2 as qctrl_validate_v2


# pylint: disable=unused-import,cyclic-import
from .session import Session
from .batch import Batch

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -104,13 +108,23 @@ class EstimatorV2(BasePrimitiveV2[EstimatorOptions], Estimator, BaseEstimatorV2)

def __init__(
self,
backend: Optional[Union[str, IBMBackend]] = None,
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.
Args:
mode: The execution mode used to make the primitive query. It can be:
* A :class:`Backend` if you are using job mode.
* A :class:`Session` if you are using session execution mode.
* A :class:`Batch` if you are using batch execution mode.
Refer to the `Qiskit Runtime documentation <https://docs.quantum.ibm.com/run>`_.
for more information about the ``Execution modes``.
backend: 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.
Expand All @@ -129,7 +143,29 @@ def __init__(
"""
BaseEstimatorV2.__init__(self)
Estimator.__init__(self)
BasePrimitiveV2.__init__(self, backend=backend, session=session, options=options)
if backend:
deprecate_arguments(
"backend",
"0.23.0",
"Please use the 'mode' parameter instead.",
)
if session:
deprecate_arguments(
"session",
"0.23.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.23.0",
"A backend object should be provided instead. Get the backend directly from"
" the service using `QiskitRuntimeService().backend('ibm_backend')`",
3,
)
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(
self, pubs: Iterable[EstimatorPubLike], *, precision: float | None = None
Expand Down
39 changes: 37 additions & 2 deletions qiskit_ibm_runtime/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from qiskit.primitives import BaseSampler
from qiskit.primitives.base import BaseSamplerV2
from qiskit.primitives.containers.sampler_pub import SamplerPub, SamplerPubLike
from qiskit.providers import BackendV1, BackendV2

from .options import Options
from .runtime_job import RuntimeJob
Expand All @@ -31,6 +32,8 @@

# pylint: disable=unused-import,cyclic-import
from .session import Session
from .batch import Batch
from .utils.deprecation import deprecate_arguments, issue_deprecation_msg
from .utils.qctrl import validate as qctrl_validate
from .utils.qctrl import validate_v2 as qctrl_validate_v2
from .options import SamplerOptions
Expand Down Expand Up @@ -63,13 +66,23 @@ class SamplerV2(BasePrimitiveV2[SamplerOptions], Sampler, BaseSamplerV2):

def __init__(
self,
backend: Optional[Union[str, IBMBackend]] = None,
mode: Optional[Union[BackendV1, BackendV2, Session, Batch, str]] = None,
backend: Optional[Union[str, BackendV1, BackendV2]] = None,
session: Optional[Session] = None,
options: Optional[Union[Dict, SamplerOptions]] = None,
):
"""Initializes the Sampler primitive.
Args:
mode: The execution mode used to make the primitive query. It can be:
* A :class:`Backend` if you are using job mode.
* A :class:`Session` if you are using session execution mode.
* A :class:`Batch` if you are using batch execution mode.
Refer to the `Qiskit Runtime documentation <https://docs.quantum.ibm.com/run>`_.
for more information about the ``Execution modes``.
backend: 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.
Expand All @@ -89,7 +102,29 @@ def __init__(
self.options: SamplerOptions
BaseSamplerV2.__init__(self)
Sampler.__init__(self)
BasePrimitiveV2.__init__(self, backend=backend, session=session, options=options)
if backend:
deprecate_arguments(
"backend",
"0.23.0",
"Please use the 'mode' parameter instead.",
)
if session:
deprecate_arguments(
"session",
"0.23.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.23.0",
"A backend object should be provided instead. Get the backend directly from"
" the service using `QiskitRuntimeService().backend('ibm_backend')`",
3,
)
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(self, pubs: Iterable[SamplerPubLike], *, shots: int | None = None) -> RuntimeJobV2:
"""Submit a request to the sampler primitive.
Expand Down
2 changes: 2 additions & 0 deletions release-notes/unreleased/1556.deprecation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
`backend` argument in `Sampler <https://docs.quantum.ibm.com/run/primitives-get-started#3-initialize-the-qiskit-runtime-sampler>`__ and `Estimator <https://docs.quantum.ibm.com/run/primitives-get-started#3-initialize-qiskit-runtime-estimator>`__ has been deprecated . Please use the new `mode` argument instead.
`session` argument in `Sampler <https://docs.quantum.ibm.com/run/primitives-get-started#3-initialize-the-qiskit-runtime-sampler>`__ and `Estimator <https://docs.quantum.ibm.com/run/primitives-get-started#3-initialize-qiskit-runtime-estimator>`__ has been deprecated . Please use the new `mode` argument instead.
3 changes: 3 additions & 0 deletions release-notes/unreleased/1556.feat.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Related to the execution modes, Sampler and Estimator now include a `mode` argument. The `mode` param
can be a Backend, Session, Batch, or None. Due to this, the backend name has been deprecated, and will
no longer be supported as a valid execution mode.
Loading

0 comments on commit bc4d01c

Please sign in to comment.