LightningTensor

class LightningTensor(*, wires=None, shots=None, method: str = 'mps', c_dtype=<class 'numpy.complex128'>, **kwargs)[source]

Bases: Device

PennyLane Lightning Tensor device.

A device to perform tensor network operations on a quantum circuit.

This device is designed to simulate large-scale quantum circuits using tensor network methods. For small circuits, other devices like lightning.qubit, lightning.gpu or lightning.kokkos are recommended.

Currently, the Matrix Product State (MPS) and the Exact Tensor Network methods are supported as implemented in the cutensornet backend.

Parameters
  • wires (Optional[int, list]) – The number of wires to initialize the device with. Defaults to None if not specified, and the device will allocate the number of wires depending on the circuit to execute. Defaults to None if not specified.

  • shots (int) – Measurements are performed drawing shots times from a discrete random variable distribution associated with a state vector and an observable. Defaults to None if not specified. Setting to None results in computing statistics like expectation values and variances analytically.

  • method (str) – Supported method. The supported methods are "mps" (Matrix Product State) and "tn" (Exact Tensor Network). Default is "mps".

  • c_dtype – Datatypes for the tensor representation. Must be one of numpy.complex64 or numpy.complex128. Default is numpy.complex128.

Keyword Arguments
  • max_bond_dim (int) – (Only for method=mps) The maximum bond dimension to be used in the MPS simulation. Default is 128. The accuracy of the wavefunction representation comes with a memory tradeoff which can be tuned with max_bond_dim. The larger the internal bond dimension, the more entanglement can be described but the larger the memory requirements. Note that GPUs are ill-suited (i.e. less competitive compared with CPUs) for simulating circuits with low bond dimensions and/or circuit layers with a single or few gates because the arithmetic intensity is lower.

  • cutoff (float) – (Only for method=mps) The threshold used to truncate the singular values of the MPS tensors. The default is 0.

  • cutoff_mode (str) – (Only for method=mps) Singular value truncation mode for MPS tensors. The options are "rel" and "abs". Default is "abs".

  • backend (str) – Supported backend. Currently, only cutensornet is supported. Default is cutensornet.

  • worksize_pref (str) – Preference for workspace size for cutensornet backend. The options are recommended and max. Default is recommended.

Example for the MPS method

import pennylane as qml

num_qubits = 100

dev = qml.device("lightning.tensor", wires=num_qubits, max_bond_dim=32)

@qml.qnode(dev)
def circuit(num_qubits):
    for qubit in range(0, num_qubits - 1):
        qml.CZ(wires=[qubit, qubit + 1])
        qml.X(wires=[qubit])
        qml.Z(wires=[qubit + 1])
    return qml.expval(qml.Z(0))
>>> print(circuit(num_qubits))
-1.0

Example for the Exact Tensor Network method

import pennylane as qml

num_qubits = 100

dev = qml.device("lightning.tensor", wires=num_qubits, method="tn")

@qml.qnode(dev)
def circuit(num_qubits):
    for qubit in range(0, num_qubits - 1):
        qml.CZ(wires=[qubit, qubit + 1])
        qml.X(wires=[qubit])
        qml.Z(wires=[qubit + 1])
    return qml.expval(qml.Z(0))
>>> print(circuit(num_qubits))
-1.0

backend

Supported backend.

c_dtype

Tensor complex data type.

capabilities

A DeviceCapabilities object describing the capabilities of the backend device.

config_filepath

A device can use a toml file to specify the capabilities of the backend device.

dtype

Tensor complex data type.

method

Supported method.

name

The name of the device.

num_wires

Number of wires addressed on this device.

observables

operations

shots

Default shots for execution workflows containing this device.

tracker

A Tracker that can store information about device executions, shots, batches, intermediate results, or any additional device dependent information.

wires

The device wires.

backend

Supported backend.

c_dtype

Tensor complex data type.

capabilities: DeviceCapabilities | None = None

A DeviceCapabilities object describing the capabilities of the backend device.

config_filepath: str | None = None

A device can use a toml file to specify the capabilities of the backend device. If this is provided, the file will be loaded into a DeviceCapabilities object assigned to the capabilities attribute.

dtype

Tensor complex data type.

method

Supported method.

name

The name of the device.

num_wires

Number of wires addressed on this device.

