Skip to content

Python API Reference

Compilation

clifft.compile

compile(
    stim_text: str,
    postselection_mask: list[int] | None = None,
    expected_detectors: list[int] | None = None,
    expected_observables: list[int] | None = None,
    normalize_syndromes: bool = False,
    hir_passes: HirPassManager
    | None
    | _DefaultPasses = _DEFAULT_PASSES,
    input_format: Literal["stim", "qasm2"] = "stim",
) -> Program

Compile a quantum circuit string to an executable sampling program.

Ordinary compilation runs parse -> trace -> [HIR optimize], then plans and prepares the result as a reusable sampling program.

When normalize_syndromes=True, a noiseless reference shot is executed internally to extract expected detector and observable parities. Detectors and observables are then XOR-normalized so that 0 means 'matches noiseless reference' and 1 means 'error'.

Reference sampling removes stochastic and readout noise without checking determinism. Coherent error rotations remain; for these errors, supply expected parities from the intended ideal circuit instead.

Parameters:

Name Type Description Default
stim_text str

Circuit text in the format selected by input_format.

required
postselection_mask list[int] | None

Optional list of uint8 flags, one per detector. Detectors where mask[i] != 0 become post-selection checks that abort the shot early if their parity is non-zero.

None
expected_detectors list[int] | None

Optional noiseless reference parities for detectors.

None
expected_observables list[int] | None

Optional noiseless reference parities for observables.

None
normalize_syndromes bool

If True, auto-compute reference parities from a noiseless reference shot (mutually exclusive with explicit parities).

False
hir_passes HirPassManager | None | _DefaultPasses

HirPassManager to run on the HIR before lowering. Defaults to default_hir_pass_manager(). Pass None to skip.

_DEFAULT_PASSES
input_format Literal['stim', 'qasm2']

"stim" for Clifft's Stim-compatible syntax or "qasm2" for the supported unitary OpenQASM 2 subset.

'stim'
Source code in .venv/lib/python3.12/site-packages/clifft/__init__.py
def compile(
    stim_text: str,
    postselection_mask: list[int] | None = None,
    expected_detectors: list[int] | None = None,
    expected_observables: list[int] | None = None,
    normalize_syndromes: bool = False,
    hir_passes: HirPassManager | None | _DefaultPasses = _DEFAULT_PASSES,
    input_format: Literal["stim", "qasm2"] = "stim",
) -> Program:
    """Compile a quantum circuit string to an executable sampling program.

    Ordinary compilation runs parse -> trace -> [HIR optimize], then plans and
    prepares the result as a reusable sampling program.

    When ``normalize_syndromes=True``, a noiseless reference shot is
    executed internally to extract expected detector and observable
    parities. Detectors and observables are then XOR-normalized so
    that 0 means 'matches noiseless reference' and 1 means 'error'.

    Reference sampling removes stochastic and readout noise without checking
    determinism. Coherent error rotations remain; for these errors, supply
    expected parities from the intended ideal circuit instead.

    Args:
        stim_text: Circuit text in the format selected by ``input_format``.
        postselection_mask: Optional list of uint8 flags, one per detector.
            Detectors where mask[i] != 0 become post-selection checks
            that abort the shot early if their parity is non-zero.
        expected_detectors: Optional noiseless reference parities for detectors.
        expected_observables: Optional noiseless reference parities for observables.
        normalize_syndromes: If True, auto-compute reference parities from a
            noiseless reference shot (mutually exclusive with explicit parities).
        hir_passes: HirPassManager to run on the HIR before lowering.
            Defaults to ``default_hir_pass_manager()``. Pass ``None`` to skip.
        input_format: ``"stim"`` for Clifft's Stim-compatible syntax or
            ``"qasm2"`` for the supported unitary OpenQASM 2 subset.
    """
    if isinstance(hir_passes, _DefaultPasses):
        hir_passes = default_hir_pass_manager()
    if input_format == "stim":
        compile_core = _compile_core
    elif input_format == "qasm2":
        compile_core = _compile_qasm2_core
    else:
        raise ValueError("input_format must be 'stim' or 'qasm2'")
    return compile_core(
        stim_text,
        postselection_mask if postselection_mask is not None else [],
        expected_detectors if expected_detectors is not None else [],
        expected_observables if expected_observables is not None else [],
        normalize_syndromes,
        hir_passes,
    )

clifft.parse

parse(text: str) -> Circuit
parse(text: str, max_ops: int) -> Circuit

parse(text: str) -> clifft._clifft_core.Circuit parse(text: str, max_ops: int) -> clifft._clifft_core.Circuit

Overloaded function.

  1. parse(text: str) -> clifft._clifft_core.Circuit

Parse a quantum circuit from a string.

  1. parse(text: str, max_ops: int) -> clifft._clifft_core.Circuit

Parse a quantum circuit from a string with an explicit AST node limit.

clifft.parse_file

parse_file(path: str) -> Circuit
parse_file(path: str, max_ops: int) -> Circuit

parse_file(path: str) -> clifft._clifft_core.Circuit parse_file(path: str, max_ops: int) -> clifft._clifft_core.Circuit

Overloaded function.

  1. parse_file(path: str) -> clifft._clifft_core.Circuit

Parse a quantum circuit from a file.

  1. parse_file(path: str, max_ops: int) -> clifft._clifft_core.Circuit

Parse a quantum circuit from a file with an explicit AST node limit.

clifft.parse_qasm2

parse_qasm2(text: str) -> Qasm2Import
parse_qasm2(text: str, max_ops: int) -> Qasm2Import

parse_qasm2(text: str) -> clifft._clifft_core.Qasm2Import parse_qasm2(text: str, max_ops: int) -> clifft._clifft_core.Qasm2Import

Overloaded function.

  1. parse_qasm2(text: str) -> clifft._clifft_core.Qasm2Import

Parse and lower a unitary OpenQASM 2 circuit.

  1. parse_qasm2(text: str, max_ops: int) -> clifft._clifft_core.Qasm2Import

Parse and lower a unitary OpenQASM 2 circuit with an explicit AST node limit.

clifft.parse_qasm2_file

parse_qasm2_file(path: str) -> Qasm2Import
parse_qasm2_file(path: str, max_ops: int) -> Qasm2Import

parse_qasm2_file(path: str) -> clifft._clifft_core.Qasm2Import parse_qasm2_file(path: str, max_ops: int) -> clifft._clifft_core.Qasm2Import

Overloaded function.

  1. parse_qasm2_file(path: str) -> clifft._clifft_core.Qasm2Import

Parse and lower a unitary OpenQASM 2 circuit file.

  1. parse_qasm2_file(path: str, max_ops: int) -> clifft._clifft_core.Qasm2Import

Parse and lower a unitary OpenQASM 2 file with an explicit AST node limit.

clifft.trace

trace(
    circuit: Circuit,
    postselection_mask: Sequence[int] = [],
    expected_detectors: Sequence[int] = [],
    expected_observables: Sequence[int] = [],
    normalize_syndromes: bool = False,
) -> HirModule

trace(circuit: clifft._clifft_core.Circuit, postselection_mask: collections.abc.Sequence[int] = [], expected_detectors: collections.abc.Sequence[int] = [], expected_observables: collections.abc.Sequence[int] = [], normalize_syndromes: bool = False) -> clifft._clifft_core.HirModule

Trace a parsed circuit through the Clifford front-end to produce the Heisenberg IR. Single-qubit rotations within 1e-12 half-turns of a Clifford angle are canonicalized. Optional postselection_mask, expected_detectors, expected_observables, and normalize_syndromes settings are recorded on the returned HirModule for HIR optimization passes and lower().

clifft.lower

lower(
    hir: HirModule,
    postselection_mask: Sequence[int] | None = None,
    expected_detectors: Sequence[int] | None = None,
    expected_observables: Sequence[int] | None = None,
) -> Program

lower(hir: clifft._clifft_core.HirModule, postselection_mask: collections.abc.Sequence[int] | None = None, expected_detectors: collections.abc.Sequence[int] | None = None, expected_observables: collections.abc.Sequence[int] | None = None) -> clifft._clifft_core.Program

Lower a Heisenberg IR module to an executable sampling program.

Parameters:

Name Type Description Default
hir HirModule

The Heisenberg IR module to lower.

required
postselection_mask Sequence[int] | None

Optional list of uint8 flags, one per detector. Defaults to hir.postselection_mask when None.

None
expected_detectors Sequence[int] | None

Optional noiseless reference parities for detectors. Defaults to hir.expected_detectors when None.

None
expected_observables Sequence[int] | None

Optional noiseless reference parities for observables. Defaults to hir.expected_observables when None.

None

clifft.ParseError

Bases: builtins.Exception

Sampling

The four fixed-plan functions share CPU batching and threading arguments. See CPU Execution and Tuning for their interaction and compatibility limits.

clifft.sample

sample(
    program: Program,
    shots: int,
    seed: int | None = None,
    threads: int | Literal["auto"] = 1,
    thread_layout: tuple[int, int] | None = None,
    intra_shot_min_active_width: int | None = None,
    batch_size: int | Literal["auto", "tune"] = "auto",
    *,
    tuning_budget_seconds: float | None = None,
) -> clifft.SampleResult

sample(program: Program, shots: int, seed: int | None = None, threads: int | typing.Literal['auto'] = 1, thread_layout: tuple[int, int] | None = None, intra_shot_min_active_width: int | None = None, batch_size: int | typing.Literal['auto', 'tune'] = 'auto', *, tuning_budget_seconds: float | None = None) -> clifft.SampleResult

