usearch 2.21.3 → 2.25.0

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 (602) hide show
  1. package/README.md +24 -24
  2. package/binding.gyp +15 -37
  3. package/c/CMakeLists.txt +4 -5
  4. package/c/README.md +7 -7
  5. package/c/lib.cpp +32 -14
  6. package/c/test.c +83 -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 +235 -52
  13. package/include/usearch/index_dense.hpp +105 -40
  14. package/include/usearch/index_plugins.hpp +1387 -204
  15. package/javascript/dist/cjs/usearch.d.ts +8 -3
  16. package/javascript/dist/cjs/usearch.js +12 -4
  17. package/javascript/dist/esm/usearch.d.ts +8 -3
  18. package/javascript/dist/esm/usearch.js +12 -4
  19. package/javascript/lib.cpp +17 -0
  20. package/javascript/usearch.ts +14 -6
  21. package/numkong/.clang-tidy +30 -0
  22. package/{simsimd → numkong}/.cmake-format.py +18 -0
  23. package/numkong/.editorconfig +12 -0
  24. package/numkong/.git-blame-ignore-revs +123 -0
  25. package/numkong/.mailmap +15 -0
  26. package/numkong/.spi.yml +11 -0
  27. package/numkong/.swift-format +14 -0
  28. package/numkong/CITATION.cff +81 -0
  29. package/numkong/CONTRIBUTING.md +500 -0
  30. package/numkong/Cargo.toml +54 -0
  31. package/numkong/MANIFEST.in +8 -0
  32. package/numkong/Package.swift +84 -0
  33. package/numkong/README.md +569 -0
  34. package/numkong/bench/README.md +217 -0
  35. package/numkong/bench/bench-browser.html +323 -0
  36. package/numkong/bench/bench.cpp +344 -0
  37. package/numkong/bench/bench.hpp +816 -0
  38. package/numkong/bench/bench.js +148 -0
  39. package/numkong/bench/bench.mjs +616 -0
  40. package/numkong/bench/bench_attention.cpp +113 -0
  41. package/numkong/bench/bench_cast.cpp +264 -0
  42. package/numkong/bench/bench_cross_amx.cpp +62 -0
  43. package/numkong/bench/bench_cross_arm.cpp +245 -0
  44. package/numkong/bench/bench_cross_blas.cpp +309 -0
  45. package/numkong/bench/bench_cross_loongarch.cpp +106 -0
  46. package/numkong/bench/bench_cross_power.cpp +84 -0
  47. package/numkong/bench/bench_cross_rvv.cpp +121 -0
  48. package/numkong/bench/bench_cross_serial.cpp +151 -0
  49. package/numkong/bench/bench_cross_sme.cpp +163 -0
  50. package/numkong/bench/bench_cross_wasm.cpp +142 -0
  51. package/numkong/bench/bench_cross_x86.cpp +455 -0
  52. package/numkong/bench/bench_curved.cpp +210 -0
  53. package/numkong/bench/bench_dot.cpp +315 -0
  54. package/numkong/bench/bench_each.cpp +503 -0
  55. package/numkong/bench/bench_geospatial.cpp +112 -0
  56. package/numkong/bench/bench_maxsim.cpp +154 -0
  57. package/numkong/bench/bench_mesh.cpp +148 -0
  58. package/numkong/bench/bench_probability.cpp +60 -0
  59. package/numkong/bench/bench_reduce.cpp +371 -0
  60. package/numkong/bench/bench_set.cpp +73 -0
  61. package/numkong/bench/bench_sparse.cpp +198 -0
  62. package/numkong/bench/bench_spatial.cpp +347 -0
  63. package/numkong/bench/bench_trigonometry.cpp +137 -0
  64. package/numkong/bench/swift/Bench.swift +506 -0
  65. package/numkong/binding.gyp +169 -0
  66. package/numkong/build.rs +484 -0
  67. package/numkong/c/dispatch.h +512 -0
  68. package/numkong/c/dispatch_bf16.c +447 -0
  69. package/numkong/c/dispatch_bf16c.c +52 -0
  70. package/numkong/c/dispatch_e2m3.c +296 -0
  71. package/numkong/c/dispatch_e3m2.c +284 -0
  72. package/numkong/c/dispatch_e4m3.c +318 -0
  73. package/numkong/c/dispatch_e5m2.c +316 -0
  74. package/numkong/c/dispatch_f16.c +452 -0
  75. package/numkong/c/dispatch_f16c.c +58 -0
  76. package/numkong/c/dispatch_f32.c +434 -0
  77. package/numkong/c/dispatch_f32c.c +99 -0
  78. package/numkong/c/dispatch_f64.c +348 -0
  79. package/numkong/c/dispatch_f64c.c +98 -0
  80. package/numkong/c/dispatch_i16.c +96 -0
  81. package/numkong/c/dispatch_i32.c +89 -0
  82. package/numkong/c/dispatch_i4.c +153 -0
  83. package/numkong/c/dispatch_i64.c +86 -0
  84. package/numkong/c/dispatch_i8.c +348 -0
  85. package/numkong/c/dispatch_other.c +348 -0
  86. package/numkong/c/dispatch_u1.c +193 -0
  87. package/numkong/c/dispatch_u16.c +124 -0
  88. package/numkong/c/dispatch_u32.c +118 -0
  89. package/numkong/c/dispatch_u4.c +153 -0
  90. package/numkong/c/dispatch_u64.c +102 -0
  91. package/numkong/c/dispatch_u8.c +364 -0
  92. package/numkong/c/numkong.c +940 -0
  93. package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
  94. package/numkong/cmake/nk_isa_probe.cmake +90 -0
  95. package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
  96. package/numkong/cmake/nk_math_lib.cmake +46 -0
  97. package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
  98. package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
  99. package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
  100. package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
  101. package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
  102. package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
  103. package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
  104. package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
  105. package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
  106. package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
  107. package/numkong/cmake/toolchain-wasi.cmake +77 -0
  108. package/numkong/cmake/toolchain-wasm.cmake +70 -0
  109. package/numkong/cmake/toolchain-wasm64.cmake +62 -0
  110. package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
  111. package/numkong/include/README.md +643 -0
  112. package/numkong/include/module.modulemap +129 -0
  113. package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
  114. package/numkong/include/numkong/attention/sme.h +2075 -0
  115. package/numkong/include/numkong/attention.h +49 -0
  116. package/numkong/include/numkong/capabilities.h +930 -0
  117. package/numkong/include/numkong/cast/README.md +262 -0
  118. package/numkong/include/numkong/cast/diamond.h +64 -0
  119. package/numkong/include/numkong/cast/haswell.h +823 -0
  120. package/numkong/include/numkong/cast/icelake.h +475 -0
  121. package/numkong/include/numkong/cast/loongsonasx.h +252 -0
  122. package/numkong/include/numkong/cast/neon.h +1174 -0
  123. package/numkong/include/numkong/cast/powervsx.h +449 -0
  124. package/numkong/include/numkong/cast/rvv.h +970 -0
  125. package/numkong/include/numkong/cast/sapphire.h +262 -0
  126. package/numkong/include/numkong/cast/serial.h +2336 -0
  127. package/numkong/include/numkong/cast/skylake.h +915 -0
  128. package/numkong/include/numkong/cast/v128relaxed.h +537 -0
  129. package/numkong/include/numkong/cast.h +254 -0
  130. package/numkong/include/numkong/cast.hpp +44 -0
  131. package/numkong/include/numkong/curved/README.md +223 -0
  132. package/numkong/include/numkong/curved/genoa.h +182 -0
  133. package/numkong/include/numkong/curved/haswell.h +276 -0
  134. package/numkong/include/numkong/curved/neon.h +329 -0
  135. package/numkong/include/numkong/curved/neonbfdot.h +211 -0
  136. package/numkong/include/numkong/curved/rvv.h +305 -0
  137. package/numkong/include/numkong/curved/serial.h +207 -0
  138. package/numkong/include/numkong/curved/skylake.h +457 -0
  139. package/numkong/include/numkong/curved/smef64.h +530 -0
  140. package/numkong/include/numkong/curved.h +513 -0
  141. package/numkong/include/numkong/curved.hpp +144 -0
  142. package/numkong/include/numkong/dot/README.md +442 -0
  143. package/numkong/include/numkong/dot/alder.h +563 -0
  144. package/numkong/include/numkong/dot/diamond.h +158 -0
  145. package/numkong/include/numkong/dot/genoa.h +289 -0
  146. package/numkong/include/numkong/dot/haswell.h +1723 -0
  147. package/numkong/include/numkong/dot/icelake.h +997 -0
  148. package/numkong/include/numkong/dot/loongsonasx.h +671 -0
  149. package/numkong/include/numkong/dot/neon.h +869 -0
  150. package/numkong/include/numkong/dot/neonbfdot.h +243 -0
  151. package/numkong/include/numkong/dot/neonfhm.h +358 -0
  152. package/numkong/include/numkong/dot/neonfp8.h +323 -0
  153. package/numkong/include/numkong/dot/neonsdot.h +622 -0
  154. package/numkong/include/numkong/dot/powervsx.h +752 -0
  155. package/numkong/include/numkong/dot/rvv.h +722 -0
  156. package/numkong/include/numkong/dot/rvvbb.h +72 -0
  157. package/numkong/include/numkong/dot/rvvbf16.h +123 -0
  158. package/numkong/include/numkong/dot/rvvhalf.h +129 -0
  159. package/numkong/include/numkong/dot/sapphire.h +141 -0
  160. package/numkong/include/numkong/dot/serial.h +874 -0
  161. package/numkong/include/numkong/dot/sierra.h +405 -0
  162. package/numkong/include/numkong/dot/skylake.h +1116 -0
  163. package/numkong/include/numkong/dot/sve.h +420 -0
  164. package/numkong/include/numkong/dot/svebfdot.h +75 -0
  165. package/numkong/include/numkong/dot/svehalf.h +168 -0
  166. package/numkong/include/numkong/dot/svesdot.h +90 -0
  167. package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
  168. package/numkong/include/numkong/dot.h +1136 -0
  169. package/numkong/include/numkong/dot.hpp +94 -0
  170. package/numkong/include/numkong/dots/README.md +496 -0
  171. package/numkong/include/numkong/dots/alder.h +117 -0
  172. package/numkong/include/numkong/dots/diamond.h +86 -0
  173. package/numkong/include/numkong/dots/genoa.h +100 -0
  174. package/numkong/include/numkong/dots/graniteamx.h +733 -0
  175. package/numkong/include/numkong/dots/haswell.h +310 -0
  176. package/numkong/include/numkong/dots/icelake.h +180 -0
  177. package/numkong/include/numkong/dots/loongsonasx.h +176 -0
  178. package/numkong/include/numkong/dots/neon.h +123 -0
  179. package/numkong/include/numkong/dots/neonbfdot.h +59 -0
  180. package/numkong/include/numkong/dots/neonfhm.h +96 -0
  181. package/numkong/include/numkong/dots/neonfp8.h +99 -0
  182. package/numkong/include/numkong/dots/neonsdot.h +144 -0
  183. package/numkong/include/numkong/dots/powervsx.h +194 -0
  184. package/numkong/include/numkong/dots/rvv.h +2593 -0
  185. package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
  186. package/numkong/include/numkong/dots/serial.h +2867 -0
  187. package/numkong/include/numkong/dots/sierra.h +100 -0
  188. package/numkong/include/numkong/dots/skylake.h +207 -0
  189. package/numkong/include/numkong/dots/sme.h +5041 -0
  190. package/numkong/include/numkong/dots/smebi32.h +477 -0
  191. package/numkong/include/numkong/dots/smef64.h +1328 -0
  192. package/numkong/include/numkong/dots/smehalf.h +47 -0
  193. package/numkong/include/numkong/dots/v128relaxed.h +317 -0
  194. package/numkong/include/numkong/dots.h +3110 -0
  195. package/numkong/include/numkong/dots.hpp +641 -0
  196. package/numkong/include/numkong/each/README.md +465 -0
  197. package/numkong/include/numkong/each/haswell.h +1658 -0
  198. package/numkong/include/numkong/each/icelake.h +272 -0
  199. package/numkong/include/numkong/each/neon.h +1138 -0
  200. package/numkong/include/numkong/each/neonbfdot.h +211 -0
  201. package/numkong/include/numkong/each/neonhalf.h +318 -0
  202. package/numkong/include/numkong/each/rvv.h +1121 -0
  203. package/numkong/include/numkong/each/sapphire.h +343 -0
  204. package/numkong/include/numkong/each/serial.h +282 -0
  205. package/numkong/include/numkong/each/skylake.h +1562 -0
  206. package/numkong/include/numkong/each/v128relaxed.h +562 -0
  207. package/numkong/include/numkong/each.h +2232 -0
  208. package/numkong/include/numkong/each.hpp +434 -0
  209. package/numkong/include/numkong/geospatial/README.md +147 -0
  210. package/numkong/include/numkong/geospatial/haswell.h +633 -0
  211. package/numkong/include/numkong/geospatial/neon.h +615 -0
  212. package/numkong/include/numkong/geospatial/rvv.h +701 -0
  213. package/numkong/include/numkong/geospatial/serial.h +309 -0
  214. package/numkong/include/numkong/geospatial/skylake.h +613 -0
  215. package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
  216. package/numkong/include/numkong/geospatial.h +453 -0
  217. package/numkong/include/numkong/geospatial.hpp +235 -0
  218. package/numkong/include/numkong/matrix.hpp +336 -0
  219. package/numkong/include/numkong/maxsim/README.md +187 -0
  220. package/numkong/include/numkong/maxsim/alder.h +511 -0
  221. package/numkong/include/numkong/maxsim/genoa.h +115 -0
  222. package/numkong/include/numkong/maxsim/haswell.h +553 -0
  223. package/numkong/include/numkong/maxsim/icelake.h +480 -0
  224. package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
  225. package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
  226. package/numkong/include/numkong/maxsim/serial.h +490 -0
  227. package/numkong/include/numkong/maxsim/sme.h +993 -0
  228. package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
  229. package/numkong/include/numkong/maxsim.h +571 -0
  230. package/numkong/include/numkong/maxsim.hpp +133 -0
  231. package/numkong/include/numkong/mesh/README.md +219 -0
  232. package/numkong/include/numkong/mesh/haswell.h +2013 -0
  233. package/numkong/include/numkong/mesh/neon.h +1821 -0
  234. package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
  235. package/numkong/include/numkong/mesh/rvv.h +936 -0
  236. package/numkong/include/numkong/mesh/serial.h +721 -0
  237. package/numkong/include/numkong/mesh/skylake.h +2344 -0
  238. package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
  239. package/numkong/include/numkong/mesh.h +666 -0
  240. package/numkong/include/numkong/mesh.hpp +701 -0
  241. package/numkong/include/numkong/numkong.h +78 -0
  242. package/numkong/include/numkong/numkong.hpp +58 -0
  243. package/numkong/include/numkong/probability/README.md +177 -0
  244. package/numkong/include/numkong/probability/haswell.h +267 -0
  245. package/numkong/include/numkong/probability/neon.h +255 -0
  246. package/numkong/include/numkong/probability/rvv.h +414 -0
  247. package/numkong/include/numkong/probability/serial.h +181 -0
  248. package/numkong/include/numkong/probability/skylake.h +324 -0
  249. package/numkong/include/numkong/probability.h +380 -0
  250. package/numkong/include/numkong/probability.hpp +120 -0
  251. package/numkong/include/numkong/random.h +50 -0
  252. package/numkong/include/numkong/random.hpp +285 -0
  253. package/numkong/include/numkong/reduce/README.md +552 -0
  254. package/numkong/include/numkong/reduce/alder.h +636 -0
  255. package/numkong/include/numkong/reduce/genoa.h +201 -0
  256. package/numkong/include/numkong/reduce/haswell.h +3785 -0
  257. package/numkong/include/numkong/reduce/icelake.h +549 -0
  258. package/numkong/include/numkong/reduce/neon.h +3980 -0
  259. package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
  260. package/numkong/include/numkong/reduce/neonfhm.h +293 -0
  261. package/numkong/include/numkong/reduce/neonsdot.h +357 -0
  262. package/numkong/include/numkong/reduce/rvv.h +3533 -0
  263. package/numkong/include/numkong/reduce/serial.h +753 -0
  264. package/numkong/include/numkong/reduce/sierra.h +338 -0
  265. package/numkong/include/numkong/reduce/skylake.h +3794 -0
  266. package/numkong/include/numkong/reduce/sve.h +52 -0
  267. package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
  268. package/numkong/include/numkong/reduce.h +1582 -0
  269. package/numkong/include/numkong/reduce.hpp +778 -0
  270. package/numkong/include/numkong/scalar/README.md +89 -0
  271. package/numkong/include/numkong/scalar/haswell.h +122 -0
  272. package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
  273. package/numkong/include/numkong/scalar/neon.h +122 -0
  274. package/numkong/include/numkong/scalar/neonhalf.h +70 -0
  275. package/numkong/include/numkong/scalar/powervsx.h +96 -0
  276. package/numkong/include/numkong/scalar/rvv.h +211 -0
  277. package/numkong/include/numkong/scalar/sapphire.h +74 -0
  278. package/numkong/include/numkong/scalar/serial.h +332 -0
  279. package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
  280. package/numkong/include/numkong/scalar.h +696 -0
  281. package/numkong/include/numkong/set/README.md +179 -0
  282. package/numkong/include/numkong/set/haswell.h +334 -0
  283. package/numkong/include/numkong/set/icelake.h +485 -0
  284. package/numkong/include/numkong/set/loongsonasx.h +181 -0
  285. package/numkong/include/numkong/set/neon.h +363 -0
  286. package/numkong/include/numkong/set/powervsx.h +326 -0
  287. package/numkong/include/numkong/set/rvv.h +226 -0
  288. package/numkong/include/numkong/set/rvvbb.h +117 -0
  289. package/numkong/include/numkong/set/serial.h +174 -0
  290. package/numkong/include/numkong/set/sve.h +187 -0
  291. package/numkong/include/numkong/set/v128relaxed.h +240 -0
  292. package/numkong/include/numkong/set.h +471 -0
  293. package/numkong/include/numkong/set.hpp +114 -0
  294. package/numkong/include/numkong/sets/README.md +149 -0
  295. package/numkong/include/numkong/sets/haswell.h +63 -0
  296. package/numkong/include/numkong/sets/icelake.h +66 -0
  297. package/numkong/include/numkong/sets/loongsonasx.h +52 -0
  298. package/numkong/include/numkong/sets/neon.h +61 -0
  299. package/numkong/include/numkong/sets/powervsx.h +65 -0
  300. package/numkong/include/numkong/sets/serial.h +43 -0
  301. package/numkong/include/numkong/sets/smebi32.h +1135 -0
  302. package/numkong/include/numkong/sets/v128relaxed.h +58 -0
  303. package/numkong/include/numkong/sets.h +382 -0
  304. package/numkong/include/numkong/sparse/README.md +156 -0
  305. package/numkong/include/numkong/sparse/icelake.h +463 -0
  306. package/numkong/include/numkong/sparse/neon.h +288 -0
  307. package/numkong/include/numkong/sparse/serial.h +117 -0
  308. package/numkong/include/numkong/sparse/sve2.h +504 -0
  309. package/numkong/include/numkong/sparse/turin.h +322 -0
  310. package/numkong/include/numkong/sparse.h +363 -0
  311. package/numkong/include/numkong/sparse.hpp +113 -0
  312. package/numkong/include/numkong/spatial/README.md +439 -0
  313. package/numkong/include/numkong/spatial/alder.h +604 -0
  314. package/numkong/include/numkong/spatial/diamond.h +240 -0
  315. package/numkong/include/numkong/spatial/genoa.h +222 -0
  316. package/numkong/include/numkong/spatial/haswell.h +979 -0
  317. package/numkong/include/numkong/spatial/icelake.h +1067 -0
  318. package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
  319. package/numkong/include/numkong/spatial/neon.h +846 -0
  320. package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
  321. package/numkong/include/numkong/spatial/neonfp8.h +258 -0
  322. package/numkong/include/numkong/spatial/neonsdot.h +429 -0
  323. package/numkong/include/numkong/spatial/powervsx.h +738 -0
  324. package/numkong/include/numkong/spatial/rvv.h +991 -0
  325. package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
  326. package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
  327. package/numkong/include/numkong/spatial/serial.h +347 -0
  328. package/numkong/include/numkong/spatial/sierra.h +516 -0
  329. package/numkong/include/numkong/spatial/skylake.h +605 -0
  330. package/numkong/include/numkong/spatial/sve.h +246 -0
  331. package/numkong/include/numkong/spatial/svebfdot.h +125 -0
  332. package/numkong/include/numkong/spatial/svehalf.h +136 -0
  333. package/numkong/include/numkong/spatial/svesdot.h +143 -0
  334. package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
  335. package/numkong/include/numkong/spatial.h +1681 -0
  336. package/numkong/include/numkong/spatial.hpp +183 -0
  337. package/numkong/include/numkong/spatials/README.md +580 -0
  338. package/numkong/include/numkong/spatials/alder.h +94 -0
  339. package/numkong/include/numkong/spatials/diamond.h +82 -0
  340. package/numkong/include/numkong/spatials/genoa.h +94 -0
  341. package/numkong/include/numkong/spatials/graniteamx.h +173 -0
  342. package/numkong/include/numkong/spatials/haswell.h +219 -0
  343. package/numkong/include/numkong/spatials/icelake.h +113 -0
  344. package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
  345. package/numkong/include/numkong/spatials/neon.h +109 -0
  346. package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
  347. package/numkong/include/numkong/spatials/neonfhm.h +92 -0
  348. package/numkong/include/numkong/spatials/neonfp8.h +111 -0
  349. package/numkong/include/numkong/spatials/neonsdot.h +143 -0
  350. package/numkong/include/numkong/spatials/powervsx.h +153 -0
  351. package/numkong/include/numkong/spatials/rvv.h +1976 -0
  352. package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
  353. package/numkong/include/numkong/spatials/serial.h +248 -0
  354. package/numkong/include/numkong/spatials/sierra.h +96 -0
  355. package/numkong/include/numkong/spatials/skylake.h +184 -0
  356. package/numkong/include/numkong/spatials/sme.h +1927 -0
  357. package/numkong/include/numkong/spatials/smef64.h +483 -0
  358. package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
  359. package/numkong/include/numkong/spatials.h +3374 -0
  360. package/numkong/include/numkong/spatials.hpp +509 -0
  361. package/numkong/include/numkong/tensor.hpp +1981 -0
  362. package/numkong/include/numkong/trigonometry/README.md +184 -0
  363. package/numkong/include/numkong/trigonometry/haswell.h +653 -0
  364. package/numkong/include/numkong/trigonometry/neon.h +638 -0
  365. package/numkong/include/numkong/trigonometry/rvv.h +700 -0
  366. package/numkong/include/numkong/trigonometry/serial.h +703 -0
  367. package/numkong/include/numkong/trigonometry/skylake.h +725 -0
  368. package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
  369. package/numkong/include/numkong/trigonometry.h +467 -0
  370. package/numkong/include/numkong/trigonometry.hpp +166 -0
  371. package/numkong/include/numkong/types.h +1695 -0
  372. package/numkong/include/numkong/types.hpp +6027 -0
  373. package/numkong/include/numkong/vector.hpp +766 -0
  374. package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
  375. package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
  376. package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
  377. package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
  378. package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
  379. package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
  380. package/numkong/javascript/README.md +254 -0
  381. package/numkong/javascript/node-gyp-build.d.ts +4 -0
  382. package/numkong/javascript/numkong-browser.ts +40 -0
  383. package/numkong/javascript/numkong-wasm.ts +750 -0
  384. package/numkong/javascript/numkong.c +712 -0
  385. package/numkong/javascript/numkong.ts +613 -0
  386. package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
  387. package/numkong/javascript/tsconfig-cjs.json +13 -0
  388. package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
  389. package/numkong/javascript/types.ts +784 -0
  390. package/numkong/numkong.gypi +104 -0
  391. package/numkong/package.json +108 -0
  392. package/numkong/probes/arm_neon.c +8 -0
  393. package/numkong/probes/arm_neon_bfdot.c +9 -0
  394. package/numkong/probes/arm_neon_fhm.c +9 -0
  395. package/numkong/probes/arm_neon_half.c +8 -0
  396. package/numkong/probes/arm_neon_sdot.c +9 -0
  397. package/numkong/probes/arm_neonfp8.c +9 -0
  398. package/numkong/probes/arm_sme.c +16 -0
  399. package/numkong/probes/arm_sme2.c +16 -0
  400. package/numkong/probes/arm_sme2p1.c +16 -0
  401. package/numkong/probes/arm_sme_bf16.c +16 -0
  402. package/numkong/probes/arm_sme_bi32.c +16 -0
  403. package/numkong/probes/arm_sme_f64.c +16 -0
  404. package/numkong/probes/arm_sme_fa64.c +14 -0
  405. package/numkong/probes/arm_sme_half.c +16 -0
  406. package/numkong/probes/arm_sme_lut2.c +15 -0
  407. package/numkong/probes/arm_sve.c +18 -0
  408. package/numkong/probes/arm_sve2.c +20 -0
  409. package/numkong/probes/arm_sve2p1.c +18 -0
  410. package/numkong/probes/arm_sve_bfdot.c +20 -0
  411. package/numkong/probes/arm_sve_half.c +18 -0
  412. package/numkong/probes/arm_sve_sdot.c +21 -0
  413. package/numkong/probes/loongarch_lasx.c +12 -0
  414. package/numkong/probes/power_vsx.c +12 -0
  415. package/numkong/probes/probe.js +127 -0
  416. package/numkong/probes/riscv_rvv.c +14 -0
  417. package/numkong/probes/riscv_rvv_bb.c +15 -0
  418. package/numkong/probes/riscv_rvv_bf16.c +17 -0
  419. package/numkong/probes/riscv_rvv_half.c +14 -0
  420. package/numkong/probes/wasm_v128relaxed.c +11 -0
  421. package/numkong/probes/x86_alder.c +17 -0
  422. package/numkong/probes/x86_diamond.c +17 -0
  423. package/numkong/probes/x86_genoa.c +17 -0
  424. package/numkong/probes/x86_graniteamx.c +19 -0
  425. package/numkong/probes/x86_haswell.c +11 -0
  426. package/numkong/probes/x86_icelake.c +17 -0
  427. package/numkong/probes/x86_sapphire.c +16 -0
  428. package/numkong/probes/x86_sapphireamx.c +18 -0
  429. package/numkong/probes/x86_sierra.c +17 -0
  430. package/numkong/probes/x86_skylake.c +15 -0
  431. package/numkong/probes/x86_turin.c +17 -0
  432. package/numkong/rust/README.md +698 -0
  433. package/numkong/rust/capabilities.rs +96 -0
  434. package/numkong/rust/cast.rs +314 -0
  435. package/numkong/rust/curved.rs +391 -0
  436. package/numkong/rust/each.rs +2721 -0
  437. package/numkong/rust/geospatial.rs +343 -0
  438. package/numkong/rust/matrix.rs +5424 -0
  439. package/numkong/rust/maxsim.rs +540 -0
  440. package/numkong/rust/mesh.rs +837 -0
  441. package/numkong/rust/numkong.rs +409 -0
  442. package/numkong/rust/probability.rs +272 -0
  443. package/numkong/rust/reduce.rs +1249 -0
  444. package/numkong/rust/set.rs +194 -0
  445. package/numkong/rust/sparse.rs +513 -0
  446. package/numkong/rust/spatial.rs +1815 -0
  447. package/numkong/rust/tensor.rs +7565 -0
  448. package/numkong/rust/types.rs +3666 -0
  449. package/numkong/rust/vector.rs +1899 -0
  450. package/numkong/rustfmt.toml +2 -0
  451. package/numkong/swift/Matrix.swift +1388 -0
  452. package/numkong/swift/MaxSim.swift +151 -0
  453. package/numkong/swift/NumKong.swift +283 -0
  454. package/numkong/swift/Numerics.swift +329 -0
  455. package/numkong/swift/README.md +433 -0
  456. package/numkong/swift/Scalar.swift +741 -0
  457. package/numkong/swift/Tensor.swift +209 -0
  458. package/numkong/test/README.md +315 -0
  459. package/numkong/test/playwright.config.ts +16 -0
  460. package/numkong/test/swift/Test.swift +534 -0
  461. package/numkong/test/test-browser-bundle-runner.mjs +36 -0
  462. package/numkong/test/test-browser-bundle.html +188 -0
  463. package/numkong/test/test-browser-runner.mjs +43 -0
  464. package/numkong/test/test-browser.html +305 -0
  465. package/numkong/test/test-dtypes.mjs +453 -0
  466. package/numkong/test/test-wasm.mjs +267 -0
  467. package/numkong/test/test.cpp +442 -0
  468. package/numkong/test/test.hpp +580 -0
  469. package/numkong/test/test.mjs +363 -0
  470. package/numkong/test/test_base.py +1041 -0
  471. package/numkong/test/test_cast.cpp +242 -0
  472. package/numkong/test/test_cross.hpp +551 -0
  473. package/numkong/test/test_cross.py +467 -0
  474. package/numkong/test/test_cross_amx.cpp +50 -0
  475. package/numkong/test/test_cross_arm.cpp +225 -0
  476. package/numkong/test/test_cross_blas.cpp +354 -0
  477. package/numkong/test/test_cross_loongarch.cpp +90 -0
  478. package/numkong/test/test_cross_power.cpp +73 -0
  479. package/numkong/test/test_cross_rvv.cpp +109 -0
  480. package/numkong/test/test_cross_serial.cpp +181 -0
  481. package/numkong/test/test_cross_sme.cpp +148 -0
  482. package/numkong/test/test_cross_wasm.cpp +141 -0
  483. package/numkong/test/test_cross_x86.cpp +442 -0
  484. package/numkong/test/test_curved.cpp +182 -0
  485. package/numkong/test/test_curved.py +207 -0
  486. package/numkong/test/test_dot.cpp +353 -0
  487. package/numkong/test/test_dot.py +296 -0
  488. package/numkong/test/test_each.cpp +437 -0
  489. package/numkong/test/test_each.py +756 -0
  490. package/numkong/test/test_geospatial.cpp +155 -0
  491. package/numkong/test/test_geospatial.py +241 -0
  492. package/numkong/test/test_maxsim.cpp +138 -0
  493. package/numkong/test/test_maxsim.py +209 -0
  494. package/numkong/test/test_mesh.cpp +203 -0
  495. package/numkong/test/test_mesh.py +394 -0
  496. package/numkong/test/test_probability.cpp +136 -0
  497. package/numkong/test/test_probability.py +166 -0
  498. package/numkong/test/test_reduce.cpp +563 -0
  499. package/numkong/test/test_reduce.py +781 -0
  500. package/numkong/test/test_set.cpp +151 -0
  501. package/numkong/test/test_set.py +120 -0
  502. package/numkong/test/test_similarities.py +579 -0
  503. package/numkong/test/test_sparse.cpp +121 -0
  504. package/numkong/test/test_sparse.py +118 -0
  505. package/numkong/test/test_spatial.cpp +518 -0
  506. package/numkong/test/test_spatial.py +269 -0
  507. package/numkong/test/test_tensor.cpp +884 -0
  508. package/numkong/test/test_tensor.py +1417 -0
  509. package/numkong/test/test_trigonometry.cpp +156 -0
  510. package/numkong/test/test_trigonometry.py +180 -0
  511. package/package.json +7 -8
  512. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  513. package/prebuilds/linux-arm64/usearch.node +0 -0
  514. package/prebuilds/linux-x64/usearch.node +0 -0
  515. package/fp16/CMakeLists.txt +0 -176
  516. package/fp16/LICENSE +0 -11
  517. package/fp16/README.md +0 -20
  518. package/fp16/bench/alt-element.cc +0 -89
  519. package/fp16/bench/from-alt-array.cc +0 -175
  520. package/fp16/bench/from-ieee-array.cc +0 -399
  521. package/fp16/bench/ieee-element.cc +0 -272
  522. package/fp16/bench/to-alt-array.cc +0 -91
  523. package/fp16/bench/to-ieee-array.cc +0 -303
  524. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  525. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  526. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  527. package/fp16/configure.py +0 -65
  528. package/fp16/confu.yaml +0 -8
  529. package/fp16/include/fp16/__init__.py +0 -0
  530. package/fp16/include/fp16/avx.py +0 -50
  531. package/fp16/include/fp16/avx2.py +0 -53
  532. package/fp16/include/fp16/bitcasts.h +0 -92
  533. package/fp16/include/fp16/fp16.h +0 -451
  534. package/fp16/include/fp16/psimd.h +0 -131
  535. package/fp16/include/fp16.h +0 -11
  536. package/fp16/jni/Android.mk +0 -6
  537. package/fp16/jni/Application.mk +0 -4
  538. package/fp16/test/alt-from-fp32-value.cc +0 -498
  539. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  540. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  541. package/fp16/test/alt-to-fp32-value.cc +0 -348
  542. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  543. package/fp16/test/bitcasts.cc +0 -56
  544. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  545. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  546. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  547. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  548. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  549. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  550. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  551. package/fp16/test/peachpy/stubs.py +0 -38
  552. package/fp16/test/tables.cc +0 -530
  553. package/fp16/test/tables.h +0 -13
  554. package/fp16/third-party/THHalf.h +0 -92
  555. package/fp16/third-party/eigen-half.h +0 -170
  556. package/fp16/third-party/float16-compressor.h +0 -80
  557. package/fp16/third-party/half.hpp +0 -2916
  558. package/fp16/third-party/npy-halffloat.h +0 -328
  559. package/simsimd/.git-blame-ignore-revs +0 -2
  560. package/simsimd/CONTRIBUTING.md +0 -321
  561. package/simsimd/Cargo.toml +0 -49
  562. package/simsimd/MANIFEST.in +0 -4
  563. package/simsimd/Package.swift +0 -28
  564. package/simsimd/README.md +0 -1493
  565. package/simsimd/binding.gyp +0 -35
  566. package/simsimd/build.rs +0 -70
  567. package/simsimd/c/lib.c +0 -374
  568. package/simsimd/include/module.modulemap +0 -4
  569. package/simsimd/include/simsimd/binary.h +0 -486
  570. package/simsimd/include/simsimd/curved.h +0 -1541
  571. package/simsimd/include/simsimd/dot.h +0 -1853
  572. package/simsimd/include/simsimd/elementwise.h +0 -2465
  573. package/simsimd/include/simsimd/geospatial.h +0 -43
  574. package/simsimd/include/simsimd/mesh.h +0 -69
  575. package/simsimd/include/simsimd/probability.h +0 -606
  576. package/simsimd/include/simsimd/simsimd.h +0 -2567
  577. package/simsimd/include/simsimd/sparse.h +0 -1384
  578. package/simsimd/include/simsimd/spatial.h +0 -2335
  579. package/simsimd/include/simsimd/types.h +0 -666
  580. package/simsimd/javascript/fallback.ts +0 -233
  581. package/simsimd/javascript/lib.c +0 -125
  582. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  583. package/simsimd/javascript/simsimd.ts +0 -179
  584. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  585. package/simsimd/package-lock.json +0 -1761
  586. package/simsimd/package.json +0 -61
  587. package/simsimd/rust/lib.rs +0 -1821
  588. package/simsimd/scripts/bench.cxx +0 -1170
  589. package/simsimd/scripts/bench.ipynb +0 -187
  590. package/simsimd/scripts/bench.js +0 -127
  591. package/simsimd/scripts/bench.rs +0 -876
  592. package/simsimd/scripts/bench_vectors.py +0 -734
  593. package/simsimd/scripts/bench_vectors_live.py +0 -213
  594. package/simsimd/scripts/test.c +0 -187
  595. package/simsimd/scripts/test.mjs +0 -220
  596. package/simsimd/scripts/test.py +0 -1505
  597. package/simsimd/swift/SimSIMD.swift +0 -149
  598. package/simsimd/swift/Test.swift +0 -128
  599. /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
  600. /package/{simsimd → numkong}/LICENSE +0 -0
  601. /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
  602. /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
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
 
