faiss 0.2.3 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
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",