The latest release of PennyLane is now out and available for everyone to use. It comes with many new additions, including a fully differentiable Hartree-Fock 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 quantum-classical code to be optimized.
With this new release, we extend this philosophy to quantum chemistry, with the introduction of a fully differentiable Hartree-Fock 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 ground-state energies without increasing the size of the basis set.
For more details and examples, please refer to the differentiable Hartree-Fock 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 near-term quantum hardware provides an amazing playground for testing and prototyping hybrid quantum-classical algorithms. However, these near-term 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 zero-noise extrapolation method
now available through the
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
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
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
>>> 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
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
For example, consider the parameter-shift 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 2-qubit unitary decomposition
Arbitrary two-qubit 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
Insert gates and channels automatically into a quantum circuit
transform has now been added, providing a way to insert single-qubit 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
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 higher-order 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 (first-order 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
@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 spin-adapted spatial orbital rotation gate.
- A new template
qml.GateFabric, which implements a local, expressive, quantum-number-preserving 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
In addition to the new features listed above, the release contains a wide array of improvements and optimizations:
qml.metric_tensortransform 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.
qml.metric_tensortransform 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.attributesmodule — including properties useful for compilation, such as
self_inverses. These attributes can be extended dynamically, and are used by various PennyLane compilation transforms.
- The new
qml.fourier.qnode_spectrumfunction 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.
ApproxTimeEvolutiontemplate can now be used with Hamiltonians that have trainable coefficients.
- Templates are now top level imported and can be used directly; for example,
- Two new methods were added to the Device API,
device.batch_transform, allowing PennyLane devices increased control over circuit decompositions.
As new things are added, outdated features are removed. Here’s what will be disappearing in this release:
qml.invfunction has been removed,
qml.adjointshould be used instead.
- The operation
qml.Interferometerhas been renamed
qml.InterferometerUnitaryin order to distinguish it from the template
DoubleExcitationUnitaryhave been renamed to
- The operator attributes
is_symmetric_over_control_wireshave been removed as attributes from the base class. They have been replaced by the sets that store the names of operations with similar properties in
There are also a couple of important deprecations in the pipeline:
Allowing cost functions to be differentiated using
qml.jacobianwithout explicitly marking parameters as trainable is being deprecated, and will be removed in an upcoming release. Please specify the
requires_gradattribute for every argument, or specify
initmodule, 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’
shapemethod can be used to get the desired shape of the tensor, which can then be generated manually.
QNode.metric_tensormethods has been deprecated, and will be removed in an upcoming release. Please use the
padparameter of the
qml.AmplitudeEmbeddingtemplate has been removed. It has instead been renamed to the
default.tensordevice from the beta folder has not been maintained in years and is deprecated. It will be removed in future releases.
diag_approxis deprecated. Approximations can be controlled with the more fine-grained
approxkeyword argument, with
approx="block-diag"(the default) reproducing the old behaviour.
templatedecorator is now deprecated with a warning message and will be removed in release
v0.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.
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 Alonso-Linaje, Romain Moyard, Lee James O’Riordan, Carrie-Anne Rubidge, Maria Schuld, Rishabh Singh, Jay Soni, Ingrid Strandberg, Antal Száva, Teresa Tamayo-Mendoza, Rodrigo Vargas, Cody Wang, David Wierichs, Moritz Willmann.