qml.transforms.core.transform_dispatcher.TransformDispatcher

class TransformDispatcher(*args, **__)[source]

Bases: object

Converts a transform that has the signature (tape -> Sequence(tape), fn) to a transform dispatcher that can act on pennylane.tape.QuantumTape, quantum function, pennylane.QNode, pennylane.devices.Device.

Warning

This class is developer-facing and should not be used directly. Instead, use qml.transform if you would like to make a custom transform.

See also

transform()

classical_cotransform

The classical co-transform.

expand_transform

The expand transform.

final_transform

True if the transformed tapes must be executed.

is_informative

True if the transform is informative.

pass_name

The name of the equivalent MLIR pass.

plxpr_transform

Function for transforming plxpr.

register

Returns a decorator for registering a specific application behavior for a given transform and a new class.

transform

The quantum transform.

classical_cotransform

The classical co-transform.

expand_transform

The expand transform.

final_transform

True if the transformed tapes must be executed.

is_informative

True if the transform is informative.

pass_name

The name of the equivalent MLIR pass.

plxpr_transform

Function for transforming plxpr.

register

Returns a decorator for registering a specific application behavior for a given transform and a new class.

@qml.transform
def printer(tape):
    print("I have a tape: ", tape)
    return (tape, ), lambda x: x[0]

@printer.register
def _(obj: qml.operation.Operator, *targs, **tkwargs):
    print("I have an operator:", obj)
    return obj
>>> printer(qml.X(0))
I have an operator: X(0)
X(0)
transform

The quantum transform.

custom_qnode_transform(fn)

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

default_qnode_transform(qnode, targs, tkwargs)

The default method that takes in a QNode and returns another QNode with the transform applied.

generic_apply_transform(obj, *targs, **tkwargs)

Generic application of a transform that forms the default for all transforms.

generic_register([arg])

Returns a decorator for registering a default application behavior for a transform for a new class.

custom_qnode_transform(fn)[source]

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

Example

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

@my_transform.custom_qnode_transform
def my_custom_qnode_wrapper(self, qnode, targs, tkwargs):
    new_tkwargs = dict(tkwargs)
    new_tkwargs['shots'] = 100
    return self.generic_apply_transform(qnode, *targs, **new_tkwargs)

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 QNode that accepts the same arguments as the input QNode with the transform applied.

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

default_qnode_transform(qnode, targs, tkwargs)[source]

The default method that takes in a QNode and returns another QNode with the transform applied.

generic_apply_transform(obj, *targs, **tkwargs)[source]

Generic application of a transform that forms the default for all transforms.

Parameters:
  • obj – The object we want to transform

  • *targs – The arguments for the transform

  • **tkwargs – The keyword arguments for the transform.

static generic_register(arg=None)[source]

Returns a decorator for registering a default application behavior for a transform for a new class.

Given a special new class, we can register how transforms should apply to them via:

class Subroutine:

    def __repr__(self):
        return f"<Subroutine: {self.ops}>"

    def __init__(self, ops):
        self.ops = ops

from pennylane.transforms.core import TransformDispatcher

@TransformDispatcher.generic_register
def apply_to_subroutine(obj: Subroutine, transform, *targs, **tkwargs):
    tape = qml.tape.QuantumScript(obj.ops)
    batch, _ = transform(tape, *targs, **tkwargs)
    return Subroutine(batch[0].operations)
>>> qml.transforms.cancel_inverses(Subroutine([qml.Y(0), qml.X(0), qml.X(0)]))
<Subroutine: [Y(0)]>

The type can also be explicitly provided like:

@TransformDispatcher.generic_register(Subroutine)
def apply_to_subroutine(obj: Subroutine, transform, *targs, **tkwargs):
    tape = qml.tape.QuantumScript(obj.ops)
    batch, _ = transform(tape, *targs, **tkwargs)
    return Subroutine(batch[0].operations)

to more explicitly force registration for a given type.