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.
Files changed (215) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +7 -7
  5. data/ext/faiss/extconf.rb +6 -3
  6. data/ext/faiss/numo.hpp +4 -4
  7. data/ext/faiss/utils.cpp +1 -1
  8. data/ext/faiss/utils.h +1 -1
  9. data/lib/faiss/version.rb +1 -1
  10. data/vendor/faiss/faiss/AutoTune.cpp +292 -291
  11. data/vendor/faiss/faiss/AutoTune.h +55 -56
  12. data/vendor/faiss/faiss/Clustering.cpp +365 -194
  13. data/vendor/faiss/faiss/Clustering.h +102 -35
  14. data/vendor/faiss/faiss/IVFlib.cpp +171 -195
  15. data/vendor/faiss/faiss/IVFlib.h +48 -51
  16. data/vendor/faiss/faiss/Index.cpp +85 -103
  17. data/vendor/faiss/faiss/Index.h +54 -48
  18. data/vendor/faiss/faiss/Index2Layer.cpp +126 -224
  19. data/vendor/faiss/faiss/Index2Layer.h +22 -36
  20. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +407 -0
  21. data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +195 -0
  22. data/vendor/faiss/faiss/IndexBinary.cpp +45 -37
  23. data/vendor/faiss/faiss/IndexBinary.h +140 -132
  24. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +73 -53
  25. data/vendor/faiss/faiss/IndexBinaryFlat.h +29 -24
  26. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +46 -43
  27. data/vendor/faiss/faiss/IndexBinaryFromFloat.h +16 -15
  28. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +215 -232
  29. data/vendor/faiss/faiss/IndexBinaryHNSW.h +25 -24
  30. data/vendor/faiss/faiss/IndexBinaryHash.cpp +182 -177
  31. data/vendor/faiss/faiss/IndexBinaryHash.h +41 -34
  32. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +489 -461
  33. data/vendor/faiss/faiss/IndexBinaryIVF.h +97 -68
  34. data/vendor/faiss/faiss/IndexFlat.cpp +115 -176
  35. data/vendor/faiss/faiss/IndexFlat.h +42 -59
  36. data/vendor/faiss/faiss/IndexFlatCodes.cpp +67 -0
  37. data/vendor/faiss/faiss/IndexFlatCodes.h +47 -0
  38. data/vendor/faiss/faiss/IndexHNSW.cpp +372 -348
  39. data/vendor/faiss/faiss/IndexHNSW.h +57 -41
  40. data/vendor/faiss/faiss/IndexIVF.cpp +545 -453
  41. data/vendor/faiss/faiss/IndexIVF.h +169 -118
  42. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +316 -0
  43. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +121 -0
  44. data/vendor/faiss/faiss/IndexIVFFlat.cpp +247 -252
  45. data/vendor/faiss/faiss/IndexIVFFlat.h +48 -51
  46. data/vendor/faiss/faiss/IndexIVFPQ.cpp +459 -517
  47. data/vendor/faiss/faiss/IndexIVFPQ.h +75 -67
  48. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +406 -372
  49. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +82 -57
  50. data/vendor/faiss/faiss/IndexIVFPQR.cpp +104 -102
  51. data/vendor/faiss/faiss/IndexIVFPQR.h +33 -28
  52. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +163 -150
  53. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +38 -25
  54. data/vendor/faiss/faiss/IndexLSH.cpp +66 -113
  55. data/vendor/faiss/faiss/IndexLSH.h +20 -38
  56. data/vendor/faiss/faiss/IndexLattice.cpp +42 -56
  57. data/vendor/faiss/faiss/IndexLattice.h +11 -16
  58. data/vendor/faiss/faiss/IndexNNDescent.cpp +229 -0
  59. data/vendor/faiss/faiss/IndexNNDescent.h +72 -0
  60. data/vendor/faiss/faiss/IndexNSG.cpp +301 -0
  61. data/vendor/faiss/faiss/IndexNSG.h +85 -0
  62. data/vendor/faiss/faiss/IndexPQ.cpp +387 -495
  63. data/vendor/faiss/faiss/IndexPQ.h +64 -82
  64. data/vendor/faiss/faiss/IndexPQFastScan.cpp +143 -170
  65. data/vendor/faiss/faiss/IndexPQFastScan.h +46 -32
  66. data/vendor/faiss/faiss/IndexPreTransform.cpp +120 -150
  67. data/vendor/faiss/faiss/IndexPreTransform.h +33 -36
  68. data/vendor/faiss/faiss/IndexRefine.cpp +139 -127
  69. data/vendor/faiss/faiss/IndexRefine.h +32 -23
  70. data/vendor/faiss/faiss/IndexReplicas.cpp +147 -153
  71. data/vendor/faiss/faiss/IndexReplicas.h +62 -56
  72. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +111 -172
  73. data/vendor/faiss/faiss/IndexScalarQuantizer.h +41 -59
  74. data/vendor/faiss/faiss/IndexShards.cpp +256 -240
  75. data/vendor/faiss/faiss/IndexShards.h +85 -73
  76. data/vendor/faiss/faiss/MatrixStats.cpp +112 -97
  77. data/vendor/faiss/faiss/MatrixStats.h +7 -10
  78. data/vendor/faiss/faiss/MetaIndexes.cpp +135 -157
  79. data/vendor/faiss/faiss/MetaIndexes.h +40 -34
  80. data/vendor/faiss/faiss/MetricType.h +7 -7
  81. data/vendor/faiss/faiss/VectorTransform.cpp +654 -475
  82. data/vendor/faiss/faiss/VectorTransform.h +64 -89
  83. data/vendor/faiss/faiss/clone_index.cpp +78 -73
  84. data/vendor/faiss/faiss/clone_index.h +4 -9
  85. data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +33 -38
  86. data/vendor/faiss/faiss/gpu/GpuAutoTune.h +11 -9
  87. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +198 -171
  88. data/vendor/faiss/faiss/gpu/GpuCloner.h +53 -35
  89. data/vendor/faiss/faiss/gpu/GpuClonerOptions.cpp +12 -14
  90. data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +27 -25
  91. data/vendor/faiss/faiss/gpu/GpuDistance.h +116 -112
  92. data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -2
  93. data/vendor/faiss/faiss/gpu/GpuIcmEncoder.h +60 -0
  94. data/vendor/faiss/faiss/gpu/GpuIndex.h +134 -137
  95. data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +76 -73
  96. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +173 -162
  97. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +67 -64
  98. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +89 -86
  99. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +150 -141
  100. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +101 -103
  101. data/vendor/faiss/faiss/gpu/GpuIndicesOptions.h +17 -16
  102. data/vendor/faiss/faiss/gpu/GpuResources.cpp +116 -128
  103. data/vendor/faiss/faiss/gpu/GpuResources.h +182 -186
  104. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +433 -422
  105. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +131 -130
  106. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +468 -456
  107. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +25 -19
  108. data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +22 -20
  109. data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +9 -8
  110. data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +39 -44
  111. data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +16 -14
  112. data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +77 -71
  113. data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +109 -88
  114. data/vendor/faiss/faiss/gpu/perf/WriteIndex.cpp +75 -64
  115. data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +230 -215
  116. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +80 -86
  117. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +284 -277
  118. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +416 -416
  119. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +611 -517
  120. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +166 -164
  121. data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +61 -53
  122. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +274 -238
  123. data/vendor/faiss/faiss/gpu/test/TestUtils.h +73 -57
  124. data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +47 -50
  125. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +79 -72
  126. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +140 -146
  127. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.h +69 -71
  128. data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +21 -16
  129. data/vendor/faiss/faiss/gpu/utils/Timer.cpp +25 -29
  130. data/vendor/faiss/faiss/gpu/utils/Timer.h +30 -29
  131. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +503 -0
  132. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +175 -0
  133. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +90 -120
  134. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +81 -65
  135. data/vendor/faiss/faiss/impl/FaissAssert.h +73 -58
  136. data/vendor/faiss/faiss/impl/FaissException.cpp +56 -48
  137. data/vendor/faiss/faiss/impl/FaissException.h +41 -29
  138. data/vendor/faiss/faiss/impl/HNSW.cpp +606 -617
  139. data/vendor/faiss/faiss/impl/HNSW.h +179 -200
  140. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +855 -0
  141. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +244 -0
  142. data/vendor/faiss/faiss/impl/NNDescent.cpp +487 -0
  143. data/vendor/faiss/faiss/impl/NNDescent.h +154 -0
  144. data/vendor/faiss/faiss/impl/NSG.cpp +679 -0
  145. data/vendor/faiss/faiss/impl/NSG.h +199 -0
  146. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +484 -454
  147. data/vendor/faiss/faiss/impl/PolysemousTraining.h +52 -55
  148. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +26 -47
  149. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +469 -459
  150. data/vendor/faiss/faiss/impl/ProductQuantizer.h +76 -87
  151. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +758 -0
  152. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +188 -0
  153. data/vendor/faiss/faiss/impl/ResultHandler.h +96 -132
  154. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +647 -707
  155. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +48 -46
  156. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +129 -131
  157. data/vendor/faiss/faiss/impl/ThreadedIndex.h +61 -55
  158. data/vendor/faiss/faiss/impl/index_read.cpp +631 -480
  159. data/vendor/faiss/faiss/impl/index_write.cpp +547 -407
  160. data/vendor/faiss/faiss/impl/io.cpp +76 -95
  161. data/vendor/faiss/faiss/impl/io.h +31 -41
  162. data/vendor/faiss/faiss/impl/io_macros.h +60 -29
  163. data/vendor/faiss/faiss/impl/kmeans1d.cpp +301 -0
  164. data/vendor/faiss/faiss/impl/kmeans1d.h +48 -0
  165. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +137 -186
  166. data/vendor/faiss/faiss/impl/lattice_Zn.h +40 -51
  167. data/vendor/faiss/faiss/impl/platform_macros.h +29 -8
  168. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +77 -124
  169. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +39 -48
  170. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +41 -52
  171. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +80 -117
  172. data/vendor/faiss/faiss/impl/simd_result_handlers.h +109 -137
  173. data/vendor/faiss/faiss/index_factory.cpp +619 -397
  174. data/vendor/faiss/faiss/index_factory.h +8 -6
  175. data/vendor/faiss/faiss/index_io.h +23 -26
  176. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +67 -75
  177. data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +22 -24
  178. data/vendor/faiss/faiss/invlists/DirectMap.cpp +96 -112
  179. data/vendor/faiss/faiss/invlists/DirectMap.h +29 -33
  180. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +307 -364
  181. data/vendor/faiss/faiss/invlists/InvertedLists.h +151 -151
  182. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +29 -34
  183. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +17 -18
  184. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +257 -293
  185. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +50 -45
  186. data/vendor/faiss/faiss/python/python_callbacks.cpp +23 -26
  187. data/vendor/faiss/faiss/python/python_callbacks.h +9 -16
  188. data/vendor/faiss/faiss/utils/AlignedTable.h +79 -44
  189. data/vendor/faiss/faiss/utils/Heap.cpp +40 -48
  190. data/vendor/faiss/faiss/utils/Heap.h +186 -209
  191. data/vendor/faiss/faiss/utils/WorkerThread.cpp +67 -76
  192. data/vendor/faiss/faiss/utils/WorkerThread.h +32 -33
  193. data/vendor/faiss/faiss/utils/distances.cpp +305 -312
  194. data/vendor/faiss/faiss/utils/distances.h +170 -122
  195. data/vendor/faiss/faiss/utils/distances_simd.cpp +498 -508
  196. data/vendor/faiss/faiss/utils/extra_distances-inl.h +117 -0
  197. data/vendor/faiss/faiss/utils/extra_distances.cpp +113 -232
  198. data/vendor/faiss/faiss/utils/extra_distances.h +30 -29
  199. data/vendor/faiss/faiss/utils/hamming-inl.h +260 -209
  200. data/vendor/faiss/faiss/utils/hamming.cpp +375 -469
  201. data/vendor/faiss/faiss/utils/hamming.h +62 -85
  202. data/vendor/faiss/faiss/utils/ordered_key_value.h +16 -18
  203. data/vendor/faiss/faiss/utils/partitioning.cpp +393 -318
  204. data/vendor/faiss/faiss/utils/partitioning.h +26 -21
  205. data/vendor/faiss/faiss/utils/quantize_lut.cpp +78 -66
  206. data/vendor/faiss/faiss/utils/quantize_lut.h +22 -20
  207. data/vendor/faiss/faiss/utils/random.cpp +39 -63
  208. data/vendor/faiss/faiss/utils/random.h +13 -16
  209. data/vendor/faiss/faiss/utils/simdlib.h +4 -2
  210. data/vendor/faiss/faiss/utils/simdlib_avx2.h +88 -85
  211. data/vendor/faiss/faiss/utils/simdlib_emulated.h +226 -165
  212. data/vendor/faiss/faiss/utils/simdlib_neon.h +832 -0
  213. data/vendor/faiss/faiss/utils/utils.cpp +304 -287
  214. data/vendor/faiss/faiss/utils/utils.h +54 -49
  215. 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/VectorTransform.h>
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/MetaIndexes.h>
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/IndexIVFPQFastScan.h>
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 (const Index *idx, IOWriter *f) {
76
- WRITE1 (idx->d);
77
- WRITE1 (idx->ntotal);
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 (dummy);
80
- WRITE1 (dummy);
81
- WRITE1 (idx->is_trained);
82
- WRITE1 (idx->metric_type);
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 (idx->metric_arg);
89
+ WRITE1(idx->metric_arg);
85
90
  }
