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

Follow up on non-versioned primitives deprecation #12818

Closed
wants to merge 8 commits into from
Closed
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
68 changes: 61 additions & 7 deletions qiskit/primitives/backend_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
)
from qiskit.utils.deprecation import deprecate_func

from .base import BaseEstimator, EstimatorResult
from .base import BaseEstimatorV1, EstimatorResult
from .primitive_job import PrimitiveJob
from .utils import _circuit_key, _observable_key, init_observable

Expand Down Expand Up @@ -89,23 +89,23 @@ def _prepare_counts(results: list[Result]):
return counts


class BackendEstimator(BaseEstimator[PrimitiveJob[EstimatorResult]]):
class BackendEstimatorV1(BaseEstimatorV1[PrimitiveJob[EstimatorResult]]):
"""Evaluates expectation value using Pauli rotation gates.

The :class:`~.BackendEstimator` class is a generic implementation of the
:class:`~.BaseEstimator` interface that is used to wrap a :class:`~.BackendV2`
:class:`~.BaseEstimatorV1` interface that is used to wrap a :class:`~.BackendV2`
(or :class:`~.BackendV1`) object in the :class:`~.BaseEstimator` API. It
facilitates using backends that do not provide a native
:class:`~.BaseEstimator` implementation in places that work with
:class:`~.BaseEstimator`. However,
:class:`~.BaseEstimatorV1` implementation in places that work with
:class:`~.BaseEstimatorV1`. However,
if you're using a provider that has a native implementation of
:class:`~.BaseEstimator`, it is a better choice to leverage that native
:class:`~.BaseEstimatorV1` or :class:`~.BaseEstimatorV2`, it is a better
choice to leverage that native
implementation as it will likely include additional optimizations and be
a more efficient implementation. The generic nature of this class
precludes doing any provider- or backend-specific optimizations.
"""

