diff --git a/doc/development/deprecations.rst b/doc/development/deprecations.rst
index c7870a13559..3763b42bec8 100644
--- a/doc/development/deprecations.rst
+++ b/doc/development/deprecations.rst
@@ -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.
diff --git a/doc/introduction/interfaces/jax.rst b/doc/introduction/interfaces/jax.rst
index aa03117a0c3..e7084383845 100644
--- a/doc/introduction/interfaces/jax.rst
+++ b/doc/introduction/interfaces/jax.rst
@@ -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.
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index db0f90fce25..24c3bdb1032 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -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)
Documentation 📝
diff --git a/pennylane/devices/experimental/device_api.py b/pennylane/devices/experimental/device_api.py
index 4676eea248f..cbcfbcbe882 100644
--- a/pennylane/devices/experimental/device_api.py
+++ b/pennylane/devices/experimental/device_api.py
@@ -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.
diff --git a/pennylane/gradients/hadamard_gradient.py b/pennylane/gradients/hadamard_gradient.py
index fb59c3c9c42..bad143fbfc1 100644
--- a/pennylane/gradients/hadamard_gradient.py
+++ b/pennylane/gradients/hadamard_gradient.py
@@ -92,7 +92,6 @@ def _hadamard_grad(
This gradient transform can be applied directly to :class:`QNode ` objects:
- >>> qml.enable_return()
>>> dev = qml.device("default.qubit", wires=2)
>>> @qml.qnode(dev)
... def circuit(params):
@@ -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)
diff --git a/pennylane/gradients/jvp.py b/pennylane/gradients/jvp.py
index e15ea5584a4..35811b40ef2 100644
--- a/pennylane/gradients/jvp.py
+++ b/pennylane/gradients/jvp.py
@@ -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]])
@@ -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]])
diff --git a/pennylane/gradients/parameter_shift.py b/pennylane/gradients/parameter_shift.py
index 05eee293ec3..17cfa09166f 100644
--- a/pennylane/gradients/parameter_shift.py
+++ b/pennylane/gradients/parameter_shift.py
@@ -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
diff --git a/pennylane/qnode.py b/pennylane/qnode.py
index a9623a7005c..d5bc695ae56 100644
--- a/pennylane/qnode.py
+++ b/pennylane/qnode.py
@@ -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
@@ -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,
@@ -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
diff --git a/pennylane/return_types.py b/pennylane/return_types.py
index 9a6d5f79a7d..0998a5e0695 100644
--- a/pennylane/return_types.py
+++ b/pennylane/return_types.py
@@ -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
@@ -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
@@ -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
@@ -678,4 +695,5 @@ def active_return():
>>> active_return()
False
"""
+
return __activated
diff --git a/pennylane/tape/qscript.py b/pennylane/tape/qscript.py
index 6c943f51411..5bdea78390c 100644
--- a/pennylane/tape/qscript.py
+++ b/pennylane/tape/qscript.py
@@ -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)
@@ -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
diff --git a/tests/test_qnode.py b/tests/test_qnode.py
index 66b6c6250f4..9ab072e246b 100644
--- a/tests/test_qnode.py
+++ b/tests/test_qnode.py
@@ -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"""
diff --git a/tests/test_return_types.py b/tests/test_return_types.py
index 733ff8e6119..14897361519 100644
--- a/tests/test_return_types.py
+++ b/tests/test_return_types.py
@@ -14,6 +14,8 @@
"""
Unit tests for the new return types.
"""
+import warnings
+
import numpy as np
import pytest
@@ -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