faiss 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +23 -21
  5. data/ext/faiss/extconf.rb +11 -0
  6. data/ext/faiss/index.cpp +4 -4
  7. data/ext/faiss/index_binary.cpp +6 -6
  8. data/ext/faiss/product_quantizer.cpp +4 -4
  9. data/lib/faiss/version.rb +1 -1
  10. data/vendor/faiss/faiss/AutoTune.cpp +13 -0
  11. data/vendor/faiss/faiss/Clustering.cpp +32 -0
  12. data/vendor/faiss/faiss/Clustering.h +14 -0
  13. data/vendor/faiss/faiss/IVFlib.cpp +101 -2
  14. data/vendor/faiss/faiss/IVFlib.h +26 -2
  15. data/vendor/faiss/faiss/Index.cpp +36 -3
  16. data/vendor/faiss/faiss/Index.h +43 -6
  17. data/vendor/faiss/faiss/Index2Layer.cpp +24 -93
  18. data/vendor/faiss/faiss/Index2Layer.h +8 -17
  19. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +610 -0
  20. data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +253 -0
  21. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +299 -0
  22. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +199 -0
  23. data/vendor/faiss/faiss/IndexBinary.cpp +20 -4
  24. data/vendor/faiss/faiss/IndexBinary.h +18 -3
  25. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +9 -2
  26. data/vendor/faiss/faiss/IndexBinaryFlat.h +4 -2
  27. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -1
  28. data/vendor/faiss/faiss/IndexBinaryFromFloat.h +2 -1
  29. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +5 -1
  30. data/vendor/faiss/faiss/IndexBinaryHNSW.h +2 -1
  31. data/vendor/faiss/faiss/IndexBinaryHash.cpp +17 -4
  32. data/vendor/faiss/faiss/IndexBinaryHash.h +8 -4
  33. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +28 -13
  34. data/vendor/faiss/faiss/IndexBinaryIVF.h +10 -7
  35. data/vendor/faiss/faiss/IndexFastScan.cpp +626 -0
  36. data/vendor/faiss/faiss/IndexFastScan.h +145 -0
  37. data/vendor/faiss/faiss/IndexFlat.cpp +52 -69
  38. data/vendor/faiss/faiss/IndexFlat.h +16 -19
  39. data/vendor/faiss/faiss/IndexFlatCodes.cpp +101 -0
  40. data/vendor/faiss/faiss/IndexFlatCodes.h +59 -0
  41. data/vendor/faiss/faiss/IndexHNSW.cpp +66 -138
  42. data/vendor/faiss/faiss/IndexHNSW.h +4 -2
  43. data/vendor/faiss/faiss/IndexIDMap.cpp +247 -0
  44. data/vendor/faiss/faiss/IndexIDMap.h +107 -0
  45. data/vendor/faiss/faiss/IndexIVF.cpp +200 -40
  46. data/vendor/faiss/faiss/IndexIVF.h +59 -22
  47. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +393 -0
  48. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +183 -0
  49. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +590 -0
  50. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +171 -0
  51. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +1290 -0
  52. data/vendor/faiss/faiss/IndexIVFFastScan.h +213 -0
  53. data/vendor/faiss/faiss/IndexIVFFlat.cpp +43 -26
  54. data/vendor/faiss/faiss/IndexIVFFlat.h +4 -2
  55. data/vendor/faiss/faiss/IndexIVFPQ.cpp +238 -53
  56. data/vendor/faiss/faiss/IndexIVFPQ.h +6 -2
  57. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +23 -852
  58. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +7 -112
  59. data/vendor/faiss/faiss/IndexIVFPQR.cpp +3 -3
  60. data/vendor/faiss/faiss/IndexIVFPQR.h +1 -1
  61. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +63 -40
  62. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +23 -7
  63. data/vendor/faiss/faiss/IndexLSH.cpp +8 -32
  64. data/vendor/faiss/faiss/IndexLSH.h +4 -16
  65. data/vendor/faiss/faiss/IndexLattice.cpp +7 -1
  66. data/vendor/faiss/faiss/IndexLattice.h +3 -1
  67. data/vendor/faiss/faiss/IndexNNDescent.cpp +4 -5
  68. data/vendor/faiss/faiss/IndexNNDescent.h +2 -1
  69. data/vendor/faiss/faiss/IndexNSG.cpp +37 -5
  70. data/vendor/faiss/faiss/IndexNSG.h +25 -1
  71. data/vendor/faiss/faiss/IndexPQ.cpp +108 -120
  72. data/vendor/faiss/faiss/IndexPQ.h +21 -22
  73. data/vendor/faiss/faiss/IndexPQFastScan.cpp +15 -450
  74. data/vendor/faiss/faiss/IndexPQFastScan.h +15 -78
  75. data/vendor/faiss/faiss/IndexPreTransform.cpp +47 -8
  76. data/vendor/faiss/faiss/IndexPreTransform.h +15 -3
  77. data/vendor/faiss/faiss/IndexRefine.cpp +36 -4
  78. data/vendor/faiss/faiss/IndexRefine.h +14 -2
  79. data/vendor/faiss/faiss/IndexReplicas.cpp +4 -2
  80. data/vendor/faiss/faiss/IndexReplicas.h +2 -1
  81. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +438 -0
  82. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +92 -0
  83. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +28 -43
  84. data/vendor/faiss/faiss/IndexScalarQuantizer.h +8 -23
  85. data/vendor/faiss/faiss/IndexShards.cpp +4 -1
  86. data/vendor/faiss/faiss/IndexShards.h +2 -1
  87. data/vendor/faiss/faiss/MetaIndexes.cpp +5 -178
  88. data/vendor/faiss/faiss/MetaIndexes.h +3 -81
  89. data/vendor/faiss/faiss/VectorTransform.cpp +45 -1
  90. data/vendor/faiss/faiss/VectorTransform.h +25 -4
  91. data/vendor/faiss/faiss/clone_index.cpp +26 -3
  92. data/vendor/faiss/faiss/clone_index.h +3 -0
  93. data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +300 -0
  94. data/vendor/faiss/faiss/cppcontrib/detail/CoarseBitType.h +24 -0
  95. data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +195 -0
  96. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +2058 -0
  97. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +408 -0
  98. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +2147 -0
  99. data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMax-inl.h +460 -0
  100. data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMaxFP16-inl.h +465 -0
  101. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +1618 -0
  102. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +251 -0
  103. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +1452 -0
  104. data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +1 -0
  105. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +2 -6
  106. data/vendor/faiss/faiss/gpu/GpuIcmEncoder.h +60 -0
  107. data/vendor/faiss/faiss/gpu/GpuIndex.h +28 -4
  108. data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +2 -1
  109. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +10 -8
  110. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +75 -14
  111. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +19 -32
  112. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +22 -31
  113. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +22 -28
  114. data/vendor/faiss/faiss/gpu/GpuResources.cpp +14 -0
  115. data/vendor/faiss/faiss/gpu/GpuResources.h +16 -3
  116. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +3 -3
  117. data/vendor/faiss/faiss/gpu/impl/IndexUtils.h +32 -0
  118. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +1 -0
  119. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +311 -75
  120. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +10 -0
  121. data/vendor/faiss/faiss/gpu/test/TestUtils.h +3 -0
  122. data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +2 -2
  123. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +5 -4
  124. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +331 -29
  125. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +110 -19
  126. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +0 -54
  127. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +0 -76
  128. data/vendor/faiss/faiss/impl/DistanceComputer.h +64 -0
  129. data/vendor/faiss/faiss/impl/HNSW.cpp +133 -32
  130. data/vendor/faiss/faiss/impl/HNSW.h +19 -16
  131. data/vendor/faiss/faiss/impl/IDSelector.cpp +125 -0
  132. data/vendor/faiss/faiss/impl/IDSelector.h +135 -0
  133. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +378 -217
  134. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +106 -29
  135. data/vendor/faiss/faiss/impl/LookupTableScaler.h +77 -0
  136. data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -0
  137. data/vendor/faiss/faiss/impl/NSG.cpp +1 -4
  138. data/vendor/faiss/faiss/impl/NSG.h +1 -1
  139. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +383 -0
  140. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +154 -0
  141. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +225 -145
  142. data/vendor/faiss/faiss/impl/ProductQuantizer.h +29 -10
  143. data/vendor/faiss/faiss/impl/Quantizer.h +43 -0
  144. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +521 -55
  145. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +94 -16
  146. data/vendor/faiss/faiss/impl/ResultHandler.h +96 -0
  147. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +108 -191
  148. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +18 -18
  149. data/vendor/faiss/faiss/impl/index_read.cpp +338 -24
  150. data/vendor/faiss/faiss/impl/index_write.cpp +300 -18
  151. data/vendor/faiss/faiss/impl/io.cpp +1 -1
  152. data/vendor/faiss/faiss/impl/io_macros.h +20 -0
  153. data/vendor/faiss/faiss/impl/kmeans1d.cpp +303 -0
  154. data/vendor/faiss/faiss/impl/kmeans1d.h +48 -0
  155. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +56 -16
  156. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +25 -8
  157. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +66 -25
  158. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +75 -27
  159. data/vendor/faiss/faiss/index_factory.cpp +772 -412
  160. data/vendor/faiss/faiss/index_factory.h +3 -0
  161. data/vendor/faiss/faiss/index_io.h +5 -0
  162. data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -0
  163. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +4 -1
  164. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +2 -1
  165. data/vendor/faiss/faiss/python/python_callbacks.cpp +27 -0
  166. data/vendor/faiss/faiss/python/python_callbacks.h +15 -0
  167. data/vendor/faiss/faiss/utils/Heap.h +31 -15
  168. data/vendor/faiss/faiss/utils/distances.cpp +384 -58
  169. data/vendor/faiss/faiss/utils/distances.h +149 -18
  170. data/vendor/faiss/faiss/utils/distances_simd.cpp +776 -6
  171. data/vendor/faiss/faiss/utils/extra_distances.cpp +12 -7
  172. data/vendor/faiss/faiss/utils/extra_distances.h +3 -1
  173. data/vendor/faiss/faiss/utils/fp16-fp16c.h +21 -0
  174. data/vendor/faiss/faiss/utils/fp16-inl.h +101 -0
  175. data/vendor/faiss/faiss/utils/fp16.h +11 -0
  176. data/vendor/faiss/faiss/utils/hamming-inl.h +54 -0
  177. data/vendor/faiss/faiss/utils/hamming.cpp +0 -48
  178. data/vendor/faiss/faiss/utils/ordered_key_value.h +10 -0
  179. data/vendor/faiss/faiss/utils/quantize_lut.cpp +62 -0
  180. data/vendor/faiss/faiss/utils/quantize_lut.h +20 -0
  181. data/vendor/faiss/faiss/utils/random.cpp +53 -0
  182. data/vendor/faiss/faiss/utils/random.h +5 -0
  183. data/vendor/faiss/faiss/utils/simdlib_avx2.h +4 -0
  184. data/vendor/faiss/faiss/utils/simdlib_emulated.h +6 -1
  185. data/vendor/faiss/faiss/utils/simdlib_neon.h +7 -2
  186. data/vendor/faiss/faiss/utils/utils.h +1 -1
  187. metadata +46 -5
  188. data/vendor/faiss/faiss/IndexResidual.cpp +0 -291
  189. data/vendor/faiss/faiss/IndexResidual.h +0 -152
