faiss 0.5.3 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (379) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/ext/faiss/ext.cpp +1 -1
  4. data/ext/faiss/extconf.rb +4 -4
  5. data/ext/faiss/index.cpp +63 -45
  6. data/ext/faiss/index_binary.cpp +37 -27
  7. data/ext/faiss/kmeans.cpp +9 -8
  8. data/ext/faiss/pca_matrix.cpp +9 -7
  9. data/ext/faiss/product_quantizer.cpp +13 -11
  10. data/ext/faiss/utils.cpp +4 -2
  11. data/ext/faiss/utils.h +4 -0
  12. data/lib/faiss/version.rb +1 -1
  13. data/lib/faiss.rb +1 -1
  14. data/vendor/faiss/faiss/AutoTune.cpp +214 -82
  15. data/vendor/faiss/faiss/AutoTune.h +14 -1
  16. data/vendor/faiss/faiss/Clustering.cpp +97 -249
  17. data/vendor/faiss/faiss/Clustering.h +18 -0
  18. data/vendor/faiss/faiss/IVFlib.cpp +67 -44
  19. data/vendor/faiss/faiss/Index.cpp +25 -12
  20. data/vendor/faiss/faiss/Index.h +26 -4
  21. data/vendor/faiss/faiss/Index2Layer.cpp +37 -53
  22. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +68 -61
  23. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +36 -34
  24. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +4 -1
  25. data/vendor/faiss/faiss/IndexBinary.cpp +6 -3
  26. data/vendor/faiss/faiss/IndexBinary.h +4 -4
  27. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +1 -1
  28. data/vendor/faiss/faiss/IndexBinaryFlat.h +1 -1
  29. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -4
  30. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +92 -95
  31. data/vendor/faiss/faiss/IndexBinaryHNSW.h +9 -3
  32. data/vendor/faiss/faiss/IndexBinaryHash.cpp +45 -236
  33. data/vendor/faiss/faiss/IndexBinaryHash.h +6 -6
  34. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +120 -414
  35. data/vendor/faiss/faiss/IndexFastScan.cpp +105 -129
  36. data/vendor/faiss/faiss/IndexFastScan.h +35 -24
  37. data/vendor/faiss/faiss/IndexFlat.cpp +216 -152
  38. data/vendor/faiss/faiss/IndexFlat.h +32 -14
  39. data/vendor/faiss/faiss/IndexFlatCodes.cpp +88 -41
  40. data/vendor/faiss/faiss/IndexFlatCodes.h +7 -1
  41. data/vendor/faiss/faiss/IndexHNSW.cpp +299 -187
  42. data/vendor/faiss/faiss/IndexHNSW.h +30 -14
  43. data/vendor/faiss/faiss/IndexIDMap.cpp +26 -22
  44. data/vendor/faiss/faiss/IndexIDMap.h +9 -7
  45. data/vendor/faiss/faiss/IndexIVF.cpp +535 -405
  46. data/vendor/faiss/faiss/IndexIVF.h +47 -16
  47. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +77 -74
  48. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +105 -99
  49. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +6 -3
  50. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +379 -249
  51. data/vendor/faiss/faiss/IndexIVFFastScan.h +65 -60
  52. data/vendor/faiss/faiss/IndexIVFFlat.cpp +41 -124
  53. data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
  54. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +89 -138
  55. data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
  56. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
  57. data/vendor/faiss/faiss/IndexIVFPQ.cpp +77 -907
  58. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +184 -122
  59. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
  60. data/vendor/faiss/faiss/IndexIVFPQR.cpp +23 -18
  61. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +59 -60
  62. data/vendor/faiss/faiss/IndexIVFRaBitQ.h +4 -3
  63. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +564 -416
  64. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +269 -111
  65. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +41 -127
  66. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
  67. data/vendor/faiss/faiss/IndexLSH.cpp +44 -25
  68. data/vendor/faiss/faiss/IndexLattice.cpp +41 -36
  69. data/vendor/faiss/faiss/IndexNNDescent.cpp +37 -21
  70. data/vendor/faiss/faiss/IndexNNDescent.h +2 -2
  71. data/vendor/faiss/faiss/IndexNSG.cpp +40 -23
  72. data/vendor/faiss/faiss/IndexNSG.h +0 -2
  73. data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +32 -12
  74. data/vendor/faiss/faiss/IndexPQ.cpp +129 -213
  75. data/vendor/faiss/faiss/IndexPQ.h +3 -2
  76. data/vendor/faiss/faiss/IndexPQFastScan.cpp +20 -14
  77. data/vendor/faiss/faiss/IndexPQFastScan.h +3 -0
  78. data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -18
  79. data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
  80. data/vendor/faiss/faiss/IndexRaBitQ.cpp +31 -43
  81. data/vendor/faiss/faiss/IndexRaBitQ.h +4 -3
  82. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +135 -317
  83. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +192 -34
  84. data/vendor/faiss/faiss/IndexRefine.cpp +30 -55
  85. data/vendor/faiss/faiss/IndexRefine.h +4 -4
  86. data/vendor/faiss/faiss/IndexReplicas.cpp +6 -6
  87. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +15 -14
  88. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +1 -1
  89. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +82 -14
  90. data/vendor/faiss/faiss/IndexShards.cpp +13 -13
  91. data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
  92. data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
  93. data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
  94. data/vendor/faiss/faiss/MetaIndexes.h +1 -1
  95. data/vendor/faiss/faiss/MetricType.h +29 -6
  96. data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
  97. data/vendor/faiss/faiss/SuperKMeans.h +97 -0
  98. data/vendor/faiss/faiss/VectorTransform.cpp +349 -141
  99. data/vendor/faiss/faiss/VectorTransform.h +39 -16
  100. data/vendor/faiss/faiss/build.cpp +23 -0
  101. data/vendor/faiss/faiss/build.h +15 -0
  102. data/vendor/faiss/faiss/clone_index.cpp +55 -51
  103. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
  104. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
  105. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
  106. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
  107. data/vendor/faiss/faiss/{cppcontrib/factory_tools.cpp → factory_tools.cpp} +6 -1
  108. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +1 -1
  109. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
  110. data/vendor/faiss/faiss/gpu/GpuResources.h +1 -1
  111. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +9 -9
  112. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +4 -3
  113. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
  114. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
  115. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
  116. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
  117. data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
  118. data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
  119. data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
  120. data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
  121. data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
  122. data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
  123. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +51 -0
  124. data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
  125. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +66 -0
  126. data/vendor/faiss/faiss/gpu_metal/MetalResources.h +79 -0
  127. data/vendor/faiss/faiss/gpu_metal/StandardMetalResources.h +35 -0
  128. data/vendor/faiss/faiss/impl/AdSampling.cpp +103 -0
  129. data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
  130. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +64 -34
  131. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
  132. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
  133. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -28
  134. data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
  135. data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
  136. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +367 -0
  137. data/vendor/faiss/faiss/impl/ClusteringInitialization.h +107 -0
  138. data/vendor/faiss/faiss/impl/CodePacker.cpp +7 -3
  139. data/vendor/faiss/faiss/impl/CodePacker.h +11 -3
  140. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +83 -0
  141. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.h +47 -0
  142. data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
  143. data/vendor/faiss/faiss/impl/FaissAssert.h +64 -3
  144. data/vendor/faiss/faiss/impl/FaissException.h +50 -3
  145. data/vendor/faiss/faiss/impl/HNSW.cpp +117 -351
  146. data/vendor/faiss/faiss/impl/HNSW.h +21 -40
  147. data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
  148. data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
  149. data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
  150. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +114 -102
  151. data/vendor/faiss/faiss/impl/NNDescent.cpp +63 -26
  152. data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
  153. data/vendor/faiss/faiss/impl/NSG.cpp +44 -26
  154. data/vendor/faiss/faiss/impl/NSG.h +20 -10
  155. data/vendor/faiss/faiss/impl/Panorama.cpp +76 -52
  156. data/vendor/faiss/faiss/impl/Panorama.h +265 -78
  157. data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
  158. data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
  159. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +62 -37
  160. data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
  161. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
  162. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
  163. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +99 -80
  164. data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
  165. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +135 -37
  166. data/vendor/faiss/faiss/impl/RaBitQUtils.h +148 -21
  167. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +298 -301
  168. data/vendor/faiss/faiss/impl/RaBitQuantizer.h +3 -10
  169. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +15 -41
  170. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.h +0 -4
  171. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +40 -32
  172. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
  173. data/vendor/faiss/faiss/impl/ResultHandler.h +218 -113
  174. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +119 -2362
  175. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +27 -3
  176. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
  177. data/vendor/faiss/faiss/impl/VisitedTable.cpp +42 -0
  178. data/vendor/faiss/faiss/impl/VisitedTable.h +76 -0
  179. data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
  180. data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
  181. data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
  182. data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
  183. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
  184. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
  185. data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
  186. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
  187. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
  188. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
  189. data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
  190. data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
  191. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
  192. data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
  193. data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
  194. data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
  195. data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
  196. data/vendor/faiss/faiss/impl/expanded_scanners.h +163 -0
  197. data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
  198. data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
  199. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
  200. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
  201. data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
  202. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +268 -0
  203. data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +176 -4
  204. data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
  205. data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
  206. data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
  207. data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
  208. data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
  209. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
  210. data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -348
  211. data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
  212. data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
  213. data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +290 -142
  214. data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
  215. data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
  216. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +91 -0
  217. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -0
  218. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +104 -0
  219. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +111 -0
  220. data/vendor/faiss/faiss/impl/index_read.cpp +1950 -505
  221. data/vendor/faiss/faiss/impl/index_read_utils.h +1 -2
  222. data/vendor/faiss/faiss/impl/index_write.cpp +112 -21
  223. data/vendor/faiss/faiss/impl/io.cpp +6 -6
  224. data/vendor/faiss/faiss/impl/io_macros.h +33 -16
  225. data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
  226. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +81 -40
  227. data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
  228. data/vendor/faiss/faiss/impl/mapped_io.cpp +15 -8
  229. data/vendor/faiss/faiss/impl/platform_macros.h +11 -4
  230. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
  231. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
  232. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
  233. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
  234. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +21 -0
  235. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +21 -0
  236. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +21 -0
  237. data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx2.h → pq_code_distance/pq_code_distance-avx2.h} +43 -220
  238. data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx512.h → pq_code_distance/pq_code_distance-avx512.h} +25 -112
  239. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +59 -0
  240. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
  241. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +256 -0
  242. data/vendor/faiss/faiss/impl/{code_distance/code_distance-sve.h → pq_code_distance/pq_code_distance-sve.cpp} +57 -146
  243. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +68 -0
  244. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +320 -483
  245. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
  246. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +121 -0
  247. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +137 -0
  248. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +371 -0
  249. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +190 -0
  250. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +94 -0
  251. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +603 -0
  252. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +597 -0
  253. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +388 -0
  254. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +630 -0
  255. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +311 -0
  256. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +387 -0
  257. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +54 -0
  258. data/vendor/faiss/faiss/impl/simd_dispatch.h +173 -0
  259. data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
  260. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +274 -171
  261. data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
  262. data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
  263. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
  264. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +275 -217
  265. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
  266. data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
  267. data/vendor/faiss/faiss/impl/svs_io.h +8 -2
  268. data/vendor/faiss/faiss/index_factory.cpp +115 -28
  269. data/vendor/faiss/faiss/index_io.h +53 -3
  270. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +73 -20
  271. data/vendor/faiss/faiss/invlists/DirectMap.cpp +24 -14
  272. data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
  273. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +157 -73
  274. data/vendor/faiss/faiss/invlists/InvertedLists.h +86 -23
  275. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
  276. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +14 -14
  277. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  278. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +9 -19
  279. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
  280. data/vendor/faiss/faiss/svs/IndexSVSFlat.h +2 -0
  281. data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
  282. data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
  283. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
  284. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
  285. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
  286. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
  287. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +25 -1
  288. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +19 -2
  289. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +1 -1
  290. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +19 -2
  291. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +14 -0
  292. data/vendor/faiss/faiss/utils/Heap.cpp +56 -10
  293. data/vendor/faiss/faiss/utils/Heap.h +21 -0
  294. data/vendor/faiss/faiss/utils/NeuralNet.cpp +54 -40
  295. data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
  296. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
  297. data/vendor/faiss/faiss/utils/distances.cpp +507 -559
  298. data/vendor/faiss/faiss/utils/distances.h +118 -1
  299. data/vendor/faiss/faiss/utils/distances_dispatch.h +250 -0
  300. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
  301. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
  302. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
  303. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
  304. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
  305. data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
  306. data/vendor/faiss/faiss/utils/distances_simd.cpp +72 -3681
  307. data/vendor/faiss/faiss/utils/extra_distances.cpp +60 -102
  308. data/vendor/faiss/faiss/utils/extra_distances.h +79 -7
  309. data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
  310. data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
  311. data/vendor/faiss/faiss/utils/hamming.h +92 -2
  312. data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
  313. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +15 -0
  314. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
  315. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
  316. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +234 -0
  317. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-generic.h +368 -0
  318. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +322 -0
  319. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-rvv.h +39 -0
  320. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer.h +146 -0
  321. data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +481 -0
  322. data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +15 -0
  323. data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +15 -0
  324. data/vendor/faiss/faiss/utils/partitioning.cpp +66 -987
  325. data/vendor/faiss/faiss/utils/partitioning.h +31 -0
  326. data/vendor/faiss/faiss/utils/popcount.h +29 -0
  327. data/vendor/faiss/faiss/utils/pq_code_distance.h +251 -0
  328. data/vendor/faiss/faiss/utils/prefetch.h +2 -2
  329. data/vendor/faiss/faiss/utils/quantize_lut.cpp +30 -30
  330. data/vendor/faiss/faiss/utils/quantize_lut.h +1 -1
  331. data/vendor/faiss/faiss/utils/rabitq_simd.h +124 -343
  332. data/vendor/faiss/faiss/utils/random.cpp +6 -6
  333. data/vendor/faiss/faiss/utils/simd_impl/IVFFlatScanner-inl.h +51 -0
  334. data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +154 -0
  335. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +777 -0
  336. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +306 -0
  337. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +1431 -0
  338. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +1095 -0
  339. data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +189 -0
  340. data/vendor/faiss/faiss/utils/simd_impl/distances_simdlib256.h +195 -0
  341. data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +392 -0
  342. data/vendor/faiss/faiss/utils/{distances_fused/simdlib_based.h → simd_impl/exhaustive_L2sqr_blas_cmax.h} +5 -10
  343. data/vendor/faiss/faiss/utils/simd_impl/hamming_impl.h +481 -0
  344. data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +14 -0
  345. data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +14 -0
  346. data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +1085 -0
  347. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +355 -0
  348. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +477 -0
  349. data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +55 -0
  350. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
  351. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
  352. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
  353. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
  354. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
  355. data/vendor/faiss/faiss/utils/simd_levels.cpp +334 -0
  356. data/vendor/faiss/faiss/utils/simd_levels.h +183 -0
  357. data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
  358. data/vendor/faiss/faiss/utils/utils.cpp +21 -14
  359. data/vendor/faiss/faiss/utils/utils.h +3 -3
  360. metadata +156 -42
  361. data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
  362. data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
  363. data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +0 -81
  364. data/vendor/faiss/faiss/impl/code_distance/code_distance.h +0 -186
  365. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -216
  366. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -224
  367. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
  368. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
  369. data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
  370. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
  371. data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -228
  372. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
  373. data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
  374. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -450
  375. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
  376. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
  377. data/vendor/faiss/faiss/utils/simdlib.h +0 -42
  378. data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -296
  379. /data/vendor/faiss/faiss/{cppcontrib/factory_tools.h → factory_tools.h} +0 -0