@deprecate_func(since="1.2", additional_msg="Use BackendEstimatorV2 instead.")
def __init__(
self,
backend: BackendV1 | BackendV2,
Expand Down Expand Up @@ -409,6 +409,60 @@ def _bound_pass_manager_run(self, circuits):
return output


class BackendEstimator(BackendEstimatorV1):
"""Evaluates expectation value using Pauli rotation gates.

The :class:`~.BackendEstimator` class is a generic implementation of the
:class:`~.BaseEstimatorV1` interface that is used to wrap a :class:`~.BackendV2`
(or :class:`~.BackendV1`) object in the :class:`~.BaseEstimator` API. It
facilitates using backends that do not provide a native
:class:`~.BaseEstimatorV1` implementation in places that work with
:class:`~.BaseEstimatorV1`. However,
if you're using a provider that has a native implementation of
:class:`~.BaseEstimatorV1` or :class:`~.BaseEstimatorV2`, it is a better
choice to leverage that native
implementation as it will likely include additional optimizations and be
a more efficient implementation. The generic nature of this class
precludes doing any provider- or backend-specific optimizations.
"""

@deprecate_func(
since="1.2",
additional_msg="The preferred replacement is "
":class:`.BackendEstimatorV2`. However, "
":class:`.BackendEstimatorV1` is a drop-in replacement "
"for `BackendEstimatorV2`, which is an alias.",
)
def __init__(
self,
backend: BackendV1 | BackendV2,
options: dict | None = None,
abelian_grouping: bool = True,
bound_pass_manager: PassManager | None = None,
skip_transpilation: bool = False,
):
"""Initialize a new BackendEstimator instance

Args:
backend: Required: the backend to run the primitive on
options: Default options.
abelian_grouping: Whether the observable should be grouped into
commuting
bound_pass_manager: An optional pass manager to run after
parameter binding.
skip_transpilation: If this is set to True the internal compilation
of the input circuits is skipped and the circuit objects
will be directly executed when this object is called.
"""
super().__init__(
backend=backend,
options=options,
abelian_grouping=abelian_grouping,
bound_pass_manager=bound_pass_manager,
skip_transpilation=skip_transpilation,
)


def _paulis2inds(paulis: PauliList) -> list[int]:
"""Convert PauliList to diagonal integers.
These are integer representations of the binary string with a
Expand Down
64 changes: 57 additions & 7 deletions qiskit/primitives/backend_sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,27 @@
from qiskit.utils.deprecation import deprecate_func

from .backend_estimator import _prepare_counts, _run_circuits
from .base import BaseSampler, SamplerResult
from .base import BaseSamplerV1, SamplerResult
from .primitive_job import PrimitiveJob
from .utils import _circuit_key


class BackendSampler(BaseSampler[PrimitiveJob[SamplerResult]]):
"""A :class:`~.BaseSampler` implementation that provides an interface for
class BackendSamplerV1(BaseSamplerV1[PrimitiveJob[SamplerResult]]):
"""A :class:`~.BaseSamplerV1` implementation that provides an interface for
leveraging the sampler interface from any backend.

This class provides a sampler interface from any backend and doesn't do
any measurement mitigation, it just computes the probability distribution
from the counts. It facilitates using backends that do not provide a
native :class:`~.BaseSampler` implementation in places that work with
:class:`~.BaseSampler`.
native :class:`~.BaseSamplerV1` implementation in places that work with
:class:`~.BaseSamplerV1`.
However, if you're using a provider that has a native implementation of
:class:`~.BaseSampler`, it is a better choice to leverage that native
:class:`~.BaseSamplerV1` or :class:`~.BaseSamplerV2`, it is a better choice to leverage that native
implementation as it will likely include additional optimizations and be
a more efficient implementation. The generic nature of this class
precludes doing any provider- or backend-specific optimizations.
"""

@deprecate_func(since="1.2", additional_msg="Use BackendSamplerV2 instead.")
def __init__(
self,
backend: BackendV1 | BackendV2,
Expand Down Expand Up @@ -213,3 +212,54 @@ def _run(
job = PrimitiveJob(self._call, circuit_indices, parameter_values, **run_options)
job._submit()
return job


class BackendSampler(BackendSamplerV1):
"""A :class:`~.BaseSamplerV1` implementation that provides an interface for
leveraging the sampler interface from any backend.

This class provides a sampler interface from any backend and doesn't do
any measurement mitigation, it just computes the probability distribution
from the counts. It facilitates using backends that do not provide a
native :class:`~.BaseSamplerV1` implementation in places that work with
:class:`~.BaseSamplerV1`.
However, if you're using a provider that has a native implementation of
:class:`~.BaseSamplerV1` or :class:`~.BaseSamplerV2`, it is a better choice to leverage that native
implementation as it will likely include additional optimizations and be
a more efficient implementation. The generic nature of this class
precludes doing any provider- or backend-specific optimizations.
"""

@deprecate_func(
since="1.2",
additional_msg="The preferred replacement is "
":class:`.BackendSamplerV2`. However, "
":class:`.BackendSamplerV1` is a drop-in replacement "
"for `BackendSampler`, which is an alias.",
)
def __init__(
self,
backend: BackendV1 | BackendV2,
options: dict | None = None,
bound_pass_manager: PassManager | None = None,
skip_transpilation: bool = False,
):
"""Initialize a new BackendSampler

Args:
backend: Required: the backend to run the sampler primitive on
options: Default options.
bound_pass_manager: An optional pass manager to run after
parameter binding.
skip_transpilation: If this is set to True the internal compilation
of the input circuits is skipped and the circuit objects
will be directly executed when this objected is called.
Raises:
ValueError: If backend is not provided
"""
super().__init__(
backend=backend,
options=options,
bound_pass_manager=bound_pass_manager,
skip_transpilation=skip_transpilation,
)
8 changes: 7 additions & 1 deletion qiskit/primitives/base/base_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,13 @@ class BaseEstimator(BaseEstimatorV1[T]):
See :class:`.BaseEstimatorV1` for details.
"""

@deprecate_func(since="1.2", additional_msg="Use BaseEstimatorV2 instead.")
@deprecate_func(
since="1.2",
additional_msg="The preferred replacement is "
":class:`.BaseEstimatorV2`. However, "
":class:`.BaseEstimatorV1` is a drop-in replacement "
"for `BaseEstimator`, which is an alias.",
)
def __init__(
self,
*,
Expand Down
8 changes: 7 additions & 1 deletion qiskit/primitives/base/base_sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,13 @@ class BaseSampler(BaseSamplerV1[T]):
See :class:`.BaseSamplerV1` for details.
"""

@deprecate_func(since="1.2", additional_msg="Use BaseSamplerV2 instead.")
@deprecate_func(
since="1.2",
additional_msg="The preferred replacement is "
":class:`.BaseSamplerV2`. However, "
":class:`.BaseSamplerV1` is a drop-in replacement "
"for `BaseSampler`, which is an alias.",
)
def __init__(
self,
*,
Expand Down
14 changes: 10 additions & 4 deletions qiskit/primitives/estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from qiskit.quantum_info.operators.base_operator import BaseOperator
from qiskit.utils.deprecation import deprecate_func

from .base import BaseEstimator, EstimatorResult
from .base import BaseEstimatorV1, EstimatorResult
from .primitive_job import PrimitiveJob
from .utils import (
_circuit_key,
Expand All @@ -36,9 +36,9 @@
)


class Estimator(BaseEstimator[PrimitiveJob[EstimatorResult]]):
class Estimator(BaseEstimatorV1[PrimitiveJob[EstimatorResult]]):
"""
Reference implementation of :class:`BaseEstimator`.
Reference implementation of :class:`BaseEstimatorV1`.

:Run Options:

Expand All @@ -52,7 +52,13 @@ class Estimator(BaseEstimator[PrimitiveJob[EstimatorResult]]):
this option is ignored.
"""

@deprecate_func(since="1.2", additional_msg="Use StatevectorEstimator instead.")
@deprecate_func(
since="1.2",
additional_msg="The preferred replacement is "
":class:`.EstimatorV2`. However, "
":class:`.EstimatorV1` is a drop-in replacement "
"for `Estimator`, which is an alias.",
)
def __init__(self, *, options: dict | None = None):
"""
Args:
Expand Down
12 changes: 9 additions & 3 deletions qiskit/primitives/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from qiskit.result import QuasiDistribution
from qiskit.utils.deprecation import deprecate_func

from .base import BaseSampler, SamplerResult
from .base import BaseSamplerV1, SamplerResult
from .primitive_job import PrimitiveJob
from .utils import (
_circuit_key,
Expand All @@ -36,7 +36,7 @@
)


class Sampler(BaseSampler[PrimitiveJob[SamplerResult]]):
class Sampler(BaseSamplerV1[PrimitiveJob[SamplerResult]]):
"""
Sampler class.

Expand All @@ -53,7 +53,13 @@ class Sampler(BaseSampler[PrimitiveJob[SamplerResult]]):
option is ignored.
"""

@deprecate_func(since="1.2", additional_msg="Use StatevectorSampler instead.")
@deprecate_func(
since="1.2",
additional_msg="The preferred replacement is "
":class:`.SamplerV2`. However, "
":class:`.SamplerV1` is a drop-in replacement "
"for `Sampler`, which is an alias.",
)
def __init__(self, *, options: dict | None = None):
"""
Args:
Expand Down
16 changes: 0 additions & 16 deletions qiskit/primitives/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,8 @@
from qiskit.quantum_info import PauliList, SparsePauliOp, Statevector
from qiskit.quantum_info.operators.base_operator import BaseOperator
from qiskit.quantum_info.operators.symplectic.base_pauli import BasePauli
from qiskit.utils.deprecation import deprecate_func


@deprecate_func(
since="1.2",
additional_msg="To initialize a circuit from a ``Statevector`` instance, "
+ "use ``QuantumCircuit.initialize`` instead.",
)
def init_circuit(state: QuantumCircuit | Statevector) -> QuantumCircuit:
"""Initialize state by converting the input to a quantum circuit.

Expand All @@ -51,10 +45,6 @@ def init_circuit(state: QuantumCircuit | Statevector) -> QuantumCircuit:
return qc


@deprecate_func(
since="1.2",
additional_msg="Use the constructor of ``SparsePauliOp`` instead.",
)
def init_observable(observable: BaseOperator | str) -> SparsePauliOp:
"""Initialize observable by converting the input to a :class:`~qiskit.quantum_info.SparsePauliOp`.

Expand All @@ -78,12 +68,6 @@ def init_observable(observable: BaseOperator | str) -> SparsePauliOp:
return SparsePauliOp(observable)


@deprecate_func(
since="1.2",
additional_msg="Use ``QuantumCircuit.layout`` and ``SparsePauliOp.apply_layout`` "
+ "to adjust an operator for a layout. Otherwise, use ``mthree.utils.final_measurement_mapping``. "
+ "See https://qiskit-extensions.github.io/mthree/apidocs/utils.html for details.",
)
def final_measurement_mapping(circuit: QuantumCircuit) -> dict[int, int]:
"""Return the final measurement mapping for the circuit.

Expand Down
13 changes: 13 additions & 0 deletions releasenotes/notes/deprecate-non-versioned-primitives.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
deprecations_primitives:
- |
Non-versioned primitives aliases are now deprecated and will be removed in the next major release.

The following classes are deprecated:

* :class:`.BaseEstimator` as :class:`.BaseEstimatorV1` alias. However, :class:`.BaseEstimatorV2` is recommended instead.
* :class:`.BaseSampler` as :class:`.BaseSamplerV1` alias. However, :class:`.BaseSamplerV2` is recommended instead.
* :class:`.Estimator` as :class:`.EstimatorV1` alias. However, :class:`.EstimatorV2` is recommended instead.
* :class:`.Sampler` as :class:`.SamplerV1` alias. However, :class:`.SamplerV2` is recommended instead.
* :class:`.BackendEstimator` as :class:`.BackendEstimatorV1` alias. However, :class:`.BackendEstimatorV2` is recommended instead.
* :class:`.BackendSampler` as :class:`.BackendSamplerV1` alias. However, :class:`.BackendSamplerV2` is recommended instead.
26 changes: 0 additions & 26 deletions releasenotes/notes/deprecate-primitives-v1.yaml

This file was deleted.

Loading
Loading