Run a compiled program and return a SampleResult.

Raises ValueError for post-selected programs because fixed-row output cannot represent discarded shots. Use sample_survivors() instead.

If seed is None (default), uses hardware entropy. threads is a positive total worker budget or 'auto' to use the implementation-reported hardware concurrency; it defaults to 1. Automatic scheduling uses either cross-shot or intra-shot workers. thread_layout=(shot_workers, intra_shot_workers) overrides that choice and ignores threads; intra-shot counts above 1 require OpenMP support. intra_shot_min_active_width overrides the default threshold of 18 for an explicit layout. batch_size='auto' uses the conservative plan policy; 1 forces scalar execution, and a positive integer requests a packed lane-capacity limit. Seeded results replay within one batching configuration, but individual rows may differ between scalar and packed modes or different capacities.

batch_size='tune' calibrates before running all requested shots. tuning_budget_seconds is a soft calibration deadline, defaulting to 0.25 seconds. Trials are extra work and are excluded from returned rows and counts. The selected configuration and timings are in result.batch_tuning. Timing-based selection need not replay for a fixed seed; pin a numeric batch_size for debugging.

Returns a SampleResult with .measurements, .detectors, .observables attributes. Supports tuple unpacking: m, d, o = clifft.sample(prog, shots)

clifft.sample_survivors

sample_survivors(
    program: Program,
    shots: int,
    seed: int | None = None,
    keep_records: bool = False,
    threads: int | Literal["auto"] = 1,
    thread_layout: tuple[int, int] | None = None,
    intra_shot_min_active_width: int | None = None,
    batch_size: int | Literal["auto", "tune"] = "auto",
    *,
    tuning_budget_seconds: float | None = None,
) -> clifft.SampleResult

sample_survivors(program: Program, shots: int, seed: int | None = None, keep_records: bool = False, threads: int | typing.Literal['auto'] = 1, thread_layout: tuple[int, int] | None = None, intra_shot_min_active_width: int | None = None, batch_size: int | typing.Literal['auto', 'tune'] = 'auto', *, tuning_budget_seconds: float | None = None) -> clifft.SampleResult

Sample shots and return results only for surviving (non-discarded) shots.

If seed is None (default), uses hardware entropy. threads is a positive total worker budget or 'auto' to use the implementation-reported hardware concurrency; it defaults to 1. thread_layout=(shot_workers, intra_shot_workers) overrides automatic scheduling. intra_shot_min_active_width overrides the default threshold of 18 for an explicit layout. batch_size='auto' uses the conservative plan policy; 1 forces scalar execution, and a positive integer requests a packed lane-capacity limit.

batch_size='tune' calibrates before running all requested shots. tuning_budget_seconds is a soft calibration deadline, defaulting to 0.25 seconds. Trials are extra work and are excluded from returned rows and counts. The selected configuration and timings are in result.batch_tuning. Timing-based selection need not replay for a fixed seed; pin a numeric batch_size for debugging.

Returns a SampleResult. Survivor metadata is always populated via .total_shots, .passed_shots, .discards, .logical_errors, and .observable_ones. Per-shot record arrays (.measurements, .detectors, .observables, .exp_vals) are only filled when keep_records=True; otherwise they are empty (rows=0).

clifft.sample_k

sample_k(
    program: Program,
    shots: int,
    k: int,
    seed: int | None = None,
    threads: int | Literal["auto"] = 1,
    thread_layout: tuple[int, int] | None = None,
    intra_shot_min_active_width: int | None = None,
    batch_size: int | Literal["auto", "tune"] = "auto",
    *,
    tuning_budget_seconds: float | None = None,
) -> clifft.SampleResult

sample_k(program: Program, shots: int, k: int, seed: int | None = None, threads: int | typing.Literal['auto'] = 1, thread_layout: tuple[int, int] | None = None, intra_shot_min_active_width: int | None = None, batch_size: int | typing.Literal['auto', 'tune'] = 'auto', *, tuning_budget_seconds: float | None = None) -> clifft.SampleResult

Sample with exactly k forced faults per shot (importance sampling).

Sites are drawn from the exact conditional Poisson-Binomial distribution. Results are conditioned on K=k and must be combined across strata with P(K=k) weights for correct error rate estimation. Raises ValueError for post-selected programs because fixed-row output cannot represent discarded shots. Use sample_k_survivors() instead.

For post-selected circuits, weight numerator and denominator separately via sample_k_survivors(): p_fail = sum(P(K=k)errors_k/shots_k) / sum(P(K=k)passed_k/shots_k).

Raises ValueError if the k-fault stratum has zero probability mass (e.g. k exceeds the number of non-zero-probability sites).

When all site probabilities are equal, an O(k) Fisher-Yates sampler is used automatically. threads is a positive total worker budget or 'auto' to use the implementation-reported hardware concurrency; it defaults to 1. thread_layout=(shot_workers, intra_shot_workers) overrides automatic scheduling. intra_shot_min_active_width overrides the default threshold of 18 for an explicit layout. batch_size='auto' uses the conservative plan policy; 1 forces scalar execution, and a positive integer requests a packed lane-capacity limit.

batch_size='tune' calibrates before running all requested shots. tuning_budget_seconds is a soft calibration deadline, defaulting to 0.25 seconds. Trials are extra work and are excluded from returned rows and counts. The selected configuration and timings are in result.batch_tuning. Timing-based selection need not replay for a fixed seed; pin a numeric batch_size for debugging.

Returns a SampleResult with .measurements, .detectors, .observables attributes. Supports tuple unpacking: m, d, o = clifft.sample_k(prog, shots, k)

clifft.sample_k_survivors

sample_k_survivors(
    program: Program,
    shots: int,
    k: int,
    seed: int | None = None,
    keep_records: bool = False,
    threads: int | Literal["auto"] = 1,
    thread_layout: tuple[int, int] | None = None,
    intra_shot_min_active_width: int | None = None,
    batch_size: int | Literal["auto", "tune"] = "auto",
    *,
    tuning_budget_seconds: float | None = None,
) -> clifft.SampleResult

sample_k_survivors(program: Program, shots: int, k: int, seed: int | None = None, keep_records: bool = False, threads: int | typing.Literal['auto'] = 1, thread_layout: tuple[int, int] | None = None, intra_shot_min_active_width: int | None = None, batch_size: int | typing.Literal['auto', 'tune'] = 'auto', *, tuning_budget_seconds: float | None = None) -> clifft.SampleResult

Sample survivors with exactly k forced faults per shot.

Results are conditioned on K=k. To estimate the overall logical error rate across strata, weight numerator and denominator separately to account for k-dependent survival probability: p_fail = sum(P(K=k)logical_errors_k/shots_k) / sum(P(K=k)passed_k/shots_k)

Raises ValueError if the k-fault stratum has zero probability mass. threads is a positive total worker budget or 'auto' to use the implementation-reported hardware concurrency; it defaults to 1. thread_layout=(shot_workers, intra_shot_workers) overrides automatic scheduling. intra_shot_min_active_width overrides the default threshold of 18 for an explicit layout. batch_size='auto' uses the conservative plan policy; 1 forces scalar execution, and a positive integer requests a packed lane-capacity limit.

batch_size='tune' calibrates before running all requested shots. tuning_budget_seconds is a soft calibration deadline, defaulting to 0.25 seconds. Trials are extra work and are excluded from returned rows and counts. The selected configuration and timings are in result.batch_tuning. Timing-based selection need not replay for a fixed seed; pin a numeric batch_size for debugging.

Returns a SampleResult. Survivor metadata is always populated via .total_shots, .passed_shots, .discards, .logical_errors, and .observable_ones. Per-shot record arrays (.measurements, .detectors, .observables, .exp_vals) are only filled when keep_records=True; otherwise they are empty (rows=0).

Optional Sinter Integration

Install clifft[sinter] for this optional integration with Stim/Sinter 1.16. See Using with Sinter for a runnable collection example.

clifft.sinter.PerfectionistSampler dataclass

PerfectionistSampler(
    *, batch_size: int | Literal["auto"] = 1024
)

Bases: Sampler

Count logical errors after rejecting every shot with a detection event.

An absent postselection mask selects every detector. An explicit mask must be a little-endian packed uint8 NumPy array selecting every detector, with one byte per eight detectors, rounded up. Padding bits are ignored; with no detectors, an absent or empty mask is accepted.

Detector and observable bits are normalized against the noiseless reference, assuming fixed parities without checking determinism. On surviving shots, any observable flip counts as one error, using zero observable prediction. Observable postselection and arbitrary decoders are unsupported. Leave Sinter's count_detection_events and count_observable_error_combos options false; Sinter rejects these options for custom samplers.

Tasks must contain a resolved stim.Circuit using instructions supported by Clifft. Heralded noise, sweep-bit controls, and Pauli targets in OBSERVABLE_INCLUDE are unsupported. Stim tags are ignored when compiling without modifying the task's circuit. A supplied detector error model participates in Sinter's task identity but is not used to predict corrections.

Register an instance in sinter.collect(custom_decoders=...). Its configuration is pickle-safe; each worker compiles its own Clifft program and uses one native thread. Sampling returns aggregate counts without materializing survivor rows. Each call uses fresh native randomness; this adapter does not expose a seed or a retained random stream. Direct sample(0) calls return zero counts.

