faiss 0.6.0 → 0.6.1

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 (361) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/ext/faiss/extconf.rb +2 -1
  4. data/ext/faiss/{index_rb.cpp → index.cpp} +1 -1
  5. data/ext/faiss/index_binary.cpp +1 -1
  6. data/ext/faiss/kmeans.cpp +1 -1
  7. data/ext/faiss/pca_matrix.cpp +1 -1
  8. data/ext/faiss/product_quantizer.cpp +1 -1
  9. data/ext/faiss/{utils_rb.cpp → utils.cpp} +1 -1
  10. data/lib/faiss/version.rb +1 -1
  11. data/vendor/faiss/faiss/AutoTune.cpp +93 -80
  12. data/vendor/faiss/faiss/Clustering.cpp +39 -240
  13. data/vendor/faiss/faiss/Clustering.h +6 -0
  14. data/vendor/faiss/faiss/IVFlib.cpp +41 -21
  15. data/vendor/faiss/faiss/Index.cpp +6 -5
  16. data/vendor/faiss/faiss/Index.h +5 -5
  17. data/vendor/faiss/faiss/Index2Layer.cpp +37 -53
  18. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +49 -37
  19. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +36 -34
  20. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +4 -1
  21. data/vendor/faiss/faiss/IndexBinary.cpp +5 -3
  22. data/vendor/faiss/faiss/IndexBinary.h +4 -4
  23. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +1 -1
  24. data/vendor/faiss/faiss/IndexBinaryFlat.h +1 -1
  25. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -4
  26. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +84 -92
  27. data/vendor/faiss/faiss/IndexBinaryHNSW.h +9 -3
  28. data/vendor/faiss/faiss/IndexBinaryHash.cpp +45 -236
  29. data/vendor/faiss/faiss/IndexBinaryHash.h +6 -6
  30. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +87 -415
  31. data/vendor/faiss/faiss/IndexFastScan.cpp +72 -109
  32. data/vendor/faiss/faiss/IndexFastScan.h +25 -23
  33. data/vendor/faiss/faiss/IndexFlat.cpp +27 -20
  34. data/vendor/faiss/faiss/IndexFlat.h +21 -18
  35. data/vendor/faiss/faiss/IndexFlatCodes.cpp +42 -19
  36. data/vendor/faiss/faiss/IndexHNSW.cpp +283 -145
  37. data/vendor/faiss/faiss/IndexHNSW.h +16 -2
  38. data/vendor/faiss/faiss/IndexIDMap.cpp +25 -21
  39. data/vendor/faiss/faiss/IndexIDMap.h +9 -7
  40. data/vendor/faiss/faiss/IndexIVF.cpp +465 -362
  41. data/vendor/faiss/faiss/IndexIVF.h +33 -12
  42. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +77 -74
  43. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +96 -93
  44. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +4 -1
  45. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +357 -238
  46. data/vendor/faiss/faiss/IndexIVFFastScan.h +42 -41
  47. data/vendor/faiss/faiss/IndexIVFFlat.cpp +36 -68
  48. data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
  49. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +53 -30
  50. data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
  51. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
  52. data/vendor/faiss/faiss/IndexIVFPQ.cpp +71 -843
  53. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +151 -121
  54. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
  55. data/vendor/faiss/faiss/IndexIVFPQR.cpp +21 -17
  56. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +26 -39
  57. data/vendor/faiss/faiss/IndexIVFRaBitQ.h +2 -1
  58. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +475 -476
  59. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +248 -93
  60. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +41 -127
  61. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
  62. data/vendor/faiss/faiss/IndexLSH.cpp +36 -19
  63. data/vendor/faiss/faiss/IndexLattice.cpp +13 -13
  64. data/vendor/faiss/faiss/IndexNNDescent.cpp +36 -21
  65. data/vendor/faiss/faiss/IndexNNDescent.h +2 -2
  66. data/vendor/faiss/faiss/IndexNSG.cpp +39 -23
  67. data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +31 -11
  68. data/vendor/faiss/faiss/IndexPQ.cpp +128 -221
  69. data/vendor/faiss/faiss/IndexPQ.h +3 -2
  70. data/vendor/faiss/faiss/IndexPQFastScan.cpp +20 -14
  71. data/vendor/faiss/faiss/IndexPQFastScan.h +3 -0
  72. data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -18
  73. data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
  74. data/vendor/faiss/faiss/IndexRaBitQ.cpp +11 -36
  75. data/vendor/faiss/faiss/IndexRaBitQ.h +2 -1
  76. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +41 -277
  77. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +183 -27
  78. data/vendor/faiss/faiss/IndexRefine.cpp +30 -25
  79. data/vendor/faiss/faiss/IndexRefine.h +4 -4
  80. data/vendor/faiss/faiss/IndexReplicas.cpp +6 -6
  81. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +15 -14
  82. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +1 -1
  83. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +82 -14
  84. data/vendor/faiss/faiss/IndexShards.cpp +10 -9
  85. data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
  86. data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
  87. data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
  88. data/vendor/faiss/faiss/MetaIndexes.h +1 -1
  89. data/vendor/faiss/faiss/MetricType.h +14 -7
  90. data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
  91. data/vendor/faiss/faiss/SuperKMeans.h +97 -0
  92. data/vendor/faiss/faiss/VectorTransform.cpp +237 -149
  93. data/vendor/faiss/faiss/VectorTransform.h +16 -16
  94. data/vendor/faiss/faiss/build.cpp +23 -0
  95. data/vendor/faiss/faiss/build.h +15 -0
  96. data/vendor/faiss/faiss/clone_index.cpp +48 -47
  97. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
  98. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
  99. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
  100. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
  101. data/vendor/faiss/faiss/factory_tools.cpp +5 -0
  102. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
  103. data/vendor/faiss/faiss/gpu/GpuResources.h +1 -1
  104. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +9 -9
  105. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +4 -3
  106. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
  107. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
  108. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
  109. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
  110. data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
  111. data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
  112. data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
  113. data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
  114. data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
  115. data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
  116. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +51 -0
  117. data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
  118. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +66 -0
  119. data/vendor/faiss/faiss/gpu_metal/MetalResources.h +79 -0
  120. data/vendor/faiss/faiss/gpu_metal/StandardMetalResources.h +35 -0
  121. data/vendor/faiss/faiss/impl/AdSampling.cpp +103 -0
  122. data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
  123. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +29 -25
  124. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
  125. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
  126. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -0
  127. data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
  128. data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
  129. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +16 -16
  130. data/vendor/faiss/faiss/impl/CodePacker.cpp +3 -3
  131. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +1 -1
  132. data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
  133. data/vendor/faiss/faiss/impl/FaissAssert.h +6 -3
  134. data/vendor/faiss/faiss/impl/FaissException.h +50 -3
  135. data/vendor/faiss/faiss/impl/HNSW.cpp +92 -317
  136. data/vendor/faiss/faiss/impl/HNSW.h +13 -34
  137. data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
  138. data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
  139. data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
  140. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +82 -77
  141. data/vendor/faiss/faiss/impl/NNDescent.cpp +62 -25
  142. data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
  143. data/vendor/faiss/faiss/impl/NSG.cpp +38 -21
  144. data/vendor/faiss/faiss/impl/NSG.h +4 -4
  145. data/vendor/faiss/faiss/impl/Panorama.cpp +23 -6
  146. data/vendor/faiss/faiss/impl/Panorama.h +258 -87
  147. data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
  148. data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
  149. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +46 -32
  150. data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
  151. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
  152. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
  153. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +30 -23
  154. data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
  155. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +55 -49
  156. data/vendor/faiss/faiss/impl/RaBitQUtils.h +65 -0
  157. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +296 -283
  158. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +26 -23
  159. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
  160. data/vendor/faiss/faiss/impl/ResultHandler.h +99 -75
  161. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +52 -4
  162. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +27 -1
  163. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
  164. data/vendor/faiss/faiss/impl/VisitedTable.h +7 -0
  165. data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
  166. data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
  167. data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
  168. data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
  169. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
  170. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
  171. data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
  172. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
  173. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
  174. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
  175. data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
  176. data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
  177. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
  178. data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
  179. data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
  180. data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
  181. data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
  182. data/vendor/faiss/faiss/impl/expanded_scanners.h +8 -3
  183. data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
  184. data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
  185. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
  186. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
  187. data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
  188. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +268 -0
  189. data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +169 -2
  190. data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
  191. data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
  192. data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
  193. data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
  194. data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
  195. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
  196. data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -356
  197. data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
  198. data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
  199. data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +282 -134
  200. data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
  201. data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
  202. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +91 -0
  203. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -0
  204. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +104 -0
  205. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +111 -0
  206. data/vendor/faiss/faiss/impl/index_read.cpp +1132 -45
  207. data/vendor/faiss/faiss/impl/index_read_utils.h +1 -1
  208. data/vendor/faiss/faiss/impl/index_write.cpp +95 -13
  209. data/vendor/faiss/faiss/impl/io.cpp +6 -6
  210. data/vendor/faiss/faiss/impl/io_macros.h +33 -16
  211. data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
  212. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +37 -23
  213. data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
  214. data/vendor/faiss/faiss/impl/mapped_io.cpp +6 -6
  215. data/vendor/faiss/faiss/impl/platform_macros.h +11 -4
  216. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
  217. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
  218. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
  219. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
  220. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +21 -0
  221. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +21 -0
  222. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +21 -0
  223. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx2.cpp → pq_code_distance-avx2.h} +9 -13
  224. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx512.cpp → pq_code_distance-avx512.h} +9 -57
  225. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +29 -111
  226. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
  227. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +238 -5
  228. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +5 -7
  229. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +68 -0
  230. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +311 -477
  231. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
  232. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +1 -1
  233. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +3 -2
  234. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +102 -11
  235. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +27 -1
  236. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +3 -3
  237. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +148 -0
  238. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +167 -0
  239. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +59 -0
  240. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +163 -0
  241. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +311 -0
  242. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +192 -8
  243. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +12 -0
  244. data/vendor/faiss/faiss/impl/simd_dispatch.h +100 -66
  245. data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
  246. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +264 -172
  247. data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
  248. data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
  249. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
  250. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +270 -218
  251. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
  252. data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
  253. data/vendor/faiss/faiss/impl/svs_io.h +8 -2
  254. data/vendor/faiss/faiss/index_factory.cpp +86 -18
  255. data/vendor/faiss/faiss/index_io.h +24 -0
  256. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +66 -16
  257. data/vendor/faiss/faiss/invlists/DirectMap.cpp +24 -14
  258. data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
  259. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +157 -73
  260. data/vendor/faiss/faiss/invlists/InvertedLists.h +86 -23
  261. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
  262. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +13 -13
  263. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  264. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +1 -1
  265. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
  266. data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
  267. data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
  268. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
  269. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
  270. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
  271. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
  272. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +25 -1
  273. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +18 -2
  274. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +1 -1
  275. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +12 -3
  276. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +7 -2
  277. data/vendor/faiss/faiss/utils/Heap.cpp +10 -10
  278. data/vendor/faiss/faiss/utils/NeuralNet.cpp +47 -36
  279. data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
  280. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
  281. data/vendor/faiss/faiss/utils/distances.cpp +390 -560
  282. data/vendor/faiss/faiss/utils/distances.h +20 -1
  283. data/vendor/faiss/faiss/utils/distances_dispatch.h +117 -37
  284. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
  285. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
  286. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
  287. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
  288. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
  289. data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
  290. data/vendor/faiss/faiss/utils/distances_simd.cpp +5 -177
  291. data/vendor/faiss/faiss/utils/extra_distances.cpp +9 -8
  292. data/vendor/faiss/faiss/utils/extra_distances.h +32 -6
  293. data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
  294. data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
  295. data/vendor/faiss/faiss/utils/hamming.h +92 -2
  296. data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
  297. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +15 -0
  298. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
  299. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
  300. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +234 -0
  301. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-generic.h +368 -0
  302. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +322 -0
  303. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-rvv.h +39 -0
  304. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer.h +146 -0
  305. data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +481 -0
  306. data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +15 -0
  307. data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +15 -0
  308. data/vendor/faiss/faiss/utils/partitioning.cpp +66 -987
  309. data/vendor/faiss/faiss/utils/partitioning.h +31 -0
  310. data/vendor/faiss/faiss/utils/popcount.h +29 -0
  311. data/vendor/faiss/faiss/utils/pq_code_distance.h +2 -2
  312. data/vendor/faiss/faiss/utils/prefetch.h +2 -2
  313. data/vendor/faiss/faiss/utils/quantize_lut.cpp +30 -30
  314. data/vendor/faiss/faiss/utils/quantize_lut.h +1 -1
  315. data/vendor/faiss/faiss/utils/rabitq_simd.h +57 -536
  316. data/vendor/faiss/faiss/utils/random.cpp +6 -6
  317. data/vendor/faiss/faiss/utils/simd_impl/IVFFlatScanner-inl.h +51 -0
  318. data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +5 -1
  319. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +213 -4
  320. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +163 -10
  321. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +250 -4
  322. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +7 -4
  323. data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +189 -0
  324. data/vendor/faiss/faiss/utils/simd_impl/distances_simdlib256.h +195 -0
  325. data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +2 -1
  326. data/vendor/faiss/faiss/utils/{distances_fused/simdlib_based.h → simd_impl/exhaustive_L2sqr_blas_cmax.h} +5 -10
  327. data/vendor/faiss/faiss/utils/simd_impl/hamming_impl.h +481 -0
  328. data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +14 -0
  329. data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +14 -0
  330. data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +1085 -0
  331. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +355 -0
  332. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +477 -0
  333. data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +55 -0
  334. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
  335. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
  336. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
  337. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
  338. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
  339. data/vendor/faiss/faiss/utils/simd_levels.cpp +17 -5
  340. data/vendor/faiss/faiss/utils/simd_levels.h +93 -1
  341. data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
  342. data/vendor/faiss/faiss/utils/utils.cpp +5 -5
  343. data/vendor/faiss/faiss/utils/utils.h +3 -3
  344. metadata +119 -34
  345. data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
  346. data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
  347. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -224
  348. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -230
  349. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
  350. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
  351. data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
  352. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
  353. data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -235
  354. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
  355. data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
  356. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -449
  357. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
  358. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
  359. data/vendor/faiss/faiss/utils/simdlib.h +0 -42
  360. data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -365
  361. /data/ext/faiss/{utils_rb.h → utils.h} +0 -0
