The latest release of PennyLane is now out and available for everyone to use. It comes with many new additions, including a fully differentiable HartreeFock solver, error mitigation with Mitiq, powerful new transforms, improved support for batch execution, and much more.
Fully differentiable quantum chemistry workflows ⚛️
Part of what makes PennyLane so powerful is its focus on differentiable workflows, allowing every aspect of your hybrid quantumclassical code to be optimized.
With this new release, we extend this philosophy to quantum chemistry, with the introduction of a fully differentiable HartreeFock solver. Construct molecular Hamiltonians and perform variational quantum algorithms that can be differentiated and optimized with respect to molecular geometry, basis set, and circuit parameters simultaneously.
Train the molecule alongside your variational algorithm, or simply explore how optimizing the basis set parameters allows you to reach lower groundstate energies without increasing the size of the basis set.
For more details and examples, please refer to the differentiable HartreeFock solver documentation. You can also learn more about molecular geometry optimization with PennyLane from our latest paper and demonstration.
Error mitigation with Mitiq 📣
With near quantum, comes great noise.
The rapid availability of nearterm quantum hardware provides an amazing playground for testing and prototyping hybrid quantumclassical algorithms. However, these nearterm devices aren’t perfect — noise tends to creep in, affecting the ability of our algorithms to work as expected.
With this release, PennyLane now integrates with Mitiq, a
software toolkit from the Unitary Fund for mitigating errors on quantum
hardware. Transform your QNodes (and devices!) using the zeronoise extrapolation method
now available through the qml.transforms.mitigate_with_zne
transform:
from mitiq.zne.scaling import fold_global
from mitiq.zne.inference import RichardsonFactory
@qml.transforms.mitigate_with_zne([1, 2, 3], fold_global, RichardsonFactory.extrapolate)
@qml.beta.qnode(dev)
def circuit(w1, w2):
qml.SimplifiedTwoDesign(w1, w2, wires=range(2))
return qml.expval(qml.PauliZ(0))
For more details, check out the mitigate_with_zne
documentation.
Powerful new transforms 🤖
Our library of quantum transforms keeps growing. Manipulate, inspect, and transform QNodes to your heart’s content. All transforms provided by PennyLane are fully differentiable, and can even be trained themselves.
Add a batch dimension to QNodes with @qml.batch_params
Transform a QNode to support an initial batch dimension for operation parameters:
@qml.batch_params
@qml.beta.qnode(dev)
def circuit(weights):
qml.StronglyEntanglingLayers(weights, wires=[0, 1, 2])
return qml.expval(qml.Hadamard(0))
By applying the @qml.batch_params
decorator to the QNode, we
can now include a batch dimension for all QNode arguments when
executing the QNode. The evaluated QNode will have an output
of shape (batch_size,)
:
>>> batch_size = 3
>>> weights = np.random.random((batch_size, 10, 3, 3))
>>> circuit(x, weights)
tensor([0.30773348 0.23135516 0.13086565], requires_grad=True)
Extract numeric representations of circuits with qml.transforms.get_unitary_matrix
And even differentiate the returned matrix with respect to QNode arguments!
def circuit(theta):
qml.RX(theta, wires=1)
qml.PauliZ(wires=0)
qml.CNOT(wires=[0, 1])
def cost(theta):
matrix = get_unitary_matrix(circuit)(theta)
return np.real(np.trace(matrix))
>>> theta = np.array(0.3, requires_grad=True)
>>> cost(theta)
1.9775421558720845
>>> qml.grad(cost)(theta)
0.14943813247359922
Visualize batch transformed QNodes
It is now possible to draw QNodes that have been transformed by a ‘batch transform’; that is, a
transform that maps a single QNode into multiple circuits under the hood. Examples of batch
transforms include @qml.metric_tensor
and @qml.gradients
.
For example, consider the parametershift rule, which generates two circuits per parameter; one circuit that has the parameter shifted forward, and another that has the parameter shifted backwards:
dev = qml.device("default.qubit", wires=2)
@qml.gradients.param_shift
@qml.beta.qnode(dev)
def circuit(x):
qml.RX(x, wires=0)
qml.CNOT(wires=[0, 1])
return qml.expval(qml.PauliZ(wires=0))
>>> print(qml.draw(circuit)(0.6))
0: ──RX(2.17)──╭C──┤ ⟨Z⟩
1: ────────────╰X──┤
0: ──RX(0.971)──╭C──┤ ⟨Z⟩
1: ──────────────╰X──┤
Differentiable 2qubit unitary decomposition
Arbitrary twoqubit unitaries can now be decomposed into elementary gates. This functionality has
been incorporated into the qml.transforms.unitary_to_rot
transform, and is available separately
as qml.transforms.two_qubit_decomposition
.
Insert gates and channels automatically into a quantum circuit
The
qml.transforms.insert
transform has now been added, providing a way to insert singlequbit operations into a quantum
circuit, at various automatic positions. The transform can apply to quantum functions, tapes, and
devices. If applied to a device, any QNode executed on that device will automatically have
the specified operations inserted!
Test drive our new QNode 🚗
A new, experimental QNode has been added, that adds support for batch execution of circuits, custom
quantum gradient support, and arbitrary order derivatives. This QNode is available via
qml.beta.QNode
, and @qml.beta.qnode
.
It differs from the standard QNode in several ways:
Everything is batched
Internally, if multiple circuits are generated for execution simultaneously, they will be packaged into a single job for execution on the device. This can lead to significant performance improvement when executing the QNode on remote quantum hardware.
Arbitrary \(n\)th order derivatives on hardware
Compute arbitrary higherorder derivatives using any support gradient transform
— even on hardware. All gates and templates are supported. Note that to specify that an \(n\)th
order derivative of a QNode needs to be computed, the max_diff
argument should be set. By
default, this is set to 1 (firstorder derivatives only).
Better decomposition strategies
When decomposing the circuit, the default decomposition strategy will prioritize decompositions that result in the smallest number of parametrized operations required to satisfy the differentiation method. Additional decompositions required to satisfy the native gate set of the quantum device will be performed later, by the device at execution time. While this may lead to a slight increase in classical processing, it significantly reduces the number of circuit evaluations needed to compute gradients of complex unitaries.
Custom gradient transforms can be specified as the differentiation method
Take any of our provided gradient transforms in
qml.gradients
and bind it
to a QNode for backpropagation. Or even define your own custom gradient
transform!
@qml.gradients.gradient_transform
def my_gradient_transform(tape):
...
return tapes, processing_fn
@qml.beta.qnode(dev, diff_method=my_gradient_transform)
def circuit():
In an upcoming release, this QNode will replace the existing one. If you come across any bugs while using this QNode, please let us know via a bug report on our GitHub bug tracker.
New operations and templates
Alongside the great new features above, we also have a ton of new operations and templates to share. These include:
 A new operation
