faiss 0.6.0 → 0.6.2

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 (378) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -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 +88 -97
  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 +89 -417
  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 +374 -206
  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 +467 -364
  41. data/vendor/faiss/faiss/IndexIVF.h +33 -12
  42. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +79 -76
  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 +39 -69
  48. data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
  49. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +56 -33
  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 +73 -846
  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 +23 -20
  56. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +30 -52
  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 +38 -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 +150 -20
  84. data/vendor/faiss/faiss/IndexScalarQuantizer.h +10 -0
  85. data/vendor/faiss/faiss/IndexShards.cpp +10 -9
  86. data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
  87. data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
  88. data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
  89. data/vendor/faiss/faiss/MetaIndexes.h +1 -1
  90. data/vendor/faiss/faiss/MetricType.h +14 -7
  91. data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
  92. data/vendor/faiss/faiss/SuperKMeans.h +97 -0
  93. data/vendor/faiss/faiss/VectorTransform.cpp +237 -149
  94. data/vendor/faiss/faiss/VectorTransform.h +16 -16
  95. data/vendor/faiss/faiss/build.cpp +23 -0
  96. data/vendor/faiss/faiss/build.h +15 -0
  97. data/vendor/faiss/faiss/clone_index.cpp +48 -47
  98. data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +1 -1
  99. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
  100. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
  101. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +902 -12
  102. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
  103. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
  104. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +702 -10
  105. data/vendor/faiss/faiss/factory_tools.cpp +9 -0
  106. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
  107. data/vendor/faiss/faiss/gpu/GpuResources.h +3 -2
  108. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +15 -16
  109. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +5 -4
  110. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
  111. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
  112. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
  113. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
  114. data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
  115. data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
  116. data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
  117. data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
  118. data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
  119. data/vendor/faiss/faiss/gpu_metal/MetalDistance.h +87 -0
  120. data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
  121. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +58 -0
  122. data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
  123. data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +181 -0
  124. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +111 -0
  125. data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +45 -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/gpu_metal/impl/MetalIVFFlat.h +193 -0
  129. data/vendor/faiss/faiss/impl/AdSampling.cpp +103 -0
  130. data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
  131. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +29 -25
  132. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
  133. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
  134. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -0
  135. data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
  136. data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
  137. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +16 -16
  138. data/vendor/faiss/faiss/impl/CodePacker.cpp +3 -3
  139. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +1 -1
  140. data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
  141. data/vendor/faiss/faiss/impl/FaissAssert.h +6 -3
  142. data/vendor/faiss/faiss/impl/FaissException.h +50 -3
  143. data/vendor/faiss/faiss/impl/HNSW.cpp +639 -507
  144. data/vendor/faiss/faiss/impl/HNSW.h +61 -44
  145. data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
  146. data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
  147. data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
  148. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +82 -77
  149. data/vendor/faiss/faiss/impl/NNDescent.cpp +62 -25
  150. data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
  151. data/vendor/faiss/faiss/impl/NSG.cpp +53 -32
  152. data/vendor/faiss/faiss/impl/NSG.h +4 -4
  153. data/vendor/faiss/faiss/impl/Panorama.cpp +23 -6
  154. data/vendor/faiss/faiss/impl/Panorama.h +269 -87
  155. data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
  156. data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
  157. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +46 -32
  158. data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
  159. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
  160. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
  161. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +55 -25
  162. data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
  163. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +55 -49
  164. data/vendor/faiss/faiss/impl/RaBitQUtils.h +65 -0
  165. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +302 -283
  166. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +26 -23
  167. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
  168. data/vendor/faiss/faiss/impl/ResultHandler.h +100 -75
  169. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +318 -7
  170. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +77 -1
  171. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
  172. data/vendor/faiss/faiss/impl/VisitedTable.cpp +10 -10
  173. data/vendor/faiss/faiss/impl/VisitedTable.h +70 -28
  174. data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
  175. data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
  176. data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
  177. data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
  178. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
  179. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
  180. data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
  181. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
  182. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
  183. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
  184. data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
  185. data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
  186. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
  187. data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
  188. data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
  189. data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
  190. data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
  191. data/vendor/faiss/faiss/impl/expanded_scanners.h +8 -3
  192. data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
  193. data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
  194. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
  195. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
  196. data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
  197. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +270 -0
  198. data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +169 -2
  199. data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
  200. data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
  201. data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
  202. data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
  203. data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
  204. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
  205. data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -356
  206. data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
  207. data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
  208. data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +282 -134
  209. data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
  210. data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
  211. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +83 -0
  212. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +113 -0
  213. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +150 -0
  214. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +142 -0
  215. data/vendor/faiss/faiss/impl/index_read.cpp +1227 -79
  216. data/vendor/faiss/faiss/impl/index_read_utils.h +1 -1
  217. data/vendor/faiss/faiss/impl/index_write.cpp +96 -13
  218. data/vendor/faiss/faiss/impl/io.cpp +6 -6
  219. data/vendor/faiss/faiss/impl/io_macros.h +58 -16
  220. data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
  221. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +37 -23
  222. data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
  223. data/vendor/faiss/faiss/impl/mapped_io.cpp +6 -6
  224. data/vendor/faiss/faiss/impl/platform_macros.h +15 -4
  225. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
  226. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
  227. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
  228. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
  229. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +23 -0
  230. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +23 -0
  231. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +23 -0
  232. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx2.cpp → pq_code_distance-avx2.h} +9 -13
  233. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx512.cpp → pq_code_distance-avx512.h} +9 -57
  234. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +45 -107
  235. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
  236. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +274 -5
  237. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +10 -7
  238. data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +105 -0
  239. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +70 -0
  240. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +311 -477
  241. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
  242. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +1 -1
  243. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +9 -2
  244. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +419 -19
  245. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +27 -1
  246. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +3 -3
  247. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +387 -2
  248. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +553 -0
  249. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +559 -0
  250. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +341 -2
  251. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +425 -3
  252. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +290 -2
  253. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +337 -0
  254. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +192 -8
  255. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +12 -0
  256. data/vendor/faiss/faiss/impl/simd_dispatch.h +157 -66
  257. data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
  258. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +264 -172
  259. data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
  260. data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
  261. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
  262. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +270 -218
  263. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
  264. data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
  265. data/vendor/faiss/faiss/impl/svs_io.h +8 -2
  266. data/vendor/faiss/faiss/index_factory.cpp +90 -18
  267. data/vendor/faiss/faiss/index_io.h +40 -0
  268. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +66 -16
  269. data/vendor/faiss/faiss/invlists/DirectMap.cpp +28 -15
  270. data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
  271. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +170 -86
  272. data/vendor/faiss/faiss/invlists/InvertedLists.h +88 -25
  273. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
  274. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +13 -13
  275. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  276. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +1 -1
  277. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
  278. data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
  279. data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
  280. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
  281. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
  282. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
  283. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
  284. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +142 -21
  285. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +33 -7
  286. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +3 -2
  287. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
  288. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +77 -27
  289. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +10 -4
  290. data/vendor/faiss/faiss/utils/Heap.cpp +10 -10
  291. data/vendor/faiss/faiss/utils/NeuralNet.cpp +47 -36
  292. data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
  293. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
  294. data/vendor/faiss/faiss/utils/bf16.h +34 -0
  295. data/vendor/faiss/faiss/utils/distances.cpp +390 -560
  296. data/vendor/faiss/faiss/utils/distances.h +20 -1
  297. data/vendor/faiss/faiss/utils/distances_dispatch.h +117 -37
  298. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
  299. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
  300. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
  301. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
  302. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
  303. data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
  304. data/vendor/faiss/faiss/utils/distances_simd.cpp +5 -178
  305. data/vendor/faiss/faiss/utils/extra_distances.cpp +9 -8
  306. data/vendor/faiss/faiss/utils/extra_distances.h +32 -6
  307. data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
  308. data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
  309. data/vendor/faiss/faiss/utils/hamming.h +92 -2
  310. data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
  311. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +16 -0
  312. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
  313. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +15 -0
  314. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
  315. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +210 -0
  316. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_spr.h +171 -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 -989
  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 +2 -2
  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 +57 -536
  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 +5 -1
  335. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +213 -4
  336. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +163 -10
  337. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +250 -4
  338. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +7 -4
  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 +2 -1
  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 +1031 -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_avx512_spr.cpp +343 -0
  350. data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +55 -0
  351. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
  352. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
  353. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
  354. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
  355. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
  356. data/vendor/faiss/faiss/utils/simd_levels.cpp +29 -7
  357. data/vendor/faiss/faiss/utils/simd_levels.h +93 -1
  358. data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
  359. data/vendor/faiss/faiss/utils/utils.cpp +5 -5
  360. data/vendor/faiss/faiss/utils/utils.h +3 -3
  361. metadata +129 -34
  362. data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
  363. data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
  364. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -224
  365. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -230
  366. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
  367. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
  368. data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
  369. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
  370. data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -235
  371. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
  372. data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
  373. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -449
  374. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
  375. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
  376. data/vendor/faiss/faiss/utils/simdlib.h +0 -42
  377. data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -365
  378. /data/ext/faiss/{utils_rb.h → utils.h} +0 -0
