qml.gradients.gradient_transform

class gradient_transform(*args, **kwargs)[source]

Bases: pennylane.transforms.batch_transform.batch_transform

Decorator for defining quantum gradient transforms.

Quantum gradient transforms are a specific case of batch_transform. All quantum gradient transforms accept a tape, and output a batch of tapes to be independently executed on a quantum device, alongside a post-processing function that returns the result.

Parameters
  • expand_fn (function) – An expansion function (if required) to be applied to the input tape before the gradient computation takes place. If not provided, the default expansion function simply expands all operations that have Operation.grad_method=None until all resulting operations have a defined gradient method.

  • differentiable (bool) – Specifies whether the gradient transform is differentiable or not. A transform may be non-differentiable if it does not use an autodiff framework for its tensor manipulations. In such a case, setting differentiable=False instructs the decorator to mark the output as ‘constant’, reducing potential overhead.

  • hybrid (bool) –

    Specifies whether classical processing inside a QNode should be taken into account when transforming a QNode.

    • If True, and classical processing is detected and this option is set to True, the Jacobian of the classical processing will be computed and included. When evaluated, the returned Jacobian will be with respect to the QNode arguments.

    • If False, any internal QNode classical processing will be ignored. When evaluated, the returned Jacobian will be with respect to the gate arguments, and not the QNode arguments.

Supported gradient transforms must be of the following form:

@gradient_transform
def my_custom_gradient(tape, argnum=None, **kwargs):
    ...
    return gradient_tapes, processing_fn

where:

  • tape (QuantumTape): the input quantum tape to compute the gradient of

  • argnum (int or list[int] or None): Which trainable parameters of the tape to differentiate with respect to. If not provided, the derivatives with respect to all trainable inputs of the tape should be returned (tape.trainable_params).

  • gradient_tapes (list[QuantumTape]): is a list of output tapes to be evaluated. If this list is empty, no quantum evaluations will be made.

  • processing_fn is a processing function to be applied to the output of the evaluated gradient_tapes. It should accept a list of numeric results with length len(gradient_tapes), and return the Jacobian matrix.

Once defined, the quantum gradient transform can be used as follows:

>>> gradient_tapes, processing_fn = my_custom_gradient(tape, *gradient_kwargs)
>>> res = execute(tapes, dev, interface="autograd", gradient_fn=qml.gradients.param_shift)
>>> jacobian = processing_fn(res)

Alternatively, gradient transforms can be applied directly to QNodes, in which case the execution is implicit:

>>> fn = my_custom_gradient(qnode, *gradient_kwargs)
>>> fn(weights) # transformed function takes the same arguments as the QNode
1.2629730888100839

Note

The input tape might have parameters of various types, including NumPy arrays, JAX Arrays, and TensorFlow and PyTorch tensors.

If the gradient transform is written in a autodiff-compatible manner, either by using a framework such as Autograd or TensorFlow, or by using qml.math for tensor manipulation, then higher-order derivatives will also be supported.

Alternatively, you may use the tape.unwrap() context manager to temporarily convert all tape parameters to NumPy arrays and floats:

>>> with tape.unwrap():
...     params = tape.get_parameters()  # list of floats

construct(tape, *targs, **tkwargs)

Applies the batch tape transform to an input tape.

custom_qnode_wrapper(fn)

Register a custom QNode execution wrapper function for the batch transform.

default_qnode_wrapper(qnode, targs, tkwargs)

A wrapper method that takes a QNode and transform arguments, and returns a function that ‘wraps’ the QNode execution.

construct(tape, *targs, **tkwargs)

Applies the batch tape transform to an input tape.

Parameters
  • tape (QuantumTape) – the tape to be transformed

  • *args – positional arguments to pass to the tape transform

  • **kwargs – keyword arguments to pass to the tape transform

Returns

list of transformed tapes to execute and a post-processing function.

Return type

tuple[list[tapes], callable]

custom_qnode_wrapper(fn)

Register a custom QNode execution wrapper function for the batch transform.

Example

def my_transform(tape, *targs, **tkwargs):
    ...
    return tapes, processing_fn

@my_transform.custom_qnode_wrapper
def my_custom_qnode_wrapper(self, qnode, targs, tkwargs):
    def wrapper_fn(*args, **kwargs):
        # construct QNode
        qnode.construct(args, kwargs)
        # apply transform to QNode's tapes
        tapes, processing_fn = self.construct(qnode.qtape, *targs, **tkwargs)
        # execute tapes and return processed result
        ...
        return processing_fn(results)
    return wrapper_fn

The custom QNode execution wrapper must have arguments self (the batch transform object), qnode (the input QNode to transform and execute), targs and tkwargs (the transform arguments and keyword arguments respectively).

It should return a callable object that accepts the same arguments as the QNode, and returns the transformed numerical result.

The default default_qnode_wrapper() method may be called if only pre- or post-processing dependent on QNode arguments is required:

@my_transform.custom_qnode_wrapper
def my_custom_qnode_wrapper(self, qnode, targs, tkwargs):
    transformed_qnode = self.default_qnode_wrapper(qnode)

    def wrapper_fn(*args, **kwargs):
        args, kwargs = pre_process(args, kwargs)
        res = transformed_qnode(*args, **kwargs)
        ...
        return ...
    return wrapper_fn
default_qnode_wrapper(qnode, targs, tkwargs)[source]

A wrapper method that takes a QNode and transform arguments, and returns a function that ‘wraps’ the QNode execution.

The returned function should accept the same keyword arguments as the QNode, and return the output of applying the tape transform to the QNode’s constructed tape.