faiss 0.2.6 → 0.2.7

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 +4 -0
  3. data/ext/faiss/extconf.rb +1 -1
  4. data/lib/faiss/version.rb +1 -1
  5. data/lib/faiss.rb +2 -2
  6. data/vendor/faiss/faiss/AutoTune.cpp +15 -4
  7. data/vendor/faiss/faiss/AutoTune.h +0 -1
  8. data/vendor/faiss/faiss/Clustering.cpp +1 -5
  9. data/vendor/faiss/faiss/Clustering.h +0 -2
  10. data/vendor/faiss/faiss/IVFlib.h +0 -2
  11. data/vendor/faiss/faiss/Index.h +1 -2
  12. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +17 -3
  13. data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +10 -1
  14. data/vendor/faiss/faiss/IndexBinary.h +0 -1
  15. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +2 -1
  16. data/vendor/faiss/faiss/IndexBinaryFlat.h +4 -0
  17. data/vendor/faiss/faiss/IndexBinaryHash.cpp +1 -3
  18. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +273 -48
  19. data/vendor/faiss/faiss/IndexBinaryIVF.h +18 -11
  20. data/vendor/faiss/faiss/IndexFastScan.cpp +13 -10
  21. data/vendor/faiss/faiss/IndexFastScan.h +5 -1
  22. data/vendor/faiss/faiss/IndexFlat.cpp +16 -3
  23. data/vendor/faiss/faiss/IndexFlat.h +1 -1
  24. data/vendor/faiss/faiss/IndexFlatCodes.cpp +5 -0
  25. data/vendor/faiss/faiss/IndexFlatCodes.h +7 -2
  26. data/vendor/faiss/faiss/IndexHNSW.cpp +3 -6
  27. data/vendor/faiss/faiss/IndexHNSW.h +0 -1
  28. data/vendor/faiss/faiss/IndexIDMap.cpp +4 -4
  29. data/vendor/faiss/faiss/IndexIDMap.h +0 -2
  30. data/vendor/faiss/faiss/IndexIVF.cpp +155 -129
  31. data/vendor/faiss/faiss/IndexIVF.h +121 -61
  32. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +2 -2
  33. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +12 -11
  34. data/vendor/faiss/faiss/IndexIVFFastScan.h +6 -1
  35. data/vendor/faiss/faiss/IndexIVFPQ.cpp +221 -165
  36. data/vendor/faiss/faiss/IndexIVFPQ.h +1 -0
  37. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +6 -1
  38. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +0 -2
  39. data/vendor/faiss/faiss/IndexNNDescent.cpp +1 -2
  40. data/vendor/faiss/faiss/IndexNNDescent.h +0 -1
  41. data/vendor/faiss/faiss/IndexNSG.cpp +1 -2
  42. data/vendor/faiss/faiss/IndexPQ.cpp +7 -9
  43. data/vendor/faiss/faiss/IndexRefine.cpp +1 -1
  44. data/vendor/faiss/faiss/IndexReplicas.cpp +3 -4
  45. data/vendor/faiss/faiss/IndexReplicas.h +0 -1
  46. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +8 -1
  47. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +7 -0
  48. data/vendor/faiss/faiss/IndexShards.cpp +26 -109
  49. data/vendor/faiss/faiss/IndexShards.h +2 -3
  50. data/vendor/faiss/faiss/IndexShardsIVF.cpp +246 -0
  51. data/vendor/faiss/faiss/IndexShardsIVF.h +42 -0
  52. data/vendor/faiss/faiss/MetaIndexes.cpp +86 -0
  53. data/vendor/faiss/faiss/MetaIndexes.h +29 -0
  54. data/vendor/faiss/faiss/MetricType.h +14 -0
  55. data/vendor/faiss/faiss/VectorTransform.cpp +8 -10
  56. data/vendor/faiss/faiss/VectorTransform.h +1 -3
  57. data/vendor/faiss/faiss/clone_index.cpp +232 -18
  58. data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +25 -3
  59. data/vendor/faiss/faiss/cppcontrib/detail/CoarseBitType.h +7 -0
  60. data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +78 -0
  61. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +20 -6
  62. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +7 -1
  63. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +21 -7
  64. data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMax-inl.h +7 -0
  65. data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMaxFP16-inl.h +7 -0
  66. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +10 -3
  67. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +7 -1
  68. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +11 -3
  69. data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +25 -2
  70. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +76 -29
  71. data/vendor/faiss/faiss/gpu/GpuCloner.h +2 -2
  72. data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +14 -13
  73. data/vendor/faiss/faiss/gpu/GpuDistance.h +18 -6
  74. data/vendor/faiss/faiss/gpu/GpuIndex.h +23 -21
  75. data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +10 -10
  76. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +11 -12
  77. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +29 -50
  78. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +3 -3
  79. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +8 -8
  80. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +4 -4
  81. data/vendor/faiss/faiss/gpu/impl/IndexUtils.h +2 -5
  82. data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +9 -7
  83. data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +4 -4
  84. data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +2 -2
  85. data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +1 -1
  86. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +55 -6
  87. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +20 -6
  88. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +95 -25
  89. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +67 -16
  90. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +4 -4
  91. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +7 -7
  92. data/vendor/faiss/faiss/gpu/test/TestUtils.h +4 -4
  93. data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +1 -1
  94. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +6 -0
  95. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +0 -7
  96. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +9 -9
  97. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +1 -1
  98. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +2 -7
  99. data/vendor/faiss/faiss/impl/CodePacker.cpp +67 -0
  100. data/vendor/faiss/faiss/impl/CodePacker.h +71 -0
  101. data/vendor/faiss/faiss/impl/DistanceComputer.h +0 -2
  102. data/vendor/faiss/faiss/impl/HNSW.cpp +3 -7
  103. data/vendor/faiss/faiss/impl/HNSW.h +6 -9
  104. data/vendor/faiss/faiss/impl/IDSelector.cpp +1 -1
  105. data/vendor/faiss/faiss/impl/IDSelector.h +39 -1
  106. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +62 -51
  107. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +11 -12
  108. data/vendor/faiss/faiss/impl/NNDescent.cpp +3 -9
  109. data/vendor/faiss/faiss/impl/NNDescent.h +10 -10
  110. data/vendor/faiss/faiss/impl/NSG.cpp +1 -6
  111. data/vendor/faiss/faiss/impl/NSG.h +4 -7
  112. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +1 -15
  113. data/vendor/faiss/faiss/impl/PolysemousTraining.h +11 -10
  114. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +0 -7
  115. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +25 -12
  116. data/vendor/faiss/faiss/impl/ProductQuantizer.h +2 -4
  117. data/vendor/faiss/faiss/impl/Quantizer.h +6 -3
  118. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +796 -174
  119. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +16 -8
  120. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +3 -5
  121. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +4 -4
  122. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +3 -3
  123. data/vendor/faiss/faiss/impl/ThreadedIndex.h +4 -4
  124. data/vendor/faiss/faiss/impl/code_distance/code_distance-avx2.h +291 -0
  125. data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +74 -0
  126. data/vendor/faiss/faiss/impl/code_distance/code_distance.h +123 -0
  127. data/vendor/faiss/faiss/impl/code_distance/code_distance_avx512.h +102 -0
  128. data/vendor/faiss/faiss/impl/index_read.cpp +13 -10
  129. data/vendor/faiss/faiss/impl/index_write.cpp +3 -4
  130. data/vendor/faiss/faiss/impl/kmeans1d.cpp +0 -1
  131. data/vendor/faiss/faiss/impl/kmeans1d.h +3 -3
  132. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +1 -1
  133. data/vendor/faiss/faiss/impl/platform_macros.h +61 -0
  134. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +48 -4
  135. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +18 -4
  136. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +2 -2
  137. data/vendor/faiss/faiss/index_factory.cpp +8 -10
  138. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +29 -12
  139. data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +8 -2
  140. data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -1
  141. data/vendor/faiss/faiss/invlists/DirectMap.h +2 -4
  142. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +118 -18
  143. data/vendor/faiss/faiss/invlists/InvertedLists.h +44 -4
  144. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +3 -3
  145. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  146. data/vendor/faiss/faiss/python/python_callbacks.cpp +1 -1
  147. data/vendor/faiss/faiss/python/python_callbacks.h +1 -1
  148. data/vendor/faiss/faiss/utils/AlignedTable.h +3 -1
  149. data/vendor/faiss/faiss/utils/Heap.cpp +139 -3
  150. data/vendor/faiss/faiss/utils/Heap.h +35 -1
  151. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +84 -0
  152. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +196 -0
  153. data/vendor/faiss/faiss/utils/approx_topk/generic.h +138 -0
  154. data/vendor/faiss/faiss/utils/approx_topk/mode.h +34 -0
  155. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +367 -0
  156. data/vendor/faiss/faiss/utils/distances.cpp +61 -7
  157. data/vendor/faiss/faiss/utils/distances.h +11 -0
  158. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +346 -0
  159. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +36 -0
  160. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +42 -0
  161. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +40 -0
  162. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +352 -0
  163. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.h +32 -0
  164. data/vendor/faiss/faiss/utils/distances_simd.cpp +515 -327
  165. data/vendor/faiss/faiss/utils/extra_distances-inl.h +17 -1
  166. data/vendor/faiss/faiss/utils/extra_distances.cpp +37 -8
  167. data/vendor/faiss/faiss/utils/extra_distances.h +2 -1
  168. data/vendor/faiss/faiss/utils/fp16-fp16c.h +7 -0
  169. data/vendor/faiss/faiss/utils/fp16-inl.h +7 -0
  170. data/vendor/faiss/faiss/utils/fp16.h +7 -0
  171. data/vendor/faiss/faiss/utils/hamming-inl.h +0 -456
  172. data/vendor/faiss/faiss/utils/hamming.cpp +104 -120
  173. data/vendor/faiss/faiss/utils/hamming.h +21 -10
  174. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +535 -0
  175. data/vendor/faiss/faiss/utils/hamming_distance/common.h +48 -0
  176. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +519 -0
  177. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +26 -0
  178. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +614 -0
  179. data/vendor/faiss/faiss/utils/partitioning.cpp +21 -25
  180. data/vendor/faiss/faiss/utils/simdlib_avx2.h +344 -3
  181. data/vendor/faiss/faiss/utils/simdlib_emulated.h +390 -0
  182. data/vendor/faiss/faiss/utils/simdlib_neon.h +655 -130
  183. data/vendor/faiss/faiss/utils/sorting.cpp +692 -0
  184. data/vendor/faiss/faiss/utils/sorting.h +71 -0
  185. data/vendor/faiss/faiss/utils/transpose/transpose-avx2-inl.h +165 -0
  186. data/vendor/faiss/faiss/utils/utils.cpp +4 -176
  187. data/vendor/faiss/faiss/utils/utils.h +2 -9
  188. metadata +29 -3
  189. data/vendor/faiss/faiss/gpu/GpuClonerOptions.cpp +0 -26