@@ -19,7 +19,6 @@ namespace faiss {
19
19
  struct ProductQuantizer;
20
20
  struct ScalarQuantizer;
21
21
 
22
- void read_index_header(Index* idx, IOReader* f);
23
22
  void read_direct_map(DirectMap* dm, IOReader* f);
24
23
  void read_ivf_header(
25
24
  IndexIVF* ivf,
@@ -30,7 +29,7 @@ ArrayInvertedLists* set_array_invlist(
30
29
  IndexIVF* ivf,
31
30
  std::vector<std::vector<idx_t>>& ids);
32
31
  void read_ProductQuantizer(ProductQuantizer* pq, IOReader* f);
33
- void read_ScalarQuantizer(ScalarQuantizer* ivsc, IOReader* f);
32
+ void read_ScalarQuantizer(ScalarQuantizer* ivsc, IOReader* f, const Index& idx);
34
33
 
35
34
  } // namespace faiss
36
35
 
@@ -12,10 +12,14 @@
12
12
 
13
13
  #include <cstdio>
14
14
  #include <cstdlib>
15
+ #include <cstring>
15
16
 
16
17
  #include <faiss/invlists/InvertedListsIOHook.h>
17
18
 
19
+ #include <faiss/invlists/BlockInvertedLists.h>
20
+
18
21
  #include <faiss/impl/FaissAssert.h>
22
+ #include <faiss/impl/RaBitQUtils.h>
19
23
  #include <faiss/utils/hamming.h>
20
24
 
21
25
  #include <faiss/Index2Layer.h>
@@ -49,6 +53,9 @@
49
53
  #ifdef FAISS_ENABLE_SVS
50
54
  #include <faiss/impl/svs_io.h>
51
55
  #include <faiss/svs/IndexSVSFlat.h>
56
+ #include <faiss/svs/IndexSVSIVF.h>
57
+ #include <faiss/svs/IndexSVSIVFLVQ.h>
58
+ #include <faiss/svs/IndexSVSIVFLeanVec.h>
52
59
  #include <faiss/svs/IndexSVSVamana.h>
53
60
  #include <faiss/svs/IndexSVSVamanaLVQ.h>
54
61
  #include <faiss/svs/IndexSVSVamanaLeanVec.h>
@@ -101,7 +108,14 @@ static void write_index_header(const Index* idx, IOWriter* f) {
101
108
  }
102
109
 
103
110
  void write_VectorTransform(const VectorTransform* vt, IOWriter* f) {
104
- if (const LinearTransform* lt = dynamic_cast<const LinearTransform*>(vt)) {
111
+ if (const HadamardRotation* hr =
112
+ dynamic_cast<const HadamardRotation*>(vt)) {
113
+ uint32_t h = fourcc("HRot");
114
+ WRITE1(h);
115
+ WRITE1(hr->seed);
116
+ } else if (
117
+ const LinearTransform* lt =
118
+ dynamic_cast<const LinearTransform*>(vt)) {
105
119
  if (dynamic_cast<const RandomRotationMatrix*>(lt)) {
106
120
  uint32_t h = fourcc("rrot");
107
121
  WRITE1(h);
@@ -258,11 +272,20 @@ void write_InvertedLists(const InvertedLists* ils, IOWriter* f) {
258
272
  } else if (
259
273
  const auto& ailp =
260
274
  dynamic_cast<const ArrayInvertedListsPanorama*>(ils)) {
261
- uint32_t h = fourcc("ilpn");
262
- WRITE1(h);
263
- WRITE1(ailp->nlist);
264
- WRITE1(ailp->code_size);
265
- WRITE1(ailp->n_levels);
275
+ if (ailp->pano.batch_size == Panorama::kDefaultBatchSize) {
276
+ uint32_t h = fourcc("ilpn");
277
+ WRITE1(h);
278
+ WRITE1(ailp->nlist);
279
+ WRITE1(ailp->code_size);
280
+ WRITE1(ailp->n_levels);
281
+ } else {
282
+ uint32_t h = fourcc("ilp2");
283
+ WRITE1(h);
284
+ WRITE1(ailp->nlist);
285
+ WRITE1(ailp->code_size);
286
+ WRITE1(ailp->n_levels);
287
+ WRITE1(ailp->pano.batch_size);
288
+ }
266
289
  uint32_t list_type = fourcc("full");
267
290
  WRITE1(list_type);
268
291
  std::vector<size_t> sizes;
@@ -446,9 +469,9 @@ void write_index(const Index* idx, IOWriter* f, int io_flags) {
446
469
  uint32_t h = fourcc("null");
447
470
  WRITE1(h);
448
471
  } else if (
449
- const IndexFlatL2Panorama* idxpan =
450
- dynamic_cast<const IndexFlatL2Panorama*>(idx)) {
451
- uint32_t h = fourcc("IxFP");
472
+ const IndexFlatPanorama* idxpan =
473
+ dynamic_cast<const IndexFlatPanorama*>(idx)) {
474
+ uint32_t h = fourcc(idxpan->metric_type == METRIC_L2 ? "IxFP" : "IxFp");
452
475
  WRITE1(h);
453
476
  WRITE1(idxpan->d);
454
477
  WRITE1(idxpan->n_levels);
@@ -637,13 +660,13 @@ void write_index(const Index* idx, IOWriter* f, int io_flags) {
637
660
 
638
661
  write_InvertedLists(ivaqfs->invlists, f);
639
662
  } else if (
640
- const ResidualCoarseQuantizer* idxr_2 =
663
+ const ResidualCoarseQuantizer* idxrcq =
641
664
  dynamic_cast<const ResidualCoarseQuantizer*>(idx)) {
642
665
  uint32_t h = fourcc("ImRQ");
643
666
  WRITE1(h);
644
667
  write_index_header(idx, f);
645
- write_ResidualQuantizer(&idxr_2->rq, f);
646
- WRITE1(idxr_2->beam_factor);
668
+ write_ResidualQuantizer(&idxrcq->rq, f);
669
+ WRITE1(idxrcq->beam_factor);
647
670
  } else if (
648
671
  const Index2Layer* idxp_2 = dynamic_cast<const Index2Layer*>(idx)) {
649
672
  uint32_t h = fourcc("Ix2L");
@@ -696,10 +719,18 @@ void write_index(const Index* idx, IOWriter* f, int io_flags) {
696
719
  } else if (
697
720
  const IndexIVFFlatPanorama* ivfp =
698
721
  dynamic_cast<const IndexIVFFlatPanorama*>(idx)) {
699
- uint32_t h = fourcc("IwPn");
700
- WRITE1(h);
701
- write_ivf_header(ivfp, f);
702
- WRITE1(ivfp->n_levels);
722
+ if (ivfp->batch_size == Panorama::kDefaultBatchSize) {
723
+ uint32_t h = fourcc("IwPn");
724
+ WRITE1(h);
725
+ write_ivf_header(ivfp, f);
726
+ WRITE1(ivfp->n_levels);
727
+ } else {
728
+ uint32_t h = fourcc("IwP2");
729
+ WRITE1(h);
730
+ write_ivf_header(ivfp, f);
731
+ WRITE1(ivfp->n_levels);
732
+ WRITE1(ivfp->batch_size);
733
+ }
703
734
  write_InvertedLists(ivfp->invlists, f);
704
735
  } else if (
705
736
  const IndexIVFFlat* ivfl_2 =
@@ -937,13 +968,12 @@ void write_index(const Index* idx, IOWriter* f, int io_flags) {
937
968
  } else if (
938
969
  const IndexRaBitQFastScan* idxqfs =
939
970
  dynamic_cast<const IndexRaBitQFastScan*>(idx)) {
940
- uint32_t h = fourcc("Irfs");
971
+ uint32_t h = fourcc("Irfn");
941
972
  WRITE1(h);
942
973
  write_index_header(idx, f);
943
974
  write_RaBitQuantizer(&idxqfs->rabitq, f);
944
975
  WRITEVECTOR(idxqfs->center);
945
976
  WRITE1(idxqfs->qb);
946
- WRITEVECTOR(idxqfs->flat_storage);
947
977
  WRITE1(idxqfs->bbs);
948
978
  WRITE1(idxqfs->ntotal2);
949
979
  WRITE1(idxqfs->M2);
@@ -997,6 +1027,8 @@ void write_index(const Index* idx, IOWriter* f, int io_flags) {
997
1027
  h = fourcc("ILVQ"); // LVQ
998
1028
  } else if (lean != nullptr) {
999
1029
  h = fourcc("ISVL"); // LeanVec
1030
+ } else if (svs->stored_vectors_valid && !svs->stored_vectors.empty()) {
1031
+ h = fourcc("ISV2"); // uncompressed + stored_vectors
1000
1032
  } else {
1001
1033
  h = fourcc("ISVD"); // uncompressed
1002
1034
  }
@@ -1039,6 +1071,10 @@ void write_index(const Index* idx, IOWriter* f, int io_flags) {
1039
1071
  os.flush();
1040
1072
  }
1041
1073
  }
1074
+
1075
+ if (h == fourcc("ISV2")) {
1076
+ WRITEVECTOR(svs->stored_vectors);
1077
+ }
1042
1078
  } else if (
1043
1079
  const IndexSVSFlat* svs = dynamic_cast<const IndexSVSFlat*>(idx)) {
1044
1080
  uint32_t h = fourcc("ISVF");
@@ -1055,12 +1091,68 @@ void write_index(const Index* idx, IOWriter* f, int io_flags) {
1055
1091
  svs->serialize_impl(os);
1056
1092
  os.flush();
1057
1093
  }
1094
+ } else if (
1095
+ const IndexSVSIVF* svs_ivf =
1096
+ dynamic_cast<const IndexSVSIVF*>(idx)) {
1097
+ uint32_t h;
1098
+ auto* lvq = dynamic_cast<const IndexSVSIVFLVQ*>(svs_ivf);
1099
+ auto* lean = dynamic_cast<const IndexSVSIVFLeanVec*>(svs_ivf);
1100
+ if (lvq != nullptr) {
1101
+ h = fourcc("ISIQ"); // IndexSVSIVFLVQ
1102
+ } else if (lean != nullptr) {
1103
+ h = fourcc("ISIL"); // IndexSVSIVFLeanVec
1104
+ } else {
1105
+ h = fourcc("ISID"); // IndexSVSIVF
1106
+ }
1107
+
1108
+ WRITE1(h);
1109
+ write_index_header(svs_ivf, f);
1110
+ WRITE1(svs_ivf->num_centroids);
1111
+ WRITE1(svs_ivf->minibatch_size);
1112
+ WRITE1(svs_ivf->num_iterations);
1113
+ WRITE1(svs_ivf->is_hierarchical);
1114
+ WRITE1(svs_ivf->training_fraction);
1115
+ WRITE1(svs_ivf->hierarchical_level1_clusters);
1116
+ WRITE1(svs_ivf->seed);
1117
+ WRITE1(svs_ivf->n_probes);
1118
+ WRITE1(svs_ivf->k_reorder);
1119
+ WRITE1(svs_ivf->num_threads);
1120
+ WRITE1(svs_ivf->intra_query_threads);
1121
+ WRITE1(svs_ivf->storage_kind);
1122
+ WRITE1(svs_ivf->is_static);
1123
+
1124
+ if (lean != nullptr) {
1125
+ WRITE1(lean->leanvec_d);
1126
+ }
1127
+
1128
+ bool initialized = (svs_ivf->impl != nullptr);
1129
+ WRITE1(initialized);
1130
+ if (initialized) {
1131
+ faiss::BufferedIOWriter bwr(f);
1132
+ faiss::svs_io::WriterStreambuf wbuf(&bwr);
1133
+ std::ostream os(&wbuf);
1134
+ svs_ivf->serialize_impl(os);
1135
+ os.flush();
1136
+ }
1137
+
1138
+ if (lean != nullptr) {
1139
+ // Store training data info
1140
+ bool trained = (lean->training_data != nullptr);
1141
+ WRITE1(trained);
1142
+ if (trained) {
1143
+ faiss::BufferedIOWriter bwr(f);
1144
+ faiss::svs_io::WriterStreambuf wbuf(&bwr);
1145
+ std::ostream os(&wbuf);
1146
+ lean->serialize_training_data(os);
1147
+ os.flush();
1148
+ }
1149
+ }
1058
1150
  }
1059
1151
  #endif // FAISS_ENABLE_SVS
1060
1152
  else if (
1061
1153
  const IndexIVFRaBitQFastScan* ivrqfs =
1062
1154
  dynamic_cast<const IndexIVFRaBitQFastScan*>(idx)) {
1063
- uint32_t h = fourcc("Iwrf");
1155
+ uint32_t h = fourcc("Iwrn");
1064
1156
  WRITE1(h);
1065
1157
  write_ivf_header(ivrqfs, f);
1066
1158
  write_RaBitQuantizer(&ivrqfs->rabitq, f);
@@ -1072,7 +1164,6 @@ void write_index(const Index* idx, IOWriter* f, int io_flags) {
1072
1164
  WRITE1(ivrqfs->implem);
1073
1165
  WRITE1(ivrqfs->qb);
1074
1166
  WRITE1(ivrqfs->centered);
1075
- WRITEVECTOR(ivrqfs->flat_storage);
1076
1167
  write_InvertedLists(ivrqfs->invlists, f);
1077
1168
  } else {
1078
1169
  FAISS_THROW_MSG("don't know how to serialize this type of index");
@@ -1156,7 +1247,7 @@ static void write_binary_multi_hash_map(
1156
1247
  size_t ntotal,
1157
1248
  IOWriter* f) {
1158
1249
  int id_bits = 0;
1159
- while ((ntotal > ((idx_t)1 << id_bits))) {
1250
+ while ((ntotal > (size_t(1) << id_bits))) {
1160
1251
  id_bits++;
1161
1252
  }
1162
1253
  WRITE1(id_bits);
@@ -134,14 +134,14 @@ int FileIOWriter::filedescriptor() {
134
134
  * IO buffer
135
135
  ***********************************************************************/
136
136
 
137
- BufferedIOReader::BufferedIOReader(IOReader* reader, size_t bsz)
138
- : reader(reader),
139
- bsz(bsz),
137
+ BufferedIOReader::BufferedIOReader(IOReader* reader_in, size_t bsz_in)
138
+ : reader(reader_in),
139
+ bsz(bsz_in),
140
140
  ofs(0),
141
141
  ofs2(0),
142
142
  b0(0),
143
143
  b1(0),
144
- buffer(bsz) {}
144
+ buffer(bsz_in) {}
145
145
 
146
146
  size_t BufferedIOReader::operator()(void* ptr, size_t unitsize, size_t nitems) {
147
147
  size_t size = unitsize * nitems;
@@ -184,8 +184,8 @@ size_t BufferedIOReader::operator()(void* ptr, size_t unitsize, size_t nitems) {
184
184
  return nb / unitsize;
185
185
  }
186
186
 
187
- BufferedIOWriter::BufferedIOWriter(IOWriter* writer, size_t bsz)
188
- : writer(writer), bsz(bsz), ofs2(0), b0(0), buffer(bsz) {}
187
+ BufferedIOWriter::BufferedIOWriter(IOWriter* writer_in, size_t bsz_in)
188
+ : writer(writer_in), bsz(bsz_in), ofs2(0), b0(0), buffer(bsz_in) {}
189
189
 
190
190
  size_t BufferedIOWriter::operator()(
191
191
  const void* ptr,
@@ -17,6 +17,10 @@
17
17
  * always called f and thus is not passed in as a macro parameter.
18
18
  **************************************************************/
19
19
 
20
+ namespace faiss {
21
+ size_t get_deserialization_vector_byte_limit();
22
+ } // namespace faiss
23
+
20
24
  #define READANDCHECK(ptr, n) \
21
25
  { \
22
26
  size_t ret = (*f)(ptr, sizeof(*(ptr)), n); \
@@ -37,14 +41,24 @@
37
41
  READ1(x); \
38
42
  }
39
43
 
40
- // will fail if we write 256G of data at once...
41
- #define READVECTOR(vec) \
42
- { \
43
- size_t size; \
44
- READANDCHECK(&size, 1); \
45
- FAISS_THROW_IF_NOT(size >= 0 && size < (uint64_t{1} << 40)); \
46
- (vec).resize(size); \
47
- READANDCHECK((vec).data(), size); \
44
+ // Rejects vectors whose total allocation would exceed the configurable
45
+ // byte limit (default 1 TB).
46
+ #define READVECTOR(vec) \
47
+ { \
48
+ size_t size; \
49
+ READANDCHECK(&size, 1); \
50
+ FAISS_THROW_IF_NOT( \
51
+ size >= 0 && \
52
+ size < (faiss::get_deserialization_vector_byte_limit() / \
53
+ sizeof(*(vec).data()))); \
54
+ FAISS_THROW_IF_NOT_FMT( \
55
+ size <= SIZE_MAX / sizeof((vec)[0]), \
56
+ "READVECTOR: size %zu would overflow for element " \
57
+ "size %zu", \
58
+ size, \
59
+ sizeof((vec)[0])); \
60
+ (vec).resize(size); \
61
+ READANDCHECK((vec).data(), size); \
48
62
  }
49
63
 
50
64
  #define WRITEANDCHECK(ptr, n) \
@@ -78,12 +92,15 @@
78
92
  WRITEANDCHECK((vec).data(), size * 4); \
79
93
  }
80
94
 
81
- #define READXBVECTOR(vec) \
82
- { \
83
- size_t size; \
84
- READANDCHECK(&size, 1); \
85
- FAISS_THROW_IF_NOT(size >= 0 && size < (uint64_t{1} << 40)); \
86
- size *= 4; \
87
- (vec).resize(size); \
88
- READANDCHECK((vec).data(), size); \
95
+ #define READXBVECTOR(vec) \
96
+ { \
97
+ size_t size; \
98
+ READANDCHECK(&size, 1); \
99
+ FAISS_THROW_IF_NOT( \
100
+ size >= 0 && \
101
+ size < (faiss::get_deserialization_vector_byte_limit() / \
102
+ (4 * sizeof(*(vec).data())))); \
103
+ size *= 4; \
104
+ (vec).resize(size); \
105
+ READANDCHECK((vec).data(), size); \
89
106
  }
@@ -48,12 +48,12 @@ void interpolate(
48
48
  const LookUpFunc& lookup,
49
49
  idx_t* argmins) {
50
50
  std::unordered_map<idx_t, idx_t> idx_to_col;
51
- for (idx_t idx = 0; idx < cols.size(); ++idx) {
51
+ for (size_t idx = 0; idx < cols.size(); ++idx) {
52
52
  idx_to_col[cols[idx]] = idx;
53
53
  }
54
54
 
55
55
  idx_t start = 0;
56
- for (idx_t r = 0; r < rows.size(); r += 2) {
56
+ for (size_t r = 0; r < rows.size(); r += 2) {
57
57
  idx_t row = rows[r];
58
58
  idx_t end = cols.size() - 1;
59
59
  if (r < rows.size() - 1) {
@@ -107,7 +107,7 @@ void smawk_impl(
107
107
 
108
108
  // call recursively on odd-indexed rows
109
109
  std::vector<idx_t> odd_rows;
110
- for (idx_t i = 1; i < rows.size(); i += 2) {
110
+ for (size_t i = 1; i < rows.size(); i += 2) {
111
111
  odd_rows.push_back(rows[i]);
112
112
  }
113
113
  smawk_impl(odd_rows, cols, lookup, argmins);
@@ -175,10 +175,10 @@ class Matrix {
175
175
  idx_t ncols;
176
176
 
177
177
  public:
178
- Matrix(idx_t nrows, idx_t ncols) {
179
- this->nrows = nrows;
180
- this->ncols = ncols;
181
- data.resize(nrows * ncols);
178
+ Matrix(idx_t nrows_in, idx_t ncols_in) {
179
+ this->nrows = nrows_in;
180
+ this->ncols = ncols_in;
181
+ data.resize(nrows_in * ncols_in);
182
182
  }
183
183
 
184
184
  inline T& at(idx_t i, idx_t j) {
@@ -240,14 +240,14 @@ double kmeans1d(const float* x, size_t n, size_t nclusters, float* centroids) {
240
240
  Matrix<float> D(nclusters, n);
241
241
  Matrix<idx_t> T(nclusters, n);
242
242
 
243
- for (idx_t m = 0; m < n; m++) {
243
+ for (idx_t m = 0; m < static_cast<idx_t>(n); m++) {
244
244
  D.at(0, m) = CC(0, m);
245
245
  T.at(0, m) = 0;
246
246
  }
247
247
 
248
248
  std::vector<idx_t> indices(nclusters, 0);
249
249
 
250
- for (idx_t k = 1; k < nclusters; ++k) {
250
+ for (idx_t k = 1; k < static_cast<idx_t>(nclusters); ++k) {
251
251
  // we define C here
252
252
  auto C = [&D, &CC, &k](idx_t m, idx_t i) {
253
253
  if (i == 0) {
@@ -259,7 +259,7 @@ double kmeans1d(const float* x, size_t n, size_t nclusters, float* centroids) {
259
259
 
260
260
  std::vector<idx_t> argmins(n); // argmin of each row
261
261
  smawk(n, n, C, argmins.data());
262
- for (idx_t m = 0; m < argmins.size(); m++) {
262
+ for (size_t m = 0; m < argmins.size(); m++) {
263
263
  idx_t idx = argmins[m];
264
264
  D.at(k, m) = C(m, idx);
265
265
  T.at(k, m) = idx;
@@ -18,6 +18,9 @@
18
18
  #include <queue>
19
19
  #include <unordered_set>
20
20
 
21
+ #include <faiss/impl/FaissAssert.h>
22
+
23
+ #include <faiss/impl/simd_dispatch.h>
21
24
  #include <faiss/utils/distances.h>
22
25
 
23
26
  namespace faiss {
@@ -38,7 +41,7 @@ struct Comb {
38
41
  std::vector<uint64_t> tab; // Pascal's triangle
39
42
  int nmax;
40
43
 
41
- explicit Comb(int nmax) : nmax(nmax) {
44
+ explicit Comb(int nmax_in) : nmax(nmax_in) {
42
45
  tab.resize(nmax * nmax, 0);
43
46
  tab[0] = 1;
44
47
  for (int i = 1; i < nmax; i++) {
@@ -169,9 +172,9 @@ void repeats_decode_64(
169
172
 
170
173
  } // anonymous namespace
171
174
 
172
- Repeats::Repeats(int dim, const float* c) : dim(dim) {
175
+ Repeats::Repeats(int dim_in, const float* c) : dim(dim_in) {
173
176
  for (int i = 0; i < dim; i++) {
174
- int j = 0;
177
+ size_t j = 0;
175
178
  for (;;) {
176
179
  if (j == repeats.size()) {
177
180
  repeats.push_back(Repeat{c[i], 1});
@@ -189,7 +192,7 @@ Repeats::Repeats(int dim, const float* c) : dim(dim) {
189
192
  uint64_t Repeats::count() const {
190
193
  uint64_t accu = 1;
191
194
  int remain = dim;
192
- for (int i = 0; i < repeats.size(); i++) {
195
+ for (size_t i = 0; i < repeats.size(); i++) {
193
196
  accu *= comb(remain, repeats[i].n);
194
197
  remain -= repeats[i].n;
195
198
  }
@@ -272,7 +275,7 @@ void EnumeratedVectors::encode_multi(size_t n, const float* c, uint64_t* codes)
272
275
  #pragma omp parallel if (n > 1000)
273
276
  {
274
277
  #pragma omp for
275
- for (int i = 0; i < n; i++) {
278
+ for (int64_t i = 0; i < static_cast<int64_t>(n); i++) {
276
279
  codes[i] = encode(c + i * dim);
277
280
  }
278
281
  }
@@ -283,7 +286,7 @@ void EnumeratedVectors::decode_multi(size_t n, const uint64_t* codes, float* c)
283
286
  #pragma omp parallel if (n > 1000)
284
287
  {
285
288
  #pragma omp for
286
- for (int i = 0; i < n; i++) {
289
+ for (int64_t i = 0; i < static_cast<int64_t>(n); i++) {
287
290
  decode(codes[i], c + i * dim);
288
291
  }
289
292
  }
@@ -302,25 +305,33 @@ void EnumeratedVectors::find_nn(
302
305
  }
303
306
 
304
307
  std::vector<float> c(dim);
305
- for (size_t i = 0; i < nc; i++) {
306
- uint64_t code = codes[nc];
307
- decode(code, c.data());
308
- for (size_t j = 0; j < nq; j++) {
309
- const float* x = xq + j * dim;
310
- float dis = fvec_inner_product(x, c.data(), dim);
311
- if (dis > distances[j]) {
312
- distances[j] = dis;
313
- labels[j] = i;
308
+ with_simd_level([&]<SIMDLevel SL>() {
309
+ for (size_t i = 0; i < nc; i++) {
310
+ uint64_t code = codes[nc];
311
+ decode(code, c.data());
312
+ for (size_t j = 0; j < nq; j++) {
313
+ const float* x = xq + j * dim;
314
+ float dis = fvec_inner_product<SL>(x, c.data(), dim);
315
+ if (dis > distances[j]) {
316
+ distances[j] = dis;
317
+ labels[j] = i;
318
+ }
314
319
  }
315
320
  }
316
- }
321
+ });
317
322
  }
318
323
 
319
324
  /**********************************************************
320
325
  * ZnSphereSearch
321
326
  **********************************************************/
322
327
 
323
- ZnSphereSearch::ZnSphereSearch(int dim, int r2) : dimS(dim), r2(r2) {
328
+ ZnSphereSearch::ZnSphereSearch(int dim, int r2_in) : dimS(dim), r2(r2_in) {
329
+ FAISS_THROW_IF_NOT_MSG(
330
+ dim > 0 && dim <= 64, "ZnSphereSearch: dim must be in [1, 64]");
331
+ FAISS_THROW_IF_NOT_MSG(
332
+ r2_in >= 0 && r2_in <= 512,
333
+ "ZnSphereSearch: r2 must be in [0, 512] to avoid"
334
+ " excessive computation in sum_of_sq");
324
335
  voc = sum_of_sq(r2, int(ceil(sqrt(r2)) + 1), dim);
325
336
  natom = voc.size() / dim;
326
337
  }
@@ -355,13 +366,15 @@ float ZnSphereSearch::search(
355
366
  // find best
356
367
  int ibest = -1;
357
368
  float dpbest = -100;
358
- for (int i = 0; i < natom; i++) {
359
- float dp = fvec_inner_product(voc.data() + i * dim, xperm, dim);
360
- if (dp > dpbest) {
361
- dpbest = dp;
362
- ibest = i;
369
+ with_simd_level([&]<SIMDLevel SL>() {
370
+ for (int i = 0; i < natom; i++) {
371
+ float dp = fvec_inner_product<SL>(voc.data() + i * dim, xperm, dim);
372
+ if (dp > dpbest) {
373
+ dpbest = dp;
374
+ ibest = i;
375
+ }
363
376
  }
364
- }
377
+ });
365
378
  // revert sort
366
379
  const float* cin = voc.data() + ibest * dim;
367
380
  for (int i = 0; i < dim; i++) {
@@ -391,8 +404,8 @@ void ZnSphereSearch::search_multi(
391
404
  * ZnSphereCodec
392
405
  **********************************************************/
393
406
 
394
- ZnSphereCodec::ZnSphereCodec(int dim, int r2)
395
- : ZnSphereSearch(dim, r2), EnumeratedVectors(dim) {
407
+ ZnSphereCodec::ZnSphereCodec(int dim_in, int r2_in)
408
+ : ZnSphereSearch(dim_in, r2_in), EnumeratedVectors(dim_in) {
396
409
  nv = 0;
397
410
  for (int i = 0; i < natom; i++) {
398
411
  Repeats repeats(dim, &voc[i * dim]);
@@ -484,16 +497,30 @@ void ZnSphereCodecRec::set_nv_cum(int ld, int r2t, int r2a, uint64_t cum) {
484
497
  all_nv_cum[(ld * (r2 + 1) + r2t) * (r2 + 1) + r2a] = cum;
485
498
  }
486
499
 
487
- ZnSphereCodecRec::ZnSphereCodecRec(int dim, int r2)
488
- : EnumeratedVectors(dim), r2(r2) {
500
+ ZnSphereCodecRec::ZnSphereCodecRec(int dim_in, int r2_in)
501
+ : EnumeratedVectors(dim_in), r2(r2_in) {
502
+ FAISS_THROW_IF_NOT_MSG(
503
+ dim_in > 0 && r2_in >= 0, "invalid ZnSphereCodecRec parameters");
489
504
  log2_dim = 0;
490
505
  while (dim > (1 << log2_dim)) {
491
506
  log2_dim++;
492
507
  }
493
- assert(dim == (1 << log2_dim) || !"dimension must be a power of 2");
508
+ assert(dim == (1 << log2_dim) && "dimension must be a power of 2");
509
+
510
+ // Validate allocation sizes to avoid null pointer dereference on
511
+ // allocation failure. The cumulative table has O(r2^2) entries.
512
+ size_t nv_size = (size_t)(log2_dim + 1) * (r2 + 1);
513
+ size_t nv_cum_size = nv_size * (r2 + 1);
514
+ FAISS_THROW_IF_NOT_MSG(
515
+ nv_cum_size / (r2 + 1) == nv_size,
516
+ "ZnSphereCodecRec: allocation size overflow");
517
+ // Cap at ~1GB worth of uint64_t entries
518
+ FAISS_THROW_IF_NOT_MSG(
519
+ nv_cum_size <= (size_t(1) << 27),
520
+ "ZnSphereCodecRec: r2 too large, would require excessive memory");
494
521
 
495
- all_nv.resize((log2_dim + 1) * (r2 + 1));
496
- all_nv_cum.resize((log2_dim + 1) * (r2 + 1) * (r2 + 1));
522
+ all_nv.resize(nv_size);
523
+ all_nv_cum.resize(nv_cum_size);
497
524
 
498
525
  for (int r2a = 0; r2a <= r2; r2a++) {
499
526
  int r = int(sqrt(r2a));
@@ -506,13 +533,13 @@ ZnSphereCodecRec::ZnSphereCodecRec(int dim, int r2)
506
533
 
507
534
  for (int ld = 1; ld <= log2_dim; ld++) {
508
535
  for (int r2sub = 0; r2sub <= r2; r2sub++) {
509
- uint64_t nv = 0;
536
+ uint64_t nv_acc = 0;
510
537
  for (int r2a = 0; r2a <= r2sub; r2a++) {
511
538
  int r2b = r2sub - r2a;
512
- set_nv_cum(ld, r2sub, r2a, nv);
513
- nv += get_nv(ld - 1, r2a) * get_nv(ld - 1, r2b);
539
+ set_nv_cum(ld, r2sub, r2a, nv_acc);
540
+ nv_acc += get_nv(ld - 1, r2a) * get_nv(ld - 1, r2b);
514
541
  }
515
- all_nv[ld * (r2 + 1) + r2sub] = nv;
542
+ all_nv[ld * (r2 + 1) + r2sub] = nv_acc;
516
543
  }
517
544
  }
518
545
  nv = get_nv(log2_dim, r2);
@@ -527,17 +554,31 @@ ZnSphereCodecRec::ZnSphereCodecRec(int dim, int r2)
527
554
  int cache_level = std::min(3, log2_dim - 1);
528
555
  decode_cache_ld = 0;
529
556
  assert(cache_level <= log2_dim);
557
+
530
558
  decode_cache.resize((r2 + 1));
531
559
 
560
+ // The decode cache stores total_cache_entries * dimsub floats.
561
+ // Cap at 2^27 total floats (~512 MB), aligned with the nv_cum
562
+ // memory cap above which also uses 2^27 entries. The entry count
563
+ // grows as the number of lattice points in dimension
564
+ // 2^cache_level, which is O(r2^(dim/2)) -- much faster than the
565
+ // O(r2^2) growth of nv_cum.
566
+ size_t total_cache_entries = 0;
567
+ int dimsub = (1 << cache_level);
568
+
532
569
  for (int r2sub = 0; r2sub <= r2; r2sub++) {
533
570
  int ld = cache_level;
534
571
  uint64_t nvi = get_nv(ld, r2sub);
572
+ total_cache_entries += nvi;
573
+ FAISS_THROW_IF_NOT_MSG(
574
+ total_cache_entries <= (size_t(1) << 27) / dimsub,
575
+ "ZnSphereCodecRec: r2 too large, decode cache "
576
+ "would require excessive memory");
535
577
  std::vector<float>& cache = decode_cache[r2sub];
536
- int dimsub = (1 << cache_level);
537
578
  cache.resize(nvi * dimsub);
538
579
  std::vector<float> c(dim);
539
580
  uint64_t code0 = get_nv_cum(cache_level + 1, r2, r2 - r2sub);
540
- for (int i = 0; i < nvi; i++) {
581
+ for (uint64_t i = 0; i < nvi; i++) {
541
582
  decode(i + code0, c.data());
542
583
  memcpy(&cache[i * dimsub],
543
584
  c.data() + dim - dimsub,
@@ -643,10 +684,10 @@ void ZnSphereCodecRec::decode(uint64_t code, float* c) const {
643
684
  }
644
685
 
645
686
  // if not use_rec, instantiate an arbitrary harmless znc_rec
646
- ZnSphereCodecAlt::ZnSphereCodecAlt(int dim, int r2)
647
- : ZnSphereCodec(dim, r2),
648
- use_rec((dim & (dim - 1)) == 0),
649
- znc_rec(use_rec ? dim : 8, use_rec ? r2 : 14) {}
687
+ ZnSphereCodecAlt::ZnSphereCodecAlt(int dim_in, int r2_in)
688
+ : ZnSphereCodec(dim_in, r2_in),
689
+ use_rec((dim_in & (dim_in - 1)) == 0),
690
+ znc_rec(use_rec ? dim_in : 8, use_rec ? r2_in : 14) {}
650
691
 
651
692
  uint64_t ZnSphereCodecAlt::encode(const float* x) const {
652
693
  if (!use_rec) {