faiss 0.5.3 → 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 (379) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/ext/faiss/ext.cpp +1 -1
  4. data/ext/faiss/extconf.rb +4 -4
  5. data/ext/faiss/index.cpp +63 -45
  6. data/ext/faiss/index_binary.cpp +37 -27
  7. data/ext/faiss/kmeans.cpp +9 -8
  8. data/ext/faiss/pca_matrix.cpp +9 -7
  9. data/ext/faiss/product_quantizer.cpp +13 -11
  10. data/ext/faiss/utils.cpp +4 -2
  11. data/ext/faiss/utils.h +4 -0
  12. data/lib/faiss/version.rb +1 -1
  13. data/lib/faiss.rb +1 -1
  14. data/vendor/faiss/faiss/AutoTune.cpp +214 -82
  15. data/vendor/faiss/faiss/AutoTune.h +14 -1
  16. data/vendor/faiss/faiss/Clustering.cpp +97 -249
  17. data/vendor/faiss/faiss/Clustering.h +18 -0
  18. data/vendor/faiss/faiss/IVFlib.cpp +67 -44
  19. data/vendor/faiss/faiss/Index.cpp +25 -12
  20. data/vendor/faiss/faiss/Index.h +26 -4
  21. data/vendor/faiss/faiss/Index2Layer.cpp +37 -53
  22. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +68 -61
  23. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +36 -34
  24. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +4 -1
  25. data/vendor/faiss/faiss/IndexBinary.cpp +6 -3
  26. data/vendor/faiss/faiss/IndexBinary.h +4 -4
  27. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +1 -1
  28. data/vendor/faiss/faiss/IndexBinaryFlat.h +1 -1
  29. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -4
  30. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +92 -95
  31. data/vendor/faiss/faiss/IndexBinaryHNSW.h +9 -3
  32. data/vendor/faiss/faiss/IndexBinaryHash.cpp +45 -236
  33. data/vendor/faiss/faiss/IndexBinaryHash.h +6 -6
  34. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +120 -414
  35. data/vendor/faiss/faiss/IndexFastScan.cpp +105 -129
  36. data/vendor/faiss/faiss/IndexFastScan.h +35 -24
  37. data/vendor/faiss/faiss/IndexFlat.cpp +216 -152
  38. data/vendor/faiss/faiss/IndexFlat.h +32 -14
  39. data/vendor/faiss/faiss/IndexFlatCodes.cpp +88 -41
  40. data/vendor/faiss/faiss/IndexFlatCodes.h +7 -1
  41. data/vendor/faiss/faiss/IndexHNSW.cpp +299 -187
  42. data/vendor/faiss/faiss/IndexHNSW.h +30 -14
  43. data/vendor/faiss/faiss/IndexIDMap.cpp +26 -22
  44. data/vendor/faiss/faiss/IndexIDMap.h +9 -7
  45. data/vendor/faiss/faiss/IndexIVF.cpp +535 -405
  46. data/vendor/faiss/faiss/IndexIVF.h +47 -16
  47. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +77 -74
  48. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +105 -99
  49. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +6 -3
  50. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +379 -249
  51. data/vendor/faiss/faiss/IndexIVFFastScan.h +65 -60
  52. data/vendor/faiss/faiss/IndexIVFFlat.cpp +41 -124
  53. data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
  54. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +89 -138
  55. data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
  56. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
  57. data/vendor/faiss/faiss/IndexIVFPQ.cpp +77 -907
  58. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +184 -122
  59. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
  60. data/vendor/faiss/faiss/IndexIVFPQR.cpp +23 -18
  61. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +59 -60
  62. data/vendor/faiss/faiss/IndexIVFRaBitQ.h +4 -3
  63. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +564 -416
  64. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +269 -111
  65. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +41 -127
  66. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
  67. data/vendor/faiss/faiss/IndexLSH.cpp +44 -25
  68. data/vendor/faiss/faiss/IndexLattice.cpp +41 -36
  69. data/vendor/faiss/faiss/IndexNNDescent.cpp +37 -21
  70. data/vendor/faiss/faiss/IndexNNDescent.h +2 -2
  71. data/vendor/faiss/faiss/IndexNSG.cpp +40 -23
  72. data/vendor/faiss/faiss/IndexNSG.h +0 -2
  73. data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +32 -12
  74. data/vendor/faiss/faiss/IndexPQ.cpp +129 -213
  75. data/vendor/faiss/faiss/IndexPQ.h +3 -2
  76. data/vendor/faiss/faiss/IndexPQFastScan.cpp +20 -14
  77. data/vendor/faiss/faiss/IndexPQFastScan.h +3 -0
  78. data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -18
  79. data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
  80. data/vendor/faiss/faiss/IndexRaBitQ.cpp +31 -43
  81. data/vendor/faiss/faiss/IndexRaBitQ.h +4 -3
  82. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +135 -317
  83. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +192 -34
  84. data/vendor/faiss/faiss/IndexRefine.cpp +30 -55
  85. data/vendor/faiss/faiss/IndexRefine.h +4 -4
  86. data/vendor/faiss/faiss/IndexReplicas.cpp +6 -6
  87. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +15 -14
  88. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +1 -1
  89. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +82 -14
  90. data/vendor/faiss/faiss/IndexShards.cpp +13 -13
  91. data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
  92. data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
  93. data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
  94. data/vendor/faiss/faiss/MetaIndexes.h +1 -1
  95. data/vendor/faiss/faiss/MetricType.h +29 -6
  96. data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
  97. data/vendor/faiss/faiss/SuperKMeans.h +97 -0
  98. data/vendor/faiss/faiss/VectorTransform.cpp +349 -141
  99. data/vendor/faiss/faiss/VectorTransform.h +39 -16
  100. data/vendor/faiss/faiss/build.cpp +23 -0
  101. data/vendor/faiss/faiss/build.h +15 -0
  102. data/vendor/faiss/faiss/clone_index.cpp +55 -51
  103. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
  104. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
  105. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
  106. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
  107. data/vendor/faiss/faiss/{cppcontrib/factory_tools.cpp → factory_tools.cpp} +6 -1
  108. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +1 -1
  109. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
  110. data/vendor/faiss/faiss/gpu/GpuResources.h +1 -1
  111. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +9 -9
  112. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +4 -3
  113. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
  114. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
  115. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
  116. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
  117. data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
  118. data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
  119. data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
  120. data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
  121. data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
  122. data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
  123. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +51 -0
  124. data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
  125. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +66 -0
  126. data/vendor/faiss/faiss/gpu_metal/MetalResources.h +79 -0
  127. data/vendor/faiss/faiss/gpu_metal/StandardMetalResources.h +35 -0
  128. data/vendor/faiss/faiss/impl/AdSampling.cpp +103 -0
  129. data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
  130. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +64 -34
  131. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
  132. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
  133. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -28
  134. data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
  135. data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
  136. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +367 -0
  137. data/vendor/faiss/faiss/impl/ClusteringInitialization.h +107 -0
  138. data/vendor/faiss/faiss/impl/CodePacker.cpp +7 -3
  139. data/vendor/faiss/faiss/impl/CodePacker.h +11 -3
  140. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +83 -0
  141. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.h +47 -0
  142. data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
  143. data/vendor/faiss/faiss/impl/FaissAssert.h +64 -3
  144. data/vendor/faiss/faiss/impl/FaissException.h +50 -3
  145. data/vendor/faiss/faiss/impl/HNSW.cpp +117 -351
  146. data/vendor/faiss/faiss/impl/HNSW.h +21 -40
  147. data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
  148. data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
  149. data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
  150. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +114 -102
  151. data/vendor/faiss/faiss/impl/NNDescent.cpp +63 -26
  152. data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
  153. data/vendor/faiss/faiss/impl/NSG.cpp +44 -26
  154. data/vendor/faiss/faiss/impl/NSG.h +20 -10
  155. data/vendor/faiss/faiss/impl/Panorama.cpp +76 -52
  156. data/vendor/faiss/faiss/impl/Panorama.h +265 -78
  157. data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
  158. data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
  159. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +62 -37
  160. data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
  161. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
  162. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
  163. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +99 -80
  164. data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
  165. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +135 -37
  166. data/vendor/faiss/faiss/impl/RaBitQUtils.h +148 -21
  167. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +298 -301
  168. data/vendor/faiss/faiss/impl/RaBitQuantizer.h +3 -10
  169. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +15 -41
  170. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.h +0 -4
  171. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +40 -32
  172. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
  173. data/vendor/faiss/faiss/impl/ResultHandler.h +218 -113
  174. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +119 -2362
  175. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +27 -3
  176. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
  177. data/vendor/faiss/faiss/impl/VisitedTable.cpp +42 -0
  178. data/vendor/faiss/faiss/impl/VisitedTable.h +76 -0
  179. data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
  180. data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
  181. data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
  182. data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
  183. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
  184. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
  185. data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
  186. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
  187. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
  188. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
  189. data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
  190. data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
  191. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
  192. data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
  193. data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
  194. data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
  195. data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
  196. data/vendor/faiss/faiss/impl/expanded_scanners.h +163 -0
  197. data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
  198. data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
  199. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
  200. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
  201. data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
  202. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +268 -0
  203. data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +176 -4
  204. data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
  205. data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
  206. data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
  207. data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
  208. data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
  209. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
  210. data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -348
  211. data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
  212. data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
  213. data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +290 -142
  214. data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
  215. data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
  216. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +91 -0
  217. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -0
  218. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +104 -0
  219. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +111 -0
  220. data/vendor/faiss/faiss/impl/index_read.cpp +1950 -505
  221. data/vendor/faiss/faiss/impl/index_read_utils.h +1 -2
  222. data/vendor/faiss/faiss/impl/index_write.cpp +112 -21
  223. data/vendor/faiss/faiss/impl/io.cpp +6 -6
  224. data/vendor/faiss/faiss/impl/io_macros.h +33 -16
  225. data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
  226. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +81 -40
  227. data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
  228. data/vendor/faiss/faiss/impl/mapped_io.cpp +15 -8
  229. data/vendor/faiss/faiss/impl/platform_macros.h +11 -4
  230. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
  231. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
  232. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
  233. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
  234. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +21 -0
  235. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +21 -0
  236. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +21 -0
  237. data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx2.h → pq_code_distance/pq_code_distance-avx2.h} +43 -220
  238. data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx512.h → pq_code_distance/pq_code_distance-avx512.h} +25 -112
  239. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +59 -0
  240. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
  241. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +256 -0
  242. data/vendor/faiss/faiss/impl/{code_distance/code_distance-sve.h → pq_code_distance/pq_code_distance-sve.cpp} +57 -146
  243. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +68 -0
  244. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +320 -483
  245. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
  246. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +121 -0
  247. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +137 -0
  248. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +371 -0
  249. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +190 -0
  250. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +94 -0
  251. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +603 -0
  252. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +597 -0
  253. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +388 -0
  254. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +630 -0
  255. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +311 -0
  256. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +387 -0
  257. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +54 -0
  258. data/vendor/faiss/faiss/impl/simd_dispatch.h +173 -0
  259. data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
  260. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +274 -171
  261. data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
  262. data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
  263. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
  264. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +275 -217
  265. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
  266. data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
  267. data/vendor/faiss/faiss/impl/svs_io.h +8 -2
  268. data/vendor/faiss/faiss/index_factory.cpp +115 -28
  269. data/vendor/faiss/faiss/index_io.h +53 -3
  270. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +73 -20
  271. data/vendor/faiss/faiss/invlists/DirectMap.cpp +24 -14
  272. data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
  273. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +157 -73
  274. data/vendor/faiss/faiss/invlists/InvertedLists.h +86 -23
  275. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
  276. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +14 -14
  277. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  278. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +9 -19
  279. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
  280. data/vendor/faiss/faiss/svs/IndexSVSFlat.h +2 -0
  281. data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
  282. data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
  283. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
  284. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
  285. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
  286. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
  287. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +25 -1
  288. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +19 -2
  289. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +1 -1
  290. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +19 -2
  291. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +14 -0
  292. data/vendor/faiss/faiss/utils/Heap.cpp +56 -10
  293. data/vendor/faiss/faiss/utils/Heap.h +21 -0
  294. data/vendor/faiss/faiss/utils/NeuralNet.cpp +54 -40
  295. data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
  296. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
  297. data/vendor/faiss/faiss/utils/distances.cpp +507 -559
  298. data/vendor/faiss/faiss/utils/distances.h +118 -1
  299. data/vendor/faiss/faiss/utils/distances_dispatch.h +250 -0
  300. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
  301. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
  302. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
  303. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
  304. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
  305. data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
  306. data/vendor/faiss/faiss/utils/distances_simd.cpp +72 -3681
  307. data/vendor/faiss/faiss/utils/extra_distances.cpp +60 -102
  308. data/vendor/faiss/faiss/utils/extra_distances.h +79 -7
  309. data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
  310. data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
  311. data/vendor/faiss/faiss/utils/hamming.h +92 -2
  312. data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
  313. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +15 -0
  314. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
  315. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
  316. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +234 -0
  317. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-generic.h +368 -0
  318. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +322 -0
  319. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-rvv.h +39 -0
  320. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer.h +146 -0
  321. data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +481 -0
  322. data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +15 -0
  323. data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +15 -0
  324. data/vendor/faiss/faiss/utils/partitioning.cpp +66 -987
  325. data/vendor/faiss/faiss/utils/partitioning.h +31 -0
  326. data/vendor/faiss/faiss/utils/popcount.h +29 -0
  327. data/vendor/faiss/faiss/utils/pq_code_distance.h +251 -0
  328. data/vendor/faiss/faiss/utils/prefetch.h +2 -2
  329. data/vendor/faiss/faiss/utils/quantize_lut.cpp +30 -30
  330. data/vendor/faiss/faiss/utils/quantize_lut.h +1 -1
  331. data/vendor/faiss/faiss/utils/rabitq_simd.h +124 -343
  332. data/vendor/faiss/faiss/utils/random.cpp +6 -6
  333. data/vendor/faiss/faiss/utils/simd_impl/IVFFlatScanner-inl.h +51 -0
  334. data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +154 -0
  335. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +777 -0
  336. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +306 -0
  337. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +1431 -0
  338. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +1095 -0
  339. data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +189 -0
  340. data/vendor/faiss/faiss/utils/simd_impl/distances_simdlib256.h +195 -0
  341. data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +392 -0
  342. data/vendor/faiss/faiss/utils/{distances_fused/simdlib_based.h → simd_impl/exhaustive_L2sqr_blas_cmax.h} +5 -10
  343. data/vendor/faiss/faiss/utils/simd_impl/hamming_impl.h +481 -0
  344. data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +14 -0
  345. data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +14 -0
  346. data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +1085 -0
  347. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +355 -0
  348. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +477 -0
  349. data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +55 -0
  350. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
  351. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
  352. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
  353. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
  354. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
  355. data/vendor/faiss/faiss/utils/simd_levels.cpp +334 -0
  356. data/vendor/faiss/faiss/utils/simd_levels.h +183 -0
  357. data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
  358. data/vendor/faiss/faiss/utils/utils.cpp +21 -14
  359. data/vendor/faiss/faiss/utils/utils.h +3 -3
  360. metadata +156 -42
  361. data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
  362. data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
  363. data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +0 -81
  364. data/vendor/faiss/faiss/impl/code_distance/code_distance.h +0 -186
  365. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -216
  366. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -224
  367. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
  368. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
  369. data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
  370. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
  371. data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -228
  372. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
  373. data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
  374. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -450
  375. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
  376. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
  377. data/vendor/faiss/faiss/utils/simdlib.h +0 -42
  378. data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -296
  379. /data/vendor/faiss/faiss/{cppcontrib/factory_tools.h → factory_tools.h} +0 -0
