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
@@ -23,7 +23,7 @@ namespace nndescent {
23
23
 
24
24
  void gen_random(std::mt19937& rng, int* addr, const int size, const int N);
25
25
 
26
- Nhood::Nhood(int l, int s, std::mt19937& rng, int N) {
26
+ Nhood::Nhood(int /* l */, int s, std::mt19937& rng, int N) {
27
27
  M = s;
28
28
  nn_new.resize(s * 2);
29
29
  gen_random(rng, nn_new.data(), (int)nn_new.size(), N);
@@ -31,25 +31,46 @@ Nhood::Nhood(int l, int s, std::mt19937& rng, int N) {
31
31
 
32
32
  /// Copy operator
33
33
  Nhood& Nhood::operator=(const Nhood& other) {
34
- M = other.M;
35
- std::copy(
36
- other.nn_new.begin(),
37
- other.nn_new.end(),
38
- std::back_inserter(nn_new));
39
- nn_new.reserve(other.nn_new.capacity());
40
- pool.reserve(other.pool.capacity());
34
+ if (this != &other) {
35
+ M = other.M;
36
+ nn_new = other.nn_new;
37
+ nn_old = other.nn_old;
38
+ rnn_new = other.rnn_new;
39
+ rnn_old = other.rnn_old;
40
+ pool = other.pool;
41
+ }
41
42
  return *this;
42
43
  }
43
44
 
44
45
  /// Copy constructor
45
- Nhood::Nhood(const Nhood& other) {
46
- M = other.M;
47
- std::copy(
48
- other.nn_new.begin(),
49
- other.nn_new.end(),
50
- std::back_inserter(nn_new));
51
- nn_new.reserve(other.nn_new.capacity());
52
- pool.reserve(other.pool.capacity());
46
+ Nhood::Nhood(const Nhood& other)
47
+ : pool(other.pool),
48
+ M(other.M),
49
+ nn_old(other.nn_old),
50
+ nn_new(other.nn_new),
51
+ rnn_old(other.rnn_old),
52
+ rnn_new(other.rnn_new) {}
53
+
54
+ /// Move constructor
55
+ Nhood::Nhood(Nhood&& other) noexcept
56
+ : pool(std::move(other.pool)),
57
+ M(other.M),
58
+ nn_old(std::move(other.nn_old)),
59
+ nn_new(std::move(other.nn_new)),
60
+ rnn_old(std::move(other.rnn_old)),
61
+ rnn_new(std::move(other.rnn_new)) {}
62
+
63
+ /// Move assignment operator
64
+ Nhood& Nhood::operator=(Nhood&& other) noexcept {
65
+ if (this != &other) {
66
+ M = other.M;
67
+ nn_new = std::move(other.nn_new);
68
+ nn_old = std::move(other.nn_old);
69
+ rnn_new = std::move(other.rnn_new);
70
+ rnn_old = std::move(other.rnn_old);
71
+ pool = std::move(other.pool);
72
+ }
73
+ return *this;
53
74
  }
54
75
 
55
76
  /// Insert a point into the candidate pool
@@ -58,7 +79,7 @@ void Nhood::insert(int id, float dist) {
58
79
  if (dist > pool.front().distance) {
59
80
  return;
60
81
  }
61
- for (int i = 0; i < pool.size(); i++) {
82
+ for (size_t i = 0; i < pool.size(); i++) {
62
83
  if (id == pool[i].id) {
63
84
  return;
64
85
  }
@@ -90,6 +111,22 @@ void Nhood::join(C callback) const {
90
111
  }
91
112
 
92
113
  void gen_random(std::mt19937& rng, int* addr, const int size, const int N) {
114
+ FAISS_THROW_IF_NOT_FMT(
115
+ size > 0 && size <= N,
116
+ "gen_random: size (%d) must be > 0 and <= N (%d)",
117
+ size,
118
+ N);
119
+ if (size == N) {
120
+ // Special case: return all indices in random order
121
+ for (int i = 0; i < size; ++i) {
122
+ addr[i] = i;
123
+ }
124
+ for (int i = size - 1; i > 0; --i) {
125
+ int j = rng() % (i + 1);
126
+ std::swap(addr[i], addr[j]);
127
+ }
128
+ return;
129
+ }
93
130
  for (int i = 0; i < size; ++i) {
94
131
  addr[i] = rng() % (N - size);
95
132
  }
@@ -153,7 +190,7 @@ using namespace nndescent;
153
190
 
154
191
  constexpr int NUM_EVAL_POINTS = 100;
155
192
 
156
- NNDescent::NNDescent(const int d, const int K) : K(K), d(d) {
193
+ NNDescent::NNDescent(const int d_in, const int K_in) : K(K_in), d(d_in) {
157
194
  L = K + 50;
158
195
  }
159
196
 
@@ -197,7 +234,7 @@ void NNDescent::update() {
197
234
  auto& nn = graph[n];
198
235
  std::sort(nn.pool.begin(), nn.pool.end());
199
236
 
200
- if (nn.pool.size() > L) {
237
+ if (nn.pool.size() > static_cast<size_t>(L)) {
201
238
  nn.pool.resize(L);
202
239
  }
203
240
  nn.pool.reserve(L); // keep the pool size be L
@@ -238,7 +275,7 @@ void NNDescent::update() {
238
275
  // the candidate pool of the other side
239
276
  if (nn.distance > other.pool.back().distance) {
240
277
  LockGuard guard(other.lock);
241
- if (other.rnn_new.size() < R) {
278
+ if (other.rnn_new.size() < static_cast<size_t>(R)) {
242
279
  other.rnn_new.push_back(n);
243
280
  } else {
244
281
  int pos = rng() % R;
@@ -254,7 +291,7 @@ void NNDescent::update() {
254
291
  // the candidate pool of the other side
255
292
  if (nn.distance > other.pool.back().distance) {
256
293
  LockGuard guard(other.lock);
257
- if (other.rnn_old.size() < R) {
294
+ if (other.rnn_old.size() < static_cast<size_t>(R)) {
258
295
  other.rnn_old.push_back(n);
259
296
  } else {
260
297
  int pos = rng() % R;
@@ -280,7 +317,7 @@ void NNDescent::update() {
280
317
 
281
318
  nn_new.insert(nn_new.end(), rnn_new.begin(), rnn_new.end());
282
319
  nn_old.insert(nn_old.end(), rnn_old.begin(), rnn_old.end());
283
- if (nn_old.size() > R * 2) {
320
+ if (nn_old.size() > static_cast<size_t>(R * 2)) {
284
321
  nn_old.resize(R * 2);
285
322
  nn_old.reserve(R * 2);
286
323
  }
@@ -294,7 +331,7 @@ void NNDescent::nndescent(DistanceComputer& qdis, bool verbose) {
294
331
  int num_eval_points = std::min(NUM_EVAL_POINTS, ntotal);
295
332
  std::vector<int> eval_points(num_eval_points);
296
333
  std::vector<std::vector<int>> acc_eval_set(num_eval_points);
297
- std::mt19937 rng(random_seed * 6577 + omp_get_thread_num());
334
+ std::mt19937 rng(random_seed * 6577);
298
335
  gen_random(rng, eval_points.data(), eval_points.size(), ntotal);
299
336
  generate_eval_set(qdis, eval_points, acc_eval_set, ntotal);
300
337
  for (int it = 0; it < iter; it++) {
@@ -315,7 +352,7 @@ void NNDescent::generate_eval_set(
315
352
  std::vector<std::vector<int>>& v,
316
353
  int N) {
317
354
  #pragma omp parallel for
318
- for (int i = 0; i < c.size(); i++) {
355
+ for (int i = 0; i < static_cast<int>(c.size()); i++) {
319
356
  std::vector<Neighbor> tmp;
320
357
  for (int j = 0; j < N; j++) {
321
358
  if (c[i] == j) {
@@ -488,7 +525,7 @@ void NNDescent::search(
488
525
  ++k;
489
526
  }
490
527
  }
491
- for (size_t i = 0; i < topk; i++) {
528
+ for (int i = 0; i < topk; i++) {
492
529
  indices[i] = retset[i].id;
493
530
  dists[i] = retset[i].distance;
494
531
  }
@@ -54,8 +54,8 @@ struct Neighbor {
54
54
  bool flag;
55
55
 
56
56
  Neighbor() = default;
57
- Neighbor(int id, float distance, bool f)
58
- : id(id), distance(distance), flag(f) {}
57
+ Neighbor(int id_in, float distance_in, bool f)
58
+ : id(id_in), distance(distance_in), flag(f) {}
59
59
 
60
60
  inline bool operator<(const Neighbor& other) const {
61
61
  return distance < other.distance;
@@ -80,6 +80,10 @@ struct Nhood {
80
80
 
81
81
  Nhood(const Nhood& other);
82
82
 
83
+ Nhood(Nhood&& other) noexcept;
84
+
85
+ Nhood& operator=(Nhood&& other) noexcept;
86
+
83
87
  void insert(int id, float dist);
84
88
 
85
89
  template <typename C>
@@ -8,6 +8,7 @@
8
8
  #include <faiss/impl/NSG.h>
9
9
 
10
10
  #include <algorithm>
11
+ #include <limits>
11
12
  #include <memory>
12
13
  #include <mutex>
13
14
  #include <stack>
@@ -42,8 +43,8 @@ struct Neighbor {
42
43
  bool flag;
43
44
 
44
45
  Neighbor() = default;
45
- Neighbor(int id, float distance, bool f)
46
- : id(id), distance(distance), flag(f) {}
46
+ Neighbor(int id_in, float distance_in, bool f)
47
+ : id(id_in), distance(distance_in), flag(f) {}
47
48
 
48
49
  inline bool operator<(const Neighbor& other) const {
49
50
  return distance < other.distance;
@@ -55,7 +56,7 @@ struct Node {
55
56
  float distance;
56
57
 
57
58
  Node() = default;
58
- Node(int id, float distance) : id(id), distance(distance) {}
59
+ Node(int id_in, float distance_in) : id(id_in), distance(distance_in) {}
59
60
 
60
61
  inline bool operator<(const Node& other) const {
61
62
  return distance < other.distance;
@@ -110,10 +111,9 @@ inline int insert_into_pool(Neighbor* addr, int K, Neighbor nn) {
110
111
 
111
112
  using namespace nsg;
112
113
 
113
- NSG::NSG(int R) : R(R), rng(0x0903) {
114
+ NSG::NSG(int R_in) : R(R_in), rng(0x0903) {
114
115
  L = R + 32;
115
116
  C = R + 100;
116
- srand(0x1998);
117
117
  }
118
118
 
119
119
  void NSG::search(
@@ -131,7 +131,7 @@ void NSG::search(
131
131
  search_on_graph<false>(
132
132
  *final_graph, dis, vt, enterpoint, pool_size, retset, tmp);
133
133
 
134
- for (size_t i = 0; i < k; i++) {
134
+ for (int i = 0; i < k; i++) {
135
135
  I[i] = retset[i].id;
136
136
  D[i] = retset[i].distance;
137
137
  }
@@ -179,7 +179,7 @@ void NSG::build(
179
179
  is_built = true;
180
180
 
181
181
  if (verbose) {
182
- int max = 0, min = 1e6;
182
+ int max = 0, min = std::numeric_limits<int>::max();
183
183
  double avg = 0;
184
184
 
185
185
  for (int i = 0; i < n; i++) {
@@ -234,10 +234,11 @@ void NSG::init_graph(Index* storage, const nsg::Graph<idx_t>& knn_graph) {
234
234
  std::unique_ptr<DistanceComputer> dis(storage_distance_computer(storage));
235
235
 
236
236
  dis->set_query(center.get());
237
- VisitedTable vt(ntotal, use_visited_hashset);
237
+ std::unique_ptr<VisitedTable> vt =
238
+ VisitedTable::create(ntotal, use_visited_hashset);
238
239
 
239
240
  // Do not collect the visited nodes
240
- search_on_graph<false>(knn_graph, *dis, vt, ep, L, retset, tmpset);
241
+ search_on_graph<false>(knn_graph, *dis, *vt, ep, L, retset, tmpset);
241
242
 
242
243
  // set enterpoint
243
244
  enterpoint = retset[0].id;
@@ -256,16 +257,18 @@ void NSG::search_on_graph(
256
257
  retset.resize(pool_size + 1);
257
258
  std::vector<int> init_ids(pool_size);
258
259
 
260
+ vt.reserve(pool_size);
261
+
259
262
  int num_ids = 0;
260
263
  std::vector<index_t> neighbors(graph.K);
261
264
  size_t nneigh = graph.get_neighbors(ep, neighbors.data());
262
- for (int i = 0; i < init_ids.size() && i < nneigh; i++) {
265
+ for (size_t i = 0; i < init_ids.size() && i < nneigh; i++) {
263
266
  int id = (int)neighbors[i];
264
267
  if (id >= ntotal) {
265
268
  continue;
266
269
  }
267
270
 
268
- init_ids[i] = id;
271
+ init_ids[num_ids] = id;
269
272
  vt.set(id);
270
273
  num_ids += 1;
271
274
  }
@@ -281,7 +284,7 @@ void NSG::search_on_graph(
281
284
  vt.set(id);
282
285
  }
283
286
 
284
- for (int i = 0; i < init_ids.size(); i++) {
287
+ for (size_t i = 0; i < init_ids.size(); i++) {
285
288
  int id = init_ids[i];
286
289
 
287
290
  float dist = dis(id);
@@ -303,7 +306,7 @@ void NSG::search_on_graph(
303
306
  int n = retset[k].id;
304
307
 
305
308
  size_t nneigh_for_n = graph.get_neighbors(n, neighbors.data());
306
- for (int m = 0; m < nneigh_for_n; m++) {
309
+ for (size_t m = 0; m < nneigh_for_n; m++) {
307
310
  int id = neighbors[m];
308
311
  if (id >= ntotal || vt.get(id)) {
309
312
  continue;
@@ -342,7 +345,8 @@ void NSG::link(
342
345
  std::vector<Node> pool;
343
346
  std::vector<Neighbor> tmp;
344
347
 
345
- VisitedTable vt(ntotal, use_visited_hashset);
348
+ std::unique_ptr<VisitedTable> vt =
349
+ VisitedTable::create(ntotal, use_visited_hashset);
346
350
  std::unique_ptr<DistanceComputer> dis(
347
351
  storage_distance_computer(storage));
348
352
 
@@ -353,13 +357,13 @@ void NSG::link(
353
357
 
354
358
  // Collect the visited nodes into pool
355
359
  search_on_graph<true>(
356
- knn_graph, *dis, vt, enterpoint, L, tmp, pool);
360
+ knn_graph, *dis, *vt, enterpoint, L, tmp, pool);
357
361
 
358
- sync_prune(i, pool, *dis, vt, knn_graph, graph);
362
+ sync_prune(i, pool, *dis, *vt, knn_graph, graph);
359
363
 
360
364
  pool.clear();
361
365
  tmp.clear();
362
- vt.advance();
366
+ vt->advance();
363
367
  }
364
368
  } // omp parallel
365
369
 
@@ -397,16 +401,30 @@ void NSG::sync_prune(
397
401
 
398
402
  std::vector<Node> result;
399
403
 
404
+ if (pool.empty()) {
405
+ for (int i = 0; i < R; i++) {
406
+ graph.at(q, i).id = EMPTY_ID;
407
+ }
408
+ return;
409
+ }
410
+
400
411
  int start = 0;
401
412
  if (pool[start].id == q) {
402
413
  start++;
403
414
  }
415
+ if (start >= static_cast<int>(pool.size())) {
416
+ for (int i = 0; i < R; i++) {
417
+ graph.at(q, i).id = EMPTY_ID;
418
+ }
419
+ return;
420
+ }
404
421
  result.push_back(pool[start]);
405
422
 
406
- while (result.size() < R && (++start) < pool.size() && start < C) {
423
+ while (result.size() < static_cast<size_t>(R) &&
424
+ (++start) < static_cast<int>(pool.size()) && start < C) {
407
425
  auto& p = pool[start];
408
426
  bool occlude = false;
409
- for (int t = 0; t < result.size(); t++) {
427
+ for (size_t t = 0; t < result.size(); t++) {
410
428
  if (p.id == result[t].id) {
411
429
  occlude = true;
412
430
  break;
@@ -422,8 +440,8 @@ void NSG::sync_prune(
422
440
  }
423
441
  }
424
442
 
425
- for (size_t i = 0; i < R; i++) {
426
- if (i < result.size()) {
443
+ for (int i = 0; i < R; i++) {
444
+ if (static_cast<size_t>(i) < result.size()) {
427
445
  graph.at(q, i).id = result[i].id;
428
446
  graph.at(q, i).distance = result[i].distance;
429
447
  } else {
@@ -437,7 +455,7 @@ void NSG::add_reverse_links(
437
455
  std::vector<std::mutex>& locks,
438
456
  DistanceComputer& dis,
439
457
  nsg::Graph<Node>& graph) {
440
- for (size_t i = 0; i < R; i++) {
458
+ for (int i = 0; i < R; i++) {
441
459
  if (graph.at(q, i).id == EMPTY_ID) {
442
460
  break;
443
461
  }
@@ -466,17 +484,18 @@ void NSG::add_reverse_links(
466
484
  }
467
485
 
468
486
  tmp_pool.push_back(sn);
469
- if (tmp_pool.size() > R) {
487
+ if (tmp_pool.size() > static_cast<size_t>(R)) {
470
488
  std::vector<Node> result;
471
489
  int start = 0;
472
490
  std::sort(tmp_pool.begin(), tmp_pool.end());
473
491
  result.push_back(tmp_pool[start]);
474
492
 
475
- while (result.size() < R && (++start) < tmp_pool.size()) {
493
+ while (result.size() < static_cast<size_t>(R) &&
494
+ (++start) < static_cast<int>(tmp_pool.size())) {
476
495
  auto& p = tmp_pool[start];
477
496
  bool occlude = false;
478
497
 
479
- for (int t = 0; t < result.size(); t++) {
498
+ for (size_t t = 0; t < result.size(); t++) {
480
499
  if (p.id == result[t].id) {
481
500
  occlude = true;
482
501
  break;
@@ -495,7 +514,7 @@ void NSG::add_reverse_links(
495
514
 
496
515
  {
497
516
  LockGuard guard(locks[des]);
498
- for (int t = 0; t < result.size(); t++) {
517
+ for (size_t t = 0; t < result.size(); t++) {
499
518
  graph.at(des, t) = result[t];
500
519
  }
501
520
  }
@@ -514,19 +533,21 @@ void NSG::add_reverse_links(
514
533
 
515
534
  int NSG::tree_grow(Index* storage, std::vector<int>& degrees) {
516
535
  int root = enterpoint;
517
- VisitedTable vt(ntotal, use_visited_hashset);
518
- VisitedTable vt2(ntotal, use_visited_hashset);
536
+ std::unique_ptr<VisitedTable> vt =
537
+ VisitedTable::create(ntotal, use_visited_hashset);
538
+ std::unique_ptr<VisitedTable> vt2 =
539
+ VisitedTable::create(ntotal, use_visited_hashset);
519
540
 
520
541
  int num_attached = 0;
521
542
  int cnt = 0;
522
543
  while (true) {
523
- cnt = dfs(vt, root, cnt);
544
+ cnt = dfs(*vt, root, cnt);
524
545
  if (cnt >= ntotal) {
525
546
  break;
526
547
  }
527
548
 
528
- root = attach_unlinked(storage, vt, vt2, degrees);
529
- vt2.advance();
549
+ root = attach_unlinked(storage, *vt, *vt2, degrees);
550
+ vt2->advance();
530
551
  num_attached += 1;
531
552
  }
532
553
 
@@ -614,7 +635,7 @@ int NSG::attach_unlinked(
614
635
 
615
636
  int node;
616
637
  bool found = false;
617
- for (int i = 0; i < pool.size(); i++) {
638
+ for (size_t i = 0; i < pool.size(); i++) {
618
639
  node = pool[i].id;
619
640
  if (degrees[node] < R && node != id) {
620
641
  found = true;
@@ -60,14 +60,14 @@ struct Graph {
60
60
  bool own_fields; ///< the underlying data owned by itself or not
61
61
 
62
62
  // construct from a known graph
63
- Graph(node_t* data, int N, int K)
64
- : data(data), K(K), N(N), own_fields(false) {}
63
+ Graph(node_t* data_in, int N_in, int K_in)
64
+ : data(data_in), K(K_in), N(N_in), own_fields(false) {}
65
65
 
66
66
  // construct an empty graph
67
67
  // NOTE: the newly allocated data needs to be destroyed at destruction time
68
- Graph(int N, int K) : K(K), N(N), own_fields(true) {
68
+ Graph(int N_in, int K_in) : K(K_in), N(N_in), own_fields(true) {
69
69
  size_t total = faiss::mul_no_overflow(
70
- (size_t)N, (size_t)K, "Graph allocation");
70
+ (size_t)N_in, (size_t)K_in, "Graph allocation");
71
71
  data = new node_t[total];
72
72
  }
73
73
 
@@ -54,16 +54,33 @@ inline void compute_cum_sums_impl(
54
54
  * Panorama structure implementation
55
55
  **************************************************************/
56
56
 
57
- Panorama::Panorama(size_t code_size, size_t n_levels, size_t batch_size)
58
- : code_size(code_size), n_levels(n_levels), batch_size(batch_size) {
57
+ Panorama::Panorama(
58
+ size_t code_size_in,
59
+ size_t n_levels_in,
60
+ size_t batch_size_in)
61
+ : code_size(code_size_in),
62
+ n_levels(n_levels_in),
63
+ batch_size(batch_size_in) {
59
64
  set_derived_values();
60
65
  }
61
66
 
62
67
  void Panorama::set_derived_values() {
63
68
  FAISS_THROW_IF_NOT_MSG(n_levels > 0, "Panorama: n_levels must be > 0");
64
69
  this->d = code_size / sizeof(float);
70
+ FAISS_THROW_IF_NOT_MSG(n_levels <= d, "Panorama: n_levels must be <= d");
65
71
  this->level_width_floats = ((d + n_levels - 1) / n_levels);
66
72
  this->level_width = this->level_width_floats * sizeof(float);
73
+ size_t n_real_levels = d / level_width_floats;
74
+ if (d > n_real_levels * level_width_floats) {
75
+ n_real_levels++;
76
+ }
77
+ if (this->n_levels != n_real_levels) {
78
+ fprintf(stderr,
79
+ "WARNING truncating nlevels from %zu to %zu\n",
80
+ this->n_levels,
81
+ n_real_levels);
82
+ this->n_levels = n_real_levels;
83
+ }
67
84
  }
68
85
 
69
86
  /**
@@ -146,12 +163,12 @@ void Panorama::reconstruct(idx_t key, float* recons, const uint8_t* codes_base)
146
163
 
147
164
  for (size_t level = 0; level < n_levels; level++) {
148
165
  size_t level_offset = level * level_width * batch_size;
166
+ size_t actual_level_width =
167
+ std::min(level_width, code_size - level * level_width);
149
168
  const uint8_t* src = codes_base + batch_offset + level_offset +
150
- pos_in_batch * level_width;
169
+ pos_in_batch * actual_level_width;
151
170
  uint8_t* dest = recons_buffer + level * level_width;
152
- size_t copy_size =
153
- std::min(level_width, code_size - level * level_width);
154
- memcpy(dest, src, copy_size);
171
+ memcpy(dest, src, actual_level_width);
155
172
  }
156
173
  }
157
174