# qml.tape.QuantumTape¶

class QuantumTape(ops=None, measurements=None, prep=None, name=None, do_queue=True, _update=True)[source]

Bases: pennylane.tape.qscript.QuantumScript, pennylane.queuing.AnnotatedQueue

A quantum tape recorder, that records and stores variational quantum programs.

Parameters
• ops (Iterable[Operator]) – An iterable of the operations to be performed

• measurements (Iterable[MeasurementProcess]) – All the measurements to be performed

• prep (Iterable[Operator]) – Any state preparations to perform at the start of the circuit

Keyword Arguments
• name (str) – a name given to the quantum tape

• do_queue=True (bool) – Whether or not to queue. Defaults to True for QuantumTape.

• _update=True (bool) – Whether or not to set various properties on initialization. Setting _update=False reduces computations if the tape is only an intermediary step.

Example

with qml.tape.QuantumTape() as tape:
qml.RX(0.432, wires=0)
qml.RY(0.543, wires=0)
qml.CNOT(wires=[0, 'a'])
qml.RX(0.133, wires='a')
qml.expval(qml.PauliZ(wires=[0]))


Once constructed, the tape may act as a quantum circuit and information about the quantum circuit can be queried:

>>> list(tape)
[RX(0.432, wires=[0]), RY(0.543, wires=[0]), CNOT(wires=[0, 'a']), RX(0.133, wires=['a']), expval(PauliZ(wires=[0]))]
>>> tape.operations
[RX(0.432, wires=[0]), RY(0.543, wires=[0]), CNOT(wires=[0, 'a']), RX(0.133, wires=['a'])]
>>> tape.observables
[expval(PauliZ(wires=[0]))]
>>> tape.get_parameters()
[0.432, 0.543, 0.133]
>>> tape.wires
<Wires = [0, 'a']>
>>> tape.num_params
3


Tapes can also be constructed by directly providing operations, measurements, and state preparations:

>>> ops = [qml.S(0), qml.T(1)]
>>> measurements = [qml.state()]
>>> prep = [qml.BasisState([1,0], wires=0)]
>>> tape = qml.tape.QuantumTape(ops, measurements, prep=prep)
>>> tape.circuit
[BasisState([1, 0], wires=[0]), S(wires=[0]), T(wires=[1]), state(wires=[])]


The existing circuit is overriden upon exiting a recording context.

Iterating over the quantum circuit can be done by iterating over the tape object:

>>> for op in tape:
...     print(op)
RX(0.432, wires=[0])
RY(0.543, wires=[0])
CNOT(wires=[0, 'a'])
RX(0.133, wires=['a'])
expval(PauliZ(wires=[0]))


Tapes can also as sequences and support indexing and the len function:

>>> tape[0]
RX(0.432, wires=[0])
>>> len(tape)
5


The CircuitGraph can also be accessed:

>>> tape.graph
<pennylane.circuit_graph.CircuitGraph object at 0x7fcc0433a690>


Once constructed, the quantum tape can be executed directly on a supported device via the execute() function:

>>> dev = qml.device("default.qubit", wires=[0, 'a'])
[array([0.77750694])]


The trainable parameters of the tape can be explicitly set, and the values of the parameters modified in-place:

>>> tape.trainable_params = [0] # set only the first parameter as trainable
>>> tape.set_parameters([0.56])
>>> tape.get_parameters()
[0.56]
>>> tape.get_parameters(trainable_only=False)
[0.56, 0.543, 0.133]


When using a tape with do_queue=False, that tape will not be queued in a parent tape context.

with qml.tape.QuantumTape() as tape1:
with qml.tape.QuantumTape(do_queue=False) as tape2:
qml.RX(0.123, wires=0)


Here, tape2 records the RX gate, but tape1 doesn’t record tape2.

>>> tape1.operations
[]
>>> tape2.operations
[RX(0.123, wires=[0])]


