faiss 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/ext/faiss/extconf.rb +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +36 -33
- data/vendor/faiss/faiss/AutoTune.h +6 -3
- data/vendor/faiss/faiss/Clustering.cpp +16 -12
- data/vendor/faiss/faiss/Index.cpp +3 -4
- data/vendor/faiss/faiss/Index.h +3 -3
- data/vendor/faiss/faiss/IndexBinary.cpp +3 -4
- data/vendor/faiss/faiss/IndexBinary.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +2 -12
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +1 -2
- data/vendor/faiss/faiss/IndexFlat.cpp +0 -148
- data/vendor/faiss/faiss/IndexFlat.h +0 -51
- data/vendor/faiss/faiss/IndexHNSW.cpp +4 -5
- data/vendor/faiss/faiss/IndexIVF.cpp +118 -31
- data/vendor/faiss/faiss/IndexIVF.h +22 -15
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +3 -3
- data/vendor/faiss/faiss/IndexIVFFlat.h +2 -1
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +39 -15
- data/vendor/faiss/faiss/IndexIVFPQ.h +25 -9
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +1116 -0
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +166 -0
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +8 -9
- data/vendor/faiss/faiss/IndexIVFPQR.h +2 -1
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +1 -2
- data/vendor/faiss/faiss/IndexPQ.cpp +34 -18
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +536 -0
- data/vendor/faiss/faiss/IndexPQFastScan.h +111 -0
- data/vendor/faiss/faiss/IndexPreTransform.cpp +47 -0
- data/vendor/faiss/faiss/IndexPreTransform.h +2 -0
- data/vendor/faiss/faiss/IndexRefine.cpp +256 -0
- data/vendor/faiss/faiss/IndexRefine.h +73 -0
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +2 -2
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +1 -1
- data/vendor/faiss/faiss/gpu/GpuDistance.h +1 -1
- data/vendor/faiss/faiss/gpu/GpuIndex.h +16 -9
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +8 -1
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +11 -11
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +19 -2
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +28 -2
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +24 -14
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +29 -2
- data/vendor/faiss/faiss/gpu/GpuResources.h +4 -0
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +60 -27
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +28 -6
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +547 -0
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +51 -0
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +3 -3
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +3 -2
- data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +274 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +7 -2
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +5 -1
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +231 -0
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +33 -0
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +1 -0
- data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +6 -0
- data/vendor/faiss/faiss/gpu/utils/Timer.cpp +5 -6
- data/vendor/faiss/faiss/gpu/utils/Timer.h +2 -2
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +5 -4
- data/vendor/faiss/faiss/impl/HNSW.cpp +2 -4
- data/vendor/faiss/faiss/impl/PolysemousTraining.h +4 -4
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +22 -12
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +2 -0
- data/vendor/faiss/faiss/impl/ResultHandler.h +452 -0
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +29 -19
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +6 -0
- data/vendor/faiss/faiss/impl/index_read.cpp +64 -96
- data/vendor/faiss/faiss/impl/index_write.cpp +34 -25
- data/vendor/faiss/faiss/impl/io.cpp +33 -2
- data/vendor/faiss/faiss/impl/io.h +7 -2
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +1 -15
- data/vendor/faiss/faiss/impl/platform_macros.h +44 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +272 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +169 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +180 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +354 -0
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +559 -0
- data/vendor/faiss/faiss/index_factory.cpp +112 -7
- data/vendor/faiss/faiss/index_io.h +1 -48
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +151 -0
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +76 -0
- data/vendor/faiss/faiss/{DirectMap.cpp → invlists/DirectMap.cpp} +1 -1
- data/vendor/faiss/faiss/{DirectMap.h → invlists/DirectMap.h} +1 -1
- data/vendor/faiss/faiss/{InvertedLists.cpp → invlists/InvertedLists.cpp} +72 -1
- data/vendor/faiss/faiss/{InvertedLists.h → invlists/InvertedLists.h} +32 -1
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +107 -0
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +63 -0
- data/vendor/faiss/faiss/{OnDiskInvertedLists.cpp → invlists/OnDiskInvertedLists.cpp} +21 -6
- data/vendor/faiss/faiss/{OnDiskInvertedLists.h → invlists/OnDiskInvertedLists.h} +5 -2
- data/vendor/faiss/faiss/python/python_callbacks.h +8 -1
- data/vendor/faiss/faiss/utils/AlignedTable.h +141 -0
- data/vendor/faiss/faiss/utils/Heap.cpp +2 -4
- data/vendor/faiss/faiss/utils/Heap.h +61 -50
- data/vendor/faiss/faiss/utils/distances.cpp +164 -319
- data/vendor/faiss/faiss/utils/distances.h +28 -20
- data/vendor/faiss/faiss/utils/distances_simd.cpp +277 -49
- data/vendor/faiss/faiss/utils/extra_distances.cpp +1 -2
- data/vendor/faiss/faiss/utils/hamming-inl.h +4 -4
- data/vendor/faiss/faiss/utils/hamming.cpp +3 -6
- data/vendor/faiss/faiss/utils/hamming.h +2 -7
- data/vendor/faiss/faiss/utils/ordered_key_value.h +98 -0
- data/vendor/faiss/faiss/utils/partitioning.cpp +1256 -0
- data/vendor/faiss/faiss/utils/partitioning.h +69 -0
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +277 -0
- data/vendor/faiss/faiss/utils/quantize_lut.h +80 -0
- data/vendor/faiss/faiss/utils/simdlib.h +31 -0
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +461 -0
- data/vendor/faiss/faiss/utils/simdlib_emulated.h +589 -0
- metadata +43 -141
- data/vendor/faiss/benchs/bench_6bit_codec.cpp +0 -80
- data/vendor/faiss/c_api/AutoTune_c.cpp +0 -83
- data/vendor/faiss/c_api/AutoTune_c.h +0 -66
- data/vendor/faiss/c_api/Clustering_c.cpp +0 -145
- data/vendor/faiss/c_api/Clustering_c.h +0 -123
- data/vendor/faiss/c_api/IndexFlat_c.cpp +0 -140
- data/vendor/faiss/c_api/IndexFlat_c.h +0 -115
- data/vendor/faiss/c_api/IndexIVFFlat_c.cpp +0 -64
- data/vendor/faiss/c_api/IndexIVFFlat_c.h +0 -58
- data/vendor/faiss/c_api/IndexIVF_c.cpp +0 -99
- data/vendor/faiss/c_api/IndexIVF_c.h +0 -142
- data/vendor/faiss/c_api/IndexLSH_c.cpp +0 -37
- data/vendor/faiss/c_api/IndexLSH_c.h +0 -40
- data/vendor/faiss/c_api/IndexPreTransform_c.cpp +0 -21
- data/vendor/faiss/c_api/IndexPreTransform_c.h +0 -32
- data/vendor/faiss/c_api/IndexShards_c.cpp +0 -38
- data/vendor/faiss/c_api/IndexShards_c.h +0 -39
- data/vendor/faiss/c_api/Index_c.cpp +0 -105
- data/vendor/faiss/c_api/Index_c.h +0 -183
- data/vendor/faiss/c_api/MetaIndexes_c.cpp +0 -49
- data/vendor/faiss/c_api/MetaIndexes_c.h +0 -49
- data/vendor/faiss/c_api/clone_index_c.cpp +0 -23
- data/vendor/faiss/c_api/clone_index_c.h +0 -32
- data/vendor/faiss/c_api/error_c.h +0 -42
- data/vendor/faiss/c_api/error_impl.cpp +0 -27
- data/vendor/faiss/c_api/error_impl.h +0 -16
- data/vendor/faiss/c_api/faiss_c.h +0 -58
- data/vendor/faiss/c_api/gpu/GpuAutoTune_c.cpp +0 -98
- data/vendor/faiss/c_api/gpu/GpuAutoTune_c.h +0 -56
- data/vendor/faiss/c_api/gpu/GpuClonerOptions_c.cpp +0 -52
- data/vendor/faiss/c_api/gpu/GpuClonerOptions_c.h +0 -68
- data/vendor/faiss/c_api/gpu/GpuIndex_c.cpp +0 -17
- data/vendor/faiss/c_api/gpu/GpuIndex_c.h +0 -30
- data/vendor/faiss/c_api/gpu/GpuIndicesOptions_c.h +0 -38
- data/vendor/faiss/c_api/gpu/GpuResources_c.cpp +0 -86
- data/vendor/faiss/c_api/gpu/GpuResources_c.h +0 -66
- data/vendor/faiss/c_api/gpu/StandardGpuResources_c.cpp +0 -54
- data/vendor/faiss/c_api/gpu/StandardGpuResources_c.h +0 -53
- data/vendor/faiss/c_api/gpu/macros_impl.h +0 -42
- data/vendor/faiss/c_api/impl/AuxIndexStructures_c.cpp +0 -220
- data/vendor/faiss/c_api/impl/AuxIndexStructures_c.h +0 -149
- data/vendor/faiss/c_api/index_factory_c.cpp +0 -26
- data/vendor/faiss/c_api/index_factory_c.h +0 -30
- data/vendor/faiss/c_api/index_io_c.cpp +0 -42
- data/vendor/faiss/c_api/index_io_c.h +0 -50
- data/vendor/faiss/c_api/macros_impl.h +0 -110
- data/vendor/faiss/demos/demo_imi_flat.cpp +0 -154
- data/vendor/faiss/demos/demo_imi_pq.cpp +0 -203
- data/vendor/faiss/demos/demo_ivfpq_indexing.cpp +0 -151
- data/vendor/faiss/demos/demo_sift1M.cpp +0 -252
- data/vendor/faiss/demos/demo_weighted_kmeans.cpp +0 -185
- data/vendor/faiss/misc/test_blas.cpp +0 -87
- data/vendor/faiss/tests/test_binary_flat.cpp +0 -62
- data/vendor/faiss/tests/test_dealloc_invlists.cpp +0 -188
- data/vendor/faiss/tests/test_ivfpq_codec.cpp +0 -70
- data/vendor/faiss/tests/test_ivfpq_indexing.cpp +0 -100
- data/vendor/faiss/tests/test_lowlevel_ivf.cpp +0 -573
- data/vendor/faiss/tests/test_merge.cpp +0 -260
- data/vendor/faiss/tests/test_omp_threads.cpp +0 -14
- data/vendor/faiss/tests/test_ondisk_ivf.cpp +0 -225
- data/vendor/faiss/tests/test_pairs_decoding.cpp +0 -193
- data/vendor/faiss/tests/test_params_override.cpp +0 -236
- data/vendor/faiss/tests/test_pq_encoding.cpp +0 -98
- data/vendor/faiss/tests/test_sliding_ivf.cpp +0 -246
- data/vendor/faiss/tests/test_threaded_index.cpp +0 -253
- data/vendor/faiss/tests/test_transfer_invlists.cpp +0 -159
- data/vendor/faiss/tutorial/cpp/1-Flat.cpp +0 -104
- data/vendor/faiss/tutorial/cpp/2-IVFFlat.cpp +0 -85
- data/vendor/faiss/tutorial/cpp/3-IVFPQ.cpp +0 -98
- data/vendor/faiss/tutorial/cpp/4-GPU.cpp +0 -122
- data/vendor/faiss/tutorial/cpp/5-Multiple-GPUs.cpp +0 -104
@@ -1,260 +0,0 @@
|
|
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
|
-
|
8
|
-
#include <cstdio>
|
9
|
-
#include <cstdlib>
|
10
|
-
#include <random>
|
11
|
-
|
12
|
-
#include <gtest/gtest.h>
|
13
|
-
|
14
|
-
#include <faiss/IndexIVFFlat.h>
|
15
|
-
#include <faiss/IndexIVFPQ.h>
|
16
|
-
#include <faiss/IndexFlat.h>
|
17
|
-
#include <faiss/MetaIndexes.h>
|
18
|
-
#include <faiss/IndexPreTransform.h>
|
19
|
-
#include <faiss/OnDiskInvertedLists.h>
|
20
|
-
#include <faiss/IVFlib.h>
|
21
|
-
|
22
|
-
|
23
|
-
namespace {
|
24
|
-
|
25
|
-
|
26
|
-
struct Tempfilename {
|
27
|
-
|
28
|
-
static pthread_mutex_t mutex;
|
29
|
-
|
30
|
-
std::string filename;
|
31
|
-
|
32
|
-
Tempfilename (const char *prefix = nullptr) {
|
33
|
-
pthread_mutex_lock (&mutex);
|
34
|
-
char *cfname = tempnam (nullptr, prefix);
|
35
|
-
filename = cfname;
|
36
|
-
free(cfname);
|
37
|
-
pthread_mutex_unlock (&mutex);
|
38
|
-
}
|
39
|
-
|
40
|
-
~Tempfilename () {
|
41
|
-
if (access (filename.c_str(), F_OK)) {
|
42
|
-
unlink (filename.c_str());
|
43
|
-
}
|
44
|
-
}
|
45
|
-
|
46
|
-
const char *c_str() {
|
47
|
-
return filename.c_str();
|
48
|
-
}
|
49
|
-
|
50
|
-
};
|
51
|
-
|
52
|
-
pthread_mutex_t Tempfilename::mutex = PTHREAD_MUTEX_INITIALIZER;
|
53
|
-
|
54
|
-
|
55
|
-
typedef faiss::Index::idx_t idx_t;
|
56
|
-
|
57
|
-
// parameters to use for the test
|
58
|
-
int d = 64;
|
59
|
-
size_t nb = 1000;
|
60
|
-
size_t nq = 100;
|
61
|
-
int nindex = 4;
|
62
|
-
int k = 10;
|
63
|
-
int nlist = 40;
|
64
|
-
|
65
|
-
struct CommonData {
|
66
|
-
|
67
|
-
std::vector <float> database;
|
68
|
-
std::vector <float> queries;
|
69
|
-
std::vector<idx_t> ids;
|
70
|
-
faiss::IndexFlatL2 quantizer;
|
71
|
-
|
72
|
-
CommonData(): database (nb * d), queries (nq * d), ids(nb), quantizer (d) {
|
73
|
-
|
74
|
-
std::mt19937 rng;
|
75
|
-
std::uniform_real_distribution<> distrib;
|
76
|
-
for (size_t i = 0; i < nb * d; i++) {
|
77
|
-
database[i] = distrib(rng);
|
78
|
-
}
|
79
|
-
for (size_t i = 0; i < nq * d; i++) {
|
80
|
-
queries[i] = distrib(rng);
|
81
|
-
}
|
82
|
-
for (int i = 0; i < nb; i++) {
|
83
|
-
ids[i] = 123 + 456 * i;
|
84
|
-
}
|
85
|
-
{ // just to train the quantizer
|
86
|
-
faiss::IndexIVFFlat iflat (&quantizer, d, nlist);
|
87
|
-
iflat.train(nb, database.data());
|
88
|
-
}
|
89
|
-
}
|
90
|
-
};
|
91
|
-
|
92
|
-
CommonData cd;
|
93
|
-
|
94
|
-
/// perform a search on shards, then merge and search again and
|
95
|
-
/// compare results.
|
96
|
-
int compare_merged (faiss::IndexShards *index_shards, bool shift_ids,
|
97
|
-
bool standard_merge = true)
|
98
|
-
{
|
99
|
-
|
100
|
-
std::vector<idx_t> refI(k * nq);
|
101
|
-
std::vector<float> refD(k * nq);
|
102
|
-
|
103
|
-
index_shards->search(nq, cd.queries.data(), k, refD.data(), refI.data());
|
104
|
-
Tempfilename filename;
|
105
|
-
|
106
|
-
std::vector<idx_t> newI(k * nq);
|
107
|
-
std::vector<float> newD(k * nq);
|
108
|
-
|
109
|
-
if (standard_merge) {
|
110
|
-
|
111
|
-
for (int i = 1; i < nindex; i++) {
|
112
|
-
faiss::ivflib::merge_into(
|
113
|
-
index_shards->at(0), index_shards->at(i),
|
114
|
-
shift_ids);
|
115
|
-
}
|
116
|
-
|
117
|
-
index_shards->syncWithSubIndexes();
|
118
|
-
} else {
|
119
|
-
std::vector<const faiss::InvertedLists *> lists;
|
120
|
-
faiss::IndexIVF *index0 = nullptr;
|
121
|
-
size_t ntotal = 0;
|
122
|
-
for (int i = 0; i < nindex; i++) {
|
123
|
-
auto index_ivf = dynamic_cast<faiss::IndexIVF*>(index_shards->at(i));
|
124
|
-
assert (index_ivf);
|
125
|
-
if (i == 0) {
|
126
|
-
index0 = index_ivf;
|
127
|
-
}
|
128
|
-
lists.push_back (index_ivf->invlists);
|
129
|
-
ntotal += index_ivf->ntotal;
|
130
|
-
}
|
131
|
-
|
132
|
-
auto il = new faiss::OnDiskInvertedLists(
|
133
|
-
index0->nlist, index0->code_size,
|
134
|
-
filename.c_str());
|
135
|
-
|
136
|
-
il->merge_from(lists.data(), lists.size());
|
137
|
-
|
138
|
-
index0->replace_invlists(il, true);
|
139
|
-
index0->ntotal = ntotal;
|
140
|
-
}
|
141
|
-
// search only on first index
|
142
|
-
index_shards->at(0)->search(nq, cd.queries.data(),
|
143
|
-
k, newD.data(), newI.data());
|
144
|
-
|
145
|
-
size_t ndiff = 0;
|
146
|
-
for (size_t i = 0; i < k * nq; i++) {
|
147
|
-
if (refI[i] != newI[i]) {
|
148
|
-
ndiff ++;
|
149
|
-
}
|
150
|
-
}
|
151
|
-
return ndiff;
|
152
|
-
}
|
153
|
-
|
154
|
-
} // namespace
|
155
|
-
|
156
|
-
|
157
|
-
// test on IVFFlat with implicit numbering
|
158
|
-
TEST(MERGE, merge_flat_no_ids) {
|
159
|
-
faiss::IndexShards index_shards(d);
|
160
|
-
index_shards.own_fields = true;
|
161
|
-
for (int i = 0; i < nindex; i++) {
|
162
|
-
index_shards.add_shard (
|
163
|
-
new faiss::IndexIVFFlat (&cd.quantizer, d, nlist));
|
164
|
-
}
|
165
|
-
EXPECT_TRUE(index_shards.is_trained);
|
166
|
-
index_shards.add(nb, cd.database.data());
|
167
|
-
size_t prev_ntotal = index_shards.ntotal;
|
168
|
-
int ndiff = compare_merged(&index_shards, true);
|
169
|
-
EXPECT_EQ (prev_ntotal, index_shards.ntotal);
|
170
|
-
EXPECT_EQ(0, ndiff);
|
171
|
-
}
|
172
|
-
|
173
|
-
|
174
|
-
// test on IVFFlat, explicit ids
|
175
|
-
TEST(MERGE, merge_flat) {
|
176
|
-
faiss::IndexShards index_shards(d, false, false);
|
177
|
-
index_shards.own_fields = true;
|
178
|
-
|
179
|
-
for (int i = 0; i < nindex; i++) {
|
180
|
-
index_shards.add_shard (
|
181
|
-
new faiss::IndexIVFFlat (&cd.quantizer, d, nlist));
|
182
|
-
}
|
183
|
-
|
184
|
-
EXPECT_TRUE(index_shards.is_trained);
|
185
|
-
index_shards.add_with_ids(nb, cd.database.data(), cd.ids.data());
|
186
|
-
int ndiff = compare_merged(&index_shards, false);
|
187
|
-
EXPECT_GE(0, ndiff);
|
188
|
-
}
|
189
|
-
|
190
|
-
// test on IVFFlat and a VectorTransform
|
191
|
-
TEST(MERGE, merge_flat_vt) {
|
192
|
-
faiss::IndexShards index_shards(d, false, false);
|
193
|
-
index_shards.own_fields = true;
|
194
|
-
|
195
|
-
// here we have to retrain because of the vectorTransform
|
196
|
-
faiss::RandomRotationMatrix rot(d, d);
|
197
|
-
rot.init(1234);
|
198
|
-
faiss::IndexFlatL2 quantizer (d);
|
199
|
-
|
200
|
-
{ // just to train the quantizer
|
201
|
-
faiss::IndexIVFFlat iflat (&quantizer, d, nlist);
|
202
|
-
faiss::IndexPreTransform ipt (&rot, &iflat);
|
203
|
-
ipt.train(nb, cd.database.data());
|
204
|
-
}
|
205
|
-
|
206
|
-
for (int i = 0; i < nindex; i++) {
|
207
|
-
faiss::IndexPreTransform * ipt = new faiss::IndexPreTransform (
|
208
|
-
new faiss::RandomRotationMatrix (rot),
|
209
|
-
new faiss::IndexIVFFlat (&quantizer, d, nlist)
|
210
|
-
);
|
211
|
-
ipt->own_fields = true;
|
212
|
-
index_shards.add_shard (ipt);
|
213
|
-
}
|
214
|
-
EXPECT_TRUE(index_shards.is_trained);
|
215
|
-
index_shards.add_with_ids(nb, cd.database.data(), cd.ids.data());
|
216
|
-
size_t prev_ntotal = index_shards.ntotal;
|
217
|
-
int ndiff = compare_merged(&index_shards, false);
|
218
|
-
EXPECT_EQ (prev_ntotal, index_shards.ntotal);
|
219
|
-
EXPECT_GE(0, ndiff);
|
220
|
-
}
|
221
|
-
|
222
|
-
|
223
|
-
// put the merged invfile on disk
|
224
|
-
TEST(MERGE, merge_flat_ondisk) {
|
225
|
-
faiss::IndexShards index_shards(d, false, false);
|
226
|
-
index_shards.own_fields = true;
|
227
|
-
Tempfilename filename;
|
228
|
-
|
229
|
-
for (int i = 0; i < nindex; i++) {
|
230
|
-
auto ivf = new faiss::IndexIVFFlat (&cd.quantizer, d, nlist);
|
231
|
-
if (i == 0) {
|
232
|
-
auto il = new faiss::OnDiskInvertedLists (
|
233
|
-
ivf->nlist, ivf->code_size,
|
234
|
-
filename.c_str());
|
235
|
-
ivf->replace_invlists(il, true);
|
236
|
-
}
|
237
|
-
index_shards.add_shard (ivf);
|
238
|
-
}
|
239
|
-
|
240
|
-
EXPECT_TRUE(index_shards.is_trained);
|
241
|
-
index_shards.add_with_ids(nb, cd.database.data(), cd.ids.data());
|
242
|
-
int ndiff = compare_merged(&index_shards, false);
|
243
|
-
|
244
|
-
EXPECT_EQ(ndiff, 0);
|
245
|
-
}
|
246
|
-
|
247
|
-
// now use ondisk specific merge
|
248
|
-
TEST(MERGE, merge_flat_ondisk_2) {
|
249
|
-
faiss::IndexShards index_shards(d, false, false);
|
250
|
-
index_shards.own_fields = true;
|
251
|
-
|
252
|
-
for (int i = 0; i < nindex; i++) {
|
253
|
-
index_shards.add_shard (
|
254
|
-
new faiss::IndexIVFFlat (&cd.quantizer, d, nlist));
|
255
|
-
}
|
256
|
-
EXPECT_TRUE(index_shards.is_trained);
|
257
|
-
index_shards.add_with_ids(nb, cd.database.data(), cd.ids.data());
|
258
|
-
int ndiff = compare_merged(&index_shards, false, false);
|
259
|
-
EXPECT_GE(0, ndiff);
|
260
|
-
}
|
@@ -1,14 +0,0 @@
|
|
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
|
-
|
8
|
-
#include <gtest/gtest.h>
|
9
|
-
|
10
|
-
#include <faiss/utils/utils.h>
|
11
|
-
|
12
|
-
TEST(Threading, openmp) {
|
13
|
-
EXPECT_TRUE(faiss::check_openmp());
|
14
|
-
}
|
@@ -1,225 +0,0 @@
|
|
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
|
-
|
8
|
-
#include <cstdio>
|
9
|
-
#include <cstdlib>
|
10
|
-
#include <random>
|
11
|
-
|
12
|
-
#include <omp.h>
|
13
|
-
|
14
|
-
#include <unordered_map>
|
15
|
-
#include <pthread.h>
|
16
|
-
|
17
|
-
#include <gtest/gtest.h>
|
18
|
-
|
19
|
-
#include <faiss/OnDiskInvertedLists.h>
|
20
|
-
#include <faiss/IndexIVFFlat.h>
|
21
|
-
#include <faiss/IndexFlat.h>
|
22
|
-
#include <faiss/utils/random.h>
|
23
|
-
#include <faiss/index_io.h>
|
24
|
-
|
25
|
-
|
26
|
-
namespace {
|
27
|
-
|
28
|
-
struct Tempfilename {
|
29
|
-
|
30
|
-
static pthread_mutex_t mutex;
|
31
|
-
|
32
|
-
std::string filename;
|
33
|
-
|
34
|
-
Tempfilename (const char *prefix = nullptr) {
|
35
|
-
pthread_mutex_lock (&mutex);
|
36
|
-
char *cfname = tempnam (nullptr, prefix);
|
37
|
-
filename = cfname;
|
38
|
-
free(cfname);
|
39
|
-
pthread_mutex_unlock (&mutex);
|
40
|
-
}
|
41
|
-
|
42
|
-
~Tempfilename () {
|
43
|
-
if (access (filename.c_str(), F_OK)) {
|
44
|
-
unlink (filename.c_str());
|
45
|
-
}
|
46
|
-
}
|
47
|
-
|
48
|
-
const char *c_str() {
|
49
|
-
return filename.c_str();
|
50
|
-
}
|
51
|
-
|
52
|
-
};
|
53
|
-
|
54
|
-
pthread_mutex_t Tempfilename::mutex = PTHREAD_MUTEX_INITIALIZER;
|
55
|
-
|
56
|
-
} // namespace
|
57
|
-
|
58
|
-
|
59
|
-
TEST(ONDISK, make_invlists) {
|
60
|
-
int nlist = 100;
|
61
|
-
int code_size = 32;
|
62
|
-
int nadd = 1000000;
|
63
|
-
std::unordered_map<int, int> listnos;
|
64
|
-
|
65
|
-
Tempfilename filename;
|
66
|
-
|
67
|
-
faiss::OnDiskInvertedLists ivf (
|
68
|
-
nlist, code_size,
|
69
|
-
filename.c_str());
|
70
|
-
|
71
|
-
{
|
72
|
-
std::vector<uint8_t> code(32);
|
73
|
-
std::mt19937 rng;
|
74
|
-
std::uniform_real_distribution<> distrib;
|
75
|
-
for (int i = 0; i < nadd; i++) {
|
76
|
-
double d = distrib(rng);
|
77
|
-
int list_no = int(nlist * d * d); // skewed distribution
|
78
|
-
int * ar = (int*)code.data();
|
79
|
-
ar[0] = i;
|
80
|
-
ar[1] = list_no;
|
81
|
-
ivf.add_entry (list_no, i, code.data());
|
82
|
-
listnos[i] = list_no;
|
83
|
-
}
|
84
|
-
}
|
85
|
-
|
86
|
-
int ntot = 0;
|
87
|
-
for (int i = 0; i < nlist; i++) {
|
88
|
-
int size = ivf.list_size(i);
|
89
|
-
const faiss::Index::idx_t *ids = ivf.get_ids (i);
|
90
|
-
const uint8_t *codes = ivf.get_codes (i);
|
91
|
-
for (int j = 0; j < size; j++) {
|
92
|
-
faiss::Index::idx_t id = ids[j];
|
93
|
-
const int * ar = (const int*)&codes[code_size * j];
|
94
|
-
EXPECT_EQ (ar[0], id);
|
95
|
-
EXPECT_EQ (ar[1], i);
|
96
|
-
EXPECT_EQ (listnos[id], i);
|
97
|
-
ntot ++;
|
98
|
-
}
|
99
|
-
}
|
100
|
-
EXPECT_EQ (ntot, nadd);
|
101
|
-
};
|
102
|
-
|
103
|
-
|
104
|
-
TEST(ONDISK, test_add) {
|
105
|
-
int d = 8;
|
106
|
-
int nlist = 30, nq = 200, nb = 1500, k = 10;
|
107
|
-
faiss::IndexFlatL2 quantizer(d);
|
108
|
-
{
|
109
|
-
std::vector<float> x(d * nlist);
|
110
|
-
faiss::float_rand(x.data(), d * nlist, 12345);
|
111
|
-
quantizer.add(nlist, x.data());
|
112
|
-
}
|
113
|
-
std::vector<float> xb(d * nb);
|
114
|
-
faiss::float_rand(xb.data(), d * nb, 23456);
|
115
|
-
|
116
|
-
faiss::IndexIVFFlat index(&quantizer, d, nlist);
|
117
|
-
index.add(nb, xb.data());
|
118
|
-
|
119
|
-
std::vector<float> xq(d * nb);
|
120
|
-
faiss::float_rand(xq.data(), d * nq, 34567);
|
121
|
-
|
122
|
-
std::vector<float> ref_D (nq * k);
|
123
|
-
std::vector<faiss::Index::idx_t> ref_I (nq * k);
|
124
|
-
|
125
|
-
index.search (nq, xq.data(), k,
|
126
|
-
ref_D.data(), ref_I.data());
|
127
|
-
|
128
|
-
Tempfilename filename, filename2;
|
129
|
-
|
130
|
-
// test add + search
|
131
|
-
{
|
132
|
-
faiss::IndexIVFFlat index2(&quantizer, d, nlist);
|
133
|
-
|
134
|
-
faiss::OnDiskInvertedLists ivf (
|
135
|
-
index.nlist, index.code_size,
|
136
|
-
filename.c_str());
|
137
|
-
|
138
|
-
index2.replace_invlists(&ivf);
|
139
|
-
|
140
|
-
index2.add(nb, xb.data());
|
141
|
-
|
142
|
-
std::vector<float> new_D (nq * k);
|
143
|
-
std::vector<faiss::Index::idx_t> new_I (nq * k);
|
144
|
-
|
145
|
-
index2.search (nq, xq.data(), k,
|
146
|
-
new_D.data(), new_I.data());
|
147
|
-
|
148
|
-
EXPECT_EQ (ref_D, new_D);
|
149
|
-
EXPECT_EQ (ref_I, new_I);
|
150
|
-
|
151
|
-
write_index(&index2, filename2.c_str());
|
152
|
-
|
153
|
-
}
|
154
|
-
|
155
|
-
// test io
|
156
|
-
{
|
157
|
-
faiss::Index *index3 = faiss::read_index(filename2.c_str());
|
158
|
-
|
159
|
-
std::vector<float> new_D (nq * k);
|
160
|
-
std::vector<faiss::Index::idx_t> new_I (nq * k);
|
161
|
-
|
162
|
-
index3->search (nq, xq.data(), k,
|
163
|
-
new_D.data(), new_I.data());
|
164
|
-
|
165
|
-
EXPECT_EQ (ref_D, new_D);
|
166
|
-
EXPECT_EQ (ref_I, new_I);
|
167
|
-
|
168
|
-
delete index3;
|
169
|
-
}
|
170
|
-
|
171
|
-
};
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
// WARN this thest will run multithreaded only in opt mode
|
176
|
-
TEST(ONDISK, make_invlists_threaded) {
|
177
|
-
int nlist = 100;
|
178
|
-
int code_size = 32;
|
179
|
-
int nadd = 1000000;
|
180
|
-
|
181
|
-
Tempfilename filename;
|
182
|
-
|
183
|
-
faiss::OnDiskInvertedLists ivf (
|
184
|
-
nlist, code_size,
|
185
|
-
filename.c_str());
|
186
|
-
|
187
|
-
std::vector<int> list_nos (nadd);
|
188
|
-
|
189
|
-
std::mt19937 rng;
|
190
|
-
std::uniform_real_distribution<> distrib;
|
191
|
-
for (int i = 0; i < nadd; i++) {
|
192
|
-
double d = distrib(rng);
|
193
|
-
list_nos[i] = int(nlist * d * d); // skewed distribution
|
194
|
-
}
|
195
|
-
|
196
|
-
#pragma omp parallel
|
197
|
-
{
|
198
|
-
std::vector<uint8_t> code(32);
|
199
|
-
#pragma omp for
|
200
|
-
for (int i = 0; i < nadd; i++) {
|
201
|
-
int list_no = list_nos[i];
|
202
|
-
int * ar = (int*)code.data();
|
203
|
-
ar[0] = i;
|
204
|
-
ar[1] = list_no;
|
205
|
-
ivf.add_entry (list_no, i, code.data());
|
206
|
-
}
|
207
|
-
}
|
208
|
-
|
209
|
-
int ntot = 0;
|
210
|
-
for (int i = 0; i < nlist; i++) {
|
211
|
-
int size = ivf.list_size(i);
|
212
|
-
const faiss::Index::idx_t *ids = ivf.get_ids (i);
|
213
|
-
const uint8_t *codes = ivf.get_codes (i);
|
214
|
-
for (int j = 0; j < size; j++) {
|
215
|
-
faiss::Index::idx_t id = ids[j];
|
216
|
-
const int * ar = (const int*)&codes[code_size * j];
|
217
|
-
EXPECT_EQ (ar[0], id);
|
218
|
-
EXPECT_EQ (ar[1], i);
|
219
|
-
EXPECT_EQ (list_nos[id], i);
|
220
|
-
ntot ++;
|
221
|
-
}
|
222
|
-
}
|
223
|
-
EXPECT_EQ (ntot, nadd);
|
224
|
-
|
225
|
-
};
|