feat(gpu_hnsw): re-vendor faiss GPU tree (nq-chunked visited bitmap, OOM fix)#10
Merged
devin-ai-integration[bot] merged 1 commit intoJul 20, 2026
Conversation
…OOM fix) Re-vendors the faiss GPU HNSW fix that bounds the grow-only visited bitmap by processing queries in nq-chunks (byte-identical to 6si/faiss devin/gpu-hnsw-oom-chunk). The bitmap was nq * ceil(N/32) * 4 bytes per scratch slot and never released, so high search concurrency on large segments exhausted device VRAM. Chunking caps it regardless of batch size / concurrency; small segments still run a single pass. Adds tests/ut/test_gpu_search.cc [gpu_hnsw_chunk_parity]: runs each search twice (default cap => single pass, vs GPU_HNSW_BITMAP_BYTES forced tiny => many chunks) and asserts identical ids/distances across fp32 & int8-DP4A, unfiltered, mid-ratio filtered, and up-front-BF (99%) paths for L2/IP/COSINE. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
This was referenced Jul 20, 2026
devin-ai-integration Bot
added a commit
to 6si/milvus
that referenced
this pull request
Jul 20, 2026
…mmit Repoint from the pre-merge feature-branch SHA 2b52090d to f7126691, the merge commit of 6si/knowhere#10 on gpu-hnsw-faiss, so the pin references the permanent integration branch rather than a feature branch. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration Bot
added a commit
that referenced
this pull request
Jul 21, 2026
Mirror the two Devin Review fixes from faiss PR #10 into thirdparty/faiss so the built libknowhere matches: - upload the filter bitset in GpuIndexHNSW::searchImpl_ before gpu_hnsw_search (the standard search() path selected the filtered kernel on a sticky-param bitset but never allocated/uploaded the device buffer -> illegal access). - guard extract_hnsw_layers against reading nb_neighbors(1) for a degenerate layer-0-only index (max_level==0), which would be an out-of-bounds read of cum_nneighbor_per_level[2]. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Re-vendors the faiss GPU HNSW OOM fix (6si/faiss#9) into knowhere's in-tree
thirdparty/faiss, byte-identical to6si/faiss@devin/gpu-hnsw-oom-chunk, and adds a chunking-parity unit test.The bug: GPU HNSW search scratch is grow-only per pool slot. The visited bitmap is
nq * ceil(N/32) * 4bytes and is never released, so high search concurrency (one bitmap per concurrent slot) on large segments exhausts device VRAM — 16 concurrentbatch=512searches on a ~538M-row segment grew the pool to ~97 of ~98 GB and OOM'd everything after (v90 Blackwell validation).The fix (vendored): the layer-0 search processes queries in nq-chunks so the bitmap is bounded regardless of batch size / concurrency;
GpuHnswSearchScratch::ensure()sizes the bitmap for one chunk.gpu_hnsw_bitmap_chunk(nq, N)derives the per-launch query count from a VRAM cap (default 256 MiB; env-tunable viaGPU_HNSW_BITMAP_MB/GPU_HNSW_BITMAP_BYTES). Chunking is result-invariant (queries independent; per-query buffers indexed by chunk-local block index against caller-offset base pointers), and small segments still run a single pass. See 6si/faiss#9 for the full mechanism.Test —
tests/ut/test_gpu_search.cc[gpu_hnsw_chunk_parity]: runs each search twice and asserts element-for-element identical ids/distances:Sections cover L2/IP/COSINE × {fp32 unfiltered, int8 unfiltered (DP4A: distinct int8 layer-0 vs fp32 upper-layer query offsets), fp32 filtered ~30% (two-tier beam + per-chunk worklist reset), fp32 filtered ~99% (up-front brute-force fallback)}.
Only
thirdparty/faiss/faiss/gpu/impl/{GpuHnswTypes.h,GpuHnswTypes.cu,GpuHnswSearch.cuh}and the test change; no public API / index-registration changes.Related PRs
Link to Devin session: https://6sense.devinenterprise.com/sessions/55dab0bd33c346df99b5818b30059342
Requested by: @premal