Skip to content

Lazy submatrix sampling for SparseSkOp#174

Merged
rileyjmurray merged 3 commits into
mainfrom
sparseskop-submatrices
May 31, 2026
Merged

Lazy submatrix sampling for SparseSkOp#174
rileyjmurray merged 3 commits into
mainfrom
sparseskop-submatrices

Conversation

@rileyjmurray

Copy link
Copy Markdown
Contributor

Sample only the requested submatrix of a sparse sketching operator, directly into COO buffers, without ever materializing the full operator. This mirrors the existing lazy-submatrix machinery for DenseSkOp (fill_dense_unpacked / submatrix_as_blackbox) and brings SparseSkOp to parity. Resolves #111.

Previously, when lskges/rskges received an unsampled operator (S.nnz < 0), they filled the entire operator and then extracted the requested submatrix out of it. Now they generate only the submatrix that's actually needed.

What changed

  • fill_sparse_unpacked(D, n_rows_sub, n_cols_sub, ro_s, co_s, nnz, vals, rows, cols, seed_state) (sparse_skops.hh) — new primitive that samples the n_rows_sub × n_cols_sub submatrix of S anchored at (ro_s, co_s) straight into caller-provided COO buffers, with indices shifted to local coordinates. It advances the RNG counter past the unneeded major-axis vectors, samples the needed ones with the same helpers as the full operator (repeated_fisher_yates for SASO, sample_indices_iid_uniform + merge for LASO), then compacts in place to the requested window. Handles both axis orderings and both Axis::Short/Axis::Long layouts.

    • Workspace query: passing any of vals/rows/cols as null performs no sampling — it just writes the worst-case required buffer length (vec_nnz * num_major_sub) into nnz and returns seed_state unchanged, so callers can size buffers as needed.
  • submatrix_as_coo(S, n_rows_sub, n_cols_sub, ro_s, co_s) (RandBLAS::sparse) — sparse analog of submatrix_as_blackbox(). Uses the workspace query to size buffers, samples the submatrix, and returns a memory-owning COOMatrix whose dimensions exactly match the submatrix — so passing it to left_spmm/right_spmm with offsets (0,0) takes the no-extract fast path.

  • lskges / rskges (skge.hh) — on the S.nnz < 0 path, build only the needed submatrix via submatrix_as_coo and call left_spmm/right_spmm with (0,0) offsets, instead of filling the full operator into a shallow copy.

  • fill_sparse now routes through fill_sparse_unpacked. fill_sparse_unpacked_nosub is retained as a thin deprecated wrapper (delegates with ro_s = co_s = 0) for backward compatibility in the 1.x series; scheduled for removal in 2.0.

  • Docs: RTD skops_and_dists.rst now documents fill_sparse_unpacked and drops the _nosub entry.

Reproducibility

Thread-independence and exact RNG reproducibility are preserved. Because the counter is skipped per-vector and the same sampling helpers are reused, a submatrix sampled lazily is bit-for-bit identical to the corresponding block of the fully-materialized operator.

Testing

  • test_sparseskop.cc: new fill_unpacked_sub_{saso,laso} tests (plus int32 index variants) checking the lazy submatrix against the full fill.
  • test_lskges.cc / test_rskges.cc: new *_SubmatrixPath.equivalence_to_full_fill tests sweeping {Short, Long} × {NoTrans, Trans} × {ColMajor, RowMajor} × vec_nnz ∈ {1,2,3}, asserting the lazy path (S.nnz < 0) produces the same B as fill-then-sketch.
  • Full suite: 435/435 passing.

rileyjmurray and others added 3 commits May 30, 2026 18:32
Sample only the requested submatrix of a sparse sketching operator without
materializing the full operator, mirroring the DenseSkOp machinery.

- fill_sparse_unpacked(D, n_rows_sub, n_cols_sub, ro_s, co_s, ...): samples
  the requested submatrix directly into COO buffers. Supports a null-pointer
  workspace query that reports the required buffer length in nnz.
- submatrix_as_coo(...): sparse analog of submatrix_as_blackbox(); uses the
  workspace query to size its buffers.
- lskges/rskges generate only the needed submatrix on the S.nnz < 0 path and
  call left_spmm/right_spmm with offsets (0,0).
- fill_sparse now routes through fill_sparse_unpacked. fill_sparse_unpacked_nosub
  is retained only for backward compatibility in the 1.x series (removal in 2.0).
- RTD: document fill_sparse_unpacked, drop fill_sparse_unpacked_nosub.

Thread-independence and exact RNG reproducibility are preserved. 435/435 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rileyjmurray rileyjmurray merged commit 705f09e into main May 31, 2026
15 checks passed
@rileyjmurray rileyjmurray deleted the sparseskop-submatrices branch May 31, 2026 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SparseSkOp: only generate the major-axis vectors needed in a given sketching operation

1 participant