qml.QNode¶
-
class
QNode
(func, device, interface='autograd', diff_method='best', mutable=True, max_expansion=10, **diff_options)[source]¶ Bases:
object
Represents a quantum node in the hybrid computational graph.
A quantum node contains a quantum function (corresponding to a variational circuit) and the computational device it is executed on.
The QNode calls the quantum function to construct a
QuantumTape
instance representing the quantum circuit.- Parameters
func (callable) – a quantum function
device (Device) – a PennyLane-compatible device
interface (str) –
The interface that will be used for classical backpropagation. This affects the types of objects that can be passed to/returned from the QNode:
interface='autograd'
: Allows autograd to backpropagate through the QNode. The QNode accepts default Python types (floats, ints, lists) as well as NumPy array arguments, and returns NumPy arrays.interface='torch'
: Allows PyTorch to backpropogate through the QNode. The QNode accepts and returns Torch tensors.interface='tf'
: Allows TensorFlow in eager mode to backpropogate through the QNode. The QNode accepts and returns TensorFlowtf.Variable
andtf.tensor
objects.None
: The QNode accepts default Python types (floats, ints, lists) as well as NumPy array arguments, and returns NumPy arrays. It does not connect to any machine learning library automatically for backpropagation.
diff_method (str, None) –
the method of differentiation to use in the created QNode
"best"
: Best available method. Uses classical backpropagation or the device directly to compute the gradient if supported, otherwise will use the analytic parameter-shift rule where possible with finite-difference as a fallback."device"
: Queries the device directly for the gradient. Only allowed on devices that provide their own gradient computation."backprop"
: Use classical backpropagation. Only allowed on simulator devices that are classically end-to-end differentiable, for exampledefault.tensor.tf
. Note that the returned QNode can only be used with the machine-learning framework supported by the device."reversible"
: Uses a reversible method for computing the gradient. This method is similar to"backprop"
, but trades off increased runtime with significantly lower memory usage. Compared to the parameter-shift rule, the reversible method can be faster or slower, depending on the density and location of parametrized gates in a circuit. Only allowed on (simulator) devices with the “reversible” capability, for exampledefault.qubit
."adjoint"
: Uses an adjoint method that reverses through the circuit after a forward pass by iteratively applying the inverse (adjoint) gate. This method is similar to the reversible method, but has a lower time overhead and a similar memory overhead. Only allowed on simulator devices such asdefault.qubit
."parameter-shift"
: Use the analytic parameter-shift rule for all supported quantum operation arguments, with finite-difference as a fallback."finite-diff"
: Uses numerical finite-differences for all quantum operation arguments.
mutable (bool) – If True, the underlying quantum circuit is re-constructed with every evaluation. This is the recommended approach, as it allows the underlying quantum structure to depend on (potentially trainable) QNode input arguments, however may add some overhead at evaluation time. If this is set to False, the quantum structure will only be constructed on the first evaluation of the QNode, and is stored and re-used for further quantum evaluations. Only set this to False if it is known that the underlying quantum structure is independent of QNode input.
max_expansion (int) – The number of times the internal circuit should be expanded when executed on a device. Expansion occurs when an operation or measurement is not supported, and results in a gate decomposition. If any operations in the decomposition remain unsupported by the device, another expansion occurs.
- Keyword Arguments
h=1e-7 (float) – step size for the finite difference method
order=1 (int) – The order of the finite difference method to use.
1
corresponds to forward finite differences,2
to centered finite differences.shift=pi/2 (float) – the size of the shift for two-term parameter-shift gradient computations
Example
>>> def circuit(x): ... qml.RX(x, wires=0) ... return expval(qml.PauliZ(0)) >>> dev = qml.device("default.qubit", wires=1) >>> qnode = qml.QNode(circuit, dev)
Attributes
-
INTERFACE_MAP
= {'autograd': <function QNode.to_autograd>, 'jax': <function QNode.to_jax>, 'tf': <function QNode.to_tf>, 'torch': <function QNode.to_torch>}¶
Methods
__call__
(*args, **kwargs)Call self as a function.
construct
(args, kwargs)Call the quantum function with a tape context, ensuring the operations get queued.
draw
([charset, wire_order, show_all_wires])Draw the quantum tape as a circuit diagram.
get_best_method
(device, interface)Returns the ‘best’ JacobianTape and differentiation method for a particular device and interface combination.
get_tape
(device, interface[, diff_method])Determine the best JacobianTape, differentiation method, interface, and device for a requested device, interface, and diff method.
metric_tensor
(*args[, diag_approx, …])Evaluate the value of the metric tensor.
Apply the Autograd interface to the internal quantum tape.
to_jax
()Apply the JAX interface to the internal quantum tape.
to_tf
([dtype])Apply the TensorFlow interface to the internal quantum tape.
to_torch
([dtype])Apply the Torch interface to the internal quantum tape.
-
construct
(args, kwargs)[source]¶ Call the quantum function with a tape context, ensuring the operations get queued.
-
draw
(charset='unicode', wire_order=None, show_all_wires=False)[source]¶ Draw the quantum tape as a circuit diagram.
- Parameters
charset (str, optional) – The charset that should be used. Currently, “unicode” and “ascii” are supported.
wire_order (Sequence[Any]) – The order (from top to bottom) to print the wires of the circuit. If not provided, this defaults to the wire order of the device.
show_all_wires (bool) – If True, all wires, including empty wires, are printed.
- Raises
ValueError – if the given charset is not supported
QuantumFunctionError – drawing is impossible because the underlying quantum tape has not yet been constructed
- Returns
the circuit representation of the tape
- Return type
str
Example
Consider the following circuit as an example:
@qml.qnode(dev) def circuit(a, w): qml.Hadamard(0) qml.CRX(a, wires=[0, 1]) qml.Rot(*w, wires=[1]) qml.CRX(-a, wires=[0, 1]) return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
We can draw the QNode after execution:
>>> result = circuit(2.3, [1.2, 3.2, 0.7]) >>> print(circuit.draw()) 0: ──H──╭C────────────────────────────╭C─────────╭┤ ⟨Z ⊗ Z⟩ 1: ─────╰RX(2.3)──Rot(1.2, 3.2, 0.7)──╰RX(-2.3)──╰┤ ⟨Z ⊗ Z⟩ >>> print(circuit.draw(charset="ascii")) 0: --H--+C----------------------------+C---------+| <Z @ Z> 1: -----+RX(2.3)--Rot(1.2, 3.2, 0.7)--+RX(-2.3)--+| <Z @ Z>
Circuit drawing works with devices with custom wire labels:
dev = qml.device('default.qubit', wires=["a", -1, "q2"]) @qml.qnode(dev) def circuit(): qml.Hadamard(wires=-1) qml.CNOT(wires=["a", "q2"]) qml.RX(0.2, wires="a") return qml.expval(qml.PauliX(wires="q2"))
When printed, the wire order matches the order defined on the device:
>>> print(circuit.draw()) a: ─────╭C──RX(0.2)──┤ -1: ──H──│────────────┤ q2: ─────╰X───────────┤ ⟨X⟩
We can use the
wire_order
argument to change the wire order:>>> print(circuit.draw(wire_order=["q2", "a", -1])) q2: ──╭X───────────┤ ⟨X⟩ a: ──╰C──RX(0.2)──┤ -1: ───H───────────┤
-
static
get_best_method
(device, interface)[source]¶ Returns the ‘best’ JacobianTape and differentiation method for a particular device and interface combination.
This method attempts to determine support for differentiation methods using the following order:
"backprop"
"device"
"parameter-shift"
"finite-diff"
The first differentiation method that is supported (going from top to bottom) will be returned.
- Parameters
device (Device) – PennyLane device
interface (str) – name of the requested interface
- Returns
Tuple containing the compatible JacobianTape, the interface to apply, the device to use, and the method argument to pass to the
JacobianTape.jacobian
method.- Return type
tuple[JacobianTape, str, Device, dict[str, str]]
-
static
get_tape
(device, interface, diff_method='best')[source]¶ Determine the best JacobianTape, differentiation method, interface, and device for a requested device, interface, and diff method.
- Parameters
device (Device) – PennyLane device
interface (str) – name of the requested interface
diff_method (str) – The requested method of differentiation. One of
"best"
,"backprop"
,"reversible"
,"adjoint"
,"device"
,"parameter-shift"
, or"finite-diff"
.
- Returns
Tuple containing the compatible JacobianTape, the interface to apply, the device to use, and the method argument to pass to the
JacobianTape.jacobian
method.- Return type
tuple[JacobianTape, str, Device, dict[str, str]]
-
metric_tensor
(*args, diag_approx=False, only_construct=False, **kwargs)[source]¶ Evaluate the value of the metric tensor.
- Parameters
args (tuple[Any]) – positional arguments
kwargs (dict[str, Any]) – auxiliary arguments
diag_approx (bool) – iff True, use the diagonal approximation
only_construct (bool) – Iff True, construct the circuits used for computing the metric tensor but do not execute them, and return the tapes.
- Returns
metric tensor
- Return type
array[float]
-
to_jax
()[source]¶ Apply the JAX interface to the internal quantum tape.
- Parameters
dtype (tf.dtype) – The dtype that the JAX QNode should output. If not provided, the default is
jnp.float64
.- Raises
QuantumFunctionError – if TensorFlow >= 2.1 is not installed
-
to_tf
(dtype=None)[source]¶ Apply the TensorFlow interface to the internal quantum tape.
- Parameters
dtype (tf.dtype) – The dtype that the TensorFlow QNode should output. If not provided, the default is
tf.float64
.- Raises
QuantumFunctionError – if TensorFlow >= 2.1 is not installed
-
to_torch
(dtype=None)[source]¶ Apply the Torch interface to the internal quantum tape.
- Parameters
dtype (tf.dtype) – The dtype that the Torch QNode should output. If not provided, the default is
torch.float64
.- Raises
QuantumFunctionError – if PyTorch >= 1.3 is not installed
Contents
Using PennyLane
Development
API
Downloads