usearch 2.21.4 → 2.25.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 (604) hide show
  1. package/README.md +65 -69
  2. package/binding.gyp +15 -37
  3. package/c/CMakeLists.txt +4 -5
  4. package/c/README.md +8 -8
  5. package/c/lib.cpp +32 -14
  6. package/c/test.c +124 -1
  7. package/c/usearch.h +24 -3
  8. package/cpp/CMakeLists.txt +4 -0
  9. package/cpp/README.md +5 -5
  10. package/cpp/bench.cpp +97 -116
  11. package/cpp/test.cpp +117 -20
  12. package/include/usearch/index.hpp +224 -48
  13. package/include/usearch/index_dense.hpp +105 -40
  14. package/include/usearch/index_plugins.hpp +1387 -204
  15. package/javascript/README.md +1 -1
  16. package/javascript/dist/cjs/usearch.d.ts +8 -3
  17. package/javascript/dist/cjs/usearch.js +12 -4
  18. package/javascript/dist/esm/usearch.d.ts +8 -3
  19. package/javascript/dist/esm/usearch.js +12 -4
  20. package/javascript/lib.cpp +17 -0
  21. package/javascript/usearch.test.js +117 -94
  22. package/javascript/usearch.ts +14 -6
  23. package/numkong/.clang-tidy +30 -0
  24. package/{simsimd → numkong}/.cmake-format.py +18 -0
  25. package/numkong/.editorconfig +12 -0
  26. package/numkong/.git-blame-ignore-revs +123 -0
  27. package/numkong/.mailmap +15 -0
  28. package/numkong/.spi.yml +11 -0
  29. package/numkong/.swift-format +14 -0
  30. package/numkong/CITATION.cff +81 -0
  31. package/numkong/CONTRIBUTING.md +500 -0
  32. package/numkong/Cargo.toml +54 -0
  33. package/numkong/MANIFEST.in +8 -0
  34. package/numkong/Package.swift +84 -0
  35. package/numkong/README.md +569 -0
  36. package/numkong/bench/README.md +217 -0
  37. package/numkong/bench/bench-browser.html +323 -0
  38. package/numkong/bench/bench.cpp +344 -0
  39. package/numkong/bench/bench.hpp +816 -0
  40. package/numkong/bench/bench.js +148 -0
  41. package/numkong/bench/bench.mjs +616 -0
  42. package/numkong/bench/bench_attention.cpp +113 -0
  43. package/numkong/bench/bench_cast.cpp +264 -0
  44. package/numkong/bench/bench_cross_amx.cpp +62 -0
  45. package/numkong/bench/bench_cross_arm.cpp +245 -0
  46. package/numkong/bench/bench_cross_blas.cpp +309 -0
  47. package/numkong/bench/bench_cross_loongarch.cpp +106 -0
  48. package/numkong/bench/bench_cross_power.cpp +84 -0
  49. package/numkong/bench/bench_cross_rvv.cpp +121 -0
  50. package/numkong/bench/bench_cross_serial.cpp +151 -0
  51. package/numkong/bench/bench_cross_sme.cpp +163 -0
  52. package/numkong/bench/bench_cross_wasm.cpp +142 -0
  53. package/numkong/bench/bench_cross_x86.cpp +455 -0
  54. package/numkong/bench/bench_curved.cpp +210 -0
  55. package/numkong/bench/bench_dot.cpp +315 -0
  56. package/numkong/bench/bench_each.cpp +503 -0
  57. package/numkong/bench/bench_geospatial.cpp +112 -0
  58. package/numkong/bench/bench_maxsim.cpp +154 -0
  59. package/numkong/bench/bench_mesh.cpp +148 -0
  60. package/numkong/bench/bench_probability.cpp +60 -0
  61. package/numkong/bench/bench_reduce.cpp +371 -0
  62. package/numkong/bench/bench_set.cpp +73 -0
  63. package/numkong/bench/bench_sparse.cpp +198 -0
  64. package/numkong/bench/bench_spatial.cpp +347 -0
  65. package/numkong/bench/bench_trigonometry.cpp +137 -0
  66. package/numkong/bench/swift/Bench.swift +506 -0
  67. package/numkong/binding.gyp +169 -0
  68. package/numkong/build.rs +484 -0
  69. package/numkong/c/dispatch.h +512 -0
  70. package/numkong/c/dispatch_bf16.c +447 -0
  71. package/numkong/c/dispatch_bf16c.c +52 -0
  72. package/numkong/c/dispatch_e2m3.c +296 -0
  73. package/numkong/c/dispatch_e3m2.c +284 -0
  74. package/numkong/c/dispatch_e4m3.c +318 -0
  75. package/numkong/c/dispatch_e5m2.c +316 -0
  76. package/numkong/c/dispatch_f16.c +452 -0
  77. package/numkong/c/dispatch_f16c.c +58 -0
  78. package/numkong/c/dispatch_f32.c +434 -0
  79. package/numkong/c/dispatch_f32c.c +99 -0
  80. package/numkong/c/dispatch_f64.c +348 -0
  81. package/numkong/c/dispatch_f64c.c +98 -0
  82. package/numkong/c/dispatch_i16.c +96 -0
  83. package/numkong/c/dispatch_i32.c +89 -0
  84. package/numkong/c/dispatch_i4.c +153 -0
  85. package/numkong/c/dispatch_i64.c +86 -0
  86. package/numkong/c/dispatch_i8.c +348 -0
  87. package/numkong/c/dispatch_other.c +348 -0
  88. package/numkong/c/dispatch_u1.c +193 -0
  89. package/numkong/c/dispatch_u16.c +124 -0
  90. package/numkong/c/dispatch_u32.c +118 -0
  91. package/numkong/c/dispatch_u4.c +153 -0
  92. package/numkong/c/dispatch_u64.c +102 -0
  93. package/numkong/c/dispatch_u8.c +364 -0
  94. package/numkong/c/numkong.c +940 -0
  95. package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
  96. package/numkong/cmake/nk_isa_probe.cmake +90 -0
  97. package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
  98. package/numkong/cmake/nk_math_lib.cmake +46 -0
  99. package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
  100. package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
  101. package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
  102. package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
  103. package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
  104. package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
  105. package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
  106. package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
  107. package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
  108. package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
  109. package/numkong/cmake/toolchain-wasi.cmake +77 -0
  110. package/numkong/cmake/toolchain-wasm.cmake +70 -0
  111. package/numkong/cmake/toolchain-wasm64.cmake +62 -0
  112. package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
  113. package/numkong/include/README.md +643 -0
  114. package/numkong/include/module.modulemap +129 -0
  115. package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
  116. package/numkong/include/numkong/attention/sme.h +2075 -0
  117. package/numkong/include/numkong/attention.h +49 -0
  118. package/numkong/include/numkong/capabilities.h +930 -0
  119. package/numkong/include/numkong/cast/README.md +262 -0
  120. package/numkong/include/numkong/cast/diamond.h +64 -0
  121. package/numkong/include/numkong/cast/haswell.h +823 -0
  122. package/numkong/include/numkong/cast/icelake.h +475 -0
  123. package/numkong/include/numkong/cast/loongsonasx.h +252 -0
  124. package/numkong/include/numkong/cast/neon.h +1174 -0
  125. package/numkong/include/numkong/cast/powervsx.h +449 -0
  126. package/numkong/include/numkong/cast/rvv.h +970 -0
  127. package/numkong/include/numkong/cast/sapphire.h +262 -0
  128. package/numkong/include/numkong/cast/serial.h +2336 -0
  129. package/numkong/include/numkong/cast/skylake.h +915 -0
  130. package/numkong/include/numkong/cast/v128relaxed.h +537 -0
  131. package/numkong/include/numkong/cast.h +254 -0
  132. package/numkong/include/numkong/cast.hpp +44 -0
  133. package/numkong/include/numkong/curved/README.md +223 -0
  134. package/numkong/include/numkong/curved/genoa.h +182 -0
  135. package/numkong/include/numkong/curved/haswell.h +276 -0
  136. package/numkong/include/numkong/curved/neon.h +329 -0
  137. package/numkong/include/numkong/curved/neonbfdot.h +211 -0
  138. package/numkong/include/numkong/curved/rvv.h +305 -0
  139. package/numkong/include/numkong/curved/serial.h +207 -0
  140. package/numkong/include/numkong/curved/skylake.h +457 -0
  141. package/numkong/include/numkong/curved/smef64.h +530 -0
  142. package/numkong/include/numkong/curved.h +513 -0
  143. package/numkong/include/numkong/curved.hpp +144 -0
  144. package/numkong/include/numkong/dot/README.md +442 -0
  145. package/numkong/include/numkong/dot/alder.h +563 -0
  146. package/numkong/include/numkong/dot/diamond.h +158 -0
  147. package/numkong/include/numkong/dot/genoa.h +289 -0
  148. package/numkong/include/numkong/dot/haswell.h +1723 -0
  149. package/numkong/include/numkong/dot/icelake.h +997 -0
  150. package/numkong/include/numkong/dot/loongsonasx.h +671 -0
  151. package/numkong/include/numkong/dot/neon.h +869 -0
  152. package/numkong/include/numkong/dot/neonbfdot.h +243 -0
  153. package/numkong/include/numkong/dot/neonfhm.h +358 -0
  154. package/numkong/include/numkong/dot/neonfp8.h +323 -0
  155. package/numkong/include/numkong/dot/neonsdot.h +622 -0
  156. package/numkong/include/numkong/dot/powervsx.h +752 -0
  157. package/numkong/include/numkong/dot/rvv.h +722 -0
  158. package/numkong/include/numkong/dot/rvvbb.h +72 -0
  159. package/numkong/include/numkong/dot/rvvbf16.h +123 -0
  160. package/numkong/include/numkong/dot/rvvhalf.h +129 -0
  161. package/numkong/include/numkong/dot/sapphire.h +141 -0
  162. package/numkong/include/numkong/dot/serial.h +874 -0
  163. package/numkong/include/numkong/dot/sierra.h +405 -0
  164. package/numkong/include/numkong/dot/skylake.h +1116 -0
  165. package/numkong/include/numkong/dot/sve.h +420 -0
  166. package/numkong/include/numkong/dot/svebfdot.h +75 -0
  167. package/numkong/include/numkong/dot/svehalf.h +168 -0
  168. package/numkong/include/numkong/dot/svesdot.h +90 -0
  169. package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
  170. package/numkong/include/numkong/dot.h +1136 -0
  171. package/numkong/include/numkong/dot.hpp +94 -0
  172. package/numkong/include/numkong/dots/README.md +496 -0
  173. package/numkong/include/numkong/dots/alder.h +117 -0
  174. package/numkong/include/numkong/dots/diamond.h +86 -0
  175. package/numkong/include/numkong/dots/genoa.h +100 -0
  176. package/numkong/include/numkong/dots/graniteamx.h +733 -0
  177. package/numkong/include/numkong/dots/haswell.h +310 -0
  178. package/numkong/include/numkong/dots/icelake.h +180 -0
  179. package/numkong/include/numkong/dots/loongsonasx.h +176 -0
  180. package/numkong/include/numkong/dots/neon.h +123 -0
  181. package/numkong/include/numkong/dots/neonbfdot.h +59 -0
  182. package/numkong/include/numkong/dots/neonfhm.h +96 -0
  183. package/numkong/include/numkong/dots/neonfp8.h +99 -0
  184. package/numkong/include/numkong/dots/neonsdot.h +144 -0
  185. package/numkong/include/numkong/dots/powervsx.h +194 -0
  186. package/numkong/include/numkong/dots/rvv.h +2593 -0
  187. package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
  188. package/numkong/include/numkong/dots/serial.h +2867 -0
  189. package/numkong/include/numkong/dots/sierra.h +100 -0
  190. package/numkong/include/numkong/dots/skylake.h +207 -0
  191. package/numkong/include/numkong/dots/sme.h +5041 -0
  192. package/numkong/include/numkong/dots/smebi32.h +477 -0
  193. package/numkong/include/numkong/dots/smef64.h +1328 -0
  194. package/numkong/include/numkong/dots/smehalf.h +47 -0
  195. package/numkong/include/numkong/dots/v128relaxed.h +317 -0
  196. package/numkong/include/numkong/dots.h +3110 -0
  197. package/numkong/include/numkong/dots.hpp +641 -0
  198. package/numkong/include/numkong/each/README.md +465 -0
  199. package/numkong/include/numkong/each/haswell.h +1658 -0
  200. package/numkong/include/numkong/each/icelake.h +272 -0
  201. package/numkong/include/numkong/each/neon.h +1138 -0
  202. package/numkong/include/numkong/each/neonbfdot.h +211 -0
  203. package/numkong/include/numkong/each/neonhalf.h +318 -0
  204. package/numkong/include/numkong/each/rvv.h +1121 -0
  205. package/numkong/include/numkong/each/sapphire.h +343 -0
  206. package/numkong/include/numkong/each/serial.h +282 -0
  207. package/numkong/include/numkong/each/skylake.h +1562 -0
  208. package/numkong/include/numkong/each/v128relaxed.h +562 -0
  209. package/numkong/include/numkong/each.h +2232 -0
  210. package/numkong/include/numkong/each.hpp +434 -0
  211. package/numkong/include/numkong/geospatial/README.md +147 -0
  212. package/numkong/include/numkong/geospatial/haswell.h +633 -0
  213. package/numkong/include/numkong/geospatial/neon.h +615 -0
  214. package/numkong/include/numkong/geospatial/rvv.h +701 -0
  215. package/numkong/include/numkong/geospatial/serial.h +309 -0
  216. package/numkong/include/numkong/geospatial/skylake.h +613 -0
  217. package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
  218. package/numkong/include/numkong/geospatial.h +453 -0
  219. package/numkong/include/numkong/geospatial.hpp +235 -0
  220. package/numkong/include/numkong/matrix.hpp +336 -0
  221. package/numkong/include/numkong/maxsim/README.md +187 -0
  222. package/numkong/include/numkong/maxsim/alder.h +511 -0
  223. package/numkong/include/numkong/maxsim/genoa.h +115 -0
  224. package/numkong/include/numkong/maxsim/haswell.h +553 -0
  225. package/numkong/include/numkong/maxsim/icelake.h +480 -0
  226. package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
  227. package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
  228. package/numkong/include/numkong/maxsim/serial.h +490 -0
  229. package/numkong/include/numkong/maxsim/sme.h +993 -0
  230. package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
  231. package/numkong/include/numkong/maxsim.h +571 -0
  232. package/numkong/include/numkong/maxsim.hpp +133 -0
  233. package/numkong/include/numkong/mesh/README.md +219 -0
  234. package/numkong/include/numkong/mesh/haswell.h +2013 -0
  235. package/numkong/include/numkong/mesh/neon.h +1821 -0
  236. package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
  237. package/numkong/include/numkong/mesh/rvv.h +936 -0
  238. package/numkong/include/numkong/mesh/serial.h +721 -0
  239. package/numkong/include/numkong/mesh/skylake.h +2344 -0
  240. package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
  241. package/numkong/include/numkong/mesh.h +666 -0
  242. package/numkong/include/numkong/mesh.hpp +701 -0
  243. package/numkong/include/numkong/numkong.h +78 -0
  244. package/numkong/include/numkong/numkong.hpp +58 -0
  245. package/numkong/include/numkong/probability/README.md +177 -0
  246. package/numkong/include/numkong/probability/haswell.h +267 -0
  247. package/numkong/include/numkong/probability/neon.h +255 -0
  248. package/numkong/include/numkong/probability/rvv.h +414 -0
  249. package/numkong/include/numkong/probability/serial.h +181 -0
  250. package/numkong/include/numkong/probability/skylake.h +324 -0
  251. package/numkong/include/numkong/probability.h +380 -0
  252. package/numkong/include/numkong/probability.hpp +120 -0
  253. package/numkong/include/numkong/random.h +50 -0
  254. package/numkong/include/numkong/random.hpp +285 -0
  255. package/numkong/include/numkong/reduce/README.md +552 -0
  256. package/numkong/include/numkong/reduce/alder.h +636 -0
  257. package/numkong/include/numkong/reduce/genoa.h +201 -0
  258. package/numkong/include/numkong/reduce/haswell.h +3785 -0
  259. package/numkong/include/numkong/reduce/icelake.h +549 -0
  260. package/numkong/include/numkong/reduce/neon.h +3980 -0
  261. package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
  262. package/numkong/include/numkong/reduce/neonfhm.h +293 -0
  263. package/numkong/include/numkong/reduce/neonsdot.h +357 -0
  264. package/numkong/include/numkong/reduce/rvv.h +3533 -0
  265. package/numkong/include/numkong/reduce/serial.h +753 -0
  266. package/numkong/include/numkong/reduce/sierra.h +338 -0
  267. package/numkong/include/numkong/reduce/skylake.h +3794 -0
  268. package/numkong/include/numkong/reduce/sve.h +52 -0
  269. package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
  270. package/numkong/include/numkong/reduce.h +1582 -0
  271. package/numkong/include/numkong/reduce.hpp +778 -0
  272. package/numkong/include/numkong/scalar/README.md +89 -0
  273. package/numkong/include/numkong/scalar/haswell.h +122 -0
  274. package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
  275. package/numkong/include/numkong/scalar/neon.h +122 -0
  276. package/numkong/include/numkong/scalar/neonhalf.h +70 -0
  277. package/numkong/include/numkong/scalar/powervsx.h +96 -0
  278. package/numkong/include/numkong/scalar/rvv.h +211 -0
  279. package/numkong/include/numkong/scalar/sapphire.h +74 -0
  280. package/numkong/include/numkong/scalar/serial.h +332 -0
  281. package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
  282. package/numkong/include/numkong/scalar.h +696 -0
  283. package/numkong/include/numkong/set/README.md +179 -0
  284. package/numkong/include/numkong/set/haswell.h +334 -0
  285. package/numkong/include/numkong/set/icelake.h +485 -0
  286. package/numkong/include/numkong/set/loongsonasx.h +181 -0
  287. package/numkong/include/numkong/set/neon.h +363 -0
  288. package/numkong/include/numkong/set/powervsx.h +326 -0
  289. package/numkong/include/numkong/set/rvv.h +226 -0
  290. package/numkong/include/numkong/set/rvvbb.h +117 -0
  291. package/numkong/include/numkong/set/serial.h +174 -0
  292. package/numkong/include/numkong/set/sve.h +187 -0
  293. package/numkong/include/numkong/set/v128relaxed.h +240 -0
  294. package/numkong/include/numkong/set.h +471 -0
  295. package/numkong/include/numkong/set.hpp +114 -0
  296. package/numkong/include/numkong/sets/README.md +149 -0
  297. package/numkong/include/numkong/sets/haswell.h +63 -0
  298. package/numkong/include/numkong/sets/icelake.h +66 -0
  299. package/numkong/include/numkong/sets/loongsonasx.h +52 -0
  300. package/numkong/include/numkong/sets/neon.h +61 -0
  301. package/numkong/include/numkong/sets/powervsx.h +65 -0
  302. package/numkong/include/numkong/sets/serial.h +43 -0
  303. package/numkong/include/numkong/sets/smebi32.h +1135 -0
  304. package/numkong/include/numkong/sets/v128relaxed.h +58 -0
  305. package/numkong/include/numkong/sets.h +382 -0
  306. package/numkong/include/numkong/sparse/README.md +156 -0
  307. package/numkong/include/numkong/sparse/icelake.h +463 -0
  308. package/numkong/include/numkong/sparse/neon.h +288 -0
  309. package/numkong/include/numkong/sparse/serial.h +117 -0
  310. package/numkong/include/numkong/sparse/sve2.h +504 -0
  311. package/numkong/include/numkong/sparse/turin.h +322 -0
  312. package/numkong/include/numkong/sparse.h +363 -0
  313. package/numkong/include/numkong/sparse.hpp +113 -0
  314. package/numkong/include/numkong/spatial/README.md +439 -0
  315. package/numkong/include/numkong/spatial/alder.h +604 -0
  316. package/numkong/include/numkong/spatial/diamond.h +240 -0
  317. package/numkong/include/numkong/spatial/genoa.h +222 -0
  318. package/numkong/include/numkong/spatial/haswell.h +979 -0
  319. package/numkong/include/numkong/spatial/icelake.h +1067 -0
  320. package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
  321. package/numkong/include/numkong/spatial/neon.h +846 -0
  322. package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
  323. package/numkong/include/numkong/spatial/neonfp8.h +258 -0
  324. package/numkong/include/numkong/spatial/neonsdot.h +429 -0
  325. package/numkong/include/numkong/spatial/powervsx.h +738 -0
  326. package/numkong/include/numkong/spatial/rvv.h +991 -0
  327. package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
  328. package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
  329. package/numkong/include/numkong/spatial/serial.h +347 -0
  330. package/numkong/include/numkong/spatial/sierra.h +516 -0
  331. package/numkong/include/numkong/spatial/skylake.h +605 -0
  332. package/numkong/include/numkong/spatial/sve.h +246 -0
  333. package/numkong/include/numkong/spatial/svebfdot.h +125 -0
  334. package/numkong/include/numkong/spatial/svehalf.h +136 -0
  335. package/numkong/include/numkong/spatial/svesdot.h +143 -0
  336. package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
  337. package/numkong/include/numkong/spatial.h +1681 -0
  338. package/numkong/include/numkong/spatial.hpp +183 -0
  339. package/numkong/include/numkong/spatials/README.md +580 -0
  340. package/numkong/include/numkong/spatials/alder.h +94 -0
  341. package/numkong/include/numkong/spatials/diamond.h +82 -0
  342. package/numkong/include/numkong/spatials/genoa.h +94 -0
  343. package/numkong/include/numkong/spatials/graniteamx.h +173 -0
  344. package/numkong/include/numkong/spatials/haswell.h +219 -0
  345. package/numkong/include/numkong/spatials/icelake.h +113 -0
  346. package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
  347. package/numkong/include/numkong/spatials/neon.h +109 -0
  348. package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
  349. package/numkong/include/numkong/spatials/neonfhm.h +92 -0
  350. package/numkong/include/numkong/spatials/neonfp8.h +111 -0
  351. package/numkong/include/numkong/spatials/neonsdot.h +143 -0
  352. package/numkong/include/numkong/spatials/powervsx.h +153 -0
  353. package/numkong/include/numkong/spatials/rvv.h +1976 -0
  354. package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
  355. package/numkong/include/numkong/spatials/serial.h +248 -0
  356. package/numkong/include/numkong/spatials/sierra.h +96 -0
  357. package/numkong/include/numkong/spatials/skylake.h +184 -0
  358. package/numkong/include/numkong/spatials/sme.h +1927 -0
  359. package/numkong/include/numkong/spatials/smef64.h +483 -0
  360. package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
  361. package/numkong/include/numkong/spatials.h +3374 -0
  362. package/numkong/include/numkong/spatials.hpp +509 -0
  363. package/numkong/include/numkong/tensor.hpp +1981 -0
  364. package/numkong/include/numkong/trigonometry/README.md +184 -0
  365. package/numkong/include/numkong/trigonometry/haswell.h +653 -0
  366. package/numkong/include/numkong/trigonometry/neon.h +638 -0
  367. package/numkong/include/numkong/trigonometry/rvv.h +700 -0
  368. package/numkong/include/numkong/trigonometry/serial.h +703 -0
  369. package/numkong/include/numkong/trigonometry/skylake.h +725 -0
  370. package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
  371. package/numkong/include/numkong/trigonometry.h +467 -0
  372. package/numkong/include/numkong/trigonometry.hpp +166 -0
  373. package/numkong/include/numkong/types.h +1695 -0
  374. package/numkong/include/numkong/types.hpp +6027 -0
  375. package/numkong/include/numkong/vector.hpp +766 -0
  376. package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
  377. package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
  378. package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
  379. package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
  380. package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
  381. package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
  382. package/numkong/javascript/README.md +254 -0
  383. package/numkong/javascript/node-gyp-build.d.ts +4 -0
  384. package/numkong/javascript/numkong-browser.ts +40 -0
  385. package/numkong/javascript/numkong-wasm.ts +750 -0
  386. package/numkong/javascript/numkong.c +712 -0
  387. package/numkong/javascript/numkong.ts +613 -0
  388. package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
  389. package/numkong/javascript/tsconfig-cjs.json +13 -0
  390. package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
  391. package/numkong/javascript/types.ts +784 -0
  392. package/numkong/numkong.gypi +104 -0
  393. package/numkong/package.json +108 -0
  394. package/numkong/probes/arm_neon.c +8 -0
  395. package/numkong/probes/arm_neon_bfdot.c +9 -0
  396. package/numkong/probes/arm_neon_fhm.c +9 -0
  397. package/numkong/probes/arm_neon_half.c +8 -0
  398. package/numkong/probes/arm_neon_sdot.c +9 -0
  399. package/numkong/probes/arm_neonfp8.c +9 -0
  400. package/numkong/probes/arm_sme.c +16 -0
  401. package/numkong/probes/arm_sme2.c +16 -0
  402. package/numkong/probes/arm_sme2p1.c +16 -0
  403. package/numkong/probes/arm_sme_bf16.c +16 -0
  404. package/numkong/probes/arm_sme_bi32.c +16 -0
  405. package/numkong/probes/arm_sme_f64.c +16 -0
  406. package/numkong/probes/arm_sme_fa64.c +14 -0
  407. package/numkong/probes/arm_sme_half.c +16 -0
  408. package/numkong/probes/arm_sme_lut2.c +15 -0
  409. package/numkong/probes/arm_sve.c +18 -0
  410. package/numkong/probes/arm_sve2.c +20 -0
  411. package/numkong/probes/arm_sve2p1.c +18 -0
  412. package/numkong/probes/arm_sve_bfdot.c +20 -0
  413. package/numkong/probes/arm_sve_half.c +18 -0
  414. package/numkong/probes/arm_sve_sdot.c +21 -0
  415. package/numkong/probes/loongarch_lasx.c +12 -0
  416. package/numkong/probes/power_vsx.c +12 -0
  417. package/numkong/probes/probe.js +127 -0
  418. package/numkong/probes/riscv_rvv.c +14 -0
  419. package/numkong/probes/riscv_rvv_bb.c +15 -0
  420. package/numkong/probes/riscv_rvv_bf16.c +17 -0
  421. package/numkong/probes/riscv_rvv_half.c +14 -0
  422. package/numkong/probes/wasm_v128relaxed.c +11 -0
  423. package/numkong/probes/x86_alder.c +17 -0
  424. package/numkong/probes/x86_diamond.c +17 -0
  425. package/numkong/probes/x86_genoa.c +17 -0
  426. package/numkong/probes/x86_graniteamx.c +19 -0
  427. package/numkong/probes/x86_haswell.c +11 -0
  428. package/numkong/probes/x86_icelake.c +17 -0
  429. package/numkong/probes/x86_sapphire.c +16 -0
  430. package/numkong/probes/x86_sapphireamx.c +18 -0
  431. package/numkong/probes/x86_sierra.c +17 -0
  432. package/numkong/probes/x86_skylake.c +15 -0
  433. package/numkong/probes/x86_turin.c +17 -0
  434. package/numkong/rust/README.md +698 -0
  435. package/numkong/rust/capabilities.rs +96 -0
  436. package/numkong/rust/cast.rs +314 -0
  437. package/numkong/rust/curved.rs +391 -0
  438. package/numkong/rust/each.rs +2721 -0
  439. package/numkong/rust/geospatial.rs +343 -0
  440. package/numkong/rust/matrix.rs +5424 -0
  441. package/numkong/rust/maxsim.rs +540 -0
  442. package/numkong/rust/mesh.rs +837 -0
  443. package/numkong/rust/numkong.rs +409 -0
  444. package/numkong/rust/probability.rs +272 -0
  445. package/numkong/rust/reduce.rs +1249 -0
  446. package/numkong/rust/set.rs +194 -0
  447. package/numkong/rust/sparse.rs +513 -0
  448. package/numkong/rust/spatial.rs +1815 -0
  449. package/numkong/rust/tensor.rs +7565 -0
  450. package/numkong/rust/types.rs +3666 -0
  451. package/numkong/rust/vector.rs +1899 -0
  452. package/numkong/rustfmt.toml +2 -0
  453. package/numkong/swift/Matrix.swift +1388 -0
  454. package/numkong/swift/MaxSim.swift +151 -0
  455. package/numkong/swift/NumKong.swift +283 -0
  456. package/numkong/swift/Numerics.swift +329 -0
  457. package/numkong/swift/README.md +433 -0
  458. package/numkong/swift/Scalar.swift +741 -0
  459. package/numkong/swift/Tensor.swift +209 -0
  460. package/numkong/test/README.md +315 -0
  461. package/numkong/test/playwright.config.ts +16 -0
  462. package/numkong/test/swift/Test.swift +534 -0
  463. package/numkong/test/test-browser-bundle-runner.mjs +36 -0
  464. package/numkong/test/test-browser-bundle.html +188 -0
  465. package/numkong/test/test-browser-runner.mjs +43 -0
  466. package/numkong/test/test-browser.html +305 -0
  467. package/numkong/test/test-dtypes.mjs +453 -0
  468. package/numkong/test/test-wasm.mjs +267 -0
  469. package/numkong/test/test.cpp +442 -0
  470. package/numkong/test/test.hpp +580 -0
  471. package/numkong/test/test.mjs +363 -0
  472. package/numkong/test/test_base.py +1041 -0
  473. package/numkong/test/test_cast.cpp +242 -0
  474. package/numkong/test/test_cross.hpp +551 -0
  475. package/numkong/test/test_cross.py +467 -0
  476. package/numkong/test/test_cross_amx.cpp +50 -0
  477. package/numkong/test/test_cross_arm.cpp +225 -0
  478. package/numkong/test/test_cross_blas.cpp +354 -0
  479. package/numkong/test/test_cross_loongarch.cpp +90 -0
  480. package/numkong/test/test_cross_power.cpp +73 -0
  481. package/numkong/test/test_cross_rvv.cpp +109 -0
  482. package/numkong/test/test_cross_serial.cpp +181 -0
  483. package/numkong/test/test_cross_sme.cpp +148 -0
  484. package/numkong/test/test_cross_wasm.cpp +141 -0
  485. package/numkong/test/test_cross_x86.cpp +442 -0
  486. package/numkong/test/test_curved.cpp +182 -0
  487. package/numkong/test/test_curved.py +207 -0
  488. package/numkong/test/test_dot.cpp +353 -0
  489. package/numkong/test/test_dot.py +296 -0
  490. package/numkong/test/test_each.cpp +437 -0
  491. package/numkong/test/test_each.py +756 -0
  492. package/numkong/test/test_geospatial.cpp +155 -0
  493. package/numkong/test/test_geospatial.py +241 -0
  494. package/numkong/test/test_maxsim.cpp +138 -0
  495. package/numkong/test/test_maxsim.py +209 -0
  496. package/numkong/test/test_mesh.cpp +203 -0
  497. package/numkong/test/test_mesh.py +394 -0
  498. package/numkong/test/test_probability.cpp +136 -0
  499. package/numkong/test/test_probability.py +166 -0
  500. package/numkong/test/test_reduce.cpp +563 -0
  501. package/numkong/test/test_reduce.py +781 -0
  502. package/numkong/test/test_set.cpp +151 -0
  503. package/numkong/test/test_set.py +120 -0
  504. package/numkong/test/test_similarities.py +579 -0
  505. package/numkong/test/test_sparse.cpp +121 -0
  506. package/numkong/test/test_sparse.py +118 -0
  507. package/numkong/test/test_spatial.cpp +518 -0
  508. package/numkong/test/test_spatial.py +269 -0
  509. package/numkong/test/test_tensor.cpp +884 -0
  510. package/numkong/test/test_tensor.py +1417 -0
  511. package/numkong/test/test_trigonometry.cpp +156 -0
  512. package/numkong/test/test_trigonometry.py +180 -0
  513. package/package.json +7 -8
  514. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  515. package/prebuilds/linux-arm64/usearch.node +0 -0
  516. package/prebuilds/linux-x64/usearch.node +0 -0
  517. package/fp16/CMakeLists.txt +0 -176
  518. package/fp16/LICENSE +0 -11
  519. package/fp16/README.md +0 -20
  520. package/fp16/bench/alt-element.cc +0 -89
  521. package/fp16/bench/from-alt-array.cc +0 -175
  522. package/fp16/bench/from-ieee-array.cc +0 -399
  523. package/fp16/bench/ieee-element.cc +0 -272
  524. package/fp16/bench/to-alt-array.cc +0 -91
  525. package/fp16/bench/to-ieee-array.cc +0 -303
  526. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  527. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  528. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  529. package/fp16/configure.py +0 -65
  530. package/fp16/confu.yaml +0 -8
  531. package/fp16/include/fp16/__init__.py +0 -0
  532. package/fp16/include/fp16/avx.py +0 -50
  533. package/fp16/include/fp16/avx2.py +0 -53
  534. package/fp16/include/fp16/bitcasts.h +0 -92
  535. package/fp16/include/fp16/fp16.h +0 -451
  536. package/fp16/include/fp16/psimd.h +0 -131
  537. package/fp16/include/fp16.h +0 -11
  538. package/fp16/jni/Android.mk +0 -6
  539. package/fp16/jni/Application.mk +0 -4
  540. package/fp16/test/alt-from-fp32-value.cc +0 -498
  541. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  542. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  543. package/fp16/test/alt-to-fp32-value.cc +0 -348
  544. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  545. package/fp16/test/bitcasts.cc +0 -56
  546. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  547. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  548. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  549. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  550. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  551. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  552. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  553. package/fp16/test/peachpy/stubs.py +0 -38
  554. package/fp16/test/tables.cc +0 -530
  555. package/fp16/test/tables.h +0 -13
  556. package/fp16/third-party/THHalf.h +0 -92
  557. package/fp16/third-party/eigen-half.h +0 -170
  558. package/fp16/third-party/float16-compressor.h +0 -80
  559. package/fp16/third-party/half.hpp +0 -2916
  560. package/fp16/third-party/npy-halffloat.h +0 -328
  561. package/simsimd/.git-blame-ignore-revs +0 -2
  562. package/simsimd/CONTRIBUTING.md +0 -321
  563. package/simsimd/Cargo.toml +0 -49
  564. package/simsimd/MANIFEST.in +0 -4
  565. package/simsimd/Package.swift +0 -28
  566. package/simsimd/README.md +0 -1493
  567. package/simsimd/binding.gyp +0 -35
  568. package/simsimd/build.rs +0 -70
  569. package/simsimd/c/lib.c +0 -374
  570. package/simsimd/include/module.modulemap +0 -4
  571. package/simsimd/include/simsimd/binary.h +0 -486
  572. package/simsimd/include/simsimd/curved.h +0 -1541
  573. package/simsimd/include/simsimd/dot.h +0 -1853
  574. package/simsimd/include/simsimd/elementwise.h +0 -2465
  575. package/simsimd/include/simsimd/geospatial.h +0 -43
  576. package/simsimd/include/simsimd/mesh.h +0 -69
  577. package/simsimd/include/simsimd/probability.h +0 -606
  578. package/simsimd/include/simsimd/simsimd.h +0 -2567
  579. package/simsimd/include/simsimd/sparse.h +0 -1384
  580. package/simsimd/include/simsimd/spatial.h +0 -2335
  581. package/simsimd/include/simsimd/types.h +0 -666
  582. package/simsimd/javascript/fallback.ts +0 -233
  583. package/simsimd/javascript/lib.c +0 -125
  584. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  585. package/simsimd/javascript/simsimd.ts +0 -179
  586. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  587. package/simsimd/package-lock.json +0 -1761
  588. package/simsimd/package.json +0 -61
  589. package/simsimd/rust/lib.rs +0 -1821
  590. package/simsimd/scripts/bench.cxx +0 -1170
  591. package/simsimd/scripts/bench.ipynb +0 -187
  592. package/simsimd/scripts/bench.js +0 -127
  593. package/simsimd/scripts/bench.rs +0 -876
  594. package/simsimd/scripts/bench_vectors.py +0 -734
  595. package/simsimd/scripts/bench_vectors_live.py +0 -213
  596. package/simsimd/scripts/test.c +0 -187
  597. package/simsimd/scripts/test.mjs +0 -220
  598. package/simsimd/scripts/test.py +0 -1505
  599. package/simsimd/swift/SimSIMD.swift +0 -149
  600. package/simsimd/swift/Test.swift +0 -128
  601. /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
  602. /package/{simsimd → numkong}/LICENSE +0 -0
  603. /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
  604. /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
