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
@@ -0,0 +1,409 @@
1
+ //! # NumKong - Hardware-Accelerated Numerics
2
+ //!
3
+ //! Provides SIMD-accelerated distance metrics, elementwise operations, and tensor algebra
4
+ //! targeting ARM NEON/SVE/SME and x86 AVX2/AVX-512 backends.
5
+ //!
6
+ //! ## Modules
7
+ //!
8
+ //! - [`types`]: Mixed-precision scalar types (`f16`, `bf16`, FP8, packed integers) and [`FloatLike`] trait
9
+ //! - [`spatial`]: Dot products, angular (cosine), and Euclidean distances
10
+ //! - [`each`]: Elementwise operations and trigonometry
11
+ //! - [`reduce`]: Statistical reductions (moments, min/max)
12
+ //! - [`set`]: Binary set similarity (Hamming, Jaccard)
13
+ //! - [`probability`]: Probability divergences (KL, JS)
14
+ //! - [`curved`]: Curved metric spaces (Bilinear, Mahalanobis)
15
+ //! - [`mesh`]: Mesh alignment (Kabsch, Umeyama, RMSD)
16
+ //! - [`geospatial`]: Geospatial distances (Haversine, Vincenty)
17
+ //! - [`sparse`]: Sparse set operations
18
+ //! - [`cast`]: Type casting between scalar formats
19
+ //! - [`capabilities`]: Runtime SIMD feature detection
20
+ //! - [`matrix`]: Batch matrix operations (GEMM, packed spatial distances)
21
+ //! - [`tensor`]: N-dimensional tensors with elementwise/reduction operations
22
+ //!
23
+ //! ## Implemented operations include:
24
+ //!
25
+ //! * Euclidean (L2), inner product, and angular (cosine) spatial distances.
26
+ //! * Hamming and Jaccard binary distances.
27
+ //! * Kullback-Leibler divergence and Jensen-Shannon distance.
28
+ //! * Elementwise scale, sum, blend, and FMA operations.
29
+ //! * Trigonometric functions (sin, cos, atan).
30
+ //! * Type casting between all scalar formats.
31
+ //! * Matrix multiplication with pre-packing (GEMM).
32
+ //!
33
+ //! ## Example
34
+ //!
35
+ //! ```rust
36
+ //! use numkong::{Dot, Angular, Euclidean};
37
+ //!
38
+ //! let a = &[1.0_f32, 2.0, 3.0];
39
+ //! let b = &[4.0_f32, 5.0, 6.0];
40
+ //!
41
+ //! let dot_product = f32::dot(a, b);
42
+ //! let angular_dist = f32::angular(a, b);
43
+ //! let l2sq_dist = f32::sqeuclidean(a, b);
44
+ //!
45
+ //! // Enable AMX and other platform-specific SIMD features
46
+ //! numkong::capabilities::configure_thread();
47
+ //! ```
48
+ //!
49
+ //! ## Mixed Precision Support
50
+ //!
51
+ //! ```rust
52
+ //! use numkong::{Angular, f16, bf16};
53
+ //!
54
+ //! // Work with half-precision floats
55
+ //! let half_a: Vec<f16> = vec![1.0, 2.0, 3.0].iter().map(|&x| f16::from_f32(x)).collect();
56
+ //! let half_b: Vec<f16> = vec![4.0, 5.0, 6.0].iter().map(|&x| f16::from_f32(x)).collect();
57
+ //! let half_angular_dist = f16::angular(&half_a, &half_b);
58
+ //!
59
+ //! // Work with brain floats
60
+ //! let brain_a: Vec<bf16> = vec![1.0, 2.0, 3.0].iter().map(|&x| bf16::from_f32(x)).collect();
61
+ //! let brain_b: Vec<bf16> = vec![4.0, 5.0, 6.0].iter().map(|&x| bf16::from_f32(x)).collect();
62
+ //! let brain_angular_dist = bf16::angular(&brain_a, &brain_b);
63
+ //!
64
+ //! // Direct bit manipulation
65
+ //! let half = f16::from_f32(3.14);
66
+ //! let bits = half.0; // Access raw u16 representation
67
+ //! let reconstructed = f16(bits);
68
+ //! ```
69
+ //!
70
+ //! ## Traits
71
+ //!
72
+ //! The `SpatialSimilarity` trait (combining `Dot`, `Angular`, `Euclidean`) covers:
73
+ //!
74
+ //! - `dot(a, b)`: Computes dot product between two slices.
75
+ //! - `angular(a, b)` / `cosine(a, b)`: Computes angular distance (1 − cosine similarity).
76
+ //! - `sqeuclidean(a, b)`: Computes squared Euclidean distance.
77
+ //! - `euclidean(a, b)`: Computes Euclidean distance.
78
+ //!
79
+ //! The `BinarySimilarity` trait (combining `Hamming`, `Jaccard`) covers:
80
+ //!
81
+ //! - `hamming(a, b)`: Computes Hamming distance between two slices.
82
+ //! - `jaccard(a, b)`: Computes Jaccard distance between two slices.
83
+ //!
84
+ //! The `ProbabilitySimilarity` trait (combining `KullbackLeibler`, `JensenShannon`) covers:
85
+ //!
86
+ //! - `jensenshannon(a, b)`: Computes Jensen-Shannon distance.
87
+ //! - `kullbackleibler(a, b)`: Computes Kullback-Leibler divergence.
88
+ //!
89
+ //! The elementwise traits (including `EachScale`, `EachSum`, `EachBlend`, `EachFMA`) covers:
90
+ //!
91
+ //! - `scale(a, alpha, beta, result)`: Element-wise `result[i] = α × a[i] + β`.
92
+ //! - `sum(a, b, result)`: Element-wise `result[i] = a[i] + b[i]`.
93
+ //! - `blend(a, b, alpha, beta, result)`: Blend `result[i] = α × a[i] + β × b[i]`.
94
+ //! - `fma(a, b, c, alpha, beta, result)`: Fused multiply-add `result[i] = α × a[i] × b[i] + β × c[i]`.
95
+ //!
96
+ //! The `Trigonometry` trait (combining `EachSin`, `EachCos`, `EachATan`) covers:
97
+ //!
98
+ //! - `sin(input, result)`: Element-wise sine.
99
+ //! - `cos(input, result)`: Element-wise cosine.
100
+ //! - `atan(input, result)`: Element-wise arctangent.
101
+ //!
102
+ //! Additional traits: `VDot`, `Roots`, `SparseIntersect`, `SparseDot`.
103
+ //!
104
+ #![allow(non_camel_case_types)]
105
+ #![allow(clippy::too_many_arguments)]
106
+ #![cfg_attr(all(not(test), not(feature = "std")), no_std)]
107
+
108
+ // Domain modules
109
+ pub mod capabilities;
110
+ pub mod cast;
111
+ pub mod curved;
112
+ pub mod each;
113
+ pub mod geospatial;
114
+ pub mod maxsim;
115
+ pub mod mesh;
116
+ pub mod probability;
117
+ pub mod reduce;
118
+ pub mod set;
119
+ pub mod sparse;
120
+ pub mod spatial;
121
+
122
+ // Containers
123
+ pub mod matrix;
124
+ pub mod tensor;
125
+ pub mod types;
126
+ pub mod vector;
127
+
128
+ // Re-export scalar types at crate root
129
+ pub use types::{
130
+ bf16, bf16c, e2m3, e3m2, e4m3, e5m2, f16, f16c, f32c, f64c, i4x2, is_close, u1x8, u4x2, DimMut,
131
+ DimRef, FloatConvertible, FloatLike, NumberLike, StorageElement,
132
+ };
133
+
134
+ // Re-export spatial traits
135
+ pub use spatial::{Angular, Dot, Euclidean, Roots, SpatialSimilarity, VDot};
136
+
137
+ // Re-export set traits
138
+ pub use set::{BinarySimilarity, Hamming, Jaccard};
139
+
140
+ // Re-export probability traits
141
+ pub use probability::{JensenShannon, KullbackLeibler, ProbabilitySimilarity};
142
+
143
+ // Re-export elementwise and trig traits
144
+ pub use each::{EachATan, EachBlend, EachCos, EachFMA, EachScale, EachSin, EachSum, Trigonometry};
145
+
146
+ // Re-export reduction traits
147
+ pub use reduce::{ReduceMinMax, ReduceMoments, Reductions};
148
+
149
+ // Re-export curved metric traits
150
+ pub use curved::{Bilinear, Mahalanobis};
151
+
152
+ // Re-export mesh alignment
153
+ pub use mesh::{MeshAlignment, MeshAlignmentResult};
154
+
155
+ // Re-export geospatial
156
+ pub use geospatial::{Geospatial, Haversine, Vincenty};
157
+
158
+ // Re-export sparse
159
+ pub use sparse::{SparseDot, SparseIntersect};
160
+
161
+ // Re-export cast operations
162
+ pub use cast::{cast, CastDtype};
163
+
164
+ // Re-export capabilities
165
+ pub use capabilities::cap;
166
+ pub use capabilities::{available, configure_thread, uses_dynamic_dispatch};
167
+
168
+ // Re-export tensor types
169
+ pub use tensor::{
170
+ AllCloseOps, Allocator, AxisIterator, AxisIteratorMut, BlendOps, CastOps, FmaOps, Global,
171
+ Matrix, MatrixSpan, MatrixView, MinMaxOps, MinMaxResult, MomentsOps, RangeStep, ScaleOps,
172
+ SliceArg, SliceRange, SliceSpec, SumOps, Tensor, TensorDims, TensorError, TensorIterator,
173
+ TensorMut, TensorRef, TensorSpan, TensorSpanDims, TensorSpanIterator, TensorView,
174
+ TensorViewDims, TensorViewIterator, TrigAtanOps, TrigCosOps, TrigSinOps, DEFAULT_MAX_RANK,
175
+ SIMD_ALIGNMENT,
176
+ };
177
+
178
+ // Re-export matrix types
179
+ pub use matrix::{
180
+ Angulars, Dots, Euclideans, Hammings, Jaccards, PackedMatrix, SymmetricAngulars, SymmetricDots,
181
+ SymmetricEuclideans, SymmetricHammings, SymmetricJaccards,
182
+ };
183
+
184
+ // Re-export vector types
185
+ pub use vector::{
186
+ Vector, VectorIndex, VectorIterator, VectorSpan, VectorSpanIterator, VectorView,
187
+ VectorViewIterator,
188
+ };
189
+
190
+ // Re-export maxsim types
191
+ pub use maxsim::{MaxSim, MaxSimPackedMatrix};
192
+
193
+ // region: Tests
194
+
195
+ #[cfg(test)]
196
+ mod tests {
197
+ use super::*;
198
+
199
+ #[test]
200
+ fn dot_smoke() {
201
+ let first = [1.0_f32, 2.0, 3.0];
202
+ let second = [4.0_f32, 5.0, 6.0];
203
+ assert!((<f32 as Dot>::dot(&first, &second).unwrap() - 32.0).abs() < 0.01);
204
+ }
205
+
206
+ #[test]
207
+ fn angular_smoke() {
208
+ let first = [1.0_f32, 0.0];
209
+ let second = [0.0_f32, 1.0];
210
+ // Orthogonal vectors → angular distance = 1.0
211
+ assert!((f32::angular(&first, &second).unwrap() - 1.0).abs() < 0.01);
212
+ }
213
+
214
+ #[test]
215
+ fn euclidean_smoke() {
216
+ let first = [0.0_f32, 0.0, 0.0];
217
+ let second = [3.0_f32, 4.0, 0.0];
218
+ assert!((f32::euclidean(&first, &second).unwrap() - 5.0).abs() < 0.1);
219
+ }
220
+
221
+ #[test]
222
+ fn maxsim_smoke() {
223
+ capabilities::configure_thread();
224
+ let queries = Tensor::<f32>::try_full(&[4, 16], 1.0).unwrap();
225
+ let documents = Tensor::<f32>::try_full(&[8, 16], 1.0).unwrap();
226
+ let queries_view = queries.view();
227
+ let docs_view = documents.view();
228
+ let queries_packed = MaxSimPackedMatrix::try_pack(&queries_view).unwrap();
229
+ let docs_packed = MaxSimPackedMatrix::try_pack(&docs_view).unwrap();
230
+ assert_eq!(queries_packed.dims(), (4, 16));
231
+ assert_eq!(docs_packed.dims(), (8, 16));
232
+ let score = queries_packed.score(&docs_packed);
233
+ assert!(
234
+ score.is_finite(),
235
+ "MaxSim score must be finite, got {score}"
236
+ );
237
+ }
238
+
239
+ #[test]
240
+ fn tensor_dots_smoke() {
241
+ capabilities::configure_thread();
242
+ let queries = Tensor::<f32>::try_full(&[2, 4], 1.0).unwrap();
243
+ let targets = Tensor::<f32>::try_full(&[3, 4], 1.0).unwrap();
244
+ let packed_targets = PackedMatrix::try_pack(&targets).unwrap();
245
+ let products = queries.dots_packed(&packed_targets);
246
+ assert_eq!(products.shape(), &[2, 3]);
247
+ assert!((products.as_slice()[0] - 4.0).abs() < 0.01);
248
+ }
249
+ }
250
+
251
+ // endregion: Tests
252
+
253
+ // region: WASM Runtime Tests
254
+
255
+ /// WASM runtime integration tests using Wasmtime
256
+ /// These tests validate that WASI builds work correctly with standalone runtimes
257
+ #[cfg(all(test, feature = "wasm-runtime"))]
258
+ mod wasm_runtime_tests {
259
+ use std::fs;
260
+ use std::path::Path;
261
+ use wasmtime::{
262
+ Config, Engine, Extern, ExternType, Linker, Memory, MemoryType, Module, SharedMemory, Store,
263
+ };
264
+ use wasmtime_wasi::WasiCtx;
265
+
266
+ fn resolve_wasi_module() -> Option<String> {
267
+ if let Ok(path) = std::env::var("NK_WASI_MODULE") {
268
+ if Path::new(&path).exists() {
269
+ return Some(path);
270
+ }
271
+ }
272
+ if Path::new("build-wasi/nk_test.wasm").exists() {
273
+ Some("build-wasi/nk_test.wasm".to_string())
274
+ } else if Path::new("build-wasi/test.wasm").exists() {
275
+ Some("build-wasi/test.wasm".to_string())
276
+ } else {
277
+ None
278
+ }
279
+ }
280
+
281
+ /// Test that WASI WASM module can be loaded and executed with Wasmtime
282
+ /// This validates the dual-path capability detection (EM_ASM vs WASI imports)
283
+ #[test]
284
+ fn wasi_with_wasmtime() -> wasmtime::Result<()> {
285
+ // Check if WASI build exists
286
+ let Some(wasm_path) = resolve_wasi_module() else {
287
+ eprintln!("WASI build not found. Run:");
288
+ eprintln!(" export WASI_SDK_PATH=~/wasi-sdk");
289
+ eprintln!(" cmake -B build-wasi -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-wasi.cmake -DNK_BUILD_TEST=ON");
290
+ eprintln!(" cmake --build build-wasi --target nk_test");
291
+ return Ok(()); // Skip test if build doesn't exist
292
+ };
293
+
294
+ println!("Loading WASI module from {}", wasm_path);
295
+
296
+ let mut config = Config::new();
297
+ config.wasm_simd(true);
298
+ config.wasm_relaxed_simd(true);
299
+ config.wasm_threads(true);
300
+ config.shared_memory(true);
301
+
302
+ // Create Wasmtime engine and linker
303
+ let engine = Engine::new(&config)?;
304
+ let mut linker = Linker::new(&engine);
305
+
306
+ // Create WASI context (Wasmtime 41+ API)
307
+ // Don't inherit_args() — cargo's test filter args would confuse the WASM test binary.
308
+ let wasi = WasiCtx::builder().inherit_stdio().inherit_env().build_p1();
309
+ let mut store = Store::new(&engine, wasi);
310
+
311
+ // Add WASI support (Wasmtime 41+ requires p1 module)
312
+ wasmtime_wasi::p1::add_to_linker_sync(&mut linker, |s| s)?;
313
+
314
+ // Provide capability detection imports (required for WASI build)
315
+ // These functions are called from nk_capabilities_v128relaxed_() in C code
316
+ linker.func_wrap("env", "nk_has_v128", || -> i32 {
317
+ // Return 1 (true) - assume SIMD128 is available in Wasmtime
318
+ println!(" nk_has_v128() called from WASM -> returning 1");
319
+ 1
320
+ })?;
321
+
322
+ linker.func_wrap("env", "nk_has_relaxed", || -> i32 {
323
+ // Return 1 (true) - assume Relaxed SIMD is available in Wasmtime
324
+ println!(" nk_has_relaxed() called from WASM -> returning 1");
325
+ 1
326
+ })?;
327
+
328
+ linker.func_wrap("wasi", "thread-spawn", |_start_arg: i32| -> i32 { -1 })?;
329
+
330
+ // Load WASM module
331
+ let wasm_bytes = fs::read(&wasm_path)?;
332
+ let module = Module::new(&engine, wasm_bytes)?;
333
+
334
+ for import in module.imports() {
335
+ if import.module() != "env" || import.name() != "memory" {
336
+ continue;
337
+ }
338
+
339
+ let ExternType::Memory(memory_ty) = import.ty() else {
340
+ continue;
341
+ };
342
+
343
+ let minimum = u32::try_from(memory_ty.minimum()).map_err(|_| {
344
+ wasmtime::Error::msg(format!(
345
+ "memory minimum {} does not fit in u32",
346
+ memory_ty.minimum()
347
+ ))
348
+ })?;
349
+ let maximum = memory_ty
350
+ .maximum()
351
+ .ok_or_else(|| wasmtime::Error::msg("shared memory import is missing a maximum"))?;
352
+ let maximum = u32::try_from(maximum).map_err(|_| {
353
+ wasmtime::Error::msg(format!("memory maximum {maximum} does not fit in u32"))
354
+ })?;
355
+
356
+ if memory_ty.is_shared() {
357
+ let memory = SharedMemory::new(&engine, MemoryType::shared(minimum, maximum))?;
358
+ linker.define(&store, "env", "memory", Extern::from(memory))?;
359
+ } else {
360
+ let memory = Memory::new(&mut store, MemoryType::new(minimum, Some(maximum)))?;
361
+ linker.define(&store, "env", "memory", Extern::from(memory))?;
362
+ }
363
+ }
364
+
365
+ // Instantiate module
366
+ println!("Instantiating WASM module...");
367
+ let instance = linker.instantiate(&mut store, &module)?;
368
+
369
+ // Get _start entry point (WASI convention; exit code comes via proc_exit trap)
370
+ let start = instance.get_typed_func::<(), ()>(&mut store, "_start")?;
371
+
372
+ // Run tests — _start calls exit(0) which triggers proc_exit(0).
373
+ // Wasmtime reports proc_exit as an I32Exit error; exit code 0 means success.
374
+ println!("Running WASM tests...");
375
+ match start.call(&mut store, ()) {
376
+ Ok(()) => {}
377
+ Err(e) => {
378
+ if let Some(exit) = e.downcast_ref::<wasmtime_wasi::I32Exit>() {
379
+ assert_eq!(exit.0, 0, "WASI tests failed with exit code {}", exit.0);
380
+ } else {
381
+ return Err(e);
382
+ }
383
+ }
384
+ }
385
+
386
+ println!("WASM tests completed successfully");
387
+ Ok(())
388
+ }
389
+
390
+ /// Test capability detection mechanism works in WASI environment
391
+ #[test]
392
+ fn capability_imports() -> wasmtime::Result<()> {
393
+ println!("Testing capability import mechanism...");
394
+
395
+ // Create minimal engine for import testing
396
+ let engine = Engine::default();
397
+ let mut linker = Linker::<()>::new(&engine);
398
+
399
+ // Test that we can define the required imports
400
+ linker.func_wrap("env", "nk_has_v128", || -> i32 { 1 })?;
401
+ linker.func_wrap("env", "nk_has_relaxed", || -> i32 { 0 })?;
402
+
403
+ println!(" ✓ Capability imports defined successfully");
404
+
405
+ Ok(())
406
+ }
407
+ }
408
+
409
+ // endregion: WASM Runtime Tests
@@ -0,0 +1,272 @@
1
+ //! Probability measures: Kullback-Leibler divergence and Jensen-Shannon distance.
2
+ //!
3
+ //! This module provides:
4
+ //!
5
+ //! - [`KullbackLeibler`]: KL divergence between two distributions
6
+ //! - [`JensenShannon`]: Jensen-Shannon distance (symmetric metric)
7
+ //! - [`ProbabilitySimilarity`]: Blanket trait combining `KullbackLeibler + JensenShannon`
8
+
9
+ use crate::types::{bf16, f16};
10
+
11
+ #[link(name = "numkong")]
12
+ extern "C" {
13
+ fn nk_jsd_f16(a: *const u16, b: *const u16, c: usize, d: *mut f32);
14
+ fn nk_jsd_bf16(a: *const u16, b: *const u16, c: usize, d: *mut f32);
15
+ fn nk_jsd_f32(a: *const f32, b: *const f32, c: usize, d: *mut f64);
16
+ fn nk_jsd_f64(a: *const f64, b: *const f64, c: usize, d: *mut f64);
17
+
18
+ fn nk_kld_f16(a: *const u16, b: *const u16, c: usize, d: *mut f32);
19
+ fn nk_kld_bf16(a: *const u16, b: *const u16, c: usize, d: *mut f32);
20
+ fn nk_kld_f32(a: *const f32, b: *const f32, c: usize, d: *mut f64);
21
+ fn nk_kld_f64(a: *const f64, b: *const f64, c: usize, d: *mut f64);
22
+ }
23
+
24
+ // region: KullbackLeibler
25
+
26
+ /// Computes the **Kullback-Leibler divergence** between two probability distributions.
27
+ ///
28
+ /// D_KL(P‖Q) = ∑ᵢ pᵢ × ln(pᵢ / qᵢ)
29
+ ///
30
+ /// Range: \[0, ∞). Not symmetric. Returns `None` if lengths differ.
31
+ ///
32
+ /// Implemented for: `f64`, `f32`, `f16`, `bf16`.
33
+ pub trait KullbackLeibler: Sized {
34
+ type Output;
35
+ fn kullbackleibler(a: &[Self], b: &[Self]) -> Option<Self::Output>;
36
+
37
+ /// Alias for `kullbackleibler`.
38
+ fn kl(a: &[Self], b: &[Self]) -> Option<Self::Output> {
39
+ Self::kullbackleibler(a, b)
40
+ }
41
+ }
42
+
43
+ impl KullbackLeibler for f64 {
44
+ type Output = f64;
45
+ fn kullbackleibler(a: &[Self], b: &[Self]) -> Option<Self::Output> {
46
+ if a.len() != b.len() {
47
+ return None;
48
+ }
49
+ let mut result: Self::Output = 0.0;
50
+ unsafe { nk_kld_f64(a.as_ptr(), b.as_ptr(), a.len(), &mut result) };
51
+ Some(result)
52
+ }
53
+ }
54
+
55
+ impl KullbackLeibler for f32 {
56
+ type Output = f64;
57
+ fn kullbackleibler(a: &[Self], b: &[Self]) -> Option<Self::Output> {
58
+ if a.len() != b.len() {
59
+ return None;
60
+ }
61
+ let mut result: Self::Output = 0.0;
62
+ unsafe { nk_kld_f32(a.as_ptr(), b.as_ptr(), a.len(), &mut result) };
63
+ Some(result)
64
+ }
65
+ }
66
+
67
+ impl KullbackLeibler for f16 {
68
+ type Output = f32;
69
+ fn kullbackleibler(a: &[Self], b: &[Self]) -> Option<Self::Output> {
70
+ if a.len() != b.len() {
71
+ return None;
72
+ }
73
+ let mut result: Self::Output = 0.0;
74
+ unsafe {
75
+ nk_kld_f16(
76
+ a.as_ptr() as *const u16,
77
+ b.as_ptr() as *const u16,
78
+ a.len(),
79
+ &mut result,
80
+ )
81
+ };
82
+ Some(result)
83
+ }
84
+ }
85
+
86
+ impl KullbackLeibler for bf16 {
87
+ type Output = f32;
88
+ fn kullbackleibler(a: &[Self], b: &[Self]) -> Option<Self::Output> {
89
+ if a.len() != b.len() {
90
+ return None;
91
+ }
92
+ let mut result: Self::Output = 0.0;
93
+ unsafe {
94
+ nk_kld_bf16(
95
+ a.as_ptr() as *const u16,
96
+ b.as_ptr() as *const u16,
97
+ a.len(),
98
+ &mut result,
99
+ )
100
+ };
101
+ Some(result)
102
+ }
103
+ }
104
+
105
+ // endregion: KullbackLeibler
106
+
107
+ // region: JensenShannon
108
+
109
+ /// Computes the **Jensen-Shannon distance** between two probability distributions.
110
+ ///
111
+ /// d_JS(P, Q) = √(½(D_KL(P‖M) + D_KL(Q‖M))), where M = (P + Q) / 2
112
+ ///
113
+ /// Range: \[0, √ln2\]. Symmetric. Returns `None` if lengths differ.
114
+ ///
115
+ /// Implemented for: `f64`, `f32`, `f16`, `bf16`.
116
+ pub trait JensenShannon: Sized {
117
+ type Output;
118
+ fn jensenshannon(a: &[Self], b: &[Self]) -> Option<Self::Output>;
119
+
120
+ /// Alias for `jensenshannon`.
121
+ fn js(a: &[Self], b: &[Self]) -> Option<Self::Output> {
122
+ Self::jensenshannon(a, b)
123
+ }
124
+ }
125
+
126
+ impl JensenShannon for f64 {
127
+ type Output = f64;
128
+ fn jensenshannon(a: &[Self], b: &[Self]) -> Option<Self::Output> {
129
+ if a.len() != b.len() {
130
+ return None;
131
+ }
132
+ let mut result: Self::Output = 0.0;
133
+ unsafe { nk_jsd_f64(a.as_ptr(), b.as_ptr(), a.len(), &mut result) };
134
+ Some(result)
135
+ }
136
+ }
137
+
138
+ impl JensenShannon for f32 {
139
+ type Output = f64;
140
+ fn jensenshannon(a: &[Self], b: &[Self]) -> Option<Self::Output> {
141
+ if a.len() != b.len() {
142
+ return None;
143
+ }
144
+ let mut result: Self::Output = 0.0;
145
+ unsafe { nk_jsd_f32(a.as_ptr(), b.as_ptr(), a.len(), &mut result) };
146
+ Some(result)
147
+ }
148
+ }
149
+
150
+ impl JensenShannon for f16 {
151
+ type Output = f32;
152
+ fn jensenshannon(a: &[Self], b: &[Self]) -> Option<Self::Output> {
153
+ if a.len() != b.len() {
154
+ return None;
155
+ }
156
+ let mut result: Self::Output = 0.0;
157
+ unsafe {
158
+ nk_jsd_f16(
159
+ a.as_ptr() as *const u16,
160
+ b.as_ptr() as *const u16,
161
+ a.len(),
162
+ &mut result,
163
+ )
164
+ };
165
+ Some(result)
166
+ }
167
+ }
168
+
169
+ impl JensenShannon for bf16 {
170
+ type Output = f32;
171
+ fn jensenshannon(a: &[Self], b: &[Self]) -> Option<Self::Output> {
172
+ if a.len() != b.len() {
173
+ return None;
174
+ }
175
+ let mut result: Self::Output = 0.0;
176
+ unsafe {
177
+ nk_jsd_bf16(
178
+ a.as_ptr() as *const u16,
179
+ b.as_ptr() as *const u16,
180
+ a.len(),
181
+ &mut result,
182
+ )
183
+ };
184
+ Some(result)
185
+ }
186
+ }
187
+
188
+ // endregion: JensenShannon
189
+
190
+ /// `ProbabilitySimilarity` bundles probability divergence metrics: KullbackLeibler and JensenShannon.
191
+ pub trait ProbabilitySimilarity: KullbackLeibler + JensenShannon {}
192
+ impl<Scalar: KullbackLeibler + JensenShannon> ProbabilitySimilarity for Scalar {}
193
+
194
+ #[cfg(test)]
195
+ mod tests {
196
+ use super::*;
197
+ use crate::types::{assert_close, bf16, f16, FloatLike, NumberLike, TestableType};
198
+
199
+ fn check_kld<Scalar>(distribution_a: &[f32], distribution_b: &[f32], expected: f64)
200
+ where
201
+ Scalar: FloatLike + TestableType + KullbackLeibler,
202
+ Scalar::Output: FloatLike,
203
+ {
204
+ let a_samples: Vec<Scalar> = distribution_a
205
+ .iter()
206
+ .map(|&v| Scalar::from_f32(v))
207
+ .collect();
208
+ let b_samples: Vec<Scalar> = distribution_b
209
+ .iter()
210
+ .map(|&v| Scalar::from_f32(v))
211
+ .collect();
212
+ let result = Scalar::kullbackleibler(&a_samples, &b_samples)
213
+ .unwrap()
214
+ .to_f64();
215
+ // Divergences involve ln() so need wider tolerance than simple dot products
216
+ assert_close(
217
+ result,
218
+ expected,
219
+ Scalar::atol().max(1e-6),
220
+ Scalar::rtol().max(1e-6),
221
+ &format!("kld<{}>", core::any::type_name::<Scalar>()),
222
+ );
223
+ }
224
+
225
+ fn check_jsd<Scalar>(distribution_a: &[f32], distribution_b: &[f32], expected: f64)
226
+ where
227
+ Scalar: FloatLike + TestableType + JensenShannon,
228
+ Scalar::Output: FloatLike,
229
+ {
230
+ let a_samples: Vec<Scalar> = distribution_a
231
+ .iter()
232
+ .map(|&v| Scalar::from_f32(v))
233
+ .collect();
234
+ let b_samples: Vec<Scalar> = distribution_b
235
+ .iter()
236
+ .map(|&v| Scalar::from_f32(v))
237
+ .collect();
238
+ let result = Scalar::jensenshannon(&a_samples, &b_samples)
239
+ .unwrap()
240
+ .to_f64();
241
+ // Divergences involve ln() so need wider tolerance than simple dot products
242
+ assert_close(
243
+ result,
244
+ expected,
245
+ Scalar::atol().max(1e-6),
246
+ Scalar::rtol().max(1e-6),
247
+ &format!("jsd<{}>", core::any::type_name::<Scalar>()),
248
+ );
249
+ }
250
+
251
+ #[test]
252
+ fn divergences() {
253
+ let distribution_a = &[0.1_f32, 0.9, 0.0];
254
+ let distribution_b = &[0.2_f32, 0.8, 0.0];
255
+
256
+ // KL(a||b) = 0.1*ln(0.1/0.2) + 0.9*ln(0.9/0.8)
257
+ let kld_expected = 0.1_f64 * (0.1_f64 / 0.2).ln() + 0.9_f64 * (0.9_f64 / 0.8).ln();
258
+ check_kld::<f64>(distribution_a, distribution_b, kld_expected);
259
+ check_kld::<f32>(distribution_a, distribution_b, kld_expected);
260
+ check_kld::<f16>(distribution_a, distribution_b, kld_expected);
261
+ check_kld::<bf16>(distribution_a, distribution_b, kld_expected);
262
+
263
+ // JS distance = sqrt(0.5 * (KL(a||m) + KL(b||m))) where m = (a+b)/2
264
+ let kl_am = 0.1_f64 * (0.1_f64 / 0.15).ln() + 0.9 * (0.9_f64 / 0.85).ln();
265
+ let kl_bm = 0.2_f64 * (0.2_f64 / 0.15).ln() + 0.8 * (0.8_f64 / 0.85).ln();
266
+ let jsd_expected = (0.5 * (kl_am + kl_bm)).sqrt();
267
+ check_jsd::<f64>(distribution_a, distribution_b, jsd_expected);
268
+ check_jsd::<f32>(distribution_a, distribution_b, jsd_expected);
269
+ check_jsd::<f16>(distribution_a, distribution_b, jsd_expected);
270
+ check_jsd::<bf16>(distribution_a, distribution_b, jsd_expected);
271
+ }
272
+ }