Skip to content

ivfpq: Reuse list tables in batch search - #65

Open
shyjsarah wants to merge 6 commits into
apache:mainfrom
shyjsarah:codex/ivfpq-batch-table-reuse-20260728
Open

ivfpq: Reuse list tables in batch search#65
shyjsarah wants to merge 6 commits into
apache:mainfrom
shyjsarah:codex/ivfpq-batch-table-reuse-20260728

Conversation

@shyjsarah

@shyjsarah shyjsarah commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Improve IVF-PQ batch-search performance by reusing batch-local list tables when many queries probe the same lists. This reduces repeated residual L2 table construction across queries and applies to both filtered and unfiltered batch search.

The optimization exposes off, on, and auto runtime modes. The default is auto, which enables reuse only when the batch and probe pattern is expected to amortize the table setup cost.

This PR is stacked on #64. Until #64 merges, GitHub also shows its 8-bit filter-scanning commits.

Changes

  • Build the list-dependent part of residual L2 PQ tables once per active loaded list.
  • Build the query-dependent inner-product table once per active query in each loaded-list batch.
  • Combine the list and query components before scanning instead of rebuilding a full residual table for every query/list pair.
  • Apply the same optimization to filtered and unfiltered batch search.
  • Add IvfPqBatchTableReuseMode with:
    • off: always use the direct residual-table path and ignore resident or batch-local precomputed tables.
    • on: request batch-local table reuse whenever the metric/layout prerequisites hold and the memory budget permits it.
    • auto: additionally require the batch-size and probe-reuse cost heuristic.
  • Use stable f64 arithmetic for batch-local list/query table construction to avoid catastrophic cancellation for 8-bit indexes with large vector offsets; scan tables and scan kernels remain f32.
  • Compute stable PQ norms lazily once per search and reuse them across loaded-list batches.
  • Bound ephemeral table memory with checked arithmetic, including list tables, shared PQ norms, and parallel query scratch tables; fall back to direct calculation when the budget is exceeded.
  • Default Rust, Java, JNI, and legacy FFI search parameters to auto.
  • Add Java VectorSearchParams.withIvfPqBatchTableReuse(...) overloads for enum and string values.
  • Keep ephemeral tables batch-local so they do not remain resident on the reader.

Testing

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace
    • core: 411 passed, 1 ignored
    • ANN support: 7 passed
    • fixtures: 2 passed, 1 ignored
    • FFI: 4 passed
    • JNI: 3 passed
  • mvn -f java/pom.xml test (BUILD SUCCESS)
  • Verified filtered and unfiltered batch results against individual reader searches with floating-point tolerance.
  • Covered off, forced on, automatic activation and fallback, resident-table bypass, memory-budget fallback, and the large-offset 8-bit stability case.

Notes

  • Depends on ivfpq: Push down row filters for 8-bit batch scans #64.
  • The performance benefit comes from amortizing list-table construction across queries when nq × nprobe is sufficiently large. auto retains the direct path for workloads where reuse is unlikely to pay off.
  • Stable f64 arithmetic is limited to ephemeral table setup; the distance scan path remains unchanged.
  • The Paimon-side vector_search option wiring is being kept in a separate local change and is not part of this PR.

@shyjsarah shyjsarah changed the title [WIP] ivfpq: Reuse list tables in batch search ivfpq: Reuse list tables in batch search Jul 29, 2026
@shyjsarah
shyjsarah force-pushed the codex/ivfpq-batch-table-reuse-20260728 branch from 39b2616 to 108893c Compare July 29, 2026 09:29
@JingsongLi

Copy link
Copy Markdown
Contributor

When temporary table reuse is enabled, there is no restriction that pq.nbits == 8; therefore, the default auto setting also enters the 4-bit path and passes the newly generated f64→f32 table to the 4-bit quantization scan for processing (core/src/ivfpq.rs:1633).

  • This causes 4-bit Top-K to vary with batch size: when nq < 64, the old path is taken, but when nq >= 64, reuse may be automatically enabled, resulting in behavior that no longer matches that of the off mode or the behavior prior to the merge.

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.

2 participants