catalyst.passes.commute_ppr¶
- commute_ppr(qnode=None, *, max_pauli_size=0)[source]¶
A quantum compilation pass that commutes Clifford Pauli product rotation (PPR) gates, \(\exp(-{iP\tfrac{\pi}{4}})\), past non-Clifford PPRs gates, \(\exp(-{iP\tfrac{\pi}{8}})\), where \(P\) is a Pauli word.
For more information on PPRs, 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:
fn (QNode) – QNode to apply the pass to.
max_pauli_size (int) – The maximum size of Pauli strings resulting from commutation. If a commutation results in a PPR that acts on more than
max_pauli_sizequbits, that commutation will not be performed.
- Returns:
Example
The
commute_pprcompilation pass can be applied as a dectorator on a QNode:import pennylane as qml from functools import partial import jax.numpy as jnp qml.capture.enable() @qml.qjit(target="mlir") @partial(qml.transforms.commute_ppr, max_pauli_size=2) @qml.qnode(qml.device("null.qubit", wires=2)) def circuit(): # equivalent to a Hadamard gate qml.PauliRot(jnp.pi / 2, pauli_word="Z", wires=0) qml.PauliRot(jnp.pi / 2, pauli_word="X", wires=0) qml.PauliRot(jnp.pi / 2, pauli_word="Z", wires=0) # equivalent to a CNOT gate qml.PauliRot(jnp.pi / 2, pauli_word="ZX", wires=[0, 1]) qml.PauliRot(-jnp.pi / 2, pauli_word="Z", wires=0) qml.PauliRot(-jnp.pi / 2, pauli_word="X", wires=1) # equivalent to a T gate qml.PauliRot(jnp.pi / 4, pauli_word="Z", wires=0) return qml.expval(qml.Z(0))
For clear and inspectable results, use
target="mlir"in theqjitdecorator, ensure that PennyLane’s program capture is enabled,pennylane.capture.enable(), and callcommute_pprfrom the PennyLane frontend (qml.transforms.commute_ppr) instead of withcatalyst.passes.commute_ppr.>>> print(qml.specs(circuit, level="all")()['resources']) { 'No transforms': ..., 'Before MLIR Passes (MLIR-0)': ..., 'commute-ppr (MLIR-1)': Resources( num_wires=2, num_gates=7, gate_types=defaultdict(<class 'int'>, {'PPR-pi/8-w1': 1, 'PPR-pi/4-w1': 5, 'PPR-pi/4-w2': 1}), gate_sizes=defaultdict(<class 'int'>, {1: 6, 2: 1}), depth=None, shots=Shots(total_shots=None, shot_vector=())) }
In the example above, the Clifford PPRs (
HandCNOT) will be commuted past the non-Clifford PPR (T). In the output above,PPR-theta-weightdenotes the type of PPR present in the circuit, wherethetais the PPR angle (\(\theta\)) andweightis the PPR weight.Note that if a commutation resulted in a PPR acting on more than
max_pauli_sizequbits (here,max_pauli_size = 2), that commutation would be skipped.