observables = frozenset({'Exp', 'Hadamard', 'Hermitian', 'Identity', 'LinearCombination', 'PauliX', 'PauliY', 'PauliZ', 'Prod', 'SProd', 'Sum'})
operations = frozenset({'Adjoint(ISWAP)', 'Adjoint(S)', 'Adjoint(SISWAP)', 'Adjoint(SX)', 'Adjoint(T)', 'BlockEncode', 'C(BlockEncode)', 'C(DoubleExcitation)', 'C(DoubleExcitationMinus)', 'C(DoubleExcitationPlus)', 'C(GlobalPhase)', 'C(Hadamard)', 'C(IsingXX)', 'C(IsingXY)', 'C(IsingYY)', 'C(IsingZZ)', 'C(MultiRZ)', 'C(PhaseShift)', 'C(RX)', 'C(RY)', 'C(RZ)', 'C(Rot)', 'C(S)', 'C(SingleExcitation)', 'C(SingleExcitationMinus)', 'C(SingleExcitationPlus)', 'C(T)', 'CNOT', 'CRX', 'CRY', 'CRZ', 'CRot', 'CSWAP', 'CY', 'CZ', 'ControlledPhaseShift', 'ControlledQubitUnitary', 'DiagonalQubitUnitary', 'DoubleExcitation', 'DoubleExcitationMinus', 'DoubleExcitationPlus', 'ECR', 'GlobalPhase', 'Hadamard', 'ISWAP', 'Identity', 'IsingXX', 'IsingXY', 'IsingYY', 'IsingZZ', 'MPSPrep', 'OrbitalRotation', 'PSWAP', 'PauliX', 'PauliY', 'PauliZ', 'PhaseShift', 'QubitCarry', 'QubitSum', 'QubitUnitary', 'RX', 'RY', 'RZ', 'Rot', 'S', 'SISWAP', 'SQISW', 'SWAP', 'SX', 'SingleExcitation', 'SingleExcitationMinus', 'SingleExcitationPlus', 'T', 'Toffoli'})
shots

Default shots for execution workflows containing this device.

Note that the device itself should always pull shots from the provided QuantumTape and its shots, not from this property. This property is used to provide a default at the start of a workflow.

tracker: Tracker = <pennylane.devices.tracker.Tracker object>

A Tracker that can store information about device executions, shots, batches, intermediate results, or any additional device dependent information.

A plugin developer can store information in the tracker by:

# querying if the tracker is active
if self.tracker.active:

    # store any keyword: value pairs of information
    self.tracker.update(executions=1, shots=self._shots, results=results)

    # Calling a user-provided callback function
    self.tracker.record()
wires

The device wires.

Note that wires are optional, and the default value of None means any wires can be used. If a device has wires defined, they will only be used for certain features. This includes:

  • Validation of tapes being executed on the device

  • Defining the wires used when evaluating a state() measurement

compute_derivatives(circuits[, execution_config])

Calculate the Jacobian of either a single or a batch of circuits on the device.

compute_jvp(circuits, tangents[, ...])

The jacobian vector product used in forward mode calculation of derivatives.

compute_vjp(circuits, cotangents[, ...])

The vector-Jacobian product used in reverse-mode differentiation.

dynamic_wires_from_circuit(circuit)

Map circuit wires to Pennylane default.qubit standard wire order.

eval_jaxpr(jaxpr, consts, *args[, ...])

An experimental method for natively evaluating PLXPR.

execute(circuits[, execution_config])

Execute a circuit or a batch of circuits and turn it into results.

execute_and_compute_derivatives(circuits[, ...])

Compute the results and Jacobians of circuits at the same time.

execute_and_compute_jvp(circuits, tangents)

Execute a batch of circuits and compute their jacobian vector products.

execute_and_compute_vjp(circuits, cotangents)

Calculate both the results and the vector-Jacobian product used in reverse-mode differentiation.

jaxpr_jvp(jaxpr, args, tangents[, ...])

An experimental method for computing the results and jvp for PLXPR.

preprocess([execution_config])

Device preprocessing function.

preprocess_transforms([execution_config])

This function defines the device transform program to be applied and an updated device configuration.

setup_execution_config([config, circuit])

Update the execution config with choices for how the device should be used and the device options.

supports_derivatives([execution_config, circuit])

Check whether or not derivatives are available for a given configuration and circuit.

