Repository: PennyLaneAI/pennylane
Pull request #3526 (2022-12-13 15:55:23)

UserWarning if qnode gradient_kwargs are not standard
**Context:**
To set the differentiation method, a QNode takes the `diff_method` kwarg. There were several examples in the documentation using `gradient_fn` or `grad_method` instead, neither of which set the gradient method, so these examples (and the code of anyone who copied them) default unintentionally to back-propogation (updated in #3500).

**Description of the Change:**
This PR adds a warning informing users to use `diff_method` if they use either `grad_method` or `gradient_fn`. It also adds a list of supported gradient kwargs the `qnode` expects, and raises a different warning informing that the kwarg passed is not recognized if it does not match the list.

**Benefits:**
Users are warned about unexpected kwargs passed to `qnode`, but not prevented from implementing custom gradient functions with custom gradient_kwargs. Users who may be using code copy-pasted from incorrect examples receive a warning to update the kwarg to `diff_method`. 

**Possible Drawbacks:**
N/A.

**Related GitHub Issues:**
#3499

github-actions[bot]: Hello. You may have forgotten to update the changelog!
Please edit [`doc/releases/changelog-dev.md`](/PennyLaneAI/pennylane/blob/master/doc/releases/changelog-dev.md) with:
* A one-to-two sentence description of the change. You may include a small working example for new features.
* A link back to this PR.
* Your name (or GitHub username) in the contributors section.
codecov[bot]: # [Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3526?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) Report
> Merging [#3526](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3526?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (1a0cee6) into [master](https://codecov.io/gh/PennyLaneAI/pennylane/commit/7b2a4ab811bd4cd61973590129e4491d20591adf?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (7b2a4ab) will **decrease** coverage by `0.00%`.
> The diff coverage is `85.71%`.

```diff
@@            Coverage Diff             @@
##           master    #3526      +/-   ##
==========================================
- Coverage   99.87%   99.86%   -0.01%     
==========================================
  Files         311      311              
  Lines       27900    27905       +5     
==========================================
+ Hits        27864    27868       +4     
- Misses         36       37       +1     
```


| [Impacted Files](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3526?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) | Coverage Δ | |
|---|---|---|
| [pennylane/qnode.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3526/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3Fub2RlLnB5) | `99.59% <80.00%> (-0.41%)` | :arrow_down: |
| [pennylane/gradients/\_\_init\_\_.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3526/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2dyYWRpZW50cy9fX2luaXRfXy5weQ==) | `100.00% <100.00%> (ø)` | |
| [pennylane/gradients/gradient\_transform.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3526/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2dyYWRpZW50cy9ncmFkaWVudF90cmFuc2Zvcm0ucHk=) | `100.00% <100.00%> (ø)` | |
| [pennylane/ops/functions/generator.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3526/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL29wcy9mdW5jdGlvbnMvZ2VuZXJhdG9yLnB5) | `100.00% <0.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)


Patch:
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index 8b51fd70e..f70957925 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -113,7 +113,12 @@
 * Limit the `numpy` version to `<1.24`.
   [(#3563)](https://github.com/PennyLaneAI/pennylane/pull/3563)
 
-<h3>Breaking changes</h3>
+* Validation has been added on the `gradient_kwargs` when initializing a QNode, and if unexpected kwargs are passed, 
+  a `UserWarning` is raised. A list of the current expected gradient function kwargs has been added as 
+  `qml.gradients.SUPPORTED_GRADIENT_KWARGS`.
+  [(#3526)](https://github.com/PennyLaneAI/pennylane/pull/3526)
+
+ <h3>Breaking changes</h3>
 
 <h3>Deprecations</h3>
 
diff --git a/pennylane/gradients/__init__.py b/pennylane/gradients/__init__.py
index 910ead9f1..4e925fca1 100644
--- a/pennylane/gradients/__init__.py
+++ b/pennylane/gradients/__init__.py
@@ -318,7 +318,7 @@ from . import parameter_shift_hessian
 from . import finite_difference
 from . import spsa_gradient
 
-from .gradient_transform import gradient_transform
+from .gradient_transform import gradient_transform, SUPPORTED_GRADIENT_KWARGS
 from .hessian_transform import hessian_transform
 from .finite_difference import finite_diff, finite_diff_coeffs
 from .parameter_shift import param_shift
diff --git a/pennylane/gradients/gradient_transform.py b/pennylane/gradients/gradient_transform.py
index 60d48ff94..deb35d788 100644
--- a/pennylane/gradients/gradient_transform.py
+++ b/pennylane/gradients/gradient_transform.py
@@ -19,6 +19,29 @@ import warnings
 import pennylane as qml
 from pennylane.transforms.tape_expand import expand_invalid_trainable
 
+SUPPORTED_GRADIENT_KWARGS = [
+    "approx_order",
+    "argnum",
+    "broadcast",
+    "diagonal_shifts",
+    "f0",
+    "force_order2",
+    "gradient_recipes",
+    "gradient_kwargs",
+    "h",
+    "n",
+    "num",
+    "off_diagonal_shifts",
+    "order",
+    "reduction",
+    "sampler",
+    "sampler_seed",
+    "shifts",
+    "shots",
+    "strategy",
+    "validate_params",
+]
+
 
 def gradient_analysis(tape, use_graph=True, grad_fn=None):
     """Update the parameter information dictionary of the tape with
diff --git a/pennylane/qnode.py b/pennylane/qnode.py
index d8a04f021..54e683237 100644
--- a/pennylane/qnode.py
+++ b/pennylane/qnode.py
@@ -381,6 +381,19 @@ class QNode:
         else:
             self._qfunc_uses_shots_arg = False
 
+        for kwarg in gradient_kwargs:
+            if kwarg in ["gradient_fn", "grad_method"]:
+                warnings.warn(
+                    f"It appears you may be trying to set the method of differentiation via the kwarg "
+                    f"{kwarg}. This is not supported in qnode and will defualt to backpropogation. Use "
+                    f"diff_method instead."
+                )
+            elif kwarg not in qml.gradients.SUPPORTED_GRADIENT_KWARGS:
+                warnings.warn(
+                    f"Received gradient_kwarg {kwarg}, which is not included in the list of standard qnode "
+                    f"gradient kwargs."
+                )
+
         # input arguments
         self.func = func
         self.device = device


Test patch:
diff --git a/tests/test_qnode.py b/tests/test_qnode.py
index 8bb2396e7..3f8a7a213 100644
--- a/tests/test_qnode.py
+++ b/tests/test_qnode.py
@@ -492,6 +492,41 @@ class TestValidation:
 
         assert np.allclose(grad, 0)
 
+    def test_unrecognized_kwargs_raise_warning(self):
+        """Test that passing gradient_kwargs not included in qml.gradients.SUPPORTED_GRADIENT_KWARGS raises warning"""
+        dev = qml.device("default.qubit", wires=2)
+
+        with warnings.catch_warnings(record=True) as w:
+
+            @qml.qnode(dev, random_kwarg=qml.gradients.finite_diff)
+            def circuit(params):
+                qml.RX(params[0], wires=0)
+                return qml.expval(qml.PauliZ(0)), qml.var(qml.PauliZ(0))
+
+            assert len(w) == 1
+            assert "not included in the list of standard qnode gradient kwargs" in str(w[0].message)
+
+    def test_incorrect_diff_method_kwargs_raise_warning(self):
+        """Tests that using one of the incorrect kwargs previously used in some examples in PennyLane
+        (grad_method, gradient_fn) to set the qnode diff_method raises a warning"""
+        dev = qml.device("default.qubit", wires=2)
+
+        with warnings.catch_warnings(record=True) as w:
+
+            @qml.qnode(dev, grad_method=qml.gradients.finite_diff)
+            def circuit(params):
+                qml.RX(params[0], wires=0)
+                return qml.expval(qml.PauliZ(0)), qml.var(qml.PauliZ(0))
+
+            @qml.qnode(dev, gradient_fn=qml.gradients.finite_diff)
+            def circuit(params):
+                qml.RX(params[0], wires=0)
+                return qml.expval(qml.PauliZ(0)), qml.var(qml.PauliZ(0))
+
+        assert len(w) == 2
+        assert "Use diff_method instead" in str(w[0].message)
+        assert "Use diff_method instead" in str(w[1].message)
+
 
 class TestTapeConstruction:
     """Tests for the tape construction"""