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
@@ -25,9 +25,13 @@
25
25
  #include <faiss/invlists/InvertedListsIOHook.h>
26
26
 
27
27
  #include <faiss/Index2Layer.h>
28
+ #include <faiss/IndexAdditiveQuantizer.h>
29
+ #include <faiss/IndexAdditiveQuantizerFastScan.h>
28
30
  #include <faiss/IndexFlat.h>
29
31
  #include <faiss/IndexHNSW.h>
30
32
  #include <faiss/IndexIVF.h>
33
+ #include <faiss/IndexIVFAdditiveQuantizer.h>
34
+ #include <faiss/IndexIVFAdditiveQuantizerFastScan.h>
31
35
  #include <faiss/IndexIVFFlat.h>
32
36
  #include <faiss/IndexIVFPQ.h>
33
37
  #include <faiss/IndexIVFPQFastScan.h>
@@ -35,12 +39,13 @@
35
39
  #include <faiss/IndexIVFSpectralHash.h>
36
40
  #include <faiss/IndexLSH.h>
37
41
  #include <faiss/IndexLattice.h>
42
+ #include <faiss/IndexNNDescent.h>
38
43
  #include <faiss/IndexNSG.h>
39
44
  #include <faiss/IndexPQ.h>
40
45
  #include <faiss/IndexPQFastScan.h>
41
46
  #include <faiss/IndexPreTransform.h>
42
47
  #include <faiss/IndexRefine.h>
43
- #include <faiss/IndexResidual.h>
48
+ #include <faiss/IndexRowwiseMinMax.h>
44
49
  #include <faiss/IndexScalarQuantizer.h>
45
50
  #include <faiss/MetaIndexes.h>
46
51
  #include <faiss/VectorTransform.h>