supports_jvp([execution_config, circuit])

Whether or not a given device defines a custom jacobian vector product.

supports_vjp([execution_config, circuit])

Whether or not this device defines a custom vector-Jacobian product.

compute_derivatives(circuits: Union[QuantumTape, Sequence[QuantumTape]], execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None)[source]

Calculate the Jacobian of either a single or a batch of circuits on the device.

Parameters
  • circuits (Union[QuantumTape, Sequence[QuantumTape]]) – the circuits to calculate derivatives for.

  • execution_config (ExecutionConfig) – a data structure with all additional information required for execution.

Returns

The Jacobian for each trainable parameter.

Return type

Tuple

compute_jvp(circuits: pennylane.tape.qscript.QuantumScript | collections.abc.Sequence[pennylane.tape.qscript.QuantumScript], tangents: tuple[numbers.Number, ...], execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None)

The jacobian vector product used in forward mode calculation of derivatives.

Parameters
  • circuits (Union[QuantumTape, Sequence[QuantumTape]]) – the circuit or batch of circuits

  • tangents (tensor-like) – Gradient vector for input parameters.

  • execution_config (ExecutionConfig) – a datastructure with all additional information required for execution

Returns

A numeric result of computing the jacobian vector product

Return type

Tuple

Definition of jvp:

If we have a function with jacobian:

\[\vec{y} = f(\vec{x}) \qquad J_{i,j} = \frac{\partial y_i}{\partial x_j}\]

The Jacobian vector product is the inner product with the derivatives of \(x\), yielding only the derivatives of the output \(y\):

\[\text{d}y_i = \Sigma_{j} J_{i,j} \text{d}x_j\]

Shape of tangents:

The tangents tuple should be the same length as circuit.get_parameters() and have a single number per parameter. If a number is zero, then the gradient with respect to that parameter does not need to be computed.

compute_vjp(circuits: Union[QuantumTape, Sequence[QuantumTape]], cotangents: Tuple[Number], execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None)[source]

The vector-Jacobian product used in reverse-mode differentiation.

Parameters
  • circuits (Union[QuantumTape, Sequence[QuantumTape]]) – the circuit or batch of circuits.

  • cotangents (Tuple[Number, Tuple[Number]]) – Gradient-output vector. Must have shape matching the output shape of the corresponding circuit. If the circuit has a single output, cotangents may be a single number, not an iterable of numbers.

  • execution_config (ExecutionConfig) – a data structure with all additional information required for execution.

Returns

A numeric result of computing the vector-Jacobian product.

Return type

tensor-like

dynamic_wires_from_circuit(circuit)[source]

Map circuit wires to Pennylane default.qubit standard wire order.

Parameters

circuit (QuantumTape) – The circuit to execute.

Returns

The updated circuit with the wires mapped to the standard wire order.

Return type

QuantumTape

eval_jaxpr(jaxpr: jax.extend.core.Jaxpr, consts: list[Union[int, float, bool, complex, bytes, list, tuple, numpy.ndarray, numpy.generic, autograd.numpy.numpy_boxes.ArrayBox, pennylane.typing.InterfaceTensor]], *args, execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None, shots: Shots = Shots(total_shots=None, shot_vector=())) list[Union[int, float, bool, complex, bytes, list, tuple, numpy.ndarray, numpy.generic, autograd.numpy.numpy_boxes.ArrayBox, pennylane.typing.InterfaceTensor]]

An experimental method for natively evaluating PLXPR. See the capture module for more details.

Parameters
  • jaxpr (jax.extend.core.Jaxpr) – Pennylane variant jaxpr containing quantum operations and measurements

  • consts (list[TensorLike]) – the closure variables consts corresponding to the jaxpr

  • *args (TensorLike) – the variables to use with the jaxpr.

Keyword Arguments
  • execution_config (Optional[ExecutionConfig]) – a data structure with additional information required for execution

  • shots (Shots) – the number of shots to use for the evaluation

Returns

the result of evaluating the jaxpr with the given parameters.

Return type

list[TensorLike]

execute(circuits: Union[QuantumTape, Sequence[QuantumTape]], execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None) Union[Result, Sequence[Result]][source]

Execute a circuit or a batch of circuits and turn it into results.

Parameters
  • circuits (Union[QuantumTape, Sequence[QuantumTape]]) – the quantum circuits to be executed.

  • execution_config (ExecutionConfig) – a data structure with additional information required for execution.