@@ -26,9 +26,13 @@
26
26
  #include <faiss/utils/hamming.h>
27
27
 
28
28
  #include <faiss/Index2Layer.h>
29
+ #include <faiss/IndexAdditiveQuantizer.h>
30
+ #include <faiss/IndexAdditiveQuantizerFastScan.h>
29
31
  #include <faiss/IndexFlat.h>
30
32
  #include <faiss/IndexHNSW.h>
31
33
  #include <faiss/IndexIVF.h>
34
+ #include <faiss/IndexIVFAdditiveQuantizer.h>
35
+ #include <faiss/IndexIVFAdditiveQuantizerFastScan.h>
32
36
  #include <faiss/IndexIVFFlat.h>
33
37
  #include <faiss/IndexIVFPQ.h>
34
38
  #include <faiss/IndexIVFPQFastScan.h>
@@ -36,12 +40,13 @@
36
40
  #include <faiss/IndexIVFSpectralHash.h>
37
41
  #include <faiss/IndexLSH.h>
38
42
  #include <faiss/IndexLattice.h>
43
+ #include <faiss/IndexNNDescent.h>
39
44
  #include <faiss/IndexNSG.h>
40
45
  #include <faiss/IndexPQ.h>
41
46
  #include <faiss/IndexPQFastScan.h>
