refactor: remove dead cooperative-distance code from GPU HNSW kernel#2
Closed
devin-ai-integration[bot] wants to merge 27 commits into
Closed
refactor: remove dead cooperative-distance code from GPU HNSW kernel#2devin-ai-integration[bot] wants to merge 27 commits into
devin-ai-integration[bot] wants to merge 27 commits into
Conversation
Port GPU HNSW kernel from Knowhere into FAISS GPU module: - GpuIndexHNSW: public API extending GpuIndex, supports copyFrom(IndexHNSW*) for both IndexHNSWFlat (float32) and IndexHNSWSQ (int8) storage types - Phase 1 upper-layer greedy search kernel (one warp per query) - Phase 2 layer-0 beam search with Overflow Candidate Queue (OCQ) maintaining sorted result buffer in shared memory and secondary overflow queue in global memory to prevent premature pruning - Warp-cooperative distance computation (L2, IP, cosine with inv-norms) - GpuHnswDeviceIndex: device-side index structure with dense layer-0 graph and sparse upper-layer representation - Build utilities to convert faiss::IndexHNSW CSR graph to dense GPU format Follows GpuIndexCagra pattern for FAISS GPU integration. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
searchImpl_ receives device pointers from GpuIndex::search, not host: - queries: cudaMemcpyHostToDevice -> cudaMemcpyDeviceToDevice - distances: cudaMemcpyDeviceToHost -> cudaMemcpyDeviceToDevice - labels: stage through host for uint64->idx_t conversion, then H2D back Stagnation counter: only count stagnation when result list is full (rc >= ef). Previously, when rc < ef both prev_worst and new_worst were FLT_MAX, so the 'no improvement' condition was always true, causing premature termination after just 4 main-loop iterations regardless of search progress. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Two fixes for SIGSEGV crash at nb=100K: 1. Stream mismatch: searchImpl_ used a custom cudaStreamNonBlocking stream but GpuIndex::search() copies query data on the default stream. Non-blocking streams don't synchronize with the default stream, creating a race on query data reads. Now uses the GpuResources default stream (matching GpuIndexCagra pattern). 2. Unchecked cudaMalloc: All cudaMalloc calls in ensure() were unchecked. If any allocation fails, the kernel accesses null/junk pointers causing SIGSEGV. Added SCRATCH_CUDA_CHECK wrapper. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Add direct search parameter passing mechanism via setSearchParams() that stores params on the GpuIndexHNSW object. searchImpl_() checks for direct params first, then falls back to dynamic_cast from SearchParameters. This ensures ef is correctly propagated to the kernel even if dynamic_cast fails across library boundaries. Also adds diagnostic fprintf logging to trace ef values through searchImpl_ and gpu_hnsw_search for debugging. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Ensure diagnostic output is not lost due to stderr buffering in container environments. Matches knowhere vendored version. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Add searchHost() that takes host pointers directly, bypassing GpuIndex::search_ex temp allocation chain. Matches knowhere. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
get_xb() can return a device pointer in GPU context. Matches knowhere. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…afety Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
When loading many segments in parallel, staging vectors (signed_codes, h_layer0_flat, h_vectors, h_inv_norms) accumulated in heap because they were only freed at function return. With 8+ querynodes loading segments concurrently, these buffers push past the pod memory limit. Fix: std::vector<T>().swap(v) immediately after each cudaMemcpy to release staging memory before the next allocation. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…e max_iter Fix 19: Remove fprintf+fflush from gpu_hnsw_search() and searchImpl_(). Fix 20: Per-segment cudaStreamNonBlocking for concurrent kernel execution. Fix 21: max_iter formula 2*ef/sw+10 (matching gpu-hnsw-sq branch). Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…-sq) Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
v20 regressed to 3,427 vec/s (2.1x slower than v19). overflow_factor=0 removes the convergence mechanism. Revert to 1. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…, loop unroll Fix 27: Multiple search performance optimizations synced from knowhere: - Set overflow_factor=0 (stagnation break is independent) - Remove __ldg from graph and inv_norms loads — use L1 cache - Add #pragma unroll 8 to distance computation loops - Use cudaMemcpyAsync for D2H with single sync at end - Sync copyFrom/copyFromWithMetric changes from knowhere Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Replace single-scratch + mutex serialization with a pool of 4 scratch slots, each with its own CUDA stream. This allows up to 4 concurrent GPU searches per segment instead of serializing all searches through one mutex. Synced from knowhere thirdparty/faiss. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Synced from knowhere thirdparty/faiss. Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
CUDA streams are now created on first acquire() instead of in the constructor. This prevents stream/context memory from inflating the process RSS during segment loading, which caused Milvus memory estimator to predict 114 GB and refuse to load segments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Two kernel optimizations for INT8 HNSW search: 1. dp4a INT8 dot product: For int8 datasets, quantize query to int8 in shared memory and use __dp4a intrinsic for distance computation. Reduces instruction count by ~4x (96 dp4a ops vs 384 FMA ops for dim=384). Query quantization error is <1% for ranking purposes. 2. Shared memory query cache: Load query vector into shared memory once at kernel start. All threads read from shared memory instead of L1/global for every distance computation across hundreds of beam search iterations. Both optimizations apply to the layer0_beam_search_kernel. Float datasets continue using the existing float-based distance functions. Upper layer search is unchanged (single distance per warp, low impact). Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Signed-off-by: premal <premal@6sense.com> Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This reverts commit e8c05ec.
select_threads_per_dist(), coop_l2_distance() and coop_ip_distance() were superseded by the 1-thread-per-distance path and have no callers. Remove the dead block. Signed-off-by: Devin AI <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 8, 2026
2708bc1 to
b8de409
Compare
Author
|
Superseded: this content is now folded directly into the clean gpu-hnsw-faiss branch (rebased onto synced upstream master, dead-code/GPU_TIMING cleanups included). Closing. |
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
Removes a dead ~60-line block from
faiss/gpu/impl/GpuHnswSearchKernel.cuhthat has zero callers.The GPU HNSW search kernel settled on a 1-thread-per-distance design. An earlier warp-cooperative distance path was left behind but never wired in:
Verified no references remain anywhere under
faiss/gpu/:No functional change — pure dead-code removal. Targets
gpu-hnsw-faiss(not a rewrite of that branch). The identical vendored copy in 6si/knowhere is cleaned up in a parallel PR.Link to Devin session: https://6sense.devinenterprise.com/sessions/d39aba56b8a3467cbbf231ab631a06ed