Skip to content

Commit

Permalink
Deprecations for 0.32 from me! (#4316)
Browse files Browse the repository at this point in the history
* deprecate the old return system

* deprecate the mode kwarg for QNode

* changelog

* PR feedback

* update notice to avoid wrongly suggesting action needed

* update docstrings, docs and warnings

* add link to qnode returns doc

* change the mode warning depending on return system active

* also add disclaimer to docstring
  • Loading branch information
timmysilv committed Jul 10, 2023
1 parent e6b403f commit f4537a9
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 18 deletions.
12 changes: 12 additions & 0 deletions doc/development/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ Deprecations
Pending deprecations
--------------------

* ``qml.enable_return`` and ``qml.disable_return`` are deprecated. Please avoid calling
``disable_return``, as the old return system is deprecated along with these switch functions.

- Deprecated in v0.32
- Will be removed in v0.33

* The ``mode`` keyword argument in ``QNode`` is deprecated, as it was only used in the old return
system (which is also deprecated). Please use ``grad_on_execution`` instead.

- Deprecated in v0.32
- Will be removed in v0.33

* The ``observables`` argument in ``QubitDevice.statistics`` is deprecated. Please use ``circuit``
instead. Using a list of observables in ``QubitDevice.statistics`` is deprecated. Please use a
``QuantumTape`` instead.
Expand Down
2 changes: 0 additions & 2 deletions doc/introduction/interfaces/jax.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ PennyLane in combination with JAX, we have to generate JAX-compatible quantum no
types in QNodes;
* Multiple probability measurements need to have the same number of wires
specified;
* Computing the jacobian of vector-valued QNodes is not supported
in ``mode="forward"``.

However, when using ``diff_method="backprop"``, all QNode measurement statistics
are supported.
Expand Down
9 changes: 9 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@

* The CV observables ``qml.X`` and ``qml.P`` have been deprecated. Use ``qml.QuadX``
and ``qml.QuadP`` instead.
[(#4330)](https://github.com/PennyLaneAI/pennylane/pull/4330)

* `qml.enable_return` and `qml.disable_return` are deprecated. Please avoid calling
`disable_return`, as the old return system is deprecated along with these switch functions.
[(#4316)](https://github.com/PennyLaneAI/pennylane/pull/4316)

* The `mode` keyword argument in `QNode` is deprecated, as it was only used in the
old return system (which is also deprecated). Please use `grad_on_execution` instead.
[(#4316)](https://github.com/PennyLaneAI/pennylane/pull/4316)

<h3>Documentation 📝</h3>

Expand Down
2 changes: 1 addition & 1 deletion pennylane/devices/experimental/device_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Device(abc.ABC):
This interface is **experimental** and not yet integrated with the rest of PennyLane.
Device drivers should be configured to run under :func:`~.enable_return`, the newer
return shape specification.
return shape specification, as the old return shape specification is deprecated.
Only the ``execute`` method must be defined to construct a device driver.
Expand Down
2 changes: 0 additions & 2 deletions pennylane/gradients/hadamard_gradient.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ def _hadamard_grad(
This gradient transform can be applied directly to :class:`QNode <pennylane.QNode>` objects:
>>> qml.enable_return()
>>> dev = qml.device("default.qubit", wires=2)
>>> @qml.qnode(dev)
... def circuit(params):
Expand Down Expand Up @@ -146,7 +145,6 @@ def _hadamard_grad(
If you use custom wires on your device, you need to pass an auxiliary wire.
>>> qml.enable_return()
>>> dev_wires = ("a", "c")
>>> dev = qml.device("default.qubit", wires=dev_wires)
>>> @qml.qnode(dev, interface="jax", diff_method="hadamard", aux_wire="c", device_wires=dev_wires)
Expand Down
3 changes: 0 additions & 3 deletions pennylane/gradients/jvp.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,6 @@ def jvp(tape, tangent, gradient_fn, shots=None, gradient_kwargs=None):
import jax
qml.enable_return()
x = jax.numpy.array([[0.1, 0.2, 0.3],
[0.4, 0.5, 0.6]])
Expand Down Expand Up @@ -368,7 +366,6 @@ def batch_jvp(tapes, tangents, gradient_fn, shots=None, reduction="append", grad
.. code-block:: python
import jax
qml.enable_return()
x = jax.numpy.array([[0.1, 0.2, 0.3],
[0.4, 0.5, 0.6]])
Expand Down
8 changes: 3 additions & 5 deletions pennylane/gradients/parameter_shift.py
Original file line number Diff line number Diff line change
Expand Up @@ -1487,11 +1487,9 @@ def proc_with_validation(results):
res = fn(results)
except (ValueError, TypeError) as e:
raise e.__class__(
"The processing function of the gradient transform ran into errors "
"while the new return type system was turned on. Make sure to "
"pass the device shots to the param_shift gradient transform "
"using the shots argument or disable the new return type "
"system by calling the qml.disable_return function."
"The processing function of the gradient transform ran into errors. "
"Make sure to pass the device shots to the param_shift gradient transform "
"using the shots argument."
) from e
return res

Expand Down
22 changes: 19 additions & 3 deletions pennylane/qnode.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,12 @@ class QNode:
Only applies if the device is queried for the gradient; gradient transform
functions available in ``qml.gradients`` are only supported on the backward
pass. The 'best' option chooses automatically between the two options and is default.
mode (str): Whether the gradients should be computed on the forward
mode (str): Deprecated kwarg indicating whether the gradients should be computed on the forward
pass (``forward``) or the backward pass (``backward``). Only applies
if the device is queried for the gradient; gradient transform
functions available in ``qml.gradients`` are only supported on the backward
pass.
pass. This argument does nothing with the new return system, and users should
instead set ``grad_on_execution`` to indicate their desired behaviour.
cache (bool or dict or Cache): Whether to cache evaluations. This can result in
a significant reduction in quantum evaluations during gradient computations.
If ``True``, a cache with corresponding ``cachesize`` is created for each batch
Expand Down Expand Up @@ -386,7 +387,7 @@ def __init__(
expansion_strategy="gradient",
max_expansion=10,
grad_on_execution="best",
mode="best",
mode=None,
cache=True,
cachesize=10000,
max_diff=1,
Expand Down Expand Up @@ -427,6 +428,21 @@ def __init__(
f"gradient kwargs."
)

if mode is None:
mode = "best"
elif qml.active_return():
warnings.warn(
"The `mode` keyword argument is deprecated and does nothing with the new return system. "
"Please use `grad_on_execution` instead.",
UserWarning,
)
else:
warnings.warn(
"The `mode` keyword argument is deprecated, along with the old return system. In "
"the new return system, you should set the `grad_on_execution` boolean instead.",
UserWarning,
)

# input arguments
self.func = func
self.device = device
Expand Down
18 changes: 18 additions & 0 deletions pennylane/return_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
Class and functions for activating, deactivating and checking the new return types system
"""
# pylint: disable=global-statement
import warnings

__activated = True


Expand Down Expand Up @@ -615,6 +617,13 @@ def circuit_stack(a, b):
(tensor([ 0.0000, 0.0050, -0.0050, 0.0050, -0.0050]), tensor([ 0.0000, -0.4888, 0.4888, 0.0012, -0.0012])))
"""

warnings.warn(
"The old return system is deprecated, and will be removed along with "
"`qml.enable_return()` in v0.33. Please consult the QNode returns page for guidance on "
"switching to the new return system: https://docs.pennylane.ai/en/stable/introduction/returns.html",
UserWarning,
)

global __activated
__activated = True

Expand Down Expand Up @@ -646,6 +655,14 @@ def circuit(x):
tensor([0.5 , 0.5 , 0.08014815, 0.96939564, 0.03060436, 0.93879128], requires_grad=True)
"""

warnings.warn(
"The old return system is deprecated, and will be removed along with "
"`qml.disable_return()` in v0.33. Please consult the QNode returns page for guidance on "
"switching to the new return system: https://docs.pennylane.ai/en/stable/introduction/returns.html",
UserWarning,
)

global __activated
__activated = False # pragma: no cover

Expand Down Expand Up @@ -678,4 +695,5 @@ def active_return():
>>> active_return()
False
"""

return __activated
2 changes: 0 additions & 2 deletions pennylane/tape/qscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,6 @@ def shape(self, device):
.. code-block:: pycon
>>> qml.enable_return()
>>> dev = qml.device('default.qubit', wires=2)
>>> qs = QuantumScript(measurements=[qml.state()])
>>> qs.shape(dev)
Expand Down Expand Up @@ -1004,7 +1003,6 @@ def numeric_type(self):
.. code-block:: pycon
>>> qml.enable_return()
>>> dev = qml.device('default.qubit', wires=2)
>>> qs = QuantumScript(measurements=[qml.state()])
>>> qs.numeric_type
Expand Down
21 changes: 21 additions & 0 deletions tests/test_qnode.py
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,27 @@ def circuit(params):

assert len(record) == 0

def test_not_giving_mode_kwarg_does_not_raise_warning(self):
"""Test that not providing a value for mode does not raise a warning."""
with warnings.catch_warnings(record=True) as record:
_ = qml.QNode(lambda f: f, qml.device("default.qubit", wires=1))

assert len(record) == 0

def test_giving_mode_kwarg_raises_warning(self):
"""Test that providing a value for mode raises a warning."""
with pytest.warns(UserWarning, match="The `mode` keyword argument is deprecated"):
_ = qml.QNode(lambda f: f, qml.device("default.qubit", wires=1), mode="best")

def test_giving_mode_kwarg_raises_warning_old_return(self):
"""Test that providing a value for mode raises a custom warning with disable_return."""
qml.disable_return()
with pytest.warns(
UserWarning, match="In the new return system, you should set the `grad_on_execution`"
):
_ = qml.QNode(lambda f: f, qml.device("default.qubit", wires=1), mode="best")
qml.enable_return()


class TestTapeConstruction:
"""Tests for the tape construction"""
Expand Down
24 changes: 24 additions & 0 deletions tests/test_return_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"""
Unit tests for the new return types.
"""
import warnings

import numpy as np
import pytest

Expand Down Expand Up @@ -1274,3 +1276,25 @@ def test_custom_wire_labels_error(self):
msg = "Returning the mutual information is not supported when using custom wire labels"
with pytest.raises(qml.QuantumFunctionError, match=msg):
qml.execute(tapes=[tape], device=dev, gradient_fn=None)


class TestDeprecationWarnings:
"""Tests that all return-system functions raise deprecation warnings."""

def test_enable_return_raises_warning(self):
"""Test that enable_return() raises a warning."""
with pytest.warns(UserWarning, match="The old return system is deprecated"):
qml.enable_return()

def test_disable_return_raises_warning(self):
"""Test that disable_return() raises a warning."""
with pytest.warns(UserWarning, match="The old return system is deprecated"):
qml.disable_return()
qml.enable_return()

def test_active_return_does_not_raise_warning(self):
"""Test that active_return() does not raise a warning."""
with warnings.catch_warnings(record=True) as record:
qml.active_return()

assert len(record) == 0

0 comments on commit f4537a9

Please sign in to comment.