qml.tape.QuantumTape¶

class
QuantumTape
(name=None, do_queue=True)[source]¶ Bases:
pennylane.queuing.AnnotatedQueue
A quantum tape recorder, that records, validates and executes variational quantum programs.
 Parameters
name (str) – a name given to the quantum tape
do_queue (bool) – Whether to queue this tape in a parent tape context.
Example
import pennylane.tape 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
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']) >>> qml.execute([tape], dev, gradient_fn=None) [array([0.77750694])]
The trainable parameters of the tape can be explicitly set, and the values of the parameters modified inplace:
>>> 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.
Attributes
Returns the quantum circuit recorded by the tape.
Alias to
get_parameters()
andset_parameters()
for backwards compatibilities with operations.Returns the gates that diagonalize the measured wires such that they are in the eigenbasis of the circuit observables.
Returns a directed acyclic graph representation of the recorded quantum circuit:
returns an integer hash uniquely representing the quantum tape
automatic differentiation interface used by the quantum tape (if any)
Returns the measurements on the quantum tape.
Returns the number of trainable parameters on the quantum tape.
Returns the expected numeric type of the tape result by inspecting its measurements.
Returns the observables on the quantum tape.
Returns the operations on the quantum tape.
The (inferred) output dimension of the quantum tape.
Returns a list of objects in the annotated queue
Resource information about a quantum circuit.
Store or return a list containing the indices of parameters that support differentiability.

circuit
¶ Returns the quantum circuit recorded by the tape.
The circuit is created with the assumptions that:
The
operations
attribute contains quantum operations and midcircuit measurements andThe
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 as recorded by the tape.
 Return type
list[Operator, MeasurementProcess]

data
¶ Alias to
get_parameters()
andset_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]

graph
¶ Returns a directed acyclic graph representation of the recorded quantum circuit:
>>> tape.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

hash
¶ returns an integer hash uniquely representing the quantum tape
 Type
int

interface
¶ automatic differentiation interface used by the quantum tape (if any)
 Type
str, None

measurements
¶ Returns the measurements on the quantum tape.
 Returns
list of recorded measurement processess
 Return type
list[MeasurementProcess]
Example
with 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]))
>>> tape.measurements [expval(PauliZ(wires=[0]))]

num_params
¶ Returns the number of trainable parameters on the quantum tape.

numeric_type
¶ Returns the expected numeric type of the tape result by inspecting its measurements.
 Raises
TapeError – raised for unsupported cases for example when the tape contains heterogeneous measurements
 Returns
the numeric type corresponding to the result type of the tape
 Return type
type
Example:
dev = qml.device("default.qubit", wires=2) a = np.array([0.1, 0.2, 0.3]) def func(a): qml.RY(a[0], wires=0) qml.RX(a[1], wires=0) qml.RY(a[2], wires=0) with qml.tape.QuantumTape() as tape: func(a) qml.state()
>>> tape.numeric_type complex

observables
¶ Returns the observables on the quantum tape.
 Returns
list of recorded quantum operations
 Return type
list[Observable]
Example
with 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]))
>>> tape.observables [expval(PauliZ(wires=[0]))]

operations
¶ Returns the operations on the quantum tape.
 Returns
recorded quantum operations
 Return type
list[Operation]
Example
with 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]))
>>> tape.operations [RX(0.432, wires=[0]), RY(0.543, wires=[0]), CNOT(wires=[0, 'a']), RX(0.133, wires=['a'])]

output_dim
¶ The (inferred) output dimension of the quantum tape.

queue
¶ Returns a list of objects in the annotated queue

specs
¶ Resource information about a quantum circuit.
 Returns
dictionaries that contain tape specifications
 Return type
