catalyst.passes.merge_ppr_ppm¶
- merge_ppr_ppm(qnode=None, *, max_pauli_size=0)[source]¶
Specify that the MLIR compiler pass for absorbing Clifford Pauli Product Rotation (PPR) operations, \(\exp{iP\tfrac{\pi}{4}}\), into the final Pauli Product Measurement (PPM) will be applied.
For more information regarding to PPM, check out the compilation hub.
- Parameters:
fn (QNode) – QNode to apply the pass to
max_pauli_size (int) – The maximum size of the Pauli strings after merging.
- Returns:
~.QNode
Example
In this example, the Clifford+T gates will be converted into PPRs first, then the Clifford PPRs will be commuted past the non-Clifford PPR, and finally the Clifford PPRs will be absorbed into the Pauli Product Measurements.
import pennylane as qml from catalyst import qjit, measure ppm_passes = [("PPM",["to-ppr", "commute-ppr","merge-ppr-ppm",])] @qjit(pipelines=ppm_passes, keep_intermediate=True, target="mlir") @qml.qnode(qml.device("lightning.qubit", wires=1)) def circuit(): qml.H(0) qml.T(0) return measure(0) print(circuit.mlir_opt)
Example MLIR Representation:
. . . %2 = qec.ppr ["X"](8) %1 : !quantum.bit %mres, %out_qubits = qec.ppm ["X"] %2 : !quantum.bit . . .
If a merging resulted in a PPM acting on more than max_pauli_size qubits (here, max_pauli_size = 2), that merging would be skipped.
from catalyst import measure, qjit from catalyst.passes import to_ppr, merge_ppr_ppm pips = [("pipe", ["enforce-runtime-invariants-pipeline"])] @qjit(pipelines=pips, target="mlir") @to_ppr @merge_ppr_ppm(max_pauli_size=2) @qml.qnode(qml.device("lightning.qubit", wires=3)) def circuit(): qml.CNOT([1, 2]) qml.CNOT([0, 1]) qml.CNOT([0, 2]) return measure(0), measure(1), measure(2) print(circuit.mlir_opt)
Example MLIR Representation:
. . . %3:2 = qec.ppr ["Z", "X"](4) %1, %2 : !quantum.bit, !quantum.bit . . . %mres, %out_qubits:2 = qec.ppm ["Y", "Z"](-1) %3#1, %4 : !quantum.bit, !quantum.bit . . .