Skip to content

Commit

Permalink
Legacy operator arithmetic deprecation (#6287)
Browse files Browse the repository at this point in the history
**Context:**
Legacy op math is being deprecated.

**Description of the Change:**
* `qml.ops.Hamiltonian` is deprecated.
* `qml.operation.Tensor` is deprecated.
* `qml.operation.disable_new_opmath` and
`qml.operation.enable_new_opmath` (as well as the context managers) are
deprecated.
* `qml.operation.convert_to_legacy_H` is deprecated.
* `PauliWord.hamiltonian` and `PauliSentence.hamiltonian` is deprecated.
* `qml.pauli.simplify` is deprecated.
* Removed `use_legacy_opmath` and `use_new_opmath` fixtures. Instead, we
use either `legacy_opmath_only`, `new_opmath_only`, or no fixture, as
appropriate for the tests.

* Added warning suppression for all the above deprecation warnings to
`pytest.ini`. Additionally, I also added the same warning suppressions
to `conftest.py` for the case when `--disable-opmath=True`, since the
warning filters in `pytest.ini` only suppress warnings that come from
inside tests, not ones that come from outside the tests, such as when
deprecated code is used for creating parameters for a test.

**Benefits:**

**Possible Drawbacks:**
In some instances, there will be a LOT of deprecation warnings at the
same time. The most impactful example of this if if using
`qml.qchem.molecular_hamiltonian`, `qml.qchem.qubit_observable`. These
using `simplify` and `PauliSentence.hamiltonian` with legacy op math, so
there will be up to 4 warnings at once when using these.

Additionally, `qml.qchem.tapering.symmetry_generators` and
`qml.qchem.tapering.clifford` use `PauliSentence.hamiltonian` when
legacy op math is enabled, so there will be up to 3 warnings at once
when using these.

**Related GitHub Issues:**

I will run the test suite with `disable_new_opmath` set to `True` once
before merging to confirm that legacy op math tests do not fail.

[sc-71940] [sc-66727] [sc-66724]

---------

Co-authored-by: Pietropaolo Frisoni <[email protected]>
  • Loading branch information
mudit2812 and PietropaoloFrisoni authored Oct 3, 2024
1 parent a8ada6b commit 9f4e67e
Show file tree
Hide file tree
Showing 54 changed files with 1,283 additions and 1,686 deletions.
37 changes: 24 additions & 13 deletions doc/development/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,30 +68,41 @@ Pending deprecations
New operator arithmetic deprecations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The v0.36 release completes the main phase of PennyLane's switchover to an updated approach for handling
arithmetic operations between operators, check out the :ref:`Updated operators <new_opmath>` page
for more details. The old system is still accessible via :func:`~.disable_new_opmath`. However, the
old system will be removed in an upcoming release and should be treated as deprecated. The following
functionality will explicitly raise a deprecation warning when used:
In PennyLane v0.39, the legacy operator arithmetic system has been deprecated. Check out the :ref:`Updated operators <new_opmath>` page
for details on how to port your legacy code to the new system. The old system is still accessible via :func:`~.disable_new_opmath`, though
it is not recommended, as the old system is deprecated and will be removed in the v0.40 release. The following functionality will explicitly
raise a deprecation warning when used:

* In PennyLane v0.39, legacy operator arithmetic has been deprecated. This includes :func:`~pennylane.operation.enable_new_opmath`,
:func:`~pennylane.operation.disable_new_opmath`, :class:`~pennylane.ops.Hamiltonian`, and :class:`~pennylane.operation.Tensor`. Note
that when new operator arithmetic is enabled, ``qml.Hamiltonian`` will continue to dispatch to :class:`~pennylane.ops.LinearCombination`;
this behaviour is not deprecated.

- Deprecated in v0.39
- Will be removed in v0.40

* :meth:`~pennylane.pauli.PauliSentence.hamiltonian` and :meth:`~pennylane.pauli.PauliWord.hamiltonian` are deprecated. Instead, please use
:meth:`~pennylane.pauli.PauliSentence.operation` and :meth:`~pennylane.pauli.PauliWord.operation` respectively.

- Deprecated in v0.39
- Will be removed in v0.40

* :func:`pennylane.pauli.simplify` is deprecated. Instead, please use :func:`pennylane.simplify` or :meth:`~pennylane.operation.Operator.simplify`.

- Deprecated in v0.39
- Will be removed in v0.40

* ``op.ops`` and ``op.coeffs`` will be deprecated in the future. Use
:meth:`~.Operator.terms` instead.

- Added and deprecated for ``Sum`` and ``Prod`` instances in v0.35

* Accessing ``qml.ops.Hamiltonian`` is deprecated because it points to the old version of the class
that may not be compatible with the new approach to operator arithmetic. Instead, using
``qml.Hamiltonian`` is recommended because it dispatches to the :class:`~.LinearCombination` class
when the new approach to operator arithmetic is enabled. This will allow you to continue to use
``qml.Hamiltonian`` with existing code without needing to make any changes.

- Use of ``qml.ops.Hamiltonian`` is deprecated in v0.36

* Accessing terms of a tensor product (e.g., ``op = X(0) @ X(1)``) via ``op.obs`` is deprecated with new operator arithmetic.
A user should use :class:`op.operands <~.CompositeOp>` instead.

- Deprecated in v0.36


Other deprecations
~~~~~~~~~~~~~~~~~~

Expand Down
7 changes: 6 additions & 1 deletion doc/news/new_opmath.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ Summary of the update

The opt-in feature ``qml.operation.enable_new_opmath()`` is now the default. Ideally, your code should not break.
If it still does, it likely only requires some minor changes. For that, see the :ref:`Troubleshooting_opmath` section.
You can still opt-out and run legacy code via ``qml.operation.disable_new_opmath()``.
You can still opt-out and run legacy code via ``qml.operation.disable_new_opmath()``, though it is deprecated, and thus,
not recommended.

.. warning::

In PennyLane v0.39, legacy operator arithmetic is deprecated and will be removed in v0.40.


* The underlying system for performing arithmetic with operators has been changed. Arithmetic can be carried out using
Expand Down
14 changes: 14 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,20 @@

<h3>Deprecations 👋</h3>

* Legacy operator arithmetic has been deprecated. This includes `qml.ops.Hamiltonian`, `qml.operation.Tensor`,
`qml.operation.enable_new_opmath`, `qml.operation.disable_new_opmath`, and `qml.operation.convert_to_legacy_H`.
Note that when new operator arithmetic is enabled, ``qml.Hamiltonian`` will continue to dispatch to
`qml.ops.LinearCombination`; this behaviour is not deprecated. For more information, check out the
[updated operator troubleshooting page](https://docs.pennylane.ai/en/stable/news/new_opmath.html).
[(#6287)](https://github.com/PennyLaneAI/pennylane/pull/6287)

* `qml.pauli.PauliSentence.hamiltonian` and `qml.pauli.PauliWord.hamiltonian` are deprecated. Instead, please use
`qml.pauli.PauliSentence.operation` and `qml.pauli.PauliWord.operation` respectively.
[(#6287)](https://github.com/PennyLaneAI/pennylane/pull/6287)

* `qml.pauli.simplify()` is deprecated. Instead, please use `qml.simplify(op)` or `op.simplify()`.
[(#6287)](https://github.com/PennyLaneAI/pennylane/pull/6287)

* The `qml.BasisStatePreparation` template is deprecated.
Instead, use `qml.BasisState`.
[(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021)
Expand Down
7 changes: 7 additions & 0 deletions pennylane/devices/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""Contains shared fixtures for the device tests."""
import argparse
import os
from warnings import warn

import numpy as np
import pytest
Expand Down Expand Up @@ -226,6 +227,12 @@ def disable_opmath_if_requested(request):
disable_opmath = request.config.getoption("--disable-opmath")
# value from yaml file is a string, convert to boolean
if eval(disable_opmath):
warn(
"Disabling the new Operator arithmetic system for legacy support. "
"If you need help troubleshooting your code, please visit "
"https://docs.pennylane.ai/en/stable/news/new_opmath.html",
UserWarning,
)
qml.operation.disable_new_opmath(warn=False)


Expand Down
80 changes: 64 additions & 16 deletions pennylane/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2123,6 +2123,14 @@ def __init__(self, *args): # pylint: disable=super-init-not-called
self._pauli_rep = None
self.queue(init=True)

warnings.warn(
"qml.operation.Tensor uses the old approach to operator arithmetic, which will become "
"unavailable in version 0.40 of PennyLane. If you are experiencing issues, visit "
"https://docs.pennylane.ai/en/stable/news/new_opmath.html or contact the PennyLane "
"team on the discussion forum: https://discuss.pennylane.ai/.",
qml.PennyLaneDeprecationWarning,
)

wires = [op.wires for op in self.obs]
if len(wires) != len(set(wires)):
warnings.warn(
Expand Down Expand Up @@ -3039,6 +3047,11 @@ def enable_new_opmath(warn=True):
"""
Change dunder methods to return arithmetic operators instead of Hamiltonians and Tensors
.. warning::
Using legacy operator arithmetic is deprecated, and will be removed in PennyLane v0.40.
For further details, see :doc:`Updated Operators </news/new_opmath/>`.
Args:
warn (bool): Whether or not to emit a warning for re-enabling new opmath. Default is ``True``.
Expand All @@ -3054,9 +3067,11 @@ def enable_new_opmath(warn=True):
"""
if warn:
warnings.warn(
"Re-enabling the new Operator arithmetic system after disabling it is not advised. "
"Please visit https://docs.pennylane.ai/en/stable/news/new_opmath.html for help troubleshooting.",
UserWarning,
"Toggling the new approach to operator arithmetic is deprecated. From version 0.40 of "
"PennyLane, only the new approach to operator arithmetic will be available. If you are "
"experiencing issues, visit https://docs.pennylane.ai/en/stable/news/new_opmath.html "
"or contact the PennyLane team on the discussion forum: https://discuss.pennylane.ai/.",
qml.PennyLaneDeprecationWarning,
)
global __use_new_opmath
__use_new_opmath = True
Expand All @@ -3066,6 +3081,11 @@ def disable_new_opmath(warn=True):
"""
Change dunder methods to return Hamiltonians and Tensors instead of arithmetic operators
.. warning::
Using legacy operator arithmetic is deprecated, and will be removed in PennyLane v0.40.
For further details, see :doc:`Updated Operators </news/new_opmath/>`.
Args:
warn (bool): Whether or not to emit a warning for disabling new opmath. Default is ``True``.
Expand All @@ -3081,10 +3101,11 @@ def disable_new_opmath(warn=True):
"""
if warn:
warnings.warn(
"Disabling the new Operator arithmetic system for legacy support. "
"If you need help troubleshooting your code, please visit "
"https://docs.pennylane.ai/en/stable/news/new_opmath.html",
UserWarning,
"Disabling the new approach to operator arithmetic is deprecated. From version 0.40 of "
"PennyLane, only the new approach to operator arithmetic will be available. If you are "
"experiencing issues, visit https://docs.pennylane.ai/en/stable/news/new_opmath.html "
"or contact the PennyLane team on the discussion forum: https://discuss.pennylane.ai/.",
qml.PennyLaneDeprecationWarning,
)
global __use_new_opmath
__use_new_opmath = False
Expand All @@ -3094,6 +3115,11 @@ def active_new_opmath():
"""
Function that checks if the new arithmetic operator dunders are active
.. warning::
Using legacy operator arithmetic is deprecated, and will be removed in PennyLane v0.40.
For further details, see :doc:`Updated Operators </news/new_opmath/>`.
Returns:
bool: Returns ``True`` if the new arithmetic operator dunders are active
Expand Down Expand Up @@ -3136,37 +3162,53 @@ def convert_to_opmath(op):


@contextmanager
def disable_new_opmath_cm():
def disable_new_opmath_cm(warn=True):
r"""Allows to use the old operator arithmetic within a
temporary context using the `with` statement."""
if warn:
warnings.warn(
"Disabling the new approach to operator arithmetic is deprecated. From version 0.40 of "
"PennyLane, only the new approach to operator arithmetic will be available. If you are "
"experiencing issues, visit https://docs.pennylane.ai/en/stable/news/new_opmath.html "
"or contact the PennyLane team on the discussion forum: https://discuss.pennylane.ai/.",
qml.PennyLaneDeprecationWarning,
)

was_active = qml.operation.active_new_opmath()
try:
if was_active:
disable_new_opmath(warn=False)
disable_new_opmath(warn=False) # Only warn once
yield
except Exception as e:
raise e
finally:
if was_active:
enable_new_opmath(warn=False)
enable_new_opmath(warn=False) # Only warn once
else:
disable_new_opmath(warn=False)
disable_new_opmath(warn=False) # Only warn once


@contextmanager
def enable_new_opmath_cm():
def enable_new_opmath_cm(warn=True):
r"""Allows to use the new operator arithmetic within a
temporary context using the `with` statement."""
if warn:
warnings.warn(
"Toggling the new approach to operator arithmetic is deprecated. From version 0.40 of "
"PennyLane, only the new approach to operator arithmetic will be available. If you are "
"experiencing issues, visit https://docs.pennylane.ai/en/stable/news/new_opmath.html "
"or contact the PennyLane team on the discussion forum: https://discuss.pennylane.ai/.",
qml.PennyLaneDeprecationWarning,
)

was_active = qml.operation.active_new_opmath()
if not was_active:
enable_new_opmath(warn=False)
enable_new_opmath(warn=False) # Only warn once
yield
if was_active:
enable_new_opmath(warn=False)
enable_new_opmath(warn=False) # Only warn once
else:
disable_new_opmath(warn=False)
disable_new_opmath(warn=False) # Only warn once


# pylint: disable=too-many-branches
Expand Down Expand Up @@ -3249,13 +3291,19 @@ def convert_to_legacy_H(op):
Arithmetic operators include :class:`~pennylane.ops.op_math.Prod`,
:class:`~pennylane.ops.op_math.Sum` and :class:`~pennylane.ops.op_math.SProd`.
.. warning::
Using legacy operator arithmetic is deprecated, and will be removed in PennyLane v0.40.
For further details, see :doc:`Updated Operators </news/new_opmath/>`.
Args:
op (Operator): The operator instance to convert.
Returns:
Operator: The operator as a :class:`~pennylane.Hamiltonian` instance
"""
with disable_new_opmath_cm():
with disable_new_opmath_cm(warn=False):
# Suppress warning because constructing Hamiltonian will raise a warning anyway
res = convert_to_H(op)
return res

Expand Down
21 changes: 11 additions & 10 deletions pennylane/ops/qubit/hamiltonian.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ class Hamiltonian(Observable):
.. warning::
As of ``v0.36``, ``qml.Hamiltonian`` dispatches to :class:`~.pennylane.ops.op_math.LinearCombination`
by default. For further details, see :doc:`Updated Operators </news/new_opmath/>`.
As of ``v0.39``, ``qml.ops.Hamiltonian`` is deprecated. When using the new operator arithmetic,
``qml.Hamiltonian`` will dispatch to :class:`~pennylane.ops.op_math.LinearCombination`. See
:doc:`Updated Operators </news/new_opmath/>` for more details.
Args:
coeffs (tensor_like): coefficients of the Hamiltonian expression
Expand Down Expand Up @@ -140,7 +141,7 @@ class Hamiltonian(Observable):
The following code examples show the behaviour of ``qml.Hamiltonian`` using old operator
arithmetic. See :doc:`Updated Operators </news/new_opmath/>` for more details. The old
behaviour can be reactivated by calling
behaviour can be reactivated by calling the deprecated
>>> qml.operation.disable_new_opmath()
Expand Down Expand Up @@ -253,13 +254,13 @@ def __init__(
method: Literal["lf", "rlf"] = "rlf",
id: str = None,
):
if qml.operation.active_new_opmath():
warn(
"Using 'qml.ops.Hamiltonian' with new operator arithmetic is deprecated. "
"Instead, use 'qml.Hamiltonian'. "
"Please visit https://docs.pennylane.ai/en/stable/news/new_opmath.html for more information and help troubleshooting.",
qml.PennyLaneDeprecationWarning,
)
warn(
"qml.ops.Hamiltonian uses the old approach to operator arithmetic, which will become "
"unavailable in version 0.40 of PennyLane. If you are experiencing issues, visit "
"https://docs.pennylane.ai/en/stable/news/new_opmath.html or contact the PennyLane "
"team on the discussion forum: https://discuss.pennylane.ai/.",
qml.PennyLaneDeprecationWarning,
)

if qml.math.shape(coeffs)[0] != len(observables):
raise ValueError(
Expand Down
31 changes: 28 additions & 3 deletions pennylane/pauli/pauli_arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# pylint:disable=protected-access
from copy import copy
from functools import lru_cache, reduce
from warnings import warn

import numpy as np
from scipy import sparse
Expand Down Expand Up @@ -82,7 +83,7 @@ def _cached_sparse_data(op):
elif op == "Y":
data = np.array([-1.0j, 1.0j], dtype=np.complex128)
indices = np.array([1, 0], dtype=np.int64)
elif op == "Z":
else: # op == "Z"
data = np.array([1.0, -1.0], dtype=np.complex128)
indices = np.array([0, 1], dtype=np.int64)
return data, indices
Expand Down Expand Up @@ -518,7 +519,19 @@ def operation(self, wire_order=None, get_as_tensor=False):
return factors[0] if len(factors) == 1 else Prod(*factors, _pauli_rep=pauli_rep)

def hamiltonian(self, wire_order=None):
"""Return :class:`~pennylane.Hamiltonian` representing the PauliWord."""
"""Return :class:`~pennylane.Hamiltonian` representing the PauliWord.
.. warning::
:meth:`~pennylane.pauli.PauliWord.hamiltonian` is deprecated. Instead, please use
:meth:`~pennylane.pauli.PauliWord.operation`
"""
warn(
"PauliWord.hamiltonian() is deprecated. Please use PauliWord.operation() instead.",
qml.PennyLaneDeprecationWarning,
)

if len(self) == 0:
if wire_order in (None, [], Wires([])):
raise ValueError("Can't get the Hamiltonian for an empty PauliWord.")
Expand Down Expand Up @@ -1022,7 +1035,19 @@ def operation(self, wire_order=None):
return summands[0] if len(summands) == 1 else Sum(*summands, _pauli_rep=self)

def hamiltonian(self, wire_order=None):
"""Returns a native PennyLane :class:`~pennylane.Hamiltonian` representing the PauliSentence."""
"""Returns a native PennyLane :class:`~pennylane.Hamiltonian` representing the PauliSentence.
.. warning::
:meth:`~pennylane.pauli.PauliSentence.hamiltonian` is deprecated. Instead, please use
:meth:`~pennylane.pauli.PauliSentence.operation`
"""
warn(
"PauliSentence.hamiltonian() is deprecated. Please use PauliSentence.operation() instead.",
qml.PennyLaneDeprecationWarning,
)

if len(self) == 0:
if wire_order in (None, [], Wires([])):
raise ValueError("Can't get the Hamiltonian for an empty PauliSentence.")
Expand Down
Loading

0 comments on commit 9f4e67e

Please sign in to comment.