catalyst.passes.reduce_t_depth¶
- reduce_t_depth(qnode)[source]¶
An MLIR compiler pass that reduces the depth and count of non-Clifford PPRs (e.g.,
T
gates) by commuting PPRs in adjacent layers and merging compatible ones (a layer comprises a set of PPRs that mutually commute). For more details, see the Figure 6 of A Game of Surface Codes.The impact can be measured using
catalyst.passes.ppm_specs
to compare the circuit depth before and after applying the pass. Theppm_specs
function provides detailed statistics includingdepth_pi8_ppr
(non-Clifford PPR depth) andpi8_ppr
(number of non-Clifford PPRs), allowing users to quantify the optimization achieved by the pass.- Parameters:
qnode (QNode) – QNode to apply the pass to.
- Returns:
Returns decorated QNode.
- Return type:
QNode
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_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.import pennylane as qml from catalyst import qjit, measure from catalyst.passes import to_ppr, commute_ppr, reduce_t_depth, merge_ppr_ppm pips = [("pipe", ["enforce-runtime-invariants-pipeline"])] @qjit(pipelines=pips, target="mlir") @reduce_t_depth @merge_ppr_ppm @commute_ppr @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 [measure(wires=i) for i in range(n)] print(circuit.mlir_opt)
Example MLIR Representation:
. . . %1 = quantum.extract %0[ 0] : !quantum.reg -> !quantum.bit %2 = quantum.extract %0[ 1] : !quantum.reg -> !quantum.bit // layer 1 %3 = qec.ppr ["X"](8) %1 : !quantum.bit %4 = qec.ppr ["X"](8) %2 : !quantum.bit // layer 2 %5 = quantum.extract %0[ 2] : !quantum.reg -> !quantum.bit %6:2 = qec.ppr ["Y", "X"](8) %3, %4 : !quantum.bit, !quantum.bit %7 = qec.ppr ["X"](8) %5 : !quantum.bit %8:3 = qec.ppr ["X", "Y", "X"](8) %6#0, %6#1, %7:!quantum.bit, !quantum.bit, !quantum.bit // layer 3 %9:3 = qec.ppr ["X", "X", "Y"](8) %8#0, %8#1, %8#2:!quantum.bit, !quantum.bit, !quantum.bit . . .