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.
Note
This transform requires decorating the workflow with
@qml.qjit. In addition, the circuits generated by this pass are currently not executable on any backend. This pass is only for Pauli-based-computation analysis with thenull.qubitdevice and potential future execution when a suitable backend is available.Lastly, the
pennylane.transforms.to_ppr()transform must be applied beforecommute_ppr.For more information on PPRs, check out the Compilation Hub.
- Args:
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. Note that the defaultmax_pauli_size=0indicates no limit.- Returns:
See also
to_ppr(),merge_ppr_ppm(),ppr_to_ppm(),ppm_compilation(),reduce_t_depth(),decompose_arbitrary_ppr()Note
For better compatibility with other PennyLane functionality, ensure that PennyLane program capture is enabled with
@qjit(capture=True).Example
The
commute_pprcompilation pass can be applied as a decorator on a QNode:import pennylane as qml import jax.numpy as jnp @qml.qjit(capture=True) @qml.transforms.commute_ppr(max_pauli_size=2) @qml.transforms.to_ppr @qml.qnode(qml.device("lightning.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))
>>> circuit() Array(-1.11022302e-16, dtype=float64) >>> print(qml.specs(circuit, level=2)()) Device: lightning.qubit Device wires: 2 Shots: Shots(total=None) Level: commute-ppr Wire allocations: 2 Total gates: 7 Gate counts: - PPR-pi/8-w1: 1 - PPR-pi/4-w1: 5 - PPR-pi/4-w2: 1 Measurements: - expval(PauliZ): 1 Depth: Not computed
In the example above, the Clifford PPRs (
PauliRotinstances with an angle of rotation of \(\tfrac{\pi}{2}\)) will be commuted past the non-Clifford PPR (PauliRotinstances with an angle of rotation of \(\tfrac{\pi}{4}\)). In the above output,PPR-theta-w<int>denotes the type of PPR present in the circuit, wherethetais the PPR angle (\(\theta\)) andw<int>denotes the PPR weight (the number of qubits it acts on, or the length of the Pauli word).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.