42
47
  #include <faiss/IndexPreTransform.h>
43
48
  #include <faiss/IndexRefine.h>
44
- #include <faiss/IndexResidual.h>
49
+ #include <faiss/IndexRowwiseMinMax.h>
45
50
  #include <faiss/IndexScalarQuantizer.h>
46
51
  #include <faiss/MetaIndexes.h>
47
52
  #include <faiss/VectorTransform.h>
@@ -95,9 +100,10 @@ void write_VectorTransform(const VectorTransform* vt, IOWriter* f) {
95
100
  uint32_t h = fourcc("rrot");
96
101
  WRITE1(h);
97
102
  } else if (const PCAMatrix* pca = dynamic_cast<const PCAMatrix*>(lt)) {
98
- uint32_t h = fourcc("PcAm");
103
+ uint32_t h = fourcc("Pcam");
99
104
  WRITE1(h);
100
105
  WRITE1(pca->eigen_power);
106
+ WRITE1(pca->epsilon);
101
107
  WRITE1(pca->random_rotation);
102
108
  WRITE1(pca->balanced_bins);
103
109
  WRITEVECTOR(pca->mean);
@@ -158,14 +164,76 @@ void write_ProductQuantizer(const ProductQuantizer* pq, IOWriter* f) {
158
164
  WRITEVECTOR(pq->centroids);
159
165
  }
160
166
 
161
- void write_ResidualQuantizer(const ResidualQuantizer* rq, IOWriter* f) {
162
- WRITE1(rq->d);
163
- WRITE1(rq->M);
164
- WRITEVECTOR(rq->nbits);
165
- WRITE1(rq->is_trained);
167
+ static void write_AdditiveQuantizer(const AdditiveQuantizer* aq, IOWriter* f) {
168
+ WRITE1(aq->d);
169
+ WRITE1(aq->M);
170
+ WRITEVECTOR(aq->nbits);
171
+ WRITE1(aq->is_trained);
172
+ WRITEVECTOR(aq->codebooks);
173
+ WRITE1(aq->search_type);
174
+ WRITE1(aq->norm_min);
175
+ WRITE1(aq->norm_max);
176
+ if (aq->search_type == AdditiveQuantizer::ST_norm_cqint8 ||
177
+ aq->search_type == AdditiveQuantizer::ST_norm_cqint4 ||
178
+ aq->search_type == AdditiveQuantizer::ST_norm_lsq2x4 ||
179
+ aq->search_type == AdditiveQuantizer::ST_norm_rq2x4) {
180
+ WRITEXBVECTOR(aq->qnorm.codes);
181
+ }
182
+
183
+ if (aq->search_type == AdditiveQuantizer::ST_norm_lsq2x4 ||
184
+ aq->search_type == AdditiveQuantizer::ST_norm_rq2x4) {
185
+ WRITEVECTOR(aq->norm_tabs);
186
+ }
187
+ }
188
+
189
+ static void write_ResidualQuantizer(const ResidualQuantizer* rq, IOWriter* f) {
190
+ write_AdditiveQuantizer(rq, f);
166
191
  WRITE1(rq->train_type);
167
192
  WRITE1(rq->max_beam_size);
168
- WRITEVECTOR(rq->codebooks);
193
+ }
194
+
195
+ static void write_LocalSearchQuantizer(
196
+ const LocalSearchQuantizer* lsq,
197
+ IOWriter* f) {
198
+ write_AdditiveQuantizer(lsq, f);
199
+ WRITE1(lsq->K);
200
+ WRITE1(lsq->train_iters);
201
+ WRITE1(lsq->encode_ils_iters);
202
+ WRITE1(lsq->train_ils_iters);
203
+ WRITE1(lsq->icm_iters);
204
+ WRITE1(lsq->p);
205
+ WRITE1(lsq->lambd);
206
+ WRITE1(lsq->chunk_size);
207
+ WRITE1(lsq->random_seed);
208
+ WRITE1(lsq->nperts);
209
+ WRITE1(lsq->update_codebooks_with_double);
210
+ }
211
+
212
+ static void write_ProductAdditiveQuantizer(
213
+ const ProductAdditiveQuantizer* paq,
214
+ IOWriter* f) {
215
+ write_AdditiveQuantizer(paq, f);
216
+ WRITE1(paq->nsplits);
217
+ }
218
+
219
+ static void write_ProductResidualQuantizer(
220
+ const ProductResidualQuantizer* prq,
221
+ IOWriter* f) {
222
+ write_ProductAdditiveQuantizer(prq, f);
223
+ for (const auto aq : prq->quantizers) {
224
+ auto rq = dynamic_cast<const ResidualQuantizer*>(aq);
225
+ write_ResidualQuantizer(rq, f);
226
+ }
227
+ }
228
+
229
+ static void write_ProductLocalSearchQuantizer(
230
+ const ProductLocalSearchQuantizer* plsq,
231
+ IOWriter* f) {
232
+ write_ProductAdditiveQuantizer(plsq, f);
233
+ for (const auto aq : plsq->quantizers) {
234
+ auto lsq = dynamic_cast<const LocalSearchQuantizer*>(aq);
235
+ write_LocalSearchQuantizer(lsq, f);
236
+ }
169
237
  }
170
238
 
171
239
  static void write_ScalarQuantizer(const ScalarQuantizer* ivsc, IOWriter* f) {
@@ -284,6 +352,21 @@ static void write_NSG(const NSG* nsg, IOWriter* f) {
284
352
  }
285
353
  }
286
354
 
355
+ static void write_NNDescent(const NNDescent* nnd, IOWriter* f) {
356
+ WRITE1(nnd->ntotal);
357
+ WRITE1(nnd->d);
358
+ WRITE1(nnd->K);
359
+ WRITE1(nnd->S);
360
+ WRITE1(nnd->R);
361
+ WRITE1(nnd->L);
362
+ WRITE1(nnd->iter);
363
+ WRITE1(nnd->search_L);
364
+ WRITE1(nnd->random_seed);
365
+ WRITE1(nnd->has_built);
366
+
367
+ WRITEVECTOR(nnd->final_graph);
368
+ }
369
+
287
370
  static void write_direct_map(const DirectMap* dm, IOWriter* f) {
288
371
  char maintain_direct_map =
289
372
  (char)dm->type; // for backwards compatibility with bool
@@ -315,7 +398,7 @@ void write_index(const Index* idx, IOWriter* f) {
315
398
  : "IxFl");
316
399
  WRITE1(h);
317
400
  write_index_header(idx, f);
318
- WRITEVECTOR(idxf->xb);
401
+ WRITEXBVECTOR(idxf->codes);
319
402
  } else if (const IndexLSH* idxl = dynamic_cast<const IndexLSH*>(idx)) {
320
403
  uint32_t h = fourcc("IxHe");
321
404
  WRITE1(h);
@@ -324,7 +407,8 @@ void write_index(const Index* idx, IOWriter* f) {
324
407
  WRITE1(idxl->rotate_data);
325
408
  WRITE1(idxl->train_thresholds);
326
409
  WRITEVECTOR(idxl->thresholds);
327
- WRITE1(idxl->bytes_per_vec);
410
+ int code_size_i = idxl->code_size;
411
+ WRITE1(code_size_i);
328
412
  write_VectorTransform(&idxl->rrot, f);
329
413
  WRITEVECTOR(idxl->codes);
330
414
  } else if (const IndexPQ* idxp = dynamic_cast<const IndexPQ*>(idx)) {
@@ -338,17 +422,153 @@ void write_index(const Index* idx, IOWriter* f) {
338
422
  WRITE1(idxp->encode_signs);
339
423
  WRITE1(idxp->polysemous_ht);
340
424
  } else if (
341
- const IndexResidual* idxr =
342
- dynamic_cast<const IndexResidual*>(idx)) {
343
- uint32_t h = fourcc("IxRQ");
425
+ const IndexResidualQuantizer* idxr =
426
+ dynamic_cast<const IndexResidualQuantizer*>(idx)) {
427
+ uint32_t h = fourcc("IxRq");
344
428
  WRITE1(h);
345
429
  write_index_header(idx, f);
346
430
  write_ResidualQuantizer(&idxr->rq, f);
347
- WRITE1(idxr->search_type);
348
- WRITE1(idxr->norm_min);
349
- WRITE1(idxr->norm_max);
350
431
  WRITE1(idxr->code_size);
351
432
  WRITEVECTOR(idxr->codes);
433
+ } else if (
434
+ auto* idxr = dynamic_cast<const IndexLocalSearchQuantizer*>(idx)) {
435
+ uint32_t h = fourcc("IxLS");
436
+ WRITE1(h);
437
+ write_index_header(idx, f);
438
+ write_LocalSearchQuantizer(&idxr->lsq, f);
439
+ WRITE1(idxr->code_size);
440
+ WRITEVECTOR(idxr->codes);
441
+ } else if (
442
+ const IndexProductResidualQuantizer* idxpr =
443
+ dynamic_cast<const IndexProductResidualQuantizer*>(idx)) {
444
+ uint32_t h = fourcc("IxPR");
445
+ WRITE1(h);
446
+ write_index_header(idx, f);
447
+ write_ProductResidualQuantizer(&idxpr->prq, f);
448
+ WRITE1(idxpr->code_size);
449
+ WRITEVECTOR(idxpr->codes);
450
+ } else if (
451
+ const IndexProductLocalSearchQuantizer* idxpl =
452
+ dynamic_cast<const IndexProductLocalSearchQuantizer*>(
453
+ idx)) {
454
+ uint32_t h = fourcc("IxPL");
455
+ WRITE1(h);
456
+ write_index_header(idx, f);
457
+ write_ProductLocalSearchQuantizer(&idxpl->plsq, f);
458
+ WRITE1(idxpl->code_size);
459
+ WRITEVECTOR(idxpl->codes);
460
+ } else if (
461
+ auto* idxaqfs =
462
+ dynamic_cast<const IndexAdditiveQuantizerFastScan*>(idx)) {
463
+ auto idxlsqfs =
464
+ dynamic_cast<const IndexLocalSearchQuantizerFastScan*>(idx);
465
+ auto idxrqfs = dynamic_cast<const IndexResidualQuantizerFastScan*>(idx);
466
+ auto idxplsqfs =
467
+ dynamic_cast<const IndexProductLocalSearchQuantizerFastScan*>(
468
+ idx);
469
+ auto idxprqfs =
470
+ dynamic_cast<const IndexProductResidualQuantizerFastScan*>(idx);
471
+ FAISS_THROW_IF_NOT(idxlsqfs || idxrqfs || idxplsqfs || idxprqfs);
472
+
473
+ if (idxlsqfs) {
474
+ uint32_t h = fourcc("ILfs");
475
+ WRITE1(h);
476
+ } else if (idxrqfs) {
477
+ uint32_t h = fourcc("IRfs");
478
+ WRITE1(h);
479
+ } else if (idxplsqfs) {
480
+ uint32_t h = fourcc("IPLf");
481
+ WRITE1(h);
482
+ } else if (idxprqfs) {
483
+ uint32_t h = fourcc("IPRf");
484
+ WRITE1(h);
485
+ }
486
+
487
+ write_index_header(idxaqfs, f);
488
+
489
+ if (idxlsqfs) {
490
+ write_LocalSearchQuantizer(&idxlsqfs->lsq, f);
491
+ } else if (idxrqfs) {
492
+ write_ResidualQuantizer(&idxrqfs->rq, f);
493
+ } else if (idxplsqfs) {
494
+ write_ProductLocalSearchQuantizer(&idxplsqfs->plsq, f);
495
+ } else if (idxprqfs) {
496
+ write_ProductResidualQuantizer(&idxprqfs->prq, f);
497
+ }
498
+ WRITE1(idxaqfs->implem);
499
+ WRITE1(idxaqfs->bbs);
500
+ WRITE1(idxaqfs->qbs);
501
+
502
+ WRITE1(idxaqfs->M);
503
+ WRITE1(idxaqfs->nbits);
504
+ WRITE1(idxaqfs->ksub);
505
+ WRITE1(idxaqfs->code_size);
506
+ WRITE1(idxaqfs->ntotal2);
507
+ WRITE1(idxaqfs->M2);
508
+
509
+ WRITE1(idxaqfs->rescale_norm);
510
+ WRITE1(idxaqfs->norm_scale);
511
+ WRITE1(idxaqfs->max_train_points);
512
+
513
+ WRITEVECTOR(idxaqfs->codes);
514
+ } else if (
515
+ auto* ivaqfs =
516
+ dynamic_cast<const IndexIVFAdditiveQuantizerFastScan*>(
517
+ idx)) {
518
+ auto ivlsqfs =
519
+ dynamic_cast<const IndexIVFLocalSearchQuantizerFastScan*>(idx);
520
+ auto ivrqfs =
521
+ dynamic_cast<const IndexIVFResidualQuantizerFastScan*>(idx);
522
+ auto ivplsqfs = dynamic_cast<
523
+ const IndexIVFProductLocalSearchQuantizerFastScan*>(idx);
524
+ auto ivprqfs =
525
+ dynamic_cast<const IndexIVFProductResidualQuantizerFastScan*>(
526
+ idx);
527
+ FAISS_THROW_IF_NOT(ivlsqfs || ivrqfs || ivplsqfs || ivprqfs);
528
+
529
+ if (ivlsqfs) {
530
+ uint32_t h = fourcc("IVLf");
531
+ WRITE1(h);
532
+ } else if (ivrqfs) {
533
+ uint32_t h = fourcc("IVRf");
534
+ WRITE1(h);
535
+ } else if (ivplsqfs) {
536
+ uint32_t h = fourcc("NPLf"); // N means IV ...
537
+ WRITE1(h);
538
+ } else {
539
+ uint32_t h = fourcc("NPRf");
540
+ WRITE1(h);
541
+ }
542
+
543
+ write_ivf_header(ivaqfs, f);
544
+
545
+ if (ivlsqfs) {
546
+ write_LocalSearchQuantizer(&ivlsqfs->lsq, f);
547
+ } else if (ivrqfs) {
548
+ write_ResidualQuantizer(&ivrqfs->rq, f);
549
+ } else if (ivplsqfs) {
550
+ write_ProductLocalSearchQuantizer(&ivplsqfs->plsq, f);
551
+ } else {
552
+ write_ProductResidualQuantizer(&ivprqfs->prq, f);
553
+ }
554
+
555
+ WRITE1(ivaqfs->by_residual);
556
+ WRITE1(ivaqfs->implem);
557
+ WRITE1(ivaqfs->bbs);
558
+ WRITE1(ivaqfs->qbs);
559
+
560
+ WRITE1(ivaqfs->M);
561
+ WRITE1(ivaqfs->nbits);
562
+ WRITE1(ivaqfs->ksub);
563
+ WRITE1(ivaqfs->code_size);
564
+ WRITE1(ivaqfs->qbs2);
565
+ WRITE1(ivaqfs->M2);
566
+
567
+ WRITE1(ivaqfs->rescale_norm);
568
+ WRITE1(ivaqfs->norm_scale);
569
+ WRITE1(ivaqfs->max_train_points);
570
+
571
+ write_InvertedLists(ivaqfs->invlists, f);
352
572
  } else if (
353
573
  const ResidualCoarseQuantizer* idxr =
354
574
  dynamic_cast<const ResidualCoarseQuantizer*>(idx)) {
@@ -421,6 +641,39 @@ void write_index(const Index* idx, IOWriter* f) {
421
641
  WRITE1(ivsc->code_size);
422
642
  WRITE1(ivsc->by_residual);
423
643
  write_InvertedLists(ivsc->invlists, f);
644
+ } else if (auto iva = dynamic_cast<const IndexIVFAdditiveQuantizer*>(idx)) {
645
+ bool is_LSQ = dynamic_cast<const IndexIVFLocalSearchQuantizer*>(iva);
646
+ bool is_RQ = dynamic_cast<const IndexIVFResidualQuantizer*>(iva);
647
+ bool is_PLSQ =
648
+ dynamic_cast<const IndexIVFProductLocalSearchQuantizer*>(iva);
649
+ uint32_t h;
650
+ if (is_LSQ) {
651
+ h = fourcc("IwLS");
652
+ } else if (is_RQ) {
653
+ h = fourcc("IwRQ");
654
+ } else if (is_PLSQ) {
655
+ h = fourcc("IwPL");
656
+ } else {
657
+ h = fourcc("IwPR");
658
+ }
659
+
660
+ WRITE1(h);
661
+ write_ivf_header(iva, f);
662
+ WRITE1(iva->code_size);
663
+ if (is_LSQ) {
664
+ write_LocalSearchQuantizer((LocalSearchQuantizer*)iva->aq, f);
665
+ } else if (is_RQ) {
666
+ write_ResidualQuantizer((ResidualQuantizer*)iva->aq, f);
667
+ } else if (is_PLSQ) {
668
+ write_ProductLocalSearchQuantizer(
669
+ (ProductLocalSearchQuantizer*)iva->aq, f);
670
+ } else {
671
+ write_ProductResidualQuantizer(
672
+ (ProductResidualQuantizer*)iva->aq, f);
673
+ }
674
+ WRITE1(iva->by_residual);
675
+ WRITE1(iva->use_precomputed_table);
676
+ write_InvertedLists(iva->invlists, f);
424
677
  } else if (
425
678
  const IndexIVFSpectralHash* ivsp =
426
679
  dynamic_cast<const IndexIVFSpectralHash*>(idx)) {
@@ -496,8 +749,10 @@ void write_index(const Index* idx, IOWriter* f) {
496
749
  write_HNSW(&idxhnsw->hnsw, f);
497
750
  write_index(idxhnsw->storage, f);
498
751
  } else if (const IndexNSG* idxnsg = dynamic_cast<const IndexNSG*>(idx)) {
499
- uint32_t h =
500
- dynamic_cast<const IndexNSGFlat*>(idx) ? fourcc("INSf") : 0;
752
+ uint32_t h = dynamic_cast<const IndexNSGFlat*>(idx) ? fourcc("INSf")
753
+ : dynamic_cast<const IndexNSGPQ*>(idx) ? fourcc("INSp")
754
+ : dynamic_cast<const IndexNSGSQ*>(idx) ? fourcc("INSs")
755
+ : 0;
501
756
  FAISS_THROW_IF_NOT(h != 0);
502
757
  WRITE1(h);
503
758
  write_index_header(idxnsg, f);
@@ -509,6 +764,17 @@ void write_index(const Index* idx, IOWriter* f) {
509
764
  WRITE1(idxnsg->nndescent_iter);
510
765
  write_NSG(&idxnsg->nsg, f);
511
766
  write_index(idxnsg->storage, f);
767
+ } else if (
768
+ const IndexNNDescent* idxnnd =
769
+ dynamic_cast<const IndexNNDescent*>(idx)) {
770
+ auto idxnndflat = dynamic_cast<const IndexNNDescentFlat*>(idx);
771
+ FAISS_THROW_IF_NOT(idxnndflat != nullptr);
772
+ uint32_t h = fourcc("INNf");
773
+ FAISS_THROW_IF_NOT(h != 0);
774
+ WRITE1(h);
775
+ write_index_header(idxnnd, f);
776
+ write_NNDescent(&idxnnd->nndescent, f);
777
+ write_index(idxnnd->storage, f);
512
778
  } else if (
513
779
  const IndexPQFastScan* idxpqfs =
514
780
  dynamic_cast<const IndexPQFastScan*>(idx)) {
@@ -536,6 +802,22 @@ void write_index(const Index* idx, IOWriter* f) {
536
802
  WRITE1(ivpq->qbs2);
537
803
  write_ProductQuantizer(&ivpq->pq, f);
538
804
  write_InvertedLists(ivpq->invlists, f);
805
+ } else if (
806
+ const IndexRowwiseMinMax* imm =
807
+ dynamic_cast<const IndexRowwiseMinMax*>(idx)) {
808
+ // IndexRowwiseMinmaxFloat
809
+ uint32_t h = fourcc("IRMf");
810
+ WRITE1(h);
811
+ write_index_header(imm, f);
812
+ write_index(imm->index, f);
813
+ } else if (
814
+ const IndexRowwiseMinMaxFP16* imm =
815
+ dynamic_cast<const IndexRowwiseMinMaxFP16*>(idx)) {
816
+ // IndexRowwiseMinmaxHalf
817
+ uint32_t h = fourcc("IRMh");
818
+ WRITE1(h);
819
+ write_index_header(imm, f);
820
+ write_index(imm->index, f);
539
821
  } else {
540
822
  FAISS_THROW_MSG("don't know how to serialize this type of index");
541
823
  }
@@ -240,7 +240,7 @@ uint32_t fourcc(const std::string& sx) {
240
240
 
241
241
  void fourcc_inv(uint32_t x, char str[5]) {
242
242
  *(uint32_t*)str = x;
243
- str[5] = 0;
243
+ str[4] = 0;
244
244
  }
245
245
 
246
246
  std::string fourcc_inv(uint32_t x) {
@@ -66,3 +66,23 @@
66
66
  WRITEANDCHECK(&size, 1); \
67
67
  WRITEANDCHECK((vec).data(), size); \
68
68
  }
69
+
70
+ // read/write xb vector for backwards compatibility of IndexFlat
71
+
72
+ #define WRITEXBVECTOR(vec) \
73
+ { \
74
+ FAISS_THROW_IF_NOT((vec).size() % 4 == 0); \
75
+ size_t size = (vec).size() / 4; \
76
+ WRITEANDCHECK(&size, 1); \
77
+ WRITEANDCHECK((vec).data(), size * 4); \
78
+ }
79
+
80
+ #define READXBVECTOR(vec) \
81
+ { \
82
+ size_t size; \
83
+ READANDCHECK(&size, 1); \
84
+ FAISS_THROW_IF_NOT(size >= 0 && size < (uint64_t{1} << 40)); \
85
+ size *= 4; \
86
+ (vec).resize(size); \
87
+ READANDCHECK((vec).data(), size); \
88
+ }