faiss 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/ext/faiss/extconf.rb +2 -1
  4. data/ext/faiss/{index_rb.cpp → index.cpp} +1 -1
  5. data/ext/faiss/index_binary.cpp +1 -1
  6. data/ext/faiss/kmeans.cpp +1 -1
  7. data/ext/faiss/pca_matrix.cpp +1 -1
  8. data/ext/faiss/product_quantizer.cpp +1 -1
  9. data/ext/faiss/{utils_rb.cpp → utils.cpp} +1 -1
  10. data/lib/faiss/version.rb +1 -1
  11. data/vendor/faiss/faiss/AutoTune.cpp +93 -80
  12. data/vendor/faiss/faiss/Clustering.cpp +39 -240
  13. data/vendor/faiss/faiss/Clustering.h +6 -0
  14. data/vendor/faiss/faiss/IVFlib.cpp +41 -21
  15. data/vendor/faiss/faiss/Index.cpp +6 -5
  16. data/vendor/faiss/faiss/Index.h +5 -5
  17. data/vendor/faiss/faiss/Index2Layer.cpp +37 -53
  18. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +49 -37
  19. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +36 -34
  20. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +4 -1
  21. data/vendor/faiss/faiss/IndexBinary.cpp +5 -3
  22. data/vendor/faiss/faiss/IndexBinary.h +4 -4
  23. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +1 -1
  24. data/vendor/faiss/faiss/IndexBinaryFlat.h +1 -1
  25. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -4
  26. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +84 -92
  27. data/vendor/faiss/faiss/IndexBinaryHNSW.h +9 -3
  28. data/vendor/faiss/faiss/IndexBinaryHash.cpp +45 -236
  29. data/vendor/faiss/faiss/IndexBinaryHash.h +6 -6
  30. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +87 -415
  31. data/vendor/faiss/faiss/IndexFastScan.cpp +72 -109
  32. data/vendor/faiss/faiss/IndexFastScan.h +25 -23
  33. data/vendor/faiss/faiss/IndexFlat.cpp +27 -20
  34. data/vendor/faiss/faiss/IndexFlat.h +21 -18
  35. data/vendor/faiss/faiss/IndexFlatCodes.cpp +42 -19
  36. data/vendor/faiss/faiss/IndexHNSW.cpp +283 -145
  37. data/vendor/faiss/faiss/IndexHNSW.h +16 -2
  38. data/vendor/faiss/faiss/IndexIDMap.cpp +25 -21
  39. data/vendor/faiss/faiss/IndexIDMap.h +9 -7
  40. data/vendor/faiss/faiss/IndexIVF.cpp +465 -362
  41. data/vendor/faiss/faiss/IndexIVF.h +33 -12
  42. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +77 -74
  43. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +96 -93
  44. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +4 -1
  45. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +357 -238
  46. data/vendor/faiss/faiss/IndexIVFFastScan.h +42 -41
  47. data/vendor/faiss/faiss/IndexIVFFlat.cpp +36 -68
  48. data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
  49. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +53 -30
  50. data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
  51. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
  52. data/vendor/faiss/faiss/IndexIVFPQ.cpp +71 -843
  53. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +151 -121
  54. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
  55. data/vendor/faiss/faiss/IndexIVFPQR.cpp +21 -17
  56. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +26 -39
  57. data/vendor/faiss/faiss/IndexIVFRaBitQ.h +2 -1
  58. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +475 -476
  59. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +248 -93
  60. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +41 -127
  61. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
  62. data/vendor/faiss/faiss/IndexLSH.cpp +36 -19
  63. data/vendor/faiss/faiss/IndexLattice.cpp +13 -13
  64. data/vendor/faiss/faiss/IndexNNDescent.cpp +36 -21
  65. data/vendor/faiss/faiss/IndexNNDescent.h +2 -2
  66. data/vendor/faiss/faiss/IndexNSG.cpp +39 -23
  67. data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +31 -11
  68. data/vendor/faiss/faiss/IndexPQ.cpp +128 -221
  69. data/vendor/faiss/faiss/IndexPQ.h +3 -2
  70. data/vendor/faiss/faiss/IndexPQFastScan.cpp +20 -14
  71. data/vendor/faiss/faiss/IndexPQFastScan.h +3 -0
  72. data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -18
  73. data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
  74. data/vendor/faiss/faiss/IndexRaBitQ.cpp +11 -36
  75. data/vendor/faiss/faiss/IndexRaBitQ.h +2 -1
  76. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +41 -277
  77. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +183 -27
  78. data/vendor/faiss/faiss/IndexRefine.cpp +30 -25
  79. data/vendor/faiss/faiss/IndexRefine.h +4 -4
  80. data/vendor/faiss/faiss/IndexReplicas.cpp +6 -6
  81. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +15 -14
  82. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +1 -1
  83. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +82 -14
  84. data/vendor/faiss/faiss/IndexShards.cpp +10 -9
  85. data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
  86. data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
  87. data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
  88. data/vendor/faiss/faiss/MetaIndexes.h +1 -1
  89. data/vendor/faiss/faiss/MetricType.h +14 -7
  90. data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
  91. data/vendor/faiss/faiss/SuperKMeans.h +97 -0
  92. data/vendor/faiss/faiss/VectorTransform.cpp +237 -149
  93. data/vendor/faiss/faiss/VectorTransform.h +16 -16
  94. data/vendor/faiss/faiss/build.cpp +23 -0
  95. data/vendor/faiss/faiss/build.h +15 -0
  96. data/vendor/faiss/faiss/clone_index.cpp +48 -47
  97. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
  98. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
  99. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
  100. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
  101. data/vendor/faiss/faiss/factory_tools.cpp +5 -0
  102. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
  103. data/vendor/faiss/faiss/gpu/GpuResources.h +1 -1
  104. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +9 -9
  105. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +4 -3
  106. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
  107. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
  108. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
  109. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
  110. data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
  111. data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
  112. data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
  113. data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
  114. data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
  115. data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
  116. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +51 -0
  117. data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
  118. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +66 -0
  119. data/vendor/faiss/faiss/gpu_metal/MetalResources.h +79 -0
  120. data/vendor/faiss/faiss/gpu_metal/StandardMetalResources.h +35 -0
  121. data/vendor/faiss/faiss/impl/AdSampling.cpp +103 -0
  122. data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
  123. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +29 -25
  124. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
  125. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
  126. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -0
  127. data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
  128. data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
  129. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +16 -16
  130. data/vendor/faiss/faiss/impl/CodePacker.cpp +3 -3
  131. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +1 -1
  132. data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
  133. data/vendor/faiss/faiss/impl/FaissAssert.h +6 -3
  134. data/vendor/faiss/faiss/impl/FaissException.h +50 -3
  135. data/vendor/faiss/faiss/impl/HNSW.cpp +92 -317
  136. data/vendor/faiss/faiss/impl/HNSW.h +13 -34
  137. data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
  138. data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
  139. data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
  140. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +82 -77
  141. data/vendor/faiss/faiss/impl/NNDescent.cpp +62 -25
  142. data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
  143. data/vendor/faiss/faiss/impl/NSG.cpp +38 -21
  144. data/vendor/faiss/faiss/impl/NSG.h +4 -4
  145. data/vendor/faiss/faiss/impl/Panorama.cpp +23 -6
  146. data/vendor/faiss/faiss/impl/Panorama.h +258 -87
  147. data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
  148. data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
  149. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +46 -32
  150. data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
  151. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
  152. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
  153. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +30 -23
  154. data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
  155. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +55 -49
  156. data/vendor/faiss/faiss/impl/RaBitQUtils.h +65 -0
  157. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +296 -283
  158. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +26 -23
  159. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
  160. data/vendor/faiss/faiss/impl/ResultHandler.h +99 -75
  161. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +52 -4
  162. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +27 -1
  163. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
  164. data/vendor/faiss/faiss/impl/VisitedTable.h +7 -0
  165. data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
  166. data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
  167. data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
  168. data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
  169. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
  170. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
  171. data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
  172. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
  173. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
  174. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
  175. data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
  176. data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
  177. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
  178. data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
  179. data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
  180. data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
  181. data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
  182. data/vendor/faiss/faiss/impl/expanded_scanners.h +8 -3
  183. data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
  184. data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
  185. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
  186. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
  187. data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
  188. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +268 -0
  189. data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +169 -2
  190. data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
  191. data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
  192. data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
  193. data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
  194. data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
  195. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
  196. data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -356
  197. data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
  198. data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
  199. data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +282 -134
  200. data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
  201. data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
  202. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +91 -0
  203. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -0
  204. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +104 -0
  205. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +111 -0
  206. data/vendor/faiss/faiss/impl/index_read.cpp +1132 -45
  207. data/vendor/faiss/faiss/impl/index_read_utils.h +1 -1
  208. data/vendor/faiss/faiss/impl/index_write.cpp +95 -13
  209. data/vendor/faiss/faiss/impl/io.cpp +6 -6
  210. data/vendor/faiss/faiss/impl/io_macros.h +33 -16
  211. data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
  212. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +37 -23
  213. data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
  214. data/vendor/faiss/faiss/impl/mapped_io.cpp +6 -6
  215. data/vendor/faiss/faiss/impl/platform_macros.h +11 -4
  216. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
  217. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
  218. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
  219. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
  220. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +21 -0
  221. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +21 -0
  222. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +21 -0
  223. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx2.cpp → pq_code_distance-avx2.h} +9 -13
  224. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx512.cpp → pq_code_distance-avx512.h} +9 -57
  225. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +29 -111
  226. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
  227. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +238 -5
  228. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +5 -7
  229. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +68 -0
  230. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +311 -477
  231. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
  232. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +1 -1
  233. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +3 -2
  234. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +102 -11
  235. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +27 -1
  236. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +3 -3
  237. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +148 -0
  238. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +167 -0
  239. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +59 -0
  240. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +163 -0
  241. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +311 -0
  242. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +192 -8
  243. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +12 -0
  244. data/vendor/faiss/faiss/impl/simd_dispatch.h +100 -66
  245. data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
  246. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +264 -172
  247. data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
  248. data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
  249. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
  250. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +270 -218
  251. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
  252. data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
  253. data/vendor/faiss/faiss/impl/svs_io.h +8 -2
  254. data/vendor/faiss/faiss/index_factory.cpp +86 -18
  255. data/vendor/faiss/faiss/index_io.h +24 -0
  256. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +66 -16
  257. data/vendor/faiss/faiss/invlists/DirectMap.cpp +24 -14
  258. data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
  259. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +157 -73
  260. data/vendor/faiss/faiss/invlists/InvertedLists.h +86 -23
  261. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
  262. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +13 -13
  263. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  264. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +1 -1
  265. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
  266. data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
  267. data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
  268. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
  269. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
  270. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
  271. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
  272. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +25 -1
  273. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +18 -2
  274. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +1 -1
  275. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +12 -3
  276. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +7 -2
  277. data/vendor/faiss/faiss/utils/Heap.cpp +10 -10
  278. data/vendor/faiss/faiss/utils/NeuralNet.cpp +47 -36
  279. data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
  280. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
  281. data/vendor/faiss/faiss/utils/distances.cpp +390 -560
  282. data/vendor/faiss/faiss/utils/distances.h +20 -1
  283. data/vendor/faiss/faiss/utils/distances_dispatch.h +117 -37
  284. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
  285. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
  286. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
  287. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
  288. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
  289. data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
  290. data/vendor/faiss/faiss/utils/distances_simd.cpp +5 -177
  291. data/vendor/faiss/faiss/utils/extra_distances.cpp +9 -8
  292. data/vendor/faiss/faiss/utils/extra_distances.h +32 -6
  293. data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
  294. data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
  295. data/vendor/faiss/faiss/utils/hamming.h +92 -2
  296. data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
  297. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +15 -0
  298. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
  299. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
  300. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +234 -0
  301. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-generic.h +368 -0
  302. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +322 -0
  303. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-rvv.h +39 -0
  304. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer.h +146 -0
  305. data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +481 -0
  306. data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +15 -0
  307. data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +15 -0
  308. data/vendor/faiss/faiss/utils/partitioning.cpp +66 -987
  309. data/vendor/faiss/faiss/utils/partitioning.h +31 -0
  310. data/vendor/faiss/faiss/utils/popcount.h +29 -0
  311. data/vendor/faiss/faiss/utils/pq_code_distance.h +2 -2
  312. data/vendor/faiss/faiss/utils/prefetch.h +2 -2
  313. data/vendor/faiss/faiss/utils/quantize_lut.cpp +30 -30
  314. data/vendor/faiss/faiss/utils/quantize_lut.h +1 -1
  315. data/vendor/faiss/faiss/utils/rabitq_simd.h +57 -536
  316. data/vendor/faiss/faiss/utils/random.cpp +6 -6
  317. data/vendor/faiss/faiss/utils/simd_impl/IVFFlatScanner-inl.h +51 -0
  318. data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +5 -1
  319. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +213 -4
  320. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +163 -10
  321. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +250 -4
  322. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +7 -4
  323. data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +189 -0
  324. data/vendor/faiss/faiss/utils/simd_impl/distances_simdlib256.h +195 -0
  325. data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +2 -1
  326. data/vendor/faiss/faiss/utils/{distances_fused/simdlib_based.h → simd_impl/exhaustive_L2sqr_blas_cmax.h} +5 -10
  327. data/vendor/faiss/faiss/utils/simd_impl/hamming_impl.h +481 -0
  328. data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +14 -0
  329. data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +14 -0
  330. data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +1085 -0
  331. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +355 -0
  332. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +477 -0
  333. data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +55 -0
  334. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
  335. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
  336. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
  337. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
  338. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
  339. data/vendor/faiss/faiss/utils/simd_levels.cpp +17 -5
  340. data/vendor/faiss/faiss/utils/simd_levels.h +93 -1
  341. data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
  342. data/vendor/faiss/faiss/utils/utils.cpp +5 -5
  343. data/vendor/faiss/faiss/utils/utils.h +3 -3
  344. metadata +119 -34
  345. data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
  346. data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
  347. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -224
  348. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -230
  349. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
  350. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
  351. data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
  352. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
  353. data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -235
  354. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
  355. data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
  356. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -449
  357. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
  358. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
  359. data/vendor/faiss/faiss/utils/simdlib.h +0 -42
  360. data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -365
  361. /data/ext/faiss/{utils_rb.h → utils.h} +0 -0