qml.OrbitalRotation
, which implements the spinadapted spatial orbital rotation gate.  A new template
qml.GateFabric
, which implements a local, expressive, quantumnumberpreserving ansatz proposed by Anselmetti et al. in arXiv:2104.05692  A new template
qml.kUpCCGSD
, which implements a unitary coupled cluster ansatz with generalized singles and pair doubles excitation operators, proposed by Joonho Lee et al. in arXiv:1810.02327
Improvements
In addition to the new features listed above, the release contains a wide array of improvements and optimizations:
 The
qml.metric_tensor
transform supports batching. Quantum circuits required to compute the metric tensor elements will be automatically submitted as a batched job. This can lead to significant performance improvements.
 The
qml.metric_tensor
transform now supports a larger set of operations, including all operations that have a single variational parameter and define a generator. In addition to a reduction in decomposition overhead, the change also results in fewer circuit evaluations.
 Operator properties and attributes are now collected in the
pennylane.ops.qubit.attributes
module — including properties useful for compilation, such asself_inverses
. These attributes can be extended dynamically, and are used by various PennyLane compilation transforms.
 The new
qml.fourier.qnode_spectrum
function allows the Fourier spectrum of QNodes to be computed with respect to QNode arguments, allowing for detailed characterization of variational algorithms.
 Quantum function transforms and batch transforms can now be applied to devices. Once applied to a device, any quantum function executed on the modified device will be transformed prior to execution.
 The
