Skip to content

[QDP] Bind and document Preprocessor in the qumat_qdp public API (#1432) - #1548

Open
andrewmusselman wants to merge 2 commits into
mainfrom
pr/1432-preprocessor-docs
Open

andrewmusselman wants to merge 2 commits into
mainfrom
pr/1432-preprocessor-docs

Conversation

@andrewmusselman

Copy link
Copy Markdown
Contributor

Purpose of PR

#1432 asks to document Preprocessor as public qumat_qdp API, assuming an earlier roadmap item had already bound it to Python. On main nothing in qdp-python/src references it, so the first commit adds the binding and the second adds the documented wrapper, export, docs and tests. If a binding already exists elsewhere, the first commit can be dropped.

Related Issues or PRs

Closes #1432

Changes Made

  • New qdp-python/src/preprocessing.rs (registered in lib.rs): _qdp.Preprocessor with static validate_input, calculate_l2_norm, validate_batch, calculate_batch_l2_norms.
    • Inputs via PyArrayLike (lists, ints, float32 converted to float64; C-contiguous float64 borrowed without copy); Fortran-ordered or strided arrays copied in row-major order.
    • Batch methods accept 2D or flat 1D input; mismatched shapes rejected.
    • sample_size == 0 and length mismatches are rejected before the core call, which would otherwise panic and abort the interpreter.
    • Errors map to RuntimeError, matching engine.rs.
  • New qumat_qdp/preprocessing.py: wrapper class with full docstrings (pydoc-markdown cannot read docstrings on compiled classes); raises a clear RuntimeError when _qdp is missing, so import qumat_qdp still works. Exported in __init__.py and __all__; no renames.
  • docs/qdp/python-api.md: "Preprocessing API" section with method table, why the L2 norm matters for amplitude encoding, single and batch examples, deprecation note for future renames.
  • docs/api/qumat_qdp.yml and header: include qumat_qdp.preprocessing.
  • Tests: testing/qdp/test_preprocessor_bindings.py and test_preprocessor.py (CPU only; covers __all__, docstrings, every error branch, F-order/strided input, and runs the documented example).

Testing

  • Stub-CUDA release wheel: 52 new tests pass. testing/qdp testing/qdp_python: 184 passed, 156 skipped (main with the same setup: 132 / 156).
  • Without _qdp the new tests are auto-skipped and qumat_qdp.Preprocessor raises the clear error.
  • cargo fmt, clippy -D warnings, ruff, ruff format and ty clean (no new diagnostics vs main). pydoc-markdown renders all four methods.
  • Not verified: the Docusaurus website build.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GuXmXRXdNF43h2FoQcNAZb

andrewmusselman and others added 2 commits October 20, 2026 16:39
Expose qdp_core::preprocessing::Preprocessor to Python as the
_qdp.Preprocessor class with four static methods: validate_input,
calculate_l2_norm, validate_batch and calculate_batch_l2_norms.

#1432 assumes these were already bound by an earlier roadmap item
("C1"), but on main nothing in qdp-python/src references Preprocessor.
This commit is that prerequisite. If a binding landed elsewhere, drop
this commit and rebase the next one onto it.

Design notes for reviewers:
- Inputs are accepted via numpy PyArrayLike with AllowTypeChange, so
  lists, tuples, ints and float32 arrays are converted to float64. A
  C-contiguous float64 array is borrowed without a copy.
- Fortran-ordered or strided arrays are copied in logical row-major
  order. PyReadonlyArray::as_slice() alone would accept an F-ordered
  array and return column-major memory order, reordering a 2D batch.
- Batch methods take either a 2D (num_samples, sample_size) array or a
  flat 1D array; a 2D shape that disagrees with the arguments is
  rejected.
- Core errors map to RuntimeError with the core message, matching
  engine.rs ("Invalid input: ...").
- calculate_batch_l2_norms guards sample_size == 0 and length
  mismatches before calling the core: par_chunks(0) panics, and the
  release profile uses panic = "abort", so it would kill the
  interpreter.

The functions are pure CPU, so the new tests in
testing/qdp/test_preprocessor_bindings.py run on a CUDA-stub build.

Part of #1432

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Make Preprocessor a documented, first-class part of qumat_qdp:

- qumat_qdp/preprocessing.py: thin Python wrapper class with
  docstrings (params, returns, raises) for validate_input,
  calculate_l2_norm, validate_batch and calculate_batch_l2_norms. It
  delegates to _qdp.Preprocessor and raises a clear RuntimeError when
  the extension is not installed, so importing qumat_qdp still works
  without _qdp. A Python module is used rather than Rust doc comments
  because pydoc-markdown parses source files and cannot see docstrings
  on compiled classes.
- Export Preprocessor from qumat_qdp/__init__.py and add it to
  __all__. Names match the Rust API; no renames.
- docs/qdp/python-api.md: new "Preprocessing API" section with a
  method table, input/exception notes, why the L2 norm matters before
  amplitude encoding (state = x / ||x||, zero-norm rejected), a
  validate_input -> calculate_l2_norm example, a batch example, and a
  note that any future rename should go through a deprecation period.
- docs/api: add qumat_qdp.preprocessing to the generated reference and
  link it from the header.
- testing/qdp/test_preprocessor.py: CPU-only tests for the public API,
  including __all__, docstrings, every error branch, Fortran-order and
  strided inputs, and executing the documented example from
  python-api.md so the docs cannot drift.

Closes #1432

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@andrewmusselman andrewmusselman added the Hackathon Community Over Code Hackathon label Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Hackathon Community Over Code Hackathon

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Docs] Document Preprocessor in qumat_qdp public API

1 participant