This is useful for when you want to transform a tape first before applying it.

 batch_size The batch size of the quantum script inferred from the batch sizes of the used operations for parameter broadcasting. circuit Returns the underlying quantum circuit as a list of operations and measurements. data Alias to get_parameters() and set_parameters() for backwards compatibilities with operations. diagonalizing_gates Returns the gates that diagonalize the measured wires such that they are in the eigenbasis of the circuit observables. do_queue Whether or not to queue the object. graph Returns a directed acyclic graph representation of the recorded quantum circuit: hash returns an integer hash uniquely representing the quantum script interface automatic differentiation interface used by the quantum script (if any) measurements Returns the measurements on the quantum script. num_params Returns the number of trainable parameters on the quantum script. numeric_type Returns the expected numeric type of the script result by inspecting its measurements. observables Returns the observables on the quantum script. operations Returns the state preparations and operations on the quantum script. output_dim The (inferred) output dimension of the quantum script. queue Returns a list of objects in the annotated queue samples_computational_basis Determines if any of the measurements are in the computational basis. specs Resource information about a quantum circuit. trainable_params Store or return a list containing the indices of parameters that support differentiability.
batch_size

The batch size of the quantum script inferred from the batch sizes of the used operations for parameter broadcasting.

batch_size for details.

Returns

The batch size of the quantum script if present, else None.

Return type

int or None

circuit

Returns the underlying quantum circuit as a list of operations and measurements.

The circuit is created with the assumptions that:

• The operations attribute contains quantum operations and mid-circuit measurements and

• The measurements attribute contains terminal measurements.

Note that the resulting list could contain MeasurementProcess objects that some devices may not support.

Returns

the quantum circuit containing quantum operations and measurements

Return type

list[Operator, MeasurementProcess]

data

Alias to get_parameters() and set_parameters() for backwards compatibilities with operations.

diagonalizing_gates

Returns the gates that diagonalize the measured wires such that they are in the eigenbasis of the circuit observables.

Returns

the operations that diagonalize the observables

Return type

List[Operation]

do_queue = False

Whether or not to queue the object. Assumed False for a vanilla Quantum Script, but may be True for its child Quantum Tape.

graph

Returns a directed acyclic graph representation of the recorded quantum circuit:

>>> ops = [qml.QubitStateVector([0, 1], 0), qml.RX(0.432, 0)]
>>> qscript = QuantumScript(ops, [qml.expval(qml.PauliZ(0))])
>>> qscript.graph
<pennylane.circuit_graph.CircuitGraph object at 0x7fcc0433a690>


Note that the circuit graph is only constructed once, on first call to this property, and cached for future use.

Returns

the circuit graph object

Return type

CircuitGraph

hash

returns an integer hash uniquely representing the quantum script

Type

int

interface

automatic differentiation interface used by the quantum script (if any)

Type

str, None

measurements

Returns the measurements on the quantum script.

Returns

list of measurement processes

Return type

list[MeasurementProcess]

Example

>>> ops = [qml.QubitStateVector([0, 1], 0), qml.RX(0.432, 0)]
>>> qscript = QuantumScript(ops, [qml.expval(qml.PauliZ(0))])
>>> qscript.measurements
[expval(PauliZ(wires=[0]))]

num_params

Returns the number of trainable parameters on the quantum script.

numeric_type

Returns the expected numeric type of the script result by inspecting its measurements.

Raises

ValueError – raised for unsupported cases for example when the script contains heterogeneous measurements

Returns

the numeric type corresponding to the result type of the script

Return type

type

Example:

>>> qscript = QuantumScript(measurements=[qml.state()])
>>> qscript.numeric_type
complex

observables

Returns the observables on the quantum script.

Returns

list of observables

Return type

list[MeasurementProcess, Observable]]

Example

>>> ops = [qml.QubitStateVector([0, 1], 0), qml.RX(0.432, 0)]
>>> qscript = QuantumScript(ops, [qml.expval(qml.PauliZ(0))])
>>> qscript.observables
[expval(PauliZ(wires=[0]))]

operations

Returns the state preparations and operations on the quantum script.

Returns

quantum operations

Return type

list[Operator]

>>> ops = [qml.QubitStateVector([0, 1], 0), qml.RX(0.432, 0)]
>>> qscript = QuantumScript(ops, [qml.expval(qml.PauliZ(0))])
>>> qscript.operations
[QubitStateVector([0, 1], wires=[0]), RX(0.432, wires=[0])]

output_dim

The (inferred) output dimension of the quantum script.

queue

Returns a list of objects in the annotated queue

samples_computational_basis

Determines if any of the measurements are in the computational basis.

specs