package/cpp/test.cpp CHANGED
@@ -12,14 +12,45 @@
12
12
  * - 128-bit `uuid_t` keys and `enum slot64_t : std::uint64_t` make most sense for
13
13
  * for database users, implementing portable, concurrent systems.
14
14
  */
15
+ #include <cassert> // `assert`
16
+ #include <cmath> // `std::abs`
17
+ #include <csignal> // `std::signal`, `SIGSEGV`, ...
18
+ #include <cstdio> // `std::fprintf`
19
+ #include <cstdlib> // `std::_Exit`
20
+
15
21
  #include <algorithm> // `std::shuffle`
16
- #include <cassert> // `assert`
17
- #include <cmath> // `std::abs`
18
22
  #include <random> // `std::default_random_engine`
19
23
  #include <stdexcept> // `std::terminate`
20
24
  #include <unordered_map> // `std::unordered_map`
21
25
  #include <vector> // `std::vector`
22
26
 
27
+ // Back-trace support. Prefer the C++23 `<stacktrace>` library when the
28
+ // toolchain + stdlib expose it (`__cpp_lib_stacktrace`); otherwise fall back
29
+ // to the OS-native facility so that unit-test crashes in CI log something
30
+ // useful beyond a bare exit code.
31
+ #if defined(__has_include)
32
+ #if __has_include(<stacktrace>)
33
+ #include <stacktrace>
34
+ #endif
35
+ #endif
36
+ #if defined(__cpp_lib_stacktrace) && __cpp_lib_stacktrace >= 202011L
37
+ #define USEARCH_HAS_STD_STACKTRACE 1
38
+ #else
39
+ #define USEARCH_HAS_STD_STACKTRACE 0
40
+ #if defined(_WIN32)
41
+ // `windows.h` must precede `dbghelp.h` — the latter uses `PSTR` and friends
42
+ // that are only defined after `windows.h`. The blank line keeps clang-format
43
+ // from re-sorting the two headers into a single alphabetized block.
44
+ #include <windows.h>
45
+
46
+ #include <dbghelp.h>
47
+ #pragma comment(lib, "Dbghelp.lib")
48
+ #else
49
+ #include <execinfo.h>
50
+ #include <unistd.h>
51
+ #endif
52
+ #endif
53
+
23
54
  #define SZ_USE_X86_AVX512 0 // Sanitizers hate AVX512
