New features since last release
New and improved simulators
-
Added a new device,
default.qubit.tf
, a pure-state qubit simulator written using TensorFlow. As a result, it supports classical backpropagation as a means to compute the Jacobian. This can be faster than the parameter-shift rule for computing quantum gradients when the number of parameters to be optimized is large.default.qubit.tf
is designed to be used with end-to-end classical backpropagation (diff_method="backprop"
) with the TensorFlow interface. This is the default method of differentiation when creating a QNode with this device.Using this method, the created QNode is a 'white-box' that is tightly integrated with your TensorFlow computation, including AutoGraph support:
>>> dev = qml.device("default.qubit.tf", wires=1) >>> @tf.function ... @qml.qnode(dev, interface="tf", diff_method="backprop") ... def circuit(x): ... qml.RX(x[1], wires=0) ... qml.Rot(x[0], x[1], x[2], wires=0) ... return qml.expval(qml.PauliZ(0)) >>> weights = tf.Variable([0.2, 0.5, 0.1]) >>> with tf.GradientTape() as tape: ... res = circuit(weights) >>> print(tape.gradient(res, weights)) tf.Tensor([-2.2526717e-01 -1.0086454e+00 1.3877788e-17], shape=(3,), dtype=float32)
See the
default.qubit.tf
documentation for more details. -
The default.tensor plugin has been significantly upgraded. It now allows two different tensor network representations to be used:
"exact"
and"mps"
. The former uses a exact factorized representation of quantum states, while the latter uses a matrix product state representation. (#572) (#599)
New machine learning functionality and integrations
-
PennyLane QNodes can now be converted into Torch layers, allowing for creation of quantum and hybrid models using the
torch.nn
API. (#588)A PennyLane QNode can be converted into a
torch.nn
layer using theqml.qnn.TorchLayer
class:>>> @qml.qnode(dev) ... def qnode(inputs, weights_0, weight_1): ... # define the circuit ... # ... >>> weight_shapes = {"weights_0": 3, "weight_1": 1} >>> qlayer = qml.qnn.TorchLayer(qnode, weight_shapes)
A hybrid model can then be easily constructed:
>>> model = torch.nn.Sequential(qlayer, torch.nn.Linear(2, 2))
-
Added a new "reversible" differentiation method which can be used in simulators, but not hardware.
The reversible approach is similar to backpropagation, but trades off extra computation for enhanced memory efficiency. Where backpropagation caches the state tensors at each step during a simulated evolution, the reversible method only caches the final pre-measurement state.
Compared to the parameter-shift method, the reversible method can be faster or slower, depending on the density and location of parametrized gates in a circuit (circuits with higher density of parametrized gates near the end of the circuit will see a benefit). (#670)
>>> dev = qml.device("default.qubit", wires=2) ... @qml.qnode(dev, diff_method="reversible") ... def circuit(x): ... qml.RX(x, wires=0) ... qml.RX(x, wires=0) ... qml.CNOT(wires=[0,1]) ... return qml.expval(qml.PauliZ(0)) >>> qml.grad(circuit)(0.5) (array(-0.47942554),)
New templates and cost functions
-
Added the new templates
UCCSD
,SingleExcitationUnitary
, andDoubleExcitationUnitary
, which together implement the Unitary Coupled-Cluster Singles and Doubles (UCCSD) ansatz to perform VQE-based quantum chemistry simulations using PennyLane-QChem. (#622) (#638) (#654) (#659) (#622) -
Added module
pennylane.qnn.cost
with classSquaredErrorLoss
. The module contains classes to calculate losses and cost functions on circuits with trainable parameters. (#642)
Improvements
-
A significant improvement with respect to how QNodes and interfaces mark quantum function arguments as differentiable when using Autograd, designed to improve performance and make QNodes more intuitive. (#648) (#650)
In particular, the following changes have been made:
-
A new
ndarray
subclasspennylane.numpy.tensor
, which extends NumPy arrays with the keyword argument and attributerequires_grad
. Tensors which haverequires_grad=False
are treated as non-differentiable by the Autograd interface. -
A new subpackage
pennylane.numpy
, which wrapsautograd.numpy
such that NumPy functions accept therequires_grad
keyword argument, and allows Autograd to differentiatepennylane.numpy.tensor
objects. -
The
argnum
argument toqml.grad
is now optional; if not provided, arguments explicitly marked asrequires_grad=False
are excluded for the list of differentiable arguments. The ability to passargnum
has been retained for backwards compatibility, and if present the old behaviour persists.
-
-
The QNode Torch interface now inspects QNode positional arguments. If any argument does not have the attribute
requires_grad=True
, it is automatically excluded from quantum gradient computations. (#652) (#660) -
The QNode TF interface now inspects QNode positional arguments. If any argument is not being watched by a
tf.GradientTape()
, it is automatically excluded from quantum gradient computations. (#655) (#660) -
QNodes have two new public methods:
QNode.set_trainable_args()
andQNode.get_trainable_args()
. These are designed to be called by interfaces, to specify to the QNode which of its input arguments are differentiable. Arguments which are non-differentiable will not be converted to PennyLane Variable objects within the QNode. (#660) -
Added
decomposition
method to PauliX, PauliY, PauliZ, S, T, Hadamard, and PhaseShift gates, which decomposes each of these gates into rotation gates. (#668) -
The
CircuitGraph
class now supports serializing contained circuit operations and measurement basis rotations to an OpenQASM2.0 script via the newCircuitGraph.to_openqasm()
method. (#623)
Breaking changes
- Removes support for Python 3.5. (#639)
Documentation
- Various small typos were fixed.
Contributors
This release contains contributions from (in alphabetical order):
Thomas Bromley, Jack Ceroni, Alain Delgado Gran, Theodor Isacsson, Josh Izaac, Nathan Killoran, Maria Schuld, Antal Száva, Nicola Vitucci.