Skip to content

Commit b1d9f79

Browse files
algoriddlefacebook-github-bot
authored andcommitted
addn_query_subset_with_ids float index bug (facebookresearch#2834)
Summary: Pull Request resolved: facebookresearch#2834 Index stored in float results in buffer overflow and corrupts search results. Reviewed By: mdouze Differential Revision: D45388883 fbshipit-source-id: 99e55d9b07b0571cec5df795304986b7f966a94e
1 parent 3704bbe commit b1d9f79

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

faiss/utils/Heap.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void HeapArray<C>::addn_query_subset_with_ids(
9393
}
9494
#pragma omp parallel for if (nsubset * nj > 100000)
9595
for (int64_t si = 0; si < nsubset; si++) {
96-
T i = subset[si];
96+
TI i = subset[si];
9797
T* __restrict simi = get_val(i);
9898
TI* __restrict idxi = get_ids(i);
9999
const T* ip_line = vin + si * nj;

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ set(FAISS_TEST_SRC
2626
test_approx_topk.cpp
2727
test_RCQ_cropping.cpp
2828
test_distances_simd.cpp
29+
test_heap.cpp
2930
)
3031

3132
add_executable(faiss_test ${FAISS_TEST_SRC})

tests/test_heap.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
#include <faiss/utils/Heap.h>
8+
#include <gtest/gtest.h>
9+
#include <numeric>
10+
11+
using namespace faiss;
12+
13+
TEST(Heap, addn_with_ids) {
14+
size_t n = 1000;
15+
size_t k = 1;
16+
std::vector<int64_t> heap_labels(n, -1);
17+
std::vector<float> heap_distances(n, 0);
18+
float_minheap_array_t heaps = {
19+
n, k, heap_labels.data(), heap_distances.data()};
20+
heaps.heapify();
21+
std::vector<int64_t> labels(n, 1);
22+
std::vector<float> distances(n, 0.0f);
23+
std::vector<int64_t> subset(n);
24+
std::iota(subset.begin(), subset.end(), 0);
25+
heaps.addn_with_ids(1, distances.data(), labels.data(), 1);
26+
heaps.reorder();
27+
EXPECT_TRUE(
28+
std::all_of(heap_labels.begin(), heap_labels.end(), [](int64_t i) {
29+
return i == 1;
30+
}));
31+
}
32+
33+
TEST(Heap, addn_query_subset_with_ids) {
34+
size_t n = 20000000; // more than 2^24
35+
size_t k = 1;
36+
std::vector<int64_t> heap_labels(n, -1);
37+
std::vector<float> heap_distances(n, 0);
38+
float_minheap_array_t heaps = {
39+
n, k, heap_labels.data(), heap_distances.data()};
40+
heaps.heapify();
41+
std::vector<int64_t> labels(n, 1);
42+
std::vector<float> distances(n, 0.0f);
43+
std::vector<int64_t> subset(n);
44+
std::iota(subset.begin(), subset.end(), 0);
45+
heaps.addn_query_subset_with_ids(
46+
n, subset.data(), 1, distances.data(), labels.data(), 1);
47+
heaps.reorder();
48+
EXPECT_TRUE(
49+
std::all_of(heap_labels.begin(), heap_labels.end(), [](int64_t i) {
50+
return i == 1;
51+
}));
52+
}

0 commit comments

Comments
 (0)