faiss 0.1.5 → 0.2.2
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 +24 -0
- data/README.md +12 -0
- data/ext/faiss/ext.cpp +1 -1
- data/ext/faiss/extconf.rb +6 -2
- data/ext/faiss/index.cpp +114 -43
- 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.rb +0 -5
- 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 +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 +24 -10
- 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,11 +9,12 @@
|
|
9
9
|
|
10
10
|
#include <faiss/Index2Layer.h>
|
11
11
|
|
12
|
+
#include <faiss/impl/platform_macros.h>
|
13
|
+
#include <stdint.h>
|
14
|
+
#include <cassert>
|
12
15
|
#include <cinttypes>
|
13
16
|
#include <cmath>
|
14
17
|
#include <cstdio>
|
15
|
-
#include <cassert>
|
16
|
-
#include <stdint.h>
|
17
18
|
|
18
19
|
#ifdef __SSE3__
|
19
20
|
#include <immintrin.h>
|
@@ -23,12 +24,11 @@
|
|
23
24
|
|
24
25
|
#include <faiss/IndexIVFPQ.h>
|
25
26
|
|
26
|
-
#include <faiss/impl/FaissAssert.h>
|
27
|
-
#include <faiss/utils/utils.h>
|
28
|
-
#include <faiss/impl/AuxIndexStructures.h>
|
29
27
|
#include <faiss/IndexFlat.h>
|
28
|
+
#include <faiss/impl/AuxIndexStructures.h>
|
29
|
+
#include <faiss/impl/FaissAssert.h>
|
30
30
|
#include <faiss/utils/distances.h>
|
31
|
-
|
31
|
+
#include <faiss/utils/utils.h>
|
32
32
|
|
33
33
|
/*
|
34
34
|
#include <faiss/utils/Heap.h>
|
@@ -40,22 +40,21 @@
|
|
40
40
|
|
41
41
|
*/
|
42
42
|
|
43
|
-
|
44
43
|
namespace faiss {
|
45
44
|
|
46
|
-
|
47
45
|
/*************************************
|
48
46
|
* Index2Layer implementation
|
49
47
|
*************************************/
|
50
48
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
49
|
+
Index2Layer::Index2Layer(
|
50
|
+
Index* quantizer,
|
51
|
+
size_t nlist,
|
52
|
+
int M,
|
53
|
+
int nbit,
|
54
|
+
MetricType metric)
|
55
|
+
: Index(quantizer->d, metric),
|
56
|
+
q1(quantizer, nlist),
|
57
|
+
pq(quantizer->d, M, nbit) {
|
59
58
|
is_trained = false;
|
60
59
|
for (int nbyte = 0; nbyte < 7; nbyte++) {
|
61
60
|
if ((1L << (8 * nbyte)) >= nlist) {
|
@@ -67,122 +66,125 @@ Index2Layer::Index2Layer (Index * quantizer, size_t nlist,
|
|
67
66
|
code_size = code_size_1 + code_size_2;
|
68
67
|
}
|
69
68
|
|
70
|
-
Index2Layer::Index2Layer
|
71
|
-
{
|
69
|
+
Index2Layer::Index2Layer() {
|
72
70
|
code_size = code_size_1 = code_size_2 = 0;
|
73
71
|
}
|
74
72
|
|
75
|
-
Index2Layer::~Index2Layer
|
76
|
-
{}
|
73
|
+
Index2Layer::~Index2Layer() {}
|
77
74
|
|
78
|
-
void Index2Layer::train(idx_t n, const float* x)
|
79
|
-
{
|
75
|
+
void Index2Layer::train(idx_t n, const float* x) {
|
80
76
|
if (verbose) {
|
81
|
-
printf
|
82
|
-
n, d);
|
77
|
+
printf("training level-1 quantizer %" PRId64 " vectors in %dD\n", n, d);
|
83
78
|
}
|
84
79
|
|
85
|
-
q1.train_q1
|
80
|
+
q1.train_q1(n, x, verbose, metric_type);
|
86
81
|
|
87
82
|
if (verbose) {
|
88
83
|
printf("computing residuals\n");
|
89
84
|
}
|
90
85
|
|
91
|
-
const float
|
86
|
+
const float* x_in = x;
|
92
87
|
|
93
|
-
x = fvecs_maybe_subsample
|
94
|
-
|
95
|
-
|
88
|
+
x = fvecs_maybe_subsample(
|
89
|
+
d,
|
90
|
+
(size_t*)&n,
|
91
|
+
pq.cp.max_points_per_centroid * pq.ksub,
|
92
|
+
x,
|
93
|
+
verbose,
|
94
|
+
pq.cp.seed);
|
96
95
|
|
97
|
-
ScopeDeleter<float> del_x
|
96
|
+
ScopeDeleter<float> del_x(x_in == x ? nullptr : x);
|
98
97
|
|
99
98
|
std::vector<idx_t> assign(n); // assignement to coarse centroids
|
100
|
-
q1.quantizer->assign
|
99
|
+
q1.quantizer->assign(n, x, assign.data());
|
101
100
|
std::vector<float> residuals(n * d);
|
102
101
|
for (idx_t i = 0; i < n; i++) {
|
103
|
-
q1.quantizer->compute_residual
|
104
|
-
|
102
|
+
q1.quantizer->compute_residual(
|
103
|
+
x + i * d, residuals.data() + i * d, assign[i]);
|
105
104
|
}
|
106
105
|
|
107
106
|
if (verbose)
|
108
|
-
printf
|
109
|
-
|
107
|
+
printf("training %zdx%zd product quantizer on %" PRId64
|
108
|
+
" vectors in %dD\n",
|
109
|
+
pq.M,
|
110
|
+
pq.ksub,
|
111
|
+
n,
|
112
|
+
d);
|
110
113
|
pq.verbose = verbose;
|
111
|
-
pq.train
|
114
|
+
pq.train(n, residuals.data());
|
112
115
|
|
113
116
|
is_trained = true;
|
114
117
|
}
|
115
118
|
|
116
|
-
void Index2Layer::add(idx_t n, const float* x)
|
117
|
-
{
|
119
|
+
void Index2Layer::add(idx_t n, const float* x) {
|
118
120
|
idx_t bs = 32768;
|
119
121
|
if (n > bs) {
|
120
122
|
for (idx_t i0 = 0; i0 < n; i0 += bs) {
|
121
123
|
idx_t i1 = std::min(i0 + bs, n);
|
122
124
|
if (verbose) {
|
123
|
-
printf("Index2Layer::add: adding %" PRId64 ":%" PRId64
|
124
|
-
|
125
|
+
printf("Index2Layer::add: adding %" PRId64 ":%" PRId64
|
126
|
+
" / %" PRId64 "\n",
|
127
|
+
i0,
|
128
|
+
i1,
|
129
|
+
n);
|
125
130
|
}
|
126
|
-
add
|
131
|
+
add(i1 - i0, x + i0 * d);
|
127
132
|
}
|
128
133
|
return;
|
129
134
|
}
|
130
135
|
|
131
|
-
std::vector<idx_t> codes1
|
132
|
-
q1.quantizer->assign
|
136
|
+
std::vector<idx_t> codes1(n);
|
137
|
+
q1.quantizer->assign(n, x, codes1.data());
|
133
138
|
std::vector<float> residuals(n * d);
|
134
139
|
for (idx_t i = 0; i < n; i++) {
|
135
|
-
q1.quantizer->compute_residual
|
136
|
-
|
140
|
+
q1.quantizer->compute_residual(
|
141
|
+
x + i * d, residuals.data() + i * d, codes1[i]);
|
137
142
|
}
|
138
|
-
std::vector<uint8_t> codes2
|
143
|
+
std::vector<uint8_t> codes2(n * code_size_2);
|
139
144
|
|
140
|
-
pq.compute_codes
|
145
|
+
pq.compute_codes(residuals.data(), codes2.data(), n);
|
141
146
|
|
142
|
-
codes.resize
|
143
|
-
uint8_t
|
147
|
+
codes.resize((ntotal + n) * code_size);
|
148
|
+
uint8_t* wp = &codes[ntotal * code_size];
|
144
149
|
|
145
150
|
{
|
146
151
|
int i = 0x11223344;
|
147
|
-
const char
|
148
|
-
FAISS_THROW_IF_NOT_MSG
|
149
|
-
|
152
|
+
const char* ip = (char*)&i;
|
153
|
+
FAISS_THROW_IF_NOT_MSG(
|
154
|
+
ip[0] == 0x44, "works only on a little-endian CPU");
|
150
155
|
}
|
151
156
|
|
152
157
|
// copy to output table
|
153
158
|
for (idx_t i = 0; i < n; i++) {
|
154
|
-
memcpy
|
159
|
+
memcpy(wp, &codes1[i], code_size_1);
|
155
160
|
wp += code_size_1;
|
156
|
-
memcpy
|
161
|
+
memcpy(wp, &codes2[i * code_size_2], code_size_2);
|
157
162
|
wp += code_size_2;
|
158
163
|
}
|
159
164
|
|
160
165
|
ntotal += n;
|
161
|
-
|
162
166
|
}
|
163
167
|
|
164
168
|
void Index2Layer::search(
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
169
|
+
idx_t /*n*/,
|
170
|
+
const float* /*x*/,
|
171
|
+
idx_t /*k*/,
|
172
|
+
float* /*distances*/,
|
173
|
+
idx_t* /*labels*/) const {
|
174
|
+
FAISS_THROW_MSG("not implemented");
|
171
175
|
}
|
172
176
|
|
173
|
-
|
174
|
-
void Index2Layer::reconstruct_n(idx_t i0, idx_t ni, float* recons) const
|
175
|
-
{
|
177
|
+
void Index2Layer::reconstruct_n(idx_t i0, idx_t ni, float* recons) const {
|
176
178
|
std::vector<float> recons1(d);
|
177
|
-
FAISS_THROW_IF_NOT
|
178
|
-
const uint8_t
|
179
|
+
FAISS_THROW_IF_NOT(i0 >= 0 && i0 + ni <= ntotal);
|
180
|
+
const uint8_t* rp = &codes[i0 * code_size];
|
179
181
|
|
180
182
|
for (idx_t i = 0; i < ni; i++) {
|
181
183
|
idx_t key = 0;
|
182
|
-
memcpy
|
183
|
-
q1.quantizer->reconstruct
|
184
|
+
memcpy(&key, rp, code_size_1);
|
185
|
+
q1.quantizer->reconstruct(key, recons1.data());
|
184
186
|
rp += code_size_1;
|
185
|
-
pq.decode
|
187
|
+
pq.decode(rp, recons);
|
186
188
|
for (idx_t j = 0; j < d; j++) {
|
187
189
|
recons[j] += recons1[j];
|
188
190
|
}
|
@@ -191,53 +193,44 @@ void Index2Layer::reconstruct_n(idx_t i0, idx_t ni, float* recons) const
|
|
191
193
|
}
|
192
194
|
}
|
193
195
|
|
194
|
-
void Index2Layer::transfer_to_IVFPQ
|
195
|
-
|
196
|
-
FAISS_THROW_IF_NOT
|
197
|
-
FAISS_THROW_IF_NOT
|
198
|
-
FAISS_THROW_IF_NOT (other.ntotal == 0);
|
196
|
+
void Index2Layer::transfer_to_IVFPQ(IndexIVFPQ& other) const {
|
197
|
+
FAISS_THROW_IF_NOT(other.nlist == q1.nlist);
|
198
|
+
FAISS_THROW_IF_NOT(other.code_size == code_size_2);
|
199
|
+
FAISS_THROW_IF_NOT(other.ntotal == 0);
|
199
200
|
|
200
|
-
const uint8_t
|
201
|
+
const uint8_t* rp = codes.data();
|
201
202
|
|
202
203
|
for (idx_t i = 0; i < ntotal; i++) {
|
203
204
|
idx_t key = 0;
|
204
|
-
memcpy
|
205
|
+
memcpy(&key, rp, code_size_1);
|
205
206
|
rp += code_size_1;
|
206
|
-
other.invlists->add_entry
|
207
|
+
other.invlists->add_entry(key, i, rp);
|
207
208
|
rp += code_size_2;
|
208
209
|
}
|
209
210
|
|
210
211
|
other.ntotal = ntotal;
|
211
|
-
|
212
212
|
}
|
213
213
|
|
214
|
-
|
215
|
-
|
216
|
-
void Index2Layer::reconstruct(idx_t key, float* recons) const
|
217
|
-
{
|
218
|
-
reconstruct_n (key, 1, recons);
|
214
|
+
void Index2Layer::reconstruct(idx_t key, float* recons) const {
|
215
|
+
reconstruct_n(key, 1, recons);
|
219
216
|
}
|
220
217
|
|
221
|
-
void Index2Layer::reset()
|
222
|
-
{
|
218
|
+
void Index2Layer::reset() {
|
223
219
|
ntotal = 0;
|
224
|
-
codes.clear
|
220
|
+
codes.clear();
|
225
221
|
}
|
226
222
|
|
227
|
-
|
228
223
|
namespace {
|
229
224
|
|
230
|
-
|
231
225
|
struct Distance2Level : DistanceComputer {
|
232
226
|
size_t d;
|
233
227
|
const Index2Layer& storage;
|
234
228
|
std::vector<float> buf;
|
235
|
-
const float
|
229
|
+
const float* q;
|
236
230
|
|
237
231
|
const float *pq_l1_tab, *pq_l2_tab;
|
238
232
|
|
239
|
-
explicit Distance2Level(const Index2Layer& storage)
|
240
|
-
: storage(storage) {
|
233
|
+
explicit Distance2Level(const Index2Layer& storage) : storage(storage) {
|
241
234
|
d = storage.d;
|
242
235
|
FAISS_ASSERT(storage.pq.dsub == 4);
|
243
236
|
pq_l2_tab = storage.pq.centroids.data();
|
@@ -250,67 +243,64 @@ struct Distance2Level : DistanceComputer {
|
|
250
243
|
return fvec_L2sqr(buf.data() + d, buf.data(), d);
|
251
244
|
}
|
252
245
|
|
253
|
-
void set_query(const float
|
246
|
+
void set_query(const float* x) override {
|
254
247
|
q = x;
|
255
248
|
}
|
256
249
|
};
|
257
250
|
|
258
251
|
// well optimized for xNN+PQNN
|
259
252
|
struct DistanceXPQ4 : Distance2Level {
|
260
|
-
|
261
253
|
int M, k;
|
262
254
|
|
263
255
|
explicit DistanceXPQ4(const Index2Layer& storage)
|
264
|
-
|
265
|
-
const IndexFlat
|
266
|
-
|
256
|
+
: Distance2Level(storage) {
|
257
|
+
const IndexFlat* quantizer =
|
258
|
+
dynamic_cast<IndexFlat*>(storage.q1.quantizer);
|
267
259
|
|
268
260
|
FAISS_ASSERT(quantizer);
|
269
261
|
M = storage.pq.M;
|
270
262
|
pq_l1_tab = quantizer->xb.data();
|
271
263
|
}
|
272
264
|
|
273
|
-
float operator
|
265
|
+
float operator()(idx_t i) override {
|
274
266
|
#ifdef __SSE3__
|
275
|
-
const uint8_t
|
267
|
+
const uint8_t* code = storage.codes.data() + i * storage.code_size;
|
276
268
|
long key = 0;
|
277
|
-
memcpy
|
269
|
+
memcpy(&key, code, storage.code_size_1);
|
278
270
|
code += storage.code_size_1;
|
279
271
|
|
280
272
|
// walking pointers
|
281
|
-
const float
|
282
|
-
const __m128
|
283
|
-
const __m128
|
273
|
+
const float* qa = q;
|
274
|
+
const __m128* l1_t = (const __m128*)(pq_l1_tab + d * key);
|
275
|
+
const __m128* pq_l2_t = (const __m128*)pq_l2_tab;
|
284
276
|
__m128 accu = _mm_setzero_ps();
|
285
277
|
|
286
278
|
for (int m = 0; m < M; m++) {
|
287
279
|
__m128 qi = _mm_loadu_ps(qa);
|
288
|
-
__m128 recons = l1_t[m]
|
289
|
-
__m128 diff = qi
|
290
|
-
accu
|
280
|
+
__m128 recons = _mm_add_ps(l1_t[m], pq_l2_t[*code++]);
|
281
|
+
__m128 diff = _mm_sub_ps(qi, recons);
|
282
|
+
accu = _mm_add_ps(accu, _mm_mul_ps(diff, diff));
|
291
283
|
pq_l2_t += 256;
|
292
284
|
qa += 4;
|
293
285
|
}
|
294
286
|
|
295
|
-
accu = _mm_hadd_ps
|
296
|
-
accu = _mm_hadd_ps
|
297
|
-
return
|
287
|
+
accu = _mm_hadd_ps(accu, accu);
|
288
|
+
accu = _mm_hadd_ps(accu, accu);
|
289
|
+
return _mm_cvtss_f32(accu);
|
298
290
|
#else
|
299
291
|
FAISS_THROW_MSG("not implemented for non-x64 platforms");
|
300
292
|
#endif
|
301
293
|
}
|
302
|
-
|
303
294
|
};
|
304
295
|
|
305
296
|
// well optimized for 2xNN+PQNN
|
306
297
|
struct Distance2xXPQ4 : Distance2Level {
|
307
|
-
|
308
298
|
int M_2, mi_nbits;
|
309
299
|
|
310
300
|
explicit Distance2xXPQ4(const Index2Layer& storage)
|
311
|
-
|
312
|
-
const MultiIndexQuantizer
|
313
|
-
|
301
|
+
: Distance2Level(storage) {
|
302
|
+
const MultiIndexQuantizer* mi =
|
303
|
+
dynamic_cast<MultiIndexQuantizer*>(storage.q1.quantizer);
|
314
304
|
|
315
305
|
FAISS_ASSERT(mi);
|
316
306
|
FAISS_ASSERT(storage.pq.M % 2 == 0);
|
@@ -319,59 +309,55 @@ struct Distance2xXPQ4 : Distance2Level {
|
|
319
309
|
pq_l1_tab = mi->pq.centroids.data();
|
320
310
|
}
|
321
311
|
|
322
|
-
float operator
|
323
|
-
const uint8_t
|
312
|
+
float operator()(idx_t i) override {
|
313
|
+
const uint8_t* code = storage.codes.data() + i * storage.code_size;
|
324
314
|
long key01 = 0;
|
325
|
-
memcpy
|
315
|
+
memcpy(&key01, code, storage.code_size_1);
|
326
316
|
code += storage.code_size_1;
|
327
317
|
#ifdef __SSE3__
|
328
318
|
|
329
319
|
// walking pointers
|
330
|
-
const float
|
331
|
-
const __m128
|
332
|
-
const __m128
|
320
|
+
const float* qa = q;
|
321
|
+
const __m128* pq_l1_t = (const __m128*)pq_l1_tab;
|
322
|
+
const __m128* pq_l2_t = (const __m128*)pq_l2_tab;
|
333
323
|
__m128 accu = _mm_setzero_ps();
|
334
324
|
|
335
325
|
for (int mi_m = 0; mi_m < 2; mi_m++) {
|
336
326
|
long l1_idx = key01 & ((1L << mi_nbits) - 1);
|
337
|
-
const __m128
|
327
|
+
const __m128* pq_l1 = pq_l1_t + M_2 * l1_idx;
|
338
328
|
|
339
329
|
for (int m = 0; m < M_2; m++) {
|
340
330
|
__m128 qi = _mm_loadu_ps(qa);
|
341
|
-
__m128 recons = pq_l1[m]
|
342
|
-
__m128 diff = qi
|
343
|
-
accu
|
331
|
+
__m128 recons = _mm_add_ps(pq_l1[m], pq_l2_t[*code++]);
|
332
|
+
__m128 diff = _mm_sub_ps(qi, recons);
|
333
|
+
accu = _mm_add_ps(accu, _mm_mul_ps(diff, diff));
|
344
334
|
pq_l2_t += 256;
|
345
335
|
qa += 4;
|
346
336
|
}
|
347
337
|
pq_l1_t += M_2 << mi_nbits;
|
348
338
|
key01 >>= mi_nbits;
|
349
339
|
}
|
350
|
-
accu = _mm_hadd_ps
|
351
|
-
accu = _mm_hadd_ps
|
352
|
-
return
|
340
|
+
accu = _mm_hadd_ps(accu, accu);
|
341
|
+
accu = _mm_hadd_ps(accu, accu);
|
342
|
+
return _mm_cvtss_f32(accu);
|
353
343
|
#else
|
354
344
|
FAISS_THROW_MSG("not implemented for non-x64 platforms");
|
355
345
|
#endif
|
356
346
|
}
|
357
|
-
|
358
347
|
};
|
359
348
|
|
349
|
+
} // namespace
|
360
350
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
DistanceComputer * Index2Layer::get_distance_computer() const {
|
351
|
+
DistanceComputer* Index2Layer::get_distance_computer() const {
|
365
352
|
#ifdef __SSE3__
|
366
|
-
const MultiIndexQuantizer
|
367
|
-
|
353
|
+
const MultiIndexQuantizer* mi =
|
354
|
+
dynamic_cast<MultiIndexQuantizer*>(q1.quantizer);
|
368
355
|
|
369
356
|
if (mi && pq.M % 2 == 0 && pq.dsub == 4) {
|
370
357
|
return new Distance2xXPQ4(*this);
|
371
358
|
}
|
372
359
|
|
373
|
-
const IndexFlat
|
374
|
-
dynamic_cast<IndexFlat*> (q1.quantizer);
|
360
|
+
const IndexFlat* fl = dynamic_cast<IndexFlat*>(q1.quantizer);
|
375
361
|
|
376
362
|
if (fl && pq.dsub == 4) {
|
377
363
|
return new DistanceXPQ4(*this);
|
@@ -381,57 +367,46 @@ DistanceComputer * Index2Layer::get_distance_computer() const {
|
|
381
367
|
return Index::get_distance_computer();
|
382
368
|
}
|
383
369
|
|
384
|
-
|
385
370
|
/* The standalone codec interface */
|
386
|
-
size_t Index2Layer::sa_code_size
|
387
|
-
{
|
371
|
+
size_t Index2Layer::sa_code_size() const {
|
388
372
|
return code_size;
|
389
373
|
}
|
390
374
|
|
391
|
-
void Index2Layer::sa_encode
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
q1.quantizer->assign (n, x, list_nos.get());
|
375
|
+
void Index2Layer::sa_encode(idx_t n, const float* x, uint8_t* bytes) const {
|
376
|
+
FAISS_THROW_IF_NOT(is_trained);
|
377
|
+
std::unique_ptr<int64_t[]> list_nos(new int64_t[n]);
|
378
|
+
q1.quantizer->assign(n, x, list_nos.get());
|
396
379
|
std::vector<float> residuals(n * d);
|
397
380
|
for (idx_t i = 0; i < n; i++) {
|
398
|
-
q1.quantizer->compute_residual
|
399
|
-
|
381
|
+
q1.quantizer->compute_residual(
|
382
|
+
x + i * d, residuals.data() + i * d, list_nos[i]);
|
400
383
|
}
|
401
|
-
pq.compute_codes
|
384
|
+
pq.compute_codes(residuals.data(), bytes, n);
|
402
385
|
|
403
386
|
for (idx_t i = n - 1; i >= 0; i--) {
|
404
|
-
uint8_t
|
405
|
-
memmove
|
406
|
-
|
407
|
-
q1.encode_listno (list_nos[i], code);
|
387
|
+
uint8_t* code = bytes + i * code_size;
|
388
|
+
memmove(code + code_size_1, bytes + i * code_size_2, code_size_2);
|
389
|
+
q1.encode_listno(list_nos[i], code);
|
408
390
|
}
|
409
|
-
|
410
391
|
}
|
411
392
|
|
412
|
-
void Index2Layer::sa_decode
|
413
|
-
{
|
414
|
-
|
393
|
+
void Index2Layer::sa_decode(idx_t n, const uint8_t* bytes, float* x) const {
|
415
394
|
#pragma omp parallel
|
416
395
|
{
|
417
|
-
std::vector<float> residual
|
396
|
+
std::vector<float> residual(d);
|
418
397
|
|
419
398
|
#pragma omp for
|
420
399
|
for (idx_t i = 0; i < n; i++) {
|
421
|
-
const uint8_t
|
422
|
-
int64_t list_no = q1.decode_listno
|
423
|
-
float
|
424
|
-
pq.decode
|
425
|
-
q1.quantizer->reconstruct
|
400
|
+
const uint8_t* code = bytes + i * code_size;
|
401
|
+
int64_t list_no = q1.decode_listno(code);
|
402
|
+
float* xi = x + i * d;
|
403
|
+
pq.decode(code + code_size_1, xi);
|
404
|
+
q1.quantizer->reconstruct(list_no, residual.data());
|
426
405
|
for (int j = 0; j < d; j++) {
|
427
406
|
xi[j] += residual[j];
|
428
407
|
}
|
429
408
|
}
|
430
409
|
}
|
431
|
-
|
432
410
|
}
|
433
411
|
|
434
|
-
|
435
|
-
|
436
|
-
|
437
412
|
} // namespace faiss
|