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.,
Tgates) 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
The circuits generated from this pass are currently only executable on the
lightning.qubitdevice with program capture enabled.- Parameters:
qnode (QNode) – QNode to apply the pass to.
- Returns:
Returns decorated QNode.
- Return type:
Example
In the example below, after performing the
catalyst.passes.to_ppr()andcatalyst.passes.merge_ppr_ppm()passes, the circuit contains a depth of four of non-Clifford PPRs. Subsequently applying thereduce_t_depthpass 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.
import pennylane as qml import catalyst p = [("my_pipe", ["quantum-compilation-stage"])] @qml.qjit(pipelines=p, target="mlir") @catalyst.passes.reduce_t_depth @catalyst.passes.merge_ppr_ppm @catalyst.passes.commute_ppr @catalyst.passes.to_ppr @qml.qnode(qml.device("null.qubit", wires=3)) def circuit(): n = 3 for i in range(n): qml.H(wires=i) qml.S(wires=i) qml.CNOT(wires=[i, (i + 1) % n]) qml.T(wires=i) qml.H(wires=i) qml.T(wires=i) return catalyst.measure(0), catalyst.measure(1), catalyst.measure(2)
>>> print(circuit.mlir_opt)
… %1 = quantum.extract %0[ 0] : !quantum.reg -> !quantum.bit %2 = quantum.extract %0[ 1] : !quantum.reg -> !quantum.bit // layer 1 %3 = pbc.ppr [“X”](8) %1 : !quantum.bit %4 = pbc.ppr [“X”](8) %2 : !quantum.bit
// layer 2 %5:2 = pbc.ppr [“Y”, “X”](8) %3, %4 : !quantum.bit, !quantum.bit %6 = quantum.extract %0[ 2] : !quantum.reg -> !quantum.bit %7:3 = pbc.ppr [“X”, “Y”, “X”](8) %5#0, %5#1, %6 : !quantum.bit, !quantum.bit, !quantum.bit %8 = pbc.ppr [“X”](8) %7#2 : !quantum.bit
// layer 3 %9:3 = pbc.ppr [“X”, “X”, “Y”](8) %7#0, %7#1, %8 : !quantum.bit, !quantum.bit, !quantum.bit
%mres, %out_qubits:3 = pbc.ppm [“X”, “X”, “Y”] %9#0, %9#1, %9#2 : i1, !quantum.bit, !quantum.bit, !quantum.bit %mres_0, %out_qubits_1:3 = pbc.ppm [“Y”, “X”, “X”] %out_qubits#0, %out_qubits#1, %out_qubits#2 : i1, !quantum.bit, !quantum.bit, !quantum.bit %mres_2, %out_qubits_3:3 = pbc.ppm [“X”, “Y”, “X”] %out_qubits_1#0, %out_qubits_1#1, %out_qubits_1#2 : i1, !quantum.bit, !quantum.bit, !quantum.bit …