Parameters:

Name Type Description Default
batch_size int | Literal['auto']

Native lane capacity, defaulting to 1024. Each call uses at most the requested number of shots and 2048 lanes; larger capacities are capped, not rejected. This is separate from Sinter's max_batch_size, which defaults to 1024 in Sinter 1.15. Increase that limit to use larger native batches. Use 1 for scalar execution or "auto" for Clifft's core policy.

1024

compiled_sampler_for_task

compiled_sampler_for_task(
    task: Task,
) -> sinter.CompiledSampler

Validate an all-detector task and compile its normalized circuit.

Source code in .venv/lib/python3.12/site-packages/clifft/sinter.py
def compiled_sampler_for_task(self, task: sinter.Task) -> sinter.CompiledSampler:
    """Validate an all-detector task and compile its normalized circuit."""
    if task.circuit is None:
        raise ValueError("PerfectionistSampler requires a resolved task.circuit")
    if task.postselected_observables_mask is not None:
        raise ValueError("PerfectionistSampler does not support observable postselection")

    num_detectors = task.circuit.num_detectors
    mask = task.postselection_mask
    if mask is not None:
        if (
            not isinstance(mask, np.ndarray)
            or mask.dtype != np.uint8
            or mask.shape != ((num_detectors + 7) // 8,)
        ):
            raise ValueError(
                "postselection_mask must be a packed uint8 array for the detectors"
            )
        # Padding bits do not refer to detectors and must not affect acceptance.
        if not np.all(np.unpackbits(mask, bitorder="little", count=num_detectors)):
            raise ValueError("PerfectionistSampler requires all-detector postselection")

    program = clifft.compile(
        str(task.circuit.without_tags()),
        postselection_mask=[1] * num_detectors,
        normalize_syndromes=True,
    )
    return _CompiledPerfectionistSampler(program, self.batch_size)

Experimental Hardware Backends

Experimental

These APIs require backend-specific source builds and may change without compatibility guarantees. They are not selected by the regular CPU API.

See HIP Backend and CUDA Backend for the current hardware and workflow limits.

clifft.experimental.hip.is_built

is_built() -> bool

Return whether this Clifft installation contains the HIP extension.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/hip.py
def is_built() -> bool:
    """Return whether this Clifft installation contains the HIP extension."""
    return _NATIVE_SPEC is not None

clifft.experimental.hip.is_available

is_available() -> bool

Return whether the extension loaded and can see an AMD GPU.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/hip.py
def is_available() -> bool:
    """Return whether the extension loaded and can see an AMD GPU."""
    return _native is not None and bool(_native.is_available())

clifft.experimental.hip.backend_info

backend_info() -> str

Describe the optional extension and any devices visible to HIP.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/hip.py
def backend_info() -> str:
    """Describe the optional extension and any devices visible to HIP."""
    if _NATIVE_SPEC is None:
        return "HIP backend not built; rebuild Clifft with CLIFFT_ENABLE_HIP=ON"
    if _native is None:
        return f"HIP extension failed to load: {_native_error}"
    return cast(str, _native.backend_info())

clifft.experimental.hip.compile

compile(
    stim_text: str,
    postselection_mask: list[int] | None = None,
    expected_detectors: list[int] | None = None,
    expected_observables: list[int] | None = None,
    normalize_syndromes: bool = False,
    hir_passes: HirPassManager
    | None
    | _DefaultPasses = _DEFAULT_PASSES,
) -> Program

Compile Stim text through the shared HIR and SamplingPlan pipeline.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/hip.py
def compile(
    stim_text: str,
    postselection_mask: list[int] | None = None,
    expected_detectors: list[int] | None = None,
    expected_observables: list[int] | None = None,
    normalize_syndromes: bool = False,
    hir_passes: HirPassManager | None | _DefaultPasses = _DEFAULT_PASSES,
) -> Program:
    """Compile Stim text through the shared HIR and SamplingPlan pipeline."""
    if isinstance(hir_passes, _DefaultPasses):
        hir_passes = default_hir_pass_manager()
    prepared = _prepare_hir_for_lowering(
        stim_text,
        expected_detectors if expected_detectors is not None else [],
        expected_observables if expected_observables is not None else [],
        normalize_syndromes,
        hir_passes,
        postselection_mask if postselection_mask is not None else [],
    )
    hir = cast(HirModule, prepared[0])
    detectors = cast(list[int], prepared[1])
    observables = cast(list[int], prepared[2])
    return lower(hir, postselection_mask, detectors, observables)

clifft.experimental.hip.Program

Program(native: Any)

An immutable, backend-private lowering of a SamplingPlan.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/hip.py
def __init__(self, native: Any) -> None:
    self._native = native

num_records property

num_records: int

Return the visible plus hidden record width required by replay.

inspect

inspect() -> str

Return diagnostic text for the packed executable.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/hip.py
def inspect(self) -> str:
    """Return diagnostic text for the packed executable."""
    return cast(str, self._native.inspect())

clifft.experimental.hip.Sampler

Sampler(
    program: Program,
    *,
    precision: Precision = "fp64",
    max_batch_shots: int | None = None,
    tier: Tier = "auto",
)

A synchronous sampler with one uploaded program and retained workspace.

Calls on one instance must not overlap. Use a separate sampler per caller.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/hip.py
def __init__(
    self,
    program: Program,
    *,
    precision: Precision = "fp64",
    max_batch_shots: int | None = None,
    tier: Tier = "auto",
) -> None:
    native = _require_native()
    self.program = program
    native_precision = _precision_value(precision)
    native_tier = _tier_value(tier)
    if max_batch_shots is None:
        self._native = native.Sampler(program._native, native_precision, tier=native_tier)
    else:
        self._native = native.Sampler(
            program._native, native_precision, max_batch_shots, native_tier
        )

tier property

tier: Tier

Return the resolved execution tier; never "auto".

replay_shot

replay_shot(forced_records: list[int]) -> ReplayResult

Force every record value to probe one measurement branch exactly.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/hip.py
def replay_shot(self, forced_records: list[int]) -> ReplayResult:
    """Force every record value to probe one measurement branch exactly."""
    result = self._native.replay_shot(forced_records)
    return ReplayResult(
        reachable=cast(bool, result["reachable"]),
        survived=cast(bool, result["survived"]),
        log_probability=cast(float, result["log_probability"]),
        outputs=cast(SampleResult, result["outputs"]),
    )

sample

sample(
    shots: int,
    *,
    seed: int | None = None,
    block_size: int | None = None,
) -> SampleResult

Sample fixed rows while reusing the retained device workspace.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/hip.py
def sample(
    self,
    shots: int,
    *,
    seed: int | None = None,
    block_size: int | None = None,
) -> SampleResult:
    """Sample fixed rows while reusing the retained device workspace."""
    if block_size is None:
        return cast(SampleResult, self._native.sample(shots, seed))
    return cast(SampleResult, self._native.sample(shots, seed, block_size))

sample_survivors

sample_survivors(
    shots: int,
    *,
    keep_records: bool = False,
    seed: int | None = None,
    block_size: int | None = None,
) -> SampleResult

Sample and retain only shots that pass postselection.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/hip.py
def sample_survivors(
    self,
    shots: int,
    *,
    keep_records: bool = False,
    seed: int | None = None,
    block_size: int | None = None,
) -> SampleResult:
    """Sample and retain only shots that pass postselection."""
    if block_size is None:
        return cast(
            SampleResult,
            self._native.sample_survivors(shots, keep_records, seed),
        )
    return cast(
        SampleResult,
        self._native.sample_survivors(shots, keep_records, seed, block_size),
    )

clifft.experimental.hip.ReplayResult dataclass

ReplayResult(
    reachable: bool,
    survived: bool,
    log_probability: float,
    outputs: SampleResult,
)

Result of one forced-record path through the HIP interpreter.

clifft.experimental.cuda.is_built

is_built() -> bool

Return whether this Clifft installation contains the CUDA extension.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/cuda.py
def is_built() -> bool:
    """Return whether this Clifft installation contains the CUDA extension."""
    return _NATIVE_SPEC is not None

clifft.experimental.cuda.is_available

is_available() -> bool

Return whether the extension loaded and can see an NVIDIA GPU.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/cuda.py
def is_available() -> bool:
    """Return whether the extension loaded and can see an NVIDIA GPU."""
    return _native is not None and bool(_native.is_available())

clifft.experimental.cuda.backend_info

backend_info() -> str

Describe the optional extension and any devices visible to CUDA.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/cuda.py
def backend_info() -> str:
    """Describe the optional extension and any devices visible to CUDA."""
    if _NATIVE_SPEC is None:
        return "CUDA backend not built; rebuild Clifft with CLIFFT_ENABLE_CUDA=ON"
    if _native is None:
        return f"CUDA extension failed to load: {_native_error}"
    return cast(str, _native.backend_info())

clifft.experimental.cuda.compile

compile(
    stim_text: str,
    postselection_mask: list[int] | None = None,
    expected_detectors: list[int] | None = None,
    expected_observables: list[int] | None = None,
    normalize_syndromes: bool = False,
    hir_passes: HirPassManager
    | None
    | _DefaultPasses = _DEFAULT_PASSES,
) -> Program

Compile Stim text through the shared HIR and SamplingPlan pipeline.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/cuda.py
def compile(
    stim_text: str,
    postselection_mask: list[int] | None = None,
    expected_detectors: list[int] | None = None,
    expected_observables: list[int] | None = None,
    normalize_syndromes: bool = False,
    hir_passes: HirPassManager | None | _DefaultPasses = _DEFAULT_PASSES,
) -> Program:
    """Compile Stim text through the shared HIR and SamplingPlan pipeline."""
    if isinstance(hir_passes, _DefaultPasses):
        hir_passes = default_hir_pass_manager()
    prepared = _prepare_hir_for_lowering(
        stim_text,
        expected_detectors if expected_detectors is not None else [],
        expected_observables if expected_observables is not None else [],
        normalize_syndromes,
        hir_passes,
        postselection_mask if postselection_mask is not None else [],
    )
    hir = cast(HirModule, prepared[0])
    detectors = cast(list[int], prepared[1])
    observables = cast(list[int], prepared[2])
    return lower(hir, postselection_mask, detectors, observables)

clifft.experimental.cuda.selected_tier

selected_tier(
    program: Program, precision: Precision = "fp64"
) -> Tier

Report the execution tier automatic selection picks on the current device.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/cuda.py
def selected_tier(program: Program, precision: Precision = "fp64") -> Tier:
    """Report the execution tier automatic selection picks on the current device."""
    native = _require_native()
    return _tier_name(native.selected_tier(program._native, _precision_value(precision)))

clifft.experimental.cuda.Program

Program(native: Any)

An immutable, backend-private lowering of a SamplingPlan.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/cuda.py
def __init__(self, native: Any) -> None:
    self._native = native

num_records property

num_records: int

Return the visible plus hidden record width required by replay.

inspect

inspect() -> str

Return diagnostic text for the packed executable.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/cuda.py
def inspect(self) -> str:
    """Return diagnostic text for the packed executable."""
    return cast(str, self._native.inspect())

clifft.experimental.cuda.Sampler

Sampler(
    program: Program,
    *,
    precision: Precision = "fp64",
    max_batch_shots: int | None = None,
    tier: Tier = "auto",
    max_concurrent_shots: int = 0,
)

A synchronous sampler with one uploaded program and retained workspace.

Calls on one instance must not overlap. Use a separate sampler per caller.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/cuda.py
def __init__(
    self,
    program: Program,
    *,
    precision: Precision = "fp64",
    max_batch_shots: int | None = None,
    tier: Tier = "auto",
    max_concurrent_shots: int = 0,
) -> None:
    native = _require_native()
    self.program = program
    kwargs: dict[str, Any] = {
        "coefficient_precision": _precision_value(precision),
        "tier": _tier_value(tier),
        "max_concurrent_shots": max_concurrent_shots,
    }
    if max_batch_shots is not None:
        kwargs["max_batch_shots"] = max_batch_shots
    self._native = native.Sampler(program._native, **kwargs)

max_concurrent_shots property

max_concurrent_shots: int

Return how many shots the cooperative tiers keep resident per launch.

tier property

tier: Tier

Return the resolved execution tier; never "auto".

replay_shot

replay_shot(forced_records: list[int]) -> ReplayResult

Force every record value to probe one measurement branch exactly.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/cuda.py
def replay_shot(self, forced_records: list[int]) -> ReplayResult:
    """Force every record value to probe one measurement branch exactly."""
    result = self._native.replay_shot(forced_records)
    return ReplayResult(
        reachable=cast(bool, result["reachable"]),
        survived=cast(bool, result["survived"]),
        log_probability=cast(float, result["log_probability"]),
        outputs=cast(SampleResult, result["outputs"]),
    )

sample

sample(
    shots: int,
    *,
    seed: int | None = None,
    block_size: int | None = None,
) -> SampleResult

Sample fixed rows while reusing the retained device workspace.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/cuda.py
def sample(
    self,
    shots: int,
    *,
    seed: int | None = None,
    block_size: int | None = None,
) -> SampleResult:
    """Sample fixed rows while reusing the retained device workspace."""
    if block_size is None:
        return cast(SampleResult, self._native.sample(shots, seed))
    return cast(SampleResult, self._native.sample(shots, seed, block_size))

sample_survivors

sample_survivors(
    shots: int,
    *,
    keep_records: bool = False,
    seed: int | None = None,
    block_size: int | None = None,
) -> SampleResult

Sample and retain only shots that pass postselection.

Source code in .venv/lib/python3.12/site-packages/clifft/experimental/cuda.py
def sample_survivors(
    self,
    shots: int,
    *,
    keep_records: bool = False,
    seed: int | None = None,
    block_size: int | None = None,
) -> SampleResult:
    """Sample and retain only shots that pass postselection."""
    if block_size is None:
        return cast(
            SampleResult,
            self._native.sample_survivors(shots, keep_records, seed),
        )
    return cast(
        SampleResult,
        self._native.sample_survivors(shots, keep_records, seed, block_size),
    )

clifft.experimental.cuda.ReplayResult dataclass

ReplayResult(
    reachable: bool,
    survived: bool,
    log_probability: float,
    outputs: SampleResult,
)

Result of one forced-record path through the CUDA interpreter.

Leakage and Loss

Sampling under a five-level leakage/loss model. See the Leakage and Loss guide and Partner Interactions for model defaults, directional overrides, and circuit annotation ordering.

clifft.noncomp.sample

sample(
    circuit: Circuit | str,
    model: Model,
    shots: int,
    seed: int | None = None,
    max_active_width: int | None = None,
    threads: int | Literal["auto"] = 1,
    *,
    final_status: bool = False,
    execution: Literal[
        "auto", "fixed", "trajectory"
    ] = "auto",
    batch_size: int | Literal["auto"] = "auto",
    collect_stats: bool = False,
) -> NonComputationalSample

Prepare and sample a circuit under a five-level leakage/loss model.

Equivalent to compile followed by NonComputationalProgram.sample. Each call repeats preparation; reuse a compiled program to amortize it. Existing positional arguments retain their meaning. Detailed final status is opt-in: add final_status=True when consuming that output.

On an inactive site, M/MX/MY and their reset variants sample the classifier independently of basis. A model capable of leakage/loss requires a classifier for physical measurements and does not support MPP. EXP_VAL is unsupported. Status probes append ordinary records without classifier heralds. Feedback consumes reported bits; detectors and observables retain raw parities without reference normalization.

Returns:

Type Description
NonComputationalSample

Measurement, detector, observable, and herald arrays; optional detailed

NonComputationalSample

final status and statistics. Three-array unpacking remains supported.

Raises:

Type Description
ValueError

For invalid circuit/model contracts, unsupported forced execution or batching, or an exceeded active-width cap.

Source code in .venv/lib/python3.12/site-packages/clifft/noncomp.py
def sample(
    circuit: Circuit | str,
    model: Model,
    shots: int,
    seed: int | None = None,
    max_active_width: int | None = None,
    threads: int | Literal["auto"] = 1,
    *,
    final_status: bool = False,
    execution: Literal["auto", "fixed", "trajectory"] = "auto",
    batch_size: int | Literal["auto"] = "auto",
    collect_stats: bool = False,
) -> NonComputationalSample:
    """Prepare and sample a circuit under a five-level leakage/loss model.

    Equivalent to [compile][clifft.noncomp.compile] followed by
    [NonComputationalProgram.sample][clifft.noncomp.NonComputationalProgram.sample].
    Each call repeats preparation; reuse a compiled program to amortize it.
    Existing positional arguments retain their meaning. Detailed final status
    is opt-in: add ``final_status=True`` when consuming that output.

    On an inactive site, M/MX/MY and their reset variants sample the classifier
    independently of basis. A model capable of leakage/loss requires a
    classifier for physical measurements and does not support MPP.
    EXP_VAL is unsupported. Status probes append ordinary records without
    classifier heralds. Feedback consumes reported bits; detectors and
    observables retain raw parities without reference normalization.

    Returns:
        Measurement, detector, observable, and herald arrays; optional detailed
        final status and statistics. Three-array unpacking remains supported.

    Raises:
        ValueError: For invalid circuit/model contracts, unsupported forced
            execution or batching, or an exceeded active-width cap.
    """
    return compile(
        circuit,
        model,
        final_status=final_status,
        execution=execution,
        max_active_width=max_active_width,
    ).sample(shots, seed, threads, batch_size=batch_size, collect_stats=collect_stats)

clifft.noncomp.compile

compile(
    circuit: Circuit | str,
    model: Model,
    *,
    final_status: bool = False,
    execution: Literal[
        "auto", "fixed", "trajectory"
    ] = "auto",
    max_active_width: int | None = None,
) -> NonComputationalProgram

Prepare an owned sampling strategy without drawing shot randomness.

execution="auto" chooses a supported exact fixed plan when its width fits; otherwise it retains a validated trajectory request. "fixed" requires fixed execution and raises with the rejection reason before sampling. "trajectory" forces the general driver. Invalid circuit/model contracts always raise rather than triggering optimization fallback.

final_status=True requests the existing detailed QubitStatus values and can require trajectories when leaked labels remain unresolved. The default omits that output. This requirement is fixed at preparation.

max_active_width caps the fixed candidate or each compiled trajectory continuation. Under auto, an over-cap fixed candidate falls back; trajectory width errors can still arise when sampling. Initial states, spreading, classifiers, and partner channels outside the fixed subset use trajectories. The existing noncomputational measurement restrictions remain in force.

Source code in .venv/lib/python3.12/site-packages/clifft/noncomp.py
def compile(
    circuit: Circuit | str,
    model: Model,
    *,
    final_status: bool = False,
    execution: Literal["auto", "fixed", "trajectory"] = "auto",
    max_active_width: int | None = None,
) -> NonComputationalProgram:
    """Prepare an owned sampling strategy without drawing shot randomness.

    ``execution="auto"`` chooses a supported exact fixed plan when its width
    fits; otherwise it retains a validated trajectory request. ``"fixed"``
    requires fixed execution and raises with the rejection reason before
    sampling. ``"trajectory"`` forces the general driver. Invalid circuit/model
    contracts always raise rather than triggering optimization fallback.

    ``final_status=True`` requests the existing detailed QubitStatus values and
    can require trajectories when leaked labels remain unresolved. The default
    omits that output. This requirement is fixed at preparation.

    ``max_active_width`` caps the fixed candidate or each compiled trajectory
    continuation. Under auto, an over-cap fixed candidate falls back; trajectory
    width errors can still arise when sampling. Initial states, spreading,
    classifiers, and partner channels outside the fixed subset use trajectories.
    The existing noncomputational measurement restrictions remain in force.
    """
    if isinstance(circuit, str):
        circuit = _clifft_core.parse(circuit)
    return NonComputationalProgram(
        _clifft_core._compile_noncomputational(
            circuit, model._handle, final_status, execution, max_active_width
        )
    )

clifft.noncomp.NonComputationalProgram

NonComputationalProgram(handle: Any)

Reusable, immutable preparation of a leakage/loss sampling strategy.

Create with compile. The program owns circuit and model snapshots. Each sample call owns its workers and RNG, so programs can be reused concurrently. A trajectory program still compiles continuations during sampling. Reading omitted final status never resamples a result.

Source code in .venv/lib/python3.12/site-packages/clifft/noncomp.py
def __init__(self, handle: Any) -> None:
    self._handle = handle

strategy property

strategy: Literal['fixed', 'trajectory']

Selected execution strategy, fixed for this prepared program.

explain

explain() -> str

Describe selection, fallback reasons, and known resource estimates.

Formatting is lazy and runs no shots. Locations identify representative circuit lines and expanded operations when available. Batch capacity and worker memory depend on sampling arguments and appear in result stats.

Source code in .venv/lib/python3.12/site-packages/clifft/noncomp.py
def explain(self) -> str:
    """Describe selection, fallback reasons, and known resource estimates.

    Formatting is lazy and runs no shots. Locations identify representative
    circuit lines and expanded operations when available. Batch capacity and
    worker memory depend on sampling arguments and appear in result stats.
    """
    return str(self._handle.explain())

sample

sample(
    shots: int,
    seed: int | None = None,
    threads: int | Literal["auto"] = 1,
    *,
    batch_size: int | Literal["auto"] = "auto",
    collect_stats: bool = False,
) -> NonComputationalSample

Sample this program with fresh per-call workers and RNG.

batch_size="auto" uses conservative shared heuristics for a fixed plan and scalar execution for trajectories. 1 forces scalar; larger integers request packing under the existing capacity limits and fail when the selected strategy is trajectory, including for zero shots. Timing-based "tune" is not supported here yet.

threads selects cross-shot workers; "auto" uses hardware concurrency. For a fixed seed, shot count, and batch configuration, results are independent of worker count and scheduling. Different strategies or batch configurations need not produce identical rows. A missing seed uses fresh entropy; zero shots use none.

Source code in .venv/lib/python3.12/site-packages/clifft/noncomp.py
def sample(
    self,
    shots: int,
    seed: int | None = None,
    threads: int | Literal["auto"] = 1,
    *,
    batch_size: int | Literal["auto"] = "auto",
    collect_stats: bool = False,
) -> NonComputationalSample:
    """Sample this program with fresh per-call workers and RNG.

    ``batch_size="auto"`` uses conservative shared heuristics for a fixed
    plan and scalar execution for trajectories. ``1`` forces scalar;
    larger integers request packing under the existing capacity limits and
    fail when the selected strategy is trajectory, including for zero shots.
    Timing-based ``"tune"`` is not supported here yet.

    ``threads`` selects cross-shot workers; ``"auto"`` uses hardware
    concurrency. For a fixed seed, shot count, and batch configuration,
    results are independent of worker count and scheduling. Different
    strategies or batch configurations need not produce identical rows.
    A missing seed uses fresh entropy; zero shots use none.
    """
    values, report = self._handle.sample(
        shots, seed, threads, batch_size=batch_size, collect_stats=collect_stats
    )
    stats = None if report is None else NonComputationalStats(**report)
    return NonComputationalSample(*values, stats=stats)

clifft.noncomp.NonComputationalStats dataclass

NonComputationalStats(
    strategy: Literal["fixed", "trajectory"],
    fallback_reason: str | None,
    preparation_compilations: int,
    initial_compilations: int,
    continuation_compilations: int,
    fixed_shots: int,
    trajectory_shots: int,
    scalar_shots: int,
    packed_shots: int,
    packed_batches: int,
    batch_size: int,
    workers: int,
    packed_worker_bytes: int,
    peak_active_width: int | None,
    preparation_seconds: float,
    sampling_seconds: float,
)

Performance diagnostics for one sampling call, enabled by collect_stats=True.

Use this report to check whether shots ran in packed batches, how much trajectory recompilation occurred, and which resources the call used. program.explain() describes the strategy chosen before sampling; these counters describe actual execution. Without collection, result.stats is None. Collection does not change sampled results.

packed_shots, batch_size, and workers describe batching and parallelism. Shot counters satisfy scalar_shots + packed_shots == fixed_shots + trajectory_shots == result.shots. Trajectories run scalar; fixed execution can run scalar or packed.

initial_compilations counts trajectory starting plans built during the call; continuation_compilations counts recompilations after a trap. Both are zero for fixed execution. preparation_compilations and preparation_seconds instead describe the program's earlier preparation, including a rejected fixed candidate; they are not repeated work per call. Worker sharing can change compilation counts without changing sampled rows.

peak_active_width is the fixed plan's width or the maximum width compiled during this trajectory call; it is None if no trajectory was compiled. packed_worker_bytes estimates retained packed buffers per worker, excluding immutable plans, result arrays, and allocator bookkeeping. It is zero for scalar execution. Timings cover native preparation/sampling, excluding Python parsing and result conversion. Collection uses driver and batch boundaries, with no per-gate profiling.

clifft.noncomp.Model

Model(
    initial_state: Sequence[float] | None = None,
    transitions: Mapping[str, Matrix] | None = None,
    classifier: Classifier | None = None,
    reset_restores_lost: bool = False,
    damping: str = "exact",
    *,
    gate_partner_effects: Mapping[str, PartnerEffect]
    | None = None,
    interactions: Sequence[InteractionRule] | None = None,
)

A leakage and loss model over the built-in five-level set.

Parameters:

Name Type Description Default
initial_state Sequence[float] | None

probability per level, P(level), summing to one. Defaults to [1.0, 0.0, 0.0, 0.0, 0.0] (all qubits start in the ground state).

None
transitions Mapping[str, Matrix] | None

maps a name to its T[to][from] matrix. A key that names a gate (e.g. "CZ") is a hook: it expands to a LEVEL_TRANSITION[key] annotation after every occurrence of that gate. A key naming a recognized instruction that cannot be hooked is rejected, since it would otherwise look like a hook that never fires. These include noise channels and annotations, as well as instructions that never parse into a node of their own: MXX/MYY/MZZ (desugared to MPP), CH/CCX/CCZ (decomposed by the parser), and identity no-ops. Annotate those positions explicitly instead. Any key -- whether an arbitrary name or a hookable gate name -- can be referenced directly from the circuit with LEVEL_TRANSITION[key] q. LEAKAGE(p) q applies source-preserving leakage inline, while LOSS(p) q applies uniform loss. A transition fires at its circuit position, with the source taken from the qubit's state there.

None
classifier Classifier | None

Optional Classifier supplying leaked/lost measurement outcomes and computational readout confusion.

None
reset_restores_lost bool

if true, a reset on a lost qubit restores it to a computational state; if false (default), the reset acts on the vacated site and is dropped.

False
damping str

handling of the no-transition update when the total transition probability differs between g and e for a coherent qubit that is not yet represented in the state vector. "exact" (the default) adds the qubit to the state vector at that site, increasing peak active width by one. "neglect" avoids the expansion but omits the state update caused by observing that no transition occurred. It is exact when g and e have the same total transition probability; otherwise the bias is of order |p_g - p_e|.

'exact'
gate_partner_effects Mapping[str, PartnerEffect] | None

Defaults keyed by "leaked" or "lost", each a PartnerEffect. Apply in both directions of supported native physical two-qubit unitary gates when the other operand is computational. Omitted statuses have no partner effect. These defaults exclude noise and virtual feedback.

None
interactions Sequence[InteractionRule] | None

Specific InteractionRule overrides. Each replaces the whole matching default. Generated interactions run after the gate and before its level-transition hooks. Explicit circuit annotations run at their own expanded position and compose with generated effects without overriding them.

None

By default, an operation with no representable effect on a leaked or lost operand -- e.g. a two-qubit gate onto a vacated site -- is dropped, acting as the identity on the surviving operands. Configured partner interactions replace that identity with Pauli noise and optional leakage spreading. Single-qubit measurements (M, MX, MY) keep their record slot; once the qubit has left the computational subspace the readout basis is incidental and the classifier supplies the bit. A measure-and-reset (MR/MRX/MRY) keeps its record the same way; its reset half re-prepares the site only when the reset restores it (a leaked qubit always; a lost qubit only with reset_restores_lost). Parity measurements (MPP) are not supported when the model can leak or lose qubits -- they have no faithful single-bit classifier substitution -- and raise before sampling begins. A model that can leak or lose qubits also requires a classifier when the circuit measures a qubit.

Construction validates shapes, probabilities, gate keys, policy values, and level table consistency. Invalid values raise ValueError; effect and rule objects of the wrong type raise TypeError.

Source code in .venv/lib/python3.12/site-packages/clifft/noncomp.py
def __init__(
    self,
    initial_state: Sequence[float] | None = None,
    transitions: Mapping[str, Matrix] | None = None,
    classifier: Classifier | None = None,
    reset_restores_lost: bool = False,
    damping: str = "exact",
    *,
    gate_partner_effects: Mapping[str, PartnerEffect] | None = None,
    interactions: Sequence[InteractionRule] | None = None,
) -> None:
    if initial_state is None:
        initial_state = [1.0, 0.0, 0.0, 0.0, 0.0]
    transition_matrices = {
        str(gate): _as_matrix(matrix) for gate, matrix in (transitions or {}).items()
    }
    matrix = None if classifier is None else classifier.matrix
    self._gate_partner_effects = dict(gate_partner_effects or {})
    self._interactions = tuple(interactions or ())
    if any(
        not isinstance(effect, PartnerEffect) for effect in self._gate_partner_effects.values()
    ):
        raise TypeError("gate_partner_effects values must be PartnerEffect objects")
    if any(not isinstance(rule, InteractionRule) for rule in self._interactions):
        raise TypeError("interactions must contain InteractionRule objects")
    self._handle = _clifft_core._build_noncomp_model(
        [float(p) for p in initial_state],
        transition_matrices,
        matrix,
        bool(reset_restores_lost),
        str(damping),
        {status: effect._values() for status, effect in self._gate_partner_effects.items()},
        [
            (rule.gate, rule.source_operand, rule.source_status, rule.effect._values())
            for rule in self._interactions
        ],
    )
    self._transition_keys: list[str] = sorted(transition_matrices.keys())
    self._classifier_rows: int | None = None if classifier is None else len(classifier.matrix)
    self._reset_restores_lost: bool = bool(reset_restores_lost)
    self._damping: str = str(damping)

clifft.noncomp.PartnerEffect dataclass

PartnerEffect(
    *,
    pauli: Sequence[float] = (0.0, 0.0, 0.0),
    spread_probability: float = 0.0,
)

Noise on a computational partner of a leaked or lost operand.

pauli=(px, py, pz) specifies mutually exclusive X, Y, and Z errors; identity has probability 1 - px - py - pz. Full depolarization is (0.25, 0.25, 0.25). The optional leakage attempt happens after the Pauli channel, with source-preserving g -> leak_g and e -> leak_e semantics on the partner. Spreading is supported only for leaked sources. Both effects default to zero. Values are validated and copied on creation.

Source code in .venv/lib/python3.12/site-packages/clifft/noncomp.py
def __init__(
    self, *, pauli: Sequence[float] = (0.0, 0.0, 0.0), spread_probability: float = 0.0
) -> None:
    values = tuple(float(p) for p in pauli)
    if len(values) != 3:
        raise ValueError("pauli requires three probabilities in X, Y, Z order")
    if any(not isfinite(p) or p < 0 or p > 1 for p in values) or sum(values) > 1:
        raise ValueError(
            "Pauli probabilities must be finite, nonnegative, and sum to at most 1"
        )
    spread = float(spread_probability)
    if not isfinite(spread) or not 0 <= spread <= 1:
        raise ValueError("spread_probability must be finite and in [0, 1]")
    object.__setattr__(self, "pauli", values)
    object.__setattr__(self, "spread_probability", spread)

clifft.noncomp.InteractionRule dataclass

InteractionRule(
    *,
    gate: str,
    source_operand: int,
    source_status: Literal["leaked", "lost"],
    effect: PartnerEffect,
)

Replace a gate's default effect for one source status and direction.

source_operand is 0 for the first operand in each ordered gate pair, or 1 for the second. source_status is "leaked" (either leaked level) or "lost". The other operand must be computational. The entire effect replaces the matching default; PartnerEffect() disables it. Model validates gate support and rejects duplicate canonical rules, including aliases such as CX and CNOT. Rules do not affect virtual feedback.

clifft.noncomp.Classifier

Classifier(matrix: Matrix)

A measurement classifier: P[symbol][level] stochastic matrix.

The matrix must have two or three rows, and every level column must sum to one. The first two rows give the probabilities of recording 0 or 1. An optional third row heralds the measurement, typically for loss. NonComputationalSample.heralds reports that symbol separately while the binary measurement record receives a uniformly sampled placeholder.

For M and MR on a computational site, the g and e columns can model Z-basis readout confusion after the quantum measurement. Computational MX, MY, MRX, and MRY measurements do not use those columns. On a leaked or lost site, every supported single-site measurement uses the corresponding classifier column regardless of basis. A computational column may not assign probability to the herald symbol.

Source code in .venv/lib/python3.12/site-packages/clifft/noncomp.py
def __init__(self, matrix: Matrix) -> None:
    self.matrix = _as_matrix(matrix)

clifft.noncomp.NonComputationalSample

NonComputationalSample(
    measurements: NDArray[uint8],
    detectors: NDArray[uint8],
    observables: NDArray[uint8],
    final_status: NDArray[uint8] | None,
    heralds: NDArray[uint8],
    num_qubits: int,
    num_measurements: int,
    num_detectors: int,
    num_observables: int,
    *,
    stats: NonComputationalStats | None = None,
)

Sampling outputs with optional detailed final status and statistics.

Attributes:

Name Type Description
measurements, (detectors, observables)

uint8 arrays, shape (shots, width).

final_status

None unless requested, otherwise a uint8 array (shots, num_qubits) of QubitStatus values. Reports the definite noncomputational level per site and shot: LEAK_G and LEAK_E are individually distinguishable. Computational sites report as QubitStatus.COMPUTATIONAL rather than G or E because their state remains quantum in the executor and may not be a definite level.

heralds

uint8 array (shots, num_measurements); 1 where the classifier sampled the herald (third) symbol for that slot, else 0.

shots, (num_qubits, num_measurements, num_detectors, num_observables)

ints.

stats

NonComputationalStats when collect_stats=True, otherwise None.

Source code in .venv/lib/python3.12/site-packages/clifft/noncomp.py
def __init__(
    self,
    measurements: npt.NDArray[np.uint8],
    detectors: npt.NDArray[np.uint8],
    observables: npt.NDArray[np.uint8],
    final_status: npt.NDArray[np.uint8] | None,
    heralds: npt.NDArray[np.uint8],
    num_qubits: int,
    num_measurements: int,
    num_detectors: int,
    num_observables: int,
    *,
    stats: NonComputationalStats | None = None,
) -> None:
    self.measurements = measurements
    self.detectors = detectors
    self.observables = observables
    self.final_status = final_status
    self.heralds = heralds
    self.shots = int(measurements.shape[0])
    self.num_qubits = int(num_qubits)
    self.num_measurements = int(num_measurements)
    self.num_detectors = int(num_detectors)
    self.num_observables = int(num_observables)
    self.stats = stats

symbols

symbols() -> npt.NDArray[np.uint8]

Return measurement symbols, using 2 for heralded slots.

This returns a copy of measurements with each heralded placeholder replaced by 2.

Source code in .venv/lib/python3.12/site-packages/clifft/noncomp.py
def symbols(self) -> npt.NDArray[np.uint8]:
    """Return measurement symbols, using 2 for heralded slots.

    This returns a copy of ``measurements`` with each heralded placeholder
    replaced by 2.
    """
    out = self.measurements.copy()
    out[self.heralds != 0] = 2
    return out

clifft.noncomp.Level

Bases: IntEnum

Indices of the built-in five-level model, for naming matrix rows/columns.

clifft.noncomp.QubitStatus

Bases: IntEnum

Per-site status stored in NonComputationalSample.final_status.

These are per-site status codes, not matrix indices. Level names matrix rows and columns (indices 0--4); QubitStatus names per-qubit outcomes (codes 0--3). The two enums share member names (LEAK_G, LEAK_E, LOST) with different integer values -- never substitute one for the other.

LEAK_G and LEAK_E are individually distinguishable in final_status, unlike the coarse leaked/lost grouping some tools use.

Strong Simulation

clifft.basis_probabilities

basis_probabilities(
    program: Program,
    bitstrings: BasisBitstrings,
    *,
    bit_order: str = "big",
    return_log: bool = False,
) -> npt.NDArray[np.float64]

Exact Born probabilities of computational-basis bitstrings.

Requires a unitary program (no measurements, feedback, noise, detectors, observables, or post-selection). For circuits with measurements, use :func:record_probabilities instead.

bit_order="big" maps the first character or array column to qubit 0. bit_order="little" maps the last character or array column to qubit 0.

Pass return_log=True to get natural-log probabilities. Zero probabilities map to -inf in log output.

Source code in .venv/lib/python3.12/site-packages/clifft/__init__.py
def basis_probabilities(
    program: Program,
    bitstrings: BasisBitstrings,
    *,
    bit_order: str = "big",
    return_log: bool = False,
) -> npt.NDArray[np.float64]:
    """Exact Born probabilities of computational-basis bitstrings.

    Requires a unitary program (no measurements, feedback, noise, detectors,
    observables, or post-selection). For circuits with measurements, use
    :func:`record_probabilities` instead.

    ``bit_order="big"`` maps the first character or array column to qubit 0.
    ``bit_order="little"`` maps the last character or array column to qubit 0.

    Pass ``return_log=True`` to get natural-log probabilities. Zero
    probabilities map to ``-inf`` in log output.
    """
    probs = cast(
        npt.NDArray[np.float64],
        _basis_probabilities_from_bitmasks(
            program, _basis_masks_from_bitstrings(program, bitstrings, bit_order)
        ),
    )
    if return_log:
        # TODO: move logspace accumulation into the C++ amplitude walk so
        # very-rare-bitstring queries don't lose precision through the
        # linear->log conversion. Current path is symmetric with
        # record_probabilities() at the API surface but does not give the
        # precision benefit; that benefit only kicks in once the underlying
        # |amplitude|^2 sum is itself tracked in logspace.
        with np.errstate(divide="ignore"):
            return np.log(probs)
    return probs

clifft.record_probabilities

record_probabilities(
    program: Program,
    records: MeasurementRecords,
    *,
    return_log: bool = False,
) -> npt.NDArray[np.float64]

Exact joint probabilities of measurement records under sample().

Requires at least one measurement. For a purely unitary program with no measurements, use :func:basis_probabilities instead.

records is one of: a single record string (e.g. "010"), a sequence of record strings, or a 2D bool / uint8 array of shape (num_records, program.num_measurements). Each record is interpreted in measurement order -- position i is the i-th entry sample().measurements would emit.

Records the program cannot emit are reported as 0.0 (or -inf when return_log=True). For deep circuits whose probabilities underflow float64, pass return_log=True so the log-domain values survive.

Source code in .venv/lib/python3.12/site-packages/clifft/__init__.py
def record_probabilities(
    program: Program,
    records: MeasurementRecords,
    *,
    return_log: bool = False,
) -> npt.NDArray[np.float64]:
    """Exact joint probabilities of measurement records under ``sample()``.

    Requires at least one measurement. For a purely unitary program with no
    measurements, use :func:`basis_probabilities` instead.

    ``records`` is one of: a single record string (e.g. ``"010"``), a
    sequence of record strings, or a 2D ``bool`` / ``uint8`` array of
    shape ``(num_records, program.num_measurements)``. Each record is
    interpreted in measurement order -- position ``i`` is the i-th entry
    sample().measurements would emit.

    Records the program cannot emit are reported as ``0.0`` (or ``-inf``
    when ``return_log=True``). For deep circuits whose probabilities
    underflow float64, pass ``return_log=True`` so the log-domain values
    survive.
    """
    # Reject zero-measurement programs up front so a user who passes a real
    # record string against a unitary program gets the right hint rather
    # than the wrapper's record-length mismatch error.
    if program.num_measurements == 0:
        raise ValueError(
            "record_probabilities() requires a program with at least one "
            "measurement; use clifft.basis_probabilities() for unitary circuits."
        )
    record_array = _records_from_outcomes(program, records)
    log_probs = cast(
        npt.NDArray[np.float64],
        _record_probabilities_from_records(program, record_array),
    )
    # C++ marks unreachable records with the finite sentinel
    # numpy.finfo(float64).min (-DBL_MAX). Translate it back to the
    # Pythonic -inf for log output, and rely on the natural underflow
    # to 0.0 under np.exp for the linear case.
    if return_log:
        return np.where(log_probs == np.finfo(np.float64).min, -np.inf, log_probs)
    return np.exp(log_probs)

State Inspection

clifft.get_statevector

get_statevector(
    program: Program,
) -> Annotated[NDArray[numpy.complex128], dict(order=C)]

get_statevector(program: clifft._clifft_core.Program) -> numpy.ndarray[dtype=complex128, order='C']

Return a dense representative of a compiled pure-unitary program's final state.

The result is normalized and defined only up to global phase. Relative amplitudes and phases are preserved, but the global phase may vary across equivalent source circuits, compiler pass configurations, or Clifft versions.

Result Types

clifft.SampleResult

SampleResult(
    measurements: NDArray[uint8],
    detectors: NDArray[uint8],
    observables: NDArray[uint8],
    total_shots: int | None = None,
    passed_shots: int | None = None,
    logical_errors: int | None = None,
    observable_ones: NDArray[uint64] | None = None,
    exp_vals: NDArray[float64] | None = None,
    batch_tuning: BatchTuningReport | None = None,
)

Structured result from Clifft sampling functions.

Common attributes

measurements: uint8 array, shape (shots, num_measurements) detectors: uint8 array, shape (shots, num_detectors) observables: uint8 array, shape (shots, num_observables) batch_tuning: calibration report when batch_size="tune", otherwise None

Survivor-only attributes

total_shots: total number of shots attempted passed_shots: number of shots that survived post-selection discards: number of discarded shots (total_shots - passed_shots) logical_errors: number of surviving shots with at least one observable flipped observable_ones: uint64 array of per-observable error counts

Supports tuple unpacking for backward compatibility:

m, d, o = clifft.sample(prog, shots)
Source code in .venv/lib/python3.12/site-packages/clifft/_sample_result.py
def __init__(
    self,
    measurements: npt.NDArray[np.uint8],
    detectors: npt.NDArray[np.uint8],
    observables: npt.NDArray[np.uint8],
    total_shots: int | None = None,
    passed_shots: int | None = None,
    logical_errors: int | None = None,
    observable_ones: npt.NDArray[np.uint64] | None = None,
    exp_vals: npt.NDArray[np.float64] | None = None,
    batch_tuning: BatchTuningReport | None = None,
) -> None:
    self.batch_tuning = batch_tuning
    self.measurements = measurements
    self.detectors = detectors
    self.observables = observables
    self.exp_vals = (
        exp_vals
        if exp_vals is not None
        else np.empty((measurements.shape[0], 0), dtype=np.float64)
    )
    self.total_shots = total_shots
    self.passed_shots = passed_shots
    self.discards = (
        None if total_shots is None or passed_shots is None else total_shots - passed_shots
    )
    self.logical_errors = logical_errors
    self.observable_ones = observable_ones

clifft.BatchTuningReport

Calibration outcome and reusable batch size. sufficient_measurements says whether the automatic choice and an alternative were compared; stop_reason records why calibration ended, including budget exhaustion even when falling back to auto.

baseline_batch_size property

baseline_batch_size: int

(self) -> int

batch_size property

batch_size: int

(self) -> int

elapsed_seconds property

elapsed_seconds: float

(self) -> float

intra_shot_workers property

intra_shot_workers: int

(self) -> int

shot_workers property

shot_workers: int

(self) -> int

stop_reason property

stop_reason: str

(self) -> str

sufficient_measurements property

sufficient_measurements: bool

(self) -> bool

trial_shots property

trial_shots: int

(self) -> int

trials property

trials: list[BatchTuningTrial]

(self) -> list[clifft._clifft_core.BatchTuningTrial]

clifft.BatchTuningTrial

Timing for one batch-size candidate. The first probe is recorded as warmup; its throughput is used when no subsequent measurement is available.

batch_size property

batch_size: int

(self) -> int

elapsed_seconds property

elapsed_seconds: float

(self) -> float

setup_seconds property

setup_seconds: float

(self) -> float

shot_workers property

shot_workers: int

(self) -> int

shots property

shots: int

(self) -> int

shots_per_second property

shots_per_second: float

Attempted-shot throughput used for selection, or zero without timing data.

used_warmup property

used_warmup: bool

Whether throughput comes from the first probe only.

warmup_seconds property

warmup_seconds: float

(self) -> float

warmup_shots property

warmup_shots: int

(self) -> int

Compiled Programs

clifft.Program

A reusable compiled sampling program

has_postselection property

has_postselection: bool

(self) -> bool

noise_site_probabilities property

noise_site_probabilities: Annotated[
    NDArray[float64], dict(order=C)
]

Per-site total fault probabilities: quantum noise sites followed by readout noise.

num_actions property

num_actions: int

(self) -> int

num_detectors property

num_detectors: int

(self) -> int

num_exp_vals property

num_exp_vals: int

(self) -> int

num_hidden_measurements property

num_hidden_measurements: int

(self) -> int

num_measurements property

num_measurements: int

(self) -> int

num_observables property

num_observables: int

(self) -> int

num_qubits property

num_qubits: int

(self) -> int

peak_active_width property

peak_active_width: int

Largest active width reached by the compiled program.

peak_rank property

peak_rank: int

Deprecated alias for peak_active_width.

inspect method descriptor

inspect() -> str

inspect(self) -> str

Deterministic human-readable diagnostic text for the whole lowered CPU program.

The format is diagnostic output for debugging and tooling, not a stable machine-readable interface.

inspect_action method descriptor

inspect_action(action: int) -> str

inspect_action(self, action: int) -> str

Deterministic human-readable diagnostic text for a single action in the lowered CPU program.

The format is diagnostic output for debugging and tooling, not a stable machine-readable interface.

Circuit and IR Inspection

clifft.Circuit

A parsed quantum circuit

nodes property

nodes: list[AstNode]

(self) -> list[clifft._clifft_core.AstNode]

num_measurements property

num_measurements: int

(self) -> int

num_qubits property

num_qubits: int

(self) -> int

clifft.Qasm2Import

A natively parsed unitary OpenQASM 2 circuit and its source phase correction

circuit property

circuit: Circuit

(self) -> clifft._clifft_core.Circuit

global_phase_half_turns property

global_phase_half_turns: float

Source phase correction t representing exp(i * pi * t).

num_qubits property

num_qubits: int

(self) -> int

clifft.AstNode

A single circuit operation

arg property

arg: float

(self) -> float

args property

args: list[float]

(self) -> list[float]

gate property

gate: GateType

(self) -> clifft._clifft_core.GateType

source_line property

source_line: int

(self) -> int

tag property

tag: str

(self) -> str

targets property

targets: list[Target]

(self) -> list[clifft._clifft_core.Target]

clifft.Target

Encoded quantum target

has_pauli property

has_pauli: bool

(self) -> bool

is_inverted property

is_inverted: bool

(self) -> bool

is_rec property

is_rec: bool

(self) -> bool

pauli property

pauli: int

(self) -> int

pauli_char property

pauli_char: str

(self) -> str

value property

value: int

(self) -> int

clifft.HirModule

Heisenberg Intermediate Representation

expected_detectors property

expected_detectors: list[int]

Optional noiseless reference parities for detectors.

expected_observables property

expected_observables: list[int]

Optional noiseless reference parities for observables.

num_detectors property

num_detectors: int

(self) -> int

num_exp_vals property

num_exp_vals: int

(self) -> int

num_measurements property

num_measurements: int

(self) -> int

num_observables property

num_observables: int

(self) -> int

num_ops property

num_ops: int

(self) -> int

num_qubits property

num_qubits: int

(self) -> int

num_t_gates property

num_t_gates: int

(self) -> int

postselection_mask property

postselection_mask: list[int]

Optional list of uint8 flags, one per detector, marking postselected detectors.

source_map property

source_map: list

Source line mapping parallel to ops (list of list of uint32).

as_dict method descriptor

as_dict() -> dict

as_dict(self) -> dict

Return a JSON-friendly dictionary representation.

clifft.HeisenbergOp

A single abstract operation in the Heisenberg IR

is_dagger property

is_dagger: bool

(self) -> bool

is_hidden property

is_hidden: bool

(self) -> bool

op_type property

op_type: OpType

(self) -> clifft._clifft_core.OpType

pauli_string property

pauli_string: str

(self) -> str

sign property

sign: bool

(self) -> bool

as_dict method descriptor

as_dict() -> dict

as_dict(self) -> dict

Return a JSON-friendly dictionary representation.

clifft.OpType

Bases: enum.Enum

Heisenberg IR operation types

clifft.GateType

Bases: enum.Enum

Quantum gate types

Pass Managers

clifft.HirPass

Abstract base class for HIR optimization passes.

clifft.HirPassManager

HirPassManager()

Runs a sequence of optimization passes over an HirModule.

init(self) -> None

add method descriptor

add(hir_pass: HirPass) -> None

add(self, hir_pass: clifft._clifft_core.HirPass) -> None

Add an optimization pass. Passes run in the order added.

run method descriptor

run(hir: HirModule) -> None

run(self, hir: clifft._clifft_core.HirModule) -> None

Run all passes on the HIR module in sequence.

clifft.default_hir_pass_manager

default_hir_pass_manager(
    *, overrides: Sequence[HirPass] = ()
) -> HirPassManager

default_hir_pass_manager(*, overrides: collections.abc.Sequence[HirPass] = ()) -> HirPassManager

Return the default pipeline, replacing selected passes in their original slots.

Overrides must be instances of distinct default-enabled pass types. The manager retains these instances; their statistics remain available after a run.

HIR Passes

clifft.PeepholeFusionPass

PeepholeFusionPass()

Bases: clifft._clifft_core.HirPass

Symplectic peephole optimization: cancels and fuses T/T-dag gates, canonicalizes rotations within 1e-12 half-turns, and removes terminal phases consumed by same-axis measurements.

init(self) -> None

cancellations property

cancellations: int

(self) -> int

fusions property

fusions: int

(self) -> int

clifft.PhasePolynomialPass

PhasePolynomialPass(
    max_variables: int = 128,
    *,
    max_wide_work: int = 50000000,
    max_wide_terms: int = 200000,
)

Bases: clifft._clifft_core.HirPass

Reduce commuting T rotations using fixed constraints from the all-zero input, measurements, and feedback. Run after peephole fusion and before squeezing or scheduling.

init(self, max_variables: int = 128, *, max_wide_work: int = 50000000, max_wide_terms: int = 200000) -> None

applied property

applied: bool

(self) -> bool

blocks_reduced property

blocks_reduced: int

(self) -> int

input_t_count property

input_t_count: int

(self) -> int

output_t_count property

output_t_count: int

(self) -> int

pauli_pullbacks property

pauli_pullbacks: int

(self) -> int

wide_attempts property

wide_attempts: int

(self) -> int

wide_budget_exhausted property

wide_budget_exhausted: bool

(self) -> bool

wide_rewrites property

wide_rewrites: int

(self) -> int

wide_work property

wide_work: int

(self) -> int

clifft.RotationSimplificationPass

RotationSimplificationPass(
    max_region_ops: int = 256, max_region_passes: int = 8
)

Bases: clifft._clifft_core.HirPass

Simplify Pauli rotations using outcome-independent stabilizer constraints. Run after PhasePolynomialPass and before squeezing or scheduling.

init(self, max_region_ops: int = 256, max_region_passes: int = 8) -> None

applied property

applied: bool

(self) -> bool

regions_capped property

regions_capped: int

(self) -> int

regions_examined property

regions_examined: int

(self) -> int

regions_reduced property

regions_reduced: int

(self) -> int

rotations_removed property

rotations_removed: int

(self) -> int

clifft.StatevectorSqueezePass

StatevectorSqueezePass()

Bases: clifft._clifft_core.HirPass

Bidirectional bubble sort: moves measurements leftward and non-Clifford gates rightward to minimize peak active width.

init(self) -> None

clifft.active_width_trace

active_width_trace(hir: HirModule) -> dict

active_width_trace(hir: clifft._clifft_core.HirModule) -> dict

Structural active-width trace of an HIR module, without lowering it to an executable program.

Returns a dict with 'initial', 'peak', and 'final' width, plus per-op 'widths' (the width after each op) and 'effects' (a lower-case effect name per op).

clifft.ActiveWidthSchedulePass

ActiveWidthSchedulePass(
    noise_transparent: bool = True,
    beam_width: int = 8,
    search_budget: float | None = 16.0,
    sink_neutral_rotations: bool = True,
)

Bases: clifft._clifft_core.HirPass

State-aware beam search over the schedule-dependence trace class that reduces peak active width, then a dense-work estimate. Opt in by adding it after PeepholeFusionPass and StatevectorSqueezePass.

init(self, noise_transparent: bool = True, beam_width: int = 8, search_budget: float | None = 16.0, sink_neutral_rotations: bool = True) -> None

applied property

applied: bool

(self) -> bool

classification_probes property

classification_probes: int

(self) -> int

incumbent_dense_work property

incumbent_dense_work: float

(self) -> float

incumbent_peak property

incumbent_peak: int

(self) -> int

result_dense_work property

result_dense_work: float

(self) -> float

result_peak property

result_peak: int

(self) -> int

swept_ops property

swept_ops: int

(self) -> int

clifft.RemoveNoisePass

RemoveNoisePass()

Bases: clifft._clifft_core.HirPass

Strips all stochastic noise and readout noise ops from the HIR. Not included in the default pass list. Used internally by compute_reference_syndrome() for noiseless reference shots.

init(self) -> None

clifft.DropNonUnitaryPass

DropNonUnitaryPass()

Bases: clifft._clifft_core.HirPass

Drops non-evolution HIR ops so the remaining program is a unitary skeleton. Not included in the default pass list and not semantics-preserving.

init(self) -> None

Utilities

clifft.version

version() -> str

version() -> str

Return the Clifft version string

clifft.runtime_isa

runtime_isa() -> str

runtime_isa() -> str

Return the resolved kernel ISA: 'scalar', 'neon', 'avx2', 'avx512', or a 'trap:...' value when CLIFFT_FORCE_ISA requests an unavailable backend

clifft.compute_reference_syndrome

compute_reference_syndrome(hir: HirModule) -> dict

compute_reference_syndrome(hir: clifft._clifft_core.HirModule) -> dict

Compute noiseless reference syndrome for an HirModule.

Removes stochastic and readout noise and samples one shot at seed 0. Does not check determinism; coherent rotations remain. For coherent errors, pass the intended ideal circuit's HIR instead. Returns a dict with 'detectors' and 'observables' lists.

Type Aliases

clifft.BasisBitstrings module-attribute

BasisBitstrings: TypeAlias = (
    str | Sequence[str] | NDArray[bool_] | NDArray[uint8]
)

clifft.MeasurementRecords module-attribute

MeasurementRecords: TypeAlias = (
    str | Sequence[str] | NDArray[bool_] | NDArray[uint8]
)