Resource information about a quantum circuit.

Returns

dictionaries that contain quantum script specifications

Return type

dict[str, Union[defaultdict,int]]

Example

>>> ops = [qml.Hadamard(0), qml.RX(0.26, 1), qml.CNOT((1,0)),
...         qml.Rot(1.8, -2.7, 0.2, 0), qml.Hadamard(1), qml.CNOT((0,1))]
>>> qscript = QuantumScript(ops, [qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))])


Asking for the specs produces a dictionary as shown below:

>>> qscript.specs['gate_sizes']
defaultdict(int, {1: 4, 2: 2})
>>> qscript.specs['gate_types']
defaultdict(int, {'Hadamard': 2, 'RX': 1, 'CNOT': 2, 'Rot': 1})


As defaultdict objects, any key not present in the dictionary returns 0.

>>> qscript.specs['gate_types']['RZ']
0

trainable_params

Store or return a list containing the indices of parameters that support differentiability. The indices provided match the order of appearence in the quantum circuit.

Setting this property can help reduce the number of quantum evaluations needed to compute the Jacobian; parameters not marked as trainable will be automatically excluded from the Jacobian computation.

The number of trainable parameters determines the number of parameters passed to set_parameters(), and changes the default output size of method get_parameters().

Note

For devices that support native backpropagation (such as default.qubit.tf and default.qubit.autograd), this property contains no relevant information when using backpropagation to compute gradients.

Example

>>> ops = [qml.RX(0.432, 0), qml.RY(0.543, 0),
...        qml.CNOT((0,"a")), qml.RX(0.133, "a")]
>>> qscript = QuantumScript(ops, [qml.expval(qml.PauliZ(0))])
>>> qscript.trainable_params
[0, 1, 2]
>>> qscript.trainable_params = [0] # set only the first parameter as trainable
>>> qscript.get_parameters()
[0.432]

 Create a quantum script that is the adjoint of this one. append(obj, **kwargs) Append obj into the queue with kwargs metadata. copy([copy_operations]) Returns a shallow copy of the quantum script. draw([wire_order, show_all_wires, decimals, …]) Draw the quantum script as a circuit diagram. expand([depth, stop_at, expand_measurements]) Expand all operations to a specific depth. from_queue(queue) Construct a QuantumScript from an AnnotatedQueue. fromkeys([value]) Create a new ordered dictionary with keys from iterable and values set to value. get(key[, default]) Return the value for key if key is in the dictionary, else default. get_info(obj) Retrieve the metadata for obj. get_operation(idx[, return_op_index]) Returns the trainable operation, and the corresponding operation argument index, for a specified trainable parameter index. get_parameters([trainable_only, operations_only]) Return the parameters incident on the quantum script operations. move_to_end(key[, last]) Move an existing element to the end (or beginning if last is false). pop(k[,d]) value. popitem([last]) Remove and return a (key, value) pair from the dictionary. remove(obj) Remove obj from the queue. set_parameters(params[, trainable_only]) Set the parameters incident on the quantum script operations. setdefault(key[, default]) Insert key with a value of default if key is not in the dictionary. shape(device) Produces the output shape of the quantum script by inspecting its measurements and the device used for execution. to_openqasm([wires, rotations, measure_all, …]) Serialize the circuit as an OpenQASM 2.0 program. A context manager that unwraps a quantum script with tensor-like parameters to NumPy arrays. update([E, ]**F) If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k] update_info(obj, **kwargs) Update obj’s metadata with kwargs if it exists in the queue.
adjoint()

Create a quantum script that is the adjoint of this one.

Adjointed quantum scripts are the conjugated and transposed version of the original script. Adjointed ops are equivalent to the inverted operation for unitary gates.

Returns

Return type

QuantumScript

append(obj, **kwargs)

Append obj into the queue with kwargs metadata.

clear()None.  Remove all items from od.
copy(copy_operations=False)

Returns a shallow copy of the quantum script.

Parameters

copy_operations (bool) – If True, the operations are also shallow copied. Otherwise, if False, the copied operations will simply be references to the original operations; changing the parameters of one script will likewise change the parameters of all copies.

Returns

a shallow copy of the quantum script

Return type

QuantumScript

draw(wire_order=None, show_all_wires=False, decimals=None, max_length=100, show_matrices=False)

