Stim Clifford transpiler

Install the optional Stim integration before importing this module:

uv add "graphqomb[stim]"

The transpiler normalizes Stim Clifford circuits to GraphQOMB’s unitary basis: the four Clifford J(angle) gates plus CZ. Each single-qubit basis gate is one graphqomb.gates.J primitive, i.e. one XY-plane Pauli measurement in MBQC (gate names use algebraic matrix order):

Basis gate

Definition

Measurement

Stim name

H

J(0)

X+

H

HS

H S = J(pi/2)

Y-

C_XNYZ

HZ

H Z = J(pi)

X-

SQRT_Y

HS_DAG

H S† = J(-pi/2)

Y+

C_XYZ

The gate convention is J(theta) = H diag(1, exp(i theta)); its MBQC measurement angle is alpha = -theta in the basis (|0> +/- exp(i alpha)|1>)/sqrt(2). Thus J(pi/2) = HS uses Y-, and S = J(0) J(pi/2) in matrix order (time order: J(pi/2), then J(0)). Outcome-dependent Pauli corrections complete the teleportation.

from graphqomb.stim_glue.transpiler import transpile

normalized = transpile("S_DAG 0\nCX 0 1", optimize=True)

The transpiler supports all fixed one- and two-qubit Clifford gates exposed by Stim, arbitrary-length SPP and SPP_DAG rotations, nested REPEAT blocks, Pauli reset and measurement boundaries, and coordinate/TICK annotations. DETECTOR, OBSERVABLE_INCLUDE, and MPAD are preserved verbatim as optimization barriers; the standalone transpiler does not interpret their measurement-record targets. Noise, non-Clifford instructions, measurement-reset instructions, MPP measurements, and classically controlled targets are rejected.

Hermitian SPP products may contain the same qubit more than once. Their ordered Pauli factors and target inversions retain Stim’s product semantics.

With optimize=True, every maximal single-qubit gate run is replaced by the shortest equivalent word over the four J gates, so any single-qubit Clifford costs at most three J primitives (three graph nodes in the compiled pattern). Optimization repeatedly scans a barrier-free block, so very large circuits without TICK or annotation barriers can take superlinear time. The importer normalizes each unitary TICK block independently, so TICK-partitioned inputs bound this cost.

The Stim importer resolves the preserved detector and observable records, handles MPP operations, and applies GraphQOMB’s circuit-level noise policy.

API reference

Transpile Stim Clifford circuits into GraphQOMB’s Clifford J/CZ basis.

This module provides:

graphqomb.stim_glue.transpiler.STIM_GATE_J_ANGLES: dict[str, float] = {'C_XNYZ': 1.5707963267948966, 'C_XYZ': -1.5707963267948966, 'H': 0.0, 'SQRT_Y': 3.141592653589793}

Map of each single-qubit basis gate, by its Stim spelling, to the angle of the one J(angle) = H Rz(angle) primitive implementing it.

The corresponding XY-plane measurement angles are the negatives of the gate angles: X+ (H), Y- (HS), X- (HZ), and Y+ (HS_DAG).

exception graphqomb.stim_glue.transpiler.UnsupportedInstructionError[source]

Bases: ValueError

Raised when an instruction cannot be represented by the supported basis.

graphqomb.stim_glue.transpiler.transpile(circuit, *, optimize=False, preserved_measurement_qubits=frozenset({}))[source]

Transpile a Stim Clifford circuit into the Clifford J/CZ gate basis.

The single-qubit basis gates are the four Clifford J(angle) gates, i.e. the XY-plane Pauli measurements: H = J(0) (X+), HS = J(pi/2) (Y-, Stim’s C_XNYZ), HZ = J(pi) (X-, Stim’s SQRT_Y), and HS_DAG = J(-pi/2) (Y+, Stim’s C_XYZ).

Parameters:
  • circuit (stim.Circuit | str) – A Stim circuit or Stim circuit text. REPEAT blocks are handled recursively. TICK, QUBIT_COORDS, SHIFT_COORDS, DETECTOR, OBSERVABLE_INCLUDE, and MPAD instructions are preserved verbatim because they do not affect the quantum operation. Measurement-record targets are not interpreted by this standalone parser.

  • optimize (bool, optional) – Remove redundant basis gates and simplify gates adjacent to R/RX/RY and M/MX/MY boundaries after transpilation.

  • preserved_measurement_qubits (collections.abc.Set[int], optional) – Qubits whose post-measurement state must survive the optimized circuit. Measurements on these qubits are never folded into a rewritten Pauli basis, so single-qubit gates ahead of them stay explicit.

Returns:

A new circuit containing only Clifford J gates, CZ, supported boundaries, and preserved instructions.

Return type:

stim.Circuit

graphqomb.stim_glue.transpiler.optimize_j_cz(circuit, *, preserved_measurement_qubits=frozenset({}))[source]

Remove redundant Clifford J and CZ gates.

Every maximal run of single-qubit basis gates on one qubit is replaced by the shortest word over the four Clifford J gates (H, HS, HZ, HS_DAG) with the same Clifford action; any single-qubit Clifford needs at most three J gates. CZ pairs cancel across commuting operations on other qubits. Single-qubit gates at R/RX/RY and M/MX/MY boundaries are folded into Pauli preparations or measurements when safe. TICK, coordinate annotations, DETECTOR, OBSERVABLE_INCLUDE, and MPAD are preserved verbatim and treated as optimization barriers. The repeated simplification passes are intended for TICK-bounded blocks; unusually large barrier-free inputs can take superlinear time.

Parameters:
  • circuit (stim.Circuit | str) – A circuit in the Clifford J/CZ basis.

  • preserved_measurement_qubits (collections.abc.Set[int], optional) – Qubits whose post-measurement state must survive the optimized circuit. Measurements on these qubits are never folded into a rewritten Pauli basis.

Returns:

The optimized circuit.

Return type:

stim.Circuit