MeasurementStage

class MeasurementStage(grouping_strategy='qwc', result_format_override=None, shot_distribution=None)[source]

Bases: BundleStage

Unified measurement stage for all circuit measurement types.

Handles both probs() and expval(H) measurements, auto-detecting the measurement type from the MetaCircuit. For expval(H), groups observables using the configured strategy (or delegates to expval-native backends via ham_ops).

During expand, records result_format on each circuit to communicate the expected result format to pipeline.run():

  • ResultFormat.PROBS for probs() measurements

  • ResultFormat.EXPVALS for expval(H) measurements

  • ResultFormat.COUNTS is never set here (reserved for PCE)

During reduce, combines measurement groups using the postprocessing function from _compute_measurement_groups.

Parameters:
  • grouping_strategy (Literal['wires', 'default', 'qwc', '_backend_expval'] | None) – Grouping strategy for expval observables. Ignored for probs() measurements. Defaults to “qwc” (qubit-wise commuting).

  • result_format_override (ResultFormat | None) – If set, overrides the auto-detected result format. For example, pass ResultFormat.COUNTS to get raw shot counts even when an observable is present.

  • shot_distribution (Literal['uniform', 'weighted', 'weighted_random'] | Callable[[list[float], int], list[int]] | None) – How to split the backend’s total shot budget across measurement groups ("uniform", "weighted", "weighted_random", or a callable). Only affects results on a sampling backend (supports_expval=False); on a backend that computes expectation values analytically it is recorded but does not change the exact result, and expand emits a UserWarning saying so. Pairing it with an explicit grouping_strategy="_backend_expval" raises ValueError. When None (default), every group is submitted with the backend’s full shot count.

Attributes Summary

axis_name

Axis name introduced by this stage.

consumes_dag_bodies

Whether this stage reads meta.circuit_bodies during expand.

handles_measurement

Whether this stage sets up measurement circuits and result format.

volatile

True only for genuinely non-deterministic shot-distribution strategies.

Methods Summary

cache_key_extras(env)

Fold the effective shot budget / variance flag into the forward-pass cache key.

dry_expand(batch, env)

Analytic path: keep grouping + shot allocation, skip QASM rendering.

expand(batch, env)

Set up measurements and declare the result format on env.

introspect(batch, env, token)

Return stage-specific metadata for dry-run reporting.

reduce(results, env, token)

Combine measurement groups (expval) or strip meas axis (probs).

Attributes Documentation

axis_name
consumes_dag_bodies
handles_measurement
volatile

True only for genuinely non-deterministic shot-distribution strategies.

"weighted_random" and user-supplied callables draw from env.rng and must re-run on every call. The built-in deterministic strategies ("uniform", "weighted") are pure functions of the observable and the shot count, so they stay cacheable; cache invalidation on shot-count changes is delegated to cache_key_extras().

Methods Documentation

cache_key_extras(env)[source]

Fold the effective shot budget / variance flag into the forward-pass cache key.

A configured shot distribution (even the deterministic ones) reads the shot budget during expand() to compute the per-group allocation; so does an active shots_override (which materialises uniform per-group shots). Including the budget means a re-run with a different one triggers fresh allocation rather than replaying a stale one. collect_variance is folded in too, since it changes the per-call post-processing. Returns () in the default case (no distribution, no override, no variance) so caching is unaffected.

Return type:

tuple[Hashable, ...]

dry_expand(batch, env)[source]

Analytic path: keep grouping + shot allocation, skip QASM rendering.

Group count is the source of truth for the measurement fan-out, so we always run _compute_measurement_groups and _allocate_per_group_shots (both cheap, pure numpy / analytic). Only the per-group QASM string generation is swapped for a placeholder so the emitted batch has correct shape without materialising measurement circuits.

Return type:

StageOutput[dict[tuple[tuple[str, Hashable], ...], MetaCircuit]]

expand(batch, env)[source]

Set up measurements and declare the result format on env.

Return type:

StageOutput[dict[tuple[tuple[str, Hashable], ...], MetaCircuit]]

introspect(batch, env, token)[source]

Return stage-specific metadata for dry-run reporting.

Override in subclasses to provide richer introspection data. Called by the dry-run tool after expand with the post-expand batch, the pipeline env, and the stage’s token.

Return type:

dict[str, Any]

reduce(results, env, token)[source]

Combine measurement groups (expval) or strip meas axis (probs).

Return type:

dict[Any, Any]