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
@@ -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++) {
@@ -256,16 +256,18 @@ void NSG::search_on_graph(
256
256
  retset.resize(pool_size + 1);
257
257
  std::vector<int> init_ids(pool_size);
258
258
 
259
+ vt.reserve(pool_size);
260
+
259
261
  int num_ids = 0;
260
262
  std::vector<index_t> neighbors(graph.K);
261
263
  size_t nneigh = graph.get_neighbors(ep, neighbors.data());
262
- for (int i = 0; i < init_ids.size() && i < nneigh; i++) {
264
+ for (size_t i = 0; i < init_ids.size() && i < nneigh; i++) {
263
265
  int id = (int)neighbors[i];
264
266
  if (id >= ntotal) {
265
267
  continue;
266
268
  }
267
269
 
268
- init_ids[i] = id;
270
+ init_ids[num_ids] = id;
269
271
  vt.set(id);
270
272
  num_ids += 1;
271
273
  }
@@ -281,7 +283,7 @@ void NSG::search_on_graph(
281
283
  vt.set(id);
282
284
  }
283
285
 
284
- for (int i = 0; i < init_ids.size(); i++) {
286
+ for (size_t i = 0; i < init_ids.size(); i++) {
285
287
  int id = init_ids[i];
286
288
 
287
289
  float dist = dis(id);
@@ -303,7 +305,7 @@ void NSG::search_on_graph(
303
305
  int n = retset[k].id;
304
306
 
305
307
  size_t nneigh_for_n = graph.get_neighbors(n, neighbors.data());
306
- for (int m = 0; m < nneigh_for_n; m++) {
308
+ for (size_t m = 0; m < nneigh_for_n; m++) {
307
309
  int id = neighbors[m];
308
310
  if (id >= ntotal || vt.get(id)) {
309
311
  continue;
@@ -397,16 +399,30 @@ void NSG::sync_prune(
397
399
 
398
400
  std::vector<Node> result;
399
401
 
402
+ if (pool.empty()) {
403
+ for (int i = 0; i < R; i++) {
404
+ graph.at(q, i).id = EMPTY_ID;
405
+ }
406
+ return;
407
+ }
408
+
400
409
  int start = 0;
401
410
  if (pool[start].id == q) {
402
411
  start++;
403
412
  }
413
+ if (start >= static_cast<int>(pool.size())) {
414
+ for (int i = 0; i < R; i++) {
415
+ graph.at(q, i).id = EMPTY_ID;
416
+ }
417
+ return;
418
+ }
404
419
  result.push_back(pool[start]);
405
420
 
406
- while (result.size() < R && (++start) < pool.size() && start < C) {
421
+ while (result.size() < static_cast<size_t>(R) &&
422
+ (++start) < static_cast<int>(pool.size()) && start < C) {
407
423
  auto& p = pool[start];
408
424
  bool occlude = false;
409
- for (int t = 0; t < result.size(); t++) {
425
+ for (size_t t = 0; t < result.size(); t++) {
410
426
  if (p.id == result[t].id) {
411
427
  occlude = true;
412
428
  break;
@@ -422,8 +438,8 @@ void NSG::sync_prune(
422
438
  }
423
439
  }
424
440
 
425
- for (size_t i = 0; i < R; i++) {
426
- if (i < result.size()) {
441
+ for (int i = 0; i < R; i++) {
442
+ if (static_cast<size_t>(i) < result.size()) {
427
443
  graph.at(q, i).id = result[i].id;
428
444
  graph.at(q, i).distance = result[i].distance;
429
445
  } else {
@@ -437,7 +453,7 @@ void NSG::add_reverse_links(
437
453
  std::vector<std::mutex>& locks,
438
454
  DistanceComputer& dis,
439
455
  nsg::Graph<Node>& graph) {
440
- for (size_t i = 0; i < R; i++) {
456
+ for (int i = 0; i < R; i++) {
441
457
  if (graph.at(q, i).id == EMPTY_ID) {
442
458
  break;
443
459
  }
@@ -466,17 +482,18 @@ void NSG::add_reverse_links(
466
482
  }
467
483
 
468
484
  tmp_pool.push_back(sn);
469
- if (tmp_pool.size() > R) {
485
+ if (tmp_pool.size() > static_cast<size_t>(R)) {
470
486
  std::vector<Node> result;
471
487
  int start = 0;
472
488
  std::sort(tmp_pool.begin(), tmp_pool.end());
473
489
  result.push_back(tmp_pool[start]);
474
490
 
475
- while (result.size() < R && (++start) < tmp_pool.size()) {
491
+ while (result.size() < static_cast<size_t>(R) &&
492
+ (++start) < static_cast<int>(tmp_pool.size())) {
476
493
  auto& p = tmp_pool[start];
477
494
  bool occlude = false;
478
495
 
479
- for (int t = 0; t < result.size(); t++) {
496
+ for (size_t t = 0; t < result.size(); t++) {
480
497
  if (p.id == result[t].id) {
481
498
  occlude = true;
482
499
  break;
@@ -495,7 +512,7 @@ void NSG::add_reverse_links(
495
512
 
496
513
  {
497
514
  LockGuard guard(locks[des]);
498
- for (int t = 0; t < result.size(); t++) {
515
+ for (size_t t = 0; t < result.size(); t++) {
499
516
  graph.at(des, t) = result[t];
500
517
  }
501
518
  }
@@ -614,7 +631,7 @@ int NSG::attach_unlinked(
614
631
 
615
632
  int node;
616
633
  bool found = false;
617
- for (int i = 0; i < pool.size(); i++) {
634
+ for (size_t i = 0; i < pool.size(); i++) {
618
635
  node = pool[i].id;
619
636
  if (degrees[node] < R && node != id) {
620
637
  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