QNode returns¶
Version 0.30.0 of PennyLane updated the return type of a QNode
. This page
provides additional details about the update and can be used to troubleshoot issues.
Note
If you are looking for a quick fix, jump to the Troubleshooting section!
After visiting the Troubleshooting section, if you are still stuck then you can:
Post on the PennyLane discussion forum.
If you suspect that your issue is due to a bug in PennyLane itself, please open a bug report on the PennyLane GitHub page.
Summary of the update¶

PennyLane QNodes now return exactly what you tell them to! 🎉
Consider the following circuit:
import pennylane as qml
dev = qml.device("default.qubit", wires=1)
@qml.qnode(dev)
def circuit(x):
qml.RX(x, wires=0)
return qml.expval(qml.PauliZ(0)), qml.probs(0)
In version 0.29 and earlier of PennyLane, circuit()
would return a single length-3 array:
>>> circuit(0.5)
tensor([0.87758256, 0.93879128, 0.06120872], requires_grad=True)
In versions 0.30 and above, circuit()
returns a length-2 tuple containing the expectation value
and probabilities separately:
>>> circuit(0.5)
(tensor(0.87758256, requires_grad=True),
tensor([0.93879128, 0.06120872], requires_grad=True))
For a detailed explanation of this change, along with code examples, check out the
enable_return()
function documentation.
Motivation¶
PennyLane has historically adopted the approach of combining the returned measurements of a QNode into a single array. However, this has presented some challenges:
The return of a QNode could be different from what is expected, as shown in the example above.
For measurements of different shapes, ragged arrays were generated internally and then squeezed into a single output array. This is incompatible with NumPy’s NEP 34 and constrains the version of NumPy that PennyLane is compatible with.
Use of stacking and squeezing presents performance bottlenecks.
The changes made in version 0.30 of PennyLane address the challenges above. However, existing users may experience breaking changes or issues when upgrading their PennyLane version.
Troubleshooting¶
You may experience issues with PennyLane’s updated QNode return system in version 0.30 and above if you have existing code that works with an earlier version of PennyLane. To help identify a fix, select the option below that describes your situation.
I am using a QNode that returns more than one quantity
Your issue may be because:
You are calculating the Jacobian of the QNode using the NumPy or TensorFlow interface. For example, the following will now raise an error:
from pennylane import numpy as np dev = qml.device("default.qubit", wires=1) @qml.qnode(dev) def circuit(x): qml.RX(x, wires=0) return qml.expval(qml.PauliY(0)), qml.expval(qml.PauliZ(0)) x = np.array(0.5, requires_grad=True) qml.jacobian(circuit)(x)
Follow the instructions here to fix this issue, which arises because NumPy and TensorFlow do not support differentiating tuples. Alternatively, consider porting your code to use the JAX or Torch interface, which could unlock additional features and performance benefits!
You are returning differently-shaped quantities together, such as
expval()
andprobs()
. For example, the following code is compatible with version 0.29 of PennyLane but will raise an error in version 0.30 and above:dev = qml.device("default.qubit", wires=1) @qml.qnode(dev) def circuit(x): qml.RX(x, wires=0) return qml.expval(qml.PauliZ(0)), qml.probs(0) def result(x): expval, p0, p1 = circuit(x) return expval + p0 - p1 x = np.array(0.5, requires_grad=True) result(x)
Such issues can be addressed by updating how the return of a QNode is processed, being aware of unpacking, slicing, and indexing. The example above would be fixed simply by updating
result()
to:def result(x): expval, (p0, p1) = circuit(x) return expval + p0 - p1
I am a device developer
If you are a device developer, your issue may be because:
Your device inherits from
QubitDevice
and you have overriden or interact with theexecute()
,batch_execute()
, orstatistics()
methods. Your device will need to be updated to accommodate for the new return behaviour. An example can be found here for the Qiskit plugin.Your device inherits directly from
Device
, in which case you may need to rewrite theexecute()
andbatch_execute()
methods.
In either case, please reach out to us for guidance!
I am unsure what to do
Please carefully read through the options above. If you are still stuck, you can:
Post on the PennyLane discussion forum. Please include a complete block of code demonstrating your issue so that we can quickly troubleshoot.
If you suspect that your issue is due to a bug in PennyLane itself, please open a bug report on the PennyLane GitHub page.
As a last resort, you can place
qml.disable_return()
at the top of your code. This will revert PennyLane’s behaviour to the QNode return type in version 0.29. However, be aware that this capability will be removed in a future version of PennyLane!