qml.device¶
- device(name, *args, **kwargs)[source]¶
Load a device and return the instance.
This function is used to load a particular quantum device, which can then be used to construct QNodes.
PennyLane comes with support for the following devices:
'default.qubit': a simple state simulator of qubit-based quantum circuit architectures.'default.mixed': a mixed-state simulator of qubit-based quantum circuit architectures.'lightning.qubit': a more performant state simulator of qubit-based quantum circuit architectures written in C++.'default.qutrit': a simple state simulator of qutrit-based quantum circuit architectures.'default.qutrit.mixed': a mixed-state simulator of qutrit-based quantum circuit architectures.'default.gaussian': a simple simulator of Gaussian states and operations on continuous-variable circuit architectures.'default.clifford': an efficient simulator of Clifford circuits.'default.tensor': a simulator of quantum circuits based on tensor networks.'null.qubit': a simulator that performs no operations associated with numerical computations.
Additional devices are supported through plugins — see the available plugins for more details. To list all currently installed devices, run
qml.about.- Parameters:
name (str) – the name of the device to load
wires (Wires) – the wires (subsystems) to initialize the device with. Note that this is optional for certain devices, such as
default.qubit
- Keyword Arguments:
config (pennylane.Configuration) – a PennyLane configuration object that contains global and/or device specific configurations.
custom_decomps (Dict[Union(str, Operator), Callable]) – Custom decompositions to be applied by the device at runtime.
Warning
The
custom_decompskeyword argument toqml.devicehas been deprecated and will be removed in 0.45. Instead, withqml.decomposition.enable_graph(), new decomposition rules can be defined as quantum functions with registered resources. Seepennylane.decompositionfor more details.All devices must be loaded by specifying their short-name as listed above, followed by the wires (subsystems) you wish to initialize. The
wiresargument can be an integer, in which case the wires of the device are addressed by consecutive integers:dev = qml.device('default.qubit', wires=5) def circuit(): qml.Hadamard(wires=1) qml.Hadamard(wires=[0]) qml.CNOT(wires=[3, 4]) ...
The
wiresargument can also be a sequence of unique numbers or strings, specifying custom wire labels that the user employs to address the wires:dev = qml.device('default.qubit', wires=['auxiliary', 'q11', 'q12', -1, 1]) def circuit(): qml.Hadamard(wires='q11') qml.Hadamard(wires=['auxiliary']) qml.CNOT(wires=['q12', -1]) ...
On some newer devices, such as
default.qubit, thewiresargument can be omitted altogether, and instead the wires will be computed when executing a circuit depending on its contents.>>> dev = qml.device("default.qubit")
When executing quantum circuits on a device, we can specify the number of times the circuit must be executed to estimate stochastic return values by using the
set_shots()transform. As an example,qml.sample()measurements will return as many samples as the number of shots specified. Note thatshotscan be a single integer or a list of shot values.dev = qml.device('default.qubit', wires=1) @qml.set_shots(10) @qml.qnode(dev) def circuit(a): qml.RX(a, wires=0) return qml.sample(qml.Z(0))
>>> circuit(0.8) # 10 samples are returned array([ 1, 1, 1, 1, -1, 1, 1, -1, 1, 1]) >>> new_circuit = qml.set_shots(circuit, shots=[3, 4, 4]) >>> new_circuit(0.8) # 3, 4, and 4 samples are returned respectively (array([1., 1., 1.]), array([ 1., 1., 1., -1.]), array([ 1., 1., -1., 1.]))
Custom Decompositions
Warning
The keyword argument for defining custom quantum gate decompositions,
custom_decomps, has been deprecated and will be removed in v0.45. Instead, to specify custom decompositions for your operators, use theqml.transforms.decomposetransform with the new graph-based system enabled viaqml.decomposition.enable_graph(). See the documentation on Customizing Decompositions indecompose()for more details on how to define and register decomposition rules.For enabling support of gates on devices where they would normally be unsupported, see the details about operator decomposition under the Preprocessing section in Building a plugin.
When constructing a device, we may optionally pass a dictionary of custom decompositions to be applied to certain operations upon device execution. This is useful for enabling support of gates on devices where they would normally be unsupported.
For example, suppose we are running on an ion trap device that does not natively implement the CNOT gate, but we would still like to write our circuits in terms of CNOTs. On an ion trap device, CNOT can be implemented using the
IsingXXgate. We first define a decomposition function (such functions have the signaturedecomposition(*params, wires)):def ion_trap_cnot(wires, **_): return [ qml.RY(np.pi/2, wires=wires[0]), qml.IsingXX(np.pi/2, wires=wires), qml.RX(-np.pi/2, wires=wires[0]), qml.RY(-np.pi/2, wires=wires[0]), qml.RY(-np.pi/2, wires=wires[1]) ]
Next, we create a device and a QNode for testing. When constructing the QNode, we can set the expansion strategy to
"device"to ensure the decomposition is applied and will be viewable when we draw the circuit. Note that custom decompositions should accept keyword arguments even when it is not used.# As the CNOT gate normally has no decomposition, we can use default.qubit # here for expository purposes. dev = qml.device( 'default.qubit', wires=2, custom_decomps={"CNOT" : ion_trap_cnot} ) @qml.qnode(dev) def run_cnot(): qml.CNOT(wires=[0, 1]) return qml.expval(qml.X(1))
>>> print(qml.draw(run_cnot, level="device")()) 0: ──RY(1.57)─╭IsingXX(1.57)──RX(-1.57)──RY(-1.57)─┤ 1: ───────────╰IsingXX(1.57)──RY(-1.57)────────────┤ <X>
Some devices may accept additional arguments. For instance,
default.gaussianaccepts the keyword argumenthbar, to set the convention used in the commutation relation \([\x,\p]=i\hbar\) (by default set to 2).Please refer to the documentation for the individual devices to see any additional arguments that might be required or supported.