faiss 0.1.0 → 0.1.1
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 +5 -0
- data/README.md +103 -3
- data/ext/faiss/ext.cpp +99 -32
- data/ext/faiss/extconf.rb +12 -2
- data/lib/faiss/ext.bundle +0 -0
- data/lib/faiss/index.rb +3 -3
- data/lib/faiss/index_binary.rb +3 -3
- data/lib/faiss/kmeans.rb +1 -1
- data/lib/faiss/pca_matrix.rb +2 -2
- data/lib/faiss/product_quantizer.rb +3 -3
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/AutoTune.cpp +719 -0
- data/vendor/faiss/AutoTune.h +212 -0
- data/vendor/faiss/Clustering.cpp +261 -0
- data/vendor/faiss/Clustering.h +101 -0
- data/vendor/faiss/IVFlib.cpp +339 -0
- data/vendor/faiss/IVFlib.h +132 -0
- data/vendor/faiss/Index.cpp +171 -0
- data/vendor/faiss/Index.h +261 -0
- data/vendor/faiss/Index2Layer.cpp +437 -0
- data/vendor/faiss/Index2Layer.h +85 -0
- data/vendor/faiss/IndexBinary.cpp +77 -0
- data/vendor/faiss/IndexBinary.h +163 -0
- data/vendor/faiss/IndexBinaryFlat.cpp +83 -0
- data/vendor/faiss/IndexBinaryFlat.h +54 -0
- data/vendor/faiss/IndexBinaryFromFloat.cpp +78 -0
- data/vendor/faiss/IndexBinaryFromFloat.h +52 -0
- data/vendor/faiss/IndexBinaryHNSW.cpp +325 -0
- data/vendor/faiss/IndexBinaryHNSW.h +56 -0
- data/vendor/faiss/IndexBinaryIVF.cpp +671 -0
- data/vendor/faiss/IndexBinaryIVF.h +211 -0
- data/vendor/faiss/IndexFlat.cpp +508 -0
- data/vendor/faiss/IndexFlat.h +175 -0
- data/vendor/faiss/IndexHNSW.cpp +1090 -0
- data/vendor/faiss/IndexHNSW.h +170 -0
- data/vendor/faiss/IndexIVF.cpp +909 -0
- data/vendor/faiss/IndexIVF.h +353 -0
- data/vendor/faiss/IndexIVFFlat.cpp +502 -0
- data/vendor/faiss/IndexIVFFlat.h +118 -0
- data/vendor/faiss/IndexIVFPQ.cpp +1207 -0
- data/vendor/faiss/IndexIVFPQ.h +161 -0
- data/vendor/faiss/IndexIVFPQR.cpp +219 -0
- data/vendor/faiss/IndexIVFPQR.h +65 -0
- data/vendor/faiss/IndexIVFSpectralHash.cpp +331 -0
- data/vendor/faiss/IndexIVFSpectralHash.h +75 -0
- data/vendor/faiss/IndexLSH.cpp +225 -0
- data/vendor/faiss/IndexLSH.h +87 -0
- data/vendor/faiss/IndexLattice.cpp +143 -0
- data/vendor/faiss/IndexLattice.h +68 -0
- data/vendor/faiss/IndexPQ.cpp +1188 -0
- data/vendor/faiss/IndexPQ.h +199 -0
- data/vendor/faiss/IndexPreTransform.cpp +288 -0
- data/vendor/faiss/IndexPreTransform.h +91 -0
- data/vendor/faiss/IndexReplicas.cpp +123 -0
- data/vendor/faiss/IndexReplicas.h +76 -0
- data/vendor/faiss/IndexScalarQuantizer.cpp +317 -0
- data/vendor/faiss/IndexScalarQuantizer.h +127 -0
- data/vendor/faiss/IndexShards.cpp +317 -0
- data/vendor/faiss/IndexShards.h +100 -0
- data/vendor/faiss/InvertedLists.cpp +623 -0
- data/vendor/faiss/InvertedLists.h +334 -0
- data/vendor/faiss/LICENSE +21 -0
- data/vendor/faiss/MatrixStats.cpp +252 -0
- data/vendor/faiss/MatrixStats.h +62 -0
- data/vendor/faiss/MetaIndexes.cpp +351 -0
- data/vendor/faiss/MetaIndexes.h +126 -0
- data/vendor/faiss/OnDiskInvertedLists.cpp +674 -0
- data/vendor/faiss/OnDiskInvertedLists.h +127 -0
- data/vendor/faiss/VectorTransform.cpp +1157 -0
- data/vendor/faiss/VectorTransform.h +322 -0
- data/vendor/faiss/c_api/AutoTune_c.cpp +83 -0
- data/vendor/faiss/c_api/AutoTune_c.h +64 -0
- data/vendor/faiss/c_api/Clustering_c.cpp +139 -0
- data/vendor/faiss/c_api/Clustering_c.h +117 -0
- data/vendor/faiss/c_api/IndexFlat_c.cpp +140 -0
- data/vendor/faiss/c_api/IndexFlat_c.h +115 -0
- data/vendor/faiss/c_api/IndexIVFFlat_c.cpp +64 -0
- data/vendor/faiss/c_api/IndexIVFFlat_c.h +58 -0
- data/vendor/faiss/c_api/IndexIVF_c.cpp +92 -0
- data/vendor/faiss/c_api/IndexIVF_c.h +135 -0
- data/vendor/faiss/c_api/IndexLSH_c.cpp +37 -0
- data/vendor/faiss/c_api/IndexLSH_c.h +40 -0
- data/vendor/faiss/c_api/IndexShards_c.cpp +44 -0
- data/vendor/faiss/c_api/IndexShards_c.h +42 -0
- data/vendor/faiss/c_api/Index_c.cpp +105 -0
- data/vendor/faiss/c_api/Index_c.h +183 -0
- data/vendor/faiss/c_api/MetaIndexes_c.cpp +49 -0
- data/vendor/faiss/c_api/MetaIndexes_c.h +49 -0
- data/vendor/faiss/c_api/clone_index_c.cpp +23 -0
- data/vendor/faiss/c_api/clone_index_c.h +32 -0
- data/vendor/faiss/c_api/error_c.h +42 -0
- data/vendor/faiss/c_api/error_impl.cpp +27 -0
- data/vendor/faiss/c_api/error_impl.h +16 -0
- data/vendor/faiss/c_api/faiss_c.h +58 -0
- data/vendor/faiss/c_api/gpu/GpuAutoTune_c.cpp +96 -0
- data/vendor/faiss/c_api/gpu/GpuAutoTune_c.h +56 -0
- data/vendor/faiss/c_api/gpu/GpuClonerOptions_c.cpp +52 -0
- data/vendor/faiss/c_api/gpu/GpuClonerOptions_c.h +68 -0
- data/vendor/faiss/c_api/gpu/GpuIndex_c.cpp +17 -0
- data/vendor/faiss/c_api/gpu/GpuIndex_c.h +30 -0
- data/vendor/faiss/c_api/gpu/GpuIndicesOptions_c.h +38 -0
- data/vendor/faiss/c_api/gpu/GpuResources_c.cpp +86 -0
- data/vendor/faiss/c_api/gpu/GpuResources_c.h +66 -0
- data/vendor/faiss/c_api/gpu/StandardGpuResources_c.cpp +54 -0
- data/vendor/faiss/c_api/gpu/StandardGpuResources_c.h +53 -0
- data/vendor/faiss/c_api/gpu/macros_impl.h +42 -0
- data/vendor/faiss/c_api/impl/AuxIndexStructures_c.cpp +220 -0
- data/vendor/faiss/c_api/impl/AuxIndexStructures_c.h +149 -0
- data/vendor/faiss/c_api/index_factory_c.cpp +26 -0
- data/vendor/faiss/c_api/index_factory_c.h +30 -0
- data/vendor/faiss/c_api/index_io_c.cpp +42 -0
- data/vendor/faiss/c_api/index_io_c.h +50 -0
- data/vendor/faiss/c_api/macros_impl.h +110 -0
- data/vendor/faiss/clone_index.cpp +147 -0
- data/vendor/faiss/clone_index.h +38 -0
- data/vendor/faiss/demos/demo_imi_flat.cpp +151 -0
- data/vendor/faiss/demos/demo_imi_pq.cpp +199 -0
- data/vendor/faiss/demos/demo_ivfpq_indexing.cpp +146 -0
- data/vendor/faiss/demos/demo_sift1M.cpp +252 -0
- data/vendor/faiss/gpu/GpuAutoTune.cpp +95 -0
- data/vendor/faiss/gpu/GpuAutoTune.h +27 -0
- data/vendor/faiss/gpu/GpuCloner.cpp +403 -0
- data/vendor/faiss/gpu/GpuCloner.h +82 -0
- data/vendor/faiss/gpu/GpuClonerOptions.cpp +28 -0
- data/vendor/faiss/gpu/GpuClonerOptions.h +53 -0
- data/vendor/faiss/gpu/GpuDistance.h +52 -0
- data/vendor/faiss/gpu/GpuFaissAssert.h +29 -0
- data/vendor/faiss/gpu/GpuIndex.h +148 -0
- data/vendor/faiss/gpu/GpuIndexBinaryFlat.h +89 -0
- data/vendor/faiss/gpu/GpuIndexFlat.h +190 -0
- data/vendor/faiss/gpu/GpuIndexIVF.h +89 -0
- data/vendor/faiss/gpu/GpuIndexIVFFlat.h +85 -0
- data/vendor/faiss/gpu/GpuIndexIVFPQ.h +143 -0
- data/vendor/faiss/gpu/GpuIndexIVFScalarQuantizer.h +100 -0
- data/vendor/faiss/gpu/GpuIndicesOptions.h +30 -0
- data/vendor/faiss/gpu/GpuResources.cpp +52 -0
- data/vendor/faiss/gpu/GpuResources.h +73 -0
- data/vendor/faiss/gpu/StandardGpuResources.cpp +295 -0
- data/vendor/faiss/gpu/StandardGpuResources.h +114 -0
- data/vendor/faiss/gpu/impl/RemapIndices.cpp +43 -0
- data/vendor/faiss/gpu/impl/RemapIndices.h +24 -0
- data/vendor/faiss/gpu/perf/IndexWrapper-inl.h +71 -0
- data/vendor/faiss/gpu/perf/IndexWrapper.h +39 -0
- data/vendor/faiss/gpu/perf/PerfClustering.cpp +115 -0
- data/vendor/faiss/gpu/perf/PerfIVFPQAdd.cpp +139 -0
- data/vendor/faiss/gpu/perf/WriteIndex.cpp +102 -0
- data/vendor/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +130 -0
- data/vendor/faiss/gpu/test/TestGpuIndexFlat.cpp +371 -0
- data/vendor/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +550 -0
- data/vendor/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +450 -0
- data/vendor/faiss/gpu/test/TestGpuMemoryException.cpp +84 -0
- data/vendor/faiss/gpu/test/TestUtils.cpp +315 -0
- data/vendor/faiss/gpu/test/TestUtils.h +93 -0
- data/vendor/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +159 -0
- data/vendor/faiss/gpu/utils/DeviceMemory.cpp +77 -0
- data/vendor/faiss/gpu/utils/DeviceMemory.h +71 -0
- data/vendor/faiss/gpu/utils/DeviceUtils.h +185 -0
- data/vendor/faiss/gpu/utils/MemorySpace.cpp +89 -0
- data/vendor/faiss/gpu/utils/MemorySpace.h +44 -0
- data/vendor/faiss/gpu/utils/StackDeviceMemory.cpp +239 -0
- data/vendor/faiss/gpu/utils/StackDeviceMemory.h +129 -0
- data/vendor/faiss/gpu/utils/StaticUtils.h +83 -0
- data/vendor/faiss/gpu/utils/Timer.cpp +60 -0
- data/vendor/faiss/gpu/utils/Timer.h +52 -0
- data/vendor/faiss/impl/AuxIndexStructures.cpp +305 -0
- data/vendor/faiss/impl/AuxIndexStructures.h +246 -0
- data/vendor/faiss/impl/FaissAssert.h +95 -0
- data/vendor/faiss/impl/FaissException.cpp +66 -0
- data/vendor/faiss/impl/FaissException.h +71 -0
- data/vendor/faiss/impl/HNSW.cpp +818 -0
- data/vendor/faiss/impl/HNSW.h +275 -0
- data/vendor/faiss/impl/PolysemousTraining.cpp +953 -0
- data/vendor/faiss/impl/PolysemousTraining.h +158 -0
- data/vendor/faiss/impl/ProductQuantizer.cpp +876 -0
- data/vendor/faiss/impl/ProductQuantizer.h +242 -0
- data/vendor/faiss/impl/ScalarQuantizer.cpp +1628 -0
- data/vendor/faiss/impl/ScalarQuantizer.h +120 -0
- data/vendor/faiss/impl/ThreadedIndex-inl.h +192 -0
- data/vendor/faiss/impl/ThreadedIndex.h +80 -0
- data/vendor/faiss/impl/index_read.cpp +793 -0
- data/vendor/faiss/impl/index_write.cpp +558 -0
- data/vendor/faiss/impl/io.cpp +142 -0
- data/vendor/faiss/impl/io.h +98 -0
- data/vendor/faiss/impl/lattice_Zn.cpp +712 -0
- data/vendor/faiss/impl/lattice_Zn.h +199 -0
- data/vendor/faiss/index_factory.cpp +392 -0
- data/vendor/faiss/index_factory.h +25 -0
- data/vendor/faiss/index_io.h +75 -0
- data/vendor/faiss/misc/test_blas.cpp +84 -0
- data/vendor/faiss/tests/test_binary_flat.cpp +64 -0
- data/vendor/faiss/tests/test_dealloc_invlists.cpp +183 -0
- data/vendor/faiss/tests/test_ivfpq_codec.cpp +67 -0
- data/vendor/faiss/tests/test_ivfpq_indexing.cpp +98 -0
- data/vendor/faiss/tests/test_lowlevel_ivf.cpp +566 -0
- data/vendor/faiss/tests/test_merge.cpp +258 -0
- data/vendor/faiss/tests/test_omp_threads.cpp +14 -0
- data/vendor/faiss/tests/test_ondisk_ivf.cpp +220 -0
- data/vendor/faiss/tests/test_pairs_decoding.cpp +189 -0
- data/vendor/faiss/tests/test_params_override.cpp +231 -0
- data/vendor/faiss/tests/test_pq_encoding.cpp +98 -0
- data/vendor/faiss/tests/test_sliding_ivf.cpp +240 -0
- data/vendor/faiss/tests/test_threaded_index.cpp +253 -0
- data/vendor/faiss/tests/test_transfer_invlists.cpp +159 -0
- data/vendor/faiss/tutorial/cpp/1-Flat.cpp +98 -0
- data/vendor/faiss/tutorial/cpp/2-IVFFlat.cpp +81 -0
- data/vendor/faiss/tutorial/cpp/3-IVFPQ.cpp +93 -0
- data/vendor/faiss/tutorial/cpp/4-GPU.cpp +119 -0
- data/vendor/faiss/tutorial/cpp/5-Multiple-GPUs.cpp +99 -0
- data/vendor/faiss/utils/Heap.cpp +122 -0
- data/vendor/faiss/utils/Heap.h +495 -0
- data/vendor/faiss/utils/WorkerThread.cpp +126 -0
- data/vendor/faiss/utils/WorkerThread.h +61 -0
- data/vendor/faiss/utils/distances.cpp +765 -0
- data/vendor/faiss/utils/distances.h +243 -0
- data/vendor/faiss/utils/distances_simd.cpp +809 -0
- data/vendor/faiss/utils/extra_distances.cpp +336 -0
- data/vendor/faiss/utils/extra_distances.h +54 -0
- data/vendor/faiss/utils/hamming-inl.h +472 -0
- data/vendor/faiss/utils/hamming.cpp +792 -0
- data/vendor/faiss/utils/hamming.h +220 -0
- data/vendor/faiss/utils/random.cpp +192 -0
- data/vendor/faiss/utils/random.h +60 -0
- data/vendor/faiss/utils/utils.cpp +783 -0
- data/vendor/faiss/utils/utils.h +181 -0
- metadata +216 -2
|
@@ -0,0 +1,102 @@
|
|
|
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
|
+
|
|
9
|
+
#include <faiss/IndexIVFFlat.h>
|
|
10
|
+
#include <faiss/IndexIVFPQ.h>
|
|
11
|
+
#include <faiss/IndexFlat.h>
|
|
12
|
+
#include <faiss/index_io.h>
|
|
13
|
+
#include <faiss/gpu/test/TestUtils.h>
|
|
14
|
+
#include <vector>
|
|
15
|
+
#include <gflags/gflags.h>
|
|
16
|
+
|
|
17
|
+
// For IVFPQ:
|
|
18
|
+
DEFINE_bool(ivfpq, false, "use IVFPQ encoding");
|
|
19
|
+
DEFINE_int32(codes, 4, "number of PQ codes per vector");
|
|
20
|
+
DEFINE_int32(bits_per_code, 8, "number of bits per PQ code");
|
|
21
|
+
|
|
22
|
+
// For IVFFlat:
|
|
23
|
+
DEFINE_bool(l2, true, "use L2 metric (versus IP metric)");
|
|
24
|
+
DEFINE_bool(ivfflat, false, "use IVF flat encoding");
|
|
25
|
+
|
|
26
|
+
// For both:
|
|
27
|
+
DEFINE_string(out, "/home/jhj/local/index.out", "index file for output");
|
|
28
|
+
DEFINE_int32(dim, 128, "vector dimension");
|
|
29
|
+
DEFINE_int32(num_coarse, 100, "number of coarse centroids");
|
|
30
|
+
DEFINE_int32(num, 100000, "total database size");
|
|
31
|
+
DEFINE_int32(num_train, -1, "number of database vecs to train on");
|
|
32
|
+
|
|
33
|
+
template <typename T>
|
|
34
|
+
void fillAndSave(T& index, int numTrain, int num, int dim) {
|
|
35
|
+
auto trainVecs = faiss::gpu::randVecs(numTrain, dim);
|
|
36
|
+
index.train(numTrain, trainVecs.data());
|
|
37
|
+
|
|
38
|
+
constexpr int kAddChunk = 1000000;
|
|
39
|
+
|
|
40
|
+
for (int i = 0; i < num; i += kAddChunk) {
|
|
41
|
+
int numRemaining = (num - i) < kAddChunk ? (num - i) : kAddChunk;
|
|
42
|
+
auto vecs = faiss::gpu::randVecs(numRemaining, dim);
|
|
43
|
+
|
|
44
|
+
printf("adding at %d: %d\n", i, numRemaining);
|
|
45
|
+
index.add(numRemaining, vecs.data());
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
faiss::write_index(&index, FLAGS_out.c_str());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
int main(int argc, char** argv) {
|
|
52
|
+
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
|
53
|
+
|
|
54
|
+
// Either ivfpq or ivfflat must be set
|
|
55
|
+
if ((FLAGS_ivfpq && FLAGS_ivfflat) ||
|
|
56
|
+
(!FLAGS_ivfpq && !FLAGS_ivfflat)) {
|
|
57
|
+
printf("must specify either ivfpq or ivfflat\n");
|
|
58
|
+
return 1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
auto dim = FLAGS_dim;
|
|
62
|
+
auto numCentroids = FLAGS_num_coarse;
|
|
63
|
+
auto num = FLAGS_num;
|
|
64
|
+
auto numTrain = FLAGS_num_train;
|
|
65
|
+
numTrain = numTrain == -1 ? std::max((num / 4), 1) : numTrain;
|
|
66
|
+
numTrain = std::min(num, numTrain);
|
|
67
|
+
|
|
68
|
+
if (FLAGS_ivfpq) {
|
|
69
|
+
faiss::IndexFlatL2 quantizer(dim);
|
|
70
|
+
faiss::IndexIVFPQ index(&quantizer, dim, numCentroids,
|
|
71
|
+
FLAGS_codes, FLAGS_bits_per_code);
|
|
72
|
+
index.verbose = true;
|
|
73
|
+
|
|
74
|
+
printf("IVFPQ: codes %d bits per code %d\n",
|
|
75
|
+
FLAGS_codes, FLAGS_bits_per_code);
|
|
76
|
+
printf("Lists: %d\n", numCentroids);
|
|
77
|
+
printf("Database: dim %d num vecs %d trained on %d\n", dim, num, numTrain);
|
|
78
|
+
printf("output file: %s\n", FLAGS_out.c_str());
|
|
79
|
+
|
|
80
|
+
fillAndSave(index, numTrain, num, dim);
|
|
81
|
+
} else if (FLAGS_ivfflat) {
|
|
82
|
+
faiss::IndexFlatL2 quantizerL2(dim);
|
|
83
|
+
faiss::IndexFlatIP quantizerIP(dim);
|
|
84
|
+
|
|
85
|
+
faiss::IndexFlat* quantizer = FLAGS_l2 ?
|
|
86
|
+
(faiss::IndexFlat*) &quantizerL2 :
|
|
87
|
+
(faiss::IndexFlat*) &quantizerIP;
|
|
88
|
+
|
|
89
|
+
faiss::IndexIVFFlat index(quantizer, dim, numCentroids,
|
|
90
|
+
FLAGS_l2 ? faiss::METRIC_L2 :
|
|
91
|
+
faiss::METRIC_INNER_PRODUCT);
|
|
92
|
+
|
|
93
|
+
printf("IVFFlat: metric %s\n", FLAGS_l2 ? "L2" : "IP");
|
|
94
|
+
printf("Lists: %d\n", numCentroids);
|
|
95
|
+
printf("Database: dim %d num vecs %d trained on %d\n", dim, num, numTrain);
|
|
96
|
+
printf("output file: %s\n", FLAGS_out.c_str());
|
|
97
|
+
|
|
98
|
+
fillAndSave(index, numTrain, num, dim);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
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
|
+
|
|
9
|
+
#include <faiss/IndexBinaryFlat.h>
|
|
10
|
+
#include <faiss/gpu/GpuIndexBinaryFlat.h>
|
|
11
|
+
#include <faiss/gpu/StandardGpuResources.h>
|
|
12
|
+
#include <faiss/gpu/utils/DeviceUtils.h>
|
|
13
|
+
#include <faiss/gpu/test/TestUtils.h>
|
|
14
|
+
#include <faiss/utils/utils.h>
|
|
15
|
+
#include <gtest/gtest.h>
|
|
16
|
+
#include <sstream>
|
|
17
|
+
#include <vector>
|
|
18
|
+
|
|
19
|
+
void compareBinaryDist(const std::vector<int>& cpuDist,
|
|
20
|
+
const std::vector<faiss::IndexBinary::idx_t>& cpuLabels,
|
|
21
|
+
const std::vector<int>& gpuDist,
|
|
22
|
+
const std::vector<faiss::IndexBinary::idx_t>& gpuLabels,
|
|
23
|
+
int numQuery,
|
|
24
|
+
int k) {
|
|
25
|
+
for (int i = 0; i < numQuery; ++i) {
|
|
26
|
+
// The index order can be permuted within a group that has the same
|
|
27
|
+
// distance, since this is based on the order in which the algorithm
|
|
28
|
+
// encounters the values. The last set of equivalent distances seen in the
|
|
29
|
+
// min-k might be truncated, so we can't check that set, but all others we
|
|
30
|
+
// can check.
|
|
31
|
+
std::set<faiss::IndexBinary::idx_t> cpuLabelSet;
|
|
32
|
+
std::set<faiss::IndexBinary::idx_t> gpuLabelSet;
|
|
33
|
+
|
|
34
|
+
int curDist = -1;
|
|
35
|
+
|
|
36
|
+
for (int j = 0; j < k; ++j) {
|
|
37
|
+
int idx = i * k + j;
|
|
38
|
+
|
|
39
|
+
if (curDist == -1) {
|
|
40
|
+
curDist = cpuDist[idx];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (curDist != cpuDist[idx]) {
|
|
44
|
+
// Distances must be monotonically increasing
|
|
45
|
+
EXPECT_LT(curDist, cpuDist[idx]);
|
|
46
|
+
|
|
47
|
+
// This is a new set of distances
|
|
48
|
+
EXPECT_EQ(cpuLabelSet, gpuLabelSet);
|
|
49
|
+
curDist = cpuDist[idx];
|
|
50
|
+
cpuLabelSet.clear();
|
|
51
|
+
gpuLabelSet.clear();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
cpuLabelSet.insert(cpuLabels[idx]);
|
|
55
|
+
gpuLabelSet.insert(gpuLabels[idx]);
|
|
56
|
+
|
|
57
|
+
// Because the distances are reproducible, they must be exactly the same
|
|
58
|
+
EXPECT_EQ(cpuDist[idx], gpuDist[idx]);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
template <int DimMultiple>
|
|
64
|
+
void testGpuIndexBinaryFlat(int kOverride = -1) {
|
|
65
|
+
faiss::gpu::StandardGpuResources res;
|
|
66
|
+
res.noTempMemory();
|
|
67
|
+
|
|
68
|
+
faiss::gpu::GpuIndexBinaryFlatConfig config;
|
|
69
|
+
config.device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
|
|
70
|
+
|
|
71
|
+
// multiples of 8 and multiples of 32 use different implementations
|
|
72
|
+
int dims = faiss::gpu::randVal(1, 20) * DimMultiple;
|
|
73
|
+
faiss::gpu::GpuIndexBinaryFlat gpuIndex(&res, dims, config);
|
|
74
|
+
|
|
75
|
+
faiss::IndexBinaryFlat cpuIndex(dims);
|
|
76
|
+
|
|
77
|
+
int k = kOverride > 0 ?
|
|
78
|
+
kOverride : faiss::gpu::randVal(1, faiss::gpu::getMaxKSelection());
|
|
79
|
+
int numVecs = faiss::gpu::randVal(k + 1, 20000);
|
|
80
|
+
int numQuery = faiss::gpu::randVal(1, 1000);
|
|
81
|
+
|
|
82
|
+
auto data = faiss::gpu::randBinaryVecs(numVecs, dims);
|
|
83
|
+
gpuIndex.add(numVecs, data.data());
|
|
84
|
+
cpuIndex.add(numVecs, data.data());
|
|
85
|
+
|
|
86
|
+
auto query = faiss::gpu::randBinaryVecs(numQuery, dims);
|
|
87
|
+
|
|
88
|
+
std::vector<int> cpuDist(numQuery * k);
|
|
89
|
+
std::vector<faiss::IndexBinary::idx_t> cpuLabels(numQuery * k);
|
|
90
|
+
|
|
91
|
+
cpuIndex.search(numQuery,
|
|
92
|
+
query.data(),
|
|
93
|
+
k,
|
|
94
|
+
cpuDist.data(),
|
|
95
|
+
cpuLabels.data());
|
|
96
|
+
|
|
97
|
+
std::vector<int> gpuDist(numQuery * k);
|
|
98
|
+
std::vector<faiss::IndexBinary::idx_t> gpuLabels(numQuery * k);
|
|
99
|
+
|
|
100
|
+
gpuIndex.search(numQuery,
|
|
101
|
+
query.data(),
|
|
102
|
+
k,
|
|
103
|
+
gpuDist.data(),
|
|
104
|
+
gpuLabels.data());
|
|
105
|
+
|
|
106
|
+
compareBinaryDist(cpuDist, cpuLabels,
|
|
107
|
+
gpuDist, gpuLabels,
|
|
108
|
+
numQuery, k);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
TEST(TestGpuIndexBinaryFlat, Test8) {
|
|
112
|
+
for (int tries = 0; tries < 4; ++tries) {
|
|
113
|
+
testGpuIndexBinaryFlat<8>();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
TEST(TestGpuIndexBinaryFlat, Test32) {
|
|
118
|
+
for (int tries = 0; tries < 4; ++tries) {
|
|
119
|
+
testGpuIndexBinaryFlat<32>();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
int main(int argc, char** argv) {
|
|
124
|
+
testing::InitGoogleTest(&argc, argv);
|
|
125
|
+
|
|
126
|
+
// just run with a fixed test seed
|
|
127
|
+
faiss::gpu::setTestSeed(100);
|
|
128
|
+
|
|
129
|
+
return RUN_ALL_TESTS();
|
|
130
|
+
}
|
|
@@ -0,0 +1,371 @@
|
|
|
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
|
+
|
|
9
|
+
#include <faiss/IndexFlat.h>
|
|
10
|
+
#include <faiss/gpu/GpuIndexFlat.h>
|
|
11
|
+
#include <faiss/gpu/StandardGpuResources.h>
|
|
12
|
+
#include <faiss/gpu/utils/DeviceUtils.h>
|
|
13
|
+
#include <faiss/gpu/test/TestUtils.h>
|
|
14
|
+
#include <gtest/gtest.h>
|
|
15
|
+
#include <sstream>
|
|
16
|
+
#include <vector>
|
|
17
|
+
|
|
18
|
+
// FIXME: figure out a better way to test fp16
|
|
19
|
+
constexpr float kF16MaxRelErr = 0.07f;
|
|
20
|
+
constexpr float kF32MaxRelErr = 6e-3f;
|
|
21
|
+
|
|
22
|
+
struct TestFlatOptions {
|
|
23
|
+
TestFlatOptions()
|
|
24
|
+
: useL2(true),
|
|
25
|
+
useFloat16(false),
|
|
26
|
+
useTransposed(false),
|
|
27
|
+
numVecsOverride(-1),
|
|
28
|
+
numQueriesOverride(-1),
|
|
29
|
+
kOverride(-1),
|
|
30
|
+
dimOverride(-1) {
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
bool useL2;
|
|
34
|
+
bool useFloat16;
|
|
35
|
+
bool useTransposed;
|
|
36
|
+
int numVecsOverride;
|
|
37
|
+
int numQueriesOverride;
|
|
38
|
+
int kOverride;
|
|
39
|
+
int dimOverride;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
void testFlat(const TestFlatOptions& opt) {
|
|
43
|
+
int numVecs = opt.numVecsOverride > 0 ?
|
|
44
|
+
opt.numVecsOverride : faiss::gpu::randVal(1000, 20000);
|
|
45
|
+
int dim = opt.dimOverride > 0 ?
|
|
46
|
+
opt.dimOverride : faiss::gpu::randVal(50, 800);
|
|
47
|
+
int numQuery = opt.numQueriesOverride > 0 ?
|
|
48
|
+
opt.numQueriesOverride : faiss::gpu::randVal(1, 512);
|
|
49
|
+
|
|
50
|
+
// Due to loss of precision in a float16 accumulator, for large k,
|
|
51
|
+
// the number of differences is pretty huge. Restrict ourselves to a
|
|
52
|
+
// fairly small `k` for float16
|
|
53
|
+
int k = opt.useFloat16 ?
|
|
54
|
+
std::min(faiss::gpu::randVal(1, 50), numVecs) :
|
|
55
|
+
std::min(faiss::gpu::randVal(1, faiss::gpu::getMaxKSelection()), numVecs);
|
|
56
|
+
if (opt.kOverride > 0) {
|
|
57
|
+
k = opt.kOverride;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
faiss::IndexFlatIP cpuIndexIP(dim);
|
|
61
|
+
faiss::IndexFlatL2 cpuIndexL2(dim);
|
|
62
|
+
|
|
63
|
+
faiss::IndexFlat* cpuIndex =
|
|
64
|
+
opt.useL2 ? (faiss::IndexFlat*) &cpuIndexL2 :
|
|
65
|
+
(faiss::IndexFlat*) &cpuIndexIP;
|
|
66
|
+
|
|
67
|
+
// Construct on a random device to test multi-device, if we have
|
|
68
|
+
// multiple devices
|
|
69
|
+
int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
|
|
70
|
+
|
|
71
|
+
faiss::gpu::StandardGpuResources res;
|
|
72
|
+
res.noTempMemory();
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
faiss::gpu::GpuIndexFlatConfig config;
|
|
76
|
+
config.device = device;
|
|
77
|
+
config.useFloat16 = opt.useFloat16;
|
|
78
|
+
config.storeTransposed = opt.useTransposed;
|
|
79
|
+
|
|
80
|
+
faiss::gpu::GpuIndexFlatIP gpuIndexIP(&res, dim, config);
|
|
81
|
+
faiss::gpu::GpuIndexFlatL2 gpuIndexL2(&res, dim, config);
|
|
82
|
+
|
|
83
|
+
faiss::gpu::GpuIndexFlat* gpuIndex =
|
|
84
|
+
opt.useL2 ? (faiss::gpu::GpuIndexFlat*) &gpuIndexL2 :
|
|
85
|
+
(faiss::gpu::GpuIndexFlat*) &gpuIndexIP;
|
|
86
|
+
|
|
87
|
+
std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
|
|
88
|
+
cpuIndex->add(numVecs, vecs.data());
|
|
89
|
+
gpuIndex->add(numVecs, vecs.data());
|
|
90
|
+
|
|
91
|
+
std::stringstream str;
|
|
92
|
+
str << (opt.useL2 ? "L2" : "IP") << " numVecs " << numVecs
|
|
93
|
+
<< " dim " << dim
|
|
94
|
+
<< " useFloat16 " << opt.useFloat16
|
|
95
|
+
<< " transposed " << opt.useTransposed
|
|
96
|
+
<< " numQuery " << numQuery
|
|
97
|
+
<< " k " << k;
|
|
98
|
+
|
|
99
|
+
// To some extent, we depend upon the relative error for the test
|
|
100
|
+
// for float16
|
|
101
|
+
faiss::gpu::compareIndices(*cpuIndex, *gpuIndex, numQuery, dim, k, str.str(),
|
|
102
|
+
opt.useFloat16 ? kF16MaxRelErr : kF32MaxRelErr,
|
|
103
|
+
// FIXME: the fp16 bounds are
|
|
104
|
+
// useless when math (the accumulator) is
|
|
105
|
+
// in fp16. Figure out another way to test
|
|
106
|
+
opt.useFloat16 ? 0.99f : 0.1f,
|
|
107
|
+
opt.useFloat16 ? 0.65f : 0.015f);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
TEST(TestGpuIndexFlat, IP_Float32) {
|
|
111
|
+
for (int tries = 0; tries < 3; ++tries) {
|
|
112
|
+
TestFlatOptions opt;
|
|
113
|
+
opt.useL2 = false;
|
|
114
|
+
opt.useFloat16 = false;
|
|
115
|
+
opt.useTransposed = false;
|
|
116
|
+
|
|
117
|
+
testFlat(opt);
|
|
118
|
+
|
|
119
|
+
opt.useTransposed = true;
|
|
120
|
+
testFlat(opt);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
TEST(TestGpuIndexFlat, L2_Float32) {
|
|
125
|
+
for (int tries = 0; tries < 3; ++tries) {
|
|
126
|
+
TestFlatOptions opt;
|
|
127
|
+
opt.useL2 = true;
|
|
128
|
+
opt.useFloat16 = false;
|
|
129
|
+
opt.useTransposed = false;
|
|
130
|
+
|
|
131
|
+
testFlat(opt);
|
|
132
|
+
|
|
133
|
+
opt.useTransposed = true;
|
|
134
|
+
testFlat(opt);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// test specialized k == 1 codepath
|
|
139
|
+
TEST(TestGpuIndexFlat, L2_Float32_K1) {
|
|
140
|
+
for (int tries = 0; tries < 3; ++tries) {
|
|
141
|
+
TestFlatOptions opt;
|
|
142
|
+
opt.useL2 = true;
|
|
143
|
+
opt.useFloat16 = false;
|
|
144
|
+
opt.useTransposed = false;
|
|
145
|
+
opt.kOverride = 1;
|
|
146
|
+
|
|
147
|
+
testFlat(opt);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
TEST(TestGpuIndexFlat, IP_Float16) {
|
|
152
|
+
for (int tries = 0; tries < 3; ++tries) {
|
|
153
|
+
TestFlatOptions opt;
|
|
154
|
+
opt.useL2 = false;
|
|
155
|
+
opt.useFloat16 = true;
|
|
156
|
+
opt.useTransposed = false;
|
|
157
|
+
|
|
158
|
+
testFlat(opt);
|
|
159
|
+
|
|
160
|
+
opt.useTransposed = true;
|
|
161
|
+
testFlat(opt);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
TEST(TestGpuIndexFlat, L2_Float16) {
|
|
166
|
+
for (int tries = 0; tries < 3; ++tries) {
|
|
167
|
+
TestFlatOptions opt;
|
|
168
|
+
opt.useL2 = true;
|
|
169
|
+
opt.useFloat16 = true;
|
|
170
|
+
opt.useTransposed = false;
|
|
171
|
+
|
|
172
|
+
testFlat(opt);
|
|
173
|
+
|
|
174
|
+
opt.useTransposed = true;
|
|
175
|
+
testFlat(opt);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// test specialized k == 1 codepath
|
|
180
|
+
TEST(TestGpuIndexFlat, L2_Float16_K1) {
|
|
181
|
+
for (int tries = 0; tries < 3; ++tries) {
|
|
182
|
+
TestFlatOptions opt;
|
|
183
|
+
opt.useL2 = true;
|
|
184
|
+
opt.useFloat16 = true;
|
|
185
|
+
opt.useTransposed = false;
|
|
186
|
+
opt.kOverride = 1;
|
|
187
|
+
|
|
188
|
+
testFlat(opt);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// test tiling along a huge vector set
|
|
193
|
+
TEST(TestGpuIndexFlat, L2_Tiling) {
|
|
194
|
+
for (int tries = 0; tries < 2; ++tries) {
|
|
195
|
+
TestFlatOptions opt;
|
|
196
|
+
opt.useL2 = true;
|
|
197
|
+
opt.useFloat16 = false;
|
|
198
|
+
opt.useTransposed = false;
|
|
199
|
+
opt.numVecsOverride = 1000000;
|
|
200
|
+
|
|
201
|
+
// keep the rest of the problem reasonably small
|
|
202
|
+
opt.numQueriesOverride = 4;
|
|
203
|
+
opt.dimOverride = 64;
|
|
204
|
+
opt.kOverride = 64;
|
|
205
|
+
|
|
206
|
+
testFlat(opt);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
TEST(TestGpuIndexFlat, QueryEmpty) {
|
|
211
|
+
faiss::gpu::StandardGpuResources res;
|
|
212
|
+
res.noTempMemory();
|
|
213
|
+
|
|
214
|
+
faiss::gpu::GpuIndexFlatConfig config;
|
|
215
|
+
config.device = 0;
|
|
216
|
+
config.useFloat16 = false;
|
|
217
|
+
config.storeTransposed = false;
|
|
218
|
+
|
|
219
|
+
int dim = 128;
|
|
220
|
+
faiss::gpu::GpuIndexFlatL2 gpuIndex(&res, dim, config);
|
|
221
|
+
|
|
222
|
+
// Querying an empty index should not blow up, and just return
|
|
223
|
+
// (FLT_MAX, -1)
|
|
224
|
+
int numQuery = 10;
|
|
225
|
+
int k = 50;
|
|
226
|
+
std::vector<float> queries(numQuery * dim, 1.0f);
|
|
227
|
+
|
|
228
|
+
std::vector<float> dist(numQuery * k, 0);
|
|
229
|
+
std::vector<faiss::Index::idx_t> ind(numQuery * k);
|
|
230
|
+
|
|
231
|
+
gpuIndex.search(numQuery, queries.data(), k, dist.data(), ind.data());
|
|
232
|
+
|
|
233
|
+
for (auto d : dist) {
|
|
234
|
+
EXPECT_EQ(d, std::numeric_limits<float>::max());
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
for (auto i : ind) {
|
|
238
|
+
EXPECT_EQ(i, -1);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
TEST(TestGpuIndexFlat, CopyFrom) {
|
|
243
|
+
int numVecs = faiss::gpu::randVal(100, 200);
|
|
244
|
+
int dim = faiss::gpu::randVal(1, 1000);
|
|
245
|
+
|
|
246
|
+
faiss::IndexFlatL2 cpuIndex(dim);
|
|
247
|
+
|
|
248
|
+
std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
|
|
249
|
+
cpuIndex.add(numVecs, vecs.data());
|
|
250
|
+
|
|
251
|
+
faiss::gpu::StandardGpuResources res;
|
|
252
|
+
res.noTempMemory();
|
|
253
|
+
|
|
254
|
+
// Fill with garbage values
|
|
255
|
+
int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
|
|
256
|
+
|
|
257
|
+
faiss::gpu::GpuIndexFlatConfig config;
|
|
258
|
+
config.device = 0;
|
|
259
|
+
config.useFloat16 = false;
|
|
260
|
+
config.storeTransposed = false;
|
|
261
|
+
|
|
262
|
+
faiss::gpu::GpuIndexFlatL2 gpuIndex(&res, 2000, config);
|
|
263
|
+
gpuIndex.copyFrom(&cpuIndex);
|
|
264
|
+
|
|
265
|
+
EXPECT_EQ(cpuIndex.ntotal, gpuIndex.ntotal);
|
|
266
|
+
EXPECT_EQ(gpuIndex.ntotal, numVecs);
|
|
267
|
+
|
|
268
|
+
EXPECT_EQ(cpuIndex.d, gpuIndex.d);
|
|
269
|
+
EXPECT_EQ(cpuIndex.d, dim);
|
|
270
|
+
|
|
271
|
+
int idx = faiss::gpu::randVal(0, numVecs - 1);
|
|
272
|
+
|
|
273
|
+
std::vector<float> gpuVals(dim);
|
|
274
|
+
gpuIndex.reconstruct(idx, gpuVals.data());
|
|
275
|
+
|
|
276
|
+
std::vector<float> cpuVals(dim);
|
|
277
|
+
cpuIndex.reconstruct(idx, cpuVals.data());
|
|
278
|
+
|
|
279
|
+
EXPECT_EQ(gpuVals, cpuVals);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
TEST(TestGpuIndexFlat, CopyTo) {
|
|
283
|
+
faiss::gpu::StandardGpuResources res;
|
|
284
|
+
res.noTempMemory();
|
|
285
|
+
|
|
286
|
+
int numVecs = faiss::gpu::randVal(100, 200);
|
|
287
|
+
int dim = faiss::gpu::randVal(1, 1000);
|
|
288
|
+
|
|
289
|
+
int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
|
|
290
|
+
|
|
291
|
+
faiss::gpu::GpuIndexFlatConfig config;
|
|
292
|
+
config.device = device;
|
|
293
|
+
config.useFloat16 = false;
|
|
294
|
+
config.storeTransposed = false;
|
|
295
|
+
|
|
296
|
+
faiss::gpu::GpuIndexFlatL2 gpuIndex(&res, dim, config);
|
|
297
|
+
|
|
298
|
+
std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
|
|
299
|
+
gpuIndex.add(numVecs, vecs.data());
|
|
300
|
+
|
|
301
|
+
// Fill with garbage values
|
|
302
|
+
faiss::IndexFlatL2 cpuIndex(2000);
|
|
303
|
+
gpuIndex.copyTo(&cpuIndex);
|
|
304
|
+
|
|
305
|
+
EXPECT_EQ(cpuIndex.ntotal, gpuIndex.ntotal);
|
|
306
|
+
EXPECT_EQ(gpuIndex.ntotal, numVecs);
|
|
307
|
+
|
|
308
|
+
EXPECT_EQ(cpuIndex.d, gpuIndex.d);
|
|
309
|
+
EXPECT_EQ(cpuIndex.d, dim);
|
|
310
|
+
|
|
311
|
+
int idx = faiss::gpu::randVal(0, numVecs - 1);
|
|
312
|
+
|
|
313
|
+
std::vector<float> gpuVals(dim);
|
|
314
|
+
gpuIndex.reconstruct(idx, gpuVals.data());
|
|
315
|
+
|
|
316
|
+
std::vector<float> cpuVals(dim);
|
|
317
|
+
cpuIndex.reconstruct(idx, cpuVals.data());
|
|
318
|
+
|
|
319
|
+
EXPECT_EQ(gpuVals, cpuVals);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
TEST(TestGpuIndexFlat, UnifiedMemory) {
|
|
323
|
+
// Construct on a random device to test multi-device, if we have
|
|
324
|
+
// multiple devices
|
|
325
|
+
int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
|
|
326
|
+
|
|
327
|
+
if (!faiss::gpu::getFullUnifiedMemSupport(device)) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
int dim = 256;
|
|
332
|
+
|
|
333
|
+
// FIXME: GpuIndexFlat doesn't support > 2^31 (vecs * dims) due to
|
|
334
|
+
// kernel indexing, so we can't test unified memory for memory
|
|
335
|
+
// oversubscription.
|
|
336
|
+
size_t numVecs = 50000;
|
|
337
|
+
int numQuery = 10;
|
|
338
|
+
int k = 10;
|
|
339
|
+
|
|
340
|
+
faiss::IndexFlatL2 cpuIndexL2(dim);
|
|
341
|
+
|
|
342
|
+
faiss::gpu::StandardGpuResources res;
|
|
343
|
+
res.noTempMemory();
|
|
344
|
+
|
|
345
|
+
faiss::gpu::GpuIndexFlatConfig config;
|
|
346
|
+
config.device = device;
|
|
347
|
+
config.memorySpace = faiss::gpu::MemorySpace::Unified;
|
|
348
|
+
|
|
349
|
+
faiss::gpu::GpuIndexFlatL2 gpuIndexL2(&res, dim, config);
|
|
350
|
+
|
|
351
|
+
std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
|
|
352
|
+
cpuIndexL2.add(numVecs, vecs.data());
|
|
353
|
+
gpuIndexL2.add(numVecs, vecs.data());
|
|
354
|
+
|
|
355
|
+
// To some extent, we depend upon the relative error for the test
|
|
356
|
+
// for float16
|
|
357
|
+
faiss::gpu::compareIndices(cpuIndexL2, gpuIndexL2,
|
|
358
|
+
numQuery, dim, k, "Unified Memory",
|
|
359
|
+
kF32MaxRelErr,
|
|
360
|
+
0.1f,
|
|
361
|
+
0.015f);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
int main(int argc, char** argv) {
|
|
365
|
+
testing::InitGoogleTest(&argc, argv);
|
|
366
|
+
|
|
367
|
+
// just run with a fixed test seed
|
|
368
|
+
faiss::gpu::setTestSeed(100);
|
|
369
|
+
|
|
370
|
+
return RUN_ALL_TESTS();
|
|
371
|
+
}
|