86
91
  }
87
92
 
88
- void write_VectorTransform (const VectorTransform *vt, IOWriter *f) {
89
- if (const LinearTransform * lt =
90
- dynamic_cast < const LinearTransform *> (vt)) {
91
- if (dynamic_cast<const RandomRotationMatrix *>(lt)) {
92
- uint32_t h = fourcc ("rrot");
93
- WRITE1 (h);
94
- } else if (const PCAMatrix * pca =
95
- dynamic_cast<const PCAMatrix *>(lt)) {
96
- uint32_t h = fourcc ("PcAm");
97
- WRITE1 (h);
98
- WRITE1 (pca->eigen_power);
99
- WRITE1 (pca->random_rotation);
100
- WRITE1 (pca->balanced_bins);
101
- WRITEVECTOR (pca->mean);
102
- WRITEVECTOR (pca->eigenvalues);
103
- WRITEVECTOR (pca->PCAMat);
104
- } else if (const ITQMatrix * itqm =
105
- dynamic_cast<const ITQMatrix *>(lt)) {
106
- uint32_t h = fourcc ("Viqm");
107
- WRITE1 (h);
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 ("LTra");
113
- WRITE1 (h);
115
+ uint32_t h = fourcc("LTra");
116
+ WRITE1(h);
114
117
  }
115
- WRITE1 (lt->have_bias);
116
- WRITEVECTOR (lt->A);
117
- WRITEVECTOR (lt->b);
118
- } else if (const RemapDimensionsTransform *rdt =
119
- dynamic_cast<const RemapDimensionsTransform *>(vt)) {
120
- uint32_t h = fourcc ("RmDT");
121
- WRITE1 (h);
122
- WRITEVECTOR (rdt->map);
123
- } else if (const NormalizationTransform *nt =
124
- dynamic_cast<const NormalizationTransform *>(vt)) {
125
- uint32_t h = fourcc ("VNrm");
126
- WRITE1 (h);
127
- WRITE1 (nt->norm);
128
- } else if (const CenteringTransform *ct =
129
- dynamic_cast<const CenteringTransform *>(vt)) {
130
- uint32_t h = fourcc ("VCnt");
131
- WRITE1 (h);
132
- WRITEVECTOR (ct->mean);
133
- } else if (const ITQTransform *itqt =
134
- dynamic_cast<const ITQTransform*> (vt)) {
135
- uint32_t h = fourcc ("Viqt");
136
- WRITE1 (h);
137
- WRITEVECTOR (itqt->mean);
138
- WRITE1 (itqt->do_pca);
139
- write_VectorTransform (&itqt->itq, f);
140
- write_VectorTransform (&itqt->pca_then_itq, f);
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 ("cannot serialize this");
148
+ FAISS_THROW_MSG("cannot serialize this");
143
149
  }
144
150
  // common fields
145
- WRITE1 (vt->d_in);
146
- WRITE1 (vt->d_out);
147
- WRITE1 (vt->is_trained);
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 write_ProductQuantizer (const ProductQuantizer *pq, IOWriter *f) {
151
- WRITE1 (pq->d);
152
- WRITE1 (pq->M);
153
- WRITE1 (pq->nbits);
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 write_ScalarQuantizer (
158
- const ScalarQuantizer *ivsc, IOWriter *f) {
159
- WRITE1 (ivsc->qtype);
160
- WRITE1 (ivsc->rangestat);
161
- WRITE1 (ivsc->rangestat_arg);
162
- WRITE1 (ivsc->d);
163
- WRITE1 (ivsc->code_size);
164
- WRITEVECTOR (ivsc->trained);
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 write_InvertedLists (const InvertedLists *ils, IOWriter *f) {
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 ("il00");
170
- WRITE1 (h);
171
- } else if (const auto & ails =
172
- dynamic_cast<const ArrayInvertedLists *>(ils)) {
173
- uint32_t h = fourcc ("ilar");
174
- WRITE1 (h);
175
- WRITE1 (ails->nlist);
176
- WRITE1 (ails->code_size);
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 (list_type);
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 (ails->ids[i].size());
231
+ sizes.push_back(ails->ids[i].size());
189
232
  }
190
- WRITEVECTOR (sizes);
233
+ WRITEVECTOR(sizes);
191
234
  } else {
192
235
  int list_type = fourcc("sprs"); // sparse
193
- WRITE1 (list_type);
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 (i);
199
- sizes.push_back (n);
241
+ sizes.push_back(i);
242
+ sizes.push_back(n);
200
243
  }
201
244
  }
202
- WRITEVECTOR (sizes);
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 (ails->codes[i].data(), n * ails->code_size);
209
- WRITEANDCHECK (ails->ids[i].data(), n);
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
- typeid(*ils).name())->write(ils, f);
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 (pq, &writer);
264
+ write_ProductQuantizer(pq, &writer);
223
265
  }