@@ -135,7 +135,7 @@ int dgesvd_(
135
135
  * VectorTransform
136
136
  *********************************************/
137
137
 
138
- float* VectorTransform::apply(Index::idx_t n, const float* x) const {
138
+ float* VectorTransform::apply(idx_t n, const float* x) const {
139
139
  float* xt = new float[n * d_out];
140
140
  apply_noalloc(n, x, xt);
141
141
  return xt;
@@ -166,8 +166,7 @@ LinearTransform::LinearTransform(int d_in, int d_out, bool have_bias)
166
166
  is_trained = false; // will be trained when A and b are initialized
167
167
  }
168
168
 
169
- void LinearTransform::apply_noalloc(Index::idx_t n, const float* x, float* xt)
170
- const {
169
+ void LinearTransform::apply_noalloc(idx_t n, const float* x, float* xt) const {
171
170
  FAISS_THROW_IF_NOT_MSG(is_trained, "Transformation not trained yet");
172
171
 
173
172
  float c_factor;
@@ -348,7 +347,7 @@ void RandomRotationMatrix::init(int seed) {
348
347
  is_trained = true;
349
348
  }
350
349
 
351
- void RandomRotationMatrix::train(Index::idx_t /*n*/, const float* /*x*/) {
350
+ void RandomRotationMatrix::train(idx_t /*n*/, const float* /*x*/) {
352
351
  // initialize with some arbitrary seed
353
352
  init(12345);
354
353
  }
@@ -442,7 +441,7 @@ void eig(size_t d_in, double* cov, double* eigenvalues, int verbose) {
442
441
 
443
442
  } // namespace
444
443
 
445
- void PCAMatrix::train(Index::idx_t n, const float* x) {
444
+ void PCAMatrix::train(idx_t n, const float* x) {
446
445
  const float* x_in = x;
447
446
 
448
447
  x = fvecs_maybe_subsample(
@@ -733,7 +732,7 @@ ITQMatrix::ITQMatrix(int d)
733
732
  : LinearTransform(d, d, false), max_iter(50), seed(123) {}
734
733
 
735
734
  /** translated from fbcode/deeplearning/catalyzer/catalyzer/quantizers.py */
736
- void ITQMatrix::train(Index::idx_t n, const float* xf) {
735
+ void ITQMatrix::train(idx_t n, const float* xf) {
737
736
  size_t d = d_in;
738
737
  std::vector<double> rotation(d * d);
739
738
 
@@ -957,8 +956,7 @@ void ITQTransform::train(idx_t n, const float* x) {
957
956
  is_trained = true;
958
957
  }
959
958
 
960
- void ITQTransform::apply_noalloc(Index::idx_t n, const float* x, float* xt)
961
- const {
959
+ void ITQTransform::apply_noalloc(idx_t n, const float* x, float* xt) const {
962
960
  FAISS_THROW_IF_NOT_MSG(is_trained, "Transformation not trained yet");
963
961
 
964
962
  std::unique_ptr<float[]> x_norm(new float[n * d_in]);
@@ -1003,7 +1001,7 @@ OPQMatrix::OPQMatrix(int d, int M, int d2)
1003
1001
  pq = nullptr;
1004
1002
  }
1005
1003
 
1006
- void OPQMatrix::train(Index::idx_t n, const float* x) {
1004
+ void OPQMatrix::train(idx_t n, const float* x) {
1007
1005
  const float* x_in = x;
1008
1006
 
1009
1007
  x = fvecs_maybe_subsample(d_in, (size_t*)&n, max_train_points, x, verbose);
@@ -1261,7 +1259,7 @@ CenteringTransform::CenteringTransform(int d) : VectorTransform(d, d) {
1261
1259
  is_trained = false;
1262
1260
  }
1263
1261
 
1264
- void CenteringTransform::train(Index::idx_t n, const float* x) {
1262
+ void CenteringTransform::train(idx_t n, const float* x) {
1265
1263
  FAISS_THROW_IF_NOT_MSG(n > 0, "need at least one training vector");
1266
1264
  mean.resize(d_in, 0);
1267
1265
  for (idx_t i = 0; i < n; i++) {
@@ -23,8 +23,6 @@ namespace faiss {
23
23
 
24
24
  /** Any transformation applied on a set of vectors */
25
25
  struct VectorTransform {
26
- typedef Index::idx_t idx_t;
27
-
28
26
  int d_in; ///! input dimension
29
27
  int d_out; ///! output dimension
30
28
 
@@ -122,7 +120,7 @@ struct RandomRotationMatrix : LinearTransform {
122
120
  /// must be called before the transform is used
123
121
  void init(int seed);
124
122
 
125
- // intializes with an arbitrary seed
123
+ // initializes with an arbitrary seed
126
124
  void train(idx_t n, const float* x) override;
127
125
 
128
126
  RandomRotationMatrix() {}
@@ -16,18 +16,24 @@
16
16
 
17
17
  #include <faiss/Index2Layer.h>
18
18
  #include <faiss/IndexAdditiveQuantizer.h>
19
+ #include <faiss/IndexAdditiveQuantizerFastScan.h>
19
20
  #include <faiss/IndexFlat.h>
20
21
  #include <faiss/IndexHNSW.h>
21
22
  #include <faiss/IndexIVF.h>
23
+ #include <faiss/IndexIVFAdditiveQuantizerFastScan.h>
22
24
  #include <faiss/IndexIVFFlat.h>
23
25
  #include <faiss/IndexIVFPQ.h>
26
+ #include <faiss/IndexIVFPQFastScan.h>
24
27
  #include <faiss/IndexIVFPQR.h>
25
28
  #include <faiss/IndexIVFSpectralHash.h>
26
29
  #include <faiss/IndexLSH.h>
27
30
  #include <faiss/IndexLattice.h>
28
31
  #include <faiss/IndexNSG.h>
29
32
  #include <faiss/IndexPQ.h>
33
+ #include <faiss/IndexPQFastScan.h>
30
34
  #include <faiss/IndexPreTransform.h>
35
+ #include <faiss/IndexRefine.h>
36
+ #include <faiss/IndexRowwiseMinMax.h>
31
37
  #include <faiss/IndexScalarQuantizer.h>
32
38
  #include <faiss/MetaIndexes.h>
33
39
  #include <faiss/VectorTransform.h>
@@ -36,6 +42,9 @@
36
42
  #include <faiss/impl/ProductQuantizer.h>
37
43
  #include <faiss/impl/ResidualQuantizer.h>
38
44
  #include <faiss/impl/ScalarQuantizer.h>
45
+ #include <faiss/impl/pq4_fast_scan.h>
46
+
47
+ #include <faiss/invlists/BlockInvertedLists.h>
39
48
 
40
49
  namespace faiss {
41
50
 
@@ -71,39 +80,220 @@ VectorTransform* Cloner::clone_VectorTransform(const VectorTransform* vt) {
71
80
  IndexIVF* Cloner::clone_IndexIVF(const IndexIVF* ivf) {
72
81
  TRYCLONE(IndexIVFPQR, ivf)
73
82
  TRYCLONE(IndexIVFPQ, ivf)
83
+
84
+ TRYCLONE(IndexIVFLocalSearchQuantizer, ivf)
85
+ TRYCLONE(IndexIVFProductLocalSearchQuantizer, ivf)
86
+ TRYCLONE(IndexIVFProductResidualQuantizer, ivf)
87
+ TRYCLONE(IndexIVFResidualQuantizer, ivf)
88
+
89
+ TRYCLONE(IndexIVFLocalSearchQuantizerFastScan, ivf)
90
+ TRYCLONE(IndexIVFProductLocalSearchQuantizerFastScan, ivf)
91
+ TRYCLONE(IndexIVFProductResidualQuantizerFastScan, ivf)
92
+ TRYCLONE(IndexIVFResidualQuantizerFastScan, ivf)
93
+ TRYCLONE(IndexIVFPQFastScan, ivf)
94
+
95
+ TRYCLONE(IndexIVFFlatDedup, ivf)
74
96
  TRYCLONE(IndexIVFFlat, ivf)
97
+
98
+ TRYCLONE(IndexIVFSpectralHash, ivf)
99
+
75
100
  TRYCLONE(IndexIVFScalarQuantizer, ivf) {
76
101
  FAISS_THROW_MSG("clone not supported for this type of IndexIVF");
77
102
  }
78
103
  return nullptr;
79
104
  }
80
105
 
106
+ IndexRefine* clone_IndexRefine(const IndexRefine* ir) {
107
+ TRYCLONE(IndexRefineFlat, ir)
108
+ TRYCLONE(IndexRefine, ir) {
109
+ FAISS_THROW_MSG("clone not supported for this type of IndexRefine");
110
+ }
111
+ }
112
+
113
+ IndexIDMap* clone_IndexIDMap(const IndexIDMap* im) {
114
+ TRYCLONE(IndexIDMap2, im)
115
+ TRYCLONE(IndexIDMap, im) {
116
+ FAISS_THROW_MSG("clone not supported for this type of IndexIDMap");
117
+ }
118
+ }
119
+
120
+ IndexHNSW* clone_IndexHNSW(const IndexHNSW* ihnsw) {
121
+ TRYCLONE(IndexHNSW2Level, ihnsw)
122
+ TRYCLONE(IndexHNSWFlat, ihnsw)
123
+ TRYCLONE(IndexHNSWPQ, ihnsw)
124
+ TRYCLONE(IndexHNSWSQ, ihnsw)
125
+ TRYCLONE(IndexHNSW, ihnsw) {
126
+ FAISS_THROW_MSG("clone not supported for this type of IndexHNSW");
127
+ }
128
+ }
129
+
130
+ IndexNNDescent* clone_IndexNNDescent(const IndexNNDescent* innd) {
131
+ TRYCLONE(IndexNNDescentFlat, innd)
132
+ TRYCLONE(IndexNNDescent, innd) {
133
+ FAISS_THROW_MSG("clone not supported for this type of IndexNNDescent");
134
+ }
135
+ }
136
+
137
+ IndexNSG* clone_IndexNSG(const IndexNSG* insg) {
138
+ TRYCLONE(IndexNSGFlat, insg)
139
+ TRYCLONE(IndexNSGPQ, insg)
140
+ TRYCLONE(IndexNSGSQ, insg)
141
+ TRYCLONE(IndexNSG, insg) {
142
+ FAISS_THROW_MSG("clone not supported for this type of IndexNNDescent");
143
+ }
144
+ }
145
+
146
+ IndexRowwiseMinMaxBase* clone_IndexRowwiseMinMax(
147
+ const IndexRowwiseMinMaxBase* irmmb) {
148
+ TRYCLONE(IndexRowwiseMinMaxFP16, irmmb)
149
+ TRYCLONE(IndexRowwiseMinMax, irmmb) {
150
+ FAISS_THROW_MSG(
151
+ "clone not supported for this type of IndexRowwiseMinMax");
152
+ }
153
+ }
154
+
155
+ #define TRYCAST(classname) classname* res = dynamic_cast<classname*>(index)
156
+
157
+ void reset_AdditiveQuantizerIndex(Index* index) {
158
+ auto clone_ProductQuantizers =
159
+ [](std::vector<AdditiveQuantizer*>& quantizers) {
160
+ for (auto& q : quantizers) {
161
+ q = dynamic_cast<AdditiveQuantizer*>(clone_Quantizer(q));
162
+ }
163
+ };
164
+ if (TRYCAST(IndexIVFLocalSearchQuantizerFastScan)) {
165
+ res->aq = &res->lsq;
166
+ } else if (TRYCAST(IndexIVFResidualQuantizerFastScan)) {
167
+ res->aq = &res->rq;
168
+ } else if (TRYCAST(IndexIVFProductLocalSearchQuantizerFastScan)) {
169
+ res->aq = &res->plsq;
170
+ clone_ProductQuantizers(res->plsq.quantizers);
171
+ } else if (TRYCAST(IndexIVFProductResidualQuantizerFastScan)) {
172
+ res->aq = &res->prq;
173
+ clone_ProductQuantizers(res->prq.quantizers);
174
+ } else if (TRYCAST(IndexIVFLocalSearchQuantizer)) {
175
+ res->aq = &res->lsq;
176
+ } else if (TRYCAST(IndexIVFResidualQuantizer)) {
177
+ res->aq = &res->rq;
178
+ } else if (TRYCAST(IndexIVFProductLocalSearchQuantizer)) {
179
+ res->aq = &res->plsq;
180
+ clone_ProductQuantizers(res->plsq.quantizers);
181
+ } else if (TRYCAST(IndexIVFProductResidualQuantizer)) {
182
+ res->aq = &res->prq;
183
+ clone_ProductQuantizers(res->prq.quantizers);
184
+ } else if (TRYCAST(IndexLocalSearchQuantizerFastScan)) {
185
+ res->aq = &res->lsq;
186
+ } else if (TRYCAST(IndexResidualQuantizerFastScan)) {
187
+ res->aq = &res->rq;
188
+ } else if (TRYCAST(IndexProductLocalSearchQuantizerFastScan)) {
189
+ res->aq = &res->plsq;
190
+ clone_ProductQuantizers(res->plsq.quantizers);
191
+ } else if (TRYCAST(IndexProductResidualQuantizerFastScan)) {
192
+ res->aq = &res->prq;
193
+ clone_ProductQuantizers(res->prq.quantizers);
194
+ } else if (TRYCAST(IndexLocalSearchQuantizer)) {
195
+ res->aq = &res->lsq;
196
+ } else if (TRYCAST(IndexResidualQuantizer)) {
197
+ res->aq = &res->rq;
198
+ } else if (TRYCAST(IndexProductLocalSearchQuantizer)) {
199
+ res->aq = &res->plsq;
200
+ clone_ProductQuantizers(res->plsq.quantizers);
201
+ } else if (TRYCAST(IndexProductResidualQuantizer)) {
202
+ res->aq = &res->prq;
203
+ clone_ProductQuantizers(res->prq.quantizers);
204
+ } else if (TRYCAST(LocalSearchCoarseQuantizer)) {
205
+ res->aq = &res->lsq;
206
+ } else if (TRYCAST(ResidualCoarseQuantizer)) {
207
+ res->aq = &res->rq;
208
+ } else {
209
+ FAISS_THROW_MSG(
210
+ "clone not supported for this type of additive quantizer index");
211
+ }
212
+ }
213
+
214
+ Index* clone_AdditiveQuantizerIndex(const Index* index) {
215
+ // IndexAdditiveQuantizer
216
+ TRYCLONE(IndexResidualQuantizer, index)
217
+ TRYCLONE(IndexProductResidualQuantizer, index)
218
+ TRYCLONE(IndexLocalSearchQuantizer, index)
219
+ TRYCLONE(IndexProductLocalSearchQuantizer, index)
220
+
221
+ // IndexFastScan
222
+ TRYCLONE(IndexResidualQuantizerFastScan, index)
223
+ TRYCLONE(IndexLocalSearchQuantizerFastScan, index)
224
+ TRYCLONE(IndexProductResidualQuantizerFastScan, index)
225
+ TRYCLONE(IndexProductLocalSearchQuantizerFastScan, index)
226
+
227
+ // AdditiveCoarseQuantizer
228
+ TRYCLONE(ResidualCoarseQuantizer, index)
229
+ TRYCLONE(LocalSearchCoarseQuantizer, index) {
230
+ FAISS_THROW_MSG(
231
+ "clone not supported for this type of additive quantizer index");
232
+ }
233
+ }
234
+
235
+ namespace {
236
+
237
+ IndexHNSW* clone_HNSW(const IndexHNSW* ihnsw) {
238
+ TRYCLONE(IndexHNSWFlat, ihnsw)
239
+ TRYCLONE(IndexHNSWPQ, ihnsw)
240
+ TRYCLONE(IndexHNSWSQ, ihnsw)
241
+ return new IndexHNSW(*ihnsw);
242
+ }
243
+
244
+ InvertedLists* clone_InvertedLists(const InvertedLists* invlists) {
245
+ if (auto* ails = dynamic_cast<const ArrayInvertedLists*>(invlists)) {
246
+ return new ArrayInvertedLists(*ails);
247
+ }
248
+ if (auto* bils = dynamic_cast<const BlockInvertedLists*>(invlists)) {
249
+ auto* bils2 = new BlockInvertedLists(*bils);
250
+ if (bils->packer) {
251
+ auto* packerPQ4 = dynamic_cast<const CodePackerPQ4*>(bils->packer);
252
+ FAISS_THROW_IF_NOT(packerPQ4);
253
+ bils2->packer = new CodePackerPQ4(*packerPQ4);
254
+ }
255
+ return bils2;
256
+ }
257
+ FAISS_THROW_FMT(
258
+ "clone not supported for this type of inverted lists %s",
259
+ typeid(*invlists).name());
260
+ }
261
+
262
+ } // anonymous namespace
263
+
81
264
  Index* Cloner::clone_Index(const Index* index) {
82
265
  TRYCLONE(IndexPQ, index)
83
266
  TRYCLONE(IndexLSH, index)
267
+
268
+ // IndexFlat
269
+ TRYCLONE(IndexFlat1D, index)
84
270
  TRYCLONE(IndexFlatL2, index)
85
271
  TRYCLONE(IndexFlatIP, index)
86
272
  TRYCLONE(IndexFlat, index)
273
+
87
274
  TRYCLONE(IndexLattice, index)
88
- TRYCLONE(IndexResidualQuantizer, index)
275
+ TRYCLONE(IndexRandom, index)
276
+ TRYCLONE(IndexPQFastScan, index)
277
+
89
278
  TRYCLONE(IndexScalarQuantizer, index)
90
279
  TRYCLONE(MultiIndexQuantizer, index)
91
- TRYCLONE(ResidualCoarseQuantizer, index)
280
+
92
281
  if (const IndexIVF* ivf = dynamic_cast<const IndexIVF*>(index)) {
93
282
  IndexIVF* res = clone_IndexIVF(ivf);
94
283
  if (ivf->invlists == nullptr) {
95
284
  res->invlists = nullptr;
96
- } else if (
97
- auto* ails = dynamic_cast<const ArrayInvertedLists*>(
98
- ivf->invlists)) {
99
- res->invlists = new ArrayInvertedLists(*ails);
100
- res->own_invlists = true;
101
285
  } else {
102
- FAISS_THROW_MSG(
103
- "clone not supported for this type of inverted lists");
286
+ res->invlists = clone_InvertedLists(ivf->invlists);
287
+ res->own_invlists = true;
104
288
  }
289
+
105
290
  res->own_fields = true;
106
291
  res->quantizer = clone_Index(ivf->quantizer);
292
+
293
+ if (dynamic_cast<const IndexIVFAdditiveQuantizerFastScan*>(res) ||
294
+ dynamic_cast<const IndexIVFAdditiveQuantizer*>(res)) {
295
+ reset_AdditiveQuantizerIndex(res);
296
+ }
107
297
  return res;
108
298
  } else if (
109
299
  const IndexPreTransform* ipt =
@@ -122,19 +312,18 @@ Index* Cloner::clone_Index(const Index* index) {
122
312
  return res;
123
313
  } else if (
124
314
  const IndexIDMap* idmap = dynamic_cast<const IndexIDMap*>(index)) {
125
- const IndexIDMap2* idmap2 = dynamic_cast<const IndexIDMap2*>(index);
126
- IndexIDMap* res =
127
- idmap2 ? new IndexIDMap2(*idmap2) : new IndexIDMap(*idmap);
315
+ IndexIDMap* res = clone_IndexIDMap(idmap);
128
316
  res->own_fields = true;
129
317
  res->index = clone_Index(idmap->index);
130
318
  return res;
131
319
  } else if (const IndexHNSW* ihnsw = dynamic_cast<const IndexHNSW*>(index)) {
132
- IndexHNSW* res = new IndexHNSW(*ihnsw);
320
+ IndexHNSW* res = clone_IndexHNSW(ihnsw);
133
321
  res->own_fields = true;
134
- res->storage = clone_Index(ihnsw->storage);
322
+ // make sure we don't get a GPU index here
323
+ res->storage = Cloner::clone_Index(ihnsw->storage);
135
324
  return res;
136
325
  } else if (const IndexNSG* insg = dynamic_cast<const IndexNSG*>(index)) {
137
- IndexNSG* res = new IndexNSG(*insg);
326
+ IndexNSG* res = clone_IndexNSG(insg);
138
327
 
139
328
  // copy the dynamic allocated graph
140
329
  auto& new_graph = res->nsg.final_graph;
@@ -147,7 +336,7 @@ Index* Cloner::clone_Index(const Index* index) {
147
336
  } else if (
148
337
  const IndexNNDescent* innd =
149
338
  dynamic_cast<const IndexNNDescent*>(index)) {
150
- IndexNNDescent* res = new IndexNNDescent(*innd);
339
+ IndexNNDescent* res = clone_IndexNNDescent(innd);
151
340
  res->own_fields = true;
152
341
  res->storage = clone_Index(innd->storage);
153
342
  return res;
@@ -157,11 +346,36 @@ Index* Cloner::clone_Index(const Index* index) {
157
346
  res->q1.own_fields = true;
158
347
  res->q1.quantizer = clone_Index(i2l->q1.quantizer);
159
348
  return res;
349
+ } else if (
350
+ const IndexRefine* ir = dynamic_cast<const IndexRefine*>(index)) {
351
+ IndexRefine* res = clone_IndexRefine(ir);
352
+ res->own_fields = true;
353
+ res->base_index = clone_Index(ir->base_index);
354
+ if (ir->refine_index != nullptr) {
355
+ res->own_refine_index = true;
356
+ res->refine_index = clone_Index(ir->refine_index);
357
+ }
358
+ return res;
359
+ } else if (
360
+ const IndexRowwiseMinMaxBase* irmmb =
361
+ dynamic_cast<const IndexRowwiseMinMaxBase*>(index)) {
362
+ IndexRowwiseMinMaxBase* res = clone_IndexRowwiseMinMax(irmmb);
363
+ res->own_fields = true;
364
+ res->index = clone_Index(irmmb->index);
365
+ } else if (
366
+ dynamic_cast<const IndexAdditiveQuantizerFastScan*>(index) ||
367
+ dynamic_cast<const IndexAdditiveQuantizer*>(index) ||
368
+ dynamic_cast<const AdditiveCoarseQuantizer*>(index)) {
369
+ Index* res = clone_AdditiveQuantizerIndex(index);
370
+ reset_AdditiveQuantizerIndex(res);
371
+ return res;
160
372
  } else {
161
- FAISS_THROW_MSG("clone not supported for this type of Index");
373
+ FAISS_THROW_FMT(
374
+ "clone not supported for this Index type %s",
375
+ typeid(*index).name());
162
376
  }
163
377
  return nullptr;
164
- }
378
+ } // namespace
165
379
 
166
380
  Quantizer* clone_Quantizer(const Quantizer* quant) {
167
381
  TRYCLONE(ResidualQuantizer, quant)
@@ -1,4 +1,9 @@
1
- // (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary.
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
2
7
 
3
8
  #pragma once
4
9
 
@@ -11,19 +16,32 @@
11
16
  // * PQ[1]x8
12
17
  // Additionally, AVX2 and ARM versions support
13
18
  // * Residual[1]x8,PQ[2]x10
19
+ // * Residual[1]x8,PQ[2]x12
14
20
  // * Residual[1]x8,PQ[2]x16
15
21
  // * Residual[1]x10,PQ[2]x10
22
+ // * Residual[1]x10,PQ[2]x12
16
23
  // * Residual[1]x10,PQ[2]x16
24
+ // * Residual[1]x12,PQ[2]x10
25
+ // * Residual[1]x12,PQ[2]x12
26
+ // * Residual[1]x12,PQ[2]x16
17
27
  // * Residual[1]x16,PQ[2]x10
28
+ // * Residual[1]x16,PQ[2]x12
18
29
  // * Residual[1]x16,PQ[2]x16
19
30
  // * Residual1x[9-16 bit],PQ[1]x10 (such as Residual1x9,PQ16x10)
20
31
  // * * (use with COARSE_BITS=16)
32
+ // * Residual1x[9-16 bit],PQ[1]x12 (such as Residual1x9,PQ16x12)
33
+ // * * (use with COARSE_BITS=16)
21
34
  // * Residual1x[9-16 bit],PQ[1]x16 (such as Residual1x9,PQ16x16)
22
35
  // * * (use with COARSE_BITS=16)
23
36
  // * PQ[1]x10
37
+ // * PQ[1]x12
24
38
  // * PQ[1]x16
25
- // Unfortunately, currently Faiss does not support something like
26
- // IVF256,PQ16x10np
39
+ // * IVF256,PQ[1]x10 (such as IVF256,PQ16x10np)
40
+ // * IVF256,PQ[1]x12 (such as IVF256,PQ16x12np)
41
+ // * IVF256,PQ[1]x16 (such as IVF256,PQ16x16np)
42
+ // * IVF[2^9-2^16 bit],PQ[1]x10 (such as IVF1024,PQ16x10np)
43
+ // * IVF[2^9-2^16 bit],PQ[1]x12 (such as IVF1024,PQ16x12np)
44
+ // * IVF[2^9-2^16 bit],PQ[1]x16 (such as IVF1024,PQ16x16np)
27
45
  //
28
46
  // The goal was to achieve the maximum performance, so the template version it
29
47
  // is. The provided index families share the same code for sa_decode.
@@ -57,6 +75,10 @@
57
75
  // decoder.
58
76
  // For example, "Residual4x10,PQ16x10np" for 256-dim data translates into
59
77
  // Index2LevelDecoder<256,64,16,10,10>
78
+ // For example, "IVF1024,PQ16x10np" for 256-dim data translates into
79
+ // Index2LevelDecoder<256,256,16,10,10>. But as there are only 1 coarse code
80
+ // element, Index2LevelDecoder<256,256,16,16,10> can be used as a faster
81
+ // decoder.
60
82
  //
61
83
  // Additional supported values for COARSE_BITS and FINE_BITS may be added later.
62
84
  //
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
1
8
  #pragma once
2
9
 
3
10
  #include <cstdint>
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
1
8
  #pragma once
2
9
 
3
10
  #include <cstdint>
@@ -120,6 +127,72 @@ struct Uint10Reader {
120
127
  }
121
128
  };
122
129
 
130
+ // reduces the number of read operations from RAM
131
+ ///////////////////////////////////////////////
132
+ // 76543210 76543210 76543210 76543210 76543210 76543210
133
+ // 00000000 0000
134
+ // 1111 11111111
135
+ // 22222222 2222
136
+ // 3333 33333333
137
+ template <intptr_t N_ELEMENTS, intptr_t CPOS>
138
+ struct Uint12Reader {
139
+ static_assert(CPOS < N_ELEMENTS, "CPOS should be less than N_ELEMENTS");
140
+
141
+ static intptr_t get(const uint8_t* const __restrict codes) {
142
+ // Read using 4-bytes or 2-bytes.
143
+
144
+ constexpr intptr_t ELEMENT_TO_READ = CPOS / 4;
145
+ constexpr intptr_t SUB_ELEMENT = CPOS % 4;
146
+
147
+ switch (SUB_ELEMENT) {
148
+ case 0: {
149
+ if (N_ELEMENTS > CPOS + 2) {
150
+ const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
151
+ codes + ELEMENT_TO_READ * 6);
152
+ return (code32 & 0b0000111111111111);
153
+ } else {
154
+ const uint16_t code16 = *reinterpret_cast<const uint16_t*>(
155
+ codes + ELEMENT_TO_READ * 6 + 0);
156
+ return (code16 & 0b0000111111111111);
157
+ }
158
+ }
159
+ case 1: {
160
+ if (N_ELEMENTS > CPOS + 1) {
161
+ const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
162
+ codes + ELEMENT_TO_READ * 6);
163
+ return (code32 & 0b111111111111000000000000) >> 12;
164
+ } else {
165
+ const uint16_t code16 = *reinterpret_cast<const uint16_t*>(
166
+ codes + ELEMENT_TO_READ * 6 + 1);
167
+ return (code16 & 0b1111111111110000) >> 4;
168
+ }
169
+ }
170
+ case 2: {
171
+ if (N_ELEMENTS > CPOS + 1) {
172
+ const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
173
+ codes + ELEMENT_TO_READ * 6 + 2);
174
+ return (code32 & 0b000011111111111100000000) >> 8;
175
+ } else {
176
+ const uint16_t code16 = *reinterpret_cast<const uint16_t*>(
177
+ codes + ELEMENT_TO_READ * 6 + 3);
178
+ return (code16 & 0b0000111111111111);
179
+ }
180
+ }
181
+ case 3: {
182
+ if (N_ELEMENTS > CPOS) {
183
+ const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
184
+ codes + ELEMENT_TO_READ * 6 + 2);
185
+ return (code32 & 0b11111111111100000000000000000000) >> 20;
186
+ } else {
187
+ const uint16_t code16 = *reinterpret_cast<const uint16_t*>(
188
+ codes + ELEMENT_TO_READ * 6 + 4);
189
+ return (code16 & 0b1111111111110000) >> 4;
190
+ }
191
+ }
192
+ }
193
+ }
194
+ };
195
+
123
196
  // reduces the number of read operations from RAM
124
197
  template <intptr_t N_ELEMENTS, intptr_t CPOS>
125
198
  struct Uint16Reader {
@@ -173,6 +246,11 @@ struct UintReaderImplType<N_ELEMENTS, 10, CPOS> {
173
246
  using reader_type = Uint10Reader<N_ELEMENTS, CPOS>;
174
247
  };
175
248
 
249
+ template <intptr_t N_ELEMENTS, intptr_t CPOS>
250
+ struct UintReaderImplType<N_ELEMENTS, 12, CPOS> {
251
+ using reader_type = Uint12Reader<N_ELEMENTS, CPOS>;
252
+ };
253
+
176
254
  template <intptr_t N_ELEMENTS, intptr_t CPOS>
177
255
  struct UintReaderImplType<N_ELEMENTS, 16, CPOS> {
178
256
  using reader_type = Uint16Reader<N_ELEMENTS, CPOS>;
@@ -1,4 +1,10 @@
1
- // (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary.
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
2
8
  #ifndef LEVEL2_AVX2_INL_H
3
9
  #define LEVEL2_AVX2_INL_H
4
10
 
@@ -1851,8 +1857,14 @@ struct Index2LevelDecoderImpl<
1851
1857
  } // namespace
1852
1858
 
1853
1859
  // Suitable for IVF256,PQ[1]x8
1860
+ // Subtable for IVF256,PQ[1]x10 (such as IVF256,PQ16x10np)
1861
+ // Subtable for IVF256,PQ[1]x12 (such as IVF256,PQ16x12np)
1862
+ // Suitable for IVF256,PQ[1]x16 (such as IVF256,PQ16x16np)
1854
1863
  // Suitable for Residual[1]x8,PQ[2]x8
1855
- // Suitable for IVF[9-16 bit],PQ[1]x8 (such as IVF1024,PQ16np)
1864
+ // Suitable for IVF[2^9-2^16 bit],PQ[1]x8 (such as IVF1024,PQ16np)
1865
+ // Suitable for IVF[2^9-2^16 bit],PQ[1]x10 (such as IVF1024,PQ16x10np)
1866
+ // Suitable for IVF[2^9-2^16 bit],PQ[1]x12 (such as IVF1024,PQ16x12np)
1867
+ // Suitable for IVF[2^9-2^16 bit],PQ[1]x16 (such as IVF1024,PQ16x16np)
1856
1868
  // Suitable for Residual[1]x[9-16 bit],PQ[2]x[3] (such as Residual2x9,PQ8)
1857
1869
  template <
1858
1870
  intptr_t DIM,
@@ -1862,11 +1874,13 @@ template <
1862
1874
  intptr_t FINE_BITS = 8>
1863
1875
  struct Index2LevelDecoder {
1864
1876
  static_assert(
1865
- COARSE_BITS == 8 || COARSE_BITS == 10 || COARSE_BITS == 16,
1866
- "Only 8, 10 or 16 bits are currently supported for COARSE_BITS");
1877
+ COARSE_BITS == 8 || COARSE_BITS == 10 || COARSE_BITS == 12 ||
1878
+ COARSE_BITS == 16,
1879
+ "Only 8, 10, 12 or 16 bits are currently supported for COARSE_BITS");
1867
1880
  static_assert(
1868
- FINE_BITS == 8 || FINE_BITS == 10 || FINE_BITS == 16,
1869
- "Only 8, 10 or 16 bits are currently supported for FINE_BITS");
1881
+ FINE_BITS == 8 || FINE_BITS == 10 || FINE_BITS == 12 ||
1882
+ FINE_BITS == 16,
1883
+ "Only 8, 10, 12 or 16 bits are currently supported for FINE_BITS");
1870
1884
 
1871
1885
  static constexpr intptr_t dim = DIM;
1872
1886
  static constexpr intptr_t coarseSize = COARSE_SIZE;
@@ -1,4 +1,10 @@
1
- // (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary.
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
2
8
  #ifndef LEVEL2_INL_H
3
9
  #define LEVEL2_INL_H
4
10