From deaf3870e7ab4bf6c76147f94f36c30eeb9cfa5e Mon Sep 17 00:00:00 2001 From: Christina Lee Date: Thu, 9 Nov 2023 15:19:44 -0500 Subject: [PATCH] Fix gradient transforms with default qubit and overridden shot vectors (#4795) [sc-44395] With this change, we can now do: ``` dev = qml.device("default.qubit") @qml.qnode(dev) def circuit(x): qml.RX(x, wires=0) return qml.expval(qml.PauliZ(0)) x = qml.numpy.array(0.543, requires_grad=True) qml.gradients.param_shift(circuit)(x, shots=(10000, 10000, 1000) ) ``` ``` (array(-0.5209), array(-0.5258), array(-0.522)) ``` --------- Co-authored-by: Matthew Silverman --- doc/releases/changelog-dev.md | 3 +++ pennylane/qnode.py | 2 ++ tests/gradients/core/test_gradient_transform.py | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index e7cd3acc385..90af0bf7c6b 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -69,6 +69,9 @@

Bug fixes 🐛

+* Gradient transforms now work with overridden shot vectors and default qubit. + [(#4795)](https://github.com/PennyLaneAI/pennylane/pull/4795) + * `qml.defer_measurements` now correctly transforms circuits when terminal measurements include wires used in mid-circuit measurements. [(#4787)](https://github.com/PennyLaneAI/pennylane/pull/4787) diff --git a/pennylane/qnode.py b/pennylane/qnode.py index f20556166a2..0a4ac258455 100644 --- a/pennylane/qnode.py +++ b/pennylane/qnode.py @@ -15,6 +15,7 @@ This module contains the QNode class and qnode decorator. """ # pylint: disable=too-many-instance-attributes,too-many-arguments,protected-access,unnecessary-lambda-assignment, too-many-branches, too-many-statements +import copy import functools import inspect import warnings @@ -842,6 +843,7 @@ def tape(self) -> QuantumTape: def construct(self, args, kwargs): # pylint: disable=too-many-branches """Call the quantum function with a tape context, ensuring the operations get queued.""" + kwargs = copy.copy(kwargs) old_interface = self.interface if self._qfunc_uses_shots_arg: diff --git a/tests/gradients/core/test_gradient_transform.py b/tests/gradients/core/test_gradient_transform.py index 596c0060e6f..4eb735fad74 100644 --- a/tests/gradients/core/test_gradient_transform.py +++ b/tests/gradients/core/test_gradient_transform.py @@ -605,7 +605,7 @@ def test_setting_shots(self): """Test that setting the number of shots works correctly for a gradient transform""" - dev = qml.device("default.qubit.legacy", wires=1, shots=1000) + dev = qml.device("default.qubit", wires=1, shots=1000) @qml.qnode(dev) def circuit(x): @@ -617,7 +617,7 @@ def circuit(x): # the gradient function can be called with different shot values grad_fn = qml.gradients.param_shift(circuit) assert grad_fn(x).shape == () - assert grad_fn(x, shots=[(1, 1000)]).shape == (1000,) + assert len(grad_fn(x, shots=[(1, 1000)])) == 1000 # the original QNode is unaffected assert circuit(x).shape == tuple()