Skip to content

Consolidate DemSampler batch sampling: sample_batch does not return a SampleBatch #448

Description

@ciaranra

Problem

DemSampler exposes two batch-sampling entry points whose names are nearly identical but whose return types are swapped relative to what the names suggest:

  • DemSampler.sample_batch(num_shots, seed=None) returns raw Python data: a tuple (list[list[bool]], list[list[bool]]) of detection events and observable flips. It does not return a SampleBatch (python/pecos-rslib/src/fault_tolerance_bindings.rs, fn sample_batch).
  • DemSampler.generate_samples(num_shots, seed=None) does return a SampleBatch, held in Rust memory for feeding multiple decoders without copying shots into Python (fn generate_samples).

The method named after the SampleBatch type is the one that does not produce it. This violates the project naming convention that user-facing names describe the output, and it is an easy trap for anyone reading example code (the docs use generate_samples, docstrings elsewhere use sample_batch).

Root cause

The duplication exists because SampleBatch has no bulk accessors. Its Python surface is per-shot and decoder-oriented (extract_syndrome(shot, buf), extract_obs_mask(shot), extract_obs_mask_wide(shot)), so a user who wants the sampled bits in Python cannot get them out of a SampleBatch. A second sampling entry point that materializes Python lists grew instead of a conversion on the batch object.

Proposal

  1. Add bulk accessors to SampleBatch, e.g. detector_events() and observable_flips() (numpy arrays or lists), so any data the batch holds can be extracted when needed. This also gives a natural home for future extractions.
  2. Make SampleBatch-returning sampling the single entry point on DemSampler.
  3. Migrate the raw-list sample_batch callers (python/quantum-pecos/src/pecos/qec/surface/decode.py, tests/qec/test_dem_equivalence.py, tests/qec/test_dem_sampler.py) to the batch + accessor path, then deprecate/remove DemSampler.sample_batch. The ~40 existing generate_samples call sites are unaffected.
  4. Decide the final name as part of this work (e.g. keep generate_samples, or rename so the SampleBatch-returning method is the one called sample_batch), applying the describe-the-output rule.

Related surfaces to keep consistent in the same pass:

  • DemSampler.sample_batch_with_pauli_masks(...) also returns raw lists; it should either return a SampleBatch or be folded into the consolidated API.
  • ParsedDem.sample_batch(...) has the same raw-list shape and should follow whatever convention this issue settles on.

Documentation and discoverability

The Rust binding docstrings for SampleBatch are in good shape (class-level purpose and example; per-method Args/Returns; the narrow-vs-wide observable semantics of get_observable_mask vs get_observable_mask_wide are documented and fail loud past 64 observables). The gaps are in discoverability, and any API consolidated here should close them in the same pass:

  1. Type stub: python/pecos-rslib/pecos_rslib.pyi contains no entry for SampleBatch — or for DemSampler or DetectorErrorModel; the qec submodule is absent from the stub entirely. There is no autocomplete or type checking for any of this API. New bulk accessors and the consolidated sampling entry point should ship with stub entries (and the broader qec stub gap is worth closing while in the file).
  2. User guide: SampleBatch appears only twice in the docs — decode_count in docs/user-guide/dem-from-guppy.md and the constructor in docs/user-guide/qec-guppy.md. The decoder-comparison methods that are the point of the class (decode_each, compare_decoders, decode_stats, decode_count_parallel, decode_stats_parallel, decode_count_batch) are not documented in any docs page. The consolidated API should get a user-guide section covering sampling, bulk extraction, and decoder comparison in one place.
  3. Docstring rendering: escaped-backtick artifacts (e.g. `decoder_type`) leak from clippy doc-markdown fixes into the Python help() output; clean these up when touching the docstrings.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions