qml.transforms.ppm_compilation

ppm_compilation(tape=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).

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 the null.qubit device and potential future execution when a suitable backend is available.

This pass combines multiple sub-passes:

The avoid_y_measure and decompose_method arguments are passed to the ppr_to_ppm() pass. The max_pauli_size argument is passed to the commute_ppr() and merge_ppr_ppm() passes.

For more information on PPRs and PPMs, check out the Compilation Hub.

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 methods. Defaults to False.

  • max_pauli_size (int) – The maximum size of the Pauli strings after commuting or merging. Defaults to 0 (no limit).

Returns:

QNode

Note

For better compatibility with other PennyLane functionality, ensure that PennyLane program capture is enabled with pennylane.capture.enable().

Example

The ppm_compilation compilation pass can be applied as a decorator on a QNode:

import pennylane as qml

qml.capture.enable()

@qml.qjit(target="mlir")
@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 qml.expval(qml.Z(0))

To inspect programs compiled with ppm_compilation via specs(), ensure that target="mlir" is given in the qjit decorator.

>>> print(qml.specs(circuit, level=2)())
Device: null.qubit
Device wires: 2
Shots: Shots(total=None)
Level: 2

Resource specifications:
Total wire allocations: 8
Total gates: 22
Circuit depth: Not computed

Gate types:
    qec.fabricate: 1
    PPM: 14
    PPR-pi/2: 7

Measurements:
    expval(PauliZ): 1

In the above output, PPR-theta denotes the type of PPR present in the circuit, where theta is the PPR angle (\(\theta\)). 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 PPM acting on more than max_pauli_size qubits (here, max_pauli_size = 2), that commutation or merge would be skipped.