Draw the quantum script as a circuit diagram. See tape_text() for more information.

Parameters
• wire_order (Sequence[Any]) – the order (from top to bottom) to print the wires of the circuit

• show_all_wires (bool) – If True, all wires, including empty wires, are printed.

• decimals (int) – How many decimal points to include when formatting operation parameters. Default None will omit parameters from operation labels.

• max_length (Int) – Maximum length of a individual line. After this length, the diagram will begin anew beneath the previous lines.

• show_matrices=False (bool) – show matrix valued parameters below all circuit diagrams

Returns

the circuit representation of the quantum script

Return type

str

expand(depth=1, stop_at=None, expand_measurements=False)

Expand all operations to a specific depth.

Parameters
• depth (int) – the depth the script should be expanded

• stop_at (Callable) – A function which accepts a queue object, and returns True if this object should not be expanded. If not provided, all objects that support expansion will be expanded.

• expand_measurements (bool) – If True, measurements will be expanded to basis rotations and computational basis measurements.

Example

Consider the following nested quantum script:

>>> prep = [qml.BasisState(np.array([1, 1]), wires=[0, 'a'])]
>>> nested_script = QuantumScript([qml.Rot(0.543, 0.1, 0.4, wires=0)])
>>> ops = [nested_script, qml.CNOT(wires=[0, 'a']), qml.RY(0.2, wires='a')]
>>> measurements = [qml.probs(wires=0), qml.probs(wires='a')]
>>> qscript = QuantumScript(ops, measurements, prep)


The nested structure is preserved:

>>> qscript.operations
<QuantumScript: wires=[0], params=3>,
CNOT(wires=[0, 'a']),
RY(0.2, wires=['a'])]


Calling .expand will return a script with all nested scripts expanded, resulting in a single script of quantum operations:

>>> new_qscript = qscript.expand(depth=2)
>>> new_qscript.operations
[PauliX(wires=[0]),
PauliX(wires=['a']),
RZ(0.543, wires=[0]),
RY(0.1, wires=[0]),
RZ(0.4, wires=[0]),
CNOT(wires=[0, 'a']),
RY(0.2, wires=['a'])]

classmethod from_queue(queue)

Construct a QuantumScript from an AnnotatedQueue.

fromkeys(value=None)

Create a new ordered dictionary with keys from iterable and values set to value.

get(key, default=None, /)

Return the value for key if key is in the dictionary, else default.

get_info(obj)

Retrieve the metadata for obj. Raises a QueuingError if obj is not in the queue.

get_operation(idx, return_op_index=False)

Returns the trainable operation, and the corresponding operation argument index, for a specified trainable parameter index.

Parameters
• idx (int) – the trainable parameter index

• return_op_index (bool) – Whether the function also returns the operation index.

Returns

tuple containing the corresponding operation, the operation index, and an integer representing the argument index, for the provided trainable parameter.

Return type

tuple[Operation, int, int]

get_parameters(trainable_only=True, operations_only=False, **kwargs)

Return the parameters incident on the quantum script operations.

The returned parameters are provided in order of appearance on the quantum script.

Parameters
• trainable_only (bool) – if True, returns only trainable parameters

• operations_only (bool) – if True, returns only the parameters of the operations excluding parameters to observables of measurements

Example

>>> ops = [qml.RX(0.432, 0), qml.RY(0.543, 0),
...        qml.CNOT((0,"a")), qml.RX(0.133, "a")]
>>> qscript = QuantumScript(ops, [qml.expval(qml.PauliZ(0))])


By default, all parameters are trainable and will be returned:

>>> qscript.get_parameters()
[0.432, 0.543, 0.133]


Setting the trainable parameter indices will result in only the specified parameters being returned:

>>> qscript.trainable_params = [1] # set the second parameter as trainable
>>> qscript.get_parameters()
[0.543]


The trainable_only argument can be set to False to instead return all parameters:

>>> qscript.get_parameters(trainable_only=False)
[0.432, 0.543, 0.133]

items()a set-like object providing a view on D’s items
keys()a set-like object providing a view on D’s keys
move_to_end(key, last=True)

Move an existing element to the end (or beginning if last is false).

Raise KeyError if the element does not exist.

pop(k[, d])v, remove specified key and return the corresponding