Returns

A numeric result of the computation.

Return type

TensorLike, tuple[TensorLike], tuple[tuple[TensorLike]]

execute_and_compute_derivatives(circuits: Union[QuantumTape, Sequence[QuantumTape]], execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None)[source]

Compute the results and Jacobians of circuits at the same time.

Parameters
  • circuits (Union[QuantumTape, Sequence[QuantumTape]]) – the circuits or batch of circuits.

  • execution_config (ExecutionConfig) – a data structure with all additional information required for execution.

Returns

A numeric result of the computation and the gradient.

Return type

tuple

execute_and_compute_jvp(circuits: pennylane.tape.qscript.QuantumScript | collections.abc.Sequence[pennylane.tape.qscript.QuantumScript], tangents: tuple[numbers.Number, ...], execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None)

Execute a batch of circuits and compute their jacobian vector products.

Parameters
  • circuits (Union[QuantumTape, Sequence[QuantumTape]]) – circuit or batch of circuits

  • tangents (tensor-like) – Gradient vector for input parameters.

  • execution_config (ExecutionConfig) – a datastructure with all additional information required for execution

Returns

A numeric result of execution and of computing the jacobian vector product

Return type

Tuple, Tuple

See also

execute() and compute_jvp()

execute_and_compute_vjp(circuits: Union[QuantumTape, Sequence[QuantumTape]], cotangents: Tuple[Number], execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None)[source]

Calculate both the results and the vector-Jacobian product used in reverse-mode differentiation.

Parameters
  • circuits (Union[QuantumTape, Sequence[QuantumTape]]) – the circuit or batch of circuits to be executed.

  • cotangents (Tuple[Number, Tuple[Number]]) – Gradient-output vector. Must have shape matching the output shape of the corresponding circuit.

  • execution_config (ExecutionConfig) – a data structure with all additional information required for execution.

Returns

the result of executing the scripts and the numeric result of computing the vector-Jacobian product

Return type

Tuple, Tuple

jaxpr_jvp(jaxpr: jax.extend.core.Jaxpr, args, tangents, execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None)

An experimental method for computing the results and jvp for PLXPR. See the capture module for more details.

Parameters
  • jaxpr (jax.extend.core.Jaxpr) – Pennylane variant jaxpr containing quantum operations and measurements

  • args (Sequence[TensorLike]) – the consts followed by the normal arguments

  • tangents (Sequence[TensorLike]) – the tangents corresponding to args. May contain jax.interpreters.ad.Zero.

Keyword Arguments

execution_config (Optional[ExecutionConfig]) – a data structure with additional information required for execution

Returns

the results and jacobian vector products

Return type

Sequence[TensorLike], Sequence[TensorLike]

>>> qml.capture.enable()
>>> import jax
>>> closure_var = jax.numpy.array(0.5)
>>> def f(x):
...     qml.RX(closure_var, 0)
...     qml.RX(x, 1)
...     return qml.expval(qml.Z(0)), qml.expval(qml.Z(1))
>>> jaxpr = jax.make_jaxpr(f)(1.2)
>>> args = (closure_var, 1.2)
>>> zero = jax.interpreters.ad.Zero(jax.core.ShapedArray((), float))
>>> tangents = (zero, 1.0)
>>> config = qml.devices.ExecutionConfig(gradient_method="adjoint")
>>> dev = qml.device('default.qubit', wires=2)
>>> res, jvps = dev.jaxpr_jvp(jaxpr.jaxpr, args, tangents, execution_config=config)
>>> res
[Array(0.87758255, dtype=float32), Array(0.36235774, dtype=float32)]
>>> jvps
[Array(0., dtype=float32), Array(-0.932039, dtype=float32)]
preprocess(execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None) tuple[pennylane.transforms.core.transform_program.TransformProgram, pennylane.devices.execution_config.ExecutionConfig]

Device preprocessing function.

Warning

This function is tracked by machine learning interfaces and should be fully differentiable. The pennylane.math module can be used to construct fully differentiable transformations.

Additional preprocessing independent of machine learning interfaces can be done inside of the execute() method.

Parameters

execution_config (ExecutionConfig) – A datastructure describing the parameters needed to fully describe the execution.

Returns

