faiss 0.5.2 → 0.6.0

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 (169) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/LICENSE.txt +1 -1
  4. data/ext/faiss/ext.cpp +1 -1
  5. data/ext/faiss/extconf.rb +5 -6
  6. data/ext/faiss/index_binary.cpp +76 -17
  7. data/ext/faiss/{index.cpp → index_rb.cpp} +108 -35
  8. data/ext/faiss/kmeans.cpp +12 -9
  9. data/ext/faiss/numo.hpp +11 -9
  10. data/ext/faiss/pca_matrix.cpp +10 -8
  11. data/ext/faiss/product_quantizer.cpp +14 -12
  12. data/ext/faiss/{utils.cpp → utils_rb.cpp} +10 -3
  13. data/ext/faiss/{utils.h → utils_rb.h} +6 -0
  14. data/lib/faiss/version.rb +1 -1
  15. data/lib/faiss.rb +1 -1
  16. data/vendor/faiss/faiss/AutoTune.cpp +130 -11
  17. data/vendor/faiss/faiss/AutoTune.h +14 -1
  18. data/vendor/faiss/faiss/Clustering.cpp +59 -10
  19. data/vendor/faiss/faiss/Clustering.h +12 -0
  20. data/vendor/faiss/faiss/IVFlib.cpp +31 -28
  21. data/vendor/faiss/faiss/Index.cpp +20 -8
  22. data/vendor/faiss/faiss/Index.h +25 -3
  23. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +19 -24
  24. data/vendor/faiss/faiss/IndexBinary.cpp +1 -0
  25. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +9 -4
  26. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +45 -11
  27. data/vendor/faiss/faiss/IndexFastScan.cpp +35 -22
  28. data/vendor/faiss/faiss/IndexFastScan.h +10 -1
  29. data/vendor/faiss/faiss/IndexFlat.cpp +193 -136
  30. data/vendor/faiss/faiss/IndexFlat.h +16 -1
  31. data/vendor/faiss/faiss/IndexFlatCodes.cpp +46 -22
  32. data/vendor/faiss/faiss/IndexFlatCodes.h +7 -1
  33. data/vendor/faiss/faiss/IndexHNSW.cpp +24 -50
  34. data/vendor/faiss/faiss/IndexHNSW.h +14 -12
  35. data/vendor/faiss/faiss/IndexIDMap.cpp +1 -1
  36. data/vendor/faiss/faiss/IndexIVF.cpp +76 -49
  37. data/vendor/faiss/faiss/IndexIVF.h +14 -4
  38. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +11 -8
  39. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +2 -2
  40. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +25 -14
  41. data/vendor/faiss/faiss/IndexIVFFastScan.h +26 -22
  42. data/vendor/faiss/faiss/IndexIVFFlat.cpp +10 -61
  43. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +39 -111
  44. data/vendor/faiss/faiss/IndexIVFPQ.cpp +89 -147
  45. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +37 -5
  46. data/vendor/faiss/faiss/IndexIVFPQR.cpp +2 -1
  47. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +42 -30
  48. data/vendor/faiss/faiss/IndexIVFRaBitQ.h +2 -2
  49. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +246 -97
  50. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +32 -29
  51. data/vendor/faiss/faiss/IndexLSH.cpp +8 -6
  52. data/vendor/faiss/faiss/IndexLattice.cpp +29 -24
  53. data/vendor/faiss/faiss/IndexNNDescent.cpp +1 -0
  54. data/vendor/faiss/faiss/IndexNSG.cpp +2 -1
  55. data/vendor/faiss/faiss/IndexNSG.h +0 -2
  56. data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +1 -1
  57. data/vendor/faiss/faiss/IndexPQ.cpp +19 -10
  58. data/vendor/faiss/faiss/IndexRaBitQ.cpp +26 -13
  59. data/vendor/faiss/faiss/IndexRaBitQ.h +2 -2
  60. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +132 -78
  61. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +14 -12
  62. data/vendor/faiss/faiss/IndexRefine.cpp +0 -30
  63. data/vendor/faiss/faiss/IndexShards.cpp +3 -4
  64. data/vendor/faiss/faiss/MetricType.h +16 -0
  65. data/vendor/faiss/faiss/VectorTransform.cpp +120 -0
  66. data/vendor/faiss/faiss/VectorTransform.h +23 -0
  67. data/vendor/faiss/faiss/clone_index.cpp +7 -4
  68. data/vendor/faiss/faiss/{cppcontrib/factory_tools.cpp → factory_tools.cpp} +1 -1
  69. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +1 -1
  70. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +37 -11
  71. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +0 -28
  72. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +367 -0
  73. data/vendor/faiss/faiss/impl/ClusteringInitialization.h +107 -0
  74. data/vendor/faiss/faiss/impl/CodePacker.cpp +4 -0
  75. data/vendor/faiss/faiss/impl/CodePacker.h +11 -3
  76. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +83 -0
  77. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.h +47 -0
  78. data/vendor/faiss/faiss/impl/FaissAssert.h +60 -2
  79. data/vendor/faiss/faiss/impl/HNSW.cpp +25 -34
  80. data/vendor/faiss/faiss/impl/HNSW.h +8 -6
  81. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +34 -27
  82. data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -1
  83. data/vendor/faiss/faiss/impl/NSG.cpp +6 -5
  84. data/vendor/faiss/faiss/impl/NSG.h +17 -7
  85. data/vendor/faiss/faiss/impl/Panorama.cpp +53 -46
  86. data/vendor/faiss/faiss/impl/Panorama.h +22 -6
  87. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +16 -5
  88. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +70 -58
  89. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +92 -0
  90. data/vendor/faiss/faiss/impl/RaBitQUtils.h +93 -31
  91. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +12 -28
  92. data/vendor/faiss/faiss/impl/RaBitQuantizer.h +3 -10
  93. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +15 -41
  94. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.h +0 -4
  95. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +14 -9
  96. data/vendor/faiss/faiss/impl/ResultHandler.h +131 -50
  97. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +67 -2358
  98. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +0 -2
  99. data/vendor/faiss/faiss/impl/VisitedTable.cpp +42 -0
  100. data/vendor/faiss/faiss/impl/VisitedTable.h +69 -0
  101. data/vendor/faiss/faiss/impl/expanded_scanners.h +158 -0
  102. data/vendor/faiss/faiss/impl/index_read.cpp +829 -471
  103. data/vendor/faiss/faiss/impl/index_read_utils.h +0 -1
  104. data/vendor/faiss/faiss/impl/index_write.cpp +17 -8
  105. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +47 -20
  106. data/vendor/faiss/faiss/impl/mapped_io.cpp +9 -2
  107. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +7 -2
  108. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +11 -3
  109. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +19 -13
  110. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +29 -21
  111. data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx2.h → pq_code_distance/pq_code_distance-avx2.cpp} +42 -215
  112. data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx512.h → pq_code_distance/pq_code_distance-avx512.cpp} +68 -107
  113. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +141 -0
  114. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +23 -0
  115. data/vendor/faiss/faiss/impl/{code_distance/code_distance-sve.h → pq_code_distance/pq_code_distance-sve.cpp} +57 -144
  116. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +9 -6
  117. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +121 -0
  118. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +136 -0
  119. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +280 -0
  120. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +164 -0
  121. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +94 -0
  122. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +455 -0
  123. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +430 -0
  124. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +329 -0
  125. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +467 -0
  126. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +203 -0
  127. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +42 -0
  128. data/vendor/faiss/faiss/impl/simd_dispatch.h +139 -0
  129. data/vendor/faiss/faiss/impl/simd_result_handlers.h +18 -18
  130. data/vendor/faiss/faiss/index_factory.cpp +35 -16
  131. data/vendor/faiss/faiss/index_io.h +29 -3
  132. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +7 -4
  133. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +1 -1
  134. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +9 -19
  135. data/vendor/faiss/faiss/svs/IndexSVSFlat.h +2 -0
  136. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +2 -1
  137. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +9 -1
  138. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +9 -0
  139. data/vendor/faiss/faiss/utils/Heap.cpp +46 -0
  140. data/vendor/faiss/faiss/utils/Heap.h +21 -0
  141. data/vendor/faiss/faiss/utils/NeuralNet.cpp +10 -7
  142. data/vendor/faiss/faiss/utils/distances.cpp +141 -23
  143. data/vendor/faiss/faiss/utils/distances.h +98 -0
  144. data/vendor/faiss/faiss/utils/distances_dispatch.h +170 -0
  145. data/vendor/faiss/faiss/utils/distances_simd.cpp +74 -3511
  146. data/vendor/faiss/faiss/utils/extra_distances-inl.h +164 -157
  147. data/vendor/faiss/faiss/utils/extra_distances.cpp +52 -95
  148. data/vendor/faiss/faiss/utils/extra_distances.h +47 -1
  149. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -1
  150. data/vendor/faiss/faiss/utils/partitioning.cpp +1 -1
  151. data/vendor/faiss/faiss/utils/pq_code_distance.h +251 -0
  152. data/vendor/faiss/faiss/utils/rabitq_simd.h +260 -0
  153. data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +150 -0
  154. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +568 -0
  155. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +153 -0
  156. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +1185 -0
  157. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +1092 -0
  158. data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +391 -0
  159. data/vendor/faiss/faiss/utils/simd_levels.cpp +322 -0
  160. data/vendor/faiss/faiss/utils/simd_levels.h +91 -0
  161. data/vendor/faiss/faiss/utils/simdlib_avx2.h +12 -1
  162. data/vendor/faiss/faiss/utils/simdlib_avx512.h +69 -0
  163. data/vendor/faiss/faiss/utils/simdlib_neon.h +6 -0
  164. data/vendor/faiss/faiss/utils/sorting.cpp +4 -4
  165. data/vendor/faiss/faiss/utils/utils.cpp +16 -9
  166. metadata +47 -18
  167. data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +0 -81
  168. data/vendor/faiss/faiss/impl/code_distance/code_distance.h +0 -186
  169. /data/vendor/faiss/faiss/{cppcontrib/factory_tools.h → factory_tools.h} +0 -0
