catalyst.passes.reduce_t_depth

reduce_t_depth(qnode)[source]

A quantum compilation pass that reduces the depth and count of non-Clifford Pauli product rotation (PPR, \(P(\theta) = \exp(-iP\theta)\)) operators (e.g., T gates) by commuting PPRs in adjacent layers and merging compatible ones (a layer comprises PPRs that mutually commute). For more details, see Figure 6 of A Game of Surface Codes.

Note

This transform requires decorating the workflow with @qml.qjit. In addition, the circuits generated by this pass are currently executable on lightning.qubit or null.qubit (for mock-execution).

Lastly, the pennylane.transforms.to_ppr() transform must be applied before reduce_t_depth.

Parameters:

qnode (QNode) – QNode to apply the pass to.

Returns:

Returns decorated QNode.

Return type:

QNode

See also

to_ppr(), commute_ppr(), merge_ppr_ppm(), ppr_to_ppm(), ppm_compilation(), decompose_arbitrary_ppr()

Note

For better compatibility with other PennyLane functionality, ensure that PennyLane program capture is enabled with @qjit(capture=True).

Example

In the example below, after performing the to_ppr() and merge_ppr_ppm() passes, the circuit contains a depth of four of non-Clifford PPRs. Subsequently applying the reduce_t_depth pass will move PPRs around via commutation, resulting in a circuit with a smaller PPR depth.

Specifically, in the circuit below, the Pauli-\(X\) PPR (\(\exp(iX\tfrac{\pi}{8})\)) on qubit Q1 will be moved to the first layer, which results in a depth of three non-Clifford PPRs.

Consider the following example:

import pennylane as qml
import jax.numpy as jnp

@qml.qjit(capture=True)
@qml.transforms.reduce_t_depth
@qml.transforms.to_ppr
@qml.qnode(qml.device("null.qubit", wires=4))
def circuit():
    qml.PauliRot(jnp.pi / 4, pauli_word="Z", wires=1)
    qml.PauliRot(-jnp.pi / 4, pauli_word="XYZ", wires=[0, 2, 3])
    qml.PauliRot(-jnp.pi / 2, pauli_word="XYZY", wires=[0, 1, 2, 3])
    qml.PauliRot(jnp.pi / 4, pauli_word="XZX", wires=[0, 1, 3])
    qml.PauliRot(-jnp.pi / 4, pauli_word="XZY", wires=[0, 1, 2])

    return qml.expval(qml.Z(0))

The reduce_t_depth compilation pass will rearrange the last three PPRs in the above circuit to reduce the non-Clifford PPR depth. This is best seen with the catalyst.draw_graph() function:

>>> import catalyst
>>> num_passes = 2
>>> fig1, _ = catalyst.draw_graph(circuit, level=num_passes-1)() 
>>> fig2, _ = catalyst.draw_graph(circuit, level=num_passes)() 

Without reduce_t_depth applied:

>>> fig1.savefig('path_to_file1.png', dpi=300, bbox_inches="tight") 
Graphical representation of circuit without ``reduce_t_depth``

With reduce_t_depth applied:

>>> fig2.savefig('path_to_file2.png', dpi=300, bbox_inches="tight") 
Graphical representation of circuit with ``reduce_t_depth``