dict[str, Union[defaultdict,int]]
Example
with qml.tape.QuantumTape() as tape: qml.Hadamard(wires=0) qml.RZ(0.26, wires=1) qml.CNOT(wires=[1, 0]) qml.Rot(1.8, 2.7, 0.2, wires=0) qml.Hadamard(wires=1) qml.CNOT(wires=[0, 1]) qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
Asking for the specs produces a dictionary as shown below:
>>> tape.specs['gate_sizes'] defaultdict(int, {1: 4, 2: 2}) >>> tape.specs['gate_types'] defaultdict(int, {'Hadamard': 2, 'RZ': 1, 'CNOT': 2, 'Rot': 1})
As
defaultdict
objects, any key not present in the dictionary returns 0.>>> tape.specs['gate_types']['RX'] 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 methodget_parameters()
.Note
For devices that support native backpropagation (such as
default.qubit.tf
anddefault.qubit.autograd
), this property contains no relevant information when using backpropagation to compute gradients.Example
with 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]))
>>> tape.trainable_params [0, 1, 2] >>> tape.trainable_params = [0] # set only the first parameter as trainable >>> tape.get_parameters() [0.432]
Methods
Returns the currently active queuing context.
adjoint
()Create a tape that is the adjoint of this one.
append
(obj, **kwargs)Append an object to this QueuingContext instance.
copy
([copy_operations])Returns a shallow copy of the quantum tape.
draw
([wire_order, show_all_wires, decimals, …])Draw the quantum tape as a circuit diagram.
expand
([depth, stop_at, expand_measurements])Expand all operations in the processed queue to a specific depth.
get_info
(obj)Retrieves information of an object in the queue instance.
get_operation
(idx)Returns the trainable operation, and the corresponding operation argument index, for a specified trainable parameter index.
get_parameters
([trainable_only])Return the parameters incident on the tape operations.
inv
()Inverts the processed operations.
Whether a queuing context is active and recording operations
remove
(obj)Remove an object from this QueuingContext instance.
set_parameters
(params[, trainable_only])Set the parameters incident on the tape operations.
shape
(device)Produces the output shape of the tape by inspecting its measurements and the device used for execution.
Context manager to temporarily stop recording operations onto the tape.
to_openqasm
([wires, rotations, measure_all, …])Serialize the circuit as an OpenQASM 2.0 program.
unwrap
()A context manager that unwraps a tape with tensorlike parameters to NumPy arrays.
update_info
(obj, **kwargs)Updates information of an object in the queue instance.

classmethod
active_context
()¶ Returns the currently active queuing context.

adjoint
()[source]¶ Create a tape that is the adjoint of this one.
Adjointed tapes are the conjugated and transposed version of the original tapes. Adjointed ops are equivalent to the inverted operation for unitary gates.
 Returns
the adjointed tape
 Return type
QuantumTape

append
(obj, **kwargs)¶ Append an object to this QueuingContext instance.
 Parameters
obj – The object to be appended

copy
(copy_operations=False)[source]¶ Returns a shallow copy of the quantum tape.
 Parameters
copy_operations (bool) – If True, the tape operations are also shallow copied. Otherwise, if False, the copied tape operations will simply be references to the original tape operations; changing the parameters of one tape will likewise change the parameters of all copies.
 Returns
a shallow copy of the tape
 Return type

draw
(wire_order=None, show_all_wires=False, decimals=None, max_length=100, show_matrices=False)[source]¶ Draw the quantum tape 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 tape
 Return type
str

expand
(depth=1, stop_at=None, expand_measurements=False)[source]¶ Expand all operations in the processed queue to a specific depth.
 Parameters
depth (int) – the depth the tape 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 tape:
with QuantumTape() as tape: qml.BasisState(np.array([1, 1]), wires=[0, 'a']) with QuantumTape() as tape2: qml.Rot(0.543, 0.1, 0.4, wires=0) qml.CNOT(wires=[0, 'a']) qml.RY(0.2, wires='a') qml.probs(wires=0), qml.probs(wires='a')
The nested structure is preserved:
>>> tape.operations [BasisState(array([1, 1]), wires=[0, 'a']), <QuantumTape: wires=[0], params=3>, CNOT(wires=[0, 'a']), RY(0.2, wires=['a'])]
Calling
.expand
will return a tape with all nested tapes expanded, resulting in a single tape of quantum operations:>>> new_tape = tape.expand(depth=2) >>> new_tape.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'])]

get_info
(obj)¶ Retrieves information of an object in the queue instance.

get_operation
(idx)[source]¶ Returns the trainable operation, and the corresponding operation argument index, for a specified trainable parameter index.
 Parameters
idx (int) – the trainable parameter index
 Returns
tuple containing the corresponding operation, and an integer representing the argument index, for the provided trainable parameter.
 Return type
tuple[Operation, int]

get_parameters
(trainable_only=True, **kwargs)[source]¶ Return the parameters incident on the tape operations.
The returned parameters are provided in order of appearance on the tape.
 Parameters
trainable_only (bool) – if True, returns only trainable parameters
Example
with 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]))
By default, all parameters are trainable and will be returned:
>>> tape.get_parameters() [0.432, 0.543, 0.133]
Setting the trainable parameter indices will result in only the specified parameters being returned:
>>> tape.trainable_params = [1] # set the second parameter as trainable >>> tape.get_parameters() [0.543]
The
trainable_only
argument can be set toFalse
to instead return all parameters:>>> tape.get_parameters(trainable_only=False) [0.432, 0.543, 0.133]

