faiss 0.2.0 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/LICENSE.txt +1 -1
- data/README.md +7 -7
- data/ext/faiss/extconf.rb +6 -3
- data/ext/faiss/numo.hpp +4 -4
- data/ext/faiss/utils.cpp +1 -1
- data/ext/faiss/utils.h +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +292 -291
- data/vendor/faiss/faiss/AutoTune.h +55 -56
- data/vendor/faiss/faiss/Clustering.cpp +365 -194
- data/vendor/faiss/faiss/Clustering.h +102 -35
- data/vendor/faiss/faiss/IVFlib.cpp +171 -195
- data/vendor/faiss/faiss/IVFlib.h +48 -51
- data/vendor/faiss/faiss/Index.cpp +85 -103
- data/vendor/faiss/faiss/Index.h +54 -48
- data/vendor/faiss/faiss/Index2Layer.cpp +126 -224
- data/vendor/faiss/faiss/Index2Layer.h +22 -36
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +407 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +195 -0
- data/vendor/faiss/faiss/IndexBinary.cpp +45 -37
- data/vendor/faiss/faiss/IndexBinary.h +140 -132
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +73 -53
- data/vendor/faiss/faiss/IndexBinaryFlat.h +29 -24
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +46 -43
- data/vendor/faiss/faiss/IndexBinaryFromFloat.h +16 -15
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +215 -232
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +25 -24
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +182 -177
- data/vendor/faiss/faiss/IndexBinaryHash.h +41 -34
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +489 -461
- data/vendor/faiss/faiss/IndexBinaryIVF.h +97 -68
- data/vendor/faiss/faiss/IndexFlat.cpp +115 -176
- data/vendor/faiss/faiss/IndexFlat.h +42 -59
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +67 -0
- data/vendor/faiss/faiss/IndexFlatCodes.h +47 -0
- data/vendor/faiss/faiss/IndexHNSW.cpp +372 -348
- data/vendor/faiss/faiss/IndexHNSW.h +57 -41
- data/vendor/faiss/faiss/IndexIVF.cpp +545 -453
- data/vendor/faiss/faiss/IndexIVF.h +169 -118
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +316 -0
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +121 -0
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +247 -252
- data/vendor/faiss/faiss/IndexIVFFlat.h +48 -51
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +459 -517
- data/vendor/faiss/faiss/IndexIVFPQ.h +75 -67
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +406 -372
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +82 -57
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +104 -102
- data/vendor/faiss/faiss/IndexIVFPQR.h +33 -28
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +163 -150
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +38 -25
- data/vendor/faiss/faiss/IndexLSH.cpp +66 -113
- data/vendor/faiss/faiss/IndexLSH.h +20 -38
- data/vendor/faiss/faiss/IndexLattice.cpp +42 -56
- data/vendor/faiss/faiss/IndexLattice.h +11 -16
- data/vendor/faiss/faiss/IndexNNDescent.cpp +229 -0
- data/vendor/faiss/faiss/IndexNNDescent.h +72 -0
- data/vendor/faiss/faiss/IndexNSG.cpp +301 -0
- data/vendor/faiss/faiss/IndexNSG.h +85 -0
- data/vendor/faiss/faiss/IndexPQ.cpp +387 -495
- data/vendor/faiss/faiss/IndexPQ.h +64 -82
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +143 -170
- data/vendor/faiss/faiss/IndexPQFastScan.h +46 -32
- data/vendor/faiss/faiss/IndexPreTransform.cpp +120 -150
- data/vendor/faiss/faiss/IndexPreTransform.h +33 -36
- data/vendor/faiss/faiss/IndexRefine.cpp +139 -127
- data/vendor/faiss/faiss/IndexRefine.h +32 -23
- data/vendor/faiss/faiss/IndexReplicas.cpp +147 -153
- data/vendor/faiss/faiss/IndexReplicas.h +62 -56
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +111 -172
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +41 -59
- data/vendor/faiss/faiss/IndexShards.cpp +256 -240
- data/vendor/faiss/faiss/IndexShards.h +85 -73
- data/vendor/faiss/faiss/MatrixStats.cpp +112 -97
- data/vendor/faiss/faiss/MatrixStats.h +7 -10
- data/vendor/faiss/faiss/MetaIndexes.cpp +135 -157
- data/vendor/faiss/faiss/MetaIndexes.h +40 -34
- data/vendor/faiss/faiss/MetricType.h +7 -7
- data/vendor/faiss/faiss/VectorTransform.cpp +654 -475
- data/vendor/faiss/faiss/VectorTransform.h +64 -89
- data/vendor/faiss/faiss/clone_index.cpp +78 -73
- data/vendor/faiss/faiss/clone_index.h +4 -9
- data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +33 -38
- data/vendor/faiss/faiss/gpu/GpuAutoTune.h +11 -9
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +198 -171
- data/vendor/faiss/faiss/gpu/GpuCloner.h +53 -35
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.cpp +12 -14
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +27 -25
- data/vendor/faiss/faiss/gpu/GpuDistance.h +116 -112
- data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -2
- data/vendor/faiss/faiss/gpu/GpuIcmEncoder.h +60 -0
- data/vendor/faiss/faiss/gpu/GpuIndex.h +134 -137
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +76 -73
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +173 -162
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +67 -64
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +89 -86
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +150 -141
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +101 -103
- data/vendor/faiss/faiss/gpu/GpuIndicesOptions.h +17 -16
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +116 -128
- data/vendor/faiss/faiss/gpu/GpuResources.h +182 -186
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +433 -422
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +131 -130
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +468 -456
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +25 -19
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +22 -20
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +9 -8
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +39 -44
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +16 -14
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +77 -71
- data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +109 -88
- data/vendor/faiss/faiss/gpu/perf/WriteIndex.cpp +75 -64
- data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +230 -215
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +80 -86
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +284 -277
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +416 -416
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +611 -517
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +166 -164
- data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +61 -53
- data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +274 -238
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +73 -57
- data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +47 -50
- data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +79 -72
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +140 -146
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.h +69 -71
- data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +21 -16
- data/vendor/faiss/faiss/gpu/utils/Timer.cpp +25 -29
- data/vendor/faiss/faiss/gpu/utils/Timer.h +30 -29
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +503 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +175 -0
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +90 -120
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +81 -65
- data/vendor/faiss/faiss/impl/FaissAssert.h +73 -58
- data/vendor/faiss/faiss/impl/FaissException.cpp +56 -48
- data/vendor/faiss/faiss/impl/FaissException.h +41 -29
- data/vendor/faiss/faiss/impl/HNSW.cpp +606 -617
- data/vendor/faiss/faiss/impl/HNSW.h +179 -200
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +855 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +244 -0
- data/vendor/faiss/faiss/impl/NNDescent.cpp +487 -0
- data/vendor/faiss/faiss/impl/NNDescent.h +154 -0
- data/vendor/faiss/faiss/impl/NSG.cpp +679 -0
- data/vendor/faiss/faiss/impl/NSG.h +199 -0
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +484 -454
- data/vendor/faiss/faiss/impl/PolysemousTraining.h +52 -55
- data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +26 -47
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +469 -459
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +76 -87
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +758 -0
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +188 -0
- data/vendor/faiss/faiss/impl/ResultHandler.h +96 -132
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +647 -707
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +48 -46
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +129 -131
- data/vendor/faiss/faiss/impl/ThreadedIndex.h +61 -55
- data/vendor/faiss/faiss/impl/index_read.cpp +631 -480
- data/vendor/faiss/faiss/impl/index_write.cpp +547 -407
- data/vendor/faiss/faiss/impl/io.cpp +76 -95
- data/vendor/faiss/faiss/impl/io.h +31 -41
- data/vendor/faiss/faiss/impl/io_macros.h +60 -29
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +301 -0
- data/vendor/faiss/faiss/impl/kmeans1d.h +48 -0
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +137 -186
- data/vendor/faiss/faiss/impl/lattice_Zn.h +40 -51
- data/vendor/faiss/faiss/impl/platform_macros.h +29 -8
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +77 -124
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +39 -48
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +41 -52
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +80 -117
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +109 -137
- data/vendor/faiss/faiss/index_factory.cpp +619 -397
- data/vendor/faiss/faiss/index_factory.h +8 -6
- data/vendor/faiss/faiss/index_io.h +23 -26
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +67 -75
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +22 -24
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +96 -112
- data/vendor/faiss/faiss/invlists/DirectMap.h +29 -33
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +307 -364
- data/vendor/faiss/faiss/invlists/InvertedLists.h +151 -151
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +29 -34
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +17 -18
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +257 -293
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +50 -45
- data/vendor/faiss/faiss/python/python_callbacks.cpp +23 -26
- data/vendor/faiss/faiss/python/python_callbacks.h +9 -16
- data/vendor/faiss/faiss/utils/AlignedTable.h +79 -44
- data/vendor/faiss/faiss/utils/Heap.cpp +40 -48
- data/vendor/faiss/faiss/utils/Heap.h +186 -209
- data/vendor/faiss/faiss/utils/WorkerThread.cpp +67 -76
- data/vendor/faiss/faiss/utils/WorkerThread.h +32 -33
- data/vendor/faiss/faiss/utils/distances.cpp +305 -312
- data/vendor/faiss/faiss/utils/distances.h +170 -122
- data/vendor/faiss/faiss/utils/distances_simd.cpp +498 -508
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +117 -0
- data/vendor/faiss/faiss/utils/extra_distances.cpp +113 -232
- data/vendor/faiss/faiss/utils/extra_distances.h +30 -29
- data/vendor/faiss/faiss/utils/hamming-inl.h +260 -209
- data/vendor/faiss/faiss/utils/hamming.cpp +375 -469
- data/vendor/faiss/faiss/utils/hamming.h +62 -85
- data/vendor/faiss/faiss/utils/ordered_key_value.h +16 -18
- data/vendor/faiss/faiss/utils/partitioning.cpp +393 -318
- data/vendor/faiss/faiss/utils/partitioning.h +26 -21
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +78 -66
- data/vendor/faiss/faiss/utils/quantize_lut.h +22 -20
- data/vendor/faiss/faiss/utils/random.cpp +39 -63
- data/vendor/faiss/faiss/utils/random.h +13 -16
- data/vendor/faiss/faiss/utils/simdlib.h +4 -2
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +88 -85
- data/vendor/faiss/faiss/utils/simdlib_emulated.h +226 -165
- data/vendor/faiss/faiss/utils/simdlib_neon.h +832 -0
- data/vendor/faiss/faiss/utils/utils.cpp +304 -287
- data/vendor/faiss/faiss/utils/utils.h +54 -49
- metadata +29 -4
|
@@ -9,11 +9,14 @@
|
|
|
9
9
|
|
|
10
10
|
#include <faiss/index_io.h>
|
|
11
11
|
|
|
12
|
+
#include <faiss/impl/io.h>
|
|
13
|
+
#include <faiss/impl/io_macros.h>
|
|
14
|
+
|
|
12
15
|
#include <cstdio>
|
|
13
16
|
#include <cstdlib>
|
|
14
17
|
|
|
15
|
-
#include <sys/types.h>
|
|
16
18
|
#include <sys/stat.h>
|
|
19
|
+
#include <sys/types.h>
|
|
17
20
|
|
|
18
21
|
#include <faiss/invlists/InvertedListsIOHook.h>
|
|
19
22
|
|
|
@@ -22,30 +25,33 @@
|
|
|
22
25
|
#include <faiss/impl/io_macros.h>
|
|
23
26
|
#include <faiss/utils/hamming.h>
|
|
24
27
|
|
|
28
|
+
#include <faiss/Index2Layer.h>
|
|
29
|
+
#include <faiss/IndexAdditiveQuantizer.h>
|
|
25
30
|
#include <faiss/IndexFlat.h>
|
|
26
|
-
#include <faiss/
|
|
27
|
-
#include <faiss/IndexPreTransform.h>
|
|
28
|
-
#include <faiss/IndexLSH.h>
|
|
29
|
-
#include <faiss/IndexPQ.h>
|
|
31
|
+
#include <faiss/IndexHNSW.h>
|
|
30
32
|
#include <faiss/IndexIVF.h>
|
|
33
|
+
#include <faiss/IndexIVFAdditiveQuantizer.h>
|
|
34
|
+
#include <faiss/IndexIVFFlat.h>
|
|
31
35
|
#include <faiss/IndexIVFPQ.h>
|
|
36
|
+
#include <faiss/IndexIVFPQFastScan.h>
|
|
32
37
|
#include <faiss/IndexIVFPQR.h>
|
|
33
|
-
#include <faiss/Index2Layer.h>
|
|
34
|
-
#include <faiss/IndexIVFFlat.h>
|
|
35
38
|
#include <faiss/IndexIVFSpectralHash.h>
|
|
36
|
-
#include <faiss/
|
|
37
|
-
#include <faiss/IndexScalarQuantizer.h>
|
|
38
|
-
#include <faiss/IndexHNSW.h>
|
|
39
|
+
#include <faiss/IndexLSH.h>
|
|
39
40
|
#include <faiss/IndexLattice.h>
|
|
41
|
+
#include <faiss/IndexNSG.h>
|
|
42
|
+
#include <faiss/IndexPQ.h>
|
|
40
43
|
#include <faiss/IndexPQFastScan.h>
|
|
41
|
-
#include <faiss/
|
|
44
|
+
#include <faiss/IndexPreTransform.h>
|
|
42
45
|
#include <faiss/IndexRefine.h>
|
|
46
|
+
#include <faiss/IndexScalarQuantizer.h>
|
|
47
|
+
#include <faiss/MetaIndexes.h>
|
|
48
|
+
#include <faiss/VectorTransform.h>
|
|
43
49
|
|
|
44
50
|
#include <faiss/IndexBinaryFlat.h>
|
|
45
51
|
#include <faiss/IndexBinaryFromFloat.h>
|
|
46
52
|
#include <faiss/IndexBinaryHNSW.h>
|
|
47
|
-
#include <faiss/IndexBinaryIVF.h>
|
|
48
53
|
#include <faiss/IndexBinaryHash.h>
|
|
54
|
+
#include <faiss/IndexBinaryIVF.h>
|
|
49
55
|
|
|
50
56
|
/*************************************************************
|
|
51
57
|
* The I/O format is the content of the class. For objects that are
|
|
@@ -68,112 +74,149 @@
|
|
|
68
74
|
|
|
69
75
|
namespace faiss {
|
|
70
76
|
|
|
71
|
-
|
|
72
77
|
/*************************************************************
|
|
73
78
|
* Write
|
|
74
79
|
**************************************************************/
|
|
75
|
-
static void write_index_header
|
|
76
|
-
WRITE1
|
|
77
|
-
WRITE1
|
|
80
|
+
static void write_index_header(const Index* idx, IOWriter* f) {
|
|
81
|
+
WRITE1(idx->d);
|
|
82
|
+
WRITE1(idx->ntotal);
|
|
78
83
|
Index::idx_t dummy = 1 << 20;
|
|
79
|
-
WRITE1
|
|
80
|
-
WRITE1
|
|
81
|
-
WRITE1
|
|
82
|
-
WRITE1
|
|
84
|
+
WRITE1(dummy);
|
|
85
|
+
WRITE1(dummy);
|
|
86
|
+
WRITE1(idx->is_trained);
|
|
87
|
+
WRITE1(idx->metric_type);
|
|
83
88
|
if (idx->metric_type > 1) {
|
|
84
|
-
WRITE1
|
|
89
|
+
WRITE1(idx->metric_arg);
|
|
85
90
|
}
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
void write_VectorTransform
|
|
89
|
-
if (const LinearTransform
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
WRITE1
|
|
98
|
-
WRITE1
|
|
99
|
-
WRITE1
|
|
100
|
-
|
|
101
|
-
WRITEVECTOR
|
|
102
|
-
WRITEVECTOR
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
WRITE1
|
|
108
|
-
WRITE1 (itqm->max_iter);
|
|
109
|
-
WRITE1 (itqm->seed);
|
|
93
|
+
void write_VectorTransform(const VectorTransform* vt, IOWriter* f) {
|
|
94
|
+
if (const LinearTransform* lt = dynamic_cast<const LinearTransform*>(vt)) {
|
|
95
|
+
if (dynamic_cast<const RandomRotationMatrix*>(lt)) {
|
|
96
|
+
uint32_t h = fourcc("rrot");
|
|
97
|
+
WRITE1(h);
|
|
98
|
+
} else if (const PCAMatrix* pca = dynamic_cast<const PCAMatrix*>(lt)) {
|
|
99
|
+
uint32_t h = fourcc("Pcam");
|
|
100
|
+
WRITE1(h);
|
|
101
|
+
WRITE1(pca->eigen_power);
|
|
102
|
+
WRITE1(pca->epsilon);
|
|
103
|
+
WRITE1(pca->random_rotation);
|
|
104
|
+
WRITE1(pca->balanced_bins);
|
|
105
|
+
WRITEVECTOR(pca->mean);
|
|
106
|
+
WRITEVECTOR(pca->eigenvalues);
|
|
107
|
+
WRITEVECTOR(pca->PCAMat);
|
|
108
|
+
} else if (const ITQMatrix* itqm = dynamic_cast<const ITQMatrix*>(lt)) {
|
|
109
|
+
uint32_t h = fourcc("Viqm");
|
|
110
|
+
WRITE1(h);
|
|
111
|
+
WRITE1(itqm->max_iter);
|
|
112
|
+
WRITE1(itqm->seed);
|
|
110
113
|
} else {
|
|
111
114
|
// generic LinearTransform (includes OPQ)
|
|
112
|
-
uint32_t h = fourcc
|
|
113
|
-
WRITE1
|
|
115
|
+
uint32_t h = fourcc("LTra");
|
|
116
|
+
WRITE1(h);
|
|
114
117
|
}
|
|
115
|
-
WRITE1
|
|
116
|
-
WRITEVECTOR
|
|
117
|
-
WRITEVECTOR
|
|
118
|
-
} else if (
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
118
|
+
WRITE1(lt->have_bias);
|
|
119
|
+
WRITEVECTOR(lt->A);
|
|
120
|
+
WRITEVECTOR(lt->b);
|
|
121
|
+
} else if (
|
|
122
|
+
const RemapDimensionsTransform* rdt =
|
|
123
|
+
dynamic_cast<const RemapDimensionsTransform*>(vt)) {
|
|
124
|
+
uint32_t h = fourcc("RmDT");
|
|
125
|
+
WRITE1(h);
|
|
126
|
+
WRITEVECTOR(rdt->map);
|
|
127
|
+
} else if (
|
|
128
|
+
const NormalizationTransform* nt =
|
|
129
|
+
dynamic_cast<const NormalizationTransform*>(vt)) {
|
|
130
|
+
uint32_t h = fourcc("VNrm");
|
|
131
|
+
WRITE1(h);
|
|
132
|
+
WRITE1(nt->norm);
|
|
133
|
+
} else if (
|
|
134
|
+
const CenteringTransform* ct =
|
|
135
|
+
dynamic_cast<const CenteringTransform*>(vt)) {
|
|
136
|
+
uint32_t h = fourcc("VCnt");
|
|
137
|
+
WRITE1(h);
|
|
138
|
+
WRITEVECTOR(ct->mean);
|
|
139
|
+
} else if (
|
|
140
|
+
const ITQTransform* itqt = dynamic_cast<const ITQTransform*>(vt)) {
|
|
141
|
+
uint32_t h = fourcc("Viqt");
|
|
142
|
+
WRITE1(h);
|
|
143
|
+
WRITEVECTOR(itqt->mean);
|
|
144
|
+
WRITE1(itqt->do_pca);
|
|
145
|
+
write_VectorTransform(&itqt->itq, f);
|
|
146
|
+
write_VectorTransform(&itqt->pca_then_itq, f);
|
|
141
147
|
} else {
|
|
142
|
-
FAISS_THROW_MSG
|
|
148
|
+
FAISS_THROW_MSG("cannot serialize this");
|
|
143
149
|
}
|
|
144
150
|
// common fields
|
|
145
|
-
WRITE1
|
|
146
|
-
WRITE1
|
|
147
|
-
WRITE1
|
|
151
|
+
WRITE1(vt->d_in);
|
|
152
|
+
WRITE1(vt->d_out);
|
|
153
|
+
WRITE1(vt->is_trained);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
void write_ProductQuantizer(const ProductQuantizer* pq, IOWriter* f) {
|
|
157
|
+
WRITE1(pq->d);
|
|
158
|
+
WRITE1(pq->M);
|
|
159
|
+
WRITE1(pq->nbits);
|
|
160
|
+
WRITEVECTOR(pq->centroids);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static void write_AdditiveQuantizer(const AdditiveQuantizer* aq, IOWriter* f) {
|
|
164
|
+
WRITE1(aq->d);
|
|
165
|
+
WRITE1(aq->M);
|
|
166
|
+
WRITEVECTOR(aq->nbits);
|
|
167
|
+
WRITE1(aq->is_trained);
|
|
168
|
+
WRITEVECTOR(aq->codebooks);
|
|
169
|
+
WRITE1(aq->search_type);
|
|
170
|
+
WRITE1(aq->norm_min);
|
|
171
|
+
WRITE1(aq->norm_max);
|
|
172
|
+
if (aq->search_type == AdditiveQuantizer::ST_norm_cqint8 ||
|
|
173
|
+
aq->search_type == AdditiveQuantizer::ST_norm_cqint4) {
|
|
174
|
+
WRITEXBVECTOR(aq->qnorm.codes);
|
|
175
|
+
}
|
|
148
176
|
}
|
|
149
177
|
|
|
150
|
-
void
|
|
151
|
-
|
|
152
|
-
WRITE1
|
|
153
|
-
WRITE1
|
|
154
|
-
WRITEVECTOR (pq->centroids);
|
|
178
|
+
static void write_ResidualQuantizer(const ResidualQuantizer* rq, IOWriter* f) {
|
|
179
|
+
write_AdditiveQuantizer(rq, f);
|
|
180
|
+
WRITE1(rq->train_type);
|
|
181
|
+
WRITE1(rq->max_beam_size);
|
|
155
182
|
}
|
|
156
183
|
|
|
157
|
-
static void
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
WRITE1
|
|
162
|
-
WRITE1
|
|
163
|
-
WRITE1
|
|
164
|
-
|
|
184
|
+
static void write_LocalSearchQuantizer(
|
|
185
|
+
const LocalSearchQuantizer* lsq,
|
|
186
|
+
IOWriter* f) {
|
|
187
|
+
write_AdditiveQuantizer(lsq, f);
|
|
188
|
+
WRITE1(lsq->K);
|
|
189
|
+
WRITE1(lsq->train_iters);
|
|
190
|
+
WRITE1(lsq->encode_ils_iters);
|
|
191
|
+
WRITE1(lsq->train_ils_iters);
|
|
192
|
+
WRITE1(lsq->icm_iters);
|
|
193
|
+
WRITE1(lsq->p);
|
|
194
|
+
WRITE1(lsq->lambd);
|
|
195
|
+
WRITE1(lsq->chunk_size);
|
|
196
|
+
WRITE1(lsq->random_seed);
|
|
197
|
+
WRITE1(lsq->nperts);
|
|
198
|
+
WRITE1(lsq->update_codebooks_with_double);
|
|
165
199
|
}
|
|
166
200
|
|
|
167
|
-
void
|
|
201
|
+
static void write_ScalarQuantizer(const ScalarQuantizer* ivsc, IOWriter* f) {
|
|
202
|
+
WRITE1(ivsc->qtype);
|
|
203
|
+
WRITE1(ivsc->rangestat);
|
|
204
|
+
WRITE1(ivsc->rangestat_arg);
|
|
205
|
+
WRITE1(ivsc->d);
|
|
206
|
+
WRITE1(ivsc->code_size);
|
|
207
|
+
WRITEVECTOR(ivsc->trained);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
void write_InvertedLists(const InvertedLists* ils, IOWriter* f) {
|
|
168
211
|
if (ils == nullptr) {
|
|
169
|
-
uint32_t h = fourcc
|
|
170
|
-
WRITE1
|
|
171
|
-
} else if (
|
|
172
|
-
|
|
173
|
-
uint32_t h = fourcc
|
|
174
|
-
WRITE1
|
|
175
|
-
WRITE1
|
|
176
|
-
WRITE1
|
|
212
|
+
uint32_t h = fourcc("il00");
|
|
213
|
+
WRITE1(h);
|
|
214
|
+
} else if (
|
|
215
|
+
const auto& ails = dynamic_cast<const ArrayInvertedLists*>(ils)) {
|
|
216
|
+
uint32_t h = fourcc("ilar");
|
|
217
|
+
WRITE1(h);
|
|
218
|
+
WRITE1(ails->nlist);
|
|
219
|
+
WRITE1(ails->code_size);
|
|
177
220
|
// here we store either as a full or a sparse data buffer
|
|
178
221
|
size_t n_non0 = 0;
|
|
179
222
|
for (size_t i = 0; i < ails->nlist; i++) {
|
|
@@ -182,329 +225,421 @@ void write_InvertedLists (const InvertedLists *ils, IOWriter *f) {
|
|
|
182
225
|
}
|
|
183
226
|
if (n_non0 > ails->nlist / 2) {
|
|
184
227
|
uint32_t list_type = fourcc("full");
|
|
185
|
-
WRITE1
|
|
228
|
+
WRITE1(list_type);
|
|
186
229
|
std::vector<size_t> sizes;
|
|
187
230
|
for (size_t i = 0; i < ails->nlist; i++) {
|
|
188
|
-
sizes.push_back
|
|
231
|
+
sizes.push_back(ails->ids[i].size());
|
|
189
232
|
}
|
|
190
|
-
WRITEVECTOR
|
|
233
|
+
WRITEVECTOR(sizes);
|
|
191
234
|
} else {
|
|
192
235
|
int list_type = fourcc("sprs"); // sparse
|
|
193
|
-
WRITE1
|
|
236
|
+
WRITE1(list_type);
|
|
194
237
|
std::vector<size_t> sizes;
|
|
195
238
|
for (size_t i = 0; i < ails->nlist; i++) {
|
|
196
239
|
size_t n = ails->ids[i].size();
|
|
197
240
|
if (n > 0) {
|
|
198
|
-
sizes.push_back
|
|
199
|
-
sizes.push_back
|
|
241
|
+
sizes.push_back(i);
|
|
242
|
+
sizes.push_back(n);
|
|
200
243
|
}
|
|
201
244
|
}
|
|
202
|
-
WRITEVECTOR
|
|
245
|
+
WRITEVECTOR(sizes);
|
|
203
246
|
}
|
|
204
247
|
// make a single contiguous data buffer (useful for mmapping)
|
|
205
248
|
for (size_t i = 0; i < ails->nlist; i++) {
|
|
206
249
|
size_t n = ails->ids[i].size();
|
|
207
250
|
if (n > 0) {
|
|
208
|
-
WRITEANDCHECK
|
|
209
|
-
WRITEANDCHECK
|
|
251
|
+
WRITEANDCHECK(ails->codes[i].data(), n * ails->code_size);
|
|
252
|
+
WRITEANDCHECK(ails->ids[i].data(), n);
|
|
210
253
|
}
|
|
211
254
|
}
|
|
212
255
|
|
|
213
256
|
} else {
|
|
214
|
-
InvertedListsIOHook::lookup_classname(
|
|
215
|
-
|
|
257
|
+
InvertedListsIOHook::lookup_classname(typeid(*ils).name())
|
|
258
|
+
->write(ils, f);
|
|
216
259
|
}
|
|
217
260
|
}
|
|
218
261
|
|
|
219
|
-
|
|
220
|
-
void write_ProductQuantizer (const ProductQuantizer*pq, const char *fname) {
|
|
262
|
+
void write_ProductQuantizer(const ProductQuantizer* pq, const char* fname) {
|
|
221
263
|
FileIOWriter writer(fname);
|
|
222
|
-
write_ProductQuantizer
|
|
264
|
+
write_ProductQuantizer(pq, &writer);
|
|
223
265
|
}
|
|
224
266
|
|
|
225
|
-
static void write_HNSW
|
|
267
|
+
static void write_HNSW(const HNSW* hnsw, IOWriter* f) {
|
|
268
|
+
WRITEVECTOR(hnsw->assign_probas);
|
|
269
|
+
WRITEVECTOR(hnsw->cum_nneighbor_per_level);
|
|
270
|
+
WRITEVECTOR(hnsw->levels);
|
|
271
|
+
WRITEVECTOR(hnsw->offsets);
|
|
272
|
+
WRITEVECTOR(hnsw->neighbors);
|
|
273
|
+
|
|
274
|
+
WRITE1(hnsw->entry_point);
|
|
275
|
+
WRITE1(hnsw->max_level);
|
|
276
|
+
WRITE1(hnsw->efConstruction);
|
|
277
|
+
WRITE1(hnsw->efSearch);
|
|
278
|
+
WRITE1(hnsw->upper_beam);
|
|
279
|
+
}
|
|
226
280
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
281
|
+
static void write_NSG(const NSG* nsg, IOWriter* f) {
|
|
282
|
+
WRITE1(nsg->ntotal);
|
|
283
|
+
WRITE1(nsg->R);
|
|
284
|
+
WRITE1(nsg->L);
|
|
285
|
+
WRITE1(nsg->C);
|
|
286
|
+
WRITE1(nsg->search_L);
|
|
287
|
+
WRITE1(nsg->enterpoint);
|
|
288
|
+
WRITE1(nsg->is_built);
|
|
289
|
+
|
|
290
|
+
if (!nsg->is_built) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
232
293
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
294
|
+
constexpr int EMPTY_ID = -1;
|
|
295
|
+
auto& graph = nsg->final_graph;
|
|
296
|
+
int K = graph->K;
|
|
297
|
+
int N = graph->N;
|
|
298
|
+
FAISS_THROW_IF_NOT(N == nsg->ntotal);
|
|
299
|
+
FAISS_THROW_IF_NOT(K == nsg->R);
|
|
300
|
+
FAISS_THROW_IF_NOT(true == graph->own_fields);
|
|
301
|
+
|
|
302
|
+
int size = 0;
|
|
303
|
+
for (int i = 0; i < N; i++) {
|
|
304
|
+
for (int j = 0; j < K; j++) {
|
|
305
|
+
int id = graph->at(i, j);
|
|
306
|
+
if (id != EMPTY_ID) {
|
|
307
|
+
WRITE1(id);
|
|
308
|
+
size += 1;
|
|
309
|
+
} else {
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
WRITE1(EMPTY_ID);
|
|
314
|
+
}
|
|
238
315
|
}
|
|
239
316
|
|
|
240
|
-
static void write_direct_map
|
|
241
|
-
char maintain_direct_map =
|
|
242
|
-
|
|
243
|
-
|
|
317
|
+
static void write_direct_map(const DirectMap* dm, IOWriter* f) {
|
|
318
|
+
char maintain_direct_map =
|
|
319
|
+
(char)dm->type; // for backwards compatibility with bool
|
|
320
|
+
WRITE1(maintain_direct_map);
|
|
321
|
+
WRITEVECTOR(dm->array);
|
|
244
322
|
if (dm->type == DirectMap::Hashtable) {
|
|
245
323
|
using idx_t = Index::idx_t;
|
|
246
324
|
std::vector<std::pair<idx_t, idx_t>> v;
|
|
247
|
-
const std::unordered_map<idx_t, idx_t
|
|
248
|
-
v.resize
|
|
325
|
+
const std::unordered_map<idx_t, idx_t>& map = dm->hashtable;
|
|
326
|
+
v.resize(map.size());
|
|
249
327
|
std::copy(map.begin(), map.end(), v.begin());
|
|
250
|
-
WRITEVECTOR
|
|
328
|
+
WRITEVECTOR(v);
|
|
251
329
|
}
|
|
252
330
|
}
|
|
253
331
|
|
|
254
|
-
static void write_ivf_header
|
|
255
|
-
write_index_header
|
|
256
|
-
WRITE1
|
|
257
|
-
WRITE1
|
|
258
|
-
write_index
|
|
259
|
-
write_direct_map
|
|
332
|
+
static void write_ivf_header(const IndexIVF* ivf, IOWriter* f) {
|
|
333
|
+
write_index_header(ivf, f);
|
|
334
|
+
WRITE1(ivf->nlist);
|
|
335
|
+
WRITE1(ivf->nprobe);
|
|
336
|
+
write_index(ivf->quantizer, f);
|
|
337
|
+
write_direct_map(&ivf->direct_map, f);
|
|
260
338
|
}
|
|
261
339
|
|
|
262
|
-
void write_index
|
|
263
|
-
if (const IndexFlat
|
|
264
|
-
uint32_t h =
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
WRITE1
|
|
276
|
-
WRITE1
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
340
|
+
void write_index(const Index* idx, IOWriter* f) {
|
|
341
|
+
if (const IndexFlat* idxf = dynamic_cast<const IndexFlat*>(idx)) {
|
|
342
|
+
uint32_t h =
|
|
343
|
+
fourcc(idxf->metric_type == METRIC_INNER_PRODUCT ? "IxFI"
|
|
344
|
+
: idxf->metric_type == METRIC_L2 ? "IxF2"
|
|
345
|
+
: "IxFl");
|
|
346
|
+
WRITE1(h);
|
|
347
|
+
write_index_header(idx, f);
|
|
348
|
+
WRITEXBVECTOR(idxf->codes);
|
|
349
|
+
} else if (const IndexLSH* idxl = dynamic_cast<const IndexLSH*>(idx)) {
|
|
350
|
+
uint32_t h = fourcc("IxHe");
|
|
351
|
+
WRITE1(h);
|
|
352
|
+
write_index_header(idx, f);
|
|
353
|
+
WRITE1(idxl->nbits);
|
|
354
|
+
WRITE1(idxl->rotate_data);
|
|
355
|
+
WRITE1(idxl->train_thresholds);
|
|
356
|
+
WRITEVECTOR(idxl->thresholds);
|
|
357
|
+
int code_size_i = idxl->code_size;
|
|
358
|
+
WRITE1(code_size_i);
|
|
359
|
+
write_VectorTransform(&idxl->rrot, f);
|
|
360
|
+
WRITEVECTOR(idxl->codes);
|
|
361
|
+
} else if (const IndexPQ* idxp = dynamic_cast<const IndexPQ*>(idx)) {
|
|
362
|
+
uint32_t h = fourcc("IxPq");
|
|
363
|
+
WRITE1(h);
|
|
364
|
+
write_index_header(idx, f);
|
|
365
|
+
write_ProductQuantizer(&idxp->pq, f);
|
|
366
|
+
WRITEVECTOR(idxp->codes);
|
|
287
367
|
// search params -- maybe not useful to store?
|
|
288
|
-
WRITE1
|
|
289
|
-
WRITE1
|
|
290
|
-
WRITE1
|
|
291
|
-
} else if(
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
WRITE1
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
WRITE1
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
368
|
+
WRITE1(idxp->search_type);
|
|
369
|
+
WRITE1(idxp->encode_signs);
|
|
370
|
+
WRITE1(idxp->polysemous_ht);
|
|
371
|
+
} else if (
|
|
372
|
+
const IndexResidualQuantizer* idxr =
|
|
373
|
+
dynamic_cast<const IndexResidualQuantizer*>(idx)) {
|
|
374
|
+
uint32_t h = fourcc("IxRq");
|
|
375
|
+
WRITE1(h);
|
|
376
|
+
write_index_header(idx, f);
|
|
377
|
+
write_ResidualQuantizer(&idxr->rq, f);
|
|
378
|
+
WRITE1(idxr->code_size);
|
|
379
|
+
WRITEVECTOR(idxr->codes);
|
|
380
|
+
} else if (
|
|
381
|
+
auto* idxr = dynamic_cast<const IndexLocalSearchQuantizer*>(idx)) {
|
|
382
|
+
uint32_t h = fourcc("IxLS");
|
|
383
|
+
WRITE1(h);
|
|
384
|
+
write_index_header(idx, f);
|
|
385
|
+
write_LocalSearchQuantizer(&idxr->lsq, f);
|
|
386
|
+
WRITE1(idxr->code_size);
|
|
387
|
+
WRITEVECTOR(idxr->codes);
|
|
388
|
+
} else if (
|
|
389
|
+
const ResidualCoarseQuantizer* idxr =
|
|
390
|
+
dynamic_cast<const ResidualCoarseQuantizer*>(idx)) {
|
|
391
|
+
uint32_t h = fourcc("ImRQ");
|
|
392
|
+
WRITE1(h);
|
|
393
|
+
write_index_header(idx, f);
|
|
394
|
+
write_ResidualQuantizer(&idxr->rq, f);
|
|
395
|
+
WRITE1(idxr->beam_factor);
|
|
396
|
+
} else if (
|
|
397
|
+
const Index2Layer* idxp = dynamic_cast<const Index2Layer*>(idx)) {
|
|
398
|
+
uint32_t h = fourcc("Ix2L");
|
|
399
|
+
WRITE1(h);
|
|
400
|
+
write_index_header(idx, f);
|
|
401
|
+
write_index(idxp->q1.quantizer, f);
|
|
402
|
+
WRITE1(idxp->q1.nlist);
|
|
403
|
+
WRITE1(idxp->q1.quantizer_trains_alone);
|
|
404
|
+
write_ProductQuantizer(&idxp->pq, f);
|
|
405
|
+
WRITE1(idxp->code_size_1);
|
|
406
|
+
WRITE1(idxp->code_size_2);
|
|
407
|
+
WRITE1(idxp->code_size);
|
|
408
|
+
WRITEVECTOR(idxp->codes);
|
|
409
|
+
} else if (
|
|
410
|
+
const IndexScalarQuantizer* idxs =
|
|
411
|
+
dynamic_cast<const IndexScalarQuantizer*>(idx)) {
|
|
412
|
+
uint32_t h = fourcc("IxSQ");
|
|
413
|
+
WRITE1(h);
|
|
414
|
+
write_index_header(idx, f);
|
|
415
|
+
write_ScalarQuantizer(&idxs->sq, f);
|
|
416
|
+
WRITEVECTOR(idxs->codes);
|
|
417
|
+
} else if (
|
|
418
|
+
const IndexLattice* idxl = dynamic_cast<const IndexLattice*>(idx)) {
|
|
419
|
+
uint32_t h = fourcc("IxLa");
|
|
420
|
+
WRITE1(h);
|
|
421
|
+
WRITE1(idxl->d);
|
|
422
|
+
WRITE1(idxl->nsq);
|
|
423
|
+
WRITE1(idxl->scale_nbit);
|
|
424
|
+
WRITE1(idxl->zn_sphere_codec.r2);
|
|
425
|
+
write_index_header(idx, f);
|
|
426
|
+
WRITEVECTOR(idxl->trained);
|
|
427
|
+
} else if (
|
|
428
|
+
const IndexIVFFlatDedup* ivfl =
|
|
429
|
+
dynamic_cast<const IndexIVFFlatDedup*>(idx)) {
|
|
430
|
+
uint32_t h = fourcc("IwFd");
|
|
431
|
+
WRITE1(h);
|
|
432
|
+
write_ivf_header(ivfl, f);
|
|
326
433
|
{
|
|
327
|
-
std::vector<Index::idx_t> tab
|
|
434
|
+
std::vector<Index::idx_t> tab(2 * ivfl->instances.size());
|
|
328
435
|
long i = 0;
|
|
329
|
-
for (auto it = ivfl->instances.begin();
|
|
330
|
-
|
|
436
|
+
for (auto it = ivfl->instances.begin(); it != ivfl->instances.end();
|
|
437
|
+
++it) {
|
|
331
438
|
tab[i++] = it->first;
|
|
332
439
|
tab[i++] = it->second;
|
|
333
440
|
}
|
|
334
|
-
WRITEVECTOR
|
|
441
|
+
WRITEVECTOR(tab);
|
|
335
442
|
}
|
|
336
|
-
write_InvertedLists
|
|
337
|
-
} else if(
|
|
338
|
-
|
|
339
|
-
uint32_t h = fourcc
|
|
340
|
-
WRITE1
|
|
341
|
-
write_ivf_header
|
|
342
|
-
write_InvertedLists
|
|
343
|
-
} else if(
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
WRITE1
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
WRITE1
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
WRITE1
|
|
372
|
-
|
|
373
|
-
|
|
443
|
+
write_InvertedLists(ivfl->invlists, f);
|
|
444
|
+
} else if (
|
|
445
|
+
const IndexIVFFlat* ivfl = dynamic_cast<const IndexIVFFlat*>(idx)) {
|
|
446
|
+
uint32_t h = fourcc("IwFl");
|
|
447
|
+
WRITE1(h);
|
|
448
|
+
write_ivf_header(ivfl, f);
|
|
449
|
+
write_InvertedLists(ivfl->invlists, f);
|
|
450
|
+
} else if (
|
|
451
|
+
const IndexIVFScalarQuantizer* ivsc =
|
|
452
|
+
dynamic_cast<const IndexIVFScalarQuantizer*>(idx)) {
|
|
453
|
+
uint32_t h = fourcc("IwSq");
|
|
454
|
+
WRITE1(h);
|
|
455
|
+
write_ivf_header(ivsc, f);
|
|
456
|
+
write_ScalarQuantizer(&ivsc->sq, f);
|
|
457
|
+
WRITE1(ivsc->code_size);
|
|
458
|
+
WRITE1(ivsc->by_residual);
|
|
459
|
+
write_InvertedLists(ivsc->invlists, f);
|
|
460
|
+
} else if (auto iva = dynamic_cast<const IndexIVFAdditiveQuantizer*>(idx)) {
|
|
461
|
+
bool is_LSQ = dynamic_cast<const IndexIVFLocalSearchQuantizer*>(iva);
|
|
462
|
+
uint32_t h = fourcc(is_LSQ ? "IwLS" : "IwRQ");
|
|
463
|
+
WRITE1(h);
|
|
464
|
+
write_ivf_header(iva, f);
|
|
465
|
+
WRITE1(iva->code_size);
|
|
466
|
+
if (is_LSQ) {
|
|
467
|
+
write_LocalSearchQuantizer((LocalSearchQuantizer*)iva->aq, f);
|
|
468
|
+
} else {
|
|
469
|
+
write_ResidualQuantizer((ResidualQuantizer*)iva->aq, f);
|
|
470
|
+
}
|
|
471
|
+
WRITE1(iva->by_residual);
|
|
472
|
+
WRITE1(iva->use_precomputed_table);
|
|
473
|
+
write_InvertedLists(iva->invlists, f);
|
|
474
|
+
} else if (
|
|
475
|
+
const IndexIVFSpectralHash* ivsp =
|
|
476
|
+
dynamic_cast<const IndexIVFSpectralHash*>(idx)) {
|
|
477
|
+
uint32_t h = fourcc("IwSh");
|
|
478
|
+
WRITE1(h);
|
|
479
|
+
write_ivf_header(ivsp, f);
|
|
480
|
+
write_VectorTransform(ivsp->vt, f);
|
|
481
|
+
WRITE1(ivsp->nbit);
|
|
482
|
+
WRITE1(ivsp->period);
|
|
483
|
+
WRITE1(ivsp->threshold_type);
|
|
484
|
+
WRITEVECTOR(ivsp->trained);
|
|
485
|
+
write_InvertedLists(ivsp->invlists, f);
|
|
486
|
+
} else if (const IndexIVFPQ* ivpq = dynamic_cast<const IndexIVFPQ*>(idx)) {
|
|
487
|
+
const IndexIVFPQR* ivfpqr = dynamic_cast<const IndexIVFPQR*>(idx);
|
|
488
|
+
|
|
489
|
+
uint32_t h = fourcc(ivfpqr ? "IwQR" : "IwPQ");
|
|
490
|
+
WRITE1(h);
|
|
491
|
+
write_ivf_header(ivpq, f);
|
|
492
|
+
WRITE1(ivpq->by_residual);
|
|
493
|
+
WRITE1(ivpq->code_size);
|
|
494
|
+
write_ProductQuantizer(&ivpq->pq, f);
|
|
495
|
+
write_InvertedLists(ivpq->invlists, f);
|
|
374
496
|
if (ivfpqr) {
|
|
375
|
-
write_ProductQuantizer
|
|
376
|
-
WRITEVECTOR
|
|
377
|
-
WRITE1
|
|
497
|
+
write_ProductQuantizer(&ivfpqr->refine_pq, f);
|
|
498
|
+
WRITEVECTOR(ivfpqr->refine_codes);
|
|
499
|
+
WRITE1(ivfpqr->k_factor);
|
|
378
500
|
}
|
|
379
501
|
|
|
380
|
-
} else if(
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
502
|
+
} else if (
|
|
503
|
+
const IndexPreTransform* ixpt =
|
|
504
|
+
dynamic_cast<const IndexPreTransform*>(idx)) {
|
|
505
|
+
uint32_t h = fourcc("IxPT");
|
|
506
|
+
WRITE1(h);
|
|
507
|
+
write_index_header(ixpt, f);
|
|
385
508
|
int nt = ixpt->chain.size();
|
|
386
|
-
WRITE1
|
|
509
|
+
WRITE1(nt);
|
|
387
510
|
for (int i = 0; i < nt; i++)
|
|
388
|
-
write_VectorTransform
|
|
389
|
-
write_index
|
|
390
|
-
} else if(
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
write_index
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
511
|
+
write_VectorTransform(ixpt->chain[i], f);
|
|
512
|
+
write_index(ixpt->index, f);
|
|
513
|
+
} else if (
|
|
514
|
+
const MultiIndexQuantizer* imiq =
|
|
515
|
+
dynamic_cast<const MultiIndexQuantizer*>(idx)) {
|
|
516
|
+
uint32_t h = fourcc("Imiq");
|
|
517
|
+
WRITE1(h);
|
|
518
|
+
write_index_header(imiq, f);
|
|
519
|
+
write_ProductQuantizer(&imiq->pq, f);
|
|
520
|
+
} else if (
|
|
521
|
+
const IndexRefine* idxrf = dynamic_cast<const IndexRefine*>(idx)) {
|
|
522
|
+
uint32_t h = fourcc("IxRF");
|
|
523
|
+
WRITE1(h);
|
|
524
|
+
write_index_header(idxrf, f);
|
|
525
|
+
write_index(idxrf->base_index, f);
|
|
526
|
+
write_index(idxrf->refine_index, f);
|
|
527
|
+
WRITE1(idxrf->k_factor);
|
|
528
|
+
} else if (
|
|
529
|
+
const IndexIDMap* idxmap = dynamic_cast<const IndexIDMap*>(idx)) {
|
|
530
|
+
uint32_t h = dynamic_cast<const IndexIDMap2*>(idx) ? fourcc("IxM2")
|
|
531
|
+
: fourcc("IxMp");
|
|
409
532
|
// no need to store additional info for IndexIDMap2
|
|
410
|
-
WRITE1
|
|
411
|
-
write_index_header
|
|
412
|
-
write_index
|
|
413
|
-
WRITEVECTOR
|
|
414
|
-
} else if(const IndexHNSW
|
|
415
|
-
|
|
533
|
+
WRITE1(h);
|
|
534
|
+
write_index_header(idxmap, f);
|
|
535
|
+
write_index(idxmap->index, f);
|
|
536
|
+
WRITEVECTOR(idxmap->id_map);
|
|
537
|
+
} else if (const IndexHNSW* idxhnsw = dynamic_cast<const IndexHNSW*>(idx)) {
|
|
538
|
+
uint32_t h = dynamic_cast<const IndexHNSWFlat*>(idx) ? fourcc("IHNf")
|
|
539
|
+
: dynamic_cast<const IndexHNSWPQ*>(idx) ? fourcc("IHNp")
|
|
540
|
+
: dynamic_cast<const IndexHNSWSQ*>(idx) ? fourcc("IHNs")
|
|
541
|
+
: dynamic_cast<const IndexHNSW2Level*>(idx) ? fourcc("IHN2")
|
|
542
|
+
: 0;
|
|
543
|
+
FAISS_THROW_IF_NOT(h != 0);
|
|
544
|
+
WRITE1(h);
|
|
545
|
+
write_index_header(idxhnsw, f);
|
|
546
|
+
write_HNSW(&idxhnsw->hnsw, f);
|
|
547
|
+
write_index(idxhnsw->storage, f);
|
|
548
|
+
} else if (const IndexNSG* idxnsg = dynamic_cast<const IndexNSG*>(idx)) {
|
|
416
549
|
uint32_t h =
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
WRITE1
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
550
|
+
dynamic_cast<const IndexNSGFlat*>(idx) ? fourcc("INSf") : 0;
|
|
551
|
+
FAISS_THROW_IF_NOT(h != 0);
|
|
552
|
+
WRITE1(h);
|
|
553
|
+
write_index_header(idxnsg, f);
|
|
554
|
+
WRITE1(idxnsg->GK);
|
|
555
|
+
WRITE1(idxnsg->build_type);
|
|
556
|
+
WRITE1(idxnsg->nndescent_S);
|
|
557
|
+
WRITE1(idxnsg->nndescent_R);
|
|
558
|
+
WRITE1(idxnsg->nndescent_L);
|
|
559
|
+
WRITE1(idxnsg->nndescent_iter);
|
|
560
|
+
write_NSG(&idxnsg->nsg, f);
|
|
561
|
+
write_index(idxnsg->storage, f);
|
|
562
|
+
} else if (
|
|
563
|
+
const IndexPQFastScan* idxpqfs =
|
|
564
|
+
dynamic_cast<const IndexPQFastScan*>(idx)) {
|
|
429
565
|
uint32_t h = fourcc("IPfs");
|
|
430
|
-
WRITE1
|
|
431
|
-
write_index_header
|
|
432
|
-
write_ProductQuantizer
|
|
433
|
-
WRITE1
|
|
434
|
-
WRITE1
|
|
435
|
-
WRITE1
|
|
436
|
-
WRITE1
|
|
437
|
-
WRITE1
|
|
438
|
-
WRITEVECTOR
|
|
439
|
-
} else if (
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
WRITE1
|
|
446
|
-
WRITE1
|
|
447
|
-
WRITE1
|
|
448
|
-
WRITE1
|
|
449
|
-
WRITE1
|
|
450
|
-
|
|
451
|
-
|
|
566
|
+
WRITE1(h);
|
|
567
|
+
write_index_header(idxpqfs, f);
|
|
568
|
+
write_ProductQuantizer(&idxpqfs->pq, f);
|
|
569
|
+
WRITE1(idxpqfs->implem);
|
|
570
|
+
WRITE1(idxpqfs->bbs);
|
|
571
|
+
WRITE1(idxpqfs->qbs);
|
|
572
|
+
WRITE1(idxpqfs->ntotal2);
|
|
573
|
+
WRITE1(idxpqfs->M2);
|
|
574
|
+
WRITEVECTOR(idxpqfs->codes);
|
|
575
|
+
} else if (
|
|
576
|
+
const IndexIVFPQFastScan* ivpq =
|
|
577
|
+
dynamic_cast<const IndexIVFPQFastScan*>(idx)) {
|
|
578
|
+
uint32_t h = fourcc("IwPf");
|
|
579
|
+
WRITE1(h);
|
|
580
|
+
write_ivf_header(ivpq, f);
|
|
581
|
+
WRITE1(ivpq->by_residual);
|
|
582
|
+
WRITE1(ivpq->code_size);
|
|
583
|
+
WRITE1(ivpq->bbs);
|
|
584
|
+
WRITE1(ivpq->M2);
|
|
585
|
+
WRITE1(ivpq->implem);
|
|
586
|
+
WRITE1(ivpq->qbs2);
|
|
587
|
+
write_ProductQuantizer(&ivpq->pq, f);
|
|
588
|
+
write_InvertedLists(ivpq->invlists, f);
|
|
452
589
|
} else {
|
|
453
|
-
FAISS_THROW_MSG
|
|
590
|
+
FAISS_THROW_MSG("don't know how to serialize this type of index");
|
|
454
591
|
}
|
|
455
592
|
}
|
|
456
593
|
|
|
457
|
-
void write_index
|
|
594
|
+
void write_index(const Index* idx, FILE* f) {
|
|
458
595
|
FileIOWriter writer(f);
|
|
459
|
-
write_index
|
|
596
|
+
write_index(idx, &writer);
|
|
460
597
|
}
|
|
461
598
|
|
|
462
|
-
void write_index
|
|
599
|
+
void write_index(const Index* idx, const char* fname) {
|
|
463
600
|
FileIOWriter writer(fname);
|
|
464
|
-
write_index
|
|
601
|
+
write_index(idx, &writer);
|
|
465
602
|
}
|
|
466
603
|
|
|
467
|
-
void write_VectorTransform
|
|
604
|
+
void write_VectorTransform(const VectorTransform* vt, const char* fname) {
|
|
468
605
|
FileIOWriter writer(fname);
|
|
469
|
-
write_VectorTransform
|
|
606
|
+
write_VectorTransform(vt, &writer);
|
|
470
607
|
}
|
|
471
608
|
|
|
472
|
-
|
|
473
609
|
/*************************************************************
|
|
474
610
|
* Write binary indexes
|
|
475
611
|
**************************************************************/
|
|
476
612
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
WRITE1
|
|
480
|
-
WRITE1
|
|
481
|
-
WRITE1
|
|
482
|
-
WRITE1
|
|
483
|
-
WRITE1 (idx->metric_type);
|
|
613
|
+
static void write_index_binary_header(const IndexBinary* idx, IOWriter* f) {
|
|
614
|
+
WRITE1(idx->d);
|
|
615
|
+
WRITE1(idx->code_size);
|
|
616
|
+
WRITE1(idx->ntotal);
|
|
617
|
+
WRITE1(idx->is_trained);
|
|
618
|
+
WRITE1(idx->metric_type);
|
|
484
619
|
}
|
|
485
620
|
|
|
486
|
-
static void write_binary_ivf_header
|
|
487
|
-
write_index_binary_header
|
|
488
|
-
WRITE1
|
|
489
|
-
WRITE1
|
|
490
|
-
write_index_binary
|
|
491
|
-
write_direct_map
|
|
621
|
+
static void write_binary_ivf_header(const IndexBinaryIVF* ivf, IOWriter* f) {
|
|
622
|
+
write_index_binary_header(ivf, f);
|
|
623
|
+
WRITE1(ivf->nlist);
|
|
624
|
+
WRITE1(ivf->nprobe);
|
|
625
|
+
write_index_binary(ivf->quantizer, f);
|
|
626
|
+
write_direct_map(&ivf->direct_map, f);
|
|
492
627
|
}
|
|
493
628
|
|
|
494
|
-
static void write_binary_hash_invlists
|
|
495
|
-
const IndexBinaryHash::InvertedListMap
|
|
496
|
-
int b,
|
|
497
|
-
{
|
|
629
|
+
static void write_binary_hash_invlists(
|
|
630
|
+
const IndexBinaryHash::InvertedListMap& invlists,
|
|
631
|
+
int b,
|
|
632
|
+
IOWriter* f) {
|
|
498
633
|
size_t sz = invlists.size();
|
|
499
|
-
WRITE1
|
|
634
|
+
WRITE1(sz);
|
|
500
635
|
size_t maxil = 0;
|
|
501
636
|
for (auto it = invlists.begin(); it != invlists.end(); ++it) {
|
|
502
|
-
if(it->second.ids.size() > maxil) {
|
|
637
|
+
if (it->second.ids.size() > maxil) {
|
|
503
638
|
maxil = it->second.ids.size();
|
|
504
639
|
}
|
|
505
640
|
}
|
|
506
641
|
int il_nbit = 0;
|
|
507
|
-
while(maxil >= ((uint64_t)1 << il_nbit)) {
|
|
642
|
+
while (maxil >= ((uint64_t)1 << il_nbit)) {
|
|
508
643
|
il_nbit++;
|
|
509
644
|
}
|
|
510
645
|
WRITE1(il_nbit);
|
|
@@ -513,25 +648,25 @@ static void write_binary_hash_invlists (
|
|
|
513
648
|
// memmap it at some point
|
|
514
649
|
|
|
515
650
|
// buffer for bitstrings
|
|
516
|
-
std::vector<uint8_t> buf
|
|
517
|
-
BitstringWriter wr
|
|
651
|
+
std::vector<uint8_t> buf(((b + il_nbit) * sz + 7) / 8);
|
|
652
|
+
BitstringWriter wr(buf.data(), buf.size());
|
|
518
653
|
for (auto it = invlists.begin(); it != invlists.end(); ++it) {
|
|
519
|
-
wr.write
|
|
520
|
-
wr.write
|
|
654
|
+
wr.write(it->first, b);
|
|
655
|
+
wr.write(it->second.ids.size(), il_nbit);
|
|
521
656
|
}
|
|
522
|
-
WRITEVECTOR
|
|
657
|
+
WRITEVECTOR(buf);
|
|
523
658
|
|
|
524
659
|
for (auto it = invlists.begin(); it != invlists.end(); ++it) {
|
|
525
|
-
WRITEVECTOR
|
|
526
|
-
WRITEVECTOR
|
|
660
|
+
WRITEVECTOR(it->second.ids);
|
|
661
|
+
WRITEVECTOR(it->second.vecs);
|
|
527
662
|
}
|
|
528
663
|
}
|
|
529
664
|
|
|
530
665
|
static void write_binary_multi_hash_map(
|
|
531
|
-
const IndexBinaryMultiHash::Map
|
|
532
|
-
int b,
|
|
533
|
-
|
|
534
|
-
{
|
|
666
|
+
const IndexBinaryMultiHash::Map& map,
|
|
667
|
+
int b,
|
|
668
|
+
size_t ntotal,
|
|
669
|
+
IOWriter* f) {
|
|
535
670
|
int id_bits = 0;
|
|
536
671
|
while ((ntotal > ((Index::idx_t)1 << id_bits))) {
|
|
537
672
|
id_bits++;
|
|
@@ -541,7 +676,7 @@ static void write_binary_multi_hash_map(
|
|
|
541
676
|
WRITE1(sz);
|
|
542
677
|
size_t nbit = (b + id_bits) * sz + ntotal * id_bits;
|
|
543
678
|
std::vector<uint8_t> buf((nbit + 7) / 8);
|
|
544
|
-
BitstringWriter wr
|
|
679
|
+
BitstringWriter wr(buf.data(), buf.size());
|
|
545
680
|
for (auto it = map.begin(); it != map.end(); ++it) {
|
|
546
681
|
wr.write(it->first, b);
|
|
547
682
|
wr.write(it->second.size(), id_bits);
|
|
@@ -549,80 +684,85 @@ static void write_binary_multi_hash_map(
|
|
|
549
684
|
wr.write(id, id_bits);
|
|
550
685
|
}
|
|
551
686
|
}
|
|
552
|
-
WRITEVECTOR
|
|
687
|
+
WRITEVECTOR(buf);
|
|
553
688
|
}
|
|
554
689
|
|
|
555
|
-
void write_index_binary
|
|
556
|
-
if (const IndexBinaryFlat
|
|
557
|
-
|
|
558
|
-
uint32_t h = fourcc
|
|
559
|
-
WRITE1
|
|
560
|
-
write_index_binary_header
|
|
561
|
-
WRITEVECTOR
|
|
562
|
-
} else if (
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
690
|
+
void write_index_binary(const IndexBinary* idx, IOWriter* f) {
|
|
691
|
+
if (const IndexBinaryFlat* idxf =
|
|
692
|
+
dynamic_cast<const IndexBinaryFlat*>(idx)) {
|
|
693
|
+
uint32_t h = fourcc("IBxF");
|
|
694
|
+
WRITE1(h);
|
|
695
|
+
write_index_binary_header(idx, f);
|
|
696
|
+
WRITEVECTOR(idxf->xb);
|
|
697
|
+
} else if (
|
|
698
|
+
const IndexBinaryIVF* ivf =
|
|
699
|
+
dynamic_cast<const IndexBinaryIVF*>(idx)) {
|
|
700
|
+
uint32_t h = fourcc("IBwF");
|
|
701
|
+
WRITE1(h);
|
|
702
|
+
write_binary_ivf_header(ivf, f);
|
|
703
|
+
write_InvertedLists(ivf->invlists, f);
|
|
704
|
+
} else if (
|
|
705
|
+
const IndexBinaryFromFloat* idxff =
|
|
706
|
+
dynamic_cast<const IndexBinaryFromFloat*>(idx)) {
|
|
707
|
+
uint32_t h = fourcc("IBFf");
|
|
708
|
+
WRITE1(h);
|
|
709
|
+
write_index_binary_header(idxff, f);
|
|
710
|
+
write_index(idxff->index, f);
|
|
711
|
+
} else if (
|
|
712
|
+
const IndexBinaryHNSW* idxhnsw =
|
|
713
|
+
dynamic_cast<const IndexBinaryHNSW*>(idx)) {
|
|
714
|
+
uint32_t h = fourcc("IBHf");
|
|
715
|
+
WRITE1(h);
|
|
716
|
+
write_index_binary_header(idxhnsw, f);
|
|
717
|
+
write_HNSW(&idxhnsw->hnsw, f);
|
|
718
|
+
write_index_binary(idxhnsw->storage, f);
|
|
719
|
+
} else if (
|
|
720
|
+
const IndexBinaryIDMap* idxmap =
|
|
721
|
+
dynamic_cast<const IndexBinaryIDMap*>(idx)) {
|
|
722
|
+
uint32_t h = dynamic_cast<const IndexBinaryIDMap2*>(idx)
|
|
723
|
+
? fourcc("IBM2")
|
|
724
|
+
: fourcc("IBMp");
|
|
586
725
|
// no need to store additional info for IndexIDMap2
|
|
587
|
-
WRITE1
|
|
588
|
-
write_index_binary_header
|
|
589
|
-
write_index_binary
|
|
590
|
-
WRITEVECTOR
|
|
591
|
-
} else if (
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
WRITE1
|
|
726
|
+
WRITE1(h);
|
|
727
|
+
write_index_binary_header(idxmap, f);
|
|
728
|
+
write_index_binary(idxmap->index, f);
|
|
729
|
+
WRITEVECTOR(idxmap->id_map);
|
|
730
|
+
} else if (
|
|
731
|
+
const IndexBinaryHash* idxh =
|
|
732
|
+
dynamic_cast<const IndexBinaryHash*>(idx)) {
|
|
733
|
+
uint32_t h = fourcc("IBHh");
|
|
734
|
+
WRITE1(h);
|
|
735
|
+
write_index_binary_header(idxh, f);
|
|
736
|
+
WRITE1(idxh->b);
|
|
737
|
+
WRITE1(idxh->nflip);
|
|
598
738
|
write_binary_hash_invlists(idxh->invlists, idxh->b, f);
|
|
599
|
-
} else if (
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
WRITE1
|
|
607
|
-
WRITE1
|
|
739
|
+
} else if (
|
|
740
|
+
const IndexBinaryMultiHash* idxmh =
|
|
741
|
+
dynamic_cast<const IndexBinaryMultiHash*>(idx)) {
|
|
742
|
+
uint32_t h = fourcc("IBHm");
|
|
743
|
+
WRITE1(h);
|
|
744
|
+
write_index_binary_header(idxmh, f);
|
|
745
|
+
write_index_binary(idxmh->storage, f);
|
|
746
|
+
WRITE1(idxmh->b);
|
|
747
|
+
WRITE1(idxmh->nhash);
|
|
748
|
+
WRITE1(idxmh->nflip);
|
|
608
749
|
for (int i = 0; i < idxmh->nhash; i++) {
|
|
609
750
|
write_binary_multi_hash_map(
|
|
610
751
|
idxmh->maps[i], idxmh->b, idxmh->ntotal, f);
|
|
611
752
|
}
|
|
612
753
|
} else {
|
|
613
|
-
FAISS_THROW_MSG
|
|
754
|
+
FAISS_THROW_MSG("don't know how to serialize this type of index");
|
|
614
755
|
}
|
|
615
756
|
}
|
|
616
757
|
|
|
617
|
-
void write_index_binary
|
|
758
|
+
void write_index_binary(const IndexBinary* idx, FILE* f) {
|
|
618
759
|
FileIOWriter writer(f);
|
|
619
760
|
write_index_binary(idx, &writer);
|
|
620
761
|
}
|
|
621
762
|
|
|
622
|
-
void write_index_binary
|
|
763
|
+
void write_index_binary(const IndexBinary* idx, const char* fname) {
|
|
623
764
|
FileIOWriter writer(fname);
|
|
624
|
-
write_index_binary
|
|
765
|
+
write_index_binary(idx, &writer);
|
|
625
766
|
}
|
|
626
767
|
|
|
627
|
-
|
|
628
768
|
} // namespace faiss
|