goankur opened a new pull request, #16656:
URL: https://github.com/apache/lucene/pull/16656

   ### Title:
   
   
   Parallel `O_DIRECT` full-precision rerank reads for larger-than-RAM KNN 
search
   
   ### Description
   
   Two-phase KNN — quantized (BBQ) graph search in RAM, then full-precision fp32
   rerank of the shortlist — keeps recall high while shrinking the resident
   footprint. But the rerank reads the `fp32` vectors serially, and once the 
index
   exceeds RAM those reads hit disk, where serializing a query's 
few-hundred-vector
   shortlist dominates p99.
   
   This PR:
   - **`ParallelVectorReadable`** (core, `store`): an optional `IndexInput`
     capability to fetch a batch of fixed-size float vectors at scattered 
offsets,
     possibly in parallel. 
   - **`RescoreTopNQuery` / `FullPrecisionFloatVectorSimilarityValuesSource`**: 
the
     full-precision rescorer reads the shortlist via that capability, off the 
main
     field's own raw fp32 through a new `Lucene99FlatVectorsReader` accessor (no
     duplicate rerank field).
   - **`Lucene99FlatVectorsWriter`**: 4 KB page-aligns FLOAT32 vector data so 
each
     read is a single block (padding is transparent to readers).
   - **`SelectiveDirectIODirectory`** (misc): opens only `.vec` with `O_DIRECT` 
and
     implements the capability; it fetches the shortlist through a 
**caller-owned
     read `Executor`**, sized independently of the searcher's executor. The core
     read path is Directory-agnostic; mmap inputs fall back to serial reads.
   
   ### Benchmarks
   
   25M Cohere-v3 (1024-dim), 102 GB index, process capped to 10 GB (~10× smaller
   than the fp32 working set) so rerank reads hit disk. Local NVMe, fio 136k
   random-4KB IOPS / 1.12 GB/s. Single-stream, oversample 5, fanout 100.
   
   | Metric | mmap baseline | O_DIRECT rerank (this PR) |
   |---|---|---|
   | p99 latency | 176 ms | 23.5 ms |
   | recall | 0.963 | 0.963 |
   | read IOPS | 35.4k | 50.9k |
   | avg read size | ~28 KB (readahead-amplified) | 4 KB |
   
   Under concurrent load the design meets p99 ≤ 50 ms at ~240–245 QPS on this 
box
   (one-off validation numbers, not committed).
   
   ### Notes for reviewers
   - Per-query rerank read concurrency is a **storage concern**: it follows the
     caller-owned read `Executor` on `SelectiveDirectIODirectory`, decoupled 
from
     the searcher's executor so a larger-than-RAM deployment can keep enough 
reads
     in flight to saturate the device without widening CPU-side search 
parallelism.
   - The capability interface is float-vector-specific (mirrors
     `IndexInput.readFloats`) rather than a general byte-oriented batch read — a
     deliberate choice to avoid a decode copy on the rerank hot path. Happy to
     generalize if preferred.
   - New test `TestSelectiveDirectIODirectory` covers parallel + serial reads,
     shuffled offsets, and the empty shortlist.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to