224
266
 
225
- static void write_HNSW (const HNSW *hnsw, IOWriter *f) {
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
- WRITEVECTOR (hnsw->assign_probas);
228
- WRITEVECTOR (hnsw->cum_nneighbor_per_level);
229
- WRITEVECTOR (hnsw->levels);
230
- WRITEVECTOR (hnsw->offsets);
231
- WRITEVECTOR (hnsw->neighbors);
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
- WRITE1 (hnsw->entry_point);
234
- WRITE1 (hnsw->max_level);
235
- WRITE1 (hnsw->efConstruction);
236
- WRITE1 (hnsw->efSearch);
237
- WRITE1 (hnsw->upper_beam);
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 (const DirectMap *dm, IOWriter *f) {
241
- char maintain_direct_map = (char)dm->type; // for backwards compatibility with bool
242
- WRITE1 (maintain_direct_map);
243
- WRITEVECTOR (dm->array);
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> & map = dm->hashtable;
248
- v.resize (map.size());
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 (v);
328
+ WRITEVECTOR(v);
251
329
  }
252
330
  }
253
331
 
254
- static void write_ivf_header (const IndexIVF *ivf, IOWriter *f) {
255
- write_index_header (ivf, f);
256
- WRITE1 (ivf->nlist);
257
- WRITE1 (ivf->nprobe);
258
- write_index (ivf->quantizer, f);
259
- write_direct_map (&ivf->direct_map, f);
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 (const Index *idx, IOWriter *f) {
263
- if (const IndexFlat * idxf = dynamic_cast<const IndexFlat *> (idx)) {
264
- uint32_t h = fourcc (
265
- idxf->metric_type == METRIC_INNER_PRODUCT ? "IxFI" :
266
- idxf->metric_type == METRIC_L2 ? "IxF2" : "IxFl");
267
- WRITE1 (h);
268
- write_index_header (idx, f);
269
- WRITEVECTOR (idxf->xb);
270
- } else if(const IndexLSH * idxl = dynamic_cast<const IndexLSH *> (idx)) {
271
- uint32_t h = fourcc ("IxHe");
272
- WRITE1 (h);
273
- write_index_header (idx, f);
274
- WRITE1 (idxl->nbits);
275
- WRITE1 (idxl->rotate_data);
276
- WRITE1 (idxl->train_thresholds);
277
- WRITEVECTOR (idxl->thresholds);
278
- WRITE1 (idxl->bytes_per_vec);
279
- write_VectorTransform (&idxl->rrot, f);
280
- WRITEVECTOR (idxl->codes);
281
- } else if(const IndexPQ * idxp = dynamic_cast<const IndexPQ *> (idx)) {
282
- uint32_t h = fourcc ("IxPq");
283
- WRITE1 (h);
284
- write_index_header (idx, f);
285
- write_ProductQuantizer (&idxp->pq, f);
286
- WRITEVECTOR (idxp->codes);
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 (idxp->search_type);
289
- WRITE1 (idxp->encode_signs);
290
- WRITE1 (idxp->polysemous_ht);
291
- } else if(const Index2Layer * idxp =
292
- dynamic_cast<const Index2Layer *> (idx)) {
293
- uint32_t h = fourcc ("Ix2L");
294
- WRITE1 (h);
295
- write_index_header (idx, f);
296
- write_index (idxp->q1.quantizer, f);
297
- WRITE1 (idxp->q1.nlist);
298
- WRITE1 (idxp->q1.quantizer_trains_alone);
299
- write_ProductQuantizer (&idxp->pq, f);
300
- WRITE1 (idxp->code_size_1);
301
- WRITE1 (idxp->code_size_2);
302
- WRITE1 (idxp->code_size);
303
- WRITEVECTOR (idxp->codes);
304
- } else if(const IndexScalarQuantizer * idxs =
305
- dynamic_cast<const IndexScalarQuantizer *> (idx)) {
306
- uint32_t h = fourcc ("IxSQ");
307
- WRITE1 (h);
308
- write_index_header (idx, f);
309
- write_ScalarQuantizer (&idxs->sq, f);
310
- WRITEVECTOR (idxs->codes);
311
- } else if(const IndexLattice * idxl =
312
- dynamic_cast<const IndexLattice *> (idx)) {
313
- uint32_t h = fourcc ("IxLa");
314
- WRITE1 (h);
315
- WRITE1 (idxl->d);
316
- WRITE1 (idxl->nsq);
317
- WRITE1 (idxl->scale_nbit);
318
- WRITE1 (idxl->zn_sphere_codec.r2);
319
- write_index_header (idx, f);
320
- WRITEVECTOR (idxl->trained);
321
- } else if(const IndexIVFFlatDedup * ivfl =
322
- dynamic_cast<const IndexIVFFlatDedup *> (idx)) {
323
- uint32_t h = fourcc ("IwFd");
324
- WRITE1 (h);
325
- write_ivf_header (ivfl, f);
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 (2 * ivfl->instances.size());
434
+ std::vector<Index::idx_t> tab(2 * ivfl->instances.size());
328
435
  long i = 0;
329
- for (auto it = ivfl->instances.begin();
330
- it != ivfl->instances.end(); ++it) {
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 (tab);
441
+ WRITEVECTOR(tab);
335
442
  }
336
- write_InvertedLists (ivfl->invlists, f);
337
- } else if(const IndexIVFFlat * ivfl =
338
- dynamic_cast<const IndexIVFFlat *> (idx)) {
339
- uint32_t h = fourcc ("IwFl");
340
- WRITE1 (h);
341
- write_ivf_header (ivfl, f);
342
- write_InvertedLists (ivfl->invlists, f);
343
- } else if(const IndexIVFScalarQuantizer * ivsc =
344
- dynamic_cast<const IndexIVFScalarQuantizer *> (idx)) {
345
- uint32_t h = fourcc ("IwSq");
346
- WRITE1 (h);
347
- write_ivf_header (ivsc, f);
348
- write_ScalarQuantizer (&ivsc->sq, f);
349
- WRITE1 (ivsc->code_size);
350
- WRITE1 (ivsc->by_residual);
351
- write_InvertedLists (ivsc->invlists, f);
352
- } else if(const IndexIVFSpectralHash *ivsp =
353
- dynamic_cast<const IndexIVFSpectralHash *>(idx)) {
354
- uint32_t h = fourcc ("IwSh");
355
- WRITE1 (h);
356
- write_ivf_header (ivsp, f);
357
- write_VectorTransform (ivsp->vt, f);
358
- WRITE1 (ivsp->nbit);
359
- WRITE1 (ivsp->period);
360
- WRITE1 (ivsp->threshold_type);
361
- WRITEVECTOR (ivsp->trained);
362
- write_InvertedLists (ivsp->invlists, f);
363
- } else if(const IndexIVFPQ * ivpq =
364
- dynamic_cast<const IndexIVFPQ *> (idx)) {
365
- const IndexIVFPQR * ivfpqr = dynamic_cast<const IndexIVFPQR *> (idx);
366
-
367
- uint32_t h = fourcc (ivfpqr ? "IwQR" : "IwPQ");
368
- WRITE1 (h);
369
- write_ivf_header (ivpq, f);
370
- WRITE1 (ivpq->by_residual);
371
- WRITE1 (ivpq->code_size);
372
- write_ProductQuantizer (&ivpq->pq, f);
373
- write_InvertedLists (ivpq->invlists, f);
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 (&ivfpqr->refine_pq, f);
376
- WRITEVECTOR (ivfpqr->refine_codes);
377
- WRITE1 (ivfpqr->k_factor);
497
+ write_ProductQuantizer(&ivfpqr->refine_pq, f);
498
+ WRITEVECTOR(ivfpqr->refine_codes);
499
+ WRITE1(ivfpqr->k_factor);
378
500
  }
379
501
 
380
- } else if(const IndexPreTransform * ixpt =
381
- dynamic_cast<const IndexPreTransform *> (idx)) {
382
- uint32_t h = fourcc ("IxPT");
383
- WRITE1 (h);
384
- write_index_header (ixpt, f);
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 (nt);
509
+ WRITE1(nt);
387
510
  for (int i = 0; i < nt; i++)
388
- write_VectorTransform (ixpt->chain[i], f);
389
- write_index (ixpt->index, f);
390
- } else if(const MultiIndexQuantizer * imiq =
391
- dynamic_cast<const MultiIndexQuantizer *> (idx)) {
392
- uint32_t h = fourcc ("Imiq");
393
- WRITE1 (h);
394
- write_index_header (imiq, f);
395
- write_ProductQuantizer (&imiq->pq, f);
396
- } else if(const IndexRefine * idxrf =
397
- dynamic_cast<const IndexRefine *> (idx)) {
398
- uint32_t h = fourcc ("IxRF");
399
- WRITE1 (h);
400
- write_index_header (idxrf, f);
401
- write_index (idxrf->base_index, f);
402
- write_index (idxrf->refine_index, f);
403
- WRITE1 (idxrf->k_factor);
404
- } else if(const IndexIDMap * idxmap =
405
- dynamic_cast<const IndexIDMap *> (idx)) {
406
- uint32_t h =
407
- dynamic_cast<const IndexIDMap2 *> (idx) ? fourcc ("IxM2") :
408
- fourcc ("IxMp");
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 (h);
411
- write_index_header (idxmap, f);
412
- write_index (idxmap->index, f);
413
- WRITEVECTOR (idxmap->id_map);
414
- } else if(const IndexHNSW * idxhnsw =
415
- dynamic_cast<const IndexHNSW *> (idx)) {
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
- dynamic_cast<const IndexHNSWFlat*>(idx) ? fourcc("IHNf") :
418
- dynamic_cast<const IndexHNSWPQ*>(idx) ? fourcc("IHNp") :
419
- dynamic_cast<const IndexHNSWSQ*>(idx) ? fourcc("IHNs") :
420
- dynamic_cast<const IndexHNSW2Level*>(idx) ? fourcc("IHN2") :
421
- 0;
422
- FAISS_THROW_IF_NOT (h != 0);
423
- WRITE1 (h);
424
- write_index_header (idxhnsw, f);
425
- write_HNSW (&idxhnsw->hnsw, f);
426
- write_index (idxhnsw->storage, f);
427
- } else if (const IndexPQFastScan *idxpqfs =
428
- dynamic_cast<const IndexPQFastScan*>(idx)) {
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 (h);
431
- write_index_header (idxpqfs, f);
432
- write_ProductQuantizer (&idxpqfs->pq, f);
433
- WRITE1 (idxpqfs->implem);
434
- WRITE1 (idxpqfs->bbs);
435
- WRITE1 (idxpqfs->qbs);
436
- WRITE1 (idxpqfs->ntotal2);
437
- WRITE1 (idxpqfs->M2);
438
- WRITEVECTOR (idxpqfs->codes);
439
- } else if (const IndexIVFPQFastScan * ivpq =
440
- dynamic_cast<const IndexIVFPQFastScan *> (idx)) {
441
- uint32_t h = fourcc ("IwPf");
442
- WRITE1 (h);
443
- write_ivf_header (ivpq, f);
444
- WRITE1 (ivpq->by_residual);
445
- WRITE1 (ivpq->code_size);
446
- WRITE1 (ivpq->bbs);
447
- WRITE1 (ivpq->M2);
448
- WRITE1 (ivpq->implem);
449
- WRITE1 (ivpq->qbs2);
450
- write_ProductQuantizer (&ivpq->pq, f);
451
- write_InvertedLists (ivpq->invlists, f);
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 ("don't know how to serialize this type of index");
590
+ FAISS_THROW_MSG("don't know how to serialize this type of index");
454
591
  }
455
592
  }
