catalyst.passes.ppm_compilation¶
- ppm_compilation(qnode=None, *, decompose_method='pauli-corrected', avoid_y_measure=False, max_pauli_size=0)[source]¶
A quantum compilation pass that transforms Clifford+T gates into Pauli product measurements (PPMs).
This pass combines multiple sub-passes:
to_ppr(): Converts gates into Pauli Product Rotations (PPRs)commute_ppr(): Commutes PPRs past non-Clifford PPRsmerge_ppr_ppm(): Merges PPRs into Pauli Product Measurements (PPMs)ppr_to_ppm(): Decomposes PPRs into PPMs
The
avoid_y_measureanddecompose_methodarguments are passed to theppr_to_ppm()pass. Themax_pauli_sizeargument is passed to thecommute_ppr()andmerge_ppr_ppm()passes.For more information on PPRs and PPMs, check out the Compilation Hub.
Note
The circuits that generated from this pass are currently not executable on any backend. This pass is only for analysis with the
null.qubitdevice and potential future execution when a suitable backend is available.- 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
"pauli-corrected","auto-corrected", and"clifford-corrected". Defaults to"pauli-corrected"."pauli-corrected"uses a reactive measurement for correction that is based on Figure 13 in arXiv:2211.15465."auto-corrected"uses an additional measurement for correction that is based on Figure 7 in A Game of Surface Codes, and"clifford-corrected"uses a Clifford rotation for correction that is based on Figure 17(b) in A Game of Surface Codes.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). This is currently only supported when using the
"clifford-corrected"and"pauli-corrected"decomposition method. Defaults toFalse.max_pauli_size (int) – The maximum size of the Pauli strings after commuting or merging. Defaults to 0 (no limit).
- Returns:
Example
The
commute_pprcompilation pass can be applied as a dectorator on a QNode:import pennylane as qml from functools import partial qml.capture.enable() @qml.qjit(target="mlir") @partial(qml.transforms.ppm_compilation, decompose_method="clifford-corrected", max_pauli_size=2) @qml.qnode(qml.device("null.qubit", wires=2)) def circuit(): qml.H(0) qml.CNOT([0, 1]) qml.T(0) return
For clear and inspectable results, use
target="mlir"in theqjitdecorator, ensure that PennyLane’s program capture is enabled,pennylane.capture.enable(), and callppm_compilationfrom the PennyLane frontend (qml.transforms.ppm_compilation) instead of withcatalyst.passes.ppm_compilation.>>> print(qml.specs(circuit, level="all")()['resources']) { 'No transforms': ..., 'Before MLIR Passes (MLIR-0)': ..., 'ppm-compilation (MLIR-1)': Resources( num_wires=7, num_gates=18, gate_types=defaultdict(<class 'int'>, {'PPM-w2': 5, 'PPM-w1': 6, 'PPR-pi/2-w1': 5, 'PPM-w3': 1, 'PPR-pi/2-w2': 1}), gate_sizes=defaultdict(<class 'int'>, {2: 6, 1: 11, 3: 1}), depth=None, shots=Shots(total_shots=None, shot_vector=()) ) }
In the above output,
PPM-weightdenotes the type of PPM present in the circuit, whereweightis the PPM weight.PPR-theta-weightdenotes the type of PPR present in the circuit, wherethetais the PPR angle (\(\theta\)) andweightis the PPR weight. Note that \(\theta = \tfrac{\pi}{2}\) PPRs correspond to Pauli operators: \(P(\tfrac{\pi}{2}) = \exp(-iP\tfrac{\pi}{2}) = P\). Pauli operators can be commuted to the end of the circuit and absorbed into terminal measurements.Note that if a commutation or merge resulted in a PPR or PPN acting on more than
max_pauli_sizequbits (here,max_pauli_size = 2), that commutation or merge would be skipped.