value. If key is not found, d is returned if given, otherwise KeyError is raised.

popitem(last=True)

Remove and return a (key, value) pair from the dictionary.

Pairs are returned in LIFO order if last is true or FIFO order if false.

remove(obj)

Remove obj from the queue. Passes silently if the object is not in the queue.

set_parameters(params, trainable_only=True)

Set the parameters incident on the quantum script operations.

Parameters
• params (list[float]) – A list of real numbers representing the parameters of the quantum operations. The parameters should be provided in order of appearance in the quantum script.

• trainable_only (bool) – if True, set only trainable parameters

Example

>>> ops = [qml.RX(0.432, 0), qml.RY(0.543, 0),
...        qml.CNOT((0,"a")), qml.RX(0.133, "a")]
>>> qscript = QuantumScript(ops, [qml.expval(qml.PauliZ(0))])


By default, all parameters are trainable and can be modified:

>>> qscript.set_parameters([0.1, 0.2, 0.3])
>>> qscript.get_parameters()
[0.1, 0.2, 0.3]


Setting the trainable parameter indices will result in only the specified parameters being modifiable. Note that this only modifies the number of parameters that must be passed.

>>> qscript.trainable_params = [0, 2] # set the first and third parameter as trainable
>>> qscript.set_parameters([-0.1, 0.5])
>>> qscript.get_parameters(trainable_only=False)
[-0.1, 0.2, 0.5]


The trainable_only argument can be set to False to instead set all parameters:

>>> qscript.set_parameters([4, 1, 6], trainable_only=False)
>>> qscript.get_parameters(trainable_only=False)
[4, 1, 6]

setdefault(key, default=None)

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

shape(device)

Produces the output shape of the quantum script by inspecting its measurements and the device used for execution.

Note

The computed shape is not stored because the output shape may be dependent on the device

used for execution.

Parameters

device (pennylane.Device) – the device that will be used for the script execution

Raises

ValueError – raised for unsupported cases for example when the script contains heterogeneous measurements

Returns

the output shape(s) of the quantum script result

Return type

Union[tuple[int], list[tuple[int]]]

Example:

>>> dev = qml.device('default.qubit', wires=2)
>>> qs = QuantumScript(measurements=[qml.state()])
>>> qs.shape(dev)
(1, 4)

to_openqasm(wires=None, rotations=True, measure_all=True, precision=None)

Serialize the circuit as an OpenQASM 2.0 program.

Measurements are assumed to be performed on all qubits in the computational basis. An optional rotations argument can be provided so that output of the OpenQASM circuit is diagonal in the eigenbasis of the quantum script’s observables. The measurement outputs can be restricted to only those specified in the script by setting measure_all=False.

Note

The serialized OpenQASM program assumes that gate definitions in qelib1.inc are available.

Parameters
• wires (Wires or None) – the wires to use when serializing the circuit

• rotations (bool) – in addition to serializing user-specified operations, also include the gates that diagonalize the measured wires such that they are in the eigenbasis of the circuit observables.

• measure_all (bool) – whether to perform a computational basis measurement on all qubits or just those specified in the script

• precision (int) – decimal digits to display for parameters

Returns

OpenQASM serialization of the circuit

Return type

str

unwrap()

A context manager that unwraps a quantum script with tensor-like parameters to NumPy arrays.

Returns

the unwrapped quantum script

Return type

QuantumScript

Example

>>> with tf.GradientTape():
...     qscript = QuantumScript([qml.RX(tf.Variable(0.1), 0),
...                             qml.RY(tf.constant(0.2), 0),
...                             qml.RZ(tf.Variable(0.3), 0)])
...     with qscript.unwrap():
...         print("Trainable params:", qscript.trainable_params)
...         print("Unwrapped params:", qscript.get_parameters())
Trainable params: [0, 2]
Unwrapped params: [0.1, 0.3]
>>> qscript.get_parameters()
[<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.1>,
<tf.Tensor: shape=(), dtype=float32, numpy=0.2>,
<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.3>]

update([E, ]**F)None.  Update D from dict/iterable E and F.

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

update_info(obj, **kwargs)

Update obj’s metadata with kwargs if it exists in the queue.

values()an object providing a view on D’s values

Using PennyLane

Development

API

Internals