Repository: PennyLaneAI/pennylane
Pull request #6032 (2024-07-23 20:27:25)

Deprecate the internal switching of a backpropagation device
**Context:**

The internal switching of one device for another backpropagation-compatible device was developed to allow the substitution of `default.qubit.legacy` with either `default.qubit.autograd`, `default.qubit.jax`, `default.qubit.torch`, or `default.qubit.tf`.  This logic has caused a lot of pain over the years, and all five of those devices are now deprecated.  In order to complete the removal of the 5 legacy devices, we need to also deprecate and remove the backprop device switching logic.

Otherwise, it would be very difficult and painful to test the switching of a backpropagation device.

**Description of the Change:**

Deprecates the switching of a device with a different device.  A warning is only raised when the device is not `default.qubit.legacy`, as default.qubit.legacy raises it's own deprecation warnings.

**Benefits:**

We can finally clean up QNode 🎉 💥 

**Possible Drawbacks:**

**Related GitHub Issues:**



Patch:
diff --git a/doc/development/deprecations.rst b/doc/development/deprecations.rst
index 7f469e133..2f05830d4 100644
--- a/doc/development/deprecations.rst
+++ b/doc/development/deprecations.rst
@@ -15,6 +15,12 @@ Pending deprecations
   - Deprecated in v0.38
   - Will be removed in v0.39
 
+* The logic for internally switching a device for a different backpropagation
+  compatible device is now deprecated, as it was in place for the deprecated `default.qubit.legacy`.
+
+  - Deprecated in v0.38
+  - Will be removed in v0.39  
+
 * The ``decomp_depth`` argument in ``qml.device`` is deprecated. 
 
   - Deprecated in v0.38
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index 6b99fcbe0..9c60329b8 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -123,7 +123,7 @@
   the circuit.
   [(#5907)](https://github.com/PennyLaneAI/pennylane/pull/5907)
 
-* `queue_idx` attribute has been removed from the `Operator`, `CompositeOp`, and `SymboliOp` classes.
+* `queue_idx` attribute has been removed from the `Operator`, `CompositeOp`, and `SymbolicOp` classes.
   [(#6005)](https://github.com/PennyLaneAI/pennylane/pull/6005)
 
 * `qml.from_qasm` no longer removes measurements from the QASM code. Use 
@@ -184,6 +184,11 @@
   Instead, use `default.qubit` as it now supports backpropagation through the several backends.
   [(#5997)](https://github.com/PennyLaneAI/pennylane/pull/5997)
 
+* The logic for internally switching a device for a different backpropagation
+  compatible device is now deprecated, as it was in place for the deprecated
+  `default.qubit.legacy`.
+  [(#6032)](https://github.com/PennyLaneAI/pennylane/pull/6032)
+
 <h3>Documentation 📝</h3>
 
 * Improves the docstring for `QuantumScript.expand` and `qml.tape.tape.expand_tape`.
diff --git a/pennylane/workflow/qnode.py b/pennylane/workflow/qnode.py
index 09c667bdd..71eb11a9f 100644
--- a/pennylane/workflow/qnode.py
+++ b/pennylane/workflow/qnode.py
@@ -878,6 +878,14 @@ class QNode:
                 if backprop_devices[mapped_interface] == device.short_name:
                     return "backprop", {}, device
 
+                if device.short_name != "default.qubit.legacy":
+                    warnings.warn(
+                        "The switching of devices for backpropagation is now deprecated in v0.38 and "
+                        "will be removed in v0.39, as this behavior was developed purely for the "
+                        "deprecated default.qubit.legacy.",
+                        qml.PennyLaneDeprecationWarning,
+                    )
+
                 # TODO: need a better way of passing existing device init options
                 # to a new device?
                 expand_fn = device.expand_fn


Test patch:
diff --git a/tests/test_qnode_legacy.py b/tests/test_qnode_legacy.py
index d8edc0890..7ea5c3315 100644
--- a/tests/test_qnode_legacy.py
+++ b/tests/test_qnode_legacy.py
@@ -36,6 +36,47 @@ def dummyfunc():
     return None
 
 
+def test_backprop_switching_deprecation():
+    """Test that a PennyLaneDeprecationWarning is raised when a device is subtituted
+    for a different backprop device.
+    """
+
+    class DummyDevice(qml.devices.LegacyDevice):
+        """A minimal device that substitutes for a backprop device."""
+
+        author = "some string"
+        name = "my legacy device"
+        short_name = "something"
+        version = 0.0
+
+        observables = {"PauliX", "PauliY", "PauliZ"}
+        operations = {"Rot", "RX", "RY", "RZ", "PauliX", "PauliY", "PauliZ", "CNOT"}
+        pennylane_requires = 0.38
+
+        _debugger = None
+
+        def capabilities(self):
+            return {"passthru_devices": {"autograd": "default.mixed"}}
+
+        def reset(self):
+            pass
+
+        # pylint: disable=unused-argument
+        def apply(self, operation, wires, par):
+            return 0.0
+
+        # pylint: disable=unused-argument
+        def expval(self, observable, wires, par):
+            return 0.0
+
+    with pytest.warns(qml.PennyLaneDeprecationWarning):
+
+        @qml.qnode(DummyDevice(shots=None), interface="autograd")
+        def _(x):
+            qml.RX(x, 0)
+            return qml.expval(qml.Z(0))
+
+
 # pylint: disable=too-many-public-methods
 class TestValidation:
     """Tests for QNode creation and validation"""