inv
()[source]¶ Inverts the processed operations.
Inversion is performed inplace.
Note
This method only inverts the quantum operations/unitary recorded by the quantum tape; state preparations and measurements are left unchanged.
Example
with QuantumTape() as tape: qml.BasisState(np.array([1, 1]), wires=[0, 'a']) qml.RX(0.432, wires=0) qml.Rot(0.543, 0.1, 0.4, wires=0).inv() qml.CNOT(wires=[0, 'a']) qml.probs(wires=0), qml.probs(wires='a')
This tape has the following properties:
>>> tape.operations [BasisState(array([1, 1]), wires=[0, 'a']), RX(0.432, wires=[0]), Rot.inv(0.543, 0.1, 0.4, wires=[0]), CNOT(wires=[0, 'a'])] >>> tape.get_parameters() [array([1, 1]), 0.432, 0.543, 0.1, 0.4]
Here, let’s set some trainable parameters:
>>> tape.trainable_params = [1, 2] >>> tape.get_parameters() [0.432, 0.543]
Inverting the tape:
>>> tape.inv() >>> tape.operations [BasisState(array([1, 1]), wires=[0, 'a']), CNOT.inv(wires=[0, 'a']), Rot(0.543, 0.1, 0.4, wires=[0]), RX.inv(0.432, wires=[0])]
Tape inversion also modifies the order of tape parameters:
>>> tape.get_parameters(trainable_only=False) [array([1, 1]), 0.543, 0.1, 0.4, 0.432] >>> tape.get_parameters(trainable_only=True) [0.543, 0.432] >>> tape.trainable_params [1, 4]

classmethod
recording
()¶ Whether a queuing context is active and recording operations

remove
(obj)¶ Remove an object from this QueuingContext instance.
 Parameters
obj – the object to be removed

set_parameters
(params, trainable_only=True)[source]¶ Set the parameters incident on the tape 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 tape.
trainable_only (bool) – if True, set only trainable parameters
Example
with 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]))
By default, all parameters are trainable and can be modified:
>>> tape.set_parameters([0.1, 0.2, 0.3]) >>> tape.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.
>>> tape.trainable_params = [0, 2] # set the first and third parameter as trainable >>> tape.set_parameters([0.1, 0.5]) >>> tape.get_parameters(trainable_only=False) [0.1, 0.2, 0.5]
The
trainable_only
argument can be set toFalse
to instead set all parameters:>>> tape.set_parameters([4, 1, 6], trainable_only=False) >>> tape.get_parameters(trainable_only=False) [4, 1, 6]

shape
(device)[source]¶ Produces the output shape of the tape 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 (Device) – the device that will be used for the tape execution
 Raises
TapeError – raised for unsupported cases for example when the tape contains heterogeneous measurements
 Returns
the output shape(s) of the tape result
 Return type
Union[tuple[int], list[tuple[int]]]
Example:
dev = qml.device("default.qubit", wires=2) a = np.array([0.1, 0.2, 0.3]) def func(a): qml.RY(a[0], wires=0) qml.RX(a[1], wires=0) qml.RY(a[2], wires=0) with qml.tape.QuantumTape() as tape: func(a) qml.state()
>>> tape.shape(dev) (1, 4)

stop_recording
()[source]¶ Context manager to temporarily stop recording operations onto the tape. This is useful is scratch space is needed.
Example
>>> with qml.tape.QuantumTape() as tape: ... qml.RX(0, wires=0) ... with tape.stop_recording(): ... qml.RY(1.0, wires=1) ... qml.RZ(2, wires=1) >>> tape.operations [RX(0, wires=[0]), RZ(2, wires=[1])]

to_openqasm
(wires=None, rotations=True, measure_all=True, precision=None)[source]¶ 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 tape’s observables. The measurement outputs can be restricted to only those specified in the tape by settingmeasure_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 userspecified 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 tape
precision (int) – decimal digits to display for parameters
 Returns
OpenQASM serialization of the circuit
 Return type
str

unwrap
()[source]¶ A context manager that unwraps a tape with tensorlike parameters to NumPy arrays.
 Parameters
tape (QuantumTape) – the quantum tape to unwrap
 Returns
the unwrapped quantum tape
 Return type
Example
>>> with tf.GradientTape(): ... with qml.tape.QuantumTape() as tape: ... qml.RX(tf.Variable(0.1), wires=0) ... qml.RY(tf.constant(0.2), wires=0) ... qml.RZ(tf.Variable(0.3), wires=0) ... with tape.unwrap(): ... print("Trainable params:", tape.trainable_params) ... print("Unwrapped params:", tape.get_parameters()) Trainable params: [0, 2] Unwrapped params: [0.1, 0.3] >>> print("Original parameters:", tape.get_parameters()) Original parameters: [<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.1>, <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.3>]

update_info
(obj, **kwargs)¶ Updates information of an object in the queue instance.
Contents
Using PennyLane
Development
API
Downloads