faiss 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +23 -21
- data/ext/faiss/extconf.rb +11 -0
- data/ext/faiss/index.cpp +4 -4
- data/ext/faiss/index_binary.cpp +6 -6
- data/ext/faiss/product_quantizer.cpp +4 -4
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +13 -0
- data/vendor/faiss/faiss/IVFlib.cpp +101 -2
- data/vendor/faiss/faiss/IVFlib.h +26 -2
- data/vendor/faiss/faiss/Index.cpp +36 -3
- data/vendor/faiss/faiss/Index.h +43 -6
- data/vendor/faiss/faiss/Index2Layer.cpp +6 -2
- data/vendor/faiss/faiss/Index2Layer.h +6 -1
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +219 -16
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +63 -5
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +299 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +199 -0
- data/vendor/faiss/faiss/IndexBinary.cpp +20 -4
- data/vendor/faiss/faiss/IndexBinary.h +18 -3
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +9 -2
- data/vendor/faiss/faiss/IndexBinaryFlat.h +4 -2
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -1
- data/vendor/faiss/faiss/IndexBinaryFromFloat.h +2 -1
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +5 -1
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +2 -1
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +17 -4
- data/vendor/faiss/faiss/IndexBinaryHash.h +8 -4
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +28 -13
- data/vendor/faiss/faiss/IndexBinaryIVF.h +10 -7
- data/vendor/faiss/faiss/IndexFastScan.cpp +626 -0
- data/vendor/faiss/faiss/IndexFastScan.h +145 -0
- data/vendor/faiss/faiss/IndexFlat.cpp +34 -21
- data/vendor/faiss/faiss/IndexFlat.h +7 -4
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +35 -1
- data/vendor/faiss/faiss/IndexFlatCodes.h +12 -0
- data/vendor/faiss/faiss/IndexHNSW.cpp +66 -138
- data/vendor/faiss/faiss/IndexHNSW.h +4 -2
- data/vendor/faiss/faiss/IndexIDMap.cpp +247 -0
- data/vendor/faiss/faiss/IndexIDMap.h +107 -0
- data/vendor/faiss/faiss/IndexIVF.cpp +121 -33
- data/vendor/faiss/faiss/IndexIVF.h +35 -16
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +84 -7
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +63 -1
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +590 -0
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +171 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +1290 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.h +213 -0
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +37 -17
- data/vendor/faiss/faiss/IndexIVFFlat.h +4 -2
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +234 -50
- data/vendor/faiss/faiss/IndexIVFPQ.h +5 -1
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +23 -852
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +7 -112
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +3 -3
- data/vendor/faiss/faiss/IndexIVFPQR.h +1 -1
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +3 -1
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +2 -1
- data/vendor/faiss/faiss/IndexLSH.cpp +4 -2
- data/vendor/faiss/faiss/IndexLSH.h +2 -1
- data/vendor/faiss/faiss/IndexLattice.cpp +7 -1
- data/vendor/faiss/faiss/IndexLattice.h +3 -1
- data/vendor/faiss/faiss/IndexNNDescent.cpp +4 -3
- data/vendor/faiss/faiss/IndexNNDescent.h +2 -1
- data/vendor/faiss/faiss/IndexNSG.cpp +37 -3
- data/vendor/faiss/faiss/IndexNSG.h +25 -1
- data/vendor/faiss/faiss/IndexPQ.cpp +106 -69
- data/vendor/faiss/faiss/IndexPQ.h +19 -5
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +15 -450
- data/vendor/faiss/faiss/IndexPQFastScan.h +15 -78
- data/vendor/faiss/faiss/IndexPreTransform.cpp +47 -8
- data/vendor/faiss/faiss/IndexPreTransform.h +15 -3
- data/vendor/faiss/faiss/IndexRefine.cpp +8 -4
- data/vendor/faiss/faiss/IndexRefine.h +4 -2
- data/vendor/faiss/faiss/IndexReplicas.cpp +4 -2
- data/vendor/faiss/faiss/IndexReplicas.h +2 -1
- data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +438 -0
- data/vendor/faiss/faiss/IndexRowwiseMinMax.h +92 -0
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +26 -15
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +6 -7
- data/vendor/faiss/faiss/IndexShards.cpp +4 -1
- data/vendor/faiss/faiss/IndexShards.h +2 -1
- data/vendor/faiss/faiss/MetaIndexes.cpp +5 -178
- data/vendor/faiss/faiss/MetaIndexes.h +3 -81
- data/vendor/faiss/faiss/VectorTransform.cpp +43 -0
- data/vendor/faiss/faiss/VectorTransform.h +22 -4
- data/vendor/faiss/faiss/clone_index.cpp +23 -1
- data/vendor/faiss/faiss/clone_index.h +3 -0
- data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +300 -0
- data/vendor/faiss/faiss/cppcontrib/detail/CoarseBitType.h +24 -0
- data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +195 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +2058 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +408 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +2147 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMax-inl.h +460 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMaxFP16-inl.h +465 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +1618 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +251 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +1452 -0
- data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +1 -0
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +0 -4
- data/vendor/faiss/faiss/gpu/GpuIndex.h +28 -4
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +2 -1
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +10 -8
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +75 -14
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +19 -32
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +22 -31
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +22 -28
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +14 -0
- data/vendor/faiss/faiss/gpu/GpuResources.h +16 -3
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +3 -3
- data/vendor/faiss/faiss/gpu/impl/IndexUtils.h +32 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +1 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +311 -75
- data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +10 -0
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +3 -0
- data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +2 -2
- data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +5 -4
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +116 -47
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +44 -13
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +0 -54
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +0 -76
- data/vendor/faiss/faiss/impl/DistanceComputer.h +64 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +123 -27
- data/vendor/faiss/faiss/impl/HNSW.h +19 -16
- data/vendor/faiss/faiss/impl/IDSelector.cpp +125 -0
- data/vendor/faiss/faiss/impl/IDSelector.h +135 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +6 -28
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +6 -1
- data/vendor/faiss/faiss/impl/LookupTableScaler.h +77 -0
- data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -0
- data/vendor/faiss/faiss/impl/NSG.cpp +1 -1
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +383 -0
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +154 -0
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +225 -145
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +29 -10
- data/vendor/faiss/faiss/impl/Quantizer.h +43 -0
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +192 -36
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +40 -20
- data/vendor/faiss/faiss/impl/ResultHandler.h +96 -0
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +97 -173
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +18 -18
- data/vendor/faiss/faiss/impl/index_read.cpp +240 -9
- data/vendor/faiss/faiss/impl/index_write.cpp +237 -5
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +6 -4
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +56 -16
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +25 -8
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +66 -25
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +75 -27
- data/vendor/faiss/faiss/index_factory.cpp +196 -7
- data/vendor/faiss/faiss/index_io.h +5 -0
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -0
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +4 -1
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +2 -1
- data/vendor/faiss/faiss/python/python_callbacks.cpp +27 -0
- data/vendor/faiss/faiss/python/python_callbacks.h +15 -0
- data/vendor/faiss/faiss/utils/Heap.h +31 -15
- data/vendor/faiss/faiss/utils/distances.cpp +380 -56
- data/vendor/faiss/faiss/utils/distances.h +113 -15
- data/vendor/faiss/faiss/utils/distances_simd.cpp +726 -6
- data/vendor/faiss/faiss/utils/extra_distances.cpp +12 -7
- data/vendor/faiss/faiss/utils/extra_distances.h +3 -1
- data/vendor/faiss/faiss/utils/fp16-fp16c.h +21 -0
- data/vendor/faiss/faiss/utils/fp16-inl.h +101 -0
- data/vendor/faiss/faiss/utils/fp16.h +11 -0
- data/vendor/faiss/faiss/utils/hamming-inl.h +54 -0
- data/vendor/faiss/faiss/utils/hamming.cpp +0 -48
- data/vendor/faiss/faiss/utils/ordered_key_value.h +10 -0
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +62 -0
- data/vendor/faiss/faiss/utils/quantize_lut.h +20 -0
- data/vendor/faiss/faiss/utils/random.cpp +53 -0
- data/vendor/faiss/faiss/utils/random.h +5 -0
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +4 -0
- data/vendor/faiss/faiss/utils/simdlib_emulated.h +6 -1
- data/vendor/faiss/faiss/utils/simdlib_neon.h +7 -2
- metadata +37 -3
|
@@ -26,10 +26,12 @@
|
|
|
26
26
|
|
|
27
27
|
#include <faiss/Index2Layer.h>
|
|
28
28
|
#include <faiss/IndexAdditiveQuantizer.h>
|
|
29
|
+
#include <faiss/IndexAdditiveQuantizerFastScan.h>
|
|
29
30
|
#include <faiss/IndexFlat.h>
|
|
30
31
|
#include <faiss/IndexHNSW.h>
|
|
31
32
|
#include <faiss/IndexIVF.h>
|
|
32
33
|
#include <faiss/IndexIVFAdditiveQuantizer.h>
|
|
34
|
+
#include <faiss/IndexIVFAdditiveQuantizerFastScan.h>
|
|
33
35
|
#include <faiss/IndexIVFFlat.h>
|
|
34
36
|
#include <faiss/IndexIVFPQ.h>
|
|
35
37
|
#include <faiss/IndexIVFPQFastScan.h>
|
|
@@ -37,11 +39,13 @@
|
|
|
37
39
|
#include <faiss/IndexIVFSpectralHash.h>
|
|
38
40
|
#include <faiss/IndexLSH.h>
|
|
39
41
|
#include <faiss/IndexLattice.h>
|
|
42
|
+
#include <faiss/IndexNNDescent.h>
|
|
40
43
|
#include <faiss/IndexNSG.h>
|
|
41
44
|
#include <faiss/IndexPQ.h>
|
|
42
45
|
#include <faiss/IndexPQFastScan.h>
|
|
43
46
|
#include <faiss/IndexPreTransform.h>
|
|
44
47
|
#include <faiss/IndexRefine.h>
|
|
48
|
+
#include <faiss/IndexRowwiseMinMax.h>
|
|
45
49
|
#include <faiss/IndexScalarQuantizer.h>
|
|
46
50
|
#include <faiss/MetaIndexes.h>
|
|
47
51
|
#include <faiss/VectorTransform.h>
|
|
@@ -271,9 +275,17 @@ static void read_AdditiveQuantizer(AdditiveQuantizer* aq, IOReader* f) {
|
|
|
271
275
|
READ1(aq->norm_min);
|
|
272
276
|
READ1(aq->norm_max);
|
|
273
277
|
if (aq->search_type == AdditiveQuantizer::ST_norm_cqint8 ||
|
|
274
|
-
aq->search_type == AdditiveQuantizer::ST_norm_cqint4
|
|
278
|
+
aq->search_type == AdditiveQuantizer::ST_norm_cqint4 ||
|
|
279
|
+
aq->search_type == AdditiveQuantizer::ST_norm_lsq2x4 ||
|
|
280
|
+
aq->search_type == AdditiveQuantizer::ST_norm_rq2x4) {
|
|
275
281
|
READXBVECTOR(aq->qnorm.codes);
|
|
276
282
|
}
|
|
283
|
+
|
|
284
|
+
if (aq->search_type == AdditiveQuantizer::ST_norm_lsq2x4 ||
|
|
285
|
+
aq->search_type == AdditiveQuantizer::ST_norm_rq2x4) {
|
|
286
|
+
READVECTOR(aq->norm_tabs);
|
|
287
|
+
}
|
|
288
|
+
|
|
277
289
|
aq->set_derived_values();
|
|
278
290
|
}
|
|
279
291
|
|
|
@@ -301,6 +313,37 @@ static void read_LocalSearchQuantizer(LocalSearchQuantizer* lsq, IOReader* f) {
|
|
|
301
313
|
READ1(lsq->update_codebooks_with_double);
|
|
302
314
|
}
|
|
303
315
|
|
|
316
|
+
static void read_ProductAdditiveQuantizer(
|
|
317
|
+
ProductAdditiveQuantizer* paq,
|
|
318
|
+
IOReader* f) {
|
|
319
|
+
read_AdditiveQuantizer(paq, f);
|
|
320
|
+
READ1(paq->nsplits);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
static void read_ProductResidualQuantizer(
|
|
324
|
+
ProductResidualQuantizer* prq,
|
|
325
|
+
IOReader* f) {
|
|
326
|
+
read_ProductAdditiveQuantizer(prq, f);
|
|
327
|
+
|
|
328
|
+
for (size_t i = 0; i < prq->nsplits; i++) {
|
|
329
|
+
auto rq = new ResidualQuantizer();
|
|
330
|
+
read_ResidualQuantizer(rq, f);
|
|
331
|
+
prq->quantizers.push_back(rq);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
static void read_ProductLocalSearchQuantizer(
|
|
336
|
+
ProductLocalSearchQuantizer* plsq,
|
|
337
|
+
IOReader* f) {
|
|
338
|
+
read_ProductAdditiveQuantizer(plsq, f);
|
|
339
|
+
|
|
340
|
+
for (size_t i = 0; i < plsq->nsplits; i++) {
|
|
341
|
+
auto lsq = new LocalSearchQuantizer();
|
|
342
|
+
read_LocalSearchQuantizer(lsq, f);
|
|
343
|
+
plsq->quantizers.push_back(lsq);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
304
347
|
static void read_ScalarQuantizer(ScalarQuantizer* ivsc, IOReader* f) {
|
|
305
348
|
READ1(ivsc->qtype);
|
|
306
349
|
READ1(ivsc->rangestat);
|
|
@@ -361,6 +404,21 @@ static void read_NSG(NSG* nsg, IOReader* f) {
|
|
|
361
404
|
}
|
|
362
405
|
}
|
|
363
406
|
|
|
407
|
+
static void read_NNDescent(NNDescent* nnd, IOReader* f) {
|
|
408
|
+
READ1(nnd->ntotal);
|
|
409
|
+
READ1(nnd->d);
|
|
410
|
+
READ1(nnd->K);
|
|
411
|
+
READ1(nnd->S);
|
|
412
|
+
READ1(nnd->R);
|
|
413
|
+
READ1(nnd->L);
|
|
414
|
+
READ1(nnd->iter);
|
|
415
|
+
READ1(nnd->search_L);
|
|
416
|
+
READ1(nnd->random_seed);
|
|
417
|
+
READ1(nnd->has_built);
|
|
418
|
+
|
|
419
|
+
READVECTOR(nnd->final_graph);
|
|
420
|
+
}
|
|
421
|
+
|
|
364
422
|
ProductQuantizer* read_ProductQuantizer(const char* fname) {
|
|
365
423
|
FileIOReader reader(fname);
|
|
366
424
|
return read_ProductQuantizer(&reader);
|
|
@@ -444,10 +502,14 @@ static IndexIVFPQ* read_ivfpq(IOReader* f, uint32_t h, int io_flags) {
|
|
|
444
502
|
}
|
|
445
503
|
|
|
446
504
|
if (ivpq->is_trained) {
|
|
447
|
-
// precomputed table not stored. It is cheaper to recompute it
|
|
505
|
+
// precomputed table not stored. It is cheaper to recompute it.
|
|
506
|
+
// precompute_table() may be disabled with a flag.
|
|
448
507
|
ivpq->use_precomputed_table = 0;
|
|
449
|
-
if (ivpq->by_residual)
|
|
450
|
-
|
|
508
|
+
if (ivpq->by_residual) {
|
|
509
|
+
if ((io_flags & IO_FLAG_SKIP_PRECOMPUTE_TABLE) == 0) {
|
|
510
|
+
ivpq->precompute_table();
|
|
511
|
+
}
|
|
512
|
+
}
|
|
451
513
|
if (ivfpqr) {
|
|
452
514
|
read_ProductQuantizer(&ivfpqr->refine_pq, f);
|
|
453
515
|
READVECTOR(ivfpqr->refine_codes);
|
|
@@ -549,6 +611,20 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
|
549
611
|
READ1(idxr->code_size);
|
|
550
612
|
READVECTOR(idxr->codes);
|
|
551
613
|
idx = idxr;
|
|
614
|
+
} else if (h == fourcc("IxPR")) {
|
|
615
|
+
auto idxpr = new IndexProductResidualQuantizer();
|
|
616
|
+
read_index_header(idxpr, f);
|
|
617
|
+
read_ProductResidualQuantizer(&idxpr->prq, f);
|
|
618
|
+
READ1(idxpr->code_size);
|
|
619
|
+
READVECTOR(idxpr->codes);
|
|
620
|
+
idx = idxpr;
|
|
621
|
+
} else if (h == fourcc("IxPL")) {
|
|
622
|
+
auto idxpl = new IndexProductLocalSearchQuantizer();
|
|
623
|
+
read_index_header(idxpl, f);
|
|
624
|
+
read_ProductLocalSearchQuantizer(&idxpl->plsq, f);
|
|
625
|
+
READ1(idxpl->code_size);
|
|
626
|
+
READVECTOR(idxpl->codes);
|
|
627
|
+
idx = idxpl;
|
|
552
628
|
} else if (h == fourcc("ImRQ")) {
|
|
553
629
|
ResidualCoarseQuantizer* idxr = new ResidualCoarseQuantizer();
|
|
554
630
|
read_index_header(idxr, f);
|
|
@@ -556,6 +632,103 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
|
556
632
|
READ1(idxr->beam_factor);
|
|
557
633
|
idxr->set_beam_factor(idxr->beam_factor);
|
|
558
634
|
idx = idxr;
|
|
635
|
+
} else if (
|
|
636
|
+
h == fourcc("ILfs") || h == fourcc("IRfs") || h == fourcc("IPRf") ||
|
|
637
|
+
h == fourcc("IPLf")) {
|
|
638
|
+
bool is_LSQ = h == fourcc("ILfs");
|
|
639
|
+
bool is_RQ = h == fourcc("IRfs");
|
|
640
|
+
bool is_PLSQ = h == fourcc("IPLf");
|
|
641
|
+
|
|
642
|
+
IndexAdditiveQuantizerFastScan* idxaqfs;
|
|
643
|
+
if (is_LSQ) {
|
|
644
|
+
idxaqfs = new IndexLocalSearchQuantizerFastScan();
|
|
645
|
+
} else if (is_RQ) {
|
|
646
|
+
idxaqfs = new IndexResidualQuantizerFastScan();
|
|
647
|
+
} else if (is_PLSQ) {
|
|
648
|
+
idxaqfs = new IndexProductLocalSearchQuantizerFastScan();
|
|
649
|
+
} else {
|
|
650
|
+
idxaqfs = new IndexProductResidualQuantizerFastScan();
|
|
651
|
+
}
|
|
652
|
+
read_index_header(idxaqfs, f);
|
|
653
|
+
|
|
654
|
+
if (is_LSQ) {
|
|
655
|
+
read_LocalSearchQuantizer((LocalSearchQuantizer*)idxaqfs->aq, f);
|
|
656
|
+
} else if (is_RQ) {
|
|
657
|
+
read_ResidualQuantizer((ResidualQuantizer*)idxaqfs->aq, f);
|
|
658
|
+
} else if (is_PLSQ) {
|
|
659
|
+
read_ProductLocalSearchQuantizer(
|
|
660
|
+
(ProductLocalSearchQuantizer*)idxaqfs->aq, f);
|
|
661
|
+
} else {
|
|
662
|
+
read_ProductResidualQuantizer(
|
|
663
|
+
(ProductResidualQuantizer*)idxaqfs->aq, f);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
READ1(idxaqfs->implem);
|
|
667
|
+
READ1(idxaqfs->bbs);
|
|
668
|
+
READ1(idxaqfs->qbs);
|
|
669
|
+
|
|
670
|
+
READ1(idxaqfs->M);
|
|
671
|
+
READ1(idxaqfs->nbits);
|
|
672
|
+
READ1(idxaqfs->ksub);
|
|
673
|
+
READ1(idxaqfs->code_size);
|
|
674
|
+
READ1(idxaqfs->ntotal2);
|
|
675
|
+
READ1(idxaqfs->M2);
|
|
676
|
+
|
|
677
|
+
READ1(idxaqfs->rescale_norm);
|
|
678
|
+
READ1(idxaqfs->norm_scale);
|
|
679
|
+
READ1(idxaqfs->max_train_points);
|
|
680
|
+
|
|
681
|
+
READVECTOR(idxaqfs->codes);
|
|
682
|
+
idx = idxaqfs;
|
|
683
|
+
} else if (
|
|
684
|
+
h == fourcc("IVLf") || h == fourcc("IVRf") || h == fourcc("NPLf") ||
|
|
685
|
+
h == fourcc("NPRf")) {
|
|
686
|
+
bool is_LSQ = h == fourcc("IVLf");
|
|
687
|
+
bool is_RQ = h == fourcc("IVRf");
|
|
688
|
+
bool is_PLSQ = h == fourcc("NPLf");
|
|
689
|
+
|
|
690
|
+
IndexIVFAdditiveQuantizerFastScan* ivaqfs;
|
|
691
|
+
if (is_LSQ) {
|
|
692
|
+
ivaqfs = new IndexIVFLocalSearchQuantizerFastScan();
|
|
693
|
+
} else if (is_RQ) {
|
|
694
|
+
ivaqfs = new IndexIVFResidualQuantizerFastScan();
|
|
695
|
+
} else if (is_PLSQ) {
|
|
696
|
+
ivaqfs = new IndexIVFProductLocalSearchQuantizerFastScan();
|
|
697
|
+
} else {
|
|
698
|
+
ivaqfs = new IndexIVFProductResidualQuantizerFastScan();
|
|
699
|
+
}
|
|
700
|
+
read_ivf_header(ivaqfs, f);
|
|
701
|
+
|
|
702
|
+
if (is_LSQ) {
|
|
703
|
+
read_LocalSearchQuantizer((LocalSearchQuantizer*)ivaqfs->aq, f);
|
|
704
|
+
} else if (is_RQ) {
|
|
705
|
+
read_ResidualQuantizer((ResidualQuantizer*)ivaqfs->aq, f);
|
|
706
|
+
} else if (is_PLSQ) {
|
|
707
|
+
read_ProductLocalSearchQuantizer(
|
|
708
|
+
(ProductLocalSearchQuantizer*)ivaqfs->aq, f);
|
|
709
|
+
} else {
|
|
710
|
+
read_ProductResidualQuantizer(
|
|
711
|
+
(ProductResidualQuantizer*)ivaqfs->aq, f);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
READ1(ivaqfs->by_residual);
|
|
715
|
+
READ1(ivaqfs->implem);
|
|
716
|
+
READ1(ivaqfs->bbs);
|
|
717
|
+
READ1(ivaqfs->qbs);
|
|
718
|
+
|
|
719
|
+
READ1(ivaqfs->M);
|
|
720
|
+
READ1(ivaqfs->nbits);
|
|
721
|
+
READ1(ivaqfs->ksub);
|
|
722
|
+
READ1(ivaqfs->code_size);
|
|
723
|
+
READ1(ivaqfs->qbs2);
|
|
724
|
+
READ1(ivaqfs->M2);
|
|
725
|
+
|
|
726
|
+
READ1(ivaqfs->rescale_norm);
|
|
727
|
+
READ1(ivaqfs->norm_scale);
|
|
728
|
+
READ1(ivaqfs->max_train_points);
|
|
729
|
+
|
|
730
|
+
read_InvertedLists(ivaqfs, f, io_flags);
|
|
731
|
+
idx = ivaqfs;
|
|
559
732
|
} else if (h == fourcc("IvFl") || h == fourcc("IvFL")) { // legacy
|
|
560
733
|
IndexIVFFlat* ivfl = new IndexIVFFlat();
|
|
561
734
|
std::vector<std::vector<Index::idx_t>> ids;
|
|
@@ -635,20 +808,34 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
|
635
808
|
}
|
|
636
809
|
read_InvertedLists(ivsc, f, io_flags);
|
|
637
810
|
idx = ivsc;
|
|
638
|
-
} else if (
|
|
811
|
+
} else if (
|
|
812
|
+
h == fourcc("IwLS") || h == fourcc("IwRQ") || h == fourcc("IwPL") ||
|
|
813
|
+
h == fourcc("IwPR")) {
|
|
639
814
|
bool is_LSQ = h == fourcc("IwLS");
|
|
815
|
+
bool is_RQ = h == fourcc("IwRQ");
|
|
816
|
+
bool is_PLSQ = h == fourcc("IwPL");
|
|
640
817
|
IndexIVFAdditiveQuantizer* iva;
|
|
641
818
|
if (is_LSQ) {
|
|
642
819
|
iva = new IndexIVFLocalSearchQuantizer();
|
|
643
|
-
} else {
|
|
820
|
+
} else if (is_RQ) {
|
|
644
821
|
iva = new IndexIVFResidualQuantizer();
|
|
822
|
+
} else if (is_PLSQ) {
|
|
823
|
+
iva = new IndexIVFProductLocalSearchQuantizer();
|
|
824
|
+
} else {
|
|
825
|
+
iva = new IndexIVFProductResidualQuantizer();
|
|
645
826
|
}
|
|
646
827
|
read_ivf_header(iva, f);
|
|
647
828
|
READ1(iva->code_size);
|
|
648
829
|
if (is_LSQ) {
|
|
649
830
|
read_LocalSearchQuantizer((LocalSearchQuantizer*)iva->aq, f);
|
|
650
|
-
} else {
|
|
831
|
+
} else if (is_RQ) {
|
|
651
832
|
read_ResidualQuantizer((ResidualQuantizer*)iva->aq, f);
|
|
833
|
+
} else if (is_PLSQ) {
|
|
834
|
+
read_ProductLocalSearchQuantizer(
|
|
835
|
+
(ProductLocalSearchQuantizer*)iva->aq, f);
|
|
836
|
+
} else {
|
|
837
|
+
read_ProductResidualQuantizer(
|
|
838
|
+
(ProductResidualQuantizer*)iva->aq, f);
|
|
652
839
|
}
|
|
653
840
|
READ1(iva->by_residual);
|
|
654
841
|
READ1(iva->use_precomputed_table);
|
|
@@ -751,8 +938,15 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
|
751
938
|
dynamic_cast<IndexPQ*>(idxhnsw->storage)->pq.compute_sdc_table();
|
|
752
939
|
}
|
|
753
940
|
idx = idxhnsw;
|
|
754
|
-
} else if (
|
|
755
|
-
|
|
941
|
+
} else if (
|
|
942
|
+
h == fourcc("INSf") || h == fourcc("INSp") || h == fourcc("INSs")) {
|
|
943
|
+
IndexNSG* idxnsg;
|
|
944
|
+
if (h == fourcc("INSf"))
|
|
945
|
+
idxnsg = new IndexNSGFlat();
|
|
946
|
+
if (h == fourcc("INSp"))
|
|
947
|
+
idxnsg = new IndexNSGPQ();
|
|
948
|
+
if (h == fourcc("INSs"))
|
|
949
|
+
idxnsg = new IndexNSGSQ();
|
|
756
950
|
read_index_header(idxnsg, f);
|
|
757
951
|
READ1(idxnsg->GK);
|
|
758
952
|
READ1(idxnsg->build_type);
|
|
@@ -764,6 +958,13 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
|
764
958
|
idxnsg->storage = read_index(f, io_flags);
|
|
765
959
|
idxnsg->own_fields = true;
|
|
766
960
|
idx = idxnsg;
|
|
961
|
+
} else if (h == fourcc("INNf")) {
|
|
962
|
+
IndexNNDescent* idxnnd = new IndexNNDescentFlat();
|
|
963
|
+
read_index_header(idxnnd, f);
|
|
964
|
+
read_NNDescent(&idxnnd->nndescent, f);
|
|
965
|
+
idxnnd->storage = read_index(f, io_flags);
|
|
966
|
+
idxnnd->own_fields = true;
|
|
967
|
+
idx = idxnnd;
|
|
767
968
|
} else if (h == fourcc("IPfs")) {
|
|
768
969
|
IndexPQFastScan* idxpqfs = new IndexPQFastScan();
|
|
769
970
|
read_index_header(idxpqfs, f);
|
|
@@ -774,6 +975,13 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
|
774
975
|
READ1(idxpqfs->ntotal2);
|
|
775
976
|
READ1(idxpqfs->M2);
|
|
776
977
|
READVECTOR(idxpqfs->codes);
|
|
978
|
+
|
|
979
|
+
const auto& pq = idxpqfs->pq;
|
|
980
|
+
idxpqfs->M = pq.M;
|
|
981
|
+
idxpqfs->nbits = pq.nbits;
|
|
982
|
+
idxpqfs->ksub = (1 << pq.nbits);
|
|
983
|
+
idxpqfs->code_size = pq.code_size;
|
|
984
|
+
|
|
777
985
|
idx = idxpqfs;
|
|
778
986
|
|
|
779
987
|
} else if (h == fourcc("IwPf")) {
|
|
@@ -788,7 +996,30 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
|
788
996
|
read_ProductQuantizer(&ivpq->pq, f);
|
|
789
997
|
read_InvertedLists(ivpq, f, io_flags);
|
|
790
998
|
ivpq->precompute_table();
|
|
999
|
+
|
|
1000
|
+
const auto& pq = ivpq->pq;
|
|
1001
|
+
ivpq->M = pq.M;
|
|
1002
|
+
ivpq->nbits = pq.nbits;
|
|
1003
|
+
ivpq->ksub = (1 << pq.nbits);
|
|
1004
|
+
ivpq->code_size = pq.code_size;
|
|
1005
|
+
|
|
791
1006
|
idx = ivpq;
|
|
1007
|
+
} else if (h == fourcc("IRMf")) {
|
|
1008
|
+
IndexRowwiseMinMax* imm = new IndexRowwiseMinMax();
|
|
1009
|
+
read_index_header(imm, f);
|
|
1010
|
+
|
|
1011
|
+
imm->index = read_index(f, io_flags);
|
|
1012
|
+
imm->own_fields = true;
|
|
1013
|
+
|
|
1014
|
+
idx = imm;
|
|
1015
|
+
} else if (h == fourcc("IRMh")) {
|
|
1016
|
+
IndexRowwiseMinMaxFP16* imm = new IndexRowwiseMinMaxFP16();
|
|
1017
|
+
read_index_header(imm, f);
|
|
1018
|
+
|
|
1019
|
+
imm->index = read_index(f, io_flags);
|
|
1020
|
+
imm->own_fields = true;
|
|
1021
|
+
|
|
1022
|
+
idx = imm;
|
|
792
1023
|
} else {
|
|
793
1024
|
FAISS_THROW_FMT(
|
|
794
1025
|
"Index type 0x%08x (\"%s\") not recognized",
|
|
@@ -27,10 +27,12 @@
|
|
|
27
27
|
|
|
28
28
|
#include <faiss/Index2Layer.h>
|
|
29
29
|
#include <faiss/IndexAdditiveQuantizer.h>
|
|
30
|
+
#include <faiss/IndexAdditiveQuantizerFastScan.h>
|
|
30
31
|
#include <faiss/IndexFlat.h>
|
|
31
32
|
#include <faiss/IndexHNSW.h>
|
|
32
33
|
#include <faiss/IndexIVF.h>
|
|
33
34
|
#include <faiss/IndexIVFAdditiveQuantizer.h>
|
|
35
|
+
#include <faiss/IndexIVFAdditiveQuantizerFastScan.h>
|
|
34
36
|
#include <faiss/IndexIVFFlat.h>
|
|
35
37
|
#include <faiss/IndexIVFPQ.h>
|
|
36
38
|
#include <faiss/IndexIVFPQFastScan.h>
|
|
@@ -38,11 +40,13 @@
|
|
|
38
40
|
#include <faiss/IndexIVFSpectralHash.h>
|
|
39
41
|
#include <faiss/IndexLSH.h>
|
|
40
42
|
#include <faiss/IndexLattice.h>
|
|
43
|
+
#include <faiss/IndexNNDescent.h>
|
|
41
44
|
#include <faiss/IndexNSG.h>
|
|
42
45
|
#include <faiss/IndexPQ.h>
|
|
43
46
|
#include <faiss/IndexPQFastScan.h>
|
|
44
47
|
#include <faiss/IndexPreTransform.h>
|
|
45
48
|
#include <faiss/IndexRefine.h>
|
|
49
|
+
#include <faiss/IndexRowwiseMinMax.h>
|
|
46
50
|
#include <faiss/IndexScalarQuantizer.h>
|
|
47
51
|
#include <faiss/MetaIndexes.h>
|
|
48
52
|
#include <faiss/VectorTransform.h>
|
|
@@ -170,9 +174,16 @@ static void write_AdditiveQuantizer(const AdditiveQuantizer* aq, IOWriter* f) {
|
|
|
170
174
|
WRITE1(aq->norm_min);
|
|
171
175
|
WRITE1(aq->norm_max);
|
|
172
176
|
if (aq->search_type == AdditiveQuantizer::ST_norm_cqint8 ||
|
|
173
|
-
aq->search_type == AdditiveQuantizer::ST_norm_cqint4
|
|
177
|
+
aq->search_type == AdditiveQuantizer::ST_norm_cqint4 ||
|
|
178
|
+
aq->search_type == AdditiveQuantizer::ST_norm_lsq2x4 ||
|
|
179
|
+
aq->search_type == AdditiveQuantizer::ST_norm_rq2x4) {
|
|
174
180
|
WRITEXBVECTOR(aq->qnorm.codes);
|
|
175
181
|
}
|
|
182
|
+
|
|
183
|
+
if (aq->search_type == AdditiveQuantizer::ST_norm_lsq2x4 ||
|
|
184
|
+
aq->search_type == AdditiveQuantizer::ST_norm_rq2x4) {
|
|
185
|
+
WRITEVECTOR(aq->norm_tabs);
|
|
186
|
+
}
|
|
176
187
|
}
|
|
177
188
|
|
|
178
189
|
static void write_ResidualQuantizer(const ResidualQuantizer* rq, IOWriter* f) {
|
|
@@ -198,6 +209,33 @@ static void write_LocalSearchQuantizer(
|
|
|
198
209
|
WRITE1(lsq->update_codebooks_with_double);
|
|
199
210
|
}
|
|
200
211
|
|
|
212
|
+
static void write_ProductAdditiveQuantizer(
|
|
213
|
+
const ProductAdditiveQuantizer* paq,
|
|
214
|
+
IOWriter* f) {
|
|
215
|
+
write_AdditiveQuantizer(paq, f);
|
|
216
|
+
WRITE1(paq->nsplits);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
static void write_ProductResidualQuantizer(
|
|
220
|
+
const ProductResidualQuantizer* prq,
|
|
221
|
+
IOWriter* f) {
|
|
222
|
+
write_ProductAdditiveQuantizer(prq, f);
|
|
223
|
+
for (const auto aq : prq->quantizers) {
|
|
224
|
+
auto rq = dynamic_cast<const ResidualQuantizer*>(aq);
|
|
225
|
+
write_ResidualQuantizer(rq, f);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
static void write_ProductLocalSearchQuantizer(
|
|
230
|
+
const ProductLocalSearchQuantizer* plsq,
|
|
231
|
+
IOWriter* f) {
|
|
232
|
+
write_ProductAdditiveQuantizer(plsq, f);
|
|
233
|
+
for (const auto aq : plsq->quantizers) {
|
|
234
|
+
auto lsq = dynamic_cast<const LocalSearchQuantizer*>(aq);
|
|
235
|
+
write_LocalSearchQuantizer(lsq, f);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
201
239
|
static void write_ScalarQuantizer(const ScalarQuantizer* ivsc, IOWriter* f) {
|
|
202
240
|
WRITE1(ivsc->qtype);
|
|
203
241
|
WRITE1(ivsc->rangestat);
|
|
@@ -314,6 +352,21 @@ static void write_NSG(const NSG* nsg, IOWriter* f) {
|
|
|
314
352
|
}
|
|
315
353
|
}
|
|
316
354
|
|
|
355
|
+
static void write_NNDescent(const NNDescent* nnd, IOWriter* f) {
|
|
356
|
+
WRITE1(nnd->ntotal);
|
|
357
|
+
WRITE1(nnd->d);
|
|
358
|
+
WRITE1(nnd->K);
|
|
359
|
+
WRITE1(nnd->S);
|
|
360
|
+
WRITE1(nnd->R);
|
|
361
|
+
WRITE1(nnd->L);
|
|
362
|
+
WRITE1(nnd->iter);
|
|
363
|
+
WRITE1(nnd->search_L);
|
|
364
|
+
WRITE1(nnd->random_seed);
|
|
365
|
+
WRITE1(nnd->has_built);
|
|
366
|
+
|
|
367
|
+
WRITEVECTOR(nnd->final_graph);
|
|
368
|
+
}
|
|
369
|
+
|
|
317
370
|
static void write_direct_map(const DirectMap* dm, IOWriter* f) {
|
|
318
371
|
char maintain_direct_map =
|
|
319
372
|
(char)dm->type; // for backwards compatibility with bool
|
|
@@ -385,6 +438,137 @@ void write_index(const Index* idx, IOWriter* f) {
|
|
|
385
438
|
write_LocalSearchQuantizer(&idxr->lsq, f);
|
|
386
439
|
WRITE1(idxr->code_size);
|
|
387
440
|
WRITEVECTOR(idxr->codes);
|
|
441
|
+
} else if (
|
|
442
|
+
const IndexProductResidualQuantizer* idxpr =
|
|
443
|
+
dynamic_cast<const IndexProductResidualQuantizer*>(idx)) {
|
|
444
|
+
uint32_t h = fourcc("IxPR");
|
|
445
|
+
WRITE1(h);
|
|
446
|
+
write_index_header(idx, f);
|
|
447
|
+
write_ProductResidualQuantizer(&idxpr->prq, f);
|
|
448
|
+
WRITE1(idxpr->code_size);
|
|
449
|
+
WRITEVECTOR(idxpr->codes);
|
|
450
|
+
} else if (
|
|
451
|
+
const IndexProductLocalSearchQuantizer* idxpl =
|
|
452
|
+
dynamic_cast<const IndexProductLocalSearchQuantizer*>(
|
|
453
|
+
idx)) {
|
|
454
|
+
uint32_t h = fourcc("IxPL");
|
|
455
|
+
WRITE1(h);
|
|
456
|
+
write_index_header(idx, f);
|
|
457
|
+
write_ProductLocalSearchQuantizer(&idxpl->plsq, f);
|
|
458
|
+
WRITE1(idxpl->code_size);
|
|
459
|
+
WRITEVECTOR(idxpl->codes);
|
|
460
|
+
} else if (
|
|
461
|
+
auto* idxaqfs =
|
|
462
|
+
dynamic_cast<const IndexAdditiveQuantizerFastScan*>(idx)) {
|
|
463
|
+
auto idxlsqfs =
|
|
464
|
+
dynamic_cast<const IndexLocalSearchQuantizerFastScan*>(idx);
|
|
465
|
+
auto idxrqfs = dynamic_cast<const IndexResidualQuantizerFastScan*>(idx);
|
|
466
|
+
auto idxplsqfs =
|
|
467
|
+
dynamic_cast<const IndexProductLocalSearchQuantizerFastScan*>(
|
|
468
|
+
idx);
|
|
469
|
+
auto idxprqfs =
|
|
470
|
+
dynamic_cast<const IndexProductResidualQuantizerFastScan*>(idx);
|
|
471
|
+
FAISS_THROW_IF_NOT(idxlsqfs || idxrqfs || idxplsqfs || idxprqfs);
|
|
472
|
+
|
|
473
|
+
if (idxlsqfs) {
|
|
474
|
+
uint32_t h = fourcc("ILfs");
|
|
475
|
+
WRITE1(h);
|
|
476
|
+
} else if (idxrqfs) {
|
|
477
|
+
uint32_t h = fourcc("IRfs");
|
|
478
|
+
WRITE1(h);
|
|
479
|
+
} else if (idxplsqfs) {
|
|
480
|
+
uint32_t h = fourcc("IPLf");
|
|
481
|
+
WRITE1(h);
|
|
482
|
+
} else if (idxprqfs) {
|
|
483
|
+
uint32_t h = fourcc("IPRf");
|
|
484
|
+
WRITE1(h);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
write_index_header(idxaqfs, f);
|
|
488
|
+
|
|
489
|
+
if (idxlsqfs) {
|
|
490
|
+
write_LocalSearchQuantizer(&idxlsqfs->lsq, f);
|
|
491
|
+
} else if (idxrqfs) {
|
|
492
|
+
write_ResidualQuantizer(&idxrqfs->rq, f);
|
|
493
|
+
} else if (idxplsqfs) {
|
|
494
|
+
write_ProductLocalSearchQuantizer(&idxplsqfs->plsq, f);
|
|
495
|
+
} else if (idxprqfs) {
|
|
496
|
+
write_ProductResidualQuantizer(&idxprqfs->prq, f);
|
|
497
|
+
}
|
|
498
|
+
WRITE1(idxaqfs->implem);
|
|
499
|
+
WRITE1(idxaqfs->bbs);
|
|
500
|
+
WRITE1(idxaqfs->qbs);
|
|
501
|
+
|
|
502
|
+
WRITE1(idxaqfs->M);
|
|
503
|
+
WRITE1(idxaqfs->nbits);
|
|
504
|
+
WRITE1(idxaqfs->ksub);
|
|
505
|
+
WRITE1(idxaqfs->code_size);
|
|
506
|
+
WRITE1(idxaqfs->ntotal2);
|
|
507
|
+
WRITE1(idxaqfs->M2);
|
|
508
|
+
|
|
509
|
+
WRITE1(idxaqfs->rescale_norm);
|
|
510
|
+
WRITE1(idxaqfs->norm_scale);
|
|
511
|
+
WRITE1(idxaqfs->max_train_points);
|
|
512
|
+
|
|
513
|
+
WRITEVECTOR(idxaqfs->codes);
|
|
514
|
+
} else if (
|
|
515
|
+
auto* ivaqfs =
|
|
516
|
+
dynamic_cast<const IndexIVFAdditiveQuantizerFastScan*>(
|
|
517
|
+
idx)) {
|
|
518
|
+
auto ivlsqfs =
|
|
519
|
+
dynamic_cast<const IndexIVFLocalSearchQuantizerFastScan*>(idx);
|
|
520
|
+
auto ivrqfs =
|
|
521
|
+
dynamic_cast<const IndexIVFResidualQuantizerFastScan*>(idx);
|
|
522
|
+
auto ivplsqfs = dynamic_cast<
|
|
523
|
+
const IndexIVFProductLocalSearchQuantizerFastScan*>(idx);
|
|
524
|
+
auto ivprqfs =
|
|
525
|
+
dynamic_cast<const IndexIVFProductResidualQuantizerFastScan*>(
|
|
526
|
+
idx);
|
|
527
|
+
FAISS_THROW_IF_NOT(ivlsqfs || ivrqfs || ivplsqfs || ivprqfs);
|
|
528
|
+
|
|
529
|
+
if (ivlsqfs) {
|
|
530
|
+
uint32_t h = fourcc("IVLf");
|
|
531
|
+
WRITE1(h);
|
|
532
|
+
} else if (ivrqfs) {
|
|
533
|
+
uint32_t h = fourcc("IVRf");
|
|
534
|
+
WRITE1(h);
|
|
535
|
+
} else if (ivplsqfs) {
|
|
536
|
+
uint32_t h = fourcc("NPLf"); // N means IV ...
|
|
537
|
+
WRITE1(h);
|
|
538
|
+
} else {
|
|
539
|
+
uint32_t h = fourcc("NPRf");
|
|
540
|
+
WRITE1(h);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
write_ivf_header(ivaqfs, f);
|
|
544
|
+
|
|
545
|
+
if (ivlsqfs) {
|
|
546
|
+
write_LocalSearchQuantizer(&ivlsqfs->lsq, f);
|
|
547
|
+
} else if (ivrqfs) {
|
|
548
|
+
write_ResidualQuantizer(&ivrqfs->rq, f);
|
|
549
|
+
} else if (ivplsqfs) {
|
|
550
|
+
write_ProductLocalSearchQuantizer(&ivplsqfs->plsq, f);
|
|
551
|
+
} else {
|
|
552
|
+
write_ProductResidualQuantizer(&ivprqfs->prq, f);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
WRITE1(ivaqfs->by_residual);
|
|
556
|
+
WRITE1(ivaqfs->implem);
|
|
557
|
+
WRITE1(ivaqfs->bbs);
|
|
558
|
+
WRITE1(ivaqfs->qbs);
|
|
559
|
+
|
|
560
|
+
WRITE1(ivaqfs->M);
|
|
561
|
+
WRITE1(ivaqfs->nbits);
|
|
562
|
+
WRITE1(ivaqfs->ksub);
|
|
563
|
+
WRITE1(ivaqfs->code_size);
|
|
564
|
+
WRITE1(ivaqfs->qbs2);
|
|
565
|
+
WRITE1(ivaqfs->M2);
|
|
566
|
+
|
|
567
|
+
WRITE1(ivaqfs->rescale_norm);
|
|
568
|
+
WRITE1(ivaqfs->norm_scale);
|
|
569
|
+
WRITE1(ivaqfs->max_train_points);
|
|
570
|
+
|
|
571
|
+
write_InvertedLists(ivaqfs->invlists, f);
|
|
388
572
|
} else if (
|
|
389
573
|
const ResidualCoarseQuantizer* idxr =
|
|
390
574
|
dynamic_cast<const ResidualCoarseQuantizer*>(idx)) {
|
|
@@ -459,14 +643,33 @@ void write_index(const Index* idx, IOWriter* f) {
|
|
|
459
643
|
write_InvertedLists(ivsc->invlists, f);
|
|
460
644
|
} else if (auto iva = dynamic_cast<const IndexIVFAdditiveQuantizer*>(idx)) {
|
|
461
645
|
bool is_LSQ = dynamic_cast<const IndexIVFLocalSearchQuantizer*>(iva);
|
|
462
|
-
|
|
646
|
+
bool is_RQ = dynamic_cast<const IndexIVFResidualQuantizer*>(iva);
|
|
647
|
+
bool is_PLSQ =
|
|
648
|
+
dynamic_cast<const IndexIVFProductLocalSearchQuantizer*>(iva);
|
|
649
|
+
uint32_t h;
|
|
650
|
+
if (is_LSQ) {
|
|
651
|
+
h = fourcc("IwLS");
|
|
652
|
+
} else if (is_RQ) {
|
|
653
|
+
h = fourcc("IwRQ");
|
|
654
|
+
} else if (is_PLSQ) {
|
|
655
|
+
h = fourcc("IwPL");
|
|
656
|
+
} else {
|
|
657
|
+
h = fourcc("IwPR");
|
|
658
|
+
}
|
|
659
|
+
|
|
463
660
|
WRITE1(h);
|
|
464
661
|
write_ivf_header(iva, f);
|
|
465
662
|
WRITE1(iva->code_size);
|
|
466
663
|
if (is_LSQ) {
|
|
467
664
|
write_LocalSearchQuantizer((LocalSearchQuantizer*)iva->aq, f);
|
|
468
|
-
} else {
|
|
665
|
+
} else if (is_RQ) {
|
|
469
666
|
write_ResidualQuantizer((ResidualQuantizer*)iva->aq, f);
|
|
667
|
+
} else if (is_PLSQ) {
|
|
668
|
+
write_ProductLocalSearchQuantizer(
|
|
669
|
+
(ProductLocalSearchQuantizer*)iva->aq, f);
|
|
670
|
+
} else {
|
|
671
|
+
write_ProductResidualQuantizer(
|
|
672
|
+
(ProductResidualQuantizer*)iva->aq, f);
|
|
470
673
|
}
|
|
471
674
|
WRITE1(iva->by_residual);
|
|
472
675
|
WRITE1(iva->use_precomputed_table);
|
|
@@ -546,8 +749,10 @@ void write_index(const Index* idx, IOWriter* f) {
|
|
|
546
749
|
write_HNSW(&idxhnsw->hnsw, f);
|
|
547
750
|
write_index(idxhnsw->storage, f);
|
|
548
751
|
} else if (const IndexNSG* idxnsg = dynamic_cast<const IndexNSG*>(idx)) {
|
|
549
|
-
uint32_t h =
|
|
550
|
-
dynamic_cast<const
|
|
752
|
+
uint32_t h = dynamic_cast<const IndexNSGFlat*>(idx) ? fourcc("INSf")
|
|
753
|
+
: dynamic_cast<const IndexNSGPQ*>(idx) ? fourcc("INSp")
|
|
754
|
+
: dynamic_cast<const IndexNSGSQ*>(idx) ? fourcc("INSs")
|
|
755
|
+
: 0;
|
|
551
756
|
FAISS_THROW_IF_NOT(h != 0);
|
|
552
757
|
WRITE1(h);
|
|
553
758
|
write_index_header(idxnsg, f);
|
|
@@ -559,6 +764,17 @@ void write_index(const Index* idx, IOWriter* f) {
|
|
|
559
764
|
WRITE1(idxnsg->nndescent_iter);
|
|
560
765
|
write_NSG(&idxnsg->nsg, f);
|
|
561
766
|
write_index(idxnsg->storage, f);
|
|
767
|
+
} else if (
|
|
768
|
+
const IndexNNDescent* idxnnd =
|
|
769
|
+
dynamic_cast<const IndexNNDescent*>(idx)) {
|
|
770
|
+
auto idxnndflat = dynamic_cast<const IndexNNDescentFlat*>(idx);
|
|
771
|
+
FAISS_THROW_IF_NOT(idxnndflat != nullptr);
|
|
772
|
+
uint32_t h = fourcc("INNf");
|
|
773
|
+
FAISS_THROW_IF_NOT(h != 0);
|
|
774
|
+
WRITE1(h);
|
|
775
|
+
write_index_header(idxnnd, f);
|
|
776
|
+
write_NNDescent(&idxnnd->nndescent, f);
|
|
777
|
+
write_index(idxnnd->storage, f);
|
|
562
778
|
} else if (
|
|
563
779
|
const IndexPQFastScan* idxpqfs =
|
|
564
780
|
dynamic_cast<const IndexPQFastScan*>(idx)) {
|
|
@@ -586,6 +802,22 @@ void write_index(const Index* idx, IOWriter* f) {
|
|
|
586
802
|
WRITE1(ivpq->qbs2);
|
|
587
803
|
write_ProductQuantizer(&ivpq->pq, f);
|
|
588
804
|
write_InvertedLists(ivpq->invlists, f);
|
|
805
|
+
} else if (
|
|
806
|
+
const IndexRowwiseMinMax* imm =
|
|
807
|
+
dynamic_cast<const IndexRowwiseMinMax*>(idx)) {
|
|
808
|
+
// IndexRowwiseMinmaxFloat
|
|
809
|
+
uint32_t h = fourcc("IRMf");
|
|
810
|
+
WRITE1(h);
|
|
811
|
+
write_index_header(imm, f);
|
|
812
|
+
write_index(imm->index, f);
|
|
813
|
+
} else if (
|
|
814
|
+
const IndexRowwiseMinMaxFP16* imm =
|
|
815
|
+
dynamic_cast<const IndexRowwiseMinMaxFP16*>(idx)) {
|
|
816
|
+
// IndexRowwiseMinmaxHalf
|
|
817
|
+
uint32_t h = fourcc("IRMh");
|
|
818
|
+
WRITE1(h);
|
|
819
|
+
write_index_header(imm, f);
|
|
820
|
+
write_index(imm->index, f);
|
|
589
821
|
} else {
|
|
590
822
|
FAISS_THROW_MSG("don't know how to serialize this type of index");
|
|
591
823
|
}
|