456
593
 
457
- void write_index (const Index *idx, FILE *f) {
594
+ void write_index(const Index* idx, FILE* f) {
458
595
  FileIOWriter writer(f);
459
- write_index (idx, &writer);
596
+ write_index(idx, &writer);
460
597
  }
461
598
 
462
- void write_index (const Index *idx, const char *fname) {
599
+ void write_index(const Index* idx, const char* fname) {
463
600
  FileIOWriter writer(fname);
464
- write_index (idx, &writer);
601
+ write_index(idx, &writer);
465
602
  }
466
603
 
467
- void write_VectorTransform (const VectorTransform *vt, const char *fname) {
604
+ void write_VectorTransform(const VectorTransform* vt, const char* fname) {
468
605
  FileIOWriter writer(fname);
469
- write_VectorTransform (vt, &writer);
606
+ write_VectorTransform(vt, &writer);
470
607
  }
471
608
 
472
-
473
609
  /*************************************************************
474
610
  * Write binary indexes
475
611
  **************************************************************/
476
612
 
477
-
478
- static void write_index_binary_header (const IndexBinary *idx, IOWriter *f) {
479
- WRITE1 (idx->d);
480
- WRITE1 (idx->code_size);
481
- WRITE1 (idx->ntotal);
482
- WRITE1 (idx->is_trained);
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 (const IndexBinaryIVF *ivf, IOWriter *f) {
487
- write_index_binary_header (ivf, f);
488
- WRITE1 (ivf->nlist);
489
- WRITE1 (ivf->nprobe);
490
- write_index_binary (ivf->quantizer, f);
491
- write_direct_map (&ivf->direct_map, f);
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 &invlists,
496
- int b, IOWriter *f)
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 (sz);
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 (((b + il_nbit) * sz + 7) / 8);
517
- BitstringWriter wr (buf.data(), buf.size());
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 (it->first, b);
520
- wr.write (it->second.ids.size(), il_nbit);
654
+ wr.write(it->first, b);
655
+ wr.write(it->second.ids.size(), il_nbit);
521
656
  }
522
- WRITEVECTOR (buf);
657
+ WRITEVECTOR(buf);
523
658
 
524
659
  for (auto it = invlists.begin(); it != invlists.end(); ++it) {
525
- WRITEVECTOR (it->second.ids);
526
- WRITEVECTOR (it->second.vecs);
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 &map,
532
- int b, size_t ntotal,
533
- IOWriter *f)
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 (buf.data(), buf.size());
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 (buf);
687
+ WRITEVECTOR(buf);
553
688
  }
554
689
 
555
- void write_index_binary (const IndexBinary *idx, IOWriter *f) {
556
- if (const IndexBinaryFlat *idxf =
557
- dynamic_cast<const IndexBinaryFlat *> (idx)) {
558
- uint32_t h = fourcc ("IBxF");
559
- WRITE1 (h);
560
- write_index_binary_header (idx, f);
561
- WRITEVECTOR (idxf->xb);
562
- } else if (const IndexBinaryIVF *ivf =
563
- dynamic_cast<const IndexBinaryIVF *> (idx)) {
564
- uint32_t h = fourcc ("IBwF");
565
- WRITE1 (h);
566
- write_binary_ivf_header (ivf, f);
567
- write_InvertedLists (ivf->invlists, f);
568
- } else if(const IndexBinaryFromFloat * idxff =
569
- dynamic_cast<const IndexBinaryFromFloat *> (idx)) {
570
- uint32_t h = fourcc ("IBFf");
571
- WRITE1 (h);
572
- write_index_binary_header (idxff, f);
573
- write_index (idxff->index, f);
574
- } else if (const IndexBinaryHNSW *idxhnsw =
575
- dynamic_cast<const IndexBinaryHNSW *> (idx)) {
576
- uint32_t h = fourcc ("IBHf");
577
- WRITE1 (h);
578
- write_index_binary_header (idxhnsw, f);
579
- write_HNSW (&idxhnsw->hnsw, f);
580
- write_index_binary (idxhnsw->storage, f);
581
- } else if(const IndexBinaryIDMap * idxmap =
582
- dynamic_cast<const IndexBinaryIDMap *> (idx)) {
583
- uint32_t h =
584
- dynamic_cast<const IndexBinaryIDMap2 *> (idx) ? fourcc ("IBM2") :
585
- fourcc ("IBMp");
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 (h);
588
- write_index_binary_header (idxmap, f);
589
- write_index_binary (idxmap->index, f);
590
- WRITEVECTOR (idxmap->id_map);
591
- } else if (const IndexBinaryHash *idxh =
592
- dynamic_cast<const IndexBinaryHash *> (idx)) {
593
- uint32_t h = fourcc ("IBHh");
594
- WRITE1 (h);
595
- write_index_binary_header (idxh, f);
596
- WRITE1 (idxh->b);
597
- WRITE1 (idxh->nflip);
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 (const IndexBinaryMultiHash *idxmh =
600
- dynamic_cast<const IndexBinaryMultiHash *> (idx)) {
601
- uint32_t h = fourcc ("IBHm");
602
- WRITE1 (h);
603
- write_index_binary_header (idxmh, f);
604
- write_index_binary (idxmh->storage, f);
605
- WRITE1 (idxmh->b);
606
- WRITE1 (idxmh->nhash);
607
- WRITE1 (idxmh->nflip);
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 ("don't know how to serialize this type of index");
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 (const IndexBinary *idx, FILE *f) {
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 (const IndexBinary *idx, const char *fname) {
763
+ void write_index_binary(const IndexBinary* idx, const char* fname) {
623
764
  FileIOWriter writer(fname);
624
- write_index_binary (idx, &writer);
765
+ write_index_binary(idx, &writer);
625
766
  }
626
767
 
627
-
628
768
  } // namespace faiss