Skip to content

Commit 40ad646

Browse files
Michael Norrismeta-codesync[bot]
authored andcommitted
Fix cuVS build (#5107)
Summary: Pull Request resolved: #5107 ``` The sentinel bug exists in both builds — the code is identical. The reason it manifests only on CMake/GHA: Different GPU hardware. Internal Buck tests run on RE with A100/H100 GPUs. GHA uses T4 (compute capability 7.5). On the T4, cuVS CAGRA's filtered search doesn't explore enough graph to fill all k result slots, leaving sentinel values (INT32_MAX). On more powerful GPUs with higher throughput, the search finds all k valid neighbors before hitting the iteration limit. Possibly different cuVS versions. Buck uses Meta's vendored fbsource//third-party/cuvs:cuvs. GHA installs libcuvs=26.02 from the rapidsai conda channel. The sentinel behavior (what value, when it appears) could differ between versions. The underlying bug — blindly thrust::copying uint32_t indices to idx_t without sanitizing sentinels — exists in both builds. It just doesn't trigger internally because the GPU hardware is powerful enough to always fill all k slots. The thrust::transform fix is correct regardless of which GPU it runs on. ``` Reviewed By: junjieqi Differential Revision: D101072304 fbshipit-source-id: fe191f61b2daba9f34f10bbd0f42c8530d51ad73
1 parent 57bf474 commit 40ad646

4 files changed

Lines changed: 40 additions & 8 deletions

File tree

faiss/gpu/impl/BinaryCuvsCagra.cu

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,11 +284,12 @@ void BinaryCuvsCagra::search(
284284
distances_float_view,
285285
filter_ref);
286286

287-
thrust::copy(
288-
raft::resource::get_thrust_policy(raft_handle),
287+
faiss::gpu::sanitizeCuvsIndices(
288+
resources_,
289289
indices_copy.data_handle(),
290-
indices_copy.data_handle() + indices_copy.size(),
291-
indices_view.data_handle());
290+
indices_view.data_handle(),
291+
indices_copy.size(),
292+
n_);
292293
auto distances_view = raft::make_device_matrix_view(
293294
outDistances.data(),
294295
static_cast<int64_t>(numQueries),

faiss/gpu/impl/CuvsCagra.cu

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,12 @@ void CuvsCagra<data_t>::search(
315315
indices_copy.view(),
316316
distances_view,
317317
filter_ref);
318-
thrust::copy(
319-
raft::resource::get_thrust_policy(raft_handle),
318+
faiss::gpu::sanitizeCuvsIndices(
319+
resources_,
320320
indices_copy.data_handle(),
321-
indices_copy.data_handle() + indices_copy.size(),
322-
indices_view.data_handle());
321+
indices_view.data_handle(),
322+
indices_copy.size(),
323+
n_);
323324
}
324325

325326
template <typename data_t>

faiss/gpu/utils/CuvsUtils.cu

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <thrust/gather.h>
3434
#include <thrust/iterator/counting_iterator.h>
3535
#include <thrust/reduce.h>
36+
#include <thrust/transform.h>
3637

3738
namespace faiss {
3839
namespace gpu {
@@ -115,5 +116,23 @@ idx_t inplaceGatherFilteredRows(
115116
return n_rows_valid;
116117
}
117118

119+
void sanitizeCuvsIndices(
120+
GpuResources* res,
121+
uint32_t* src,
122+
idx_t* dst,
123+
size_t count,
124+
idx_t n) {
125+
raft::device_resources& raft_handle = res->getRaftHandleCurrentDevice();
126+
thrust::transform(
127+
raft_handle.get_thrust_policy(),
128+
src,
129+
src + count,
130+
dst,
131+
[n] __device__(uint32_t idx) -> idx_t {
132+
return idx < static_cast<uint32_t>(n) ? static_cast<idx_t>(idx)
133+
: idx_t{-1};
134+
});
135+
}
136+
118137
} // namespace gpu
119138
} // namespace faiss

faiss/gpu/utils/CuvsUtils.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,17 @@ idx_t inplaceGatherFilteredRows(
7171
GpuResources* res,
7272
Tensor<float, 2, true>& vecs,
7373
Tensor<idx_t, 1, true>& indices);
74+
75+
/// Copy uint32_t indices to idx_t, replacing any index >= n with -1.
76+
/// cuVS CAGRA returns sentinel values (e.g. INT32_MAX) for result slots
77+
/// where filtered search couldn't find a valid neighbor.
78+
void sanitizeCuvsIndices(
79+
GpuResources* res,
80+
uint32_t* src,
81+
idx_t* dst,
82+
size_t count,
83+
idx_t n);
84+
7485
} // namespace gpu
7586
} // namespace faiss
7687
#pragma GCC visibility pop

0 commit comments

Comments
 (0)