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
@@ -11,15 +11,14 @@
11
11
  #include <faiss/VectorTransform.h>
12
12
  #include <faiss/impl/AuxIndexStructures.h>
13
13
 
14
- #include <chrono>
15
14
  #include <cinttypes>
16
15
  #include <cmath>
17
16
  #include <cstdio>
18
17
  #include <cstring>
19
-
20
- #include <omp.h>
18
+ #include <limits>
21
19
 
22
20
  #include <faiss/IndexFlat.h>
21
+ #include <faiss/impl/ClusteringHelpers.h>
23
22
  #include <faiss/impl/FaissAssert.h>
24
23
  #include <faiss/impl/kmeans1d.h>
25
24
  #include <faiss/utils/distances.h>
@@ -28,10 +27,10 @@
28
27
 
29
28
  namespace faiss {
30
29
 
31
- Clustering::Clustering(int d, int k) : d(d), k(k) {}
30
+ Clustering::Clustering(int d_, int k_) : d(d_), k(k_) {}
32
31
 
33
- Clustering::Clustering(int d, int k, const ClusteringParameters& cp)
34
- : ClusteringParameters(cp), d(d), k(k) {}
32
+ Clustering::Clustering(int d_, int k_, const ClusteringParameters& cp)
33
+ : ClusteringParameters(cp), d(d_), k(k_) {}
35
34
 
36
35
  void Clustering::post_process_centroids() {
37
36
  if (spherical) {
@@ -58,213 +57,6 @@ void Clustering::train(
58
57
  weights);
59
58
  }
60
59
 
61
- namespace {
62
-
63
- uint64_t get_actual_rng_seed(const int seed) {
64
- return (seed >= 0)
65
- ? seed
66
- : static_cast<uint64_t>(std::chrono::high_resolution_clock::now()
67
- .time_since_epoch()
68
- .count());
69
- }
70
-
71
- idx_t subsample_training_set(
72
- const Clustering& clus,
73
- idx_t nx,
74
- const uint8_t* x,
75
- size_t line_size,
76
- const float* weights,
77
- uint8_t** x_out,
78
- float** weights_out) {
79
- if (clus.verbose) {
80
- printf("Sampling a subset of %zd / %" PRId64 " for training\n",
81
- clus.k * clus.max_points_per_centroid,
82
- nx);
83
- }
84
-
85
- const uint64_t actual_seed = get_actual_rng_seed(clus.seed);
86
-
87
- std::vector<int> perm;
88
- if (clus.use_faster_subsampling) {
89
- // use subsampling with splitmix64 rng
90
- SplitMix64RandomGenerator rng(actual_seed);
91
-
92
- const idx_t new_nx = clus.k * clus.max_points_per_centroid;
93
- perm.resize(new_nx);
94
- for (idx_t i = 0; i < new_nx; i++) {
95
- perm[i] = rng.rand_int(nx);
96
- }
97
- } else {
98
- // use subsampling with a default std rng
99
- perm.resize(nx);
100
- rand_perm(perm.data(), nx, actual_seed);
101
- }
102
-
103
- nx = clus.k * clus.max_points_per_centroid;
104
- uint8_t* x_new = new uint8_t[nx * line_size];
105
- *x_out = x_new;
106
-
107
- // might be worth omp-ing as well
108
- for (idx_t i = 0; i < nx; i++) {
109
- memcpy(x_new + i * line_size, x + perm[i] * line_size, line_size);
110
- }
111
- if (weights) {
112
- float* weights_new = new float[nx];
113
- for (idx_t i = 0; i < nx; i++) {
114
- weights_new[i] = weights[perm[i]];
115
- }
116
- *weights_out = weights_new;
117
- } else {
118
- *weights_out = nullptr;
119
- }
120
- return nx;
121
- }
122
-
123
- /** compute centroids as (weighted) sum of training points
124
- *
125
- * @param x training vectors, size n * code_size (from codec)
126
- * @param codec how to decode the vectors (if NULL then cast to float*)
127
- * @param weights per-training vector weight, size n (or NULL)
128
- * @param assign nearest centroid for each training vector, size n
129
- * @param k_frozen do not update the k_frozen first centroids
130
- * @param centroids centroid vectors (output only), size k * d
131
- * @param hassign histogram of assignments per centroid (size k),
132
- * should be 0 on input
133
- *
134
- */
135
-
136
- void compute_centroids(
137
- size_t d,
138
- size_t k,
139
- size_t n,
140
- size_t k_frozen,
141
- const uint8_t* x,
142
- const Index* codec,
143
- const int64_t* assign,
144
- const float* weights,
145
- float* hassign,
146
- float* centroids) {
147
- k -= k_frozen;
148
- centroids += k_frozen * d;
149
-
150
- memset(centroids, 0, sizeof(*centroids) * d * k);
151
-
152
- size_t line_size = codec ? codec->sa_code_size() : d * sizeof(float);
153
-
154
- #pragma omp parallel
155
- {
156
- int nt = omp_get_num_threads();
157
- int rank = omp_get_thread_num();
158
-
159
- // this thread is taking care of centroids c0:c1
160
- size_t c0 = (k * rank) / nt;
161
- size_t c1 = (k * (rank + 1)) / nt;
162
- std::vector<float> decode_buffer(d);
163
-
164
- for (size_t i = 0; i < n; i++) {
165
- int64_t ci = assign[i];
166
- assert(ci >= 0 && ci < k + k_frozen);
167
- ci -= k_frozen;
168
- if (ci >= c0 && ci < c1) {
169
- float* c = centroids + ci * d;
170
- const float* xi;
171
- if (!codec) {
172
- xi = reinterpret_cast<const float*>(x + i * line_size);
173
- } else {
174
- float* xif = decode_buffer.data();
175
- codec->sa_decode(1, x + i * line_size, xif);
176
- xi = xif;
177
- }
178
- if (weights) {
179
- float w = weights[i];
180
- hassign[ci] += w;
181
- for (size_t j = 0; j < d; j++) {
182
- c[j] += xi[j] * w;
183
- }
184
- } else {
185
- hassign[ci] += 1.0;
186
- for (size_t j = 0; j < d; j++) {
187
- c[j] += xi[j];
188
- }
189
- }
190
- }
191
- }
192
- }
193
-
194
- #pragma omp parallel for
195
- for (idx_t ci = 0; ci < k; ci++) {
196
- if (hassign[ci] == 0) {
197
- continue;
198
- }
199
- float norm = 1 / hassign[ci];
200
- float* c = centroids + ci * d;
201
- for (size_t j = 0; j < d; j++) {
202
- c[j] *= norm;
203
- }
204
- }
205
- }
206
-
207
- // a bit above machine epsilon for float16
208
- #define EPS (1 / 1024.)
209
-
210
- /** Handle empty clusters by splitting larger ones.
211
- *
212
- * It works by slightly changing the centroids to make 2 clusters from
213
- * a single one. Takes the same arguments as compute_centroids.
214
- *
215
- * @return nb of splitting operations (larger is worse)
216
- */
217
- int split_clusters(
218
- size_t d,
219
- size_t k,
220
- size_t n,
221
- size_t k_frozen,
222
- float* hassign,
223
- float* centroids) {
224
- k -= k_frozen;
225
- centroids += k_frozen * d;
226
-
227
- /* Take care of void clusters */
228
- size_t nsplit = 0;
229
- RandomGenerator rng(1234);
230
- for (size_t ci = 0; ci < k; ci++) {
231
- if (hassign[ci] == 0) { /* need to redefine a centroid */
232
- size_t cj;
233
- for (cj = 0; true; cj = (cj + 1) % k) {
234
- /* probability to pick this cluster for split */
235
- float p = (hassign[cj] - 1.0) / (float)(n - k);
236
- float r = rng.rand_float();
237
- if (r < p) {
238
- break; /* found our cluster to be split */
239
- }
240
- }
241
- memcpy(centroids + ci * d,
242
- centroids + cj * d,
243
- sizeof(*centroids) * d);
244
-
245
- /* small symmetric perturbation */
246
- for (size_t j = 0; j < d; j++) {
247
- if (j % 2 == 0) {
248
- centroids[ci * d + j] *= 1 + EPS;
249
- centroids[cj * d + j] *= 1 - EPS;
250
- } else {
251
- centroids[ci * d + j] *= 1 - EPS;
252
- centroids[cj * d + j] *= 1 + EPS;
253
- }
254
- }
255
-
256
- /* assume even split of the cluster */
257
- hassign[ci] = hassign[cj] / 2;
258
- hassign[cj] -= hassign[ci];
259
- nsplit++;
260
- }
261
- }
262
-
263
- return nsplit;
264
- }
265
-
266
- } // namespace
267
-
268
60
  void Clustering::train_encoded(
269
61
  idx_t nx,
270
62
  const uint8_t* x_in,
@@ -272,7 +64,7 @@ void Clustering::train_encoded(
272
64
  Index& index,
273
65
  const float* weights) {
274
66
  FAISS_THROW_IF_NOT_FMT(
275
- nx >= k,
67
+ nx >= static_cast<idx_t>(k),
276
68
  "Number of training points (%" PRId64
277
69
  ") should be at least "
278
70
  "as large as number of clusters (%zd)",
@@ -280,13 +72,13 @@ void Clustering::train_encoded(
280
72
  k);
281
73
 
282
74
  FAISS_THROW_IF_NOT_FMT(
283
- (!codec || codec->d == d),
75
+ (!codec || static_cast<size_t>(codec->d) == d),
284
76
  "Codec dimension %d not the same as data dimension %d",
285
77
  int(codec->d),
286
78
  int(d));
287
79
 
288
80
  FAISS_THROW_IF_NOT_FMT(
289
- index.d == d,
81
+ static_cast<size_t>(index.d) == d,
290
82
  "Index dimension %d not the same as data dimension %d",
291
83
  int(index.d),
292
84
  int(d));
@@ -309,16 +101,16 @@ void Clustering::train_encoded(
309
101
  std::unique_ptr<float[]> del3;
310
102
  size_t line_size = codec ? codec->sa_code_size() : sizeof(float) * d;
311
103
 
312
- if (nx > k * max_points_per_centroid) {
104
+ if (static_cast<size_t>(nx) > k * max_points_per_centroid) {
313
105
  uint8_t* x_new;
314
106
  float* weights_new;
315
- nx = subsample_training_set(
107
+ nx = detail::subsample_training_set(
316
108
  *this, nx, x, line_size, weights, &x_new, &weights_new);
317
109
  del1.reset(x_new);
318
110
  x = x_new;
319
111
  del3.reset(weights_new);
320
112
  weights = weights_new;
321
- } else if (nx < k * min_points_per_centroid) {
113
+ } else if (static_cast<size_t>(nx) < k * min_points_per_centroid) {
322
114
  fprintf(stderr,
323
115
  "WARNING clustering %" PRId64
324
116
  " points to %zd centroids: "
@@ -328,7 +120,7 @@ void Clustering::train_encoded(
328
120
  idx_t(k) * min_points_per_centroid);
329
121
  }
330
122
 
331
- if (nx == k) {
123
+ if (static_cast<size_t>(nx) == k) {
332
124
  // this is a corner case, just copy training set to clusters
333
125
  if (verbose) {
334
126
  printf("Number of training points (%" PRId64
@@ -397,7 +189,7 @@ void Clustering::train_encoded(
397
189
  t0 = getmillisecs();
398
190
 
399
191
  // initialize seed
400
- const uint64_t actual_seed = get_actual_rng_seed(seed);
192
+ const uint64_t actual_seed = detail::get_actual_rng_seed(seed);
401
193
 
402
194
  // temporary buffer to decode vectors during the optimization
403
195
  std::vector<float> decode_buffer(codec ? d * decode_block_size : 0);
@@ -486,9 +278,10 @@ void Clustering::train_encoded(
486
278
  } else {
487
279
  // search by blocks of decode_block_size vectors
488
280
  size_t code_size = codec->sa_code_size();
489
- for (size_t i0 = 0; i0 < nx; i0 += decode_block_size) {
281
+ for (size_t i0 = 0; i0 < static_cast<size_t>(nx);
282
+ i0 += decode_block_size) {
490
283
  size_t i1 = i0 + decode_block_size;
491
- if (i1 > nx) {
284
+ if (i1 > static_cast<size_t>(nx)) {
492
285
  i1 = nx;
493
286
  }
494
287
  codec->sa_decode(
@@ -507,7 +300,7 @@ void Clustering::train_encoded(
507
300
 
508
301
  // accumulate objective
509
302
  obj = 0;
510
- for (int j = 0; j < nx; j++) {
303
+ for (idx_t j = 0; j < nx; j++) {
511
304
  obj += dis[j];
512
305
  }
513
306
 
@@ -515,7 +308,7 @@ void Clustering::train_encoded(
515
308
  std::vector<float> hassign(k);
516
309
 
517
310
  size_t k_frozen = frozen_centroids ? n_input_centroids : 0;
518
- compute_centroids(
311
+ detail::compute_centroids(
519
312
  d,
520
313
  k,
521
314
  nx,
@@ -527,7 +320,7 @@ void Clustering::train_encoded(
527
320
  hassign.data(),
528
321
  centroids.data());
529
322
 
530
- int nsplit = split_clusters(
323
+ int nsplit = detail::split_clusters(
531
324
  d, k, nx, k_frozen, hassign.data(), centroids.data());
532
325
 
533
326
  // collect statistics
@@ -535,7 +328,7 @@ void Clustering::train_encoded(
535
328
  obj,
536
329
  (getmillisecs() - t0) / 1000.0,
537
330
  t_search_tot / 1000,
538
- imbalance_factor(nx, k, assign.get()),
331
+ imbalance_factor(nx, static_cast<int>(k), assign.get()),
539
332
  nsplit};
540
333
  iteration_stats.push_back(stats);
541
334
 
@@ -569,7 +362,12 @@ void Clustering::train_encoded(
569
362
  if (i > 0) {
570
363
  float prev_obj =
571
364
  iteration_stats[iteration_stats.size() - 2].obj;
572
- if (obj == prev_obj) {
365
+
366
+ double change = (prev_obj == 0)
367
+ ? std::numeric_limits<double>::max()
368
+ : std::abs(prev_obj - obj) / std::abs(prev_obj);
369
+
370
+ if (change >= 0 && change <= early_stop_threshold) {
573
371
  if (verbose) {
574
372
  printf("\n Converged at iteration %d: "
575
373
  "objective did not change\n",
@@ -604,19 +402,19 @@ void Clustering::train_encoded(
604
402
  }
605
403
  }
606
404
 
607
- Clustering1D::Clustering1D(int k) : Clustering(1, k) {}
405
+ Clustering1D::Clustering1D(int k_) : Clustering(1, k_) {}
608
406
 
609
- Clustering1D::Clustering1D(int k, const ClusteringParameters& cp)
610
- : Clustering(1, k, cp) {}
407
+ Clustering1D::Clustering1D(int k_, const ClusteringParameters& cp)
408
+ : Clustering(1, k_, cp) {}
611
409
 
612
410
  void Clustering1D::train_exact(idx_t n, const float* x) {
613
411
  const float* xt = x;
614
412
 
615
413
  std::unique_ptr<uint8_t[]> del;
616
- if (n > k * max_points_per_centroid) {
414
+ if (static_cast<size_t>(n) > k * max_points_per_centroid) {
617
415
  uint8_t* x_new;
618
416
  float* weights_new;
619
- n = subsample_training_set(
417
+ n = detail::subsample_training_set(
620
418
  *this,
621
419
  n,
622
420
  (uint8_t*)x,
@@ -641,7 +439,7 @@ float kmeans_clustering(
641
439
  size_t k,
642
440
  const float* x,
643
441
  float* centroids) {
644
- Clustering clus(d, k);
442
+ Clustering clus(static_cast<int>(d), static_cast<int>(k));
645
443
  clus.verbose = d * n * k > (size_t(1) << 30);
646
444
  // display logs if > 1Gflop per iteration
647
445
  IndexFlatL2 index(d);
@@ -664,13 +462,14 @@ Index* ProgressiveDimIndexFactory::operator()(int dim) {
664
462
  return new IndexFlatL2(dim);
665
463
  }
666
464
 
667
- ProgressiveDimClustering::ProgressiveDimClustering(int d, int k) : d(d), k(k) {}
465
+ ProgressiveDimClustering::ProgressiveDimClustering(int d_, int k_)
466
+ : d(d_), k(k_) {}
668
467
 
669
468
  ProgressiveDimClustering::ProgressiveDimClustering(
670
- int d,
671
- int k,
469
+ int d_,
470
+ int k_,
672
471
  const ProgressiveDimClusteringParameters& cp)
673
- : ProgressiveDimClusteringParameters(cp), d(d), k(k) {}
472
+ : ProgressiveDimClusteringParameters(cp), d(d_), k(k_) {}
674
473
 
675
474
  namespace {
676
475
 
@@ -691,7 +490,7 @@ void ProgressiveDimClustering::train(
691
490
  ProgressiveDimIndexFactory& factory) {
692
491
  int d_prev = 0;
693
492
 
694
- PCAMatrix pca(d, d);
493
+ PCAMatrix pca(static_cast<int>(d), static_cast<int>(d));
695
494
 
696
495
  std::vector<float> xbuf;
697
496
  if (apply_pca) {
@@ -716,7 +515,7 @@ void ProgressiveDimClustering::train(
716
515
  }
717
516
  std::unique_ptr<Index> clustering_index(factory(di));
718
517
 
719
- Clustering clus(di, k, *this);
518
+ Clustering clus(di, static_cast<int>(k), *this);
720
519
  if (d_prev > 0) {
721
520
  // copy warm-start centroids (padded with 0s)
722
521
  clus.centroids.resize(k * di);
@@ -69,6 +69,12 @@ struct ClusteringParameters {
69
69
  /// Only used when init_method = AFK_MC2.
70
70
  /// Longer chains give better approximation but are slower.
71
71
  uint16_t afkmc2_chain_length = 50;
72
+
73
+ /// Early stop threshold, the range is [0, 1].
74
+ /// The value of 0 implies a default Faiss behavior,
75
+ /// so the training process stops only if an error
76
+ /// is unchanged from the previous iteration.
77
+ double early_stop_threshold = 0.0;
72
78
  };
73
79
 
74
80
  struct ClusteringIterationStats {
@@ -37,7 +37,7 @@ void check_compatible_for_merge(const Index* index0, const Index* index1) {
37
37
  FAISS_THROW_IF_NOT_MSG(pt1, "both indexes should be pretransforms");
38
38
 
39
39
  FAISS_THROW_IF_NOT(pt0->chain.size() == pt1->chain.size());
40
- for (int i = 0; i < pt0->chain.size(); i++) {
40
+ for (size_t i = 0; i < pt0->chain.size(); i++) {
41
41
  FAISS_THROW_IF_NOT(typeid(pt0->chain[i]) == typeid(pt1->chain[i]));
42
42
  }
43
43
 
@@ -125,7 +125,7 @@ void search_centroid(
125
125
  index = index_pre->index;
126
126
  }
127
127
  faiss::IndexIVF* index_ivf = dynamic_cast<faiss::IndexIVF*>(index);
128
- assert(index_ivf);
128
+ FAISS_THROW_IF_NOT_MSG(index_ivf, "could not extract IVF index");
129
129
  index_ivf->quantizer->assign(n, x, centroid_ids);
130
130
  }
131
131
 
@@ -146,7 +146,7 @@ void search_and_return_centroids(
146
146
  index = index_pre->index;
147
147
  }
148
148
  faiss::IndexIVF* index_ivf = dynamic_cast<faiss::IndexIVF*>(index);
149
- assert(index_ivf);
149
+ FAISS_THROW_IF_NOT_MSG(index_ivf, "could not extract IVF index");
150
150
 
151
151
  size_t nprobe = index_ivf->nprobe;
152
152
  std::vector<idx_t> cent_nos(n * nprobe);
@@ -180,9 +180,9 @@ void search_and_return_centroids(
180
180
  }
181
181
  }
182
182
 
183
- SlidingIndexWindow::SlidingIndexWindow(Index* index) : index(index) {
183
+ SlidingIndexWindow::SlidingIndexWindow(Index* index_) : index(index_) {
184
184
  n_slice = 0;
185
- IndexIVF* index_ivf = const_cast<IndexIVF*>(extract_index_ivf(index));
185
+ IndexIVF* index_ivf = const_cast<IndexIVF*>(extract_index_ivf(index_));
186
186
  ils = dynamic_cast<ArrayInvertedLists*>(index_ivf->invlists);
187
187
  FAISS_THROW_IF_NOT_MSG(
188
188
  ils, "only supports indexes with ArrayInvertedLists");
@@ -249,7 +249,7 @@ void SlidingIndexWindow::step(const Index* sub_index, bool remove_oldest) {
249
249
  IndexIVF* index_ivf = extract_index_ivf(index);
250
250
 
251
251
  if (remove_oldest && ils2) {
252
- for (int i = 0; i < nlist; i++) {
252
+ for (size_t i = 0; i < nlist; i++) {
253
253
  std::vector<size_t>& sizesi = sizes[i];
254
254
  size_t amount_to_remove = sizesi[0];
255
255
  index_ivf->ntotal += ils2->ids[i].size() - amount_to_remove;
@@ -265,7 +265,7 @@ void SlidingIndexWindow::step(const Index* sub_index, bool remove_oldest) {
265
265
  sizesi[n_slice - 1] = ils->ids[i].size();
266
266
  }
267
267
  } else if (ils2) {
268
- for (int i = 0; i < nlist; i++) {
268
+ for (size_t i = 0; i < nlist; i++) {
269
269
  index_ivf->ntotal += ils2->ids[i].size();
270
270
  shift_and_add(ils->ids[i], 0, ils2->ids[i]);
271
271
  shift_and_add(ils->codes[i], 0, ils2->codes[i]);
@@ -273,7 +273,7 @@ void SlidingIndexWindow::step(const Index* sub_index, bool remove_oldest) {
273
273
  }
274
274
  n_slice++;
275
275
  } else if (remove_oldest) {
276
- for (int i = 0; i < nlist; i++) {
276
+ for (size_t i = 0; i < nlist; i++) {
277
277
  size_t amount_to_remove = sizes[i][0];
278
278
  index_ivf->ntotal -= amount_to_remove;
279
279
  remove_from_begin(ils->ids[i], amount_to_remove);
@@ -296,7 +296,8 @@ void SlidingIndexWindow::step(const Index* sub_index, bool remove_oldest) {
296
296
  ArrayInvertedLists* get_invlist_range(const Index* index, long i0, long i1) {
297
297
  const IndexIVF* ivf = extract_index_ivf(index);
298
298
 
299
- FAISS_THROW_IF_NOT(0 <= i0 && i0 <= i1 && i1 <= ivf->nlist);
299
+ FAISS_THROW_IF_NOT(
300
+ 0 <= i0 && i0 <= i1 && static_cast<size_t>(i1) <= ivf->nlist);
300
301
 
301
302
  const InvertedLists* src = ivf->invlists;
302
303
 
@@ -319,12 +320,14 @@ void set_invlist_range(
319
320
  ArrayInvertedLists* src) {
320
321
  IndexIVF* ivf = extract_index_ivf(index);
321
322
 
322
- FAISS_THROW_IF_NOT(0 <= i0 && i0 <= i1 && i1 <= ivf->nlist);
323
+ FAISS_THROW_IF_NOT(
324
+ 0 <= i0 && i0 <= i1 && static_cast<size_t>(i1) <= ivf->nlist);
323
325
 
324
326
  ArrayInvertedLists* dst = dynamic_cast<ArrayInvertedLists*>(ivf->invlists);
325
327
  FAISS_THROW_IF_NOT_MSG(dst, "only ArrayInvertedLists supported");
326
328
  FAISS_THROW_IF_NOT(
327
- src->nlist == i1 - i0 && dst->code_size == src->code_size);
329
+ src->nlist == static_cast<size_t>(i1 - i0) &&
330
+ dst->code_size == src->code_size);
328
331
 
329
332
  size_t ntotal = index->ntotal;
330
333
  for (long i = i0; i < i1; i++) {
@@ -342,7 +345,7 @@ static size_t count_ndis(
342
345
  const idx_t* Iq) {
343
346
  size_t nb_dis = 0;
344
347
  const InvertedLists* il = index_ivf->invlists;
345
- for (idx_t i = 0; i < n_list_scan; i++) {
348
+ for (size_t i = 0; i < n_list_scan; i++) {
346
349
  if (Iq[i] >= 0) {
347
350
  nb_dis += il->list_size(Iq[i]);
348
351
  }
@@ -457,12 +460,12 @@ void range_search_with_parameters(
457
460
  IndexIVFResidualQuantizer* ivf_residual_from_quantizer(
458
461
  const ResidualQuantizer& rq,
459
462
  int nlevel) {
460
- FAISS_THROW_IF_NOT(nlevel > 0 && nlevel + 1 < rq.M);
463
+ FAISS_THROW_IF_NOT(nlevel > 0 && static_cast<size_t>(nlevel + 1) < rq.M);
461
464
 
462
465
  std::vector<size_t> nbits(nlevel);
463
466
  std::copy(rq.nbits.begin(), rq.nbits.begin() + nlevel, nbits.begin());
464
467
  std::unique_ptr<ResidualCoarseQuantizer> rcq(
465
- new ResidualCoarseQuantizer(rq.d, nbits));
468
+ new ResidualCoarseQuantizer(static_cast<int>(rq.d), nbits));
466
469
 
467
470
  // set the coarse quantizer from the 2 first quantizers
468
471
  rcq->rq.initialize_from(rq);
@@ -477,7 +480,7 @@ IndexIVFResidualQuantizer* ivf_residual_from_quantizer(
477
480
 
478
481
  // build a IVFResidualQuantizer from that
479
482
  std::vector<size_t> nbits_refined;
480
- for (int i = nlevel; i < rq.M; i++) {
483
+ for (size_t i = nlevel; i < rq.M; i++) {
481
484
  nbits_refined.push_back(rq.nbits[i]);
482
485
  }
483
486
  std::unique_ptr<IndexIVFResidualQuantizer> index(
@@ -489,7 +492,8 @@ IndexIVFResidualQuantizer* ivf_residual_from_quantizer(
489
492
  faiss::METRIC_L2,
490
493
  rq.search_type));
491
494
  index->own_fields = true;
492
- rcq.release();
495
+ // Ownership transferred to index via own_fields = true
496
+ (void)rcq.release();
493
497
  index->by_residual = true;
494
498
  index->rq.initialize_from(rq, nlevel);
495
499
  index->is_trained = true;
@@ -522,17 +526,17 @@ void ivf_residual_add_from_flat_codes(
522
526
  int rank = omp_get_thread_num();
523
527
 
524
528
  #pragma omp for
525
- for (idx_t i = 0; i < nb; i++) {
529
+ for (idx_t i = 0; i < static_cast<idx_t>(nb); i++) {
526
530
  const uint8_t* code = &raw_codes[i * code_size];
527
531
  BitstringReader rd(code, code_size);
528
- idx_t list_no = rd.read(rcq->rq.tot_bits);
532
+ idx_t list_no = rd.read(static_cast<int>(rcq->rq.tot_bits));
529
533
 
530
534
  if (list_no % nt ==
531
535
  rank) { // each thread takes care of 1/nt of the invlists
532
536
  // copy AQ indexes one by one
533
537
  BitstringWriter wr(tmp_code.data(), tmp_code.size());
534
- for (int j = 0; j < rq.M; j++) {
535
- int nbit = rq.nbits[j];
538
+ for (size_t j = 0; j < rq.M; j++) {
539
+ int nbit = static_cast<int>(rq.nbits[j]);
536
540
  wr.write(rd.read(nbit), nbit);
537
541
  }
538
542
  // we need to recompute the norm
@@ -540,7 +544,9 @@ void ivf_residual_add_from_flat_codes(
540
544
  // ok
541
545
  index->rq.decode(tmp_code.data(), tmp.data(), 1);
542
546
  float norm = fvec_norm_L2sqr<SL>(tmp.data(), rq.d);
543
- wr.write(rq.encode_norm(norm), rq.norm_bits);
547
+ wr.write(
548
+ rq.encode_norm(norm),
549
+ static_cast<int>(rq.norm_bits));
544
550
 
545
551
  // add code to the inverted list
546
552
  invlists.add_entry(list_no, i, tmp_code.data());
@@ -598,7 +604,14 @@ void handle_ivf(
598
604
  sharded_centroids[i].data());
599
605
  }
600
606
  char fname[256];
607
+ #if defined(__GNUC__) || defined(__clang__)
608
+ #pragma GCC diagnostic push
609
+ #pragma GCC diagnostic ignored "-Wformat-nonliteral"
610
+ #endif
601
611
  snprintf(fname, 256, filename_template.c_str(), i);
612
+ #if defined(__GNUC__) || defined(__clang__)
613
+ #pragma GCC diagnostic pop
614
+ #endif
602
615
  faiss::write_index(sharded_index, fname);
603
616
  delete sharded_index;
604
617
  }
@@ -649,7 +662,14 @@ void handle_binary_ivf(
649
662
  sharded_centroids[i].data());
650
663
  }
651
664
  char fname[256];
665
+ #if defined(__GNUC__) || defined(__clang__)
666
+ #pragma GCC diagnostic push
667
+ #pragma GCC diagnostic ignored "-Wformat-nonliteral"
668
+ #endif
652
669
  snprintf(fname, 256, filename_template.c_str(), i);
670
+ #if defined(__GNUC__) || defined(__clang__)
671
+ #pragma GCC diagnostic pop
672
+ #endif
653
673
  faiss::write_index_binary(sharded_index, fname);
654
674
  delete sharded_index;
655
675
  }
@@ -24,7 +24,7 @@ void Index::train(idx_t /*n*/, const float* /*x*/) {
24
24
  // does nothing by default
25
25
  }
26
26
 
27
- void Index::train(
27
+ void Index::train_with_queries(
28
28
  idx_t /*n*/,
29
29
  const float* /*x*/,
30
30
  idx_t /*n_train_q*/,
@@ -55,7 +55,7 @@ void Index::add_with_ids(
55
55
 
56
56
  size_t Index::remove_ids(const IDSelector& /*sel*/) {
57
57
  FAISS_THROW_MSG("remove_ids not implemented for this type of index");
58
- return -1;
58
+ return static_cast<size_t>(-1);
59
59
  }
60
60
 
61
61
  void Index::reconstruct(idx_t, float*) const {
@@ -129,7 +129,7 @@ void Index::search1(const float*, ResultHandler&, SearchParameters*) const {
129
129
 
130
130
  void Index::compute_residual(const float* x, float* residual, idx_t key) const {
131
131
  reconstruct(key, residual);
132
- for (size_t i = 0; i < d; i++) {
132
+ for (int i = 0; i < d; i++) {
133
133
  residual[i] = x[i] - residual[i];
134
134
  }
135
135
  }
@@ -168,9 +168,10 @@ struct GenericDistanceComputer : DistanceComputer {
168
168
  size_t d;
169
169
  const Index& storage;
170
170
  std::vector<float> buf;
171
- const float* q;
171
+ const float* q = nullptr;
172
172
 
173
- explicit GenericDistanceComputer(const Index& storage) : storage(storage) {
173
+ explicit GenericDistanceComputer(const Index& storage_in)
174
+ : storage(storage_in) {
174
175
  d = storage.d;
175
176
  buf.resize(d * 2);
176
177
  }