Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dev/util_gen_stub_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
"__next__",
}
skip = {
"__annotate_func__",
"__annotations_cache__",
"__firstlineno__",
"__static_attributes__",
"__replace__",
Expand Down
14 changes: 13 additions & 1 deletion doc/gates.md
Original file line number Diff line number Diff line change
Expand Up @@ -4879,13 +4879,19 @@ detection event simulations and affect whether the observable is included in err
makes it easier to benchmark all observables of a code, without having to introduce noiseless qubits entangled with the
logical qubit to avoid the testing of the X observable anticommuting with the testing of the Z observable.

Unlike a `DETECTOR` instruction which provides a complete description of a detector by listing all its constituent
measurement records, an individual `OBSERVABLE_INCLUDE` instruction is not required to (and generally does not) fully
describe a logical observable. Instead, measurement records or Pauli targets are added to it incrementally. A logical
observable can be given both types of description: as a collection of Pauli targets and as a collection of measurement
record targets.

Parens Arguments:

A non-negative integer specifying the index of the logical observable to add the measurement records to.

Targets:

The measurement records to add to the specified observable.
The measurement records or Pauli terms to add to the specified observable.

Example:

Expand Down Expand Up @@ -4921,6 +4927,12 @@ Example:
OBSERVABLE_INCLUDE(0) X0 X1
OBSERVABLE_INCLUDE(1) Z0 Z2

# Stim circuit may include a description of an observable in terms of Pauli targets
# alongside a description in terms of measurement records.
OBSERVABLE_INCLUDE(0) Z0 Z1
M 0 1
OBSERVABLE_INCLUDE(0) rec[-2] rec[-1]

<a name="QUBIT_COORDS"></a>
### The 'QUBIT_COORDS' Instruction

Expand Down
126 changes: 63 additions & 63 deletions doc/sinter_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,11 @@ class CollectionOptions:
biggest batch size that can finish in under the given number of
seconds. Limits each batch to be no larger than that.
"""
max_shots: Optional[int] = None
max_errors: Optional[int] = None
start_batch_size: Optional[int] = None
max_batch_size: Optional[int] = None
max_batch_seconds: Optional[float] = None
max_shots: Union = None
max_errors: Union = None
start_batch_size: Union = None
max_batch_size: Union = None
max_batch_seconds: Union = None
```

<a name="sinter.CollectionOptions.combine"></a>
Expand Down Expand Up @@ -461,9 +461,9 @@ class Fit:
of the best fit's square error, or whose likelihood was within some
maximum Bayes factor of the max likelihood hypothesis.
"""
low: Optional[float]
best: Optional[float]
high: Optional[float]
low: Union
best: Union
high: Union
```

<a name="sinter.Progress"></a>
Expand Down Expand Up @@ -586,16 +586,16 @@ class Task:
def __init__(
self,
*,
circuit: Optional[stim.Circuit] = None,
decoder: Optional[str] = None,
detector_error_model: Optional[stim.DetectorErrorModel] = None,
postselection_mask: Optional[np.ndarray] = None,
postselected_observables_mask: Optional[np.ndarray] = None,
circuit: stim.Circuit | None = None,
decoder: str | None = None,
detector_error_model: stim.DetectorErrorModel | None = None,
postselection_mask: np.ndarray | None = None,
postselected_observables_mask: np.ndarray | None = None,
json_metadata: Any = None,
collection_options: sinter.CollectionOptions = sinter.CollectionOptions(),
skip_validation: bool = False,
circuit_path: Union[str, pathlib.Path, NoneType] = None,
_unvalidated_strong_id: Optional[str] = None,
circuit_path: str | pathlib.Path | None = None,
_unvalidated_strong_id: str | None = None,
) -> None:
"""
Args:
Expand Down Expand Up @@ -864,14 +864,14 @@ def to_csv_line(
def with_edits(
self,
*,
strong_id: Optional[str] = None,
decoder: Optional[str] = None,
json_metadata: Optional[Any] = None,
shots: Optional[int] = None,
errors: Optional[int] = None,
discards: Optional[int] = None,
seconds: Optional[float] = None,
custom_counts: Optional[Counter[str]] = None,
strong_id: str | None = None,
decoder: str | None = None,
json_metadata: Any | None = None,
shots: int | None = None,
errors: int | None = None,
discards: int | None = None,
seconds: float | None = None,
custom_counts: Counter[str] | None = None,
) -> sinter.TaskStats:
```

Expand Down Expand Up @@ -925,23 +925,23 @@ def better_sorted_str_terms(
def collect(
*,
num_workers: int,
tasks: Union[Iterator[sinter.Task], Iterable[sinter.Task]],
existing_data_filepaths: Iterable[Union[str, pathlib.Path]] = (),
save_resume_filepath: Union[NoneType, str, pathlib.Path] = None,
progress_callback: Optional[Callable[[sinter.Progress], NoneType]] = None,
max_shots: Optional[int] = None,
max_errors: Optional[int] = None,
tasks: Iterator[sinter.Task] | Iterable[sinter.Task],
existing_data_filepaths: Iterable[str | pathlib.Path] = (),
save_resume_filepath: None | str | pathlib.Path = None,
progress_callback: Callable[[sinter.Progress], NoneType] | None = None,
max_shots: int | None = None,
max_errors: int | None = None,
count_observable_error_combos: bool = False,
count_detection_events: bool = False,
decoders: Optional[Iterable[str]] = None,
max_batch_seconds: Optional[int] = None,
max_batch_size: Optional[int] = None,
start_batch_size: Optional[int] = None,
decoders: Iterable[str] | None = None,
max_batch_seconds: int | None = None,
max_batch_size: int | None = None,
start_batch_size: int | None = None,
print_progress: bool = False,
hint_num_tasks: Optional[int] = None,
custom_decoders: Optional[Dict[str, Union[sinter.Decoder, sinter.Sampler]]] = None,
custom_error_count_key: Optional[str] = None,
allowed_cpu_affinity_ids: Optional[Iterable[int]] = None,
hint_num_tasks: int | None = None,
custom_decoders: Dict[str, sinter.Decoder | sinter.Sampler] | None = None,
custom_error_count_key: str | None = None,
allowed_cpu_affinity_ids: Iterable[int] | None = None,
) -> List[sinter.TaskStats]:
"""Collects statistics from the given tasks, using multiprocessing.

Expand Down Expand Up @@ -1252,20 +1252,20 @@ def group_by(
def iter_collect(
*,
num_workers: int,
tasks: Union[Iterator[sinter.Task], Iterable[sinter.Task]],
hint_num_tasks: Optional[int] = None,
additional_existing_data: Union[NoneType, Dict[str, sinter.TaskStats], Iterable[sinter.TaskStats]] = None,
max_shots: Optional[int] = None,
max_errors: Optional[int] = None,
decoders: Optional[Iterable[str]] = None,
max_batch_seconds: Optional[int] = None,
max_batch_size: Optional[int] = None,
start_batch_size: Optional[int] = None,
tasks: Iterator[sinter.Task] | Iterable[sinter.Task],
hint_num_tasks: int | None = None,
additional_existing_data: None | Dict[str, sinter.TaskStats] | Iterable[sinter.TaskStats] = None,
max_shots: int | None = None,
max_errors: int | None = None,
decoders: Iterable[str] | None = None,
max_batch_seconds: int | None = None,
max_batch_size: int | None = None,
start_batch_size: int | None = None,
count_observable_error_combos: bool = False,
count_detection_events: bool = False,
custom_decoders: Optional[Dict[str, Union[sinter.Decoder, sinter.Sampler]]] = None,
custom_error_count_key: Optional[str] = None,
allowed_cpu_affinity_ids: Optional[Iterable[int]] = None,
custom_decoders: Dict[str, sinter.Decoder | sinter.Sampler] | None = None,
custom_error_count_key: str | None = None,
allowed_cpu_affinity_ids: Iterable[int] | None = None,
) -> Iterator[sinter.Progress]:
"""Iterates error correction statistics collected from worker processes.

Expand Down Expand Up @@ -1377,7 +1377,7 @@ def iter_collect(
# (at top-level in the sinter module)
def log_binomial(
*,
p: Union[float, np.ndarray],
p: float | np.ndarray,
n: int,
hits: int,
) -> np.ndarray:
Expand Down Expand Up @@ -1466,7 +1466,7 @@ def plot_discard_rate(
group_func: Callable[[sinter.TaskStats], ~TCurveId] = lambda _: None,
filter_func: Callable[[sinter.TaskStats], Any] = lambda _: True,
plot_args_func: Callable[[int, ~TCurveId, List[sinter.TaskStats]], Dict[str, Any]] = lambda index, group_key, group_stats: dict(),
highlight_max_likelihood_factor: Optional[float] = 1000.0,
highlight_max_likelihood_factor: float | None = 1000.0,
point_label_func: Callable[[sinter.TaskStats], Any] = lambda _: None,
) -> None:
"""Plots discard rates in curves with uncertainty highlights.
Expand Down Expand Up @@ -1530,8 +1530,8 @@ def plot_error_rate(
group_func: Callable[[sinter.TaskStats], ~TCurveId] = lambda _: None,
filter_func: Callable[[sinter.TaskStats], Any] = lambda _: True,
plot_args_func: Callable[[int, ~TCurveId, List[sinter.TaskStats]], Dict[str, Any]] = lambda index, group_key, group_stats: dict(),
highlight_max_likelihood_factor: Optional[float] = 1000.0,
line_fits: Optional[Tuple[Literal['linear', 'log', 'sqrt'], Literal['linear', 'log', 'sqrt']]] = None,
highlight_max_likelihood_factor: float | None = 1000.0,
line_fits: Tuple[Literal['linear', 'log', 'sqrt'], Literal['linear', 'log', 'sqrt']] | None = None,
point_label_func: Callable[[sinter.TaskStats], Any] = lambda _: None,
) -> None:
"""Plots error rates in curves with uncertainty highlights.
Expand Down Expand Up @@ -1593,7 +1593,7 @@ def plot_error_rate(

# (at top-level in the sinter module)
def post_selection_mask_from_4th_coord(
dem: Union[stim.Circuit, stim.DetectorErrorModel],
dem: stim.Circuit | stim.DetectorErrorModel,
) -> np.ndarray:
"""Returns a mask that postselects detector's with non-zero 4th coordinate.

Expand Down Expand Up @@ -1666,7 +1666,7 @@ def predict_observables(
dets: np.ndarray,
decoder: str,
bit_pack_result: bool = False,
custom_decoders: Optional[Dict[str, sinter.Decoder]] = None,
custom_decoders: Dict[str, sinter.Decoder] | None = None,
) -> np.ndarray:
"""Predicts which observables were flipped based on detection event data.

Expand Down Expand Up @@ -1729,7 +1729,7 @@ def predict_observables_bit_packed(
dem: stim.DetectorErrorModel,
dets_bit_packed: np.ndarray,
decoder: str,
custom_decoders: Optional[Dict[str, sinter.Decoder]] = None,
custom_decoders: Dict[str, sinter.Decoder] | None = None,
) -> np.ndarray:
"""Predicts which observables were flipped based on detection event data.

Expand Down Expand Up @@ -1786,14 +1786,14 @@ def predict_observables_bit_packed(
def predict_on_disk(
*,
decoder: str,
dem_path: Union[str, pathlib.Path],
dets_path: Union[str, pathlib.Path],
dem_path: str | pathlib.Path,
dets_path: str | pathlib.Path,
dets_format: str,
obs_out_path: Union[str, pathlib.Path],
obs_out_path: str | pathlib.Path,
obs_out_format: str,
postselect_detectors_with_non_zero_4th_coord: bool = False,
discards_out_path: Union[str, pathlib.Path, NoneType] = None,
discards_out_format: Optional[str] = None,
discards_out_path: str | pathlib.Path | None = None,
discards_out_format: str | None = None,
custom_decoders: Dict[str, sinter.Decoder] = None,
) -> None:
"""Performs decoding and postselection on disk.
Expand Down Expand Up @@ -1866,11 +1866,11 @@ def read_stats_from_csv_files(

# (at top-level in the sinter module)
def shot_error_rate_to_piece_error_rate(
shot_error_rate: Union[float, sinter.Fit],
shot_error_rate: float | sinter.Fit,
*,
pieces: float,
values: float = 1,
) -> Union[float, sinter.Fit]:
) -> float | sinter.Fit:
"""Convert from total error rate to per-piece error rate.

Args:
Expand Down
14 changes: 13 additions & 1 deletion src/stim/gates/gate_data_annotations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,19 @@ detection event simulations and affect whether the observable is included in err
makes it easier to benchmark all observables of a code, without having to introduce noiseless qubits entangled with the
logical qubit to avoid the testing of the X observable anticommuting with the testing of the Z observable.

Unlike a `DETECTOR` instruction which provides a complete description of a detector by listing all its constituent
measurement records, an individual `OBSERVABLE_INCLUDE` instruction is not required to (and generally does not) fully
describe a logical observable. Instead, measurement records or Pauli targets are added to it incrementally. A logical
observable can be given both types of description: as a collection of Pauli targets and as a collection of measurement
record targets.

Parens Arguments:

A non-negative integer specifying the index of the logical observable to add the measurement records to.

Targets:

The measurement records to add to the specified observable.
The measurement records or Pauli terms to add to the specified observable.

Example:

Expand Down Expand Up @@ -178,6 +184,12 @@ Parens Arguments:
DETECTOR rec[-3] rec[-6]
OBSERVABLE_INCLUDE(0) X0 X1
OBSERVABLE_INCLUDE(1) Z0 Z2

# Stim circuit may include a description of an observable in terms of Pauli targets
# alongside a description in terms of measurement records.
OBSERVABLE_INCLUDE(0) Z0 Z1
M 0 1
OBSERVABLE_INCLUDE(0) rec[-2] rec[-1]
)MARKDOWN",
.unitary_data = {},
.flow_data = {},
Expand Down
Loading