package/c/test.c CHANGED
@@ -1,10 +1,91 @@
1
+ /**
2
+ * @file test.c
3
+ * @author Ash Vardanian
4
+ * @brief Unit tests for the pure-C ABI of USearch (`usearch.h`).
5
+ * @date June 25, 2023
6
+ *
7
+ * Exercises the lifecycle of `usearch_index_t` through the public C surface:
8
+ * index creation with every supported metric and scalar kind, `add` / `get` /
9
+ * `find` / `remove`, on-disk `save` / `load` / `view`, and error propagation
10
+ * via `usearch_error_t`. The harness is intentionally dependency-free so it
11
+ * can run in the same matrix as the C++ tests and on cross-compilation
12
+ * targets where only the C runtime is available.
13
+ *
14
+ * On startup we install a signal handler (see `install_crash_handlers`) that
15
+ * prints a native back-trace before re-raising, so CI logs pinpoint the
16
+ * faulting frame instead of stopping at a bare exit code.
17
+ */
1
18
  #include <errno.h>
2
- #include <stdio.h> // `remove`
19
+ #include <signal.h> // `signal`, `raise`, `SIGSEGV`
20
+ #include <stdio.h> // `remove`
3
21
  #include <stdlib.h>
22
+ #include <string.h> // `memset`
4
23
  #include <sys/stat.h>