@@ -58,7 +58,7 @@ struct IndexBinary {
58
58
  } else {
59
59
  FAISS_THROW_MSG("IndexBinary::train: unsupported numeric type");
60
60
  }
61
- };
61
+ }
62
62
 
63
63
  /** Add n vectors of dimension d to the index.
64
64
  *
@@ -72,7 +72,7 @@ struct IndexBinary {
72
72
  } else {
73
73
  FAISS_THROW_MSG("IndexBinary::add: unsupported numeric type");
74
74
  }
75
- };
75
+ }
76
76
 
77
77
  /** Same as add, but stores xids instead of sequential ids.
78
78
  *
@@ -93,7 +93,7 @@ struct IndexBinary {
93
93
  FAISS_THROW_MSG(
94
94
  "IndexBinary::add_with_ids: unsupported numeric type");
95
95
  }
96
- };
96
+ }
97
97
 
98
98
  /** Query n vectors of dimension d to the index.
99
99
  *
@@ -129,7 +129,7 @@ struct IndexBinary {
129
129
  } else {
130
130
  FAISS_THROW_MSG("IndexBinary::search: unsupported numeric type");
131
131
  }
132
- };
132
+ }
133
133
 
134
134
  /** Query n vectors of dimension d to the index.
135
135
  *
@@ -18,7 +18,7 @@
18
18
 
19
19
  namespace faiss {
20
20
 
21
- IndexBinaryFlat::IndexBinaryFlat(idx_t d) : IndexBinary(d) {}
21
+ IndexBinaryFlat::IndexBinaryFlat(idx_t d_) : IndexBinary(d_) {}
22
22
 
23
23
  void IndexBinaryFlat::add(idx_t n, const uint8_t* x) {
24
24
  xb.insert(xb.end(), x, x + n * code_size);
@@ -14,8 +14,8 @@
14
14
 
15
15
  #include <faiss/IndexBinary.h>
16
16
 
17
+ #include <faiss/impl/approx_topk/approx_topk.h>
17
18
  #include <faiss/impl/maybe_owned_vector.h>
18
- #include <faiss/utils/approx_topk/mode.h>
19
19
 
20
20
  namespace faiss {
21
21
 
@@ -18,10 +18,10 @@ namespace faiss {
18
18
 
19
19
  IndexBinaryFromFloat::IndexBinaryFromFloat() = default;
20
20
 
21
- IndexBinaryFromFloat::IndexBinaryFromFloat(Index* index)
22
- : IndexBinary(index->d), index(index), own_fields(false) {
23
- is_trained = index->is_trained;
24
- ntotal = index->ntotal;
21
+ IndexBinaryFromFloat::IndexBinaryFromFloat(Index* index_)
22
+ : IndexBinary(index_->d), index(index_), own_fields(false) {
23
+ is_trained = index_->is_trained;
24
+ ntotal = index_->ntotal;
25
25
  }
26
26
 
27
27
  IndexBinaryFromFloat::~IndexBinaryFromFloat() {
@@ -27,8 +27,17 @@
27
27
  #include <faiss/utils/hamming.h>
28
28
  #include <faiss/utils/random.h>
29
29
 
30
+ #include <faiss/impl/simd_dispatch.h>
31
+
30
32
  #include <random>
31
33
 
34
+ // Scalar (NONE) fallback for dynamic dispatch
35
+ #define THE_SIMD_LEVEL SIMDLevel::NONE
36
+ // NOLINTNEXTLINE(facebook-hte-InlineHeader)
37
+ // NOLINTNEXTLINE(facebook-hte-InlineHeader)
38
+ #include <faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h>
39
+ #undef THE_SIMD_LEVEL
40
+
32
41
  namespace faiss {
33
42
 
34
43
  /**************************************************************
@@ -61,10 +70,8 @@ void hnsw_add_vertices(
61
70
  printf(" max_level = %d\n", max_level);
62
71
  }
63
72
 
64
- std::vector<omp_lock_t> locks(ntotal);
65
- for (int i = 0; i < ntotal; i++) {
66
- omp_init_lock(&locks[i]);
67
- }
73
+ auto& locks = index_hnsw.locks;
74
+ locks.prepare(ntotal);
68
75
 
69
76
  // add vectors from highest to lowest level
70
77
  std::vector<int> hist;
@@ -73,10 +80,11 @@ void hnsw_add_vertices(
73
80
  { // make buckets with vectors of the same level
74
81
 
75
82
  // build histogram
76
- for (int i = 0; i < n; i++) {
77
- HNSW::storage_idx_t pt_id = i + n0;
83
+ for (size_t i = 0; i < n; i++) {
84
+ HNSW::storage_idx_t pt_id =
85
+ static_cast<HNSW::storage_idx_t>(i + n0);
78
86
  int pt_level = hnsw.levels[pt_id] - 1;
79
- while (pt_level >= hist.size()) {
87
+ while (pt_level >= static_cast<int>(hist.size())) {
80
88
  hist.push_back(0);
81
89
  }
82
90
  hist[pt_level]++;
@@ -84,13 +92,14 @@ void hnsw_add_vertices(
84
92
 
85
93
  // accumulate
86
94
  std::vector<int> offsets(hist.size() + 1, 0);
87
- for (int i = 0; i < hist.size() - 1; i++) {
95
+ for (size_t i = 0; i < hist.size() - 1; i++) {
88
96
  offsets[i + 1] = offsets[i] + hist[i];
89
97
  }
90
98
 
91
99
  // bucket sort
92
- for (int i = 0; i < n; i++) {
93
- HNSW::storage_idx_t pt_id = i + n0;
100
+ for (size_t i = 0; i < n; i++) {
101
+ HNSW::storage_idx_t pt_id =
102
+ static_cast<HNSW::storage_idx_t>(i + n0);
94
103
  int pt_level = hnsw.levels[pt_id] - 1;
95
104
  order[offsets[pt_level]++] = pt_id;
96
105
  }
@@ -99,33 +108,35 @@ void hnsw_add_vertices(
99
108
  { // perform add
100
109
  RandomGenerator rng2(789);
101
110
 
102
- int i1 = n;
111
+ size_t i1 = static_cast<int>(n);
103
112
 
104
- for (int pt_level = hist.size() - 1;
113
+ for (int pt_level = static_cast<int>(hist.size()) - 1;
105
114
  pt_level >= int(!index_hnsw.init_level0);
106
115
  pt_level--) {
107
- int i0 = i1 - hist[pt_level];
116
+ size_t i0 = i1 - hist[pt_level];
108
117
 
109
118
  if (verbose) {
110
- printf("Adding %d elements at level %d\n", i1 - i0, pt_level);
119
+ printf("Adding %zu elements at level %d\n", i1 - i0, pt_level);
111
120
  }
112
121
 
113
122
  // random permutation to get rid of dataset order bias
114
- for (int j = i0; j < i1; j++) {
115
- std::swap(order[j], order[j + rng2.rand_int(i1 - j)]);
123
+ for (size_t j = i0; j < i1; j++) {
124
+ std::swap(
125
+ order[j],
126
+ order[j + rng2.rand_int(static_cast<int>(i1 - j))]);
116
127
  }
117
128
 
118
129
  #pragma omp parallel
119
130
  {
120
- VisitedTable vt(ntotal);
131
+ std::unique_ptr<VisitedTable> vt = VisitedTable::create(ntotal);
121
132
 
122
133
  std::unique_ptr<DistanceComputer> dis(
123
134
  index_hnsw.get_distance_computer());
124
- int prev_display =
125
- verbose && omp_get_thread_num() == 0 ? 0 : -1;
135
+ bool do_display = verbose && omp_get_thread_num() == 0;
136
+ size_t prev_display = 0;
126
137
 
127
138
  #pragma omp for schedule(dynamic)
128
- for (int i = i0; i < i1; i++) {
139
+ for (int64_t i = i0; i < i1; i++) {
129
140
  HNSW::storage_idx_t pt_id = order[i];
130
141
  dis->set_query(
131
142
  (float*)(x + (pt_id - n0) * index_hnsw.code_size));
@@ -135,12 +146,12 @@ void hnsw_add_vertices(
135
146
  pt_level,
136
147
  pt_id,
137
148
  locks,
138
- vt,
149
+ *vt,
139
150
  index_hnsw.keep_max_size_level0 && (pt_level == 0));
140
151
 
141
- if (prev_display >= 0 && i - i0 > prev_display + 10000) {
152
+ if (do_display && i - i0 > prev_display + 10000) {
142
153
  prev_display = i - i0;
143
- printf(" %d / %d\r", i - i0, i1 - i0);
154
+ printf(" %zu / %zu\r", i - i0, i1 - i0);
144
155
  fflush(stdout);
145
156
  }
146
157
  }
@@ -156,9 +167,8 @@ void hnsw_add_vertices(
156
167
  if (verbose) {
157
168
  printf("Done in %.3f ms\n", getmillisecs() - t0);
158
169
  }
159
-
160
- for (int i = 0; i < ntotal; i++) {
161
- omp_destroy_lock(&locks[i]);
170
+ if (!index_hnsw.retain_locks) {
171
+ locks.clear();
162
172
  }
163
173
  }
164
174
 
@@ -172,19 +182,19 @@ IndexBinaryHNSW::IndexBinaryHNSW() {
172
182
  is_trained = true;
173
183
  }
174
184
 
175
- IndexBinaryHNSW::IndexBinaryHNSW(int d, int M)
176
- : IndexBinary(d),
185
+ IndexBinaryHNSW::IndexBinaryHNSW(int d_, int M)
186
+ : IndexBinary(d_),
177
187
  hnsw(M),
178
188
  own_fields(true),
179
- storage(new IndexBinaryFlat(d)) {
189
+ storage(new IndexBinaryFlat(d_)) {
180
190
  is_trained = true;
181
191
  }
182
192
 
183
- IndexBinaryHNSW::IndexBinaryHNSW(IndexBinary* storage, int M)
184
- : IndexBinary(storage->d),
193
+ IndexBinaryHNSW::IndexBinaryHNSW(IndexBinary* storage_, int M)
194
+ : IndexBinary(storage_->d),
185
195
  hnsw(M),
186
196
  own_fields(false),
187
- storage(storage) {
197
+ storage(storage_) {
188
198
  is_trained = true;
189
199
  }
190
200
 
@@ -222,42 +232,57 @@ void IndexBinaryHNSW::search(
222
232
  using RH = HeapBlockResultHandler<HNSW::C>;
223
233
  RH bres(n, distances_f, labels, k);
224
234
 
235
+ size_t n1 = 0, n2 = 0, ndis = 0, nhops = 0;
236
+
225
237
  #pragma omp parallel
226
238
  {
227
- VisitedTable vt(ntotal);
239
+ std::unique_ptr<VisitedTable> vt = VisitedTable::create(ntotal);
228
240
  std::unique_ptr<DistanceComputer> dis(get_distance_computer());
229
241
  RH::SingleResultHandler res(bres);
230
242
 
231
- #pragma omp for
243
+ #pragma omp for reduction(+ : n1, n2, ndis, nhops)
232
244
  for (idx_t i = 0; i < n; i++) {
233
245
  res.begin(i);
234
246
  dis->set_query((float*)(x + i * code_size));
235
247
  // Given that IndexBinaryHNSW is not an IndexHNSW, we pass nullptr
236
248
  // as the index parameter. This state does not get used in the
237
- // search function, as it is merely there to to enable Panorama
249
+ // search function, as it is merely there to enable Panorama
238
250
  // execution for IndexHNSWFlatPanorama.
239
- hnsw.search(*dis, nullptr, res, vt, params_in);
251
+ HNSWStats stats = hnsw.search(*dis, nullptr, res, *vt, params_in);
252
+ n1 += stats.n1;
253
+ n2 += stats.n2;
254
+ ndis += stats.ndis;
255
+ nhops += stats.nhops;
240
256
  res.end();
241
257
  }
242
258
  }
243
259
 
260
+ hnsw_stats.combine({n1, n2, ndis, nhops});
261
+
244
262
  #pragma omp parallel for
245
- for (int i = 0; i < n * k; ++i) {
263
+ for (idx_t i = 0; i < n * k; ++i) {
246
264
  distances[i] = std::round(distances_f[i]);
247
265
  }
248
266
  }
249
267
 
250
268
  void IndexBinaryHNSW::add(idx_t n, const uint8_t* x) {
251
269
  FAISS_THROW_IF_NOT(is_trained);
252
- int n0 = ntotal;
270
+ size_t n0 = ntotal;
253
271
  storage->add(n, x);
254
272
  ntotal = storage->ntotal;
255
273
 
256
- hnsw_add_vertices(*this, n0, n, x, verbose, hnsw.levels.size() == ntotal);
274
+ hnsw_add_vertices(
275
+ *this,
276
+ n0,
277
+ n,
278
+ x,
279
+ verbose,
280
+ hnsw.levels.size() == static_cast<size_t>(ntotal));
257
281
  }
258
282
 
259
283
  void IndexBinaryHNSW::reset() {
260
284
  hnsw.reset();
285
+ locks.clear();
261
286
  storage->reset();
262
287
  ntotal = 0;
263
288
  }
@@ -266,60 +291,15 @@ void IndexBinaryHNSW::reconstruct(idx_t key, uint8_t* recons) const {
266
291
  storage->reconstruct(key, recons);
267
292
  }
268
293
 
269
- namespace {
270
-
271
- template <class HammingComputer>
272
- struct FlatHammingDis : DistanceComputer {
273
- const int code_size;
274
- const uint8_t* b;
275
- size_t ndis;
276
- HammingComputer hc;
277
-
278
- float operator()(idx_t i) override {
279
- ndis++;
280
- return hc.hamming(b + i * code_size);
281
- }
282
-
283
- float symmetric_dis(idx_t i, idx_t j) override {
284
- return HammingComputerDefault(b + j * code_size, code_size)
285
- .hamming(b + i * code_size);
286
- }
287
-
288
- explicit FlatHammingDis(const IndexBinaryFlat& storage)
289
- : code_size(storage.code_size),
290
- b(storage.xb.data()),
291
- ndis(0),
292
- hc() {}
293
-
294
- // NOTE: Pointers are cast from float in order to reuse the floating-point
295
- // DistanceComputer.
296
- void set_query(const float* x) override {
297
- hc.set((uint8_t*)x, code_size);
298
- }
299
-
300
- ~FlatHammingDis() override {
301
- #pragma omp critical
302
- {
303
- hnsw_stats.ndis += ndis;
304
- }
305
- }
306
- };
307
-
308
- struct BuildDistanceComputer {
309
- using T = DistanceComputer*;
310
- template <class HammingComputer>
311
- DistanceComputer* f(IndexBinaryFlat* flat_storage) {
312
- return new FlatHammingDis<HammingComputer>(*flat_storage);
313
- }
314
- };
315
-
316
- } // namespace
317
-
318
294
  DistanceComputer* IndexBinaryHNSW::get_distance_computer() const {
319
295
  IndexBinaryFlat* flat_storage = dynamic_cast<IndexBinaryFlat*>(storage);
320
- FAISS_ASSERT(flat_storage != nullptr);
321
- BuildDistanceComputer bd;
322
- return dispatch_HammingComputer(code_size, bd, flat_storage);
296
+ FAISS_THROW_IF_NOT_MSG(
297
+ flat_storage != nullptr,
298
+ "IndexBinaryHNSW requires IndexBinaryFlat storage");
299
+ return with_simd_level([&]<SIMDLevel SL>() {
300
+ return make_binary_hnsw_distance_computer_fixSL<SL>(
301
+ code_size, flat_storage);
302
+ });
323
303
  }
324
304
 
325
305
  /**************************************************************
@@ -330,8 +310,8 @@ IndexBinaryHNSWCagra::IndexBinaryHNSWCagra() : IndexBinaryHNSW() {
330
310
  storage = nullptr;
331
311
  }
332
312
 
333
- IndexBinaryHNSWCagra::IndexBinaryHNSWCagra(int d, int M)
334
- : IndexBinaryHNSW(d, M) {
313
+ IndexBinaryHNSWCagra::IndexBinaryHNSWCagra(int d_, int M)
314
+ : IndexBinaryHNSW(d_, M) {
335
315
  init_level0 = true;
336
316
  keep_max_size_level0 = true;
337
317
  }
@@ -354,6 +334,13 @@ void IndexBinaryHNSWCagra::search(
354
334
  if (!base_level_only) {
355
335
  IndexBinaryHNSW::search(n, x, k, distances, labels, params);
356
336
  } else {
337
+ FAISS_THROW_IF_NOT_MSG(
338
+ ntotal > 0, "IndexBinaryHNSWCagra: cannot search empty index");
339
+ FAISS_THROW_IF_NOT_MSG(
340
+ num_base_level_search_entrypoints > 0,
341
+ "IndexBinaryHNSWCagra: "
342
+ "num_base_level_search_entrypoints must be > 0");
343
+
357
344
  float* distances_f = (float*)distances;
358
345
 
359
346
  using RH = HeapBlockResultHandler<HNSW::C>;
@@ -379,7 +366,7 @@ void IndexBinaryHNSWCagra::search(
379
366
  float distance = (*dis)(idx);
380
367
 
381
368
  if (distance < nearest_d[i]) {
382
- nearest[i] = idx;
369
+ nearest[i] = static_cast<storage_idx_t>(idx);
383
370
  nearest_d[i] = distance;
384
371
  }
385
372
  }
@@ -389,7 +376,7 @@ void IndexBinaryHNSWCagra::search(
389
376
 
390
377
  #pragma omp parallel
391
378
  {
392
- VisitedTable vt(ntotal);
379
+ std::unique_ptr<VisitedTable> vt = VisitedTable::create(ntotal);
393
380
  std::unique_ptr<DistanceComputer> dis(get_distance_computer());
394
381
  HNSWStats search_stats;
395
382
  RH::SingleResultHandler res(bres);
@@ -407,15 +394,19 @@ void IndexBinaryHNSWCagra::search(
407
394
  &nearest_d[i],
408
395
  1, // search_type
409
396
  search_stats,
410
- vt,
397
+ *vt,
411
398
  params);
412
399
 
413
400
  res.end();
414
401
  }
402
+ #pragma omp critical
403
+ {
404
+ hnsw_stats.combine(search_stats);
405
+ }
415
406
  }
416
407
 
417
408
  #pragma omp parallel for
418
- for (int i = 0; i < n * k; ++i) {
409
+ for (idx_t i = 0; i < n * k; ++i) {
419
410
  distances[i] = std::round(distances_f[i]);
420
411
  }
421
412
  }
@@ -11,6 +11,7 @@
11
11
 
12
12
  #include <faiss/IndexBinaryFlat.h>
13
13
  #include <faiss/impl/HNSW.h>
14
+ #include <faiss/impl/hnsw/LockVector.h>
14
15
  #include <faiss/utils/utils.h>
15
16
 
16
17
  namespace faiss {
@@ -19,14 +20,14 @@ namespace faiss {
19
20
  * link structure built on top */
