faiss 0.6.2 → 0.6.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 +8 -0
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +3 -1
- data/vendor/faiss/faiss/Clustering.cpp +9 -1
- data/vendor/faiss/faiss/Clustering.h +8 -0
- data/vendor/faiss/faiss/IVFlib.cpp +14 -3
- data/vendor/faiss/faiss/Index.h +2 -2
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +9 -10
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +2 -3
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +24 -4
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +16 -145
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +0 -6
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +5 -9
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +8 -18
- data/vendor/faiss/faiss/IndexBinaryIVF.h +8 -1
- data/vendor/faiss/faiss/IndexEDEN.cpp +273 -0
- data/vendor/faiss/faiss/IndexEDEN.h +57 -0
- data/vendor/faiss/faiss/IndexFastScan.cpp +15 -4
- data/vendor/faiss/faiss/IndexFlat.cpp +21 -54
- data/vendor/faiss/faiss/IndexFlat.h +2 -2
- data/vendor/faiss/faiss/IndexHNSW.cpp +311 -102
- data/vendor/faiss/faiss/IndexHNSW.h +31 -7
- data/vendor/faiss/faiss/IndexIDMap.cpp +26 -8
- data/vendor/faiss/faiss/IndexIDMap.h +2 -0
- data/vendor/faiss/faiss/IndexIVF.cpp +36 -10
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +3 -4
- data/vendor/faiss/faiss/IndexIVFEDEN.cpp +302 -0
- data/vendor/faiss/faiss/IndexIVFEDEN.h +70 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +5 -6
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +3 -4
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +49 -23
- data/vendor/faiss/faiss/IndexIVFPQ.h +11 -0
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +0 -1
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +19 -49
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +180 -76
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +5 -4
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +8 -6
- data/vendor/faiss/faiss/IndexLSH.cpp +2 -3
- data/vendor/faiss/faiss/IndexLattice.cpp +5 -0
- data/vendor/faiss/faiss/IndexNNDescent.cpp +9 -2
- data/vendor/faiss/faiss/IndexNSG.cpp +7 -2
- data/vendor/faiss/faiss/IndexPQ.cpp +6 -8
- data/vendor/faiss/faiss/IndexPreTransform.cpp +15 -0
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +2 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +1 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +5 -1
- data/vendor/faiss/faiss/IndexRefine.cpp +30 -1
- data/vendor/faiss/faiss/IndexReplicas.cpp +1 -2
- data/vendor/faiss/faiss/IndexShards.cpp +5 -5
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +6 -5
- data/vendor/faiss/faiss/MetaIndexes.cpp +2 -4
- data/vendor/faiss/faiss/SuperKMeans.cpp +286 -247
- data/vendor/faiss/faiss/SuperKMeans.h +33 -2
- data/vendor/faiss/faiss/VectorTransform.cpp +71 -2
- data/vendor/faiss/faiss/VectorTransform.h +3 -0
- data/vendor/faiss/faiss/clone_index.cpp +8 -0
- data/vendor/faiss/faiss/factory_tools.cpp +47 -4
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +11 -11
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +1 -5
- data/vendor/faiss/faiss/gpu/GpuDistance.h +2 -5
- data/vendor/faiss/faiss/gpu/GpuIndex.h +38 -16
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +71 -1
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +17 -0
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +16 -0
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +1 -1
- data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +2 -2
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +180 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +1 -5
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFPQ.h +88 -0
- data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFPQ.h +134 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +7 -4
- data/vendor/faiss/faiss/impl/DistanceComputer.h +34 -0
- data/vendor/faiss/faiss/impl/EDENQuantizer.h +119 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +528 -267
- data/vendor/faiss/faiss/impl/HNSW.h +46 -7
- data/vendor/faiss/faiss/impl/IDSelector.h +44 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +2 -2
- data/vendor/faiss/faiss/impl/NNDescent.cpp +10 -3
- data/vendor/faiss/faiss/impl/NSG.cpp +3 -1
- data/vendor/faiss/faiss/impl/Panorama.h +20 -9
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +152 -84
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +38 -26
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +45 -37
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +35 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +239 -72
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +66 -4
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +4 -13
- data/vendor/faiss/faiss/impl/ResultHandler.h +34 -34
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +287 -84
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +26 -10
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +2 -2
- data/vendor/faiss/faiss/impl/VisitedTable.cpp +22 -2
- data/vendor/faiss/faiss/impl/VisitedTable.h +20 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +90 -14
- data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +4 -4
- data/vendor/faiss/faiss/impl/expanded_scanners.h +5 -1
- data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +1 -0
- data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +35 -2
- data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +1 -1
- data/vendor/faiss/faiss/impl/index_read.cpp +491 -50
- data/vendor/faiss/faiss/impl/index_write.cpp +86 -30
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +8 -9
- data/vendor/faiss/faiss/impl/platform_macros.h +3 -1
- data/vendor/faiss/faiss/impl/polysemous_training/avx512.cpp +284 -0
- data/vendor/faiss/faiss/impl/polysemous_training/dispatch.h +115 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +73 -39
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +0 -1
- data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +26 -15
- data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +4 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +4 -4
- data/vendor/faiss/faiss/impl/result_handler/ResultHandler.cpp +195 -0
- data/vendor/faiss/faiss/impl/result_handler/avx2.cpp +133 -0
- data/vendor/faiss/faiss/impl/result_handler/avx512.cpp +281 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx2.cpp +72 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx512.cpp +228 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer.cpp +887 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +2 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +9 -8
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +90 -24
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +30 -30
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +4 -5
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +101 -34
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +169 -13
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +125 -26
- data/vendor/faiss/faiss/impl/simd_dispatch.h +70 -31
- data/vendor/faiss/faiss/index_factory.cpp +40 -7
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -1
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +9 -6
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +29 -8
- data/vendor/faiss/faiss/python/python_callbacks.cpp +3 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +60 -0
- data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +26 -1
- data/vendor/faiss/faiss/svs/IndexSVSFlat.h +13 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +47 -5
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +23 -3
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +4 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +10 -4
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +2 -1
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +1 -1
- data/vendor/faiss/faiss/utils/distances.cpp +30 -11
- data/vendor/faiss/faiss/utils/distances_dispatch.h +30 -24
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +1 -1
- data/vendor/faiss/faiss/utils/distances_simd.cpp +4 -3
- data/vendor/faiss/faiss/utils/extra_distances.cpp +4 -14
- data/vendor/faiss/faiss/utils/extra_distances.h +1 -2
- data/vendor/faiss/faiss/utils/hamming.cpp +16 -10
- data/vendor/faiss/faiss/utils/hamming.h +10 -1
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +14 -3
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_vpopcnt.cpp +24 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +1 -1
- data/vendor/faiss/faiss/utils/hamming_distance/{hamming_computer-avx512_spr.h → hamming_computer-avx512_vpopcnt.h} +85 -24
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +141 -0
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +29 -8
- data/vendor/faiss/faiss/utils/rabitq_simd.h +202 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +194 -30
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +0 -1
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +263 -15
- data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +198 -18
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +245 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +330 -40
- data/vendor/faiss/faiss/utils/simd_impl/{rabitq_avx512_spr.cpp → rabitq_avx512_vpopcnt.cpp} +112 -23
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +11 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +143 -6
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +2 -7
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +6 -1
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_sve.cpp +34 -0
- data/vendor/faiss/faiss/utils/simd_levels.cpp +196 -47
- data/vendor/faiss/faiss/utils/simd_levels.h +33 -8
- data/vendor/faiss/faiss/utils/utils.cpp +9 -27
- metadata +21 -5
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +0 -15
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
// -*- c++ -*-
|
|
9
9
|
|
|
10
|
+
#include <cmath>
|
|
10
11
|
#include <cstring>
|
|
11
12
|
#include <memory>
|
|
12
13
|
|
|
@@ -206,6 +207,206 @@ const float kLloydMaxBoundaries8[] = {
|
|
|
206
207
|
2.8413202220f, 2.9594262622f, 3.0937618168f, 3.2505157199f,
|
|
207
208
|
3.4405881450f, 3.6864032383f, 4.0502898282f
|
|
208
209
|
};
|
|
210
|
+
const float kLloydMaxCentroids5[] = {
|
|
211
|
+
-3.260726295605043f, -2.691115579554310f, -2.317736402126149f,
|
|
212
|
+
-2.028725991363304f, -1.787231211885846f, -1.576226389073775f,
|
|
213
|
+
-1.386338935362625f, -1.211803212032400f, -1.048782381365585f,
|
|
214
|
+
-0.894564395854440f, -0.747135131789057f, -0.604933168939543f,
|
|
215
|
+
-0.466699175119721f, -0.331378051429876f, -0.198051689203879f,
|
|
216
|
+
-0.065889622349093f, 0.065889622349093f, 0.198051689203879f,
|
|
217
|
+
0.331378051429876f, 0.466699175119721f, 0.604933168939543f,
|
|
218
|
+
0.747135131789057f, 0.894564395854440f, 1.048782381365585f,
|
|
219
|
+
1.211803212032400f, 1.386338935362625f, 1.576226389073775f,
|
|
220
|
+
1.787231211885846f, 2.028725991363304f, 2.317736402126149f,
|
|
221
|
+
2.691115579554310f, 3.260726295605043f
|
|
222
|
+
};
|
|
223
|
+
const float kLloydMaxBoundaries5[] = {
|
|
224
|
+
-2.975920937579676f, -2.504425990840229f,
|
|
225
|
+
-2.173231196744727f, -1.907978601624575f,
|
|
226
|
+
-1.681728800479811f, -1.481282662218200f,
|
|
227
|
+
-1.299071073697513f, -1.130292796698992f,
|
|
228
|
+
-0.971673388610013f, -0.820849763821748f,
|
|
229
|
+
-0.676034150364300f, -0.535816172029632f,
|
|
230
|
+
-0.399038613274799f, -0.264714870316877f,
|
|
231
|
+
-0.131970655776486f, 0.000000000000000f,
|
|
232
|
+
0.131970655776486f, 0.264714870316877f,
|
|
233
|
+
0.399038613274799f, 0.535816172029632f,
|
|
234
|
+
0.676034150364300f, 0.820849763821748f,
|
|
235
|
+
0.971673388610013f, 1.130292796698992f,
|
|
236
|
+
1.299071073697513f, 1.481282662218200f,
|
|
237
|
+
1.681728800479811f, 1.907978601624575f,
|
|
238
|
+
2.173231196744727f, 2.504425990840229f,
|
|
239
|
+
2.975920937579676f
|
|
240
|
+
};
|
|
241
|
+
const float kLloydMaxCentroids6[] = {
|
|
242
|
+
-3.744069023696475f, -3.240416640324168f, -2.917391465309850f,
|
|
243
|
+
-2.672261701410258f, -2.471294740528467f, -2.298972741297400f,
|
|
244
|
+
-2.146803022259123f, -2.009604894545278f, -1.883971899229356f,
|
|
245
|
+
-1.767537148129260f, -1.658584711429843f, -1.555827465952835f,
|
|
246
|
+
-1.458272959944728f, -1.365137897182360f, -1.275791622351997f,
|
|
247
|
+
-1.189717571132746f, -1.106485959691858f, -1.025734313393752f,
|
|
248
|
+
-0.947153093015629f, -0.870474868055092f, -0.795466052902551f,
|
|
249
|
+
-0.721920472069418f, -0.649654245231535f, -0.578501846064579f,
|
|
250
|
+
-0.508312758753803f, -0.438948800917774f, -0.370281933281155f,
|
|
251
|
+
-0.302192289440361f, -0.234566569768735f, -0.167296609901720f,
|
|
252
|
+
-0.100278121713920f, -0.033409455880258f, 0.033409455880258f,
|
|
253
|
+
0.100278121713920f, 0.167296609901720f, 0.234566569768735f,
|
|
254
|
+
0.302192289440361f, 0.370281933281155f, 0.438948800917774f,
|
|
255
|
+
0.508312758753803f, 0.578501846064579f, 0.649654245231535f,
|
|
256
|
+
0.721920472069418f, 0.795466052902551f, 0.870474868055092f,
|
|
257
|
+
0.947153093015629f, 1.025734313393752f, 1.106485959691858f,
|
|
258
|
+
1.189717571132746f, 1.275791622351997f, 1.365137897182360f,
|
|
259
|
+
1.458272959944728f, 1.555827465952835f, 1.658584711429843f,
|
|
260
|
+
1.767537148129260f, 1.883971899229356f, 2.009604894545278f,
|
|
261
|
+
2.146803022259123f, 2.298972741297400f, 2.471294740528467f,
|
|
262
|
+
2.672261701410258f, 2.917391465309850f, 3.240416640324168f,
|
|
263
|
+
3.744069023696475f
|
|
264
|
+
};
|
|
265
|
+
const float kLloydMaxBoundaries6[] = {
|
|
266
|
+
-3.492242832010322f, -3.078904052817009f,
|
|
267
|
+
-2.794826583360054f, -2.571778220969362f,
|
|
268
|
+
-2.385133740912933f, -2.222887881778261f,
|
|
269
|
+
-2.078203958402201f, -1.946788396887317f,
|
|
270
|
+
-1.825754523679308f, -1.713060929779552f,
|
|
271
|
+
-1.607206088691339f, -1.507050212948781f,
|
|
272
|
+
-1.411705428563544f, -1.320464759767178f,
|
|
273
|
+
-1.232754596742371f, -1.148101765412302f,
|
|
274
|
+
-1.066110136542805f, -0.986443703204690f,
|
|
275
|
+
-0.908813980535361f, -0.832970460478822f,
|
|
276
|
+
-0.758693262485985f, -0.685787358650477f,
|
|
277
|
+
-0.614078045648057f, -0.543407302409191f,
|
|
278
|
+
-0.473630779835788f, -0.404615367099464f,
|
|
279
|
+
-0.336237111360758f, -0.268379429604548f,
|
|
280
|
+
-0.200931589835227f, -0.133787365807820f,
|
|
281
|
+
-0.066843788797089f, 0.000000000000000f,
|
|
282
|
+
0.066843788797089f, 0.133787365807820f,
|
|
283
|
+
0.200931589835227f, 0.268379429604548f,
|
|
284
|
+
0.336237111360758f, 0.404615367099464f,
|
|
285
|
+
0.473630779835788f, 0.543407302409191f,
|
|
286
|
+
0.614078045648057f, 0.685787358650477f,
|
|
287
|
+
0.758693262485985f, 0.832970460478822f,
|
|
288
|
+
0.908813980535361f, 0.986443703204690f,
|
|
289
|
+
1.066110136542805f, 1.148101765412302f,
|
|
290
|
+
1.232754596742371f, 1.320464759767178f,
|
|
291
|
+
1.411705428563544f, 1.507050212948781f,
|
|
292
|
+
1.607206088691339f, 1.713060929779552f,
|
|
293
|
+
1.825754523679308f, 1.946788396887317f,
|
|
294
|
+
2.078203958402201f, 2.222887881778261f,
|
|
295
|
+
2.385133740912933f, 2.571778220969362f,
|
|
296
|
+
2.794826583360054f, 3.078904052817009f,
|
|
297
|
+
3.492242832010322f
|
|
298
|
+
};
|
|
299
|
+
const float kLloydMaxCentroids7[] = {
|
|
300
|
+
-4.189521933023523f, -3.734857105369156f, -3.447381010593710f,
|
|
301
|
+
-3.231896182843021f, -3.057216102842374f, -2.909021527386642f,
|
|
302
|
+
-2.779491911054078f, -2.663867022558051f, -2.559023499137449f,
|
|
303
|
+
-2.462795908452321f, -2.373620316421171f, -2.290326870492530f,
|
|
304
|
+
-2.212016460501213f, -2.137983242734970f, -2.067662153838450f,
|
|
305
|
+
-2.000593243383757f, -1.936396720412283f, -1.874755326807296f,
|
|
306
|
+
-1.815400993379865f, -1.758105160675647f, -1.702671162415673f,
|
|
307
|
+
-1.648928306223807f, -1.596727786313424f, -1.545938700893484f,
|
|
308
|
+
-1.496445137501057f, -1.448144252238147f, -1.400944106526214f,
|
|
309
|
+
-1.354762105115604f, -1.309523700469555f, -1.265161378699170f,
|
|
310
|
+
-1.221613876387012f, -1.178825265520504f, -1.136744262343403f,
|
|
311
|
+
-1.095323771921318f, -1.054520418037026f, -1.014294067830043f,
|
|
312
|
+
-0.974607484216044f, -0.935426075762634f, -0.896717615963322f,
|
|
313
|
+
-0.858451939611374f, -0.820600783245502f, -0.783137537563140f,
|
|
314
|
+
-0.746037126679468f, -0.709275946093977f, -0.672831567493634f,
|
|
315
|
+
-0.636682661398141f, -0.600808970989236f, -0.565191195643323f,
|
|
316
|
+
-0.529810843625619f, -0.494650181610316f, -0.459692230045422f,
|
|
317
|
+
-0.424920552397901f, -0.390319263305967f, -0.355873075050329f,
|
|
318
|
+
-0.321567103923158f, -0.287386806226095f, -0.253318071908346f,
|
|
319
|
+
-0.219347083403316f, -0.185460257086808f, -0.151644263013162f,
|
|
320
|
+
-0.117885968250325f, -0.084172419896719f, -0.050490753968962f,
|
|
321
|
+
-0.016828143177728f, 0.016828143177728f, 0.050490753968962f,
|
|
322
|
+
0.084172419896719f, 0.117885968250325f, 0.151644263013162f,
|
|
323
|
+
0.185460257086808f, 0.219347083403316f, 0.253318071908346f,
|
|
324
|
+
0.287386806226095f, 0.321567103923158f, 0.355873075050329f,
|
|
325
|
+
0.390319263305967f, 0.424920552397901f, 0.459692230045422f,
|
|
326
|
+
0.494650181610316f, 0.529810843625619f, 0.565191195643323f,
|
|
327
|
+
0.600808970989236f, 0.636682661398141f, 0.672831567493634f,
|
|
328
|
+
0.709275946093977f, 0.746037126679468f, 0.783137537563140f,
|
|
329
|
+
0.820600783245502f, 0.858451939611374f, 0.896717615963322f,
|
|
330
|
+
0.935426075762634f, 0.974607484216044f, 1.014294067830043f,
|
|
331
|
+
1.054520418037026f, 1.095323771921318f, 1.136744262343403f,
|
|
332
|
+
1.178825265520504f, 1.221613876387012f, 1.265161378699170f,
|
|
333
|
+
1.309523700469555f, 1.354762105115604f, 1.400944106526214f,
|
|
334
|
+
1.448144252238147f, 1.496445137501057f, 1.545938700893484f,
|
|
335
|
+
1.596727786313424f, 1.648928306223807f, 1.702671162415673f,
|
|
336
|
+
1.758105160675647f, 1.815400993379865f, 1.874755326807296f,
|
|
337
|
+
1.936396720412283f, 2.000593243383757f, 2.067662153838450f,
|
|
338
|
+
2.137983242734970f, 2.212016460501213f, 2.290326870492530f,
|
|
339
|
+
2.373620316421171f, 2.462795908452321f, 2.559023499137449f,
|
|
340
|
+
2.663867022558051f, 2.779491911054078f, 2.909021527386642f,
|
|
341
|
+
3.057216102842374f, 3.231896182843021f, 3.447381010593710f,
|
|
342
|
+
3.734857105369156f, 4.189521933023523f
|
|
343
|
+
};
|
|
344
|
+
const float kLloydMaxBoundaries7[] = {
|
|
345
|
+
-3.962189519196340f, -3.591119057981433f,
|
|
346
|
+
-3.339638596718365f, -3.144556142842697f,
|
|
347
|
+
-2.983118815114508f, -2.844256719220360f,
|
|
348
|
+
-2.721679466806065f, -2.611445260847750f,
|
|
349
|
+
-2.510909703794885f, -2.418208112436746f,
|
|
350
|
+
-2.331973593456850f, -2.251171665496871f,
|
|
351
|
+
-2.174999851618091f, -2.102822698286710f,
|
|
352
|
+
-2.034127698611103f, -1.968494981898020f,
|
|
353
|
+
-1.905576023609790f, -1.845078160093581f,
|
|
354
|
+
-1.786753077027756f, -1.730388161545660f,
|
|
355
|
+
-1.675799734319740f, -1.622828046268615f,
|
|
356
|
+
-1.571333243603454f, -1.521191919197270f,
|
|
357
|
+
-1.472294694869602f, -1.424544179382180f,
|
|
358
|
+
-1.377853105820909f, -1.332142902792580f,
|
|
359
|
+
-1.287342539584363f, -1.243387627543091f,
|
|
360
|
+
-1.200219570953758f, -1.157784763931954f,
|
|
361
|
+
-1.116034017132360f, -1.074922094979172f,
|
|
362
|
+
-1.034407242933534f, -0.994450776023043f,
|
|
363
|
+
-0.955016779989339f, -0.916071845862978f,
|
|
364
|
+
-0.877584777787348f, -0.839526361428438f,
|
|
365
|
+
-0.801869160404321f, -0.764587332121304f,
|
|
366
|
+
-0.727656536386722f, -0.691053756793806f,
|
|
367
|
+
-0.654757114445887f, -0.618745816193689f,
|
|
368
|
+
-0.583000083316280f, -0.547501019634471f,
|
|
369
|
+
-0.512230512617967f, -0.477171205827869f,
|
|
370
|
+
-0.442306391221661f, -0.407619907851934f,
|
|
371
|
+
-0.373096169178148f, -0.338720089486743f,
|
|
372
|
+
-0.304476955074627f, -0.270352439067221f,
|
|
373
|
+
-0.236332577655831f, -0.202403670245062f,
|
|
374
|
+
-0.168552260049985f, -0.134765115631744f,
|
|
375
|
+
-0.101029194073522f, -0.067331586932840f,
|
|
376
|
+
-0.033659448573345f, 0.000000000000000f,
|
|
377
|
+
0.033659448573345f, 0.067331586932840f,
|
|
378
|
+
0.101029194073522f, 0.134765115631744f,
|
|
379
|
+
0.168552260049985f, 0.202403670245062f,
|
|
380
|
+
0.236332577655831f, 0.270352439067221f,
|
|
381
|
+
0.304476955074627f, 0.338720089486743f,
|
|
382
|
+
0.373096169178148f, 0.407619907851934f,
|
|
383
|
+
0.442306391221661f, 0.477171205827869f,
|
|
384
|
+
0.512230512617967f, 0.547501019634471f,
|
|
385
|
+
0.583000083316280f, 0.618745816193689f,
|
|
386
|
+
0.654757114445887f, 0.691053756793806f,
|
|
387
|
+
0.727656536386722f, 0.764587332121304f,
|
|
388
|
+
0.801869160404321f, 0.839526361428438f,
|
|
389
|
+
0.877584777787348f, 0.916071845862978f,
|
|
390
|
+
0.955016779989339f, 0.994450776023043f,
|
|
391
|
+
1.034407242933534f, 1.074922094979172f,
|
|
392
|
+
1.116034017132360f, 1.157784763931954f,
|
|
393
|
+
1.200219570953758f, 1.243387627543091f,
|
|
394
|
+
1.287342539584363f, 1.332142902792580f,
|
|
395
|
+
1.377853105820909f, 1.424544179382180f,
|
|
396
|
+
1.472294694869602f, 1.521191919197270f,
|
|
397
|
+
1.571333243603454f, 1.622828046268615f,
|
|
398
|
+
1.675799734319740f, 1.730388161545660f,
|
|
399
|
+
1.786753077027756f, 1.845078160093581f,
|
|
400
|
+
1.905576023609790f, 1.968494981898020f,
|
|
401
|
+
2.034127698611103f, 2.102822698286710f,
|
|
402
|
+
2.174999851618091f, 2.251171665496871f,
|
|
403
|
+
2.331973593456850f, 2.418208112436746f,
|
|
404
|
+
2.510909703794885f, 2.611445260847750f,
|
|
405
|
+
2.721679466806065f, 2.844256719220360f,
|
|
406
|
+
2.983118815114508f, 3.144556142842697f,
|
|
407
|
+
3.339638596718365f, 3.591119057981433f,
|
|
408
|
+
3.962189519196340f
|
|
409
|
+
};
|
|
209
410
|
// clang-format on
|
|
210
411
|
|
|
211
412
|
struct LloydMaxTable {
|
|
@@ -219,20 +420,35 @@ const LloydMaxTable kLloydMaxTables[] = {
|
|
|
219
420
|
{kLloydMaxCentroids2, kLloydMaxBoundaries2}, // 2
|
|
220
421
|
{kLloydMaxCentroids3, kLloydMaxBoundaries3}, // 3
|
|
221
422
|
{kLloydMaxCentroids4, kLloydMaxBoundaries4}, // 4
|
|
222
|
-
{
|
|
223
|
-
{
|
|
224
|
-
{
|
|
423
|
+
{kLloydMaxCentroids5, kLloydMaxBoundaries5}, // 5
|
|
424
|
+
{kLloydMaxCentroids6, kLloydMaxBoundaries6}, // 6
|
|
425
|
+
{kLloydMaxCentroids7, kLloydMaxBoundaries7}, // 7
|
|
225
426
|
{kLloydMaxCentroids8, kLloydMaxBoundaries8}, // 8
|
|
226
427
|
};
|
|
227
428
|
|
|
228
|
-
|
|
429
|
+
// The tables are Lloyd-Max optimal for N(0, 1) input. Callers whose input has
|
|
430
|
+
// a different standard deviation pass it as `scale` to stretch the table.
|
|
431
|
+
void populate_lloyd_max_trained(
|
|
432
|
+
size_t mse_bits,
|
|
433
|
+
std::vector<float>& trained,
|
|
434
|
+
float scale = 1.0f) {
|
|
229
435
|
FAISS_THROW_IF_NOT(mse_bits >= 1 && mse_bits <= 8);
|
|
230
|
-
FAISS_THROW_IF_NOT(kLloydMaxTables[mse_bits].centroids
|
|
436
|
+
FAISS_THROW_IF_NOT(kLloydMaxTables[mse_bits].centroids);
|
|
231
437
|
size_t k = size_t(1) << mse_bits;
|
|
232
438
|
const auto& t = kLloydMaxTables[mse_bits];
|
|
233
439
|
trained.resize(k + (k - 1));
|
|
234
|
-
|
|
235
|
-
|
|
440
|
+
for (size_t i = 0; i < k; i++) {
|
|
441
|
+
trained[i] = t.centroids[i] * scale;
|
|
442
|
+
}
|
|
443
|
+
for (size_t i = 0; i + 1 < k; i++) {
|
|
444
|
+
trained[k + i] = t.boundaries[i] * scale;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Component scale of a unit-norm vector in R^d.
|
|
449
|
+
float unit_norm_component_scale(size_t d) {
|
|
450
|
+
FAISS_THROW_IF_NOT(d > 0);
|
|
451
|
+
return 1.0f / std::sqrt(static_cast<float>(d));
|
|
236
452
|
}
|
|
237
453
|
|
|
238
454
|
} // namespace
|
|
@@ -251,14 +467,17 @@ ScalarQuantizer::ScalarQuantizer() {}
|
|
|
251
467
|
void ScalarQuantizer::set_derived_sizes() {
|
|
252
468
|
switch (qtype) {
|
|
253
469
|
case QT_1bit_tqmse:
|
|
470
|
+
case QT_1bit_eden:
|
|
254
471
|
code_size = (d + 7) / 8;
|
|
255
472
|
bits = 1;
|
|
256
473
|
break;
|
|
257
474
|
case QT_2bit_tqmse:
|
|
475
|
+
case QT_2bit_eden:
|
|
258
476
|
code_size = (d * 2 + 7) / 8;
|
|
259
477
|
bits = 2;
|
|
260
478
|
break;
|
|
261
479
|
case QT_3bit_tqmse:
|
|
480
|
+
case QT_3bit_eden:
|
|
262
481
|
code_size = (d * 3 + 7) / 8;
|
|
263
482
|
bits = 3;
|
|
264
483
|
break;
|
|
@@ -267,19 +486,30 @@ void ScalarQuantizer::set_derived_sizes() {
|
|
|
267
486
|
case QT_8bit_direct:
|
|
268
487
|
case QT_8bit_direct_signed:
|
|
269
488
|
case QT_8bit_tqmse:
|
|
489
|
+
case QT_8bit_eden:
|
|
270
490
|
code_size = d;
|
|
271
491
|
bits = 8;
|
|
272
492
|
break;
|
|
273
493
|
case QT_4bit:
|
|
274
494
|
case QT_4bit_uniform:
|
|
275
495
|
case QT_4bit_tqmse:
|
|
496
|
+
case QT_4bit_eden:
|
|
276
497
|
code_size = (d + 1) / 2;
|
|
277
498
|
bits = 4;
|
|
278
499
|
break;
|
|
500
|
+
case QT_5bit_eden:
|
|
501
|
+
code_size = (d * 5 + 7) / 8;
|
|
502
|
+
bits = 5;
|
|
503
|
+
break;
|
|
279
504
|
case QT_6bit:
|
|
505
|
+
case QT_6bit_eden:
|
|
280
506
|
code_size = (d * 6 + 7) / 8;
|
|
281
507
|
bits = 6;
|
|
282
508
|
break;
|
|
509
|
+
case QT_7bit_eden:
|
|
510
|
+
code_size = (d * 7 + 7) / 8;
|
|
511
|
+
bits = 7;
|
|
512
|
+
break;
|
|
283
513
|
case QT_fp16:
|
|
284
514
|
code_size = d * 2;
|
|
285
515
|
bits = 16;
|
|
@@ -334,7 +564,7 @@ void ScalarQuantizer::train(size_t n, const float* x) {
|
|
|
334
564
|
case QT_4bit_uniform:
|
|
335
565
|
case QT_8bit_uniform:
|
|
336
566
|
FAISS_THROW_IF_NOT(n > 0);
|
|
337
|
-
FAISS_THROW_IF_NOT(x
|
|
567
|
+
FAISS_THROW_IF_NOT(x);
|
|
338
568
|
train_Uniform(
|
|
339
569
|
rangestat,
|
|
340
570
|
rangestat_arg,
|
|
@@ -347,7 +577,7 @@ void ScalarQuantizer::train(size_t n, const float* x) {
|
|
|
347
577
|
case QT_8bit:
|
|
348
578
|
case QT_6bit:
|
|
349
579
|
FAISS_THROW_IF_NOT(n > 0);
|
|
350
|
-
FAISS_THROW_IF_NOT(x
|
|
580
|
+
FAISS_THROW_IF_NOT(x);
|
|
351
581
|
train_NonUniform(
|
|
352
582
|
rangestat,
|
|
353
583
|
rangestat_arg,
|
|
@@ -363,20 +593,35 @@ void ScalarQuantizer::train(size_t n, const float* x) {
|
|
|
363
593
|
case QT_8bit_direct_signed:
|
|
364
594
|
// no training necessary
|
|
365
595
|
break;
|
|
596
|
+
case QT_1bit_eden:
|
|
597
|
+
case QT_2bit_eden:
|
|
598
|
+
case QT_3bit_eden:
|
|
599
|
+
case QT_4bit_eden:
|
|
600
|
+
case QT_5bit_eden:
|
|
601
|
+
case QT_6bit_eden:
|
|
602
|
+
case QT_7bit_eden:
|
|
603
|
+
case QT_8bit_eden:
|
|
604
|
+
populate_lloyd_max_trained(bits, trained);
|
|
605
|
+
break;
|
|
366
606
|
case QT_1bit_tqmse:
|
|
367
|
-
populate_lloyd_max_trained(
|
|
607
|
+
populate_lloyd_max_trained(
|
|
608
|
+
1, trained, unit_norm_component_scale(d));
|
|
368
609
|
break;
|
|
369
610
|
case QT_2bit_tqmse:
|
|
370
|
-
populate_lloyd_max_trained(
|
|
611
|
+
populate_lloyd_max_trained(
|
|
612
|
+
2, trained, unit_norm_component_scale(d));
|
|
371
613
|
break;
|
|
372
614
|
case QT_3bit_tqmse:
|
|
373
|
-
populate_lloyd_max_trained(
|
|
615
|
+
populate_lloyd_max_trained(
|
|
616
|
+
3, trained, unit_norm_component_scale(d));
|
|
374
617
|
break;
|
|
375
618
|
case QT_4bit_tqmse:
|
|
376
|
-
populate_lloyd_max_trained(
|
|
619
|
+
populate_lloyd_max_trained(
|
|
620
|
+
4, trained, unit_norm_component_scale(d));
|
|
377
621
|
break;
|
|
378
622
|
case QT_8bit_tqmse:
|
|
379
|
-
populate_lloyd_max_trained(
|
|
623
|
+
populate_lloyd_max_trained(
|
|
624
|
+
8, trained, unit_norm_component_scale(d));
|
|
380
625
|
break;
|
|
381
626
|
case QT_2bit_tq:
|
|
382
627
|
case QT_3bit_tq:
|
|
@@ -390,7 +635,6 @@ void ScalarQuantizer::train(size_t n, const float* x) {
|
|
|
390
635
|
trained.push_back(seed_f[0]);
|
|
391
636
|
trained.push_back(seed_f[1]);
|
|
392
637
|
trained.push_back(static_cast<float>(turboq_refine.qjl_type));
|
|
393
|
-
turboq_refine.init_projection(d);
|
|
394
638
|
break;
|
|
395
639
|
}
|
|
396
640
|
default:
|
|
@@ -398,36 +642,15 @@ void ScalarQuantizer::train(size_t n, const float* x) {
|
|
|
398
642
|
}
|
|
399
643
|
}
|
|
400
644
|
|
|
401
|
-
void ScalarQuantizer::TurboQuantRefine::init_projection(size_t d) {
|
|
402
|
-
if (use_fwht()) {
|
|
403
|
-
padded_d = 1;
|
|
404
|
-
while (padded_d < d) {
|
|
405
|
-
padded_d <<= 1;
|
|
406
|
-
}
|
|
407
|
-
fwht_signs.resize(padded_d);
|
|
408
|
-
RandomGenerator rng(seed);
|
|
409
|
-
for (size_t i = 0; i < padded_d; i++) {
|
|
410
|
-
fwht_signs[i] = (rng.rand_int(2) == 0) ? 1.0f : -1.0f;
|
|
411
|
-
}
|
|
412
|
-
} else {
|
|
413
|
-
rr_matrix.resize(d * d);
|
|
414
|
-
float_randn(rr_matrix.data(), d * d, seed);
|
|
415
|
-
matrix_qr(static_cast<int>(d), static_cast<int>(d), rr_matrix.data());
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
|
|
419
645
|
ScalarQuantizer::SQuantizer* ScalarQuantizer::select_quantizer() const {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
return
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
return scalar_quantizer::sq_select_quantizer<SIMDLevel::NONE>(
|
|
429
|
-
qtype, d, trained);
|
|
430
|
-
});
|
|
646
|
+
// A SIMD level's factory returns nullptr when the dimension is
|
|
647
|
+
// incompatible (e.g. AVX-512 needs d % 16 == 0); the dispatcher then falls
|
|
648
|
+
// back to the next-lower level (AVX-512 -> AVX2 -> scalar).
|
|
649
|
+
return with_simd_level_fallback<AVAILABLE_SIMD_LEVELS_BASE_WITH_SPR>(
|
|
650
|
+
[&]<SIMDLevel SL>() -> SQuantizer* {
|
|
651
|
+
return scalar_quantizer::sq_select_quantizer<SL>(
|
|
652
|
+
qtype, d, trained);
|
|
653
|
+
});
|
|
431
654
|
}
|
|
432
655
|
|
|
433
656
|
void ScalarQuantizer::compute_codes(const float* x, uint8_t* codes, size_t n)
|
|
@@ -438,7 +661,7 @@ void ScalarQuantizer::compute_codes(const float* x, uint8_t* codes, size_t n)
|
|
|
438
661
|
std::unique_ptr<SQuantizer> squant(select_quantizer());
|
|
439
662
|
|
|
440
663
|
memset(codes, 0, code_size * n);
|
|
441
|
-
#pragma omp parallel for
|
|
664
|
+
#pragma omp parallel for if (n > 100)
|
|
442
665
|
for (int64_t i = 0; i < static_cast<int64_t>(n); i++) {
|
|
443
666
|
squant->encode_vector(x + i * d, codes + i * code_size);
|
|
444
667
|
}
|
|
@@ -451,7 +674,7 @@ void ScalarQuantizer::decode(const uint8_t* codes, float* x, size_t n) const {
|
|
|
451
674
|
}
|
|
452
675
|
std::unique_ptr<SQuantizer> squant(select_quantizer());
|
|
453
676
|
|
|
454
|
-
#pragma omp parallel for
|
|
677
|
+
#pragma omp parallel for if (n > 100)
|
|
455
678
|
for (int64_t i = 0; i < static_cast<int64_t>(n); i++) {
|
|
456
679
|
squant->decode_vector(codes + i * code_size, x + i * d);
|
|
457
680
|
}
|
|
@@ -460,17 +683,11 @@ void ScalarQuantizer::decode(const uint8_t* codes, float* x, size_t n) const {
|
|
|
460
683
|
ScalarQuantizer::SQDistanceComputer* ScalarQuantizer::get_distance_computer(
|
|
461
684
|
MetricType metric) const {
|
|
462
685
|
FAISS_THROW_IF_NOT(metric == METRIC_L2 || metric == METRIC_INNER_PRODUCT);
|
|
463
|
-
return
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
return dc;
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
return scalar_quantizer::sq_select_distance_computer<SIMDLevel::NONE>(
|
|
472
|
-
metric, qtype, d, trained);
|
|
473
|
-
});
|
|
686
|
+
return with_simd_level_fallback<AVAILABLE_SIMD_LEVELS_BASE_WITH_SPR>(
|
|
687
|
+
[&]<SIMDLevel SL>() -> SQDistanceComputer* {
|
|
688
|
+
return scalar_quantizer::sq_select_distance_computer<SL>(
|
|
689
|
+
metric, qtype, d, trained);
|
|
690
|
+
});
|
|
474
691
|
}
|
|
475
692
|
|
|
476
693
|
InvertedListScanner* ScalarQuantizer::select_InvertedListScanner(
|
|
@@ -479,33 +696,19 @@ InvertedListScanner* ScalarQuantizer::select_InvertedListScanner(
|
|
|
479
696
|
bool store_pairs,
|
|
480
697
|
const IDSelector* sel,
|
|
481
698
|
bool by_residual) const {
|
|
482
|
-
return
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
return s;
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
return scalar_quantizer::sq_select_InvertedListScanner<SIMDLevel::NONE>(
|
|
499
|
-
qtype,
|
|
500
|
-
mt,
|
|
501
|
-
d,
|
|
502
|
-
code_size,
|
|
503
|
-
trained,
|
|
504
|
-
quantizer,
|
|
505
|
-
store_pairs,
|
|
506
|
-
sel,
|
|
507
|
-
by_residual);
|
|
508
|
-
});
|
|
699
|
+
return with_simd_level_fallback<AVAILABLE_SIMD_LEVELS_BASE_WITH_SPR>(
|
|
700
|
+
[&]<SIMDLevel SL>() -> InvertedListScanner* {
|
|
701
|
+
return scalar_quantizer::sq_select_InvertedListScanner<SL>(
|
|
702
|
+
qtype,
|
|
703
|
+
mt,
|
|
704
|
+
d,
|
|
705
|
+
code_size,
|
|
706
|
+
trained,
|
|
707
|
+
quantizer,
|
|
708
|
+
store_pairs,
|
|
709
|
+
sel,
|
|
710
|
+
by_residual);
|
|
711
|
+
});
|
|
509
712
|
}
|
|
510
713
|
|
|
511
714
|
} // namespace faiss
|
|
@@ -45,6 +45,14 @@ struct ScalarQuantizer : Quantizer {
|
|
|
45
45
|
QT_3bit_tq, ///< Full TurboQuant (2-bit MSE + 1-bit QJL + factors)
|
|
46
46
|
QT_4bit_tq, ///< Full TurboQuant (3-bit MSE + 1-bit QJL + factors)
|
|
47
47
|
QT_5bit_tq, ///< Full TurboQuant (4-bit MSE + 1-bit QJL + factors)
|
|
48
|
+
QT_1bit_eden, ///< EDEN Lloyd-Max scalar code, 1 bit per component
|
|
49
|
+
QT_2bit_eden, ///< EDEN Lloyd-Max scalar code, 2 bits per component
|
|
50
|
+
QT_3bit_eden, ///< EDEN Lloyd-Max scalar code, 3 bits per component
|
|
51
|
+
QT_4bit_eden, ///< EDEN Lloyd-Max scalar code, 4 bits per component
|
|
52
|
+
QT_5bit_eden, ///< EDEN Lloyd-Max scalar code, 5 bits per component
|
|
53
|
+
QT_6bit_eden, ///< EDEN Lloyd-Max scalar code, 6 bits per component
|
|
54
|
+
QT_7bit_eden, ///< EDEN Lloyd-Max scalar code, 7 bits per component
|
|
55
|
+
QT_8bit_eden, ///< EDEN Lloyd-Max scalar code, 8 bits per component
|
|
48
56
|
QT_count
|
|
49
57
|
};
|
|
50
58
|
|
|
@@ -135,6 +143,18 @@ struct ScalarQuantizer : Quantizer {
|
|
|
135
143
|
float distance_to_code(const uint8_t* code) final {
|
|
136
144
|
return query_to_code(code);
|
|
137
145
|
}
|
|
146
|
+
|
|
147
|
+
void distance_to_code_batch_4(
|
|
148
|
+
const uint8_t* c1,
|
|
149
|
+
const uint8_t* c2,
|
|
150
|
+
const uint8_t* c3,
|
|
151
|
+
const uint8_t* c4,
|
|
152
|
+
float& d1,
|
|
153
|
+
float& d2,
|
|
154
|
+
float& d3,
|
|
155
|
+
float& d4) override {
|
|
156
|
+
query_to_codes_batch_4(c1, c2, c3, c4, d1, d2, d3, d4);
|
|
157
|
+
}
|
|
138
158
|
};
|
|
139
159
|
|
|
140
160
|
/// TurboQuant full (QT_*_tq) refinement state, isolated from the
|
|
@@ -157,18 +177,9 @@ struct ScalarQuantizer : Quantizer {
|
|
|
157
177
|
return s;
|
|
158
178
|
}
|
|
159
179
|
|
|
180
|
+
/// The selected projection is built from `trained` by the quantizer.
|
|
160
181
|
uint8_t qjl_type = 0;
|
|
161
182
|
uint64_t seed = 42;
|
|
162
|
-
size_t padded_d = 0;
|
|
163
|
-
std::vector<float> fwht_signs;
|
|
164
|
-
std::vector<float> rr_matrix;
|
|
165
|
-
size_t nb_bits_lo = 0;
|
|
166
|
-
size_t n_hi_dims = 0;
|
|
167
|
-
|
|
168
|
-
void init_projection(size_t d);
|
|
169
|
-
bool use_fwht() const {
|
|
170
|
-
return qjl_type == 0;
|
|
171
|
-
}
|
|
172
183
|
|
|
173
184
|
struct DistanceComputer : SQDistanceComputer {
|
|
174
185
|
virtual void configure(uint8_t qb, bool int_qjl) = 0;
|
|
@@ -179,6 +190,11 @@ struct ScalarQuantizer : Quantizer {
|
|
|
179
190
|
};
|
|
180
191
|
};
|
|
181
192
|
|
|
193
|
+
static_assert(
|
|
194
|
+
sizeof(TurboQuantRefine) <= 16,
|
|
195
|
+
"keep this a small config struct -- do not add projection buffers "
|
|
196
|
+
"here (T287092602)");
|
|
197
|
+
|
|
182
198
|
TurboQuantRefine turboq_refine;
|
|
183
199
|
|
|
184
200
|
SQDistanceComputer* get_distance_computer(
|
|
@@ -70,8 +70,8 @@ void ThreadedIndex<IndexT>::addIndex(IndexT* index) {
|
|
|
70
70
|
|
|
71
71
|
// Make sure this index is not duplicated
|
|
72
72
|
for (auto& p : indices_) {
|
|
73
|
-
|
|
74
|
-
p.first
|
|
73
|
+
FAISS_THROW_IF_MSG(
|
|
74
|
+
p.first == index,
|
|
75
75
|
"addIndex: attempting to add index "
|
|
76
76
|
"that is already in the collection");
|
|
77
77
|
}
|
|
@@ -15,8 +15,12 @@ namespace faiss {
|
|
|
15
15
|
// advance() is O(1) except every 250 calls, which are O(size).
|
|
16
16
|
// The hash set strategy is a constant factor slower for get()/set(),
|
|
17
17
|
// but O(1) to construct and O(visits) to advance.
|
|
18
|
-
//
|
|
19
|
-
|
|
18
|
+
// 10M is only a current estimated threshold, not a proven crossover: we are not
|
|
19
|
+
// sure the array still wins at 10M. The point where the array stops paying off
|
|
20
|
+
// varies by dataset (it shifts with dimension, working-set / cache pressure,
|
|
21
|
+
// etc.), so this is a coarse default that should eventually be replaced by
|
|
22
|
+
// smarter per-index tuning.
|
|
23
|
+
size_t visited_table_hashset_threshold = 10000000;
|
|
20
24
|
|
|
21
25
|
std::unique_ptr<VisitedTable> VisitedTable::create(
|
|
22
26
|
size_t size,
|
|
@@ -29,6 +33,22 @@ std::unique_ptr<VisitedTable> VisitedTable::create(
|
|
|
29
33
|
return std::make_unique<VisitedTableVector>(size);
|
|
30
34
|
}
|
|
31
35
|
|
|
36
|
+
VisitedTable& VisitedTable::get_reusable(
|
|
37
|
+
size_t size,
|
|
38
|
+
std::optional<bool> use_hashset) {
|
|
39
|
+
bool use_set =
|
|
40
|
+
use_hashset.value_or(size >= visited_table_hashset_threshold);
|
|
41
|
+
if (use_set) {
|
|
42
|
+
thread_local VisitedTableSet tls_set;
|
|
43
|
+
tls_set.advance();
|
|
44
|
+
return tls_set;
|
|
45
|
+
}
|
|
46
|
+
thread_local VisitedTableVector tls_vec(0);
|
|
47
|
+
tls_vec.ensure_size(size);
|
|
48
|
+
tls_vec.advance();
|
|
49
|
+
return tls_vec;
|
|
50
|
+
}
|
|
51
|
+
|
|
32
52
|
void VisitedTableVector::advance() {
|
|
33
53
|
if (visno < 254) {
|
|
34
54
|
// 254 rather than 255 because sometimes we use visno and visno+1
|
|
@@ -48,6 +48,18 @@ struct VisitedTable {
|
|
|
48
48
|
static std::unique_ptr<VisitedTable> create(
|
|
49
49
|
size_t size,
|
|
50
50
|
std::optional<bool> use_hashset = std::nullopt);
|
|
51
|
+
|
|
52
|
+
/// Returns a thread-local, reusable table sized for at least `size` and
|
|
53
|
+
/// reset to a clean state. Unlike create(), it does not allocate on each
|
|
54
|
+
/// call: the O(size) versioned array is allocated once per thread and
|
|
55
|
+
/// reused across searches, avoiding a per-search alloc+zero of the whole
|
|
56
|
+
/// array when a static index is searched repeatedly.
|
|
57
|
+
///
|
|
58
|
+
/// The returned reference is owned by thread-local storage: do not delete
|
|
59
|
+
/// it and do not use it beyond the current search on the calling thread.
|
|
60
|
+
static VisitedTable& get_reusable(
|
|
61
|
+
size_t size,
|
|
62
|
+
std::optional<bool> use_hashset = std::nullopt);
|
|
51
63
|
};
|
|
52
64
|
|
|
53
65
|
/// Set-based implementation using unordered_set.
|
|
@@ -87,6 +99,14 @@ struct VisitedTableVector FAISS_FINAL : VisitedTable {
|
|
|
87
99
|
|
|
88
100
|
explicit VisitedTableVector(size_t size) : visited(size, 0) {}
|
|
89
101
|
|
|
102
|
+
/// Grow so indices in [0, size) are valid; new slots read as unvisited.
|
|
103
|
+
/// Never shrinks, so capacity is retained when the table is reused.
|
|
104
|
+
void ensure_size(size_t size) {
|
|
105
|
+
if (visited.size() < size) {
|
|
106
|
+
visited.resize(size, 0);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
90
110
|
bool set(size_t no) final {
|
|
91
111
|
if (visited[no] == visno) {
|
|
92
112
|
return false;
|