faiss 0.1.7 → 0.2.3
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 +18 -0
- data/README.md +7 -7
- data/ext/faiss/ext.cpp +1 -1
- data/ext/faiss/extconf.rb +8 -2
- data/ext/faiss/index.cpp +102 -69
- data/ext/faiss/index_binary.cpp +24 -30
- data/ext/faiss/kmeans.cpp +20 -16
- data/ext/faiss/numo.hpp +867 -0
- data/ext/faiss/pca_matrix.cpp +13 -14
- data/ext/faiss/product_quantizer.cpp +23 -24
- data/ext/faiss/utils.cpp +10 -37
- data/ext/faiss/utils.h +2 -13
- data/lib/faiss/version.rb +1 -1
- data/lib/faiss.rb +0 -5
- data/vendor/faiss/faiss/AutoTune.cpp +292 -291
- data/vendor/faiss/faiss/AutoTune.h +55 -56
- data/vendor/faiss/faiss/Clustering.cpp +334 -195
- data/vendor/faiss/faiss/Clustering.h +88 -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 +139 -164
- data/vendor/faiss/faiss/Index2Layer.h +22 -22
- 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 +116 -147
- data/vendor/faiss/faiss/IndexFlat.h +35 -46
- data/vendor/faiss/faiss/IndexHNSW.cpp +372 -348
- data/vendor/faiss/faiss/IndexHNSW.h +57 -41
- data/vendor/faiss/faiss/IndexIVF.cpp +474 -454
- data/vendor/faiss/faiss/IndexIVF.h +146 -113
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +248 -250
- data/vendor/faiss/faiss/IndexIVFFlat.h +48 -51
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +457 -516
- data/vendor/faiss/faiss/IndexIVFPQ.h +74 -66
- 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 +125 -133
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +19 -21
- data/vendor/faiss/faiss/IndexLSH.cpp +75 -96
- data/vendor/faiss/faiss/IndexLSH.h +21 -26
- data/vendor/faiss/faiss/IndexLattice.cpp +42 -56
- data/vendor/faiss/faiss/IndexLattice.h +11 -16
- data/vendor/faiss/faiss/IndexNNDescent.cpp +231 -0
- data/vendor/faiss/faiss/IndexNNDescent.h +72 -0
- data/vendor/faiss/faiss/IndexNSG.cpp +303 -0
- data/vendor/faiss/faiss/IndexNSG.h +85 -0
- data/vendor/faiss/faiss/IndexPQ.cpp +405 -464
- data/vendor/faiss/faiss/IndexPQ.h +64 -67
- 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 +115 -131
- data/vendor/faiss/faiss/IndexRefine.h +22 -23
- data/vendor/faiss/faiss/IndexReplicas.cpp +147 -153
- data/vendor/faiss/faiss/IndexReplicas.h +62 -56
- data/vendor/faiss/faiss/IndexResidual.cpp +291 -0
- data/vendor/faiss/faiss/IndexResidual.h +152 -0
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +120 -155
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +41 -45
- 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 +652 -474
- data/vendor/faiss/faiss/VectorTransform.h +61 -89
- data/vendor/faiss/faiss/clone_index.cpp +77 -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 +197 -170
- 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/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 +270 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +115 -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 +595 -611
- data/vendor/faiss/faiss/impl/HNSW.h +179 -200
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +672 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +172 -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 +682 -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 +448 -0
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +130 -0
- data/vendor/faiss/faiss/impl/ResultHandler.h +96 -132
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +648 -701
- 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 +547 -479
- data/vendor/faiss/faiss/impl/index_write.cpp +497 -407
- data/vendor/faiss/faiss/impl/io.cpp +75 -94
- data/vendor/faiss/faiss/impl/io.h +31 -41
- data/vendor/faiss/faiss/impl/io_macros.h +40 -29
- 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 +269 -218
- data/vendor/faiss/faiss/index_factory.h +6 -7
- 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 +301 -310
- data/vendor/faiss/faiss/utils/distances.h +133 -118
- data/vendor/faiss/faiss/utils/distances_simd.cpp +456 -516
- 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 +53 -48
- metadata +26 -12
- data/lib/faiss/index.rb +0 -20
- data/lib/faiss/index_binary.rb +0 -20
- data/lib/faiss/kmeans.rb +0 -15
- data/lib/faiss/pca_matrix.rb +0 -15
- data/lib/faiss/product_quantizer.rb +0 -22
|
@@ -9,231 +9,207 @@
|
|
|
9
9
|
|
|
10
10
|
#include <faiss/IndexScalarQuantizer.h>
|
|
11
11
|
|
|
12
|
-
#include <cstdio>
|
|
13
12
|
#include <algorithm>
|
|
13
|
+
#include <cstdio>
|
|
14
14
|
|
|
15
15
|
#include <omp.h>
|
|
16
16
|
|
|
17
|
-
#include <faiss/utils/utils.h>
|
|
18
|
-
#include <faiss/impl/FaissAssert.h>
|
|
19
17
|
#include <faiss/impl/AuxIndexStructures.h>
|
|
18
|
+
#include <faiss/impl/FaissAssert.h>
|
|
20
19
|
#include <faiss/impl/ScalarQuantizer.h>
|
|
20
|
+
#include <faiss/utils/utils.h>
|
|
21
21
|
|
|
22
22
|
namespace faiss {
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
24
|
/*******************************************************************
|
|
27
25
|
* IndexScalarQuantizer implementation
|
|
28
26
|
********************************************************************/
|
|
29
27
|
|
|
30
|
-
IndexScalarQuantizer::IndexScalarQuantizer
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
qtype == ScalarQuantizer::QT_fp16 ||
|
|
38
|
-
qtype == ScalarQuantizer::QT_8bit_direct;
|
|
28
|
+
IndexScalarQuantizer::IndexScalarQuantizer(
|
|
29
|
+
int d,
|
|
30
|
+
ScalarQuantizer::QuantizerType qtype,
|
|
31
|
+
MetricType metric)
|
|
32
|
+
: Index(d, metric), sq(d, qtype) {
|
|
33
|
+
is_trained = qtype == ScalarQuantizer::QT_fp16 ||
|
|
34
|
+
qtype == ScalarQuantizer::QT_8bit_direct;
|
|
39
35
|
code_size = sq.code_size;
|
|
40
36
|
}
|
|
41
37
|
|
|
38
|
+
IndexScalarQuantizer::IndexScalarQuantizer()
|
|
39
|
+
: IndexScalarQuantizer(0, ScalarQuantizer::QT_8bit) {}
|
|
42
40
|
|
|
43
|
-
IndexScalarQuantizer::
|
|
44
|
-
IndexScalarQuantizer(0, ScalarQuantizer::QT_8bit)
|
|
45
|
-
{}
|
|
46
|
-
|
|
47
|
-
void IndexScalarQuantizer::train(idx_t n, const float* x)
|
|
48
|
-
{
|
|
41
|
+
void IndexScalarQuantizer::train(idx_t n, const float* x) {
|
|
49
42
|
sq.train(n, x);
|
|
50
43
|
is_trained = true;
|
|
51
44
|
}
|
|
52
45
|
|
|
53
|
-
void IndexScalarQuantizer::add(idx_t n, const float* x)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
sq.compute_codes (x, &codes[ntotal * code_size], n);
|
|
46
|
+
void IndexScalarQuantizer::add(idx_t n, const float* x) {
|
|
47
|
+
FAISS_THROW_IF_NOT(is_trained);
|
|
48
|
+
codes.resize((n + ntotal) * code_size);
|
|
49
|
+
sq.compute_codes(x, &codes[ntotal * code_size], n);
|
|
58
50
|
ntotal += n;
|
|
59
51
|
}
|
|
60
52
|
|
|
61
|
-
|
|
62
53
|
void IndexScalarQuantizer::search(
|
|
63
54
|
idx_t n,
|
|
64
55
|
const float* x,
|
|
65
56
|
idx_t k,
|
|
66
57
|
float* distances,
|
|
67
|
-
idx_t* labels) const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
FAISS_THROW_IF_NOT
|
|
71
|
-
|
|
58
|
+
idx_t* labels) const {
|
|
59
|
+
FAISS_THROW_IF_NOT(k > 0);
|
|
60
|
+
|
|
61
|
+
FAISS_THROW_IF_NOT(is_trained);
|
|
62
|
+
FAISS_THROW_IF_NOT(
|
|
63
|
+
metric_type == METRIC_L2 || metric_type == METRIC_INNER_PRODUCT);
|
|
72
64
|
|
|
73
65
|
#pragma omp parallel
|
|
74
66
|
{
|
|
75
|
-
InvertedListScanner* scanner =
|
|
76
|
-
|
|
67
|
+
InvertedListScanner* scanner =
|
|
68
|
+
sq.select_InvertedListScanner(metric_type, nullptr, true);
|
|
77
69
|
ScopeDeleter1<InvertedListScanner> del(scanner);
|
|
78
70
|
|
|
79
71
|
#pragma omp for
|
|
80
72
|
for (idx_t i = 0; i < n; i++) {
|
|
81
|
-
float
|
|
82
|
-
idx_t
|
|
73
|
+
float* D = distances + k * i;
|
|
74
|
+
idx_t* I = labels + k * i;
|
|
83
75
|
// re-order heap
|
|
84
76
|
if (metric_type == METRIC_L2) {
|
|
85
|
-
maxheap_heapify
|
|
77
|
+
maxheap_heapify(k, D, I);
|
|
86
78
|
} else {
|
|
87
|
-
minheap_heapify
|
|
79
|
+
minheap_heapify(k, D, I);
|
|
88
80
|
}
|
|
89
|
-
scanner->set_query
|
|
90
|
-
scanner->scan_codes
|
|
91
|
-
nullptr, D, I, k);
|
|
81
|
+
scanner->set_query(x + i * d);
|
|
82
|
+
scanner->scan_codes(ntotal, codes.data(), nullptr, D, I, k);
|
|
92
83
|
|
|
93
84
|
// re-order heap
|
|
94
85
|
if (metric_type == METRIC_L2) {
|
|
95
|
-
maxheap_reorder
|
|
86
|
+
maxheap_reorder(k, D, I);
|
|
96
87
|
} else {
|
|
97
|
-
minheap_reorder
|
|
88
|
+
minheap_reorder(k, D, I);
|
|
98
89
|
}
|
|
99
90
|
}
|
|
100
91
|
}
|
|
101
|
-
|
|
102
92
|
}
|
|
103
93
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
ScalarQuantizer::SQDistanceComputer *dc =
|
|
108
|
-
sq.get_distance_computer (metric_type);
|
|
94
|
+
DistanceComputer* IndexScalarQuantizer::get_distance_computer() const {
|
|
95
|
+
ScalarQuantizer::SQDistanceComputer* dc =
|
|
96
|
+
sq.get_distance_computer(metric_type);
|
|
109
97
|
dc->code_size = sq.code_size;
|
|
110
98
|
dc->codes = codes.data();
|
|
111
99
|
return dc;
|
|
112
100
|
}
|
|
113
101
|
|
|
114
|
-
|
|
115
|
-
void IndexScalarQuantizer::reset()
|
|
116
|
-
{
|
|
102
|
+
void IndexScalarQuantizer::reset() {
|
|
117
103
|
codes.clear();
|
|
118
104
|
ntotal = 0;
|
|
119
105
|
}
|
|
120
106
|
|
|
121
|
-
void IndexScalarQuantizer::reconstruct_n(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
std::unique_ptr<ScalarQuantizer::Quantizer> squant(sq.select_quantizer ());
|
|
107
|
+
void IndexScalarQuantizer::reconstruct_n(idx_t i0, idx_t ni, float* recons)
|
|
108
|
+
const {
|
|
109
|
+
std::unique_ptr<ScalarQuantizer::Quantizer> squant(sq.select_quantizer());
|
|
125
110
|
for (size_t i = 0; i < ni; i++) {
|
|
126
111
|
squant->decode_vector(&codes[(i + i0) * code_size], recons + i * d);
|
|
127
112
|
}
|
|
128
113
|
}
|
|
129
114
|
|
|
130
|
-
void IndexScalarQuantizer::reconstruct(idx_t key, float* recons) const
|
|
131
|
-
{
|
|
115
|
+
void IndexScalarQuantizer::reconstruct(idx_t key, float* recons) const {
|
|
132
116
|
reconstruct_n(key, 1, recons);
|
|
133
117
|
}
|
|
134
118
|
|
|
135
119
|
/* Codec interface */
|
|
136
|
-
size_t IndexScalarQuantizer::sa_code_size
|
|
137
|
-
{
|
|
120
|
+
size_t IndexScalarQuantizer::sa_code_size() const {
|
|
138
121
|
return sq.code_size;
|
|
139
122
|
}
|
|
140
123
|
|
|
141
|
-
void IndexScalarQuantizer::sa_encode
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
sq.compute_codes (x, bytes, n);
|
|
124
|
+
void IndexScalarQuantizer::sa_encode(idx_t n, const float* x, uint8_t* bytes)
|
|
125
|
+
const {
|
|
126
|
+
FAISS_THROW_IF_NOT(is_trained);
|
|
127
|
+
sq.compute_codes(x, bytes, n);
|
|
146
128
|
}
|
|
147
129
|
|
|
148
|
-
void IndexScalarQuantizer::sa_decode
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
FAISS_THROW_IF_NOT (is_trained);
|
|
130
|
+
void IndexScalarQuantizer::sa_decode(idx_t n, const uint8_t* bytes, float* x)
|
|
131
|
+
const {
|
|
132
|
+
FAISS_THROW_IF_NOT(is_trained);
|
|
152
133
|
sq.decode(bytes, x, n);
|
|
153
134
|
}
|
|
154
135
|
|
|
155
|
-
|
|
156
|
-
|
|
157
136
|
/*******************************************************************
|
|
158
137
|
* IndexIVFScalarQuantizer implementation
|
|
159
138
|
********************************************************************/
|
|
160
139
|
|
|
161
|
-
IndexIVFScalarQuantizer::IndexIVFScalarQuantizer
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
140
|
+
IndexIVFScalarQuantizer::IndexIVFScalarQuantizer(
|
|
141
|
+
Index* quantizer,
|
|
142
|
+
size_t d,
|
|
143
|
+
size_t nlist,
|
|
144
|
+
ScalarQuantizer::QuantizerType qtype,
|
|
145
|
+
MetricType metric,
|
|
146
|
+
bool encode_residual)
|
|
147
|
+
: IndexIVF(quantizer, d, nlist, 0, metric),
|
|
148
|
+
sq(d, qtype),
|
|
149
|
+
by_residual(encode_residual) {
|
|
169
150
|
code_size = sq.code_size;
|
|
170
151
|
// was not known at construction time
|
|
171
152
|
invlists->code_size = code_size;
|
|
172
153
|
is_trained = false;
|
|
173
154
|
}
|
|
174
155
|
|
|
175
|
-
IndexIVFScalarQuantizer::IndexIVFScalarQuantizer
|
|
176
|
-
|
|
177
|
-
by_residual(true)
|
|
178
|
-
{
|
|
179
|
-
}
|
|
156
|
+
IndexIVFScalarQuantizer::IndexIVFScalarQuantizer()
|
|
157
|
+
: IndexIVF(), by_residual(true) {}
|
|
180
158
|
|
|
181
|
-
void IndexIVFScalarQuantizer::train_residual
|
|
182
|
-
{
|
|
159
|
+
void IndexIVFScalarQuantizer::train_residual(idx_t n, const float* x) {
|
|
183
160
|
sq.train_residual(n, x, quantizer, by_residual, verbose);
|
|
184
161
|
}
|
|
185
162
|
|
|
186
|
-
void IndexIVFScalarQuantizer::encode_vectors(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
163
|
+
void IndexIVFScalarQuantizer::encode_vectors(
|
|
164
|
+
idx_t n,
|
|
165
|
+
const float* x,
|
|
166
|
+
const idx_t* list_nos,
|
|
167
|
+
uint8_t* codes,
|
|
168
|
+
bool include_listnos) const {
|
|
169
|
+
std::unique_ptr<ScalarQuantizer::Quantizer> squant(sq.select_quantizer());
|
|
170
|
+
size_t coarse_size = include_listnos ? coarse_code_size() : 0;
|
|
193
171
|
memset(codes, 0, (code_size + coarse_size) * n);
|
|
194
172
|
|
|
195
|
-
#pragma omp parallel if(n > 1000)
|
|
173
|
+
#pragma omp parallel if (n > 1000)
|
|
196
174
|
{
|
|
197
|
-
std::vector<float> residual
|
|
175
|
+
std::vector<float> residual(d);
|
|
198
176
|
|
|
199
177
|
#pragma omp for
|
|
200
178
|
for (idx_t i = 0; i < n; i++) {
|
|
201
|
-
int64_t list_no = list_nos
|
|
179
|
+
int64_t list_no = list_nos[i];
|
|
202
180
|
if (list_no >= 0) {
|
|
203
|
-
const float
|
|
204
|
-
uint8_t
|
|
181
|
+
const float* xi = x + i * d;
|
|
182
|
+
uint8_t* code = codes + i * (code_size + coarse_size);
|
|
205
183
|
if (by_residual) {
|
|
206
|
-
quantizer->compute_residual (
|
|
207
|
-
|
|
208
|
-
xi = residual.data ();
|
|
184
|
+
quantizer->compute_residual(xi, residual.data(), list_no);
|
|
185
|
+
xi = residual.data();
|
|
209
186
|
}
|
|
210
187
|
if (coarse_size) {
|
|
211
|
-
encode_listno
|
|
188
|
+
encode_listno(list_no, code);
|
|
212
189
|
}
|
|
213
|
-
squant->encode_vector
|
|
190
|
+
squant->encode_vector(xi, code + coarse_size);
|
|
214
191
|
}
|
|
215
192
|
}
|
|
216
193
|
}
|
|
217
194
|
}
|
|
218
195
|
|
|
219
|
-
void IndexIVFScalarQuantizer::sa_decode
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
size_t coarse_size = coarse_code_size ();
|
|
196
|
+
void IndexIVFScalarQuantizer::sa_decode(idx_t n, const uint8_t* codes, float* x)
|
|
197
|
+
const {
|
|
198
|
+
std::unique_ptr<ScalarQuantizer::Quantizer> squant(sq.select_quantizer());
|
|
199
|
+
size_t coarse_size = coarse_code_size();
|
|
224
200
|
|
|
225
|
-
#pragma omp parallel if(n > 1000)
|
|
201
|
+
#pragma omp parallel if (n > 1000)
|
|
226
202
|
{
|
|
227
|
-
std::vector<float> residual
|
|
203
|
+
std::vector<float> residual(d);
|
|
228
204
|
|
|
229
205
|
#pragma omp for
|
|
230
206
|
for (idx_t i = 0; i < n; i++) {
|
|
231
|
-
const uint8_t
|
|
232
|
-
int64_t list_no = decode_listno
|
|
233
|
-
float
|
|
234
|
-
squant->decode_vector
|
|
207
|
+
const uint8_t* code = codes + i * (code_size + coarse_size);
|
|
208
|
+
int64_t list_no = decode_listno(code);
|
|
209
|
+
float* xi = x + i * d;
|
|
210
|
+
squant->decode_vector(code + coarse_size, xi);
|
|
235
211
|
if (by_residual) {
|
|
236
|
-
quantizer->reconstruct
|
|
212
|
+
quantizer->reconstruct(list_no, residual.data());
|
|
237
213
|
for (size_t j = 0; j < d; j++) {
|
|
238
214
|
xi[j] += residual[j];
|
|
239
215
|
}
|
|
@@ -242,83 +218,72 @@ void IndexIVFScalarQuantizer::sa_decode (idx_t n, const uint8_t *codes,
|
|
|
242
218
|
}
|
|
243
219
|
}
|
|
244
220
|
|
|
221
|
+
void IndexIVFScalarQuantizer::add_core(
|
|
222
|
+
idx_t n,
|
|
223
|
+
const float* x,
|
|
224
|
+
const idx_t* xids,
|
|
225
|
+
const idx_t* coarse_idx) {
|
|
226
|
+
FAISS_THROW_IF_NOT(is_trained);
|
|
245
227
|
|
|
246
|
-
|
|
247
|
-
void IndexIVFScalarQuantizer::add_with_ids
|
|
248
|
-
(idx_t n, const float * x, const idx_t *xids)
|
|
249
|
-
{
|
|
250
|
-
FAISS_THROW_IF_NOT (is_trained);
|
|
251
|
-
std::unique_ptr<int64_t []> idx (new int64_t [n]);
|
|
252
|
-
quantizer->assign (n, x, idx.get());
|
|
253
228
|
size_t nadd = 0;
|
|
254
|
-
std::unique_ptr<ScalarQuantizer::Quantizer> squant(sq.select_quantizer
|
|
229
|
+
std::unique_ptr<ScalarQuantizer::Quantizer> squant(sq.select_quantizer());
|
|
255
230
|
|
|
256
|
-
DirectMapAdd dm_add
|
|
231
|
+
DirectMapAdd dm_add(direct_map, n, xids);
|
|
257
232
|
|
|
258
|
-
#pragma omp parallel reduction(
|
|
233
|
+
#pragma omp parallel reduction(+ : nadd)
|
|
259
234
|
{
|
|
260
|
-
std::vector<float> residual
|
|
261
|
-
std::vector<uint8_t> one_code
|
|
235
|
+
std::vector<float> residual(d);
|
|
236
|
+
std::vector<uint8_t> one_code(code_size);
|
|
262
237
|
int nt = omp_get_num_threads();
|
|
263
238
|
int rank = omp_get_thread_num();
|
|
264
239
|
|
|
265
240
|
// each thread takes care of a subset of lists
|
|
266
241
|
for (size_t i = 0; i < n; i++) {
|
|
267
|
-
int64_t list_no =
|
|
242
|
+
int64_t list_no = coarse_idx[i];
|
|
268
243
|
if (list_no >= 0 && list_no % nt == rank) {
|
|
269
244
|
int64_t id = xids ? xids[i] : ntotal + i;
|
|
270
245
|
|
|
271
|
-
const float
|
|
246
|
+
const float* xi = x + i * d;
|
|
272
247
|
if (by_residual) {
|
|
273
|
-
quantizer->compute_residual
|
|
248
|
+
quantizer->compute_residual(xi, residual.data(), list_no);
|
|
274
249
|
xi = residual.data();
|
|
275
250
|
}
|
|
276
251
|
|
|
277
|
-
memset
|
|
278
|
-
squant->encode_vector
|
|
252
|
+
memset(one_code.data(), 0, code_size);
|
|
253
|
+
squant->encode_vector(xi, one_code.data());
|
|
279
254
|
|
|
280
|
-
size_t ofs = invlists->add_entry
|
|
255
|
+
size_t ofs = invlists->add_entry(list_no, id, one_code.data());
|
|
281
256
|
|
|
282
|
-
dm_add.add
|
|
257
|
+
dm_add.add(i, list_no, ofs);
|
|
283
258
|
nadd++;
|
|
284
259
|
|
|
285
260
|
} else if (rank == 0 && list_no == -1) {
|
|
286
|
-
dm_add.add
|
|
261
|
+
dm_add.add(i, -1, 0);
|
|
287
262
|
}
|
|
288
263
|
}
|
|
289
264
|
}
|
|
290
265
|
|
|
291
|
-
|
|
292
266
|
ntotal += n;
|
|
293
267
|
}
|
|
294
268
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
InvertedListScanner* IndexIVFScalarQuantizer::get_InvertedListScanner
|
|
300
|
-
(bool store_pairs) const
|
|
301
|
-
{
|
|
302
|
-
return sq.select_InvertedListScanner (metric_type, quantizer, store_pairs,
|
|
303
|
-
by_residual);
|
|
269
|
+
InvertedListScanner* IndexIVFScalarQuantizer::get_InvertedListScanner(
|
|
270
|
+
bool store_pairs) const {
|
|
271
|
+
return sq.select_InvertedListScanner(
|
|
272
|
+
metric_type, quantizer, store_pairs, by_residual);
|
|
304
273
|
}
|
|
305
274
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
{
|
|
275
|
+
void IndexIVFScalarQuantizer::reconstruct_from_offset(
|
|
276
|
+
int64_t list_no,
|
|
277
|
+
int64_t offset,
|
|
278
|
+
float* recons) const {
|
|
311
279
|
std::vector<float> centroid(d);
|
|
312
|
-
quantizer->reconstruct
|
|
280
|
+
quantizer->reconstruct(list_no, centroid.data());
|
|
313
281
|
|
|
314
|
-
const uint8_t* code = invlists->get_single_code
|
|
315
|
-
sq.decode
|
|
282
|
+
const uint8_t* code = invlists->get_single_code(list_no, offset);
|
|
283
|
+
sq.decode(code, recons, 1);
|
|
316
284
|
for (int i = 0; i < d; ++i) {
|
|
317
285
|
recons[i] += centroid[i];
|
|
318
286
|
}
|
|
319
287
|
}
|
|
320
288
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
289
|
} // namespace faiss
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
#include <faiss/IndexIVF.h>
|
|
17
17
|
#include <faiss/impl/ScalarQuantizer.h>
|
|
18
18
|
|
|
19
|
-
|
|
20
19
|
namespace faiss {
|
|
21
20
|
|
|
22
21
|
/**
|
|
@@ -25,10 +24,7 @@ namespace faiss {
|
|
|
25
24
|
* (default).
|
|
26
25
|
*/
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
struct IndexScalarQuantizer: Index {
|
|
27
|
+
struct IndexScalarQuantizer : Index {
|
|
32
28
|
/// Used to encode the vectors
|
|
33
29
|
ScalarQuantizer sq;
|
|
34
30
|
|
|
@@ -43,22 +39,23 @@ struct IndexScalarQuantizer: Index {
|
|
|
43
39
|
* @param M number of subquantizers
|
|
44
40
|
* @param nbits number of bit per subvector index
|
|
45
41
|
*/
|
|
46
|
-
IndexScalarQuantizer
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
IndexScalarQuantizer(
|
|
43
|
+
int d,
|
|
44
|
+
ScalarQuantizer::QuantizerType qtype,
|
|
45
|
+
MetricType metric = METRIC_L2);
|
|
49
46
|
|
|
50
|
-
IndexScalarQuantizer
|
|
47
|
+
IndexScalarQuantizer();
|
|
51
48
|
|
|
52
49
|
void train(idx_t n, const float* x) override;
|
|
53
50
|
|
|
54
51
|
void add(idx_t n, const float* x) override;
|
|
55
52
|
|
|
56
53
|
void search(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
idx_t n,
|
|
55
|
+
const float* x,
|
|
56
|
+
idx_t k,
|
|
57
|
+
float* distances,
|
|
58
|
+
idx_t* labels) const override;
|
|
62
59
|
|
|
63
60
|
void reset() override;
|
|
64
61
|
|
|
@@ -66,62 +63,61 @@ struct IndexScalarQuantizer: Index {
|
|
|
66
63
|
|
|
67
64
|
void reconstruct(idx_t key, float* recons) const override;
|
|
68
65
|
|
|
69
|
-
DistanceComputer
|
|
66
|
+
DistanceComputer* get_distance_computer() const override;
|
|
70
67
|
|
|
71
68
|
/* standalone codec interface */
|
|
72
|
-
size_t sa_code_size
|
|
73
|
-
|
|
74
|
-
void sa_encode (idx_t n, const float *x,
|
|
75
|
-
uint8_t *bytes) const override;
|
|
76
|
-
|
|
77
|
-
void sa_decode (idx_t n, const uint8_t *bytes,
|
|
78
|
-
float *x) const override;
|
|
69
|
+
size_t sa_code_size() const override;
|
|
79
70
|
|
|
71
|
+
void sa_encode(idx_t n, const float* x, uint8_t* bytes) const override;
|
|
80
72
|
|
|
73
|
+
void sa_decode(idx_t n, const uint8_t* bytes, float* x) const override;
|
|
81
74
|
};
|
|
82
75
|
|
|
83
|
-
|
|
84
|
-
/** An IVF implementation where the components of the residuals are
|
|
76
|
+
/** An IVF implementation where the components of the residuals are
|
|
85
77
|
* encoded with a scalar quantizer. All distance computations
|
|
86
78
|
* are asymmetric, so the encoded vectors are decoded and approximate
|
|
87
79
|
* distances are computed.
|
|
88
80
|
*/
|
|
89
81
|
|
|
90
|
-
struct IndexIVFScalarQuantizer: IndexIVF {
|
|
82
|
+
struct IndexIVFScalarQuantizer : IndexIVF {
|
|
91
83
|
ScalarQuantizer sq;
|
|
92
84
|
bool by_residual;
|
|
93
85
|
|
|
94
|
-
IndexIVFScalarQuantizer(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
86
|
+
IndexIVFScalarQuantizer(
|
|
87
|
+
Index* quantizer,
|
|
88
|
+
size_t d,
|
|
89
|
+
size_t nlist,
|
|
90
|
+
ScalarQuantizer::QuantizerType qtype,
|
|
91
|
+
MetricType metric = METRIC_L2,
|
|
92
|
+
bool encode_residual = true);
|
|
98
93
|
|
|
99
94
|
IndexIVFScalarQuantizer();
|
|
100
95
|
|
|
101
96
|
void train_residual(idx_t n, const float* x) override;
|
|
102
97
|
|
|
103
|
-
void encode_vectors(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
98
|
+
void encode_vectors(
|
|
99
|
+
idx_t n,
|
|
100
|
+
const float* x,
|
|
101
|
+
const idx_t* list_nos,
|
|
102
|
+
uint8_t* codes,
|
|
103
|
+
bool include_listnos = false) const override;
|
|
109
104
|
|
|
110
|
-
|
|
111
|
-
|
|
105
|
+
void add_core(
|
|
106
|
+
idx_t n,
|
|
107
|
+
const float* x,
|
|
108
|
+
const idx_t* xids,
|
|
109
|
+
const idx_t* precomputed_idx) override;
|
|
112
110
|
|
|
111
|
+
InvertedListScanner* get_InvertedListScanner(
|
|
112
|
+
bool store_pairs) const override;
|
|
113
113
|
|
|
114
|
-
void reconstruct_from_offset
|
|
115
|
-
|
|
114
|
+
void reconstruct_from_offset(int64_t list_no, int64_t offset, float* recons)
|
|
115
|
+
const override;
|
|
116
116
|
|
|
117
117
|
/* standalone codec interface */
|
|
118
|
-
void sa_decode
|
|
119
|
-
float *x) const override;
|
|
120
|
-
|
|
118
|
+
void sa_decode(idx_t n, const uint8_t* bytes, float* x) const override;
|
|
121
119
|
};
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
121
|
+
} // namespace faiss
|
|
126
122
|
|
|
127
123
|
#endif
|