catalyst.passes.ppr_to_ppm¶
- ppr_to_ppm(qnode=None, *, decompose_method='auto-corrected', avoid_y_measure=False)[source]¶
Specify that the MLIR compiler passes for decomposing Pauli Product rotations (PPR) , \(\exp(-iP\theta)\), into Pauli Pauli measurements (PPM) will be applied.
This pass is used to decompose both non-Clifford and Clifford PPRs into PPMs. The non-Clifford PPRs (\(\theta = \tfrac{\pi}{8}\)) are decomposed first, and then Clifford PPRs (\(\theta = \tfrac{\pi}{4}\)) are decomposed. Non-Clifford decomposition can be performed in one of two ways:
"clifford-corrected"
or"auto-corrected"
, by default the latter is used. Both methods are based on A Game of Surface Codes, figures 7 and 17(b) respectively.- Parameters:
qnode (QNode, optional) – QNode to apply the pass to. If None, returns a decorator.
decompose_method (str, optional) – The method to use for decomposing non-Clifford PPRs. Options are
"auto-corrected"
and"clifford-corrected"
. Defaults to"auto-corrected"
."auto-corrected"
uses an additional measurement for correction."clifford-corrected"
uses a Clifford rotation for correction.avoid_y_measure (bool) – Rather than performing a Pauli-Y measurement for Clifford rotations (sometimes more costly), a \(Y\) state (\(Y\vert 0 \rangle\)) is used instead (requires \(Y\) state preparation). Defaults to
False
.
- Returns:
- Returns decorated QNode if qnode is provided,
otherwise returns a decorator.
- Return type:
QNode or callable
Example
This example shows the sequence of passes that will be applied. The last pass will convert the non-Clifford PPR into Pauli Product Measurements.
import pennylane as qml from catalyst import qjit, measure from catalyst.passes import to_ppr, commute_ppr, merge_ppr_ppm, ppr_to_ppm pipeline = [("pipe", ["enforce-runtime-invariants-pipeline"])] @qjit(pipelines=pipeline, target="mlir") @to_ppr @commute_ppr @merge_ppr_ppm @ppr_to_ppm @qml.qnode(qml.device("null.qubit", wires=2)) def circuit(): qml.H(0) qml.T(0) qml.CNOT([0, 1]) return measure(0), measure(1) print(circuit.mlir_opt)
Example MLIR Representation:
. . . %5 = qec.fabricate zero : !quantum.bit %6 = qec.fabricate magic : !quantum.bit %mres, %out_qubits:2 = qec.ppm ["X", "Z"] %1, %6 : !quantum.bit, !quantum.bit %mres_0, %out_qubits_1:2 = qec.ppm ["Z", "Y"] %5, %out_qubits#1 : !quantum.bit, !quantum.bit %mres_2, %out_qubits_3 = qec.ppm ["X"] %out_qubits_1#1 : !quantum.bit %mres_4, %out_qubits_5 = qec.select.ppm(%mres, ["X"], ["Z"]) %out_qubits_1#0 : !quantum.bit %7 = arith.xori %mres_0, %mres_2 : i1 %8 = qec.ppr ["X"](2) %out_qubits#0 cond(%7) : !quantum.bit . . .