24
55
  #include <stringzilla/stringzilla.hpp> // Levenshtein distance implementation
25
56
 
@@ -54,7 +85,7 @@ void __expect_eq(value_at a, value_at b, char const* file, int line, char const*
54
85
  enum slot32_t : std::uint32_t {};
55
86
  template <> struct unum::usearch::hash_gt<slot32_t> : public unum::usearch::hash_gt<std::uint32_t> {};
56
87
  template <> struct unum::usearch::default_free_value_gt<slot32_t> {
57
- static slot32_t value() noexcept { return static_cast<slot32_t>(std::numeric_limits<std::uint32_t>::max()); }
88
+ static slot32_t value() noexcept { return static_cast<slot32_t>((std::numeric_limits<std::uint32_t>::max)()); }
58
89
  };
59
90
 
60
91
  /*
@@ -166,8 +197,8 @@ void test_uint40() {
166
197
  }
167
198
 
168
199
  // Test min and max functions
169
- expect_eq(uint40_t::min(), uint40_t(0u));
170
- expect_eq(uint40_t::max(), uint40_t(max_uint40_k));
200
+ expect_eq((uint40_t::min)(), uint40_t(0u));
201
+ expect_eq((uint40_t::max)(), uint40_t(max_uint40_k));
171
202
 
172
203
  // Test copy and move semantics
173
204
  for (std::uint64_t input_u64 : test_numbers) {
@@ -664,7 +695,7 @@ void test_cosine(std::size_t collection_size, std::size_t dimensions) {
664
695
  vector_of_vectors_t vector_of_vectors(collection_size);
665
696
  for (auto& vector : vector_of_vectors) {
666
697
  vector.resize(dimensions);
667
- std::generate(vector.begin(), vector.end(), [=] { return float(std::rand()) / float(INT_MAX); });
698
+ std::generate(vector.begin(), vector.end(), [=] { return float(std::rand()) / float(RAND_MAX); });
668
699
  }
669
700
 
670
701
  struct metric_t {
@@ -1127,20 +1158,20 @@ void test_filtered_search() {
1127
1158
  {
1128
1159
  auto predicate = [](index_dense_t::key_t key) { return key != 0; };
1129
1160
  auto results = index.filtered_search(vector_of_vectors[0].data(), 10, predicate);
1130
- expect_eq(10, results.size()); // ! Should not contain 0
1161
+ expect_eq(10u, results.size()); // ! Should not contain 0
1131
1162
  for (std::size_t i = 0; i != results.size(); ++i)
1132
1163
  expect(0 != results[i].member.key);
1133
1164
  }
1134
1165
  {
1135
1166
  auto predicate = [](index_dense_t::key_t) { return false; };
1136
1167
  auto results = index.filtered_search(vector_of_vectors[0].data(), 10, predicate);
1137
- expect_eq(0, results.size()); // ! Should not contain 0
1168
+ expect_eq(0u, results.size()); // ! Should not contain 0
1138
1169
  }
1139
1170
  {
1140
1171
  auto predicate = [](index_dense_t::key_t key) { return key == 10; };
1141
1172
  auto results = index.filtered_search(vector_of_vectors[0].data(), 10, predicate);
1142
- expect_eq(1, results.size()); // ! Should not contain 0
1143
- expect_eq(10, results[0].member.key);
1173
+ expect_eq(1u, results.size()); // ! Should not contain 0
1174
+ expect_eq(index_dense_t::key_t(10), results[0].member.key);
1144
1175
  }
1145
1176
  }
1146
1177
 
@@ -1179,13 +1210,73 @@ void test_isolate() {
1179
1210
  }
1180
1211
  }
1181
1212
 
1213
+ static void usearch_write_backtrace(int signal_number) {
1214
+ std::fprintf(stderr, "\n[usearch] Fatal signal %d. Back-trace:\n", signal_number);
1215
+ #if USEARCH_HAS_STD_STACKTRACE
1216
+ // C++23 `std::stacktrace` covers every platform the library can reach.
1217
+ auto const current_trace = std::stacktrace::current();
1218
+ std::size_t frame_index = 0;
1219
+ for (auto const& frame : current_trace) {
1220
+ std::fprintf(stderr, " #%2zu %s\n", frame_index, std::to_string(frame).c_str());
1221
+ ++frame_index;
1222
+ }
1223
+ #elif defined(_WIN32)
1224
+ // Fallback for MSVC stdlibs without `<stacktrace>`: DbgHelp API.
1225
+ constexpr USHORT backtrace_depth_limit = 64;
1226
+ void* backtrace_frames[backtrace_depth_limit];
1227
+ USHORT backtrace_depth = CaptureStackBackTrace(0, backtrace_depth_limit, backtrace_frames, nullptr);
1228
+ HANDLE current_process = GetCurrentProcess();
1229
+ SymInitialize(current_process, nullptr, TRUE);
1230
+
1231
+ unsigned char symbol_info_buffer[sizeof(SYMBOL_INFO) + 256 * sizeof(char)];
1232
+ SYMBOL_INFO* symbol_info = reinterpret_cast<SYMBOL_INFO*>(symbol_info_buffer);
1233
+ symbol_info->MaxNameLen = 255;
1234
+ symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO);
1235
+
1236
+ for (USHORT frame_index = 0; frame_index < backtrace_depth; ++frame_index) {
1237
+ if (SymFromAddr(current_process, reinterpret_cast<DWORD64>(backtrace_frames[frame_index]), 0, symbol_info))
1238
+ std::fprintf(stderr, " #%2u %s + 0x%llx\n", static_cast<unsigned>(frame_index), symbol_info->Name,
1239
+ static_cast<unsigned long long>(reinterpret_cast<DWORD64>(backtrace_frames[frame_index]) -
1240
+ symbol_info->Address));
1241
+ else
1242
+ std::fprintf(stderr, " #%2u %p\n", static_cast<unsigned>(frame_index), backtrace_frames[frame_index]);
1243
+ }
1244
+ #else
1245
+ // Fallback for POSIX stdlibs without `<stacktrace>`: `<execinfo.h>`.
1246
+ constexpr int backtrace_depth_limit = 64;
1247
+ void* backtrace_frames[backtrace_depth_limit];
1248
+ int const backtrace_depth = backtrace(backtrace_frames, backtrace_depth_limit);
1249
+ backtrace_symbols_fd(backtrace_frames, backtrace_depth, STDERR_FILENO);
1250
+ #endif
1251
+ std::fflush(stderr);
1252
+ }
1253
+
1254
+ static void usearch_crash_handler(int signal_number) {
1255
+ usearch_write_backtrace(signal_number);
1256
+ // Restore the default disposition and re-raise so the shell / CI sees the true exit status.
1257
+ std::signal(signal_number, SIG_DFL);
1258
+ std::raise(signal_number);
1259
+ }
1260
+
1261
+ static void install_crash_handlers() {
1262
+ int const fatal_signals[] = {SIGSEGV, SIGABRT, SIGILL, SIGFPE};
1263
+ for (int signal_number : fatal_signals)
1264
+ std::signal(signal_number, &usearch_crash_handler);
1265
+ }
1266
+
1182
1267
  int main(int, char**) {
1183
- test_uint40();
1184
- test_cosine<float, std::int64_t, uint40_t>(10, 10);
1268
+ install_crash_handlers();
1269
+
1270
+ std::printf("Hardware acceleration compiled: %s\n", hardware_acceleration_compiled());
1271
+ std::printf("Hardware acceleration available: %s\n", hardware_acceleration_available());
1185
1272
 
1186
1273
  // Non-default floating-point types may result in many compilation & rounding issues.
1187
- test_cosine<f16_t, std::int64_t, uint40_t>(10, 10);
1274
+ test_uint40();
1275
+ test_cosine<f32_t, std::int64_t, uint40_t>(10, 10);
1188
1276
  test_cosine<bf16_t, std::int64_t, uint40_t>(10, 10);
1277
+ test_cosine<f16_t, std::int64_t, uint40_t>(10, 10);
1278
+ test_cosine<e5m2_t, std::int64_t, uint40_t>(10, 10);
1279
+ test_cosine<e4m3_t, std::int64_t, uint40_t>(10, 10);
1189
1280
 
1190
1281
  // Test plugins, like K-Means clustering.
1191
1282
  {
@@ -1195,7 +1286,7 @@ int main(int, char**) {
1195
1286
  std::vector<float> vectors(vectors_count * dimensions), centroids(centroids_count * dimensions);
1196
1287
  matrix_slice_gt<float const> vectors_slice(vectors.data(), dimensions, vectors_count);
1197
1288
  matrix_slice_gt<float> centroids_slice(centroids.data(), dimensions, centroids_count);
1198
- std::generate(vectors.begin(), vectors.end(), [] { return float(std::rand()) / float(INT_MAX); });
1289
+ std::generate(vectors.begin(), vectors.end(), [] { return float(std::rand()) / float(RAND_MAX); });
1199
1290
  std::vector<std::size_t> assignments(vectors_count);
1200
1291
  std::vector<distance_punned_t> distances(vectors_count);
1201
1292
  auto clustering_result = clustering(vectors_slice, centroids_slice, {assignments.data(), assignments.size()},
@@ -1209,9 +1300,11 @@ int main(int, char**) {
1209
1300
  for (std::size_t dataset_count : {10, 100})
1210
1301
  for (std::size_t queries_count : {1, 10})
1211
1302
  for (std::size_t wanted_count : {1, 5}) {
1212
- test_exact_search<float>(dataset_count, queries_count, wanted_count);
1213
- test_exact_search<f16_t>(dataset_count, queries_count, wanted_count);
1303
+ test_exact_search<f32_t>(dataset_count, queries_count, wanted_count);
1214
1304
  test_exact_search<bf16_t>(dataset_count, queries_count, wanted_count);
1305
+ test_exact_search<f16_t>(dataset_count, queries_count, wanted_count);
1306
+ test_exact_search<e5m2_t>(dataset_count, queries_count, wanted_count);
1307
+ test_exact_search<e4m3_t>(dataset_count, queries_count, wanted_count);
1215
1308
  }
1216
1309
 
1217
1310
  // Make sure the initializers and the algorithms can work with inadequately small values.
@@ -1235,12 +1328,16 @@ int main(int, char**) {
1235
1328
  std::printf("Testing common cases\n");
1236
1329
  for (std::size_t collection_size : {10, 500})
1237
1330
  for (std::size_t dimensions : {97, 256}) {
1238
- std::printf("- Indexing %zu vectors with cos: <float, std::int64_t, slot32_t> \n", collection_size);
1239
- test_cosine<float, std::int64_t, slot32_t>(collection_size, dimensions);
1240
- std::printf("- Indexing %zu vectors with cos: <float, std::int64_t, uint40_t> \n", collection_size);
1241
- test_cosine<float, std::int64_t, uint40_t>(collection_size, dimensions);
1331
+ std::printf("- Indexing %zu vectors with cos: <f32_t, std::int64_t, slot32_t> \n", collection_size);
1332
+ test_cosine<f32_t, std::int64_t, slot32_t>(collection_size, dimensions);
1333
+ std::printf("- Indexing %zu vectors with cos: <f32_t, std::int64_t, uint40_t> \n", collection_size);
1334
+ test_cosine<f32_t, std::int64_t, uint40_t>(collection_size, dimensions);
1242
1335
  std::printf("- Indexing %zu vectors with cos: <bf16, std::int64_t, uint40_t> \n", collection_size);
1243
1336
  test_cosine<bf16_t, std::int64_t, uint40_t>(collection_size, dimensions);
1337
+ std::printf("- Indexing %zu vectors with cos: <e5m2, std::int64_t, uint40_t> \n", collection_size);
1338
+ test_cosine<e5m2_t, std::int64_t, uint40_t>(collection_size, dimensions);
1339
+ std::printf("- Indexing %zu vectors with cos: <e4m3, std::int64_t, uint40_t> \n", collection_size);
1340
+ test_cosine<e4m3_t, std::int64_t, uint40_t>(collection_size, dimensions);
1244
1341
  }
1245
1342
 
1246
1343
  // Test with binary vectors