faiss 0.2.0 → 0.2.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 +16 -0
- data/LICENSE.txt +1 -1
- data/README.md +7 -7
- data/ext/faiss/extconf.rb +6 -3
- data/ext/faiss/numo.hpp +4 -4
- data/ext/faiss/utils.cpp +1 -1
- data/ext/faiss/utils.h +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +292 -291
- data/vendor/faiss/faiss/AutoTune.h +55 -56
- data/vendor/faiss/faiss/Clustering.cpp +365 -194
- data/vendor/faiss/faiss/Clustering.h +102 -35
- data/vendor/faiss/faiss/IVFlib.cpp +171 -195
- data/vendor/faiss/faiss/IVFlib.h +48 -51
- data/vendor/faiss/faiss/Index.cpp +85 -103
- data/vendor/faiss/faiss/Index.h +54 -48
- data/vendor/faiss/faiss/Index2Layer.cpp +126 -224
- data/vendor/faiss/faiss/Index2Layer.h +22 -36
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +407 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +195 -0
- data/vendor/faiss/faiss/IndexBinary.cpp +45 -37
- data/vendor/faiss/faiss/IndexBinary.h +140 -132
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +73 -53
- data/vendor/faiss/faiss/IndexBinaryFlat.h +29 -24
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +46 -43
- data/vendor/faiss/faiss/IndexBinaryFromFloat.h +16 -15
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +215 -232
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +25 -24
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +182 -177
- data/vendor/faiss/faiss/IndexBinaryHash.h +41 -34
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +489 -461
- data/vendor/faiss/faiss/IndexBinaryIVF.h +97 -68
- data/vendor/faiss/faiss/IndexFlat.cpp +115 -176
- data/vendor/faiss/faiss/IndexFlat.h +42 -59
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +67 -0
- data/vendor/faiss/faiss/IndexFlatCodes.h +47 -0
- data/vendor/faiss/faiss/IndexHNSW.cpp +372 -348
- data/vendor/faiss/faiss/IndexHNSW.h +57 -41
- data/vendor/faiss/faiss/IndexIVF.cpp +545 -453
- data/vendor/faiss/faiss/IndexIVF.h +169 -118
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +316 -0
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +121 -0
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +247 -252
- data/vendor/faiss/faiss/IndexIVFFlat.h +48 -51
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +459 -517
- data/vendor/faiss/faiss/IndexIVFPQ.h +75 -67
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +406 -372
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +82 -57
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +104 -102
- data/vendor/faiss/faiss/IndexIVFPQR.h +33 -28
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +163 -150
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +38 -25
- data/vendor/faiss/faiss/IndexLSH.cpp +66 -113
- data/vendor/faiss/faiss/IndexLSH.h +20 -38
- data/vendor/faiss/faiss/IndexLattice.cpp +42 -56
- data/vendor/faiss/faiss/IndexLattice.h +11 -16
- data/vendor/faiss/faiss/IndexNNDescent.cpp +229 -0
- data/vendor/faiss/faiss/IndexNNDescent.h +72 -0
- data/vendor/faiss/faiss/IndexNSG.cpp +301 -0
- data/vendor/faiss/faiss/IndexNSG.h +85 -0
- data/vendor/faiss/faiss/IndexPQ.cpp +387 -495
- data/vendor/faiss/faiss/IndexPQ.h +64 -82
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +143 -170
- data/vendor/faiss/faiss/IndexPQFastScan.h +46 -32
- data/vendor/faiss/faiss/IndexPreTransform.cpp +120 -150
- data/vendor/faiss/faiss/IndexPreTransform.h +33 -36
- data/vendor/faiss/faiss/IndexRefine.cpp +139 -127
- data/vendor/faiss/faiss/IndexRefine.h +32 -23
- data/vendor/faiss/faiss/IndexReplicas.cpp +147 -153
- data/vendor/faiss/faiss/IndexReplicas.h +62 -56
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +111 -172
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +41 -59
- data/vendor/faiss/faiss/IndexShards.cpp +256 -240
- data/vendor/faiss/faiss/IndexShards.h +85 -73
- data/vendor/faiss/faiss/MatrixStats.cpp +112 -97
- data/vendor/faiss/faiss/MatrixStats.h +7 -10
- data/vendor/faiss/faiss/MetaIndexes.cpp +135 -157
- data/vendor/faiss/faiss/MetaIndexes.h +40 -34
- data/vendor/faiss/faiss/MetricType.h +7 -7
- data/vendor/faiss/faiss/VectorTransform.cpp +654 -475
- data/vendor/faiss/faiss/VectorTransform.h +64 -89
- data/vendor/faiss/faiss/clone_index.cpp +78 -73
- data/vendor/faiss/faiss/clone_index.h +4 -9
- data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +33 -38
- data/vendor/faiss/faiss/gpu/GpuAutoTune.h +11 -9
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +198 -171
- data/vendor/faiss/faiss/gpu/GpuCloner.h +53 -35
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.cpp +12 -14
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +27 -25
- data/vendor/faiss/faiss/gpu/GpuDistance.h +116 -112
- data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -2
- data/vendor/faiss/faiss/gpu/GpuIcmEncoder.h +60 -0
- data/vendor/faiss/faiss/gpu/GpuIndex.h +134 -137
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +76 -73
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +173 -162
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +67 -64
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +89 -86
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +150 -141
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +101 -103
- data/vendor/faiss/faiss/gpu/GpuIndicesOptions.h +17 -16
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +116 -128
- data/vendor/faiss/faiss/gpu/GpuResources.h +182 -186
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +433 -422
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +131 -130
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +468 -456
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +25 -19
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +22 -20
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +9 -8
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +39 -44
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +16 -14
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +77 -71
- data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +109 -88
- data/vendor/faiss/faiss/gpu/perf/WriteIndex.cpp +75 -64
- data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +230 -215
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +80 -86
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +284 -277
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +416 -416
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +611 -517
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +166 -164
- data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +61 -53
- data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +274 -238
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +73 -57
- data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +47 -50
- data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +79 -72
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +140 -146
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.h +69 -71
- data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +21 -16
- data/vendor/faiss/faiss/gpu/utils/Timer.cpp +25 -29
- data/vendor/faiss/faiss/gpu/utils/Timer.h +30 -29
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +503 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +175 -0
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +90 -120
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +81 -65
- data/vendor/faiss/faiss/impl/FaissAssert.h +73 -58
- data/vendor/faiss/faiss/impl/FaissException.cpp +56 -48
- data/vendor/faiss/faiss/impl/FaissException.h +41 -29
- data/vendor/faiss/faiss/impl/HNSW.cpp +606 -617
- data/vendor/faiss/faiss/impl/HNSW.h +179 -200
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +855 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +244 -0
- data/vendor/faiss/faiss/impl/NNDescent.cpp +487 -0
- data/vendor/faiss/faiss/impl/NNDescent.h +154 -0
- data/vendor/faiss/faiss/impl/NSG.cpp +679 -0
- data/vendor/faiss/faiss/impl/NSG.h +199 -0
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +484 -454
- data/vendor/faiss/faiss/impl/PolysemousTraining.h +52 -55
- data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +26 -47
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +469 -459
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +76 -87
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +758 -0
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +188 -0
- data/vendor/faiss/faiss/impl/ResultHandler.h +96 -132
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +647 -707
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +48 -46
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +129 -131
- data/vendor/faiss/faiss/impl/ThreadedIndex.h +61 -55
- data/vendor/faiss/faiss/impl/index_read.cpp +631 -480
- data/vendor/faiss/faiss/impl/index_write.cpp +547 -407
- data/vendor/faiss/faiss/impl/io.cpp +76 -95
- data/vendor/faiss/faiss/impl/io.h +31 -41
- data/vendor/faiss/faiss/impl/io_macros.h +60 -29
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +301 -0
- data/vendor/faiss/faiss/impl/kmeans1d.h +48 -0
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +137 -186
- data/vendor/faiss/faiss/impl/lattice_Zn.h +40 -51
- data/vendor/faiss/faiss/impl/platform_macros.h +29 -8
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +77 -124
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +39 -48
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +41 -52
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +80 -117
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +109 -137
- data/vendor/faiss/faiss/index_factory.cpp +619 -397
- data/vendor/faiss/faiss/index_factory.h +8 -6
- data/vendor/faiss/faiss/index_io.h +23 -26
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +67 -75
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +22 -24
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +96 -112
- data/vendor/faiss/faiss/invlists/DirectMap.h +29 -33
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +307 -364
- data/vendor/faiss/faiss/invlists/InvertedLists.h +151 -151
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +29 -34
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +17 -18
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +257 -293
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +50 -45
- data/vendor/faiss/faiss/python/python_callbacks.cpp +23 -26
- data/vendor/faiss/faiss/python/python_callbacks.h +9 -16
- data/vendor/faiss/faiss/utils/AlignedTable.h +79 -44
- data/vendor/faiss/faiss/utils/Heap.cpp +40 -48
- data/vendor/faiss/faiss/utils/Heap.h +186 -209
- data/vendor/faiss/faiss/utils/WorkerThread.cpp +67 -76
- data/vendor/faiss/faiss/utils/WorkerThread.h +32 -33
- data/vendor/faiss/faiss/utils/distances.cpp +305 -312
- data/vendor/faiss/faiss/utils/distances.h +170 -122
- data/vendor/faiss/faiss/utils/distances_simd.cpp +498 -508
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +117 -0
- data/vendor/faiss/faiss/utils/extra_distances.cpp +113 -232
- data/vendor/faiss/faiss/utils/extra_distances.h +30 -29
- data/vendor/faiss/faiss/utils/hamming-inl.h +260 -209
- data/vendor/faiss/faiss/utils/hamming.cpp +375 -469
- data/vendor/faiss/faiss/utils/hamming.h +62 -85
- data/vendor/faiss/faiss/utils/ordered_key_value.h +16 -18
- data/vendor/faiss/faiss/utils/partitioning.cpp +393 -318
- data/vendor/faiss/faiss/utils/partitioning.h +26 -21
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +78 -66
- data/vendor/faiss/faiss/utils/quantize_lut.h +22 -20
- data/vendor/faiss/faiss/utils/random.cpp +39 -63
- data/vendor/faiss/faiss/utils/random.h +13 -16
- data/vendor/faiss/faiss/utils/simdlib.h +4 -2
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +88 -85
- data/vendor/faiss/faiss/utils/simdlib_emulated.h +226 -165
- data/vendor/faiss/faiss/utils/simdlib_neon.h +832 -0
- data/vendor/faiss/faiss/utils/utils.cpp +304 -287
- data/vendor/faiss/faiss/utils/utils.h +54 -49
- metadata +29 -4
|
@@ -9,34 +9,28 @@
|
|
|
9
9
|
|
|
10
10
|
#include <faiss/MetaIndexes.h>
|
|
11
11
|
|
|
12
|
+
#include <stdint.h>
|
|
12
13
|
#include <cinttypes>
|
|
13
14
|
#include <cstdio>
|
|
14
15
|
#include <limits>
|
|
15
|
-
#include <stdint.h>
|
|
16
16
|
|
|
17
|
+
#include <faiss/impl/AuxIndexStructures.h>
|
|
17
18
|
#include <faiss/impl/FaissAssert.h>
|
|
18
19
|
#include <faiss/utils/Heap.h>
|
|
19
|
-
#include <faiss/impl/AuxIndexStructures.h>
|
|
20
20
|
#include <faiss/utils/WorkerThread.h>
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
namespace faiss {
|
|
24
23
|
|
|
25
|
-
namespace {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
} // namespace
|
|
24
|
+
namespace {} // namespace
|
|
29
25
|
|
|
30
26
|
/*****************************************************
|
|
31
27
|
* IndexIDMap implementation
|
|
32
28
|
*******************************************************/
|
|
33
29
|
|
|
34
30
|
template <typename IndexT>
|
|
35
|
-
IndexIDMapTemplate<IndexT>::IndexIDMapTemplate
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{
|
|
39
|
-
FAISS_THROW_IF_NOT_MSG (index->ntotal == 0, "index must be empty on input");
|
|
31
|
+
IndexIDMapTemplate<IndexT>::IndexIDMapTemplate(IndexT* index)
|
|
32
|
+
: index(index), own_fields(false) {
|
|
33
|
+
FAISS_THROW_IF_NOT_MSG(index->ntotal == 0, "index must be empty on input");
|
|
40
34
|
this->is_trained = index->is_trained;
|
|
41
35
|
this->metric_type = index->metric_type;
|
|
42
36
|
this->verbose = index->verbose;
|
|
@@ -44,168 +38,159 @@ IndexIDMapTemplate<IndexT>::IndexIDMapTemplate (IndexT *index):
|
|
|
44
38
|
}
|
|
45
39
|
|
|
46
40
|
template <typename IndexT>
|
|
47
|
-
void IndexIDMapTemplate<IndexT>::add
|
|
48
|
-
|
|
49
|
-
{
|
|
50
|
-
FAISS_THROW_MSG
|
|
51
|
-
|
|
41
|
+
void IndexIDMapTemplate<IndexT>::add(
|
|
42
|
+
idx_t,
|
|
43
|
+
const typename IndexT::component_t*) {
|
|
44
|
+
FAISS_THROW_MSG(
|
|
45
|
+
"add does not make sense with IndexIDMap, "
|
|
46
|
+
"use add_with_ids");
|
|
52
47
|
}
|
|
53
48
|
|
|
54
|
-
|
|
55
49
|
template <typename IndexT>
|
|
56
|
-
void IndexIDMapTemplate<IndexT>::train
|
|
57
|
-
|
|
58
|
-
{
|
|
59
|
-
index->train
|
|
50
|
+
void IndexIDMapTemplate<IndexT>::train(
|
|
51
|
+
idx_t n,
|
|
52
|
+
const typename IndexT::component_t* x) {
|
|
53
|
+
index->train(n, x);
|
|
60
54
|
this->is_trained = index->is_trained;
|
|
61
55
|
}
|
|
62
56
|
|
|
63
57
|
template <typename IndexT>
|
|
64
|
-
void IndexIDMapTemplate<IndexT>::reset
|
|
65
|
-
|
|
66
|
-
index->reset ();
|
|
58
|
+
void IndexIDMapTemplate<IndexT>::reset() {
|
|
59
|
+
index->reset();
|
|
67
60
|
id_map.clear();
|
|
68
61
|
this->ntotal = 0;
|
|
69
62
|
}
|
|
70
63
|
|
|
71
|
-
|
|
72
64
|
template <typename IndexT>
|
|
73
|
-
void IndexIDMapTemplate<IndexT>::add_with_ids
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
{
|
|
77
|
-
index->add
|
|
65
|
+
void IndexIDMapTemplate<IndexT>::add_with_ids(
|
|
66
|
+
idx_t n,
|
|
67
|
+
const typename IndexT::component_t* x,
|
|
68
|
+
const typename IndexT::idx_t* xids) {
|
|
69
|
+
index->add(n, x);
|
|
78
70
|
for (idx_t i = 0; i < n; i++)
|
|
79
|
-
id_map.push_back
|
|
71
|
+
id_map.push_back(xids[i]);
|
|
80
72
|
this->ntotal = index->ntotal;
|
|
81
73
|
}
|
|
82
74
|
|
|
83
|
-
|
|
84
75
|
template <typename IndexT>
|
|
85
|
-
void IndexIDMapTemplate<IndexT>::search
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
76
|
+
void IndexIDMapTemplate<IndexT>::search(
|
|
77
|
+
idx_t n,
|
|
78
|
+
const typename IndexT::component_t* x,
|
|
79
|
+
idx_t k,
|
|
80
|
+
typename IndexT::distance_t* distances,
|
|
81
|
+
typename IndexT::idx_t* labels) const {
|
|
82
|
+
index->search(n, x, k, distances, labels);
|
|
83
|
+
idx_t* li = labels;
|
|
91
84
|
#pragma omp parallel for
|
|
92
85
|
for (idx_t i = 0; i < n * k; i++) {
|
|
93
86
|
li[i] = li[i] < 0 ? li[i] : id_map[li[i]];
|
|
94
87
|
}
|
|
95
88
|
}
|
|
96
89
|
|
|
97
|
-
|
|
98
90
|
template <typename IndexT>
|
|
99
|
-
void IndexIDMapTemplate<IndexT>::range_search
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
91
|
+
void IndexIDMapTemplate<IndexT>::range_search(
|
|
92
|
+
typename IndexT::idx_t n,
|
|
93
|
+
const typename IndexT::component_t* x,
|
|
94
|
+
typename IndexT::distance_t radius,
|
|
95
|
+
RangeSearchResult* result) const {
|
|
96
|
+
index->range_search(n, x, radius, result);
|
|
104
97
|
#pragma omp parallel for
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
98
|
+
for (idx_t i = 0; i < result->lims[result->nq]; i++) {
|
|
99
|
+
result->labels[i] = result->labels[i] < 0 ? result->labels[i]
|
|
100
|
+
: id_map[result->labels[i]];
|
|
101
|
+
}
|
|
109
102
|
}
|
|
110
103
|
|
|
111
104
|
namespace {
|
|
112
105
|
|
|
113
|
-
struct IDTranslatedSelector: IDSelector {
|
|
114
|
-
const std::vector
|
|
115
|
-
const IDSelector
|
|
116
|
-
IDTranslatedSelector
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
106
|
+
struct IDTranslatedSelector : IDSelector {
|
|
107
|
+
const std::vector<int64_t>& id_map;
|
|
108
|
+
const IDSelector& sel;
|
|
109
|
+
IDTranslatedSelector(
|
|
110
|
+
const std::vector<int64_t>& id_map,
|
|
111
|
+
const IDSelector& sel)
|
|
112
|
+
: id_map(id_map), sel(sel) {}
|
|
120
113
|
bool is_member(idx_t id) const override {
|
|
121
|
-
|
|
114
|
+
return sel.is_member(id_map[id]);
|
|
122
115
|
}
|
|
123
116
|
};
|
|
124
117
|
|
|
125
|
-
}
|
|
118
|
+
} // namespace
|
|
126
119
|
|
|
127
120
|
template <typename IndexT>
|
|
128
|
-
size_t IndexIDMapTemplate<IndexT>::remove_ids
|
|
129
|
-
{
|
|
121
|
+
size_t IndexIDMapTemplate<IndexT>::remove_ids(const IDSelector& sel) {
|
|
130
122
|
// remove in sub-index first
|
|
131
|
-
IDTranslatedSelector sel2
|
|
132
|
-
size_t nremove = index->remove_ids
|
|
123
|
+
IDTranslatedSelector sel2(id_map, sel);
|
|
124
|
+
size_t nremove = index->remove_ids(sel2);
|
|
133
125
|
|
|
134
126
|
int64_t j = 0;
|
|
135
127
|
for (idx_t i = 0; i < this->ntotal; i++) {
|
|
136
|
-
if (sel.is_member
|
|
128
|
+
if (sel.is_member(id_map[i])) {
|
|
137
129
|
// remove
|
|
138
130
|
} else {
|
|
139
131
|
id_map[j] = id_map[i];
|
|
140
132
|
j++;
|
|
141
133
|
}
|
|
142
134
|
}
|
|
143
|
-
FAISS_ASSERT
|
|
135
|
+
FAISS_ASSERT(j == index->ntotal);
|
|
144
136
|
this->ntotal = j;
|
|
145
137
|
id_map.resize(this->ntotal);
|
|
146
138
|
return nremove;
|
|
147
139
|
}
|
|
148
140
|
|
|
149
141
|
template <typename IndexT>
|
|
150
|
-
IndexIDMapTemplate<IndexT>::~IndexIDMapTemplate
|
|
151
|
-
|
|
152
|
-
|
|
142
|
+
IndexIDMapTemplate<IndexT>::~IndexIDMapTemplate() {
|
|
143
|
+
if (own_fields)
|
|
144
|
+
delete index;
|
|
153
145
|
}
|
|
154
146
|
|
|
155
|
-
|
|
156
|
-
|
|
157
147
|
/*****************************************************
|
|
158
148
|
* IndexIDMap2 implementation
|
|
159
149
|
*******************************************************/
|
|
160
150
|
|
|
161
151
|
template <typename IndexT>
|
|
162
|
-
IndexIDMap2Template<IndexT>::IndexIDMap2Template
|
|
163
|
-
|
|
164
|
-
{}
|
|
152
|
+
IndexIDMap2Template<IndexT>::IndexIDMap2Template(IndexT* index)
|
|
153
|
+
: IndexIDMapTemplate<IndexT>(index) {}
|
|
165
154
|
|
|
166
155
|
template <typename IndexT>
|
|
167
|
-
void IndexIDMap2Template<IndexT>::add_with_ids
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
{
|
|
156
|
+
void IndexIDMap2Template<IndexT>::add_with_ids(
|
|
157
|
+
idx_t n,
|
|
158
|
+
const typename IndexT::component_t* x,
|
|
159
|
+
const typename IndexT::idx_t* xids) {
|
|
171
160
|
size_t prev_ntotal = this->ntotal;
|
|
172
|
-
IndexIDMapTemplate<IndexT>::add_with_ids
|
|
161
|
+
IndexIDMapTemplate<IndexT>::add_with_ids(n, x, xids);
|
|
173
162
|
for (size_t i = prev_ntotal; i < this->ntotal; i++) {
|
|
174
|
-
rev_map
|
|
163
|
+
rev_map[this->id_map[i]] = i;
|
|
175
164
|
}
|
|
176
165
|
}
|
|
177
166
|
|
|
178
167
|
template <typename IndexT>
|
|
179
|
-
void IndexIDMap2Template<IndexT>::construct_rev_map
|
|
180
|
-
|
|
181
|
-
rev_map.clear ();
|
|
168
|
+
void IndexIDMap2Template<IndexT>::construct_rev_map() {
|
|
169
|
+
rev_map.clear();
|
|
182
170
|
for (size_t i = 0; i < this->ntotal; i++) {
|
|
183
|
-
rev_map
|
|
171
|
+
rev_map[this->id_map[i]] = i;
|
|
184
172
|
}
|
|
185
173
|
}
|
|
186
174
|
|
|
187
|
-
|
|
188
175
|
template <typename IndexT>
|
|
189
|
-
size_t IndexIDMap2Template<IndexT>::remove_ids(const IDSelector& sel)
|
|
190
|
-
{
|
|
176
|
+
size_t IndexIDMap2Template<IndexT>::remove_ids(const IDSelector& sel) {
|
|
191
177
|
// This is quite inefficient
|
|
192
|
-
size_t nremove = IndexIDMapTemplate<IndexT>::remove_ids
|
|
193
|
-
construct_rev_map
|
|
178
|
+
size_t nremove = IndexIDMapTemplate<IndexT>::remove_ids(sel);
|
|
179
|
+
construct_rev_map();
|
|
194
180
|
return nremove;
|
|
195
181
|
}
|
|
196
182
|
|
|
197
183
|
template <typename IndexT>
|
|
198
|
-
void IndexIDMap2Template<IndexT>::reconstruct
|
|
199
|
-
|
|
200
|
-
{
|
|
184
|
+
void IndexIDMap2Template<IndexT>::reconstruct(
|
|
185
|
+
idx_t key,
|
|
186
|
+
typename IndexT::component_t* recons) const {
|
|
201
187
|
try {
|
|
202
|
-
this->index->reconstruct
|
|
188
|
+
this->index->reconstruct(rev_map.at(key), recons);
|
|
203
189
|
} catch (const std::out_of_range& e) {
|
|
204
|
-
FAISS_THROW_FMT
|
|
190
|
+
FAISS_THROW_FMT("key %" PRId64 " not found", key);
|
|
205
191
|
}
|
|
206
192
|
}
|
|
207
193
|
|
|
208
|
-
|
|
209
194
|
// explicit template instantiations
|
|
210
195
|
|
|
211
196
|
template struct IndexIDMapTemplate<Index>;
|
|
@@ -213,81 +198,79 @@ template struct IndexIDMapTemplate<IndexBinary>;
|
|
|
213
198
|
template struct IndexIDMap2Template<Index>;
|
|
214
199
|
template struct IndexIDMap2Template<IndexBinary>;
|
|
215
200
|
|
|
216
|
-
|
|
217
201
|
/*****************************************************
|
|
218
202
|
* IndexSplitVectors implementation
|
|
219
203
|
*******************************************************/
|
|
220
204
|
|
|
205
|
+
IndexSplitVectors::IndexSplitVectors(idx_t d, bool threaded)
|
|
206
|
+
: Index(d), own_fields(false), threaded(threaded), sum_d(0) {}
|
|
221
207
|
|
|
222
|
-
IndexSplitVectors::
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
{
|
|
226
|
-
|
|
208
|
+
void IndexSplitVectors::add_sub_index(Index* index) {
|
|
209
|
+
sub_indexes.push_back(index);
|
|
210
|
+
sync_with_sub_indexes();
|
|
227
211
|
}
|
|
228
212
|
|
|
229
|
-
void IndexSplitVectors::
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
void IndexSplitVectors::sync_with_sub_indexes ()
|
|
236
|
-
{
|
|
237
|
-
if (sub_indexes.empty()) return;
|
|
238
|
-
Index * index0 = sub_indexes[0];
|
|
213
|
+
void IndexSplitVectors::sync_with_sub_indexes() {
|
|
214
|
+
if (sub_indexes.empty())
|
|
215
|
+
return;
|
|
216
|
+
Index* index0 = sub_indexes[0];
|
|
239
217
|
sum_d = index0->d;
|
|
240
218
|
metric_type = index0->metric_type;
|
|
241
219
|
is_trained = index0->is_trained;
|
|
242
220
|
ntotal = index0->ntotal;
|
|
243
221
|
for (int i = 1; i < sub_indexes.size(); i++) {
|
|
244
|
-
Index
|
|
245
|
-
FAISS_THROW_IF_NOT
|
|
246
|
-
FAISS_THROW_IF_NOT
|
|
222
|
+
Index* index = sub_indexes[i];
|
|
223
|
+
FAISS_THROW_IF_NOT(metric_type == index->metric_type);
|
|
224
|
+
FAISS_THROW_IF_NOT(ntotal == index->ntotal);
|
|
247
225
|
sum_d += index->d;
|
|
248
226
|
}
|
|
249
|
-
|
|
250
227
|
}
|
|
251
228
|
|
|
252
229
|
void IndexSplitVectors::add(idx_t /*n*/, const float* /*x*/) {
|
|
253
|
-
|
|
230
|
+
FAISS_THROW_MSG("not implemented");
|
|
254
231
|
}
|
|
255
232
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
{
|
|
262
|
-
FAISS_THROW_IF_NOT_MSG
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
"not enough indexes compared to # dimensions");
|
|
233
|
+
void IndexSplitVectors::search(
|
|
234
|
+
idx_t n,
|
|
235
|
+
const float* x,
|
|
236
|
+
idx_t k,
|
|
237
|
+
float* distances,
|
|
238
|
+
idx_t* labels) const {
|
|
239
|
+
FAISS_THROW_IF_NOT_MSG(k == 1, "search implemented only for k=1");
|
|
240
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
241
|
+
sum_d == d, "not enough indexes compared to # dimensions");
|
|
266
242
|
|
|
267
243
|
int64_t nshard = sub_indexes.size();
|
|
268
|
-
float
|
|
269
|
-
idx_t
|
|
270
|
-
ScopeDeleter<float> del
|
|
271
|
-
ScopeDeleter<idx_t> del2
|
|
272
|
-
|
|
273
|
-
auto query_func = [n,
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
244
|
+
float* all_distances = new float[nshard * k * n];
|
|
245
|
+
idx_t* all_labels = new idx_t[nshard * k * n];
|
|
246
|
+
ScopeDeleter<float> del(all_distances);
|
|
247
|
+
ScopeDeleter<idx_t> del2(all_labels);
|
|
248
|
+
|
|
249
|
+
auto query_func = [n,
|
|
250
|
+
x,
|
|
251
|
+
k,
|
|
252
|
+
distances,
|
|
253
|
+
labels,
|
|
254
|
+
all_distances,
|
|
255
|
+
all_labels,
|
|
256
|
+
this](int no) {
|
|
257
|
+
const IndexSplitVectors* index = this;
|
|
258
|
+
float* distances1 = no == 0 ? distances : all_distances + no * k * n;
|
|
259
|
+
idx_t* labels1 = no == 0 ? labels : all_labels + no * k * n;
|
|
278
260
|
if (index->verbose)
|
|
279
|
-
printf
|
|
280
|
-
const Index
|
|
261
|
+
printf("begin query shard %d on %" PRId64 " points\n", no, n);
|
|
262
|
+
const Index* sub_index = index->sub_indexes[no];
|
|
281
263
|
int64_t sub_d = sub_index->d, d = index->d;
|
|
282
264
|
idx_t ofs = 0;
|
|
283
|
-
for (int i = 0; i < no; i++)
|
|
284
|
-
|
|
285
|
-
|
|
265
|
+
for (int i = 0; i < no; i++)
|
|
266
|
+
ofs += index->sub_indexes[i]->d;
|
|
267
|
+
float* sub_x = new float[sub_d * n];
|
|
268
|
+
ScopeDeleter<float> del1(sub_x);
|
|
286
269
|
for (idx_t i = 0; i < n; i++)
|
|
287
|
-
memcpy
|
|
288
|
-
sub_index->search
|
|
270
|
+
memcpy(sub_x + i * sub_d, x + ofs + i * d, sub_d * sizeof(sub_x));
|
|
271
|
+
sub_index->search(n, sub_x, k, distances1, labels1);
|
|
289
272
|
if (index->verbose)
|
|
290
|
-
printf
|
|
273
|
+
printf("end query shard %d\n", no);
|
|
291
274
|
};
|
|
292
275
|
|
|
293
276
|
if (!threaded) {
|
|
@@ -295,13 +278,13 @@ void IndexSplitVectors::search (
|
|
|
295
278
|
query_func(i);
|
|
296
279
|
}
|
|
297
280
|
} else {
|
|
298
|
-
std::vector<std::unique_ptr<WorkerThread
|
|
281
|
+
std::vector<std::unique_ptr<WorkerThread>> threads;
|
|
299
282
|
std::vector<std::future<bool>> v;
|
|
300
283
|
|
|
301
284
|
for (int i = 0; i < nshard; i++) {
|
|
302
285
|
threads.emplace_back(new WorkerThread());
|
|
303
|
-
WorkerThread
|
|
304
|
-
v.emplace_back(wt->add([i, query_func](){query_func(i); }));
|
|
286
|
+
WorkerThread* wt = threads.back().get();
|
|
287
|
+
v.emplace_back(wt->add([i, query_func]() { query_func(i); }));
|
|
305
288
|
}
|
|
306
289
|
|
|
307
290
|
// Blocking wait for completion
|
|
@@ -313,8 +296,8 @@ void IndexSplitVectors::search (
|
|
|
313
296
|
int64_t factor = 1;
|
|
314
297
|
for (int i = 0; i < nshard; i++) {
|
|
315
298
|
if (i > 0) { // results of 0 are already in the table
|
|
316
|
-
const float
|
|
317
|
-
const idx_t
|
|
299
|
+
const float* distances_i = all_distances + i * k * n;
|
|
300
|
+
const idx_t* labels_i = all_labels + i * k * n;
|
|
318
301
|
for (int64_t j = 0; j < n; j++) {
|
|
319
302
|
if (labels[j] >= 0 && labels_i[j] >= 0) {
|
|
320
303
|
labels[j] += labels_i[j] * factor;
|
|
@@ -327,26 +310,21 @@ void IndexSplitVectors::search (
|
|
|
327
310
|
}
|
|
328
311
|
factor *= sub_indexes[i]->ntotal;
|
|
329
312
|
}
|
|
330
|
-
|
|
331
313
|
}
|
|
332
314
|
|
|
333
315
|
void IndexSplitVectors::train(idx_t /*n*/, const float* /*x*/) {
|
|
334
|
-
|
|
316
|
+
FAISS_THROW_MSG("not implemented");
|
|
335
317
|
}
|
|
336
318
|
|
|
337
|
-
void IndexSplitVectors::reset
|
|
338
|
-
|
|
339
|
-
FAISS_THROW_MSG ("not implemented");
|
|
319
|
+
void IndexSplitVectors::reset() {
|
|
320
|
+
FAISS_THROW_MSG("not implemented");
|
|
340
321
|
}
|
|
341
322
|
|
|
342
|
-
|
|
343
|
-
IndexSplitVectors::~IndexSplitVectors ()
|
|
344
|
-
{
|
|
323
|
+
IndexSplitVectors::~IndexSplitVectors() {
|
|
345
324
|
if (own_fields) {
|
|
346
325
|
for (int s = 0; s < sub_indexes.size(); s++)
|
|
347
|
-
delete sub_indexes
|
|
326
|
+
delete sub_indexes[s];
|
|
348
327
|
}
|
|
349
328
|
}
|
|
350
329
|
|
|
351
|
-
|
|
352
330
|
} // namespace faiss
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
#ifndef META_INDEXES_H
|
|
11
11
|
#define META_INDEXES_H
|
|
12
12
|
|
|
13
|
-
#include <vector>
|
|
14
|
-
#include <unordered_map>
|
|
15
13
|
#include <faiss/Index.h>
|
|
16
|
-
#include <faiss/IndexShards.h>
|
|
17
14
|
#include <faiss/IndexReplicas.h>
|
|
15
|
+
#include <faiss/IndexShards.h>
|
|
16
|
+
#include <unordered_map>
|
|
17
|
+
#include <vector>
|
|
18
18
|
|
|
19
19
|
namespace faiss {
|
|
20
20
|
|
|
@@ -25,22 +25,25 @@ struct IndexIDMapTemplate : IndexT {
|
|
|
25
25
|
using component_t = typename IndexT::component_t;
|
|
26
26
|
using distance_t = typename IndexT::distance_t;
|
|
27
27
|
|
|
28
|
-
IndexT
|
|
29
|
-
bool own_fields;
|
|
28
|
+
IndexT* index; ///! the sub-index
|
|
29
|
+
bool own_fields; ///! whether pointers are deleted in destructo
|
|
30
30
|
std::vector<idx_t> id_map;
|
|
31
31
|
|
|
32
|
-
explicit IndexIDMapTemplate
|
|
32
|
+
explicit IndexIDMapTemplate(IndexT* index);
|
|
33
33
|
|
|
34
34
|
/// @param xids if non-null, ids to store for the vectors (size n)
|
|
35
|
-
void add_with_ids(idx_t n, const component_t* x, const idx_t* xids)
|
|
35
|
+
void add_with_ids(idx_t n, const component_t* x, const idx_t* xids)
|
|
36
|
+
override;
|
|
36
37
|
|
|
37
38
|
/// this will fail. Use add_with_ids
|
|
38
39
|
void add(idx_t n, const component_t* x) override;
|
|
39
40
|
|
|
40
41
|
void search(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
idx_t n,
|
|
43
|
+
const component_t* x,
|
|
44
|
+
idx_t k,
|
|
45
|
+
distance_t* distances,
|
|
46
|
+
idx_t* labels) const override;
|
|
44
47
|
|
|
45
48
|
void train(idx_t n, const component_t* x) override;
|
|
46
49
|
|
|
@@ -49,17 +52,22 @@ struct IndexIDMapTemplate : IndexT {
|
|
|
49
52
|
/// remove ids adapted to IndexFlat
|
|
50
53
|
size_t remove_ids(const IDSelector& sel) override;
|
|
51
54
|
|
|
52
|
-
void range_search
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
void range_search(
|
|
56
|
+
idx_t n,
|
|
57
|
+
const component_t* x,
|
|
58
|
+
distance_t radius,
|
|
59
|
+
RangeSearchResult* result) const override;
|
|
60
|
+
|
|
61
|
+
~IndexIDMapTemplate() override;
|
|
62
|
+
IndexIDMapTemplate() {
|
|
63
|
+
own_fields = false;
|
|
64
|
+
index = nullptr;
|
|
65
|
+
}
|
|
57
66
|
};
|
|
58
67
|
|
|
59
68
|
using IndexIDMap = IndexIDMapTemplate<Index>;
|
|
60
69
|
using IndexBinaryIDMap = IndexIDMapTemplate<IndexBinary>;
|
|
61
70
|
|
|
62
|
-
|
|
63
71
|
/** same as IndexIDMap but also provides an efficient reconstruction
|
|
64
72
|
* implementation via a 2-way index */
|
|
65
73
|
template <typename IndexT>
|
|
@@ -70,47 +78,47 @@ struct IndexIDMap2Template : IndexIDMapTemplate<IndexT> {
|
|
|
70
78
|
|
|
71
79
|
std::unordered_map<idx_t, idx_t> rev_map;
|
|
72
80
|
|
|
73
|
-
explicit IndexIDMap2Template
|
|
81
|
+
explicit IndexIDMap2Template(IndexT* index);
|
|
74
82
|
|
|
75
83
|
/// make the rev_map from scratch
|
|
76
|
-
void construct_rev_map
|
|
84
|
+
void construct_rev_map();
|
|
77
85
|
|
|
78
|
-
void add_with_ids(idx_t n, const component_t* x, const idx_t* xids)
|
|
86
|
+
void add_with_ids(idx_t n, const component_t* x, const idx_t* xids)
|
|
87
|
+
override;
|
|
79
88
|
|
|
80
89
|
size_t remove_ids(const IDSelector& sel) override;
|
|
81
90
|
|
|
82
|
-
void reconstruct
|
|
91
|
+
void reconstruct(idx_t key, component_t* recons) const override;
|
|
83
92
|
|
|
84
93
|
~IndexIDMap2Template() override {}
|
|
85
|
-
IndexIDMap2Template
|
|
94
|
+
IndexIDMap2Template() {}
|
|
86
95
|
};
|
|
87
96
|
|
|
88
97
|
using IndexIDMap2 = IndexIDMap2Template<Index>;
|
|
89
98
|
using IndexBinaryIDMap2 = IndexIDMap2Template<IndexBinary>;
|
|
90
99
|
|
|
91
|
-
|
|
92
100
|
/** splits input vectors in segments and assigns each segment to a sub-index
|
|
93
101
|
* used to distribute a MultiIndexQuantizer
|
|
94
102
|
*/
|
|
95
|
-
struct IndexSplitVectors: Index {
|
|
103
|
+
struct IndexSplitVectors : Index {
|
|
96
104
|
bool own_fields;
|
|
97
105
|
bool threaded;
|
|
98
106
|
std::vector<Index*> sub_indexes;
|
|
99
|
-
idx_t sum_d;
|
|
107
|
+
idx_t sum_d; /// sum of dimensions seen so far
|
|
100
108
|
|
|
101
|
-
explicit IndexSplitVectors
|
|
109
|
+
explicit IndexSplitVectors(idx_t d, bool threaded = false);
|
|
102
110
|
|
|
103
|
-
void add_sub_index
|
|
104
|
-
void sync_with_sub_indexes
|
|
111
|
+
void add_sub_index(Index*);
|
|
112
|
+
void sync_with_sub_indexes();
|
|
105
113
|
|
|
106
114
|
void add(idx_t n, const float* x) override;
|
|
107
115
|
|
|
108
116
|
void search(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
117
|
+
idx_t n,
|
|
118
|
+
const float* x,
|
|
119
|
+
idx_t k,
|
|
120
|
+
float* distances,
|
|
121
|
+
idx_t* labels) const override;
|
|
114
122
|
|
|
115
123
|
void train(idx_t n, const float* x) override;
|
|
116
124
|
|
|
@@ -119,8 +127,6 @@ struct IndexSplitVectors: Index {
|
|
|
119
127
|
~IndexSplitVectors() override;
|
|
120
128
|
};
|
|
121
129
|
|
|
122
|
-
|
|
123
130
|
} // namespace faiss
|
|
124
131
|
|
|
125
|
-
|
|
126
132
|
#endif
|
|
@@ -18,12 +18,12 @@ namespace faiss {
|
|
|
18
18
|
/// (brute-force) indices supporting additional metric types for vector
|
|
19
19
|
/// comparison.
|
|
20
20
|
enum MetricType {
|
|
21
|
-
METRIC_INNER_PRODUCT = 0,
|
|
22
|
-
METRIC_L2 = 1,
|
|
23
|
-
METRIC_L1,
|
|
24
|
-
METRIC_Linf,
|
|
25
|
-
METRIC_Lp,
|
|
26
|
-
|
|
21
|
+
METRIC_INNER_PRODUCT = 0, ///< maximum inner product search
|
|
22
|
+
METRIC_L2 = 1, ///< squared L2 search
|
|
23
|
+
METRIC_L1, ///< L1 (aka cityblock)
|
|
24
|
+
METRIC_Linf, ///< infinity distance
|
|
25
|
+
METRIC_Lp, ///< L_p distance, p is given by a faiss::Index
|
|
26
|
+
/// metric_arg
|
|
27
27
|
|
|
28
28
|
/// some additional metrics defined in scipy.spatial.distance
|
|
29
29
|
METRIC_Canberra = 20,
|
|
@@ -31,6 +31,6 @@ enum MetricType {
|
|
|
31
31
|
METRIC_JensenShannon,
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
}
|
|
34
|
+
} // namespace faiss
|
|
35
35
|
|
|
36
36
|
#endif
|