@@ -0,0 +1,329 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and 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
+
8
+ #pragma once
9
+
10
+ #include <faiss/impl/scalar_quantizer/codecs.h>
11
+ #include <faiss/impl/scalar_quantizer/distance_computers.h>
12
+ #include <faiss/impl/scalar_quantizer/quantizers.h>
13
+ #include <faiss/impl/scalar_quantizer/scanners.h>
14
+ #include <faiss/impl/scalar_quantizer/similarities.h>
15
+
16
+ #ifndef THE_LEVEL_TO_DISPATCH
17
+ #error "THE_LEVEL_TO_DISPATCH should be set on input to this header"
18
+ #endif
19
+
20
+ namespace faiss {
21
+
22
+ namespace scalar_quantizer {
23
+
24
+ // Define SL as alias for THE_LEVEL_TO_DISPATCH for use in this file
25
+ constexpr SIMDLevel SL = THE_LEVEL_TO_DISPATCH;
26
+
27
+ // Returns true if dimension d is compatible with the given SIMD level
28
+ template <SIMDLevel SL2>
29
+ constexpr bool is_dimension_compatible(size_t d) {
30
+ if constexpr (SL2 == SIMDLevel::AVX512) {
31
+ return d % 16 == 0;
32
+ } else if constexpr (SL2 == SIMDLevel::AVX2 || SL2 == SIMDLevel::ARM_NEON) {
33
+ return d % 8 == 0;
34
+ } else {
35
+ return true; // SIMDLevel::NONE has no alignment requirements
36
+ }
37
+ }
38
+
39
+ /*******************************************************************
40
+ * sq_select_quantizer: the big switch returning SQuantizer*
41
+ *******************************************************************/
42
+
43
+ template <>
44
+ ScalarQuantizer::SQuantizer* sq_select_quantizer<THE_LEVEL_TO_DISPATCH>(
45
+ QuantizerType qtype,
46
+ size_t d,
47
+ const std::vector<float>& trained) {
48
+ // Return nullptr for incompatible dimensions in SIMD cases
49
+ if constexpr (SL != SIMDLevel::NONE) {
50
+ if (!is_dimension_compatible<SL>(d)) {
51
+ return nullptr;
52
+ }
53
+ }
54
+ switch (qtype) {
55
+ case ScalarQuantizer::QT_8bit:
56
+ return new QuantizerTemplate<
57
+ Codec8bit<SL>,
58
+ QuantizerTemplateScaling::NON_UNIFORM,
59
+ SL>(d, trained);
60
+ case ScalarQuantizer::QT_6bit:
61
+ return new QuantizerTemplate<
62
+ Codec6bit<SL>,
63
+ QuantizerTemplateScaling::NON_UNIFORM,
64
+ SL>(d, trained);
65
+ case ScalarQuantizer::QT_4bit:
66
+ return new QuantizerTemplate<
67
+ Codec4bit<SL>,
68
+ QuantizerTemplateScaling::NON_UNIFORM,
69
+ SL>(d, trained);
70
+ case ScalarQuantizer::QT_8bit_uniform:
71
+ return new QuantizerTemplate<
72
+ Codec8bit<SL>,
73
+ QuantizerTemplateScaling::UNIFORM,
74
+ SL>(d, trained);
75
+ case ScalarQuantizer::QT_4bit_uniform:
76
+ return new QuantizerTemplate<
77
+ Codec4bit<SL>,
78
+ QuantizerTemplateScaling::UNIFORM,
79
+ SL>(d, trained);
80
+ case ScalarQuantizer::QT_fp16:
81
+ return new QuantizerFP16<SL>(d, trained);
82
+ case ScalarQuantizer::QT_bf16:
83
+ return new QuantizerBF16<SL>(d, trained);
84
+ case ScalarQuantizer::QT_8bit_direct:
85
+ return new Quantizer8bitDirect<SL>(d, trained);
86
+ case ScalarQuantizer::QT_8bit_direct_signed:
87
+ return new Quantizer8bitDirectSigned<SL>(d, trained);
88
+ default:
89
+ FAISS_THROW_MSG("unknown qtype");
90
+ }
91
+ }
92
+
93
+ /*******************************************************************
94
+ * select_distance_computer_body: helper for sq_select_distance_computer
95
+ *******************************************************************/
96
+
97
+ template <class Sim, SIMDLevel SL2>
98
+ SQDistanceComputer* select_distance_computer_body(
99
+ ScalarQuantizer::QuantizerType qtype,
100
+ size_t d,
101
+ const std::vector<float>& trained) {
102
+ // Return nullptr for incompatible dimensions in SIMD cases
103
+ if constexpr (SL2 != SIMDLevel::NONE) {
104
+ if (!is_dimension_compatible<SL2>(d)) {
105
+ return nullptr;
106
+ }
107
+ }
108
+ switch (qtype) {
109
+ case ScalarQuantizer::QT_8bit_uniform:
110
+ return new DCTemplate<
111
+ QuantizerTemplate<
112
+ Codec8bit<SL2>,
113
+ QuantizerTemplateScaling::UNIFORM,
114
+ SL2>,
115
+ Sim,
116
+ SL2>(d, trained);
117
+
118
+ case ScalarQuantizer::QT_4bit_uniform:
119
+ return new DCTemplate<
120
+ QuantizerTemplate<
121
+ Codec4bit<SL2>,
122
+ QuantizerTemplateScaling::UNIFORM,
123
+ SL2>,
124
+ Sim,
125
+ SL2>(d, trained);
126
+
127
+ case ScalarQuantizer::QT_8bit:
128
+ return new DCTemplate<
129
+ QuantizerTemplate<
130
+ Codec8bit<SL2>,
131
+ QuantizerTemplateScaling::NON_UNIFORM,
132
+ SL2>,
133
+ Sim,
134
+ SL2>(d, trained);
135
+
136
+ case ScalarQuantizer::QT_6bit:
137
+ return new DCTemplate<
138
+ QuantizerTemplate<
139
+ Codec6bit<SL2>,
140
+ QuantizerTemplateScaling::NON_UNIFORM,
141
+ SL2>,
142
+ Sim,
143
+ SL2>(d, trained);
144
+
145
+ case ScalarQuantizer::QT_4bit:
146
+ return new DCTemplate<
147
+ QuantizerTemplate<
148
+ Codec4bit<SL2>,
149
+ QuantizerTemplateScaling::NON_UNIFORM,
150
+ SL2>,
151
+ Sim,
152
+ SL2>(d, trained);
153
+
154
+ case ScalarQuantizer::QT_fp16:
155
+ return new DCTemplate<QuantizerFP16<SL2>, Sim, SL2>(d, trained);
156
+
157
+ case ScalarQuantizer::QT_bf16:
158
+ return new DCTemplate<QuantizerBF16<SL2>, Sim, SL2>(d, trained);
159
+
160
+ case ScalarQuantizer::QT_8bit_direct:
161
+ if constexpr (SL2 == SIMDLevel::AVX512) {
162
+ if (d % 32 == 0) {
163
+ return new DistanceComputerByte<Sim, SL2>(
164
+ static_cast<int>(d), trained);
165
+ }
166
+ } else if constexpr (SL2 == SIMDLevel::AVX2) {
167
+ if (d % 16 == 0) {
168
+ return new DistanceComputerByte<Sim, SL2>(
169
+ static_cast<int>(d), trained);
170
+ }
171
+ }
172
+ return new DCTemplate<Quantizer8bitDirect<SL2>, Sim, SL2>(
173
+ d, trained);
174
+
175
+ case ScalarQuantizer::QT_8bit_direct_signed:
176
+ return new DCTemplate<Quantizer8bitDirectSigned<SL2>, Sim, SL2>(
177
+ d, trained);
178
+ default:
179
+ FAISS_THROW_MSG("unknown qtype");
180
+ }
181
+ }
182
+
183
+ /*******************************************************************
184
+ * sq_select_distance_computer: returns SQDistanceComputer*
185
+ *******************************************************************/
186
+
187
+ template <>
188
+ SQDistanceComputer* sq_select_distance_computer<THE_LEVEL_TO_DISPATCH>(
189
+ MetricType metric,
190
+ ScalarQuantizer::QuantizerType qtype,
191
+ size_t d,
192
+ const std::vector<float>& trained) {
193
+ if (metric == METRIC_L2) {
194
+ return select_distance_computer_body<SimilarityL2<SL>, SL>(
195
+ qtype, d, trained);
196
+ } else {
197
+ return select_distance_computer_body<SimilarityIP<SL>, SL>(
198
+ qtype, d, trained);
199
+ }
200
+ }
201
+
202
+ /*******************************************************************
203
+ * sq_select_InvertedListScanner: returns InvertedListScanner*
204
+ *******************************************************************/
205
+
206
+ template <>
207
+ InvertedListScanner* sq_select_InvertedListScanner<THE_LEVEL_TO_DISPATCH>(
208
+ QuantizerType qtype,
209
+ MetricType mt,
210
+ size_t d,
211
+ size_t code_size,
212
+ const std::vector<float>& trained,
213
+ const Index* quantizer,
214
+ bool store_pairs,
215
+ const IDSelector* sel,
216
+ bool by_residual) {
217
+ auto scan = [&]<class DCClass>() -> InvertedListScanner* {
218
+ if constexpr (DCClass::Sim::metric_type == METRIC_L2) {
219
+ return new IVFSQScannerL2<DCClass>(
220
+ int(d),
221
+ trained,
222
+ code_size,
223
+ quantizer,
224
+ store_pairs,
225
+ sel,
226
+ by_residual);
227
+ } else if constexpr (
228
+ DCClass::Sim::metric_type == METRIC_INNER_PRODUCT) {
229
+ return new IVFSQScannerIP<DCClass>(
230
+ int(d), trained, code_size, store_pairs, sel, by_residual);
231
+ } else {
232
+ FAISS_THROW_MSG("unsupported metric type");
233
+ }
234
+ };
235
+
236
+ auto select_by_simd_and_metric =
237
+ [&]<SIMDLevel SL2, class Similarity>() -> InvertedListScanner* {
238
+ // Return nullptr for incompatible dimensions in SIMD cases
239
+ if constexpr (SL2 != SIMDLevel::NONE) {
240
+ if (!is_dimension_compatible<SL2>(d)) {
241
+ return nullptr;
242
+ }
243
+ }
244
+ switch (qtype) {
245
+ case ScalarQuantizer::QT_8bit_uniform:
246
+ return scan.template operator()<DCTemplate<
247
+ QuantizerTemplate<
248
+ Codec8bit<SL2>,
249
+ QuantizerTemplateScaling::UNIFORM,
250
+ SL2>,
251
+ Similarity,
252
+ SL2>>();
253
+ case ScalarQuantizer::QT_4bit_uniform:
254
+ return scan.template operator()<DCTemplate<
255
+ QuantizerTemplate<
256
+ Codec4bit<SL2>,
257
+ QuantizerTemplateScaling::UNIFORM,
258
+ SL2>,
259
+ Similarity,
260
+ SL2>>();
261
+ case ScalarQuantizer::QT_8bit:
262
+ return scan.template operator()<DCTemplate<
263
+ QuantizerTemplate<
264
+ Codec8bit<SL2>,
265
+ QuantizerTemplateScaling::NON_UNIFORM,
266
+ SL2>,
267
+ Similarity,
268
+ SL2>>();
269
+ case ScalarQuantizer::QT_4bit:
270
+ return scan.template operator()<DCTemplate<
271
+ QuantizerTemplate<
272
+ Codec4bit<SL2>,
273
+ QuantizerTemplateScaling::NON_UNIFORM,
274
+ SL2>,
275
+ Similarity,
276
+ SL2>>();
277
+ case ScalarQuantizer::QT_6bit:
278
+ return scan.template operator()<DCTemplate<
279
+ QuantizerTemplate<
280
+ Codec6bit<SL2>,
281
+ QuantizerTemplateScaling::NON_UNIFORM,
282
+ SL2>,
283
+ Similarity,
284
+ SL2>>();
285
+ case ScalarQuantizer::QT_fp16:
286
+ return scan.template
287
+ operator()<DCTemplate<QuantizerFP16<SL2>, Similarity, SL2>>();
288
+ case ScalarQuantizer::QT_bf16:
289
+ return scan.template
290
+ operator()<DCTemplate<QuantizerBF16<SL2>, Similarity, SL2>>();
291
+ case ScalarQuantizer::QT_8bit_direct:
292
+ if constexpr (SL2 == SIMDLevel::AVX512) {
293
+ if (d % 32 == 0) {
294
+ return scan.template
295
+ operator()<DistanceComputerByte<Similarity, SL2>>();
296
+ }
297
+ } else if constexpr (SL2 == SIMDLevel::AVX2) {
298
+ if (d % 16 == 0) {
299
+ return scan.template
300
+ operator()<DistanceComputerByte<Similarity, SL2>>();
301
+ }
302
+ }
303
+ return scan.template operator()<DCTemplate<
304
+ Quantizer8bitDirect<SL2>,
305
+ Similarity,
306
+ SL2>>();
307
+ case ScalarQuantizer::QT_8bit_direct_signed:
308
+ return scan.template operator()<DCTemplate<
309
+ Quantizer8bitDirectSigned<SL2>,
310
+ Similarity,
311
+ SL2>>();
312
+ default:
313
+ FAISS_THROW_MSG("unknown qtype");
314
+ }
315
+ };
316
+
317
+ if (mt == METRIC_L2) {
318
+ return select_by_simd_and_metric
319
+ .template operator()<SL, SimilarityL2<SL>>();
320
+ } else if (mt == METRIC_INNER_PRODUCT) {
321
+ return select_by_simd_and_metric
322
+ .template operator()<SL, SimilarityIP<SL>>();
323
+ }
324
+ FAISS_THROW_MSG("unsupported metric type");
325
+ }
326
+
327
+ } // namespace scalar_quantizer
328
+
329
+ } // namespace faiss