A transform program that is called before execution, and a configuration

with unset specifications filled in.

Return type

TransformProgram, ExecutionConfig

Raises

Exception – An exception can be raised if the input cannot be converted into a form supported by the device.

Preprocessing program may include:

  • expansion to Operator’s and MeasurementProcess objects supported by the device.

  • splitting a circuit with the measurement of non-commuting observables or Hamiltonians into multiple executions

  • splitting circuits with batched parameters into multiple executions

  • gradient specific preprocessing, such as making sure trainable operators have generators

  • validation of configuration parameters

  • choosing a best gradient method and grad_on_execution value.

Example

All the transforms that are part of the preprocessing need to respect the transform contract defined in pennylane.transform().

from pennylane.tape import TapeBatch
from pennylane.typing import PostprocessingFn

@transform
def my_preprocessing_transform(tape: qml.tape.QuantumScript) -> tuple[QuantumScriptBatch, PostprocessingFn]:
    # e.g. valid the measurements, expand the tape for the hardware execution, ...

    def blank_processing_fn(results):
        return results[0]

    return [tape], processing_fn

Then we can define the preprocess method on the custom device. The program can accept an arbitrary number of transforms.

def preprocess(config):
    program = TransformProgram()
    program.add_transform(my_preprocessing_transform)
    return program, config

See also

transform() and TransformProgram

Derivatives and jacobian products will be bound to the machine learning library before the postprocessing function is called on results. Therefore the machine learning library will be responsible for combining the device provided derivatives and post processing derivatives.

from pennylane.interfaces.jax import execute as jax_boundary

def f(x):
    circuit = qml.tape.QuantumScript([qml.Rot(*x, wires=0)], [qml.expval(qml.Z(0))])
    config = ExecutionConfig(gradient_method="adjoint")
    program, config = dev.preprocess(config)
    circuit_batch, postprocessing = program((circuit, ))

    def execute_fn(tapes):
        return dev.execute_and_compute_derivatives(tapes, config)

    results = jax_boundary(circuit_batch, dev, execute_fn, None, {})
    return postprocessing(results)

x = jax.numpy.array([1.0, 2.0, 3.0])
jax.grad(f)(x)

In the above code, the quantum derivatives are registered with jax in the jax_boundary function. Only then is the classical postprocessing called on the result object.

preprocess_transforms(execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None) TransformProgram[source]

This function defines the device transform program to be applied and an updated device configuration.

Parameters

execution_config (Union[ExecutionConfig, Sequence[ExecutionConfig]]) – A data structure describing the parameters needed to fully describe the execution.

Returns

A transform program that when called returns QuantumTape’s that the device can natively execute as well as a postprocessing function to be called after execution, and a configuration with unset specifications filled in.

Return type

TransformProgram, ExecutionConfig

This device currently:

  • Does not support derivatives.

  • Does not support vector-Jacobian products.

setup_execution_config(config: pennylane.devices.execution_config.ExecutionConfig | None = None, circuit=None) ExecutionConfig[source]

Update the execution config with choices for how the device should be used and the device options.

supports_derivatives(execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None, circuit: Optional[QuantumTape] = None) bool[source]

Check whether or not derivatives are available for a given configuration and circuit.

Parameters
  • execution_config (ExecutionConfig) – The configuration of the desired derivative calculation.

  • circuit (QuantumTape) – An optional circuit to check derivatives support for.

Returns

Whether or not a derivative can be calculated provided the given information.

Return type

Bool

supports_jvp(execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None, circuit: pennylane.tape.qscript.QuantumScript | None = None) bool

Whether or not a given device defines a custom jacobian vector product.

Parameters
  • execution_config (ExecutionConfig) – A description of the hyperparameters for the desired computation.

  • circuit (None, QuantumTape) – A specific circuit to check differentation for.

Default behaviour assumes this to be True if compute_jvp() is overridden.

supports_vjp(execution_config: pennylane.devices.execution_config.ExecutionConfig | None = None, circuit: Optional[QuantumTape] = None) bool[source]

Whether or not this device defines a custom vector-Jacobian product.

Parameters
  • execution_config (ExecutionConfig) – The configuration of the desired derivative calculation.

  • circuit (QuantumTape) – An optional circuit to check derivatives support for.

Returns

Whether or not a derivative can be calculated provided the given information.

Return type

Bool