From d90d5399f14bc28bde7c184a57264e57fb905578 Mon Sep 17 00:00:00 2001 From: Andrija Paurevic <46359773+andrijapau@users.noreply.github.com> Date: Wed, 15 Jan 2025 17:21:26 -0500 Subject: [PATCH] Remove `qtape`/`tape` property from `QNode` (#6825) Completing the deprecation cycle. No idea why those tests didn't complain in CI before when it was first deprecated ... weird! [sc-82149] --- doc/development/deprecations.rst | 12 +++--- doc/releases/changelog-dev.md | 5 +++ pennylane/workflow/qnode.py | 21 +--------- tests/devices/test_default_clifford.py | 4 +- tests/ops/functions/test_map_wires.py | 4 +- tests/test_qnode.py | 56 -------------------------- tests/test_qnode_legacy.py | 15 ------- 7 files changed, 16 insertions(+), 101 deletions(-) diff --git a/doc/development/deprecations.rst b/doc/development/deprecations.rst index 76d278d0b40..44cfc9150c7 100644 --- a/doc/development/deprecations.rst +++ b/doc/development/deprecations.rst @@ -9,12 +9,6 @@ deprecations are listed below. Pending deprecations -------------------- -* The ``tape`` and ``qtape`` properties of ``QNode`` have been deprecated. - Instead, use the ``qml.workflow.construct_tape`` function. - - - Deprecated in v0.40 - - Will be removed in v0.41 - * The ``max_expansion`` argument in :func:`~pennylane.devices.preprocess.decompose` is deprecated. - Deprecated in v0.40 @@ -68,6 +62,12 @@ for details on how to port your legacy code to the new system. The following fun Completed deprecation cycles ---------------------------- +* The ``tape`` and ``qtape`` properties of ``QNode`` have been removed. + Instead, use the ``qml.workflow.construct_tape`` function. + + - Deprecated in v0.40 + - Removed in v0.41 + * The ``gradient_fn`` keyword argument to ``qml.execute`` has been removed. Instead, it has been replaced with ``diff_method``. - Deprecated in v0.40 diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index 878599ca4ca..4399efce503 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -17,6 +17,10 @@

Breaking changes 💔

+* The ``tape`` and ``qtape`` properties of ``QNode`` have been removed. + Instead, use the ``qml.workflow.construct_tape`` function. + [(#6825)](https://github.com/PennyLaneAI/pennylane/pull/6825) + * The ``gradient_fn`` keyword argument to ``qml.execute`` has been removed. Instead, it has been replaced with ``diff_method``. [(#6830)](https://github.com/PennyLaneAI/pennylane/pull/6830) @@ -46,3 +50,4 @@ This release contains contributions from (in alphabetical order): Yushao Chen, Diksha Dhawan, Christina Lee, +Andrija Paurevic diff --git a/pennylane/workflow/qnode.py b/pennylane/workflow/qnode.py index 9d83024834a..93a9d40874d 100644 --- a/pennylane/workflow/qnode.py +++ b/pennylane/workflow/qnode.py @@ -29,7 +29,7 @@ from pennylane.logging import debug_logger from pennylane.math import Interface, SupportedInterfaceUserInput, get_canonical_interface_name from pennylane.measurements import MidMeasureMP -from pennylane.tape import QuantumScript, QuantumTape +from pennylane.tape import QuantumScript from pennylane.transforms.core import TransformContainer, TransformDispatcher, TransformProgram from ._capture_qnode import capture_qnode @@ -695,25 +695,6 @@ def get_gradient_fn( f"options are {tuple(get_args(SupportedDiffMethods))}." ) - @property - def tape(self) -> QuantumTape: - """The quantum tape - - .. warning:: - - This property is deprecated in v0.40 and will be removed in v0.41. - Instead, use the :func:`qml.workflow.construct_tape <.workflow.construct_tape>` function. - """ - - warnings.warn( - "The tape/qtape property is deprecated and will be removed in v0.41. " - "Instead, use the qml.workflow.construct_tape function.", - qml.PennyLaneDeprecationWarning, - ) - return self._tape - - qtape = tape # for backwards compatibility - @debug_logger def construct(self, args, kwargs) -> qml.tape.QuantumScript: """Call the quantum function with a tape context, ensuring the operations get queued.""" diff --git a/tests/devices/test_default_clifford.py b/tests/devices/test_default_clifford.py index ad420ee8120..9a26846a261 100644 --- a/tests/devices/test_default_clifford.py +++ b/tests/devices/test_default_clifford.py @@ -599,9 +599,9 @@ def circuit_fn(): return qml.expval(qml.PauliZ(0)) qnode_clfrd = qml.QNode(circuit_fn, dev_c) - qnode_clfrd() + tape = qml.workflow.construct_tape(qnode_clfrd)() - conf_c, tape_c = dev_c.setup_execution_config(), qnode_clfrd.tape + conf_c, tape_c = dev_c.setup_execution_config(), tape with pytest.raises( NotImplementedError, diff --git a/tests/ops/functions/test_map_wires.py b/tests/ops/functions/test_map_wires.py index 8f6abe2f02b..aee65a01920 100644 --- a/tests/ops/functions/test_map_wires.py +++ b/tests/ops/functions/test_map_wires.py @@ -198,8 +198,8 @@ def qfunc(): assert isinstance(m_ops[1], Prod) qml.assert_equal(m_ops[0], mapped_op) qml.assert_equal(m_ops[1], mapped_op_2) - assert m_qnode.tape.observables[0].wires == Wires(wire_map[0]) - assert m_qnode.tape.observables[1].wires == Wires(wire_map[1]) + assert m_tape.observables[0].wires == Wires(wire_map[0]) + assert m_tape.observables[1].wires == Wires(wire_map[1]) @pytest.mark.jax def test_jitting_simplified_qfunc(self): diff --git a/tests/test_qnode.py b/tests/test_qnode.py index e5a92989e7d..9529df3f6f0 100644 --- a/tests/test_qnode.py +++ b/tests/test_qnode.py @@ -31,21 +31,6 @@ from pennylane.typing import PostprocessingFn -def test_tape_property_is_deprecated(): - """Test that the tape property is deprecated.""" - dev = qml.device("default.qubit") - - @qml.qnode(dev) - def circuit(x): - qml.RX(x, wires=0) - return qml.PauliY(0) - - with pytest.warns( - qml.PennyLaneDeprecationWarning, match="The tape/qtape property is deprecated" - ): - _ = circuit.tape - - def dummyfunc(): """dummy func.""" return None @@ -482,47 +467,6 @@ def circuit(): class TestTapeConstruction: """Tests for the tape construction""" - def test_basic_tape_construction(self, tol): - """Test that a quantum tape is properly constructed""" - dev = qml.device("default.qubit", wires=2) - - def func(x, y): - qml.RX(x, wires=0) - qml.RY(y, wires=1) - qml.CNOT(wires=[0, 1]) - return qml.expval(qml.PauliZ(0)) - - qn = QNode(func, dev) - - x = pnp.array(0.12, requires_grad=True) - y = pnp.array(0.54, requires_grad=True) - - res = qn(x, y) - with pytest.warns( - qml.PennyLaneDeprecationWarning, match="tape/qtape property is deprecated" - ): - tape = qn.tape - - assert isinstance(tape, QuantumScript) - assert len(tape.operations) == 3 - assert len(tape.observables) == 1 - assert tape.num_params == 2 - assert tape.shots.total_shots is None - - expected = qml.execute([tape], dev, None) - assert np.allclose(res, expected, atol=tol, rtol=0) - - # when called, a new quantum tape is constructed - old_tape = tape - res2 = qn(x, y) - with pytest.warns( - qml.PennyLaneDeprecationWarning, match="tape/qtape property is deprecated" - ): - new_tape = qn.tape - - assert np.allclose(res, res2, atol=tol, rtol=0) - assert new_tape is not old_tape - def test_returning_non_measurements(self): """Test that an exception is raised if a non-measurement is returned from the QNode.""" diff --git a/tests/test_qnode_legacy.py b/tests/test_qnode_legacy.py index 0bcb4bf1134..26c46687934 100644 --- a/tests/test_qnode_legacy.py +++ b/tests/test_qnode_legacy.py @@ -32,21 +32,6 @@ from pennylane.typing import PostprocessingFn -def test_legacy_qtape_property_is_deprecated(): - """Test that the legacy qtape property is deprecated.""" - dev = qml.device("default.qubit") - - @qml.qnode(dev) - def circuit(x): - qml.RX(x, wires=0) - return qml.PauliY(0) - - with pytest.warns( - qml.PennyLaneDeprecationWarning, match="The tape/qtape property is deprecated" - ): - _ = circuit.qtape - - def dummyfunc(): """dummy func.""" return None