5
24
 
25
+ /* Back-trace support for the C test harness. The `signal` API is standard C;
26
+ * the back-trace itself is taken via an OS-specific facility since C has no
27
+ * standard stack-introspection API. On Windows, `dbghelp.h` references types
28
+ * (e.g. `PSTR`) that are only defined after `windows.h`, so the two headers
29
+ * are separated by a blank line to keep clang-format from re-sorting them
30
+ * into a single alphabetized block. */
31
+ #if defined(_WIN32)
32
+ #include <windows.h>
33
+
34
+ #include <dbghelp.h>
35
+ #pragma comment(lib, "Dbghelp.lib")
36
+ #elif defined(__unix__) || defined(__APPLE__)
37
+ #include <execinfo.h>
38
+ #include <unistd.h>
39
+ #endif
40
+
6
41
  #include "usearch.h"
7
42
 
43
+ static void usearch_write_backtrace(int signal_number) {
44
+ fprintf(stderr, "\n[usearch] Fatal signal %d. Back-trace:\n", signal_number);
45
+ #if defined(_WIN32)
46
+ enum { backtrace_depth_limit = 64 };
47
+ void* backtrace_frames[backtrace_depth_limit];
48
+ USHORT backtrace_depth = CaptureStackBackTrace(0, backtrace_depth_limit, backtrace_frames, NULL);
49
+ HANDLE current_process = GetCurrentProcess();
50
+ SymInitialize(current_process, NULL, TRUE);
51
+
52
+ unsigned char symbol_info_buffer[sizeof(SYMBOL_INFO) + 256 * sizeof(char)];
53
+ SYMBOL_INFO* symbol_info = (SYMBOL_INFO*)symbol_info_buffer;
54
+ symbol_info->MaxNameLen = 255;
55
+ symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO);
56
+
57
+ for (USHORT frame_index = 0; frame_index < backtrace_depth; ++frame_index) {
58
+ if (SymFromAddr(current_process, (DWORD64)backtrace_frames[frame_index], 0, symbol_info))
59
+ fprintf(stderr, " #%2u %s + 0x%llx\n", (unsigned)frame_index, symbol_info->Name,
60
+ (unsigned long long)((DWORD64)backtrace_frames[frame_index] - symbol_info->Address));
61
+ else
62
+ fprintf(stderr, " #%2u %p\n", (unsigned)frame_index, backtrace_frames[frame_index]);
63
+ }
64
+ #elif defined(__unix__) || defined(__APPLE__)
65
+ enum { backtrace_depth_limit = 64 };
66
+ void* backtrace_frames[backtrace_depth_limit];
67
+ int backtrace_depth = backtrace(backtrace_frames, backtrace_depth_limit);
68
+ backtrace_symbols_fd(backtrace_frames, backtrace_depth, STDERR_FILENO);
69
+ #else
70
+ (void)signal_number;
71
+ fprintf(stderr, " <back-trace unavailable on this platform>\n");
72
+ #endif
73
+ fflush(stderr);
74
+ }
75
+
76
+ static void usearch_crash_handler(int signal_number) {
77
+ usearch_write_backtrace(signal_number);
78
+ /* Restore the default disposition and re-raise so the shell / CI sees the true exit status. */
79
+ signal(signal_number, SIG_DFL);
80
+ raise(signal_number);
81
+ }
82
+
83
+ static void install_crash_handlers(void) {
84
+ int const fatal_signals[] = {SIGSEGV, SIGABRT, SIGILL, SIGFPE};
85
+ for (unsigned signal_index = 0; signal_index < sizeof(fatal_signals) / sizeof(fatal_signals[0]); ++signal_index)
86
+ signal(fatal_signals[signal_index], &usearch_crash_handler);
87
+ }
88
+
8
89
  void expect(bool must_be_true, char const* message) {
9
90
  if (must_be_true)
10
91
  return;
@@ -367,7 +448,48 @@ void test_view(size_t const collection_size, size_t const dimensions) {
367
448
  printf("Test: View - PASSED\n");
368
449
  }
369
450
 
451
+ void test_mini_float_quantizations(size_t const collection_size, size_t const dimensions) {
452
+ printf("Test: Mini-float quantizations... %zu vectors, %zu dimensions\n", collection_size, dimensions);
453
+ usearch_scalar_kind_t kinds[] = {
454
+ usearch_scalar_e5m2_k,
455
+ usearch_scalar_e4m3_k,
456
+ usearch_scalar_e3m2_k,
457
+ usearch_scalar_e2m3_k,
458
+ };
459
+ float* data = create_vectors(collection_size, dimensions);
460
+ usearch_key_t* keys = (usearch_key_t*)malloc(collection_size * sizeof(usearch_key_t));
461
+ float* distances = (float*)malloc(collection_size * sizeof(float));
462
+ expect(keys && distances, "Failed to allocate memory");
463
+
464
+ for (size_t k = 0; k < sizeof(kinds) / sizeof(kinds[0]); ++k) {
465
+ usearch_error_t error = NULL;
466
+ usearch_init_options_t opts = create_options(dimensions);
467
+ opts.quantization = kinds[k];
468
+ usearch_index_t index = usearch_init(&opts, &error);
469
+ expect(!error, error);
470
+ usearch_reserve(index, collection_size, &error);
471
+ expect(!error, error);
472
+ for (size_t i = 0; i < collection_size; ++i) {
473
+ usearch_add(index, (usearch_key_t)i, data + i * dimensions, usearch_scalar_f32_k, &error);
474
+ expect(!error, error);
475
+ }
476
+ expect_eq(usearch_size(index, &error), collection_size, error);
477
+ for (size_t i = 0; i < collection_size; ++i) {
478
+ size_t found =
479
+ usearch_search(index, data + i * dimensions, usearch_scalar_f32_k, 1, keys, distances, &error);
480
+ expect(!error, error);
481
+ expect(found >= 1, "Vector not found");
482
+ }
483
+ usearch_free(index, &error);
484
+ }
485
+ free(data);
486
+ free(keys);
487
+ free(distances);
488
+ printf("Test: Mini-float quantizations - PASSED\n");
489
+ }
490
+
370
491
  int main(int argc, char const* argv[]) {
492
+ install_crash_handlers();
371
493
  printf("Running tests...\n");
372
494
  printf("USearch version: %s\n", usearch_version());
373
495
 
@@ -382,6 +504,7 @@ int main(int argc, char const* argv[]) {
382
504
  test_remove_vector(collection_sizes[index], dimensions[jdx]);
383
505
  test_save_load(collection_sizes[index], dimensions[jdx]);
384
506
  test_view(collection_sizes[index], dimensions[jdx]);
507
+ test_mini_float_quantizations(collection_sizes[index], dimensions[jdx]);
385
508
  }
386
509
  }
387
510
 
package/c/usearch.h CHANGED
@@ -53,12 +53,17 @@ USEARCH_EXPORT typedef enum usearch_metric_kind_t {
53
53
 
54
54
  USEARCH_EXPORT typedef enum usearch_scalar_kind_t {
55
55
  usearch_scalar_unknown_k = 0,
56
- usearch_scalar_f32_k = 1,
57
56
  usearch_scalar_f64_k = 2,
57
+ usearch_scalar_f32_k = 1,
58
+ usearch_scalar_bf16_k = 6,
58
59
  usearch_scalar_f16_k = 3,
60
+ usearch_scalar_e5m2_k = 7,
61
+ usearch_scalar_e4m3_k = 8,
62
+ usearch_scalar_e3m2_k = 11,
63
+ usearch_scalar_e2m3_k = 10,
59
64
  usearch_scalar_i8_k = 4,
65
+ usearch_scalar_u8_k = 9,
60
66
  usearch_scalar_b1_k = 5,
61
- usearch_scalar_bf16_k = 6,
62
67
  } usearch_scalar_kind_t;
63
68
 
64
69
  USEARCH_EXPORT typedef struct usearch_init_options_t {
@@ -109,12 +114,26 @@ USEARCH_EXPORT typedef struct usearch_init_options_t {
109
114
  bool multi;
110
115
  } usearch_init_options_t;
111
116
 
117
+ USEARCH_EXPORT typedef int (*usearch_filtered_search_callback_t)(usearch_key_t, void*);
118
+
112
119
  /**
113
120
  * @brief Retrieves the version of the library.
114
121
  * @return The version of the library.
115
122
  */
116
123
  USEARCH_EXPORT char const* usearch_version(void);
117
124
 
125
+ /**
126
+ * @brief Retrieves a list of hardware capabilities in this precompiled binary.
127
+ * @return A comma-separated string with names of CPU features.
128
+ */
129
+ USEARCH_EXPORT char const* usearch_hardware_acceleration_compiled(void);
130
+
131
+ /**
132
+ * @brief Retrieves a list of hardware capabilities supported by the current machine.
133
+ * @return A comma-separated string with names of CPU features.
134
+ */
135
+ USEARCH_EXPORT char const* usearch_hardware_acceleration_available(void);
136
+
118
137
  /**
119
138
  * @brief Initializes a new instance of the index.
120
139
  * @param options Pointer to the `usearch_init_options_t` structure containing initialization options.
@@ -391,7 +410,7 @@ USEARCH_EXPORT size_t usearch_search( //
391
410
  USEARCH_EXPORT size_t usearch_filtered_search( //
392
411
  usearch_index_t index, //
393
412
  void const* query_vector, usearch_scalar_kind_t query_kind, size_t count, //
394
- int (*filter)(usearch_key_t key, void* filter_state), void* filter_state, //
413
+ usearch_filtered_search_callback_t filter, void* filter_state, //
395
414
  usearch_key_t* keys, usearch_distance_t* distances, usearch_error_t* error);
396
415
 
397
416
  /**
@@ -480,6 +499,8 @@ USEARCH_EXPORT void usearch_exact_search( //
480
499
  */
481
500
  USEARCH_EXPORT void usearch_clear(usearch_index_t index, usearch_error_t* error);
482
501
 
502
+ extern int goFilteredSearchCallback(usearch_key_t, void*);
503
+
483
504
  #ifdef __cplusplus
484
505
  }
485
506
  #endif
@@ -7,6 +7,10 @@ if (USEARCH_BUILD_TEST_CPP)
7
7
 
8
8
  target_include_directories(test_cpp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../stringzilla/include)
9
9
 
10
+ # Export the dynamic symbol table so `backtrace_symbols` / `std::stacktrace`
11
+ # can resolve function names when the in-test crash handler fires.
12
+ set_target_properties(test_cpp PROPERTIES ENABLE_EXPORTS ON)
13
+
10
14
  if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
11
15
  target_compile_options(test_cpp PRIVATE -Wno-vla -Wno-unused-function -Wno-cast-function-type)
12
16
  endif ()
package/cpp/README.md CHANGED
@@ -6,7 +6,7 @@ To use in a C++ project, copy the `include/usearch/*` headers into your project.
6
6
  Alternatively, fetch it with CMake:
7
7
 
8
8
  ```cmake
9
- FetchContent_Declare(usearch GIT_REPOSITORY https://github.com/unum-cloud/usearch.git)
9
+ FetchContent_Declare(usearch GIT_REPOSITORY https://github.com/unum-cloud/USearch.git)
10
10
  FetchContent_MakeAvailable(usearch)
11
11
  ```
12
12
 
@@ -43,9 +43,9 @@ int main(int argc, char **argv) {
43
43
 
44
44
  Here we:
45
45
 
46
- - define a metric of kind [`metric_kind_t::l2sq_k`](https://unum-cloud.github.io/usearch/cpp/reference.html#_CPPv413metric_kind_t),
47
- - to be applied to [`scalar_kind_t::f32_k`](https://unum-cloud.github.io/usearch/cpp/reference.html#_CPPv413scalar_kind_t) floating-point vectors,
48
- - instantiate an [`index_dense_t`](https://unum-cloud.github.io/usearch/cpp/reference.html#_CPPv4I00EN4unum7usearch14index_dense_gtE) index.
46
+ - define a metric of kind [`metric_kind_t::l2sq_k`](https://unum-cloud.github.io/USearch/cpp/reference.html#_CPPv413metric_kind_t),
47
+ - to be applied to [`scalar_kind_t::f32_k`](https://unum-cloud.github.io/USearch/cpp/reference.html#_CPPv413scalar_kind_t) floating-point vectors,
48
+ - instantiate an [`index_dense_t`](https://unum-cloud.github.io/USearch/cpp/reference.html#_CPPv4I00EN4unum7usearch14index_dense_gtE) index.
49
49
 
50
50
  The `add` is thread-safe for concurrent index construction.
51
51
  It also has an overload for different vector types, casting them under the hood.
@@ -174,7 +174,7 @@ In its high-level interface, USearch supports a variety of metrics, including th
174
174
  - `metric_haversine_gt<scalar_t>` for "Haversine" or "Great Circle" distance between coordinates used in GIS applications.
175
175
  - `metric_divergence_gt<scalar_t>` for the "Jensen Shannon" similarity between probability distributions.
176
176
 
177
- In reality, for most common types, one of the [SimSIMD](https://github.com/ashvardanian/SimSIMD) backends will be triggered, providing hardware-acceleration for most common CPUs.
177
+ In reality, for most common types, one of the [NumKong](https://github.com/ashvardanian/numkong) backends will be triggered, providing hardware-acceleration for most common CPUs.
178
178
 
179
179
  If you need a different metric, you can implement it yourself and wrap it into a `metric_punned_t`, which is our alternative to the `std::function`.
180
180
  Unlike the `std::function`, it is a trivial type, which is important for performance.
package/cpp/bench.cpp CHANGED
@@ -26,16 +26,18 @@
26
26
 
27
27
  #include <sys/stat.h> // `stat`
28
28
 
29
- #include <algorithm>
30
29
  #include <csignal>
31
30
  #include <cstdio>
32
- #include <iostream> // `std::cerr`
33
- #include <numeric> // `std::iota`
34
- #include <stdexcept> // `std::invalid_argument`
35
- #include <string> // `std::to_string`
36
- #include <thread> // `std::thread::hardware_concurrency()`
37
- #include <variant> // `std::monostate`
38
- #include <vector>
31
+
32
+ #include <algorithm> // ?
33
+ #include <iostream> // `std::cerr`
34
+ #include <numeric> // `std::iota`
35
+ #include <stdexcept> // `std::invalid_argument`
36
+ #include <string> // `std::to_string`
37
+ #include <thread> // `std::thread::hardware_concurrency()`
38
+ #include <unordered_map> // `std::unordered_map`
39
+ #include <variant> // `std::monostate`
40
+ #include <vector> // `std::vector`
39
41
 
40
42
  #include <clipp.h> // Command Line Interface
41
43
  #if USEARCH_USE_OPENMP
@@ -112,9 +114,10 @@ struct alignas(32) persisted_matrix_gt {
112
114
  if (fstat(file_descriptor, &stat_vectors) == -1)
113
115
  throw std::invalid_argument("Couldn't obtain file stats");
114
116
  raw_length = stat_vectors.st_size;
115
- raw_handle = (std::uint8_t*)mmap(NULL, raw_length, PROT_READ, MAP_PRIVATE, file_descriptor, 0);
116
- if (raw_handle == nullptr)
117
+ auto* result = mmap(NULL, raw_length, PROT_READ, MAP_PRIVATE, file_descriptor, 0);
118
+ if (result == MAP_FAILED)
117
119
  throw std::invalid_argument("Couldn't memory-map the file");
120
+ raw_handle = (std::uint8_t*)result;
118
121
  std::memcpy(&rows, raw_handle, sizeof(rows));
119
122
  std::memcpy(&cols, raw_handle + sizeof(rows), sizeof(cols));
120
123
  scalars = (scalar_t*)(raw_handle + sizeof(rows) + sizeof(cols));
@@ -201,14 +204,20 @@ struct persisted_dataset_gt {
201
204
  for (std::size_t i = 0; i < ids_matrix.rows; ++i)
202
205
  vector_ids_[i] = static_cast<default_key_t>(*ids_matrix.row(i));
203
206
  }
207
+
208
+ // When custom IDs are loaded and self-search is active, populate
209
+ // neighborhoods_iota_ with the actual IDs so recall comparison works.
210
+ if (has_vector_ids() && !queries_.scalars && !neighborhoods_.scalars) {
211
+ for (std::size_t i = 0; i < neighborhoods_iota_.size(); ++i)
212
+ neighborhoods_iota_[i] = static_cast<compressed_slot_t>(vector_ids_[i]);
213
+ }
204
214
  }
205
215
 
206
216
  bool search_itself() const noexcept { return vectors_count() && !queries_.rows; }
207
217
  bool has_vector_ids() const noexcept { return !vector_ids_.empty(); }
208
218
 
209
219
  default_key_t vector_id(std::size_t i) const noexcept {
210
- return has_vector_ids() ? vector_ids_[i + vectors_to_skip_]
211
- : static_cast<default_key_t>(i + vectors_to_skip_);
220
+ return has_vector_ids() ? vector_ids_[i + vectors_to_skip_] : static_cast<default_key_t>(i + vectors_to_skip_);
212
221
  }
213
222
 
214
223
  std::size_t dimensions() const noexcept { return vectors_.cols; }
@@ -224,9 +233,7 @@ struct persisted_dataset_gt {
224
233
  std::size_t vectors_count() const noexcept {
225
234
  return vectors_to_take_ ? vectors_to_take_ : (vectors_.rows - vectors_to_skip_);
226
235
  }
227
- matrix_slice_gt<scalar_t const> vectors_view() const noexcept {
228
- return {vector(vectors_to_skip_), vectors_count(), dimensions()};
229
- }
236
+ matrix_slice_gt<scalar_t const> vectors_view() const noexcept { return {vector(0), vectors_count(), dimensions()}; }
230
237
  };
231
238
 
232
239
  template <typename scalar_at, typename vector_id_at> //
@@ -288,7 +295,7 @@ struct running_stats_printer_t {
288
295
  std::size_t count = progress.load();
289
296
  timestamp_t time = std::chrono::high_resolution_clock::now();
290
297
  std::size_t duration = std::chrono::duration_cast<std::chrono::nanoseconds>(time - start_time).count();
291
- float vectors_per_second = count * 1e9 / duration;
298
+ float vectors_per_second = static_cast<float>(count * 1e9 / duration);
292
299
  std::printf("\r\33[2K100 %% completed, %.0f vectors/s\n", vectors_per_second);
293
300
  }
294
301
 
@@ -314,7 +321,7 @@ struct running_stats_printer_t {
314
321
  timestamp_t time_new = std::chrono::high_resolution_clock::now();
315
322
  std::size_t duration =
316
323
  std::chrono::duration_cast<std::chrono::nanoseconds>(time_new - last_printed_time).count();
317
- float vectors_per_second = count_new * 1e9 / duration;
324
+ float vectors_per_second = static_cast<float>(count_new * 1e9 / duration);
318
325
 
319
326
  std::printf("\r%3.3f%% [%.*s%*s] %.0f vectors/s, finished %zu/%zu", percentage * 100.f, left_pad, bars_k,
320
327
  right_pad, "", vectors_per_second, progress, total);
@@ -377,9 +384,8 @@ void search_many( //
377
384
  }
378
385
 
379
386
  template <typename dataset_at, typename index_at> //
380
- static void single_shot(dataset_at& dataset, index_at& index, bool construct = true) {
387
+ static void single_shot(dataset_at& dataset, index_at& index, bool construct = true, bool bench_join = false) {
381
388
  using distance_t = typename index_at::distance_t;
382
- constexpr default_key_t missing_key = std::numeric_limits<default_key_t>::max();
383
389
 
384
390
  std::printf("\n");
385
391
  std::printf("------------\n");
@@ -391,6 +397,9 @@ static void single_shot(dataset_at& dataset, index_at& index, bool construct = t
391
397
  index_many(index, dataset.vectors_count(), ids.data(), dataset.vector(0), dataset.dimensions());
392
398
  }
393
399
 
400
+ std::size_t mem = index.memory_usage();
401
+ std::printf("Memory usage: %.2f GB\n", mem / (1024.0 * 1024.0 * 1024.0));
402
+
394
403
  // Perform search, evaluate speed
395
404
  std::vector<default_key_t> found_neighbors(dataset.queries_count() * dataset.neighborhood_size());
396
405
  std::vector<distance_t> found_distances(dataset.queries_count() * dataset.neighborhood_size());
@@ -409,40 +418,38 @@ static void single_shot(dataset_at& dataset, index_at& index, bool construct = t
409
418
  std::printf("Recall@1 %.2f %%\n", recall_at_1 * 100.f / dataset.queries_count());
410
419
  std::printf("Recall %.2f %%\n", recall_full * 100.f / dataset.queries_count());
411
420
 
412
- // Perform joins
413
- std::vector<default_key_t> man_to_woman(dataset.vectors_count());
414
- std::vector<default_key_t> woman_to_man(dataset.vectors_count());
415
- std::size_t join_attempts = 0;
416
- {
421
+ if (!bench_join) {
422
+ // Perform joins using maps to support non-contiguous IDs
423
+ std::unordered_map<default_key_t, default_key_t> man_to_woman;
424
+ std::unordered_map<default_key_t, default_key_t> woman_to_man;
425
+ std::size_t join_attempts = 0;
426
+
417
427
  index_at& men = index;
418
428
  index_at women = index.copy();
419
- std::fill(man_to_woman.begin(), man_to_woman.end(), missing_key);
420
- std::fill(woman_to_man.begin(), woman_to_man.end(), missing_key);
421
- {
422
- executor_default_t executor(index.limits().threads());
423
- running_stats_printer_t printer{1, "Join"};
424
- join_result_t result = join( //
425
- men, women, index_join_config_t{executor.size()}, //
426
- man_to_woman.data(), woman_to_man.data(), //
427
- executor, [&](std::size_t progress, std::size_t total) {
428
- if (progress % 1000 == 0)
429
- printer.print(progress, total);
430
- return true;
431
- });
432
- // Refresh once again to show 100% completion
433
- printer.print();
434
- join_attempts = result.visited_members;
435
- }
436
- }
437
- // Evaluate join quality
438
- std::size_t recall_join = 0, unmatched_count = 0;
439
- for (std::size_t i = 0; i != index.size(); ++i) {
440
- recall_join += man_to_woman[i] == static_cast<default_key_t>(i);
441
- unmatched_count += man_to_woman[i] == missing_key;
429
+
430
+ executor_default_t executor(index.limits().threads());
431
+ running_stats_printer_t printer{1, "Join"};
432
+ join_result_t result = join( //
433
+ men, women, index_join_config_t{executor.size()}, //
434
+ man_to_woman, woman_to_man, //
435
+ executor, [&](std::size_t progress, std::size_t total) {
436
+ if (progress % 1000 == 0)
437
+ printer.print(progress, total);
438
+ return true;
439
+ });
440
+ // Refresh once again to show 100% completion
441
+ printer.print();
442
+ join_attempts = result.visited_members;
443
+
444
+ // Evaluate join quality
445
+ std::size_t recall_join = 0;
446
+ for (auto const& [man, woman] : man_to_woman)
447
+ recall_join += (man == woman);
448
+ std::size_t unmatched_count = dataset.vectors_count() - man_to_woman.size();
449
+ std::printf("Recall Joins %.2f %%\n", recall_join * 100.f / index.size());
450
+ std::printf("Unmatched %.2f %% (%zu items)\n", unmatched_count * 100.f / index.size(), unmatched_count);
451
+ std::printf("Proposals %.2f / man (%zu total)\n", join_attempts * 1.f / index.size(), join_attempts);
442
452
  }
443
- std::printf("Recall Joins %.2f %%\n", recall_join * 100.f / index.size());
444
- std::printf("Unmatched %.2f %% (%zu items)\n", unmatched_count * 100.f / index.size(), unmatched_count);
445
- std::printf("Proposals %.2f / man (%zu total)\n", join_attempts * 1.f / index.size(), join_attempts);
446
453
 
447
454
  std::printf("------------\n");
448
455
  std::printf("\n");
@@ -473,7 +480,7 @@ void handler(int sig) {
473
480
  name = "<unknown>";
474
481
  }
475
482
  DWORD bytes_written;
476
- WriteFile(STDERR_FILENO, name, std::strlen(name), &bytes_written, NULL);
483
+ WriteFile(STDERR_FILENO, name, static_cast<DWORD>(std::strlen(name)), &bytes_written, NULL);
477
484
  WriteFile(STDERR_FILENO, "\n", 1, &bytes_written, NULL);
478
485
  }
479
486
  free(symbol);
@@ -508,49 +515,24 @@ struct args_t {
508
515
  bool help = false;
509
516
 
510
517
  bool big = false;
518
+ bool join = false;
519
+ bool view = false;
511
520
 
512
- bool quantize_bf16 = false;
513
- bool quantize_f16 = false;
514
- bool quantize_i8 = false;
515
- bool quantize_b1 = false;
516
-
517
- bool metric_ip = false;
518
- bool metric_l2 = false;
519
- bool metric_cos = false;
520
- bool metric_haversine = false;
521
- bool metric_divergence = false;
522
- bool metric_hamming = false;
523
- bool metric_tanimoto = false;
524
- bool metric_sorensen = false;
521
+ std::string dtype_str = "f32";
522
+ std::string metric_str = "ip";
525
523
 
526
524
  metric_kind_t metric() const noexcept {
527
- if (metric_l2)
528
- return metric_kind_t::l2sq_k;
529
- if (metric_cos)
530
- return metric_kind_t::cos_k;
531
- if (metric_haversine)
532
- return metric_kind_t::haversine_k;
533
- if (metric_divergence)
534
- return metric_kind_t::divergence_k;
535
- if (metric_hamming)
536
- return metric_kind_t::hamming_k;
537
- if (metric_tanimoto)
538
- return metric_kind_t::tanimoto_k;
539
- if (metric_sorensen)
540
- return metric_kind_t::sorensen_k;
541
- return metric_kind_t::ip_k;
525
+ auto parsed = metric_from_name(metric_str.c_str(), metric_str.size());
526
+ if (!parsed)
527
+ return metric_kind_t::ip_k;
528
+ return parsed.result;
542
529
  }
543
530
 
544
531
  scalar_kind_t quantization() const noexcept {
545
- if (quantize_bf16)
546
- return scalar_kind_t::bf16_k;
547
- if (quantize_f16)
548
- return scalar_kind_t::f16_k;
549
- if (quantize_i8)
550
- return scalar_kind_t::i8_k;
551
- if (quantize_b1)
552
- return scalar_kind_t::b1x8_k;
553
- return scalar_kind_t::f32_k;
532
+ auto parsed = scalar_kind_from_name(dtype_str.c_str(), dtype_str.size());
533
+ if (!parsed)
534
+ return scalar_kind_t::f32_k;
535
+ return parsed.result;
554
536
  }
555
537
  };
556
538
 
@@ -569,14 +551,16 @@ void run_punned(dataset_at& dataset, args_t const& args, index_dense_config_t co
569
551
  std::printf("-- Hardware acceleration: %s\n", index.metric().isa_name());
570
552
  std::printf("Will benchmark in-memory\n");
571
553
 
572
- single_shot(dataset, index, true);
554
+ single_shot(dataset, index, true, args.join);
573
555
  index.save(args.path_output.c_str());
574
556
 
557
+ if (!args.view)
558
+ return;
575
559
  std::printf("Will benchmark an on-disk view\n");
576
560
 
577
561
  index_at index_view = index.fork();
578
562
  index_view.view(args.path_output.c_str());
579
- single_shot(dataset, index_view, false);
563
+ single_shot(dataset, index_view, false, args.join);
580
564
  }
581
565
 
582
566
  template <typename index_at, typename dataset_at> //
@@ -586,14 +570,16 @@ void run_typed(dataset_at& dataset, args_t const& args, index_config_t config, i
586
570
  index.reserve(limits);
587
571
  std::printf("Will benchmark in-memory\n");
588
572
 
589
- single_shot(dataset, index, true);
573
+ single_shot(dataset, index, true, args.join);
590
574
  index.save(args.path_output.c_str());
591
575
 
576
+ if (!args.view)
577
+ return;
592
578
  std::printf("Will benchmark an on-disk view\n");
593
579
 
594
580
  index_at index_view = index.fork();
595
581
  index_view.view(args.path_output.c_str());
596
- single_shot(dataset, index_view, false);
582
+ single_shot(dataset, index_view, false, args.join);
597
583
  }
598
584
 
599
585
  template <typename dataset_scalar_at> void bench_with_args(args_t const& args) {
@@ -636,9 +622,9 @@ int main(int argc, char** argv) {
636
622
  auto args = args_t{};
637
623
  auto cli = ( //
638
624
  (option("--vectors") & value("path", args.path_vectors))
639
- .doc(".[fhbd]bin, .i8bin, .f32bin file path to construct the index"),
625
+ .doc(".[fhbd]bin, .i8bin, .u8bin, .f32bin file path to construct the index"),
640
626
  (option("--queries") & value("path", args.path_queries))
641
- .doc(".[fhbd]bin, .i8bin, .f32bin file path to query the index"),
627
+ .doc(".[fhbd]bin, .i8bin, .u8bin, .f32bin file path to query the index"),
642
628
  (option("--neighbors") & value("path", args.path_neighbors)).doc(".ibin, .i32bin file path with ground truth"),
643
629
  (option("--ids") & value("path", args.path_ids)).doc(".i32bin file path with vector IDs (optional)"),
644
630
  (option("-o", "--output") & value("path", args.path_output)).doc(".usearch output file path"),
@@ -649,20 +635,13 @@ int main(int argc, char** argv) {
649
635
  (option("--expansion-search") & value("integer", args.expansion_search)).doc("Affects search depth"),
650
636
  (option("--rows-skip") & value("integer", args.vectors_to_skip)).doc("Number of vectors to skip"),
651
637
  (option("--rows-take") & value("integer", args.vectors_to_take)).doc("Number of vectors to take"),
652
- ( //
653
- option("-bf16", "--bf16quant").set(args.quantize_bf16).doc("Enable `bf16_t` quantization") |
654
- option("-f16", "--f16quant").set(args.quantize_f16).doc("Enable `f16_t` quantization") |
655
- option("-i8", "--i8quant").set(args.quantize_i8).doc("Enable `i8_t` quantization") |
656
- option("-b1", "--b1quant").set(args.quantize_b1).doc("Enable `b1x8_t` quantization")),
657
- ( //
658
- option("--ip").set(args.metric_ip).doc("Choose Inner Product metric") |
659
- option("--l2sq").set(args.metric_l2).doc("Choose L2 Euclidean metric") |
660
- option("--cos").set(args.metric_cos).doc("Choose Angular metric") |
661
- option("--hamming").set(args.metric_hamming).doc("Choose Hamming metric") |
662
- option("--tanimoto").set(args.metric_tanimoto).doc("Choose Tanimoto metric") |
663
- option("--sorensen").set(args.metric_sorensen).doc("Choose Sorensen metric") |
664
- option("--haversine").set(args.metric_haversine).doc("Choose Haversine metric")),
665
- option("-h", "--help").set(args.help).doc("Print this help information on this tool and exit"));
638
+ (option("--dtype") & value("type", args.dtype_str))
639
+ .doc("Quantization type: f64, f32, bf16, f16, e5m2, e4m3, e3m2, e2m3, i8, u8, b1"),
640
+ (option("--metric") & value("name", args.metric_str))
641
+ .doc("Distance metric: ip, l2sq, cos, hamming, tanimoto, sorensen, haversine"),
642
+ option("-h", "--help").set(args.help).doc("Print this help information on this tool and exit"),
643
+ option("--join").set(args.join).doc("Also benchmark joins"),
644
+ option("--view").set(args.view).doc("Also benchmark on-disk view"));
666
645
 
667
646
  if (!parse(argc, argv, cli)) {
668
647
  std::cerr << make_man_page(cli, argv[0]);
@@ -678,10 +657,12 @@ int main(int argc, char** argv) {
678
657
  // to better estimate statistics between tasks batches, without having to recreate
679
658
  // the threads.
680
659
  omp_set_dynamic(true);
681
- omp_set_num_threads(args.threads);
660
+ omp_set_num_threads(static_cast<int>(args.threads));
682
661
  std::printf("- OpenMP threads: %d\n", omp_get_max_threads());
683
662
  #endif
684
663
 
664
+ std::printf("- Hardware acceleration compiled: %s\n", hardware_acceleration_compiled());
665
+ std::printf("- Hardware acceleration available: %s\n", hardware_acceleration_available());
685
666
  std::printf("- Dataset: \n");
686
667
  std::printf("-- Base vectors path: %s\n", args.path_vectors.c_str());
687
668
  std::printf("-- Query vectors path: %s\n", args.path_queries.c_str());
@@ -693,18 +674,18 @@ int main(int argc, char** argv) {
693
674
  return stack.find(needle, stack.size() - needle.size()) != std::string_view::npos;
694
675
  };
695
676
 
696
- if (ends_with(args.path_vectors, ".fbin"))
697
- bench_with_args<f32_t>(args);
698
- else if (ends_with(args.path_vectors, ".dbin"))
677
+ if (ends_with(args.path_vectors, ".dbin"))
699
678
  bench_with_args<f64_t>(args);
679
+ else if (ends_with(args.path_vectors, ".fbin") || ends_with(args.path_vectors, ".f32bin"))
680
+ bench_with_args<f32_t>(args);
700
681
  else if (ends_with(args.path_vectors, ".hbin"))
701
682
  bench_with_args<f16_t>(args);
702
- else if (ends_with(args.path_vectors, ".bbin"))
703
- bench_with_args<b1x8_t>(args);
704
683
  else if (ends_with(args.path_vectors, ".i8bin"))
705
684
  bench_with_args<i8_t>(args);
706
- else if (ends_with(args.path_vectors, ".f32bin"))
707
- bench_with_args<f32_t>(args);
685
+ else if (ends_with(args.path_vectors, ".u8bin"))
686
+ bench_with_args<u8_t>(args);
687
+ else if (ends_with(args.path_vectors, ".bbin"))
688
+ bench_with_args<b1x8_t>(args);
708
689
  else
709
690
  throw std::runtime_error("Unknown input file path");
710
691