qml.workflow.construct_batch¶
- construct_batch(qnode, level='user')[source]¶
Construct the batch of tapes and post processing for a designated stage in the transform program.
Warning
Using
level=Noneis deprecated and will be removed in a future release. Please uselevel='device'to include all transforms.- Parameters:
qnode (QNode) – the qnode we want to get the tapes and post-processing for.
level (None, str, int, slice) – An indication of what transforms to apply before drawing. Check
get_transform_program()for more information on the allowed values and usage details of this argument.
- Returns:
A function with the same call signature as the initial quantum function. This function returns a batch (tuple) of tapes and postprocessing function.
- Return type:
Callable
See also
pennylane.workflow.get_transform_program()to inspect the contents of the transform program for a specified level.Usage Details
Suppose we have a QNode with several user transforms.
from pennylane.workflow import construct_batch @qml.transforms.undo_swaps @qml.transforms.merge_rotations @qml.transforms.cancel_inverses @qml.qnode(qml.device('default.qubit'), diff_method="parameter-shift", gradient_kwargs = {"shifts": np.pi/4}) def circuit(x): qml.RandomLayers(qml.numpy.array([[1.0, 2.0]]), wires=(0,1)) qml.RX(x, wires=0) qml.RX(-x, wires=0) qml.SWAP((0,1)) qml.X(0) qml.X(0) return qml.expval(qml.X(0) + qml.Y(0))
We can inspect what the device will execute with:
>>> batch, fn = construct_batch(circuit, level="device")(1.23) >>> batch[0].circuit [RY(1.0, wires=[1]), RX(2.0, wires=[0]), expval(X(0) + Y(0))]
These tapes can be natively executed by the device. However, with non-backprop devices the parameters will need to be converted to NumPy with
convert_to_numpy_parameters().>>> fn(dev.execute(batch)) (np.float64(-0.9092974268256817),)
Or what the parameter shift gradient transform will be applied to:
>>> batch, fn = construct_batch(circuit, level="gradient")(1.23) >>> batch[0].circuit [RY(tensor(1., requires_grad=True), wires=[1]), RX(tensor(2., requires_grad=True), wires=[0]), expval(X(0) + Y(0))]
We can inspect what was directly captured from the qfunc with
level=0.>>> batch, fn = construct_batch(circuit, level=0)(1.23) >>> batch[0].circuit [RandomLayers(tensor([[1., 2.]], requires_grad=True), wires=[0, 1]), RX(1.23, wires=[0]), RX(-1.23, wires=[0]), SWAP(wires=[0, 1]), X(0), X(0), expval(X(0) + Y(0))]
And iterate though stages in the transform program with different integers. If we request
level=1, thecancel_inversestransform has been applied.>>> batch, fn = construct_batch(circuit, level=1)(1.23) >>> batch[0].circuit [RandomLayers(tensor([[1., 2.]], requires_grad=True), wires=[0, 1]), RX(1.23, wires=[0]), RX(-1.23, wires=[0]), SWAP(wires=[0, 1]), expval(X(0) + Y(0))]
We can also slice into a subset of the transform program.
slice(1, None)would skip the first user transformcancel_inverses:>>> batch, fn = construct_batch(circuit, level=slice(1,None))(1.23) >>> batch[0].circuit [RY(tensor(1., requires_grad=True), wires=[1]), RX(tensor(2., requires_grad=True), wires=[0]), X(0), X(0), expval(X(0) + Y(0))]