@@ -77,16 +82,22 @@ VectorTransform* read_VectorTransform(IOReader* f) {
77
82
  VectorTransform* vt = nullptr;
78
83
 
79
84
  if (h == fourcc("rrot") || h == fourcc("PCAm") || h == fourcc("LTra") ||
80
- h == fourcc("PcAm") || h == fourcc("Viqm")) {
85
+ h == fourcc("PcAm") || h == fourcc("Viqm") || h == fourcc("Pcam")) {
81
86
  LinearTransform* lt = nullptr;
82
87
  if (h == fourcc("rrot")) {
83
88
  lt = new RandomRotationMatrix();
84
- } else if (h == fourcc("PCAm") || h == fourcc("PcAm")) {
89
+ } else if (
90
+ h == fourcc("PCAm") || h == fourcc("PcAm") ||
91
+ h == fourcc("Pcam")) {
85
92
  PCAMatrix* pca = new PCAMatrix();
86
93
  READ1(pca->eigen_power);
94
+ if (h == fourcc("Pcam")) {
95
+ READ1(pca->epsilon);
96
+ }
87
97
  READ1(pca->random_rotation);
88
- if (h == fourcc("PcAm"))
98
+ if (h != fourcc("PCAm")) {
89
99
  READ1(pca->balanced_bins);
100
+ }
90
101
  READVECTOR(pca->mean);
91
102
  READVECTOR(pca->eigenvalues);
92
103
  READVECTOR(pca->PCAMat);
@@ -139,9 +150,10 @@ VectorTransform* read_VectorTransform(IOReader* f) {
139
150
  vt = itqt;
140
151
  } else {
141
152
  FAISS_THROW_FMT(
142
- "fourcc %ud (\"%s\") not recognized",
153
+ "fourcc %ud (\"%s\") not recognized in %s",
143
154
  h,
144
- fourcc_inv_printable(h).c_str());
155
+ fourcc_inv_printable(h).c_str(),
156
+ f->name.c_str());
145
157
  }
146
158
  READ1(vt->d_in);
147
159
  READ1(vt->d_out);
@@ -239,15 +251,97 @@ static void read_ProductQuantizer(ProductQuantizer* pq, IOReader* f) {
239
251
  READVECTOR(pq->centroids);
240
252
  }
241
253
 
242
- static void read_ResidualQuantizer(ResidualQuantizer* rq, IOReader* f) {
254
+ static void read_ResidualQuantizer_old(ResidualQuantizer* rq, IOReader* f) {
243
255
  READ1(rq->d);
244
256
  READ1(rq->M);
245
257
  READVECTOR(rq->nbits);
246
- rq->set_derived_values();
247
258
  READ1(rq->is_trained);
248
259
  READ1(rq->train_type);
249
260
  READ1(rq->max_beam_size);
250
261
  READVECTOR(rq->codebooks);
262
+ READ1(rq->search_type);
263
+ READ1(rq->norm_min);
264
+ READ1(rq->norm_max);
265
+ rq->set_derived_values();
266
+ }
267
+
268
+ static void read_AdditiveQuantizer(AdditiveQuantizer* aq, IOReader* f) {
269
+ READ1(aq->d);
270
+ READ1(aq->M);
271
+ READVECTOR(aq->nbits);
272
+ READ1(aq->is_trained);
273
+ READVECTOR(aq->codebooks);
274
+ READ1(aq->search_type);
275
+ READ1(aq->norm_min);
276
+ READ1(aq->norm_max);
277
+ if (aq->search_type == AdditiveQuantizer::ST_norm_cqint8 ||
278
+ aq->search_type == AdditiveQuantizer::ST_norm_cqint4 ||
279
+ aq->search_type == AdditiveQuantizer::ST_norm_lsq2x4 ||
280
+ aq->search_type == AdditiveQuantizer::ST_norm_rq2x4) {
281
+ READXBVECTOR(aq->qnorm.codes);
282
+ }
283
+
284
+ if (aq->search_type == AdditiveQuantizer::ST_norm_lsq2x4 ||
285
+ aq->search_type == AdditiveQuantizer::ST_norm_rq2x4) {
286
+ READVECTOR(aq->norm_tabs);
287
+ }
288
+
289
+ aq->set_derived_values();
290
+ }
291
+
292
+ static void read_ResidualQuantizer(ResidualQuantizer* rq, IOReader* f) {
293
+ read_AdditiveQuantizer(rq, f);
294
+ READ1(rq->train_type);
295
+ READ1(rq->max_beam_size);
296
+ if (!(rq->train_type & ResidualQuantizer::Skip_codebook_tables)) {
297
+ rq->compute_codebook_tables();
298
+ }
299
+ }
300
+
301
+ static void read_LocalSearchQuantizer(LocalSearchQuantizer* lsq, IOReader* f) {
302
+ read_AdditiveQuantizer(lsq, f);
303
+ READ1(lsq->K);
304
+ READ1(lsq->train_iters);
305
+ READ1(lsq->encode_ils_iters);
306
+ READ1(lsq->train_ils_iters);
307
+ READ1(lsq->icm_iters);
308
+ READ1(lsq->p);
309
+ READ1(lsq->lambd);
310
+ READ1(lsq->chunk_size);
311
+ READ1(lsq->random_seed);
312
+ READ1(lsq->nperts);
313
+ READ1(lsq->update_codebooks_with_double);
314
+ }
315
+
316
+ static void read_ProductAdditiveQuantizer(
317
+ ProductAdditiveQuantizer* paq,
318
+ IOReader* f) {
319
+ read_AdditiveQuantizer(paq, f);
320
+ READ1(paq->nsplits);
321
+ }
322
+
323
+ static void read_ProductResidualQuantizer(
324
+ ProductResidualQuantizer* prq,
325
+ IOReader* f) {
326
+ read_ProductAdditiveQuantizer(prq, f);
327
+
328
+ for (size_t i = 0; i < prq->nsplits; i++) {
329
+ auto rq = new ResidualQuantizer();
330
+ read_ResidualQuantizer(rq, f);
331
+ prq->quantizers.push_back(rq);
332
+ }
333
+ }
334
+
335
+ static void read_ProductLocalSearchQuantizer(
336
+ ProductLocalSearchQuantizer* plsq,
337
+ IOReader* f) {
338
+ read_ProductAdditiveQuantizer(plsq, f);
339
+
340
+ for (size_t i = 0; i < plsq->nsplits; i++) {
341
+ auto lsq = new LocalSearchQuantizer();
342
+ read_LocalSearchQuantizer(lsq, f);
343
+ plsq->quantizers.push_back(lsq);
344
+ }
251
345
  }
252
346
 
253
347
  static void read_ScalarQuantizer(ScalarQuantizer* ivsc, IOReader* f) {
@@ -310,6 +404,21 @@ static void read_NSG(NSG* nsg, IOReader* f) {
310
404
  }
311
405
  }
312
406
 
407
+ static void read_NNDescent(NNDescent* nnd, IOReader* f) {
408
+ READ1(nnd->ntotal);
409
+ READ1(nnd->d);
410
+ READ1(nnd->K);
411
+ READ1(nnd->S);
412
+ READ1(nnd->R);
413
+ READ1(nnd->L);
414
+ READ1(nnd->iter);
415
+ READ1(nnd->search_L);
416
+ READ1(nnd->random_seed);
417
+ READ1(nnd->has_built);
418
+
419
+ READVECTOR(nnd->final_graph);
420
+ }
421
+
313
422
  ProductQuantizer* read_ProductQuantizer(const char* fname) {
314
423
  FileIOReader reader(fname);
315
424
  return read_ProductQuantizer(&reader);
@@ -393,10 +502,14 @@ static IndexIVFPQ* read_ivfpq(IOReader* f, uint32_t h, int io_flags) {
393
502
  }
394
503
 
395
504
  if (ivpq->is_trained) {
396
- // precomputed table not stored. It is cheaper to recompute it
505
+ // precomputed table not stored. It is cheaper to recompute it.
506
+ // precompute_table() may be disabled with a flag.
397
507
  ivpq->use_precomputed_table = 0;
398
- if (ivpq->by_residual)
399
- ivpq->precompute_table();
508
+ if (ivpq->by_residual) {
509
+ if ((io_flags & IO_FLAG_SKIP_PRECOMPUTE_TABLE) == 0) {
510
+ ivpq->precompute_table();
511
+ }
512
+ }
400
513
  if (ivfpqr) {
401
514
  read_ProductQuantizer(&ivfpqr->refine_pq, f);
402
515
  READVECTOR(ivfpqr->refine_codes);
@@ -422,8 +535,10 @@ Index* read_index(IOReader* f, int io_flags) {
422
535
  idxf = new IndexFlat();
423
536
  }
424
537
  read_index_header(idxf, f);
425
- READVECTOR(idxf->xb);
426
- FAISS_THROW_IF_NOT(idxf->xb.size() == idxf->ntotal * idxf->d);
538
+ idxf->code_size = idxf->d * sizeof(float);
539
+ READXBVECTOR(idxf->codes);
540
+ FAISS_THROW_IF_NOT(
541
+ idxf->codes.size() == idxf->ntotal * idxf->code_size);
427
542
  // leak!
428
543
  idx = idxf;
429
544
  } else if (h == fourcc("IxHE") || h == fourcc("IxHe")) {
@@ -433,7 +548,9 @@ Index* read_index(IOReader* f, int io_flags) {
433
548
  READ1(idxl->rotate_data);
434
549
  READ1(idxl->train_thresholds);
435
550
  READVECTOR(idxl->thresholds);
436
- READ1(idxl->bytes_per_vec);
551
+ int code_size_i;
552
+ READ1(code_size_i);
553
+ idxl->code_size = code_size_i;
437
554
  if (h == fourcc("IxHE")) {
438
555
  FAISS_THROW_IF_NOT_FMT(
439
556
  idxl->nbits % 64 == 0,
@@ -441,7 +558,7 @@ Index* read_index(IOReader* f, int io_flags) {
441
558
  "nbits multiple of 64 (got %d)",
442
559
  (int)idxl->nbits);
443
560
  // leak
444
- idxl->bytes_per_vec *= 8;
561
+ idxl->code_size *= 8;
445
562
  }
446
563
  {
447
564
  RandomRotationMatrix* rrot = dynamic_cast<RandomRotationMatrix*>(
@@ -454,7 +571,7 @@ Index* read_index(IOReader* f, int io_flags) {
454
571
  FAISS_THROW_IF_NOT(
455
572
  idxl->rrot.d_in == idxl->d && idxl->rrot.d_out == idxl->nbits);
456
573
  FAISS_THROW_IF_NOT(
457
- idxl->codes.size() == idxl->ntotal * idxl->bytes_per_vec);
574
+ idxl->codes.size() == idxl->ntotal * idxl->code_size);
458
575
  idx = idxl;
459
576
  } else if (
460
577
  h == fourcc("IxPQ") || h == fourcc("IxPo") || h == fourcc("IxPq")) {
@@ -462,6 +579,7 @@ Index* read_index(IOReader* f, int io_flags) {
462
579
  IndexPQ* idxp = new IndexPQ();
463
580
  read_index_header(idxp, f);
464
581
  read_ProductQuantizer(&idxp->pq, f);
582
+ idxp->code_size = idxp->pq.code_size;
465
583
  READVECTOR(idxp->codes);
466
584
  if (h == fourcc("IxPo") || h == fourcc("IxPq")) {
467
585
  READ1(idxp->search_type);
@@ -475,16 +593,38 @@ Index* read_index(IOReader* f, int io_flags) {
475
593
  idxp->metric_type = METRIC_L2;
476
594
  }
477
595
  idx = idxp;
478
- } else if (h == fourcc("IxRQ")) {
479
- IndexResidual* idxr = new IndexResidual();
596
+ } else if (h == fourcc("IxRQ") || h == fourcc("IxRq")) {
597
+ IndexResidualQuantizer* idxr = new IndexResidualQuantizer();
480
598
  read_index_header(idxr, f);
481
- read_ResidualQuantizer(&idxr->rq, f);
482
- READ1(idxr->search_type);
483
- READ1(idxr->norm_min);
484
- READ1(idxr->norm_max);
599
+ if (h == fourcc("IxRQ")) {
600
+ read_ResidualQuantizer_old(&idxr->rq, f);
601
+ } else {
602
+ read_ResidualQuantizer(&idxr->rq, f);
603
+ }
604
+ READ1(idxr->code_size);
605
+ READVECTOR(idxr->codes);
606
+ idx = idxr;
607
+ } else if (h == fourcc("IxLS")) {
608
+ auto idxr = new IndexLocalSearchQuantizer();
609
+ read_index_header(idxr, f);
610
+ read_LocalSearchQuantizer(&idxr->lsq, f);
485
611
  READ1(idxr->code_size);
486
612
  READVECTOR(idxr->codes);
487
613
  idx = idxr;
614
+ } else if (h == fourcc("IxPR")) {
615
+ auto idxpr = new IndexProductResidualQuantizer();
616
+ read_index_header(idxpr, f);
617
+ read_ProductResidualQuantizer(&idxpr->prq, f);
618
+ READ1(idxpr->code_size);
619
+ READVECTOR(idxpr->codes);
620
+ idx = idxpr;
621
+ } else if (h == fourcc("IxPL")) {
622
+ auto idxpl = new IndexProductLocalSearchQuantizer();
623
+ read_index_header(idxpl, f);
624
+ read_ProductLocalSearchQuantizer(&idxpl->plsq, f);
625
+ READ1(idxpl->code_size);
626
+ READVECTOR(idxpl->codes);
627
+ idx = idxpl;
488
628
  } else if (h == fourcc("ImRQ")) {
489
629
  ResidualCoarseQuantizer* idxr = new ResidualCoarseQuantizer();
490
630
  read_index_header(idxr, f);
@@ -492,6 +632,103 @@ Index* read_index(IOReader* f, int io_flags) {
492
632
  READ1(idxr->beam_factor);
493
633
  idxr->set_beam_factor(idxr->beam_factor);
494
634
  idx = idxr;
635
+ } else if (
636
+ h == fourcc("ILfs") || h == fourcc("IRfs") || h == fourcc("IPRf") ||
637
+ h == fourcc("IPLf")) {
638
+ bool is_LSQ = h == fourcc("ILfs");
639
+ bool is_RQ = h == fourcc("IRfs");
640
+ bool is_PLSQ = h == fourcc("IPLf");
641
+
642
+ IndexAdditiveQuantizerFastScan* idxaqfs;
643
+ if (is_LSQ) {
644
+ idxaqfs = new IndexLocalSearchQuantizerFastScan();
645
+ } else if (is_RQ) {
646
+ idxaqfs = new IndexResidualQuantizerFastScan();
647
+ } else if (is_PLSQ) {
648
+ idxaqfs = new IndexProductLocalSearchQuantizerFastScan();
649
+ } else {
650
+ idxaqfs = new IndexProductResidualQuantizerFastScan();
651
+ }
652
+ read_index_header(idxaqfs, f);
653
+
654
+ if (is_LSQ) {
655
+ read_LocalSearchQuantizer((LocalSearchQuantizer*)idxaqfs->aq, f);
656
+ } else if (is_RQ) {
657
+ read_ResidualQuantizer((ResidualQuantizer*)idxaqfs->aq, f);
658
+ } else if (is_PLSQ) {
659
+ read_ProductLocalSearchQuantizer(
660
+ (ProductLocalSearchQuantizer*)idxaqfs->aq, f);
661
+ } else {
662
+ read_ProductResidualQuantizer(
663
+ (ProductResidualQuantizer*)idxaqfs->aq, f);
664
+ }
665
+
666
+ READ1(idxaqfs->implem);
667
+ READ1(idxaqfs->bbs);
668
+ READ1(idxaqfs->qbs);
669
+
670
+ READ1(idxaqfs->M);
671
+ READ1(idxaqfs->nbits);
672
+ READ1(idxaqfs->ksub);
673
+ READ1(idxaqfs->code_size);
674
+ READ1(idxaqfs->ntotal2);
675
+ READ1(idxaqfs->M2);
676
+
677
+ READ1(idxaqfs->rescale_norm);
678
+ READ1(idxaqfs->norm_scale);
679
+ READ1(idxaqfs->max_train_points);
680
+
681
+ READVECTOR(idxaqfs->codes);
682
+ idx = idxaqfs;
683
+ } else if (
684
+ h == fourcc("IVLf") || h == fourcc("IVRf") || h == fourcc("NPLf") ||
685
+ h == fourcc("NPRf")) {
686
+ bool is_LSQ = h == fourcc("IVLf");
687
+ bool is_RQ = h == fourcc("IVRf");
688
+ bool is_PLSQ = h == fourcc("NPLf");
689
+
690
+ IndexIVFAdditiveQuantizerFastScan* ivaqfs;
691
+ if (is_LSQ) {
692
+ ivaqfs = new IndexIVFLocalSearchQuantizerFastScan();
693
+ } else if (is_RQ) {
694
+ ivaqfs = new IndexIVFResidualQuantizerFastScan();
695
+ } else if (is_PLSQ) {
696
+ ivaqfs = new IndexIVFProductLocalSearchQuantizerFastScan();
697
+ } else {
698
+ ivaqfs = new IndexIVFProductResidualQuantizerFastScan();
699
+ }
700
+ read_ivf_header(ivaqfs, f);
701
+
702
+ if (is_LSQ) {
703
+ read_LocalSearchQuantizer((LocalSearchQuantizer*)ivaqfs->aq, f);
704
+ } else if (is_RQ) {
705
+ read_ResidualQuantizer((ResidualQuantizer*)ivaqfs->aq, f);
706
+ } else if (is_PLSQ) {
707
+ read_ProductLocalSearchQuantizer(
708
+ (ProductLocalSearchQuantizer*)ivaqfs->aq, f);
709
+ } else {
710
+ read_ProductResidualQuantizer(
711
+ (ProductResidualQuantizer*)ivaqfs->aq, f);
712
+ }
713
+
714
+ READ1(ivaqfs->by_residual);
715
+ READ1(ivaqfs->implem);
716
+ READ1(ivaqfs->bbs);
717
+ READ1(ivaqfs->qbs);
718
+
719
+ READ1(ivaqfs->M);
720
+ READ1(ivaqfs->nbits);
721
+ READ1(ivaqfs->ksub);
722
+ READ1(ivaqfs->code_size);
723
+ READ1(ivaqfs->qbs2);
724
+ READ1(ivaqfs->M2);
725
+
726
+ READ1(ivaqfs->rescale_norm);
727
+ READ1(ivaqfs->norm_scale);
728
+ READ1(ivaqfs->max_train_points);
729
+
730
+ read_InvertedLists(ivaqfs, f, io_flags);
731
+ idx = ivaqfs;
495
732
  } else if (h == fourcc("IvFl") || h == fourcc("IvFL")) { // legacy
496
733
  IndexIVFFlat* ivfl = new IndexIVFFlat();
497
734
  std::vector<std::vector<Index::idx_t>> ids;
@@ -571,6 +808,39 @@ Index* read_index(IOReader* f, int io_flags) {
571
808
  }
572
809
  read_InvertedLists(ivsc, f, io_flags);
573
810
  idx = ivsc;
811
+ } else if (
812
+ h == fourcc("IwLS") || h == fourcc("IwRQ") || h == fourcc("IwPL") ||
813
+ h == fourcc("IwPR")) {
814
+ bool is_LSQ = h == fourcc("IwLS");
815
+ bool is_RQ = h == fourcc("IwRQ");
816
+ bool is_PLSQ = h == fourcc("IwPL");
817
+ IndexIVFAdditiveQuantizer* iva;
818
+ if (is_LSQ) {
819
+ iva = new IndexIVFLocalSearchQuantizer();
820
+ } else if (is_RQ) {
821
+ iva = new IndexIVFResidualQuantizer();
822
+ } else if (is_PLSQ) {
823
+ iva = new IndexIVFProductLocalSearchQuantizer();
824
+ } else {
825
+ iva = new IndexIVFProductResidualQuantizer();
826
+ }
827
+ read_ivf_header(iva, f);
828
+ READ1(iva->code_size);
829
+ if (is_LSQ) {
830
+ read_LocalSearchQuantizer((LocalSearchQuantizer*)iva->aq, f);
831
+ } else if (is_RQ) {
832
+ read_ResidualQuantizer((ResidualQuantizer*)iva->aq, f);
833
+ } else if (is_PLSQ) {
834
+ read_ProductLocalSearchQuantizer(
835
+ (ProductLocalSearchQuantizer*)iva->aq, f);
836
+ } else {
837
+ read_ProductResidualQuantizer(
838
+ (ProductResidualQuantizer*)iva->aq, f);
839
+ }
840
+ READ1(iva->by_residual);
841
+ READ1(iva->use_precomputed_table);
842
+ read_InvertedLists(iva, f, io_flags);
843
+ idx = iva;
574
844
  } else if (h == fourcc("IwSh")) {
575
845
  IndexIVFSpectralHash* ivsp = new IndexIVFSpectralHash();
576
846
  read_ivf_header(ivsp, f);
@@ -668,8 +938,15 @@ Index* read_index(IOReader* f, int io_flags) {
668
938
  dynamic_cast<IndexPQ*>(idxhnsw->storage)->pq.compute_sdc_table();
669
939
  }
670
940
  idx = idxhnsw;
671
- } else if (h == fourcc("INSf")) {
672
- IndexNSG* idxnsg = new IndexNSGFlat();
941
+ } else if (
942
+ h == fourcc("INSf") || h == fourcc("INSp") || h == fourcc("INSs")) {
943
+ IndexNSG* idxnsg;
944
+ if (h == fourcc("INSf"))
945
+ idxnsg = new IndexNSGFlat();
946
+ if (h == fourcc("INSp"))
947
+ idxnsg = new IndexNSGPQ();
948
+ if (h == fourcc("INSs"))
949
+ idxnsg = new IndexNSGSQ();
673
950
  read_index_header(idxnsg, f);
674
951
  READ1(idxnsg->GK);
675
952
  READ1(idxnsg->build_type);
@@ -681,6 +958,13 @@ Index* read_index(IOReader* f, int io_flags) {
681
958
  idxnsg->storage = read_index(f, io_flags);
682
959
  idxnsg->own_fields = true;
683
960
  idx = idxnsg;
961
+ } else if (h == fourcc("INNf")) {
962
+ IndexNNDescent* idxnnd = new IndexNNDescentFlat();
963
+ read_index_header(idxnnd, f);
964
+ read_NNDescent(&idxnnd->nndescent, f);
965
+ idxnnd->storage = read_index(f, io_flags);
966
+ idxnnd->own_fields = true;
967
+ idx = idxnnd;
684
968
  } else if (h == fourcc("IPfs")) {
685
969
  IndexPQFastScan* idxpqfs = new IndexPQFastScan();
686
970
  read_index_header(idxpqfs, f);
@@ -691,6 +975,13 @@ Index* read_index(IOReader* f, int io_flags) {
691
975
  READ1(idxpqfs->ntotal2);
692
976
  READ1(idxpqfs->M2);
693
977
  READVECTOR(idxpqfs->codes);
978
+
979
+ const auto& pq = idxpqfs->pq;
980
+ idxpqfs->M = pq.M;
981
+ idxpqfs->nbits = pq.nbits;
982
+ idxpqfs->ksub = (1 << pq.nbits);
983
+ idxpqfs->code_size = pq.code_size;
984
+
694
985
  idx = idxpqfs;
695
986
 
696
987
  } else if (h == fourcc("IwPf")) {
@@ -705,7 +996,30 @@ Index* read_index(IOReader* f, int io_flags) {
705
996
  read_ProductQuantizer(&ivpq->pq, f);
706
997
  read_InvertedLists(ivpq, f, io_flags);
707
998
  ivpq->precompute_table();
999
+
1000
+ const auto& pq = ivpq->pq;
1001
+ ivpq->M = pq.M;
1002
+ ivpq->nbits = pq.nbits;
1003
+ ivpq->ksub = (1 << pq.nbits);
1004
+ ivpq->code_size = pq.code_size;
1005
+
708
1006
  idx = ivpq;
1007
+ } else if (h == fourcc("IRMf")) {
1008
+ IndexRowwiseMinMax* imm = new IndexRowwiseMinMax();
1009
+ read_index_header(imm, f);
1010
+
1011
+ imm->index = read_index(f, io_flags);
1012
+ imm->own_fields = true;
1013
+
1014
+ idx = imm;
1015
+ } else if (h == fourcc("IRMh")) {
1016
+ IndexRowwiseMinMaxFP16* imm = new IndexRowwiseMinMaxFP16();
1017
+ read_index_header(imm, f);
1018
+
1019
+ imm->index = read_index(f, io_flags);
1020
+ imm->own_fields = true;
1021
+
1022
+ idx = imm;
709
1023
  } else {
710
1024
  FAISS_THROW_FMT(
711
1025
  "Index type 0x%08x (\"%s\") not recognized",