@@ -30,11 +30,15 @@
30
30
  #include <faiss/impl/IDSelector.h>
31
31
  #include <faiss/impl/platform_macros.h>
32
32
  #include <faiss/utils/Heap.h>
33
+ #include <faiss/utils/popcount.h>
34
+ #include <faiss/utils/simd_levels.h>
33
35
 
34
36
  // Low-level Hamming distance computations and hamdis_t.
35
- #include <faiss/utils/hamming_distance/hamdis-inl.h>
37
+ #include <faiss/utils/hamming_distance/hamming_computer.h>
38
+ // Scalar (NONE) HammingComputer struct specializations.
39
+ #include <faiss/utils/hamming_distance/hamming_computer-generic.h>
36
40
 
37
- #include <faiss/utils/approx_topk/mode.h>
41
+ #include <faiss/impl/approx_topk/approx_topk.h>
38
42
 
39
43
  namespace faiss {
40
44
 
@@ -284,6 +288,92 @@ void unpack_bitstrings(
284
288
  size_t code_size,
285
289
  int32_t* unpacked);
286
290
 
291
+ /** Per-SIMD-level Hamming function implementations.
292
+ * Specializations live in per-ISA TUs (hamming_avx2.cpp, etc.).
293
+ * The `_fixSL` suffix marks these as pinned-to-a-SIMDLevel (no dispatch),
294
+ * distinguishing them from the non-templated DD entry points above. */
295
+
296
+ template <SIMDLevel SL>
297
+ void hammings_knn_hc_fixSL(
298
+ int_maxheap_array_t* ha,
299
+ const uint8_t* a,
300
+ const uint8_t* b,
301
+ size_t nb,
302
+ size_t ncodes,
303
+ int ordered,
304
+ ApproxTopK_mode_t approx_topk_mode,
305
+ const IDSelector* sel);
306
+
307
+ template <SIMDLevel SL>
308
+ void hammings_knn_mc_fixSL(
309
+ const uint8_t* a,
310
+ const uint8_t* b,
311
+ size_t na,
312
+ size_t nb,
313
+ size_t k,
314
+ size_t ncodes,
315
+ int32_t* distances,
316
+ int64_t* labels,
317
+ const IDSelector* sel);
318
+
319
+ template <SIMDLevel SL>
320
+ void hamming_range_search_fixSL(
321
+ const uint8_t* a,
322
+ const uint8_t* b,
323
+ size_t na,
324
+ size_t nb,
325
+ int radius,
326
+ size_t code_size,
327
+ RangeSearchResult* result,
328
+ const IDSelector* sel);
329
+
330
+ template <SIMDLevel SL>
331
+ void hammings_fixSL(
332
+ const uint8_t* a,
333
+ const uint8_t* b,
334
+ size_t na,
335
+ size_t nb,
336
+ size_t ncodes,
337
+ hamdis_t* dis);
338
+
339
+ template <SIMDLevel SL>
340
+ void generalized_hammings_knn_hc_fixSL(
341
+ int_maxheap_array_t* ha,
342
+ const uint8_t* a,
343
+ const uint8_t* b,
344
+ size_t nb,
345
+ size_t code_size,
346
+ int ordered);
347
+
348
+ template <SIMDLevel SL>
349
+ void hamming_count_thres_fixSL(
350
+ const uint8_t* bs1,
351
+ const uint8_t* bs2,
352
+ size_t n1,
353
+ size_t n2,
354
+ hamdis_t ht,
355
+ size_t ncodes,
356
+ size_t* nptr);
357
+
358
+ template <SIMDLevel SL>
359
+ void crosshamming_count_thres_fixSL(
360
+ const uint8_t* dbs,
361
+ size_t n,
362
+ hamdis_t ht,
363
+ size_t ncodes,
364
+ size_t* nptr);
365
+
366
+ template <SIMDLevel SL>
367
+ size_t match_hamming_thres_fixSL(
368
+ const uint8_t* bs1,
369
+ const uint8_t* bs2,
370
+ size_t n1,
371
+ size_t n2,
372
+ hamdis_t ht,
373
+ size_t ncodes,
374
+ int64_t* idx,
375
+ hamdis_t* dis);
376
+
287
377
  } // namespace faiss
