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
@@ -22,12 +22,23 @@
22
22
  #include <faiss/impl/DistanceComputer.h>
23
23
  #include <faiss/impl/FaissAssert.h>
24
24
  #include <faiss/impl/ResultHandler.h>
25
+ #include <faiss/impl/VisitedTable.h>
25
26
  #include <faiss/utils/Heap.h>
26
27
  #include <faiss/utils/hamming.h>
27
28
  #include <faiss/utils/random.h>
28
29
 
30
+ #include <faiss/impl/simd_dispatch.h>
31
+
29
32
  #include <random>
30
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
+ #include <faiss/utils/hamming_distance/hamming_computer-generic.h>
40
+ #undef THE_SIMD_LEVEL
41
+
31
42
  namespace faiss {
32
43
 
33
44
  /**************************************************************
@@ -60,10 +71,8 @@ void hnsw_add_vertices(
60
71
  printf(" max_level = %d\n", max_level);
61
72
  }
62
73
 
63
- std::vector<omp_lock_t> locks(ntotal);
64
- for (int i = 0; i < ntotal; i++) {
65
- omp_init_lock(&locks[i]);
66
- }
74
+ auto& locks = index_hnsw.locks;
75
+ locks.prepare(ntotal);
67
76
 
68
77
  // add vectors from highest to lowest level
69
78
  std::vector<int> hist;
@@ -72,10 +81,11 @@ void hnsw_add_vertices(
72
81
  { // make buckets with vectors of the same level
73
82
 
74
83
  // build histogram
75
- for (int i = 0; i < n; i++) {
76
- HNSW::storage_idx_t pt_id = i + n0;
84
+ for (size_t i = 0; i < n; i++) {
85
+ HNSW::storage_idx_t pt_id =
86
+ static_cast<HNSW::storage_idx_t>(i + n0);
77
87
  int pt_level = hnsw.levels[pt_id] - 1;
78
- while (pt_level >= hist.size()) {
88
+ while (pt_level >= static_cast<int>(hist.size())) {
79
89
  hist.push_back(0);
80
90
  }
81
91
  hist[pt_level]++;
@@ -83,13 +93,14 @@ void hnsw_add_vertices(
83
93
 
84
94
  // accumulate
85
95
  std::vector<int> offsets(hist.size() + 1, 0);
86
- for (int i = 0; i < hist.size() - 1; i++) {
96
+ for (size_t i = 0; i < hist.size() - 1; i++) {
87
97
  offsets[i + 1] = offsets[i] + hist[i];
88
98
  }
89
99
 
90
100
  // bucket sort
91
- for (int i = 0; i < n; i++) {
92
- HNSW::storage_idx_t pt_id = i + n0;
101
+ for (size_t i = 0; i < n; i++) {
102
+ HNSW::storage_idx_t pt_id =
103
+ static_cast<HNSW::storage_idx_t>(i + n0);
93
104
  int pt_level = hnsw.levels[pt_id] - 1;
94
105
  order[offsets[pt_level]++] = pt_id;
95
106
  }
@@ -98,20 +109,22 @@ void hnsw_add_vertices(
98
109
  { // perform add
99
110
  RandomGenerator rng2(789);
100
111
 
101
- int i1 = n;
112
+ size_t i1 = static_cast<int>(n);
102
113
 
103
- for (int pt_level = hist.size() - 1;
114
+ for (int pt_level = static_cast<int>(hist.size()) - 1;
104
115
  pt_level >= int(!index_hnsw.init_level0);
105
116
  pt_level--) {
106
- int i0 = i1 - hist[pt_level];
117
+ size_t i0 = i1 - hist[pt_level];
107
118
 
108
119
  if (verbose) {
109
- printf("Adding %d elements at level %d\n", i1 - i0, pt_level);
120
+ printf("Adding %zu elements at level %d\n", i1 - i0, pt_level);
110
121
  }
111
122
 
112
123
  // random permutation to get rid of dataset order bias
113
- for (int j = i0; j < i1; j++) {
114
- std::swap(order[j], order[j + rng2.rand_int(i1 - j)]);
124
+ for (size_t j = i0; j < i1; j++) {
125
+ std::swap(
126
+ order[j],
127
+ order[j + rng2.rand_int(static_cast<int>(i1 - j))]);
115
128
  }
116
129
 
117
130
  #pragma omp parallel
@@ -120,11 +133,11 @@ void hnsw_add_vertices(
120
133
 
121
134
  std::unique_ptr<DistanceComputer> dis(
122
135
  index_hnsw.get_distance_computer());
123
- int prev_display =
124
- verbose && omp_get_thread_num() == 0 ? 0 : -1;
136
+ bool do_display = verbose && omp_get_thread_num() == 0;
137
+ size_t prev_display = 0;
125
138
 
126
139
  #pragma omp for schedule(dynamic)
127
- for (int i = i0; i < i1; i++) {
140
+ for (int64_t i = i0; i < i1; i++) {
128
141
  HNSW::storage_idx_t pt_id = order[i];
129
142
  dis->set_query(
130
143
  (float*)(x + (pt_id - n0) * index_hnsw.code_size));
@@ -137,9 +150,9 @@ void hnsw_add_vertices(
137
150
  vt,
138
151
  index_hnsw.keep_max_size_level0 && (pt_level == 0));
139
152
 
140
- if (prev_display >= 0 && i - i0 > prev_display + 10000) {
153
+ if (do_display && i - i0 > prev_display + 10000) {
141
154
  prev_display = i - i0;
142
- printf(" %d / %d\r", i - i0, i1 - i0);
155
+ printf(" %zu / %zu\r", i - i0, i1 - i0);
143
156
  fflush(stdout);
144
157
  }
145
158
  }
@@ -155,9 +168,8 @@ void hnsw_add_vertices(
155
168
  if (verbose) {
156
169
  printf("Done in %.3f ms\n", getmillisecs() - t0);
157
170
  }
158
-
159
- for (int i = 0; i < ntotal; i++) {
160
- omp_destroy_lock(&locks[i]);
171
+ if (!index_hnsw.retain_locks) {
172
+ locks.clear();
161
173
  }
162
174
  }
163
175
 
@@ -171,19 +183,19 @@ IndexBinaryHNSW::IndexBinaryHNSW() {
171
183
  is_trained = true;
172
184
  }
173
185
 
174
- IndexBinaryHNSW::IndexBinaryHNSW(int d, int M)
175
- : IndexBinary(d),
186
+ IndexBinaryHNSW::IndexBinaryHNSW(int d_, int M)
187
+ : IndexBinary(d_),
176
188
  hnsw(M),
177
189
  own_fields(true),
178
- storage(new IndexBinaryFlat(d)) {
190
+ storage(new IndexBinaryFlat(d_)) {
179
191
  is_trained = true;
180
192
  }
181
193
 
182
- IndexBinaryHNSW::IndexBinaryHNSW(IndexBinary* storage, int M)
183
- : IndexBinary(storage->d),
194
+ IndexBinaryHNSW::IndexBinaryHNSW(IndexBinary* storage_, int M)
195
+ : IndexBinary(storage_->d),
184
196
  hnsw(M),
185
197
  own_fields(false),
186
- storage(storage) {
198
+ storage(storage_) {
187
199
  is_trained = true;
188
200
  }
189
201
 
@@ -205,10 +217,14 @@ void IndexBinaryHNSW::search(
205
217
  idx_t k,
206
218
  int32_t* distances,
207
219
  idx_t* labels,
208
- const SearchParameters* params) const {
209
- FAISS_THROW_IF_NOT_MSG(
210
- !params, "search params not supported for this index");
220
+ const SearchParameters* params_in) const {
211
221
  FAISS_THROW_IF_NOT(k > 0);
222
+ const SearchParametersHNSW* params = nullptr;
223
+ if (params_in) {
224
+ params = dynamic_cast<const SearchParametersHNSW*>(params_in);
225
+ FAISS_THROW_IF_NOT_MSG(
226
+ params, "IndexBinaryHNSW params have incorrect type");
227
+ }
212
228
 
213
229
  // we use the buffer for distances as float but convert them back
214
230
  // to int in the end
@@ -217,42 +233,57 @@ void IndexBinaryHNSW::search(
217
233
  using RH = HeapBlockResultHandler<HNSW::C>;
218
234
  RH bres(n, distances_f, labels, k);
219
235
 
236
+ size_t n1 = 0, n2 = 0, ndis = 0, nhops = 0;
237
+
220
238
  #pragma omp parallel
221
239
  {
222
240
  VisitedTable vt(ntotal);
223
241
  std::unique_ptr<DistanceComputer> dis(get_distance_computer());
224
242
  RH::SingleResultHandler res(bres);
225
243
 
226
- #pragma omp for
244
+ #pragma omp for reduction(+ : n1, n2, ndis, nhops)
227
245
  for (idx_t i = 0; i < n; i++) {
228
246
  res.begin(i);
229
247
  dis->set_query((float*)(x + i * code_size));
230
248
  // Given that IndexBinaryHNSW is not an IndexHNSW, we pass nullptr
231
249
  // as the index parameter. This state does not get used in the
232
- // search function, as it is merely there to to enable Panorama
250
+ // search function, as it is merely there to enable Panorama
233
251
  // execution for IndexHNSWFlatPanorama.
234
- hnsw.search(*dis, nullptr, res, vt);
252
+ HNSWStats stats = hnsw.search(*dis, nullptr, res, vt, params_in);
253
+ n1 += stats.n1;
254
+ n2 += stats.n2;
255
+ ndis += stats.ndis;
256
+ nhops += stats.nhops;
235
257
  res.end();
236
258
  }
237
259
  }
238
260
 
261
+ hnsw_stats.combine({n1, n2, ndis, nhops});
262
+
239
263
  #pragma omp parallel for
240
- for (int i = 0; i < n * k; ++i) {
264
+ for (idx_t i = 0; i < n * k; ++i) {
241
265
  distances[i] = std::round(distances_f[i]);
242
266
  }
243
267
  }
244
268
 
245
269
  void IndexBinaryHNSW::add(idx_t n, const uint8_t* x) {
246
270
  FAISS_THROW_IF_NOT(is_trained);
247
- int n0 = ntotal;
271
+ size_t n0 = ntotal;
248
272
  storage->add(n, x);
249
273
  ntotal = storage->ntotal;
250
274
 
251
- hnsw_add_vertices(*this, n0, n, x, verbose, hnsw.levels.size() == ntotal);
275
+ hnsw_add_vertices(
276
+ *this,
277
+ n0,
278
+ n,
279
+ x,
280
+ verbose,
281
+ hnsw.levels.size() == static_cast<size_t>(ntotal));
252
282
  }
253
283
 
254
284
  void IndexBinaryHNSW::reset() {
255
285
  hnsw.reset();
286
+ locks.clear();
256
287
  storage->reset();
257
288
  ntotal = 0;
258
289
  }
@@ -261,60 +292,15 @@ void IndexBinaryHNSW::reconstruct(idx_t key, uint8_t* recons) const {
261
292
  storage->reconstruct(key, recons);
262
293
  }
263
294
 
264
- namespace {
265
-
266
- template <class HammingComputer>
267
- struct FlatHammingDis : DistanceComputer {
268
- const int code_size;
269
- const uint8_t* b;
270
- size_t ndis;
271
- HammingComputer hc;
272
-
273
- float operator()(idx_t i) override {
274
- ndis++;
275
- return hc.hamming(b + i * code_size);
276
- }
277
-
278
- float symmetric_dis(idx_t i, idx_t j) override {
279
- return HammingComputerDefault(b + j * code_size, code_size)
280
- .hamming(b + i * code_size);
281
- }
282
-
283
- explicit FlatHammingDis(const IndexBinaryFlat& storage)
284
- : code_size(storage.code_size),
285
- b(storage.xb.data()),
286
- ndis(0),
287
- hc() {}
288
-
289
- // NOTE: Pointers are cast from float in order to reuse the floating-point
290
- // DistanceComputer.
291
- void set_query(const float* x) override {
292
- hc.set((uint8_t*)x, code_size);
293
- }
294
-
295
- ~FlatHammingDis() override {
296
- #pragma omp critical
297
- {
298
- hnsw_stats.ndis += ndis;
299
- }
300
- }
301
- };
302
-
303
- struct BuildDistanceComputer {
304
- using T = DistanceComputer*;
305
- template <class HammingComputer>
306
- DistanceComputer* f(IndexBinaryFlat* flat_storage) {
307
- return new FlatHammingDis<HammingComputer>(*flat_storage);
308
- }
309
- };
310
-
311
- } // namespace
312
-
313
295
  DistanceComputer* IndexBinaryHNSW::get_distance_computer() const {
314
296
  IndexBinaryFlat* flat_storage = dynamic_cast<IndexBinaryFlat*>(storage);
315
- FAISS_ASSERT(flat_storage != nullptr);
316
- BuildDistanceComputer bd;
317
- return dispatch_HammingComputer(code_size, bd, flat_storage);
297
+ FAISS_THROW_IF_NOT_MSG(
298
+ flat_storage != nullptr,
299
+ "IndexBinaryHNSW requires IndexBinaryFlat storage");
300
+ return with_simd_level([&]<SIMDLevel SL>() {
301
+ return make_binary_hnsw_distance_computer_fixSL<SL>(
302
+ code_size, flat_storage);
303
+ });
318
304
  }
319
305
 
320
306
  /**************************************************************
@@ -325,8 +311,8 @@ IndexBinaryHNSWCagra::IndexBinaryHNSWCagra() : IndexBinaryHNSW() {
325
311
  storage = nullptr;
326
312
  }
327
313
 
328
- IndexBinaryHNSWCagra::IndexBinaryHNSWCagra(int d, int M)
329
- : IndexBinaryHNSW(d, M) {
314
+ IndexBinaryHNSWCagra::IndexBinaryHNSWCagra(int d_, int M)
315
+ : IndexBinaryHNSW(d_, M) {
330
316
  init_level0 = true;
331
317
  keep_max_size_level0 = true;
332
318
  }
@@ -349,6 +335,13 @@ void IndexBinaryHNSWCagra::search(
349
335
  if (!base_level_only) {
350
336
  IndexBinaryHNSW::search(n, x, k, distances, labels, params);
351
337
  } else {
338
+ FAISS_THROW_IF_NOT_MSG(
339
+ ntotal > 0, "IndexBinaryHNSWCagra: cannot search empty index");
340
+ FAISS_THROW_IF_NOT_MSG(
341
+ num_base_level_search_entrypoints > 0,
342
+ "IndexBinaryHNSWCagra: "
343
+ "num_base_level_search_entrypoints must be > 0");
344
+
352
345
  float* distances_f = (float*)distances;
353
346
 
354
347
  using RH = HeapBlockResultHandler<HNSW::C>;
@@ -374,7 +367,7 @@ void IndexBinaryHNSWCagra::search(
374
367
  float distance = (*dis)(idx);
375
368
 
376
369
  if (distance < nearest_d[i]) {
377
- nearest[i] = idx;
370
+ nearest[i] = static_cast<storage_idx_t>(idx);
378
371
  nearest_d[i] = distance;
379
372
  }
380
373
  }
@@ -407,10 +400,14 @@ void IndexBinaryHNSWCagra::search(
407
400
 
408
401
  res.end();
409
402
  }
403
+ #pragma omp critical
404
+ {
405
+ hnsw_stats.combine(search_stats);
406
+ }
410
407
  }
411
408
 
412
409
  #pragma omp parallel for
413
- for (int i = 0; i < n * k; ++i) {
410
+ for (idx_t i = 0; i < n * k; ++i) {
414
411
  distances[i] = std::round(distances_f[i]);
415
412
  }
416
413
  }
@@ -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);