# Architectural overview¶

PennyLane is a framework for optimization and machine learning of quantum and hybrid quantum-classical computations. The library provides a unified architecture for near-term quantum computing devices, supporting various quantum information paradigms.

PennyLane’s core feature is the ability to compute gradients of variational quantum circuits in a way that is compatible with classical techniques such as backpropagation. PennyLane thus extends the automatic differentiation algorithms common in optimization and machine learning to include quantum and hybrid computations. A plugin system makes the framework compatible with any gate-based quantum simulator or hardware.

Using PennyLane, quantum computing *devices* can be used to
evaluate quantum nodes (*QNodes*) and to return statistics of the results. To
process the classical information obtained, *interfaces* allow using
accelerated machine learning libraries.

In most cases, computations with PennyLane are performed on a local machine using a simulator. Through using PennyLane plugins, one can, however, also utilize remote quantum devices and simulators.

## Components of PennyLane¶

### Devices¶

In PennyLane, the abstraction of a quantum computation device is encompassed
within the `Device`

class, making it one of the basic components of
the library. The `Device`

class provides a common API for accessing quantum
devices, independent of both the type of device (both simulators and hardware are supported),
as well as the quantum information model used.

In particular, the `Device`

class provides a common API for:

Initializing various device parameters such as the number of samples/shots,

Executing quantum circuits,

Retrieving measurement and state results (including samples, measurement statistics, and probabilities).

There are also device subclasses available, containing shared logic for
particular types of devices. For example, qubit-based devices can inherit from
the `QubitDevice`

class, easing development.

To register a new device with PennyLane, they must register an entry point under the pennylane.plugins
namespace using Setuptools. Once registered, the device can be instantiated using the `device()`

loader function.

A Python package that registers one or more PennyLane devices is known as a *plugin*. For more details
on plugins and devices, see Building a plugin.

The purpose of the `Device`

class can be summarized as:

Providing a common API to execute a quantum circuit and request the measurement of the associated observable.

Providing an easy way of developing a new device for PennyLane

### QNodes¶

A quantum node or QNode (represented by a subclass of
`BaseQNode`

) is an encapsulation of a function
\(f(x;\theta)=R^m\rightarrow R^n\) that is executed using quantum
information processing on a quantum device.

Users don’t typically instantiate QNodes directly—instead, the `qnode()`

decorator or
`QNode()`

constructor function automates the process of creating a QNode from a provided
quantum function and device. The constructor attempts to determine the `"best"`

differentiation method for the provided device and interface. For more fine-grained control,
the differentiation method can be specified directly via the `diff_method`

option.

### Tapes¶

Internally, QNodes store the details of the quantum processing using a datastructure called the
*tape*. Apart from encapsulating quantum processing, tapes also provide custom quantum
differentiation rules. Examples include the parameter-shift rule,
where the derivative of a tape can be expressed by a linear combination of other tapes plus
classical post-processing. As these rules allow quantum gradients to be obtained from tapes, hybrid
computations may include QNodes as part of training deep learning models.

A common representation of quantum circuits is a Directed Acyclic Graph (DAG) where quantum
operations are nodes within the graph. Each tape builds such a DAG using a `CircuitGraph`

instance.

For further details on tapes, and a full list of tapes with their custom differentiation rules, refer to the qml.tape module.

### Interfaces¶

The integration between classical and quantum computations is encompassed by
interfaces. QNodes that provide black-box gradient rules are ‘wrapped’ by an interface function.
These wrappers further transform
the `QNode`

such that the quantum gradient rules of the QNodes are registered
to the machine learning interface via a custom gradient class or function.

Typically, an interface integrates QNodes with external libraries as follows:

It wraps the QNode, returning a QNode that accepts and returns the core data structure of the classical machine learning library (e.g., a TensorFlow or PyTorch tensor, Autograd NumPy array, etc).

It unwraps the input data structures to simple NumPy arrays, so that the quantum device can execute the user’s quantum function.

It registers the

`QNode.jacobian()`

method as a custom gradient method, so that the machine learning library can ‘backpropagate’ across the QNode, when integrated into a classical computation.

We refer to the Gradients and training page for a more in-depth introduction and a list of available interfaces.

## Key design details¶

The following are key design details related to how PennyLane works internally.

### Operators¶

Quantum operators are incorporated by the `Operator`

class which
contains basic information about the operator (e.g. number of parameters,
number of wires it acts on, etc.) and further convenience methods (e.g.
`matrix`

, `eigvals`

).

Two important subclasses of the `Operator`

class are:

the

`Operation`

class representing quantum gates,the

`Observable`

representing quantum observables specified for measurement.

Together with `Operator`

, these classes serve as base classes for quantum
operators.

Certain operators can serve as both quantum gates and observables (e.g.
`PauliZ`

, `PauliX`

, etc.). Such classes inherit from both
`Operation`

and `Observable`

classes.

Quantum operators are used to build quantum functions
which are evaluated by a `QNode`

on a bound device. Users can define such quantum
functions by creating regular Python functions and instantiating `Operator`

instances in temporal order, one per line.

The following is an example of this using the `qnode()`

decorator and a
valid pre-defined device (`dev`

).

```
@qml.qnode(dev)
def circuit():
qml.PauliX(0)
return qml.expval(qml.PauliZ(0))
```

### Queuing of operators¶

In PennyLane, the construction of quantum gates is separated from the specific QNode that they belong to. QNode circuit construction happens only when the QNode is evaluated. On QNode evaluation, the quantum function is executed.

Operators are queued to the QNode on instantiation, by having `Operator.__init__()`

call the `Operator.queue()`

method. The operators themselves queue themselves to
the surrounding `QueuingContext`

.

Measurement functions such as `expval()`

are responsible for queuing observables.

For further details, refer to the description in `QueuingContext`

.

## Contents

## Downloads