ApproxTimeEvolution
template can now be used with Hamiltonians that have trainable coefficients.
 Templates are now top level imported and can be used directly; for example,
qml.StronglyEntanglingWires(weights, wires)
.
 Two new methods were added to the Device API,
device.expand_fn
anddevice.batch_transform
, allowing PennyLane devices increased control over circuit decompositions.
Breaking changes
As new things are added, outdated features are removed. Here’s what will be disappearing in this release:
 The
qml.inv
function has been removed,qml.adjoint
should be used instead.
 The operation
qml.Interferometer
has been renamedqml.InterferometerUnitary
in order to distinguish it from the templateqml.templates.Interferometer
.
 Templates
SingleExcitationUnitary
andDoubleExcitationUnitary
have been renamed toFermionicSingleExcitation
andFermionicDoubleExcitation
, respectively.
 The operator attributes
has_unitary_generator
,is_composable_rotation
,is_self_inverse
,is_symmetric_over_all_wires
, andis_symmetric_over_control_wires
have been removed as attributes from the base class. They have been replaced by the sets that store the names of operations with similar properties inpennylane.ops.qubit.attributes
.
Deprecations
There are also a couple of important deprecations in the pipeline:

Allowing cost functions to be differentiated using
qml.grad
orqml.jacobian
without explicitly marking parameters as trainable is being deprecated, and will be removed in an upcoming release. Please specify therequires_grad
attribute for every argument, or specifyargnum
when usingqml.grad
orqml.jacobian
.
 The
init
module, which contains functions to generate random parameter tensors for templates, is flagged for deprecation and will be removed in the next release cycle. Instead, the templates’shape
method can be used to get the desired shape of the tensor, which can then be generated manually.
 The
QNode.draw
andQNode.metric_tensor
methods has been deprecated, and will be removed in an upcoming release. Please use theqml.draw
andqml.metric_tensor
transforms instead.
 The
pad
parameter of theqml.AmplitudeEmbedding
template has been removed. It has instead been renamed to thepad_with
parameter.
 The
default.tensor
device from the beta folder has not been maintained in years and is deprecated. It will be removed in future releases.
 The
qml.metric_tensor
andqml.QNGOptimizer
keyword argumentdiag_approx
is deprecated. Approximations can be controlled with the more finegrainedapprox
keyword argument, withapprox="blockdiag"
(the default) reproducing the old behaviour.
 The
template
decorator is now deprecated with a warning message and will be removed in releasev0.20.0
. It has been removed from different PennyLane functions.
These highlights are just scratching the surface — check out the full release notes for more details.
Contributors
As always, this release would not have been possible without the hard work of our development team and contributors:
Catalina Albornoz, Juan Miguel Arrazola, Utkarsh Azad, Akash Narayanan B, Sam Banning, Thomas Bromley, Jack Ceroni, Alain Delgado, Olivia Di Matteo, Andrew Gardhouse, Anthony Hayes, Theodor Isacsson, David Ittah, Josh Izaac, Soran Jahangiri, Nathan Killoran, Christina Lee, Guillermo AlonsoLinaje, Romain Moyard, Lee James O’Riordan, CarrieAnne Rubidge, Maria Schuld, Rishabh Singh, Jay Soni, Ingrid Strandberg, Antal Száva, Teresa TamayoMendoza, Rodrigo Vargas, Cody Wang, David Wierichs, Moritz Willmann.