@@ -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,18 @@
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
+ #include <faiss/utils/hamming_distance/hamming_computer-generic.h>
40
+ #undef THE_SIMD_LEVEL
41
+
32
42
  namespace faiss {
33
43
 
34
44
  /**************************************************************
@@ -61,10 +71,8 @@ void hnsw_add_vertices(
61
71
  printf(" max_level = %d\n", max_level);
62
72
  }
63
73
 
64
- std::vector<omp_lock_t> locks(ntotal);
65
- for (int i = 0; i < ntotal; i++) {
66
- omp_init_lock(&locks[i]);
67
- }
74
+ auto& locks = index_hnsw.locks;
75
+ locks.prepare(ntotal);
68
76
 
69
77
  // add vectors from highest to lowest level
70
78
  std::vector<int> hist;
@@ -73,10 +81,11 @@ void hnsw_add_vertices(
73
81
  { // make buckets with vectors of the same level
74
82
 
75
83
  // build histogram
76
- for (int i = 0; i < n; i++) {
77
- 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);
78
87
  int pt_level = hnsw.levels[pt_id] - 1;
79
- while (pt_level >= hist.size()) {
88
+ while (pt_level >= static_cast<int>(hist.size())) {
80
89
  hist.push_back(0);
81
90
  }
82
91
  hist[pt_level]++;
@@ -84,13 +93,14 @@ void hnsw_add_vertices(
84
93
 
85
94
  // accumulate
86
95
  std::vector<int> offsets(hist.size() + 1, 0);
87
- for (int i = 0; i < hist.size() - 1; i++) {
96
+ for (size_t i = 0; i < hist.size() - 1; i++) {
88
97
  offsets[i + 1] = offsets[i] + hist[i];
89
98
  }
90
99
 
91
100
  // bucket sort
92
- for (int i = 0; i < n; i++) {
93
- 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);
94
104
  int pt_level = hnsw.levels[pt_id] - 1;
95
105
  order[offsets[pt_level]++] = pt_id;
96
106
  }
@@ -99,20 +109,22 @@ void hnsw_add_vertices(
99
109
  { // perform add
100
110
  RandomGenerator rng2(789);
101
111
 
102
- int i1 = n;
112
+ size_t i1 = static_cast<int>(n);
103
113
 
104
- for (int pt_level = hist.size() - 1;
114
+ for (int pt_level = static_cast<int>(hist.size()) - 1;
105
115
  pt_level >= int(!index_hnsw.init_level0);
106
116
  pt_level--) {
107
- int i0 = i1 - hist[pt_level];
117
+ size_t i0 = i1 - hist[pt_level];
108
118
 
109
119
  if (verbose) {
110
- 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);
111
121
  }
112
122
 
113
123
  // 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)]);
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))]);
116
128
  }
117
129
 
118
130
  #pragma omp parallel
@@ -121,11 +133,11 @@ void hnsw_add_vertices(
121
133
 
122
134
  std::unique_ptr<DistanceComputer> dis(
123
135
  index_hnsw.get_distance_computer());
124
- int prev_display =
125
- verbose && omp_get_thread_num() == 0 ? 0 : -1;
136
+ bool do_display = verbose && omp_get_thread_num() == 0;
137
+ size_t prev_display = 0;
126
138
 
127
139
  #pragma omp for schedule(dynamic)
128
- for (int i = i0; i < i1; i++) {
140
+ for (int64_t i = i0; i < i1; i++) {
129
141
  HNSW::storage_idx_t pt_id = order[i];
130
142
  dis->set_query(
131
143
  (float*)(x + (pt_id - n0) * index_hnsw.code_size));
@@ -138,9 +150,9 @@ void hnsw_add_vertices(
138
150
  vt,
139
151
  index_hnsw.keep_max_size_level0 && (pt_level == 0));
140
152
 
141
- if (prev_display >= 0 && i - i0 > prev_display + 10000) {
153
+ if (do_display && i - i0 > prev_display + 10000) {
142
154
  prev_display = i - i0;
143
- printf(" %d / %d\r", i - i0, i1 - i0);
155
+ printf(" %zu / %zu\r", i - i0, i1 - i0);
144
156
  fflush(stdout);
145
157
  }
146
158
  }
@@ -156,9 +168,8 @@ void hnsw_add_vertices(
156
168
  if (verbose) {
157
169
  printf("Done in %.3f ms\n", getmillisecs() - t0);
158
170
  }
159
-
160
- for (int i = 0; i < ntotal; i++) {
161
- omp_destroy_lock(&locks[i]);
171
+ if (!index_hnsw.retain_locks) {
172
+ locks.clear();
162
173
  }
163
174
  }
164
175
 
@@ -172,19 +183,19 @@ IndexBinaryHNSW::IndexBinaryHNSW() {
172
183
  is_trained = true;
173
184
  }
174
185
 
175
- IndexBinaryHNSW::IndexBinaryHNSW(int d, int M)
176
- : IndexBinary(d),
186
+ IndexBinaryHNSW::IndexBinaryHNSW(int d_, int M)
187
+ : IndexBinary(d_),
177
188
  hnsw(M),
178
189
  own_fields(true),
179
- storage(new IndexBinaryFlat(d)) {
190
+ storage(new IndexBinaryFlat(d_)) {
180
191
  is_trained = true;
181
192
  }
182
193
 
183
- IndexBinaryHNSW::IndexBinaryHNSW(IndexBinary* storage, int M)
184
- : IndexBinary(storage->d),
194
+ IndexBinaryHNSW::IndexBinaryHNSW(IndexBinary* storage_, int M)
195
+ : IndexBinary(storage_->d),
185
196
  hnsw(M),
186
197
  own_fields(false),
187
- storage(storage) {
198
+ storage(storage_) {
188
199
  is_trained = true;
189
200
  }
190
201
 
@@ -222,42 +233,57 @@ void IndexBinaryHNSW::search(
222
233
  using RH = HeapBlockResultHandler<HNSW::C>;
223
234
  RH bres(n, distances_f, labels, k);
224
235
 
236
+ size_t n1 = 0, n2 = 0, ndis = 0, nhops = 0;
237
+
225
238
  #pragma omp parallel
226
239
  {
227
240
  VisitedTable vt(ntotal);
228
241
  std::unique_ptr<DistanceComputer> dis(get_distance_computer());
229
242
  RH::SingleResultHandler res(bres);
230
243
 
231
- #pragma omp for
244
+ #pragma omp for reduction(+ : n1, n2, ndis, nhops)
232
245
  for (idx_t i = 0; i < n; i++) {
233
246
  res.begin(i);
234
247
  dis->set_query((float*)(x + i * code_size));
235
248
  // Given that IndexBinaryHNSW is not an IndexHNSW, we pass nullptr
236
249
  // as the index parameter. This state does not get used in the
237
- // search function, as it is merely there to to enable Panorama
250
+ // search function, as it is merely there to enable Panorama
238
251
  // execution for IndexHNSWFlatPanorama.
239
- hnsw.search(*dis, nullptr, res, vt, params_in);
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;
240
257
  res.end();
241
258
  }
242
259
  }
243
260
 
261
+ hnsw_stats.combine({n1, n2, ndis, nhops});
262
+
244
263
  #pragma omp parallel for
245
- for (int i = 0; i < n * k; ++i) {
264
+ for (idx_t i = 0; i < n * k; ++i) {
246
265
  distances[i] = std::round(distances_f[i]);
247
266
  }
248
267
  }
249
268
 
250
269
  void IndexBinaryHNSW::add(idx_t n, const uint8_t* x) {
251
270
  FAISS_THROW_IF_NOT(is_trained);
252
- int n0 = ntotal;
271
+ size_t n0 = ntotal;
253
272
  storage->add(n, x);
254
273
  ntotal = storage->ntotal;
255
274
 
256
- 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));
257
282
  }
258
283
 
259
284
  void IndexBinaryHNSW::reset() {
260
285
  hnsw.reset();
286
+ locks.clear();
261
287
  storage->reset();
262
288
  ntotal = 0;
263
289
  }
@@ -266,60 +292,15 @@ void IndexBinaryHNSW::reconstruct(idx_t key, uint8_t* recons) const {
266
292
  storage->reconstruct(key, recons);
267
293
  }
268
294
 
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
295
  DistanceComputer* IndexBinaryHNSW::get_distance_computer() const {
319
296
  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);
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
+ });
323
304
  }
324
305
 
325
306
  /**************************************************************
@@ -330,8 +311,8 @@ IndexBinaryHNSWCagra::IndexBinaryHNSWCagra() : IndexBinaryHNSW() {
330
311
  storage = nullptr;
331
312
  }
332
313
 
333
- IndexBinaryHNSWCagra::IndexBinaryHNSWCagra(int d, int M)
334
- : IndexBinaryHNSW(d, M) {
314
+ IndexBinaryHNSWCagra::IndexBinaryHNSWCagra(int d_, int M)
315
+ : IndexBinaryHNSW(d_, M) {
335
316
  init_level0 = true;
336
317
  keep_max_size_level0 = true;
337
318
  }
@@ -354,6 +335,13 @@ void IndexBinaryHNSWCagra::search(
354
335
  if (!base_level_only) {
355
336
  IndexBinaryHNSW::search(n, x, k, distances, labels, params);
356
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
+
357
345
  float* distances_f = (float*)distances;
358
346
 
359
347
  using RH = HeapBlockResultHandler<HNSW::C>;
@@ -379,7 +367,7 @@ void IndexBinaryHNSWCagra::search(
379
367
  float distance = (*dis)(idx);
380
368
 
381
369
  if (distance < nearest_d[i]) {
382
- nearest[i] = idx;
370
+ nearest[i] = static_cast<storage_idx_t>(idx);
383
371
  nearest_d[i] = distance;
384
372
  }
385
373
  }
@@ -412,10 +400,14 @@ void IndexBinaryHNSWCagra::search(
412
400
 
413
401
  res.end();
414
402
  }
403
+ #pragma omp critical
404
+ {
405
+ hnsw_stats.combine(search_stats);
406
+ }
415
407
  }
416
408
 
417
409
  #pragma omp parallel for
418
- for (int i = 0; i < n * k; ++i) {
410
+ for (idx_t i = 0; i < n * k; ++i) {
419
411
  distances[i] = std::round(distances_f[i]);
420
412
  }
421
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);