@@ -1,196 +0,0 @@
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 <immintrin.h>
11
-
12
- #include <limits>
13
-
14
- #include <faiss/impl/FaissAssert.h>
15
- #include <faiss/utils/Heap.h>
16
-
17
- namespace faiss {
18
-
19
- template <typename C, uint32_t NBUCKETS, uint32_t N>
20
- struct HeapWithBuckets {
21
- // this case was not implemented yet.
22
- };
23
-
24
- template <uint32_t NBUCKETS, uint32_t N>
25
- struct HeapWithBuckets<CMax<float, int>, NBUCKETS, N> {
26
- static constexpr uint32_t NBUCKETS_8 = NBUCKETS / 8;
27
- static_assert(
28
- (NBUCKETS) > 0 && ((NBUCKETS % 8) == 0),
29
- "Number of buckets needs to be 8, 16, 24, ...");
30
-
31
- static void addn(
32
- // number of elements
33
- const uint32_t n,
34
- // distances. It is assumed to have n elements.
35
- const float* const __restrict distances,
36
- // number of best elements to keep
37
- const uint32_t k,
38
- // output distances
39
- float* const __restrict bh_val,
40
- // output indices, each being within [0, n) range
41
- int32_t* const __restrict bh_ids) {
42
- // forward a call to bs_addn with 1 beam
43
- bs_addn(1, n, distances, k, bh_val, bh_ids);
44
- }
45
-
46
- static void bs_addn(
47
- // beam_size parameter of Beam Search algorithm
48
- const uint32_t beam_size,
49
- // number of elements per beam
50
- const uint32_t n_per_beam,
51
- // distances. It is assumed to have (n_per_beam * beam_size)
52
- // elements.
53
- const float* const __restrict distances,
54
- // number of best elements to keep
55
- const uint32_t k,
56
- // output distances
57
- float* const __restrict bh_val,
58
- // output indices, each being within [0, n_per_beam * beam_size)
59
- // range
60
- int32_t* const __restrict bh_ids) {
61
- // // Basically, the function runs beam_size iterations.
62
- // // Every iteration NBUCKETS * N elements are added to a regular heap.
63
- // // So, maximum number of added elements is beam_size * NBUCKETS * N.
64
- // // This number is expected to be less or equal than k.
65
- // FAISS_THROW_IF_NOT_FMT(
66
- // beam_size * NBUCKETS * N >= k,
67
- // "Cannot pick %d elements, only %d. "
68
- // "Check the function and template arguments values.",
69
- // k,
70
- // beam_size * NBUCKETS * N);
71
-
72
- using C = CMax<float, int>;
73
-
74
- // main loop
75
- for (uint32_t beam_index = 0; beam_index < beam_size; beam_index++) {
76
- __m256 min_distances_i[NBUCKETS_8][N];
77
- __m256i min_indices_i[NBUCKETS_8][N];
78
-
79
- for (uint32_t j = 0; j < NBUCKETS_8; j++) {
80
- for (uint32_t p = 0; p < N; p++) {
81
- min_distances_i[j][p] =
82
- _mm256_set1_ps(std::numeric_limits<float>::max());
83
- min_indices_i[j][p] =
84
- _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
85
- }
86
- }
87
-
88
- __m256i current_indices = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
89
- __m256i indices_delta = _mm256_set1_epi32(NBUCKETS);
90
-
91
- const uint32_t nb = (n_per_beam / NBUCKETS) * NBUCKETS;
92
-
93
- // put the data into buckets
94
- for (uint32_t ip = 0; ip < nb; ip += NBUCKETS) {
95
- for (uint32_t j = 0; j < NBUCKETS_8; j++) {
96
- const __m256 distances_reg = _mm256_loadu_ps(
97
- distances + j * 8 + ip + n_per_beam * beam_index);
98
-
99
- // loop. Compiler should get rid of unneeded ops
100
- __m256 distance_candidate = distances_reg;
101
- __m256i indices_candidate = current_indices;
102
-
103
- for (uint32_t p = 0; p < N; p++) {
104
- const __m256 comparison = _mm256_cmp_ps(
105
- min_distances_i[j][p],
106
- distance_candidate,
107
- _CMP_LE_OS);
108
-
109
- // // blend seems to be slower than min
110
- // const __m256 min_distances_new = _mm256_blendv_ps(
111
- // distance_candidate,
112
- // min_distances_i[j][p],
113
- // comparison);
114
- const __m256 min_distances_new = _mm256_min_ps(
115
- distance_candidate, min_distances_i[j][p]);
116
- const __m256i min_indices_new =
117
- _mm256_castps_si256(_mm256_blendv_ps(
118
- _mm256_castsi256_ps(indices_candidate),
119
- _mm256_castsi256_ps(
120
- min_indices_i[j][p]),
121
- comparison));
122
-
123
- // // blend seems to be slower than min
124
- // const __m256 max_distances_new = _mm256_blendv_ps(
125
- // min_distances_i[j][p],
126
- // distance_candidate,
127
- // comparison);
128
- const __m256 max_distances_new = _mm256_max_ps(
129
- min_distances_i[j][p], distances_reg);
130
- const __m256i max_indices_new =
131
- _mm256_castps_si256(_mm256_blendv_ps(
132
- _mm256_castsi256_ps(
133
- min_indices_i[j][p]),
134
- _mm256_castsi256_ps(indices_candidate),
135
- comparison));
136
-
137
- distance_candidate = max_distances_new;
138
- indices_candidate = max_indices_new;
139
-
140
- min_distances_i[j][p] = min_distances_new;
141
- min_indices_i[j][p] = min_indices_new;
142
- }
143
- }
144
-
145
- current_indices =
146
- _mm256_add_epi32(current_indices, indices_delta);
147
- }
148
-
149
- // fix the indices
150
- for (uint32_t j = 0; j < NBUCKETS_8; j++) {
151
- const __m256i offset =
152
- _mm256_set1_epi32(n_per_beam * beam_index + j * 8);
153
- for (uint32_t p = 0; p < N; p++) {
154
- min_indices_i[j][p] =
155
- _mm256_add_epi32(min_indices_i[j][p], offset);
156
- }
157
- }
158
-
159
- // merge every bucket into the regular heap
160
- for (uint32_t p = 0; p < N; p++) {
161
- for (uint32_t j = 0; j < NBUCKETS_8; j++) {
162
- int32_t min_indices_scalar[8];
163
- float min_distances_scalar[8];
164
-
165
- _mm256_storeu_si256(
166
- (__m256i*)min_indices_scalar, min_indices_i[j][p]);
167
- _mm256_storeu_ps(
168
- min_distances_scalar, min_distances_i[j][p]);
169
-
170
- // this exact way is needed to maintain the order as if the
171
- // input elements were pushed to the heap sequentially
172
- for (size_t j8 = 0; j8 < 8; j8++) {
173
- const auto value = min_distances_scalar[j8];
174
- const auto index = min_indices_scalar[j8];
175
- if (C::cmp2(bh_val[0], value, bh_ids[0], index)) {
176
- heap_replace_top<C>(
177
- k, bh_val, bh_ids, value, index);
178
- }
179
- }
180
- }
181
- }
182
-
183
- // process leftovers
184
- for (uint32_t ip = nb; ip < n_per_beam; ip++) {
185
- const int32_t index = ip + n_per_beam * beam_index;
186
- const float value = distances[index];
187
-
188
- if (C::cmp(bh_val[0], value)) {
189
- heap_replace_top<C>(k, bh_val, bh_ids, value, index);
190
- }
191
- }
192
- }
193
- }
194
- };
195
-
196
- } // namespace faiss
@@ -1,34 +0,0 @@
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
- /// Represents the mode of use of approximate top-k computations
11
- /// that allows to trade accuracy vs speed. So, every options
12
- /// besides EXACT_TOPK increases the speed.
13
- ///
14
- /// B represents the number of buckets.
15
- /// D is the number of min-k elements to track within every bucket.
16
- ///
17
- /// Default option is EXACT_TOPK.
18
- /// APPROX_TOPK_BUCKETS_B16_D2 is worth starting from, if you'd like
19
- /// to experiment a bit.
20
- ///
21
- /// It seems that only the limited number of combinations are
22
- /// meaningful, because of the limited supply of SIMD registers.
23
- /// Also, certain combinations, such as B32_D1 and B16_D1, were concluded
24
- /// to be not very precise in benchmarks, so they were not introduced.
25
- ///
26
- /// TODO: Consider d-ary SIMD heap.
27
-
28
- enum ApproxTopK_mode_t : int {
29
- EXACT_TOPK = 0,
30
- APPROX_TOPK_BUCKETS_B32_D2 = 1,
31
- APPROX_TOPK_BUCKETS_B8_D3 = 2,
32
- APPROX_TOPK_BUCKETS_B16_D2 = 3,
33
- APPROX_TOPK_BUCKETS_B8_D2 = 4,
34
- };
@@ -1,36 +0,0 @@
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
- // AVX512 might be not used, but this version provides ~2x speedup
9
- // over AVX2 kernel, say, for training PQx10 or PQx12, and speeds up
10
- // additional cases with larger dimensionalities.
11
-
12
- #pragma once
13
-
14
- #include <faiss/impl/ResultHandler.h>
15
- #include <faiss/impl/platform_macros.h>
16
-
17
- #include <faiss/utils/Heap.h>
18
-
19
- #ifdef __AVX512F__
20
-
21
- namespace faiss {
22
-
23
- // Returns true if the fused kernel is available and the data was processed.
24
- // Returns false if the fused kernel is not available.
25
- bool exhaustive_L2sqr_fused_cmax_AVX512(
26
- const float* x,
27
- const float* y,
28
- size_t d,
29
- size_t nx,
30
- size_t ny,
31
- Top1BlockResultHandler<CMax<float, int64_t>>& res,
32
- const float* y_norms);
33
-
34
- } // namespace faiss
35
-
36
- #endif
@@ -1,228 +0,0 @@
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
- /** In this file are the implementations of extra metrics beyond L2
11
- * and inner product */
12
-
13
- #include <faiss/MetricType.h>
14
- #include <faiss/impl/FaissAssert.h>
15
- #include <faiss/utils/distances.h>
16
- #include <cmath>
17
- #include <type_traits>
18
-
19
- namespace faiss {
20
-
21
- template <MetricType mt>
22
- struct VectorDistance {
23
- size_t d;
24
- float metric_arg;
25
- static constexpr bool is_similarity = is_similarity_metric(mt);
26
-
27
- inline float operator()(const float* x, const float* y) const;
28
-
29
- // heap template to use for this type of metric
30
- using C = typename std::conditional<
31
- is_similarity_metric(mt),
32
- CMin<float, int64_t>,
33
- CMax<float, int64_t>>::type;
34
- };
35
-
36
- template <>
37
- inline float VectorDistance<METRIC_L2>::operator()(
38
- const float* x,
39
- const float* y) const {
40
- return fvec_L2sqr(x, y, d);
41
- }
42
-
43
- template <>
44
- inline float VectorDistance<METRIC_INNER_PRODUCT>::operator()(
45
- const float* x,
46
- const float* y) const {
47
- return fvec_inner_product(x, y, d);
48
- }
49
-
50
- template <>
51
- inline float VectorDistance<METRIC_L1>::operator()(
52
- const float* x,
53
- const float* y) const {
54
- return fvec_L1(x, y, d);
55
- }
56
-
57
- template <>
58
- inline float VectorDistance<METRIC_Linf>::operator()(
59
- const float* x,
60
- const float* y) const {
61
- return fvec_Linf(x, y, d);
62
- /*
63
- float vmax = 0;
64
- for (size_t i = 0; i < d; i++) {
65
- float diff = fabs (x[i] - y[i]);
66
- if (diff > vmax) vmax = diff;
67
- }
68
- return vmax;*/
69
- }
70
-
71
- template <>
72
- inline float VectorDistance<METRIC_Lp>::operator()(
73
- const float* x,
74
- const float* y) const {
75
- float accu = 0;
76
- for (size_t i = 0; i < d; i++) {
77
- float diff = fabs(x[i] - y[i]);
78
- accu += powf(diff, metric_arg);
79
- }
80
- return accu;
81
- }
82
-
83
- template <>
84
- inline float VectorDistance<METRIC_Canberra>::operator()(
85
- const float* x,
86
- const float* y) const {
87
- float accu = 0;
88
- for (size_t i = 0; i < d; i++) {
89
- float xi = x[i], yi = y[i];
90
- accu += fabs(xi - yi) / (fabs(xi) + fabs(yi));
91
- }
92
- return accu;
93
- }
94
-
95
- template <>
96
- inline float VectorDistance<METRIC_BrayCurtis>::operator()(
97
- const float* x,
98
- const float* y) const {
99
- float accu_num = 0, accu_den = 0;
100
- for (size_t i = 0; i < d; i++) {
101
- float xi = x[i], yi = y[i];
102
- accu_num += fabs(xi - yi);
103
- accu_den += fabs(xi + yi);
104
- }
105
- return accu_num / accu_den;
106
- }
107
-
108
- template <>
109
- inline float VectorDistance<METRIC_JensenShannon>::operator()(
110
- const float* x,
111
- const float* y) const {
112
- float accu = 0;
113
- for (size_t i = 0; i < d; i++) {
114
- float xi = x[i], yi = y[i];
115
- float mi = 0.5 * (xi + yi);
116
- float kl1 = -xi * log(mi / xi);
117
- float kl2 = -yi * log(mi / yi);
118
- accu += kl1 + kl2;
119
- }
120
- return 0.5 * accu;
121
- }
122
-
123
- template <>
124
- inline float VectorDistance<METRIC_Jaccard>::operator()(
125
- const float* x,
126
- const float* y) const {
127
- // WARNING: this distance is defined only for positive input vectors.
128
- // Providing vectors with negative values would lead to incorrect results.
129
- float accu_num = 0, accu_den = 0;
130
- for (size_t i = 0; i < d; i++) {
131
- accu_num += fmin(x[i], y[i]);
132
- accu_den += fmax(x[i], y[i]);
133
- }
134
- return accu_num / accu_den;
135
- }
136
-
137
- template <>
138
- inline float VectorDistance<METRIC_NaNEuclidean>::operator()(
139
- const float* x,
140
- const float* y) const {
141
- // https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.nan_euclidean_distances.html
142
- float accu = 0;
143
- size_t present = 0;
144
- for (size_t i = 0; i < d; i++) {
145
- if (!std::isnan(x[i]) && !std::isnan(y[i])) {
146
- float diff = x[i] - y[i];
147
- accu += diff * diff;
148
- present++;
149
- }
150
- }
151
- if (present == 0) {
152
- return NAN;
153
- }
154
- return float(d) / float(present) * accu;
155
- }
156
-
157
- template <>
158
- inline float VectorDistance<METRIC_GOWER>::operator()(
159
- const float* x,
160
- const float* y) const {
161
- float accu = 0;
162
- size_t valid_dims = 0;
163
-
164
- for (size_t i = 0; i < d; i++) {
165
- if (std::isnan(x[i]) || std::isnan(y[i])) {
166
- continue;
167
- }
168
-
169
- if (x[i] >= 0 && y[i] >= 0) {
170
- if (x[i] > 1 || y[i] > 1) {
171
- return std::numeric_limits<float>::quiet_NaN();
172
- }
173
- // Numeric dimensions are in [0,1]
174
- accu += fabs(x[i] - y[i]);
175
- } else if (x[i] < 0 && y[i] < 0) {
176
- // Categorical dimensions are negative values
177
- accu += float(int(x[i] != y[i]));
178
- } else {
179
- // Invalid representation
180
- return std::numeric_limits<float>::quiet_NaN();
181
- }
182
- valid_dims++;
183
- }
184
-
185
- if (valid_dims == 0) {
186
- return std::numeric_limits<float>::quiet_NaN();
187
- }
188
- return accu / valid_dims;
189
- }
190
-
191
- /***************************************************************************
192
- * Dispatching function that takes a metric type and a consumer object
193
- * the consumer object should contain a return type T and a operation template
194
- * function f() that is called to perform the operation. The first argument
195
- * of the function is the VectorDistance object. The rest are passed in as is.
196
- **************************************************************************/
197
-
198
- template <class Consumer, class... Types>
199
- typename Consumer::T dispatch_VectorDistance(
200
- size_t d,
201
- MetricType metric,
202
- float metric_arg,
203
- Consumer& consumer,
204
- Types... args) {
205
- switch (metric) {
206
- #define DISPATCH_VD(mt) \
207
- case mt: { \
208
- VectorDistance<mt> vd = {d, metric_arg}; \
209
- return consumer.template f<VectorDistance<mt>>(vd, args...); \
210
- }
211
- DISPATCH_VD(METRIC_INNER_PRODUCT);
212
- DISPATCH_VD(METRIC_L2);
213
- DISPATCH_VD(METRIC_L1);
214
- DISPATCH_VD(METRIC_Linf);
215
- DISPATCH_VD(METRIC_Lp);
216
- DISPATCH_VD(METRIC_Canberra);
217
- DISPATCH_VD(METRIC_BrayCurtis);
218
- DISPATCH_VD(METRIC_JensenShannon);
219
- DISPATCH_VD(METRIC_Jaccard);
220
- DISPATCH_VD(METRIC_NaNEuclidean);
221
- DISPATCH_VD(METRIC_GOWER);
222
- default:
223
- FAISS_THROW_FMT("Invalid metric %d", metric);
224
- }
225
- #undef DISPATCH_VD
226
- }
227
-
228
- } // namespace faiss