20
21
 
21
22
  struct IndexBinaryHNSW : IndexBinary {
22
- typedef HNSW::storage_idx_t storage_idx_t;
23
+ using storage_idx_t = HNSW::storage_idx_t;
23
24
 
24
25
  // the link structure
25
26
  HNSW hnsw;
26
27
 
27
28
  // the sequential storage
28
- bool own_fields;
29
- IndexBinary* storage;
29
+ bool own_fields = false;
30
+ IndexBinary* storage = nullptr;
30
31
 
31
32
  // When set to false, level 0 in the knn graph is not initialized.
32
33
  // This option is used by GpuIndexBinaryCagra::copyTo(IndexBinaryHNSW*)
@@ -40,6 +41,11 @@ struct IndexBinaryHNSW : IndexBinary {
40
41
  // used when GpuIndexBinaryCagra::copyFrom(IndexBinaryHNSW*) is called.
41
42
  bool keep_max_size_level0 = false;
42
43
 
44
+ // Per-node locks for HNSW graph construction.
45
+ LockVector locks;
46
+ // locks are freed after each call to add() unless this flag is set.
47
+ bool retain_locks = false;
48
+
43
49
  explicit IndexBinaryHNSW();
44
50
  explicit IndexBinaryHNSW(int d, int M = 32);
45
51
  explicit IndexBinaryHNSW(IndexBinary* storage, int M = 32);