288
378
 
289
379
  #include <faiss/utils/hamming-inl.h>
@@ -8,25 +8,25 @@
8
8
  #ifndef FAISS_hamming_common_h
9
9
  #define FAISS_hamming_common_h
10
10
 
11
+ #include <cassert>
12
+ #include <cstddef>
11
13
  #include <cstdint>
12
14
 
13
15
  #include <faiss/impl/platform_macros.h>
16
+ #include <faiss/utils/popcount.h>
17
+ #include <faiss/utils/simd_levels.h>
18
+
19
+ #ifdef __aarch64__
20
+ // Include <arm_neon.h> at global scope so the NEON types it declares
21
+ // (uint8x16_t, uint16x8_t, ...) end up in `::` and not inside `faiss::`.
22
+ #include <arm_neon.h>
23
+ #endif
14
24
 
15
25
  /* The Hamming distance type */
16
26
  using hamdis_t = int32_t;
17
27
 
18
28
  namespace faiss {
19
29
 
20
- // trust the compiler to provide efficient popcount implementations
21
- inline int popcount32(uint32_t x) {
22
- return __builtin_popcount(x);
23
- }
24
-
25
- // popcount
26
- inline int popcount64(uint64_t x) {
27
- return __builtin_popcountl(x);
28
- }
29
-
30
30
  // This table was moved from .cpp to .h file, because
31
31
  // otherwise it was causing compilation errors while trying to
32
32
  // compile swig modules on Windows.
@@ -43,6 +43,283 @@ inline constexpr uint8_t hamdis_tab_ham_bytes[256] = {
43
43
  4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
44
44
  4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
45
45
 
46
+ /***************************************************************************
47
+ * generalized Hamming = number of bytes that are different between
48
+ * two codes.
49
+ ***************************************************************************/
50
+
51
+ inline int generalized_hamming_64(uint64_t a) {
52
+ a |= a >> 1;
53
+ a |= a >> 2;
54
+ a |= a >> 4;
55
+ a &= 0x0101010101010101UL;
56
+ return popcount64(a);
57
+ }
58
+
59
+ /***************************************************************************
60
+ * Free-function hamming<nbits>() templates.
61
+ * hamming<64> is architecture-independent.
62
+ * hamming<128>, hamming<256>, the primary template, and the runtime-nwords
63
+ * overload have NEON-optimized versions on aarch64.
64
+ ***************************************************************************/
65
+
66
+ #ifndef SWIG
67
+
68
+ /* hamming<64> — identical on all architectures */
69
+ template <size_t nbits>
70
+ inline hamdis_t hamming(const uint64_t* bs1, const uint64_t* bs2);
71
+
72
+ template <>
73
+ inline hamdis_t hamming<64>(const uint64_t* pa, const uint64_t* pb) {
74
+ return popcount64(pa[0] ^ pb[0]);
75
+ }
76
+
77
+ #ifdef __aarch64__
78
+
79
+ /* Hamming distances for multiples of 64 bits — NEON version */
80
+ template <size_t nbits>
81
+ inline hamdis_t hamming(const uint64_t* pa, const uint64_t* pb) {
82
+ constexpr size_t nwords256 = nbits / 256;
83
+ constexpr size_t nwords128 = (nbits - nwords256 * 256) / 128;
84
+ constexpr size_t nwords64 =
85
+ (nbits - nwords256 * 256 - nwords128 * 128) / 64;
86
+
87
+ hamdis_t h = 0;
88
+ if (nwords256 > 0) {
89
+ for (size_t i = 0; i < nwords256; i++) {
90
+ h += hamming<256>(pa, pb);
91
+ pa += 4;
92
+ pb += 4;
93
+ }
94
+ }
95
+
96
+ if (nwords128 > 0) {
97
+ h += hamming<128>(pa, pb);
98
+ pa += 2;
99
+ pb += 2;
100
+ }
101
+
102
+ if (nwords64 > 0) {
103
+ h += hamming<64>(pa, pb);
104
+ }
105
+
106
+ return h;
107
+ }
108
+
109
+ template <>
110
+ inline hamdis_t hamming<128>(const uint64_t* pa, const uint64_t* pb) {
111
+ const uint8_t* pa8 = reinterpret_cast<const uint8_t*>(pa);
112
+ const uint8_t* pb8 = reinterpret_cast<const uint8_t*>(pb);
113
+ uint8x16_t or0 = veorq_u8(vld1q_u8(pa8), vld1q_u8(pb8));
114
+ uint8x16_t c0 = vcntq_u8(or0);
115
+ auto dis = vaddvq_u8(c0);
116
+ return dis;
117
+ }
118
+
119
+ template <>
120
+ inline hamdis_t hamming<256>(const uint64_t* pa, const uint64_t* pb) {
121
+ const uint8_t* pa8 = reinterpret_cast<const uint8_t*>(pa);
122
+ const uint8_t* pb8 = reinterpret_cast<const uint8_t*>(pb);
123
+ uint8x16_t or0 = veorq_u8(vld1q_u8(pa8), vld1q_u8(pb8));
124
+ uint8x16_t or1 = veorq_u8(vld1q_u8(pa8 + 16), vld1q_u8(pb8 + 16));
125
+ uint8x16_t c0 = vcntq_u8(or0);
126
+ uint8x16_t c1 = vcntq_u8(or1);
127
+ uint8x16_t ca = vpaddq_u8(c0, c1);
128
+ auto dis = vaddvq_u8(ca);
129
+ return dis;
130
+ }
131
+
132
+ /* Hamming distances for multiple of 64 bits */
133
+ inline hamdis_t hamming(const uint64_t* pa, const uint64_t* pb, size_t nwords) {
134
+ const size_t nwords256 = nwords / 4;
135
+ const size_t nwords128 = (nwords % 4) / 2;
136
+ const size_t nwords64 = nwords % 2;
137
+
138
+ hamdis_t h = 0;
139
+ if (nwords256 > 0) {
140
+ for (size_t i = 0; i < nwords256; i++) {
141
+ h += hamming<256>(pa, pb);
142
+ pa += 4;
143
+ pb += 4;
144
+ }
145
+ }
146
+
147
+ if (nwords128 > 0) {
148
+ h += hamming<128>(pa, pb);
149
+ pa += 2;
150
+ pb += 2;
151
+ }
152
+
153
+ if (nwords64 > 0) {
154
+ h += hamming<64>(pa, pb);
155
+ }
156
+
157
+ return h;
158
+ }
159
+
160
+ #else // !__aarch64__
161
+
162
+ /* Hamming distances for multiples of 64 bits — scalar version */
163
+ template <size_t nbits>
164
+ inline hamdis_t hamming(const uint64_t* bs1, const uint64_t* bs2) {
165
+ const size_t nwords = nbits / 64;
166
+ size_t i;
167
+ hamdis_t h = 0;
168
+ for (i = 0; i < nwords; i++) {
169
+ h += popcount64(bs1[i] ^ bs2[i]);
170
+ }
171
+ return h;
172
+ }
173
+
174
+ /* specialized (optimized) functions */
175
+ template <>
176
+ inline hamdis_t hamming<128>(const uint64_t* pa, const uint64_t* pb) {
177
+ return popcount64(pa[0] ^ pb[0]) + popcount64(pa[1] ^ pb[1]);
178
+ }
179
+
180
+ template <>
181
+ inline hamdis_t hamming<256>(const uint64_t* pa, const uint64_t* pb) {
182
+ return popcount64(pa[0] ^ pb[0]) + popcount64(pa[1] ^ pb[1]) +
183
+ popcount64(pa[2] ^ pb[2]) + popcount64(pa[3] ^ pb[3]);
184
+ }
185
+
186
+ /* Hamming distances for multiple of 64 bits */
187
+ inline hamdis_t hamming(
188
+ const uint64_t* bs1,
189
+ const uint64_t* bs2,
190
+ size_t nwords) {
191
+ hamdis_t h = 0;
192
+ for (size_t i = 0; i < nwords; i++) {
193
+ h += popcount64(bs1[i] ^ bs2[i]);
194
+ }
195
+ return h;
196
+ }
197
+
198
+ #endif // __aarch64__
199
+
200
+ /***************************************************************************
201
+ * Bit-level Hamming distance implementation functions.
202
+ * These depend only on the hamming<nbits>() free functions above.
203
+ ***************************************************************************/
204
+
205
+ template <size_t nbits>
206
+ inline void hammings_impl(
207
+ const uint64_t* __restrict bs1,
208
+ const uint64_t* __restrict bs2,
209
+ size_t n1,
210
+ size_t n2,
211
+ hamdis_t* __restrict dis) {
212
+ size_t i, j;
213
+ const size_t nwords = nbits / 64;
214
+ for (i = 0; i < n1; i++) {
215
+ const uint64_t* __restrict bs1_ = bs1 + i * nwords;
216
+ hamdis_t* __restrict dis_ = dis + i * n2;
217
+ for (j = 0; j < n2; j++) {
218
+ dis_[j] = hamming<nbits>(bs1_, bs2 + j * nwords);
219
+ }
220
+ }
221
+ }
222
+
223
+ inline void hammings_impl_runtime(
224
+ const uint64_t* __restrict bs1,
225
+ const uint64_t* __restrict bs2,
226
+ size_t n1,
227
+ size_t n2,
228
+ size_t nbits,
229
+ hamdis_t* __restrict dis) {
230
+ size_t i, j;
231
+ const size_t nwords = nbits / 64;
232
+ for (i = 0; i < n1; i++) {
233
+ const uint64_t* __restrict bs1_ = bs1 + i * nwords;
234
+ hamdis_t* __restrict dis_ = dis + i * n2;
235
+ for (j = 0; j < n2; j++) {
236
+ dis_[j] = hamming(bs1_, bs2 + j * nwords, nwords);
237
+ }
238
+ }
239
+ }
240
+
241
+ template <size_t nbits>
242
+ inline void hamming_count_thres_impl(
243
+ const uint64_t* __restrict bs1,
244
+ const uint64_t* __restrict bs2,
245
+ size_t n1,
246
+ size_t n2,
247
+ hamdis_t ht,
248
+ size_t* __restrict nptr) {
249
+ const size_t nwords = nbits / 64;
250
+ size_t i, j, posm = 0;
251
+ const uint64_t* bs2_ = bs2;
252
+
253
+ for (i = 0; i < n1; i++) {
254
+ bs2 = bs2_;
255
+ for (j = 0; j < n2; j++) {
256
+ if (hamming<nbits>(bs1, bs2) <= ht) {
257
+ posm++;
258
+ }
259
+ bs2 += nwords;
260
+ }
261
+ bs1 += nwords;
262
+ }
263
+ *nptr = posm;
264
+ }
265
+
266
+ template <size_t nbits>
267
+ inline void crosshamming_count_thres_impl(
268
+ const uint64_t* __restrict dbs,
269
+ size_t n,
270
+ int ht,
271
+ size_t* __restrict nptr) {
272
+ const size_t nwords = nbits / 64;
273
+ size_t i, j, posm = 0;
274
+ const uint64_t* bs1 = dbs;
275
+ for (i = 0; i < n; i++) {
276
+ const uint64_t* bs2 = bs1 + nwords;
277
+ for (j = i + 1; j < n; j++) {
278
+ if (hamming<nbits>(bs1, bs2) <= ht) {
279
+ posm++;
280
+ }
281
+ bs2 += nwords;
282
+ }
283
+ bs1 += nwords;
284
+ }
285
+ *nptr = posm;
286
+ }
287
+
288
+ template <size_t nbits>
289
+ inline size_t match_hamming_thres_impl(
290
+ const uint64_t* __restrict bs1,
291
+ const uint64_t* __restrict bs2,
292
+ size_t n1,
293
+ size_t n2,
294
+ int ht,
295
+ int64_t* __restrict idx,
296
+ hamdis_t* __restrict hams) {
297
+ const size_t nwords = nbits / 64;
298
+ size_t i, j, posm = 0;
299
+ hamdis_t h;
300
+ const uint64_t* bs2_ = bs2;
301
+ for (i = 0; i < n1; i++) {
302
+ bs2 = bs2_;
303
+ for (j = 0; j < n2; j++) {
304
+ h = hamming<nbits>(bs1, bs2);
305
+ if (h <= ht) {
306
+ *idx = i;
307
+ idx++;
308
+ *idx = j;
309
+ idx++;
310
+ *hams = h;
311
+ hams++;
312
+ posm++;
313
+ }
314
+ bs2 += nwords;
315
+ }
316
+ bs1 += nwords;
317
+ }
318
+ return posm;
319
+ }
320
+
321
+ #endif // SWIG
322
+
46
323
  } // namespace faiss
47
324
 
48
325
  #endif
@@ -0,0 +1,15 @@
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
+ #ifdef COMPILE_SIMD_AVX2
9
+
10
+ #define THE_SIMD_LEVEL SIMDLevel::AVX2
11
+ // NOLINTNEXTLINE(facebook-hte-InlineHeader)
12
+ #include <faiss/utils/hamming_distance/hamming_computer-avx2.h>
13
+ #include <faiss/utils/hamming_distance/hamming_impl.h>
14
+
15
+ #endif // COMPILE_SIMD_AVX2
@@ -0,0 +1,15 @@
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
+ #ifdef COMPILE_SIMD_AVX512
9
+
10
+ #define THE_SIMD_LEVEL SIMDLevel::AVX512
11
+ // NOLINTNEXTLINE(facebook-hte-InlineHeader)
12
+ #include <faiss/utils/hamming_distance/hamming_computer-avx512.h>
13
+ #include <faiss/utils/hamming_distance/hamming_impl.h>
14
+
15
+ #endif // COMPILE_SIMD_AVX512
@@ -0,0 +1,142 @@
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
+ #ifndef HAMMING_COMPUTER_AVX2_H
9
+ #define HAMMING_COMPUTER_AVX2_H
10
+
11
+ // AVX2 HammingComputer and GenHammingComputer specializations.
12
+ // Types without custom AVX2 code inherit from the NONE specializations
13
+ // in hamming_computer-generic.h. Custom AVX2 specializations for
14
+ // GenHammingComputer classes leverage SSE/AVX2 intrinsics.
15
+
16
+ #include <cassert>
17
+ #include <cstdint>
18
+
19
+ #include <faiss/impl/platform_macros.h>
20
+ #include <faiss/utils/hamming_distance/hamming_computer-generic.h>
21
+
22
+ #include <immintrin.h>
23
+
24
+ namespace faiss {
25
+
26
+ /***************************************************************************
27
+ * AVX2 inheriting specializations for types without custom AVX2 code.
28
+ * These explicitly inherit the scalar (NONE) implementation so that
29
+ * every SIMDLevel has a concrete specialization.
30
+ ***************************************************************************/
31
+
32
+ #define FAISS_INHERIT_HAMMING(Class) \
33
+ template <> \
34
+ struct Class##_tpl<SIMDLevel::AVX2> : Class##_tpl<SIMDLevel::NONE> { \
35
+ using Class##_tpl<SIMDLevel::NONE>::Class##_tpl; \
36
+ }
37
+
38
+ FAISS_INHERIT_HAMMING(HammingComputer16);
39
+ FAISS_INHERIT_HAMMING(HammingComputer20);
40
+ FAISS_INHERIT_HAMMING(HammingComputer32);
41
+ FAISS_INHERIT_HAMMING(HammingComputer64);
42
+ FAISS_INHERIT_HAMMING(HammingComputerDefault);
43
+ FAISS_INHERIT_HAMMING(GenHammingComputer8);
44
+
45
+ #undef FAISS_INHERIT_HAMMING
46
+
47
+ /***************************************************************************
48
+ * Custom AVX2 specializations for GenHammingComputer classes.
49
+ ***************************************************************************/
50
+
51
+ // I'm not sure whether this version is faster of slower, tbh
52
+ // todo: test on different CPUs
53
+ template <>
54
+ struct GenHammingComputer16_tpl<SIMDLevel::AVX2> {
55
+ __m128i a;
56
+
57
+ GenHammingComputer16_tpl(
58
+ const uint8_t* a8,
59
+ FAISS_MAYBE_UNUSED int code_size) {
60
+ assert(code_size == 16);
61
+ a = _mm_loadu_si128((const __m128i_u*)a8);
62
+ }
63
+
64
+ inline int hamming(const uint8_t* b8) const {
65
+ const __m128i b = _mm_loadu_si128((const __m128i_u*)b8);
66
+ const __m128i cmp = _mm_cmpeq_epi8(a, b);
67
+ const auto movemask = _mm_movemask_epi8(cmp);
68
+ return 16 - popcount32(movemask);
69
+ }
70
+
71
+ inline static constexpr int get_code_size() {
72
+ return 16;
73
+ }
74
+ };
75
+
76
+ template <>
77
+ struct GenHammingComputer32_tpl<SIMDLevel::AVX2> {
78
+ __m256i a;
79
+
80
+ GenHammingComputer32_tpl(
81
+ const uint8_t* a8,
82
+ FAISS_MAYBE_UNUSED int code_size) {
83
+ assert(code_size == 32);
84
+ a = _mm256_loadu_si256((const __m256i_u*)a8);
85
+ }
86
+
87
+ inline int hamming(const uint8_t* b8) const {
88
+ const __m256i b = _mm256_loadu_si256((const __m256i_u*)b8);
89
+ const __m256i cmp = _mm256_cmpeq_epi8(a, b);
90
+ const uint32_t movemask = _mm256_movemask_epi8(cmp);
91
+ return 32 - popcount32(movemask);
92
+ }
93
+
94
+ inline static constexpr int get_code_size() {
95
+ return 32;
96
+ }
97
+ };
98
+
99
+ // A specialized version might be needed for the very long
100
+ // GenHamming code_size. In such a case, one may accumulate
101
+ // counts using _mm256_sub_epi8 and then compute a horizontal
102
+ // sum (using _mm256_sad_epu8, maybe, in blocks of no larger
103
+ // than 256 * 32 bytes).
104
+
105
+ template <>
106
+ struct GenHammingComputerM8_tpl<SIMDLevel::AVX2> {
107
+ const uint64_t* a;
108
+ int n;
109
+
110
+ GenHammingComputerM8_tpl(const uint8_t* a8, int code_size) {
111
+ assert(code_size % 8 == 0);
112
+ a = (uint64_t*)a8;
113
+ n = code_size / 8;
114
+ }
115
+
116
+ int hamming(const uint8_t* b8) const {
117
+ const uint64_t* b = (uint64_t*)b8;
118
+ int accu = 0;
119
+
120
+ int i = 0;
121
+ int n4 = (n / 4) * 4;
122
+ for (; i < n4; i += 4) {
123
+ const __m256i av = _mm256_loadu_si256((const __m256i_u*)(a + i));
124
+ const __m256i bv = _mm256_loadu_si256((const __m256i_u*)(b + i));
125
+ const __m256i cmp = _mm256_cmpeq_epi8(av, bv);
126
+ const uint32_t movemask = _mm256_movemask_epi8(cmp);
127
+ accu += 32 - popcount32(movemask);
128
+ }
129
+
130
+ for (; i < n; i++)
131
+ accu += generalized_hamming_64(a[i] ^ b[i]);
132
+ return accu;
133
+ }
134
+
135
+ inline int get_code_size() const {
136
+ return n * 8;
137
+ }
138
+ };
139
+
140
+ } // namespace faiss
141
+
142
+ #endif