usearch 2.21.4 → 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 +224 -48
  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
@@ -0,0 +1,551 @@
1
+ /**
2
+ * @brief Template test functions for batch operations (dots, hammings).
3
+ * @file test/test_cross.hpp
4
+ * @author Ash Vardanian
5
+ * @date January 14, 2025
6
+ *
7
+ * This header contains the template test implementations that are shared
8
+ * across all ISA-specific test files.
9
+ */
10
+ #pragma once
11
+ #ifndef NK_TEST_CROSS_HPP
12
+ #define NK_TEST_CROSS_HPP
13
+
14
+ #include "numkong/spatials.h" // `nk_angulars_packed_*`, `nk_euclideans_packed_*`
15
+
16
+ #include "numkong/dots.hpp" // `nk::dots_packed`, `nk::dots_symmetric`
17
+ #include "numkong/matrix.hpp" // `nk::dots_packed_size`, `nk::dots_pack`
18
+ #include "numkong/reduce.hpp" // `nk::reduce_moments`
19
+
20
+ #include "test.hpp"
21
+
22
+ /**
23
+ * @brief Generic GEMM test against f118_t reference.
24
+ * Works for all types: f32, f64, f16, bf16, i8.
25
+ */
26
+ template <typename scalar_type_>
27
+ error_stats_t test_dots_packed(typename scalar_type_::dots_packed_size_kernel_t packed_size_fn,
28
+ typename scalar_type_::dots_pack_kernel_t pack_fn,
29
+ typename scalar_type_::dots_packed_kernel_t dots_fn) {
30
+ using scalar_t = scalar_type_;
31
+ using result_t = typename scalar_t::dot_result_t;
32
+ using reference_t = reference_for<scalar_t, result_t>;
33
+
34
+ error_stats_t stats(comparison_family_t::mixed_precision_reduction_k);
35
+ std::mt19937 generator(global_config.seed);
36
+
37
+ std::size_t m = global_config.matrix_height, n = global_config.matrix_width;
38
+ std::size_t const dims_per_value = nk::dimensions_per_value<scalar_t>();
39
+ std::size_t k_values = nk::divide_round_up(global_config.matrix_depth, dims_per_value);
40
+ std::size_t k = k_values * dims_per_value;
41
+ std::size_t a_stride = k_values * sizeof(scalar_t);
42
+ std::size_t b_stride = k_values * sizeof(scalar_t);
43
+ std::size_t c_stride = n * sizeof(result_t);
44
+
45
+ auto a = make_vector<scalar_t>(m * k), b = make_vector<scalar_t>(n * k);
46
+ auto c = make_vector<result_t>(m * n);
47
+ auto c_ref = make_vector<reference_t>(m * n);
48
+
49
+ nk_size_t packed_size = packed_size_fn(n, k);
50
+ auto b_packed = make_vector<char>(packed_size);
51
+ nk_size_t ref_packed_size = nk::dots_packed_size<scalar_t, nk::no_simd_k>(n, k);
52
+ auto b_packed_ref = make_vector<char>(ref_packed_size);
53
+
54
+ for (auto start = test_start_time(); within_time_budget(start);) {
55
+ fill_random(generator, a);
56
+ fill_random(generator, b);
57
+
58
+ // Run kernel being tested
59
+ pack_fn(b.raw_values_data(), n, k, b_stride, b_packed.raw_values_data());
60
+ dots_fn(a.raw_values_data(), b_packed.raw_values_data(), c.raw_values_data(), m, n, k, a_stride, c_stride);
61
+
62
+ // Compute reference using nk:: template
63
+ nk::dots_pack<scalar_t, nk::no_simd_k>(b.values_data(), n, k, b_stride, b_packed_ref.raw_values_data());
64
+ nk::dots_packed<scalar_t, reference_t, nk::no_simd_k>(a.values_data(), b_packed_ref.raw_values_data(),
65
+ c_ref.values_data(), m, n, k, a_stride,
66
+ n * sizeof(reference_t));
67
+
68
+ for (std::size_t i = 0; i < m * n; i++) stats.accumulate(c[i], c_ref[i]);
69
+ }
70
+ return stats;
71
+ }
72
+
73
+ /**
74
+ * @brief Generic symmetric GEMM (A x A^T) test against f118_t reference.
75
+ * Works for all types: f32, f64, f16, bf16, i8, u8, i4, u4, e4m3, e5m2.
76
+ */
77
+ template <typename scalar_type_>
78
+ error_stats_t test_dots_symmetric(typename scalar_type_::dots_symmetric_kernel_t kernel_fn) {
79
+ using scalar_t = scalar_type_;
80
+ using result_t = typename scalar_t::dot_result_t;
81
+ using reference_t = reference_for<scalar_t, result_t>;
82
+
83
+ error_stats_t stats(comparison_family_t::mixed_precision_reduction_k);
84
+ std::mt19937 generator(global_config.seed);
85
+
86
+ std::size_t n = global_config.matrix_height;
87
+ std::size_t const dims_per_value = nk::dimensions_per_value<scalar_t>();
88
+ std::size_t k_values = nk::divide_round_up(global_config.matrix_depth, dims_per_value);
89
+ std::size_t k = k_values * dims_per_value;
90
+ std::size_t a_stride = k_values * sizeof(scalar_t);
91
+ std::size_t c_stride = n * sizeof(result_t);
92
+
93
+ auto a = make_vector<scalar_t>(n * k);
94
+ auto c = make_vector<result_t>(n * n);
95
+ auto c_ref = make_vector<reference_t>(n * n);
96
+
97
+ for (auto start = test_start_time(); within_time_budget(start);) {
98
+ fill_random(generator, a);
99
+
100
+ // Run kernel being tested
101
+ kernel_fn(a.raw_values_data(), n, k, a_stride, c.raw_values_data(), c_stride, 0, n);
102
+
103
+ // Compute reference using nk:: template
104
+ nk::dots_symmetric<scalar_t, reference_t, nk::no_simd_k>(a.values_data(), n, k, a_stride, c_ref.values_data(),
105
+ n * sizeof(reference_t));
106
+
107
+ // Only check upper triangle and diagonal
108
+ for (std::size_t i = 0; i < n; i++)
109
+ for (std::size_t j = i; j < n; j++) stats.accumulate(c[i * n + j], c_ref[i * n + j]);
110
+ }
111
+ return stats;
112
+ }
113
+
114
+ /**
115
+ * @brief Test batched Hamming distance computation with packed B matrix.
116
+ */
117
+ template <typename scalar_type_>
118
+ error_stats_t test_hammings_packed(typename scalar_type_::hammings_packed_size_kernel_t packed_size_fn,
119
+ typename scalar_type_::hammings_pack_kernel_t pack_fn,
120
+ typename scalar_type_::hammings_packed_kernel_t hammings_fn) {
121
+ using scalar_t = scalar_type_;
122
+ using result_t = u32_t;
123
+
124
+ error_stats_t stats(comparison_family_t::exact_k);
125
+ std::mt19937 generator(global_config.seed);
126
+
127
+ std::size_t m = global_config.matrix_height, n = global_config.matrix_width, k = global_config.dense_dimensions;
128
+ std::size_t k_bytes = nk::divide_round_up(k, 8);
129
+ std::size_t a_stride = k_bytes * sizeof(scalar_t);
130
+ std::size_t b_stride = k_bytes * sizeof(scalar_t);
131
+ std::size_t c_stride = n * sizeof(result_t);
132
+
133
+ auto a = make_vector<scalar_t>(m * k), b = make_vector<scalar_t>(n * k);
134
+ auto c = make_vector<result_t>(m * n);
135
+ auto c_ref = make_vector<result_t>(m * n);
136
+
137
+ nk_size_t packed_size = packed_size_fn(n, k);
138
+ auto b_packed = make_vector<char>(packed_size);
139
+
140
+ // Allocate buffer for reference computation
141
+ nk_size_t packed_size_ref = nk::dots_packed_size<scalar_t, nk::no_simd_k>(n, k);
142
+ auto b_packed_ref = make_vector<char>(packed_size_ref);
143
+
144
+ for (auto start = test_start_time(); within_time_budget(start);) {
145
+ fill_random(generator, a);
146
+ fill_random(generator, b);
147
+
148
+ // Run kernel being tested
149
+ pack_fn(b.raw_values_data(), n, k, b_stride, b_packed.raw_values_data());
150
+ hammings_fn(a.raw_values_data(), b_packed.raw_values_data(), c.raw_values_data(), m, n, k, a_stride, c_stride);
151
+
152
+ // Compute reference using C++ template with no_simd_k
153
+ nk::dots_pack<scalar_t, nk::no_simd_k>(b.values_data(), n, k, b_stride, b_packed_ref.raw_values_data());
154
+ nk::hammings_packed<scalar_t, result_t, nk::no_simd_k>(a.values_data(), b_packed_ref.raw_values_data(),
155
+ c_ref.values_data(), m, n, k, a_stride, c_stride);
156
+
157
+ // Hamming distances are exact integers
158
+ for (std::size_t i = 0; i < m * n; i++) stats.accumulate(c[i], c_ref[i]);
159
+ }
160
+ return stats;
161
+ }
162
+
163
+ /**
164
+ * @brief Test symmetric Hamming distance matrix computation.
165
+ */
166
+ template <typename scalar_type_>
167
+ error_stats_t test_hammings_symmetric(typename scalar_type_::hammings_symmetric_kernel_t kernel_fn) {
168
+ using scalar_t = scalar_type_;
169
+ using result_t = u32_t;
170
+
171
+ error_stats_t stats(comparison_family_t::exact_k);
172
+ std::mt19937 generator(global_config.seed);
173
+
174
+ std::size_t n = global_config.matrix_height, k = global_config.dense_dimensions;
175
+ std::size_t k_bytes = nk::divide_round_up(k, 8);
176
+ std::size_t a_stride = k_bytes * sizeof(scalar_t);
177
+ std::size_t c_stride = n * sizeof(result_t);
178
+
179
+ auto a = make_vector<scalar_t>(n * k);
180
+ auto c = make_vector<result_t>(n * n);
181
+ auto c_ref = make_vector<result_t>(n * n);
182
+
183
+ for (auto start = test_start_time(); within_time_budget(start);) {
184
+ fill_random(generator, a);
185
+
186
+ // Run kernel being tested
187
+ kernel_fn(a.raw_values_data(), n, k, a_stride, c.raw_values_data(), c_stride, 0, n);
188
+
189
+ // Compute reference using nk:: template
190
+ nk::hammings_symmetric<scalar_t, result_t, nk::no_simd_k>(a.values_data(), n, k, a_stride, c_ref.values_data(),
191
+ n * sizeof(result_t));
192
+
193
+ // Hamming distances are exact integers — check upper triangle only
194
+ for (std::size_t i = 0; i < n; i++)
195
+ for (std::size_t j = i; j < n; j++) stats.accumulate(c[i * n + j], c_ref[i * n + j]);
196
+ }
197
+ return stats;
198
+ }
199
+
200
+ /**
201
+ * @brief Test batched Jaccard distance computation with packed B matrix.
202
+ */
203
+ template <typename scalar_type_>
204
+ error_stats_t test_jaccards_packed(typename scalar_type_::jaccards_packed_size_kernel_t packed_size_fn,
205
+ typename scalar_type_::jaccards_pack_kernel_t pack_fn,
206
+ typename scalar_type_::jaccards_packed_kernel_t jaccards_fn) {
207
+ using scalar_t = scalar_type_;
208
+ using result_t = f32_t;
209
+
210
+ error_stats_t stats(comparison_family_t::exact_k);
211
+ std::mt19937 generator(global_config.seed);
212
+
213
+ std::size_t m = global_config.matrix_height, n = global_config.matrix_width, k = global_config.dense_dimensions;
214
+ std::size_t k_bytes = nk::divide_round_up(k, 8);
215
+ std::size_t a_stride = k_bytes * sizeof(scalar_t);
216
+ std::size_t b_stride = k_bytes * sizeof(scalar_t);
217
+ std::size_t c_stride = n * sizeof(result_t);
218
+
219
+ auto a = make_vector<scalar_t>(m * k), b = make_vector<scalar_t>(n * k);
220
+ auto c = make_vector<result_t>(m * n);
221
+ auto c_ref = make_vector<result_t>(m * n);
222
+
223
+ nk_size_t packed_size = packed_size_fn(n, k);
224
+ auto b_packed = make_vector<char>(packed_size);
225
+
226
+ // Allocate buffer for reference computation
227
+ nk_size_t packed_size_ref = nk::dots_packed_size<scalar_t, nk::no_simd_k>(n, k);
228
+ auto b_packed_ref = make_vector<char>(packed_size_ref);
229
+
230
+ for (auto start = test_start_time(); within_time_budget(start);) {
231
+ fill_random(generator, a);
232
+ fill_random(generator, b);
233
+
234
+ // Run kernel being tested
235
+ pack_fn(b.raw_values_data(), n, k, b_stride, b_packed.raw_values_data());
236
+ jaccards_fn(a.raw_values_data(), b_packed.raw_values_data(), c.raw_values_data(), m, n, k, a_stride, c_stride);
237
+
238
+ // Compute reference using C++ template with no_simd_k
239
+ nk::dots_pack<scalar_t, nk::no_simd_k>(b.values_data(), n, k, b_stride, b_packed_ref.raw_values_data());
240
+ nk::jaccards_packed<scalar_t, result_t, nk::no_simd_k>(a.values_data(), b_packed_ref.raw_values_data(),
241
+ c_ref.values_data(), m, n, k, a_stride, c_stride);
242
+
243
+ // Jaccard distances are f32 — use approximate comparison
244
+ for (std::size_t i = 0; i < m * n; i++) stats.accumulate(c[i], c_ref[i]);
245
+ }
246
+ return stats;
247
+ }
248
+
249
+ /**
250
+ * @brief Test symmetric Jaccard distance matrix computation.
251
+ */
252
+ template <typename scalar_type_>
253
+ error_stats_t test_jaccards_symmetric(typename scalar_type_::jaccards_symmetric_kernel_t kernel_fn) {
254
+ using scalar_t = scalar_type_;
255
+ using result_t = f32_t;
256
+
257
+ error_stats_t stats(comparison_family_t::exact_k);
258
+ std::mt19937 generator(global_config.seed);
259
+
260
+ std::size_t n = global_config.matrix_height, k = global_config.dense_dimensions;
261
+ std::size_t k_bytes = nk::divide_round_up(k, 8);
262
+ std::size_t a_stride = k_bytes * sizeof(scalar_t);
263
+ std::size_t c_stride = n * sizeof(result_t);
264
+
265
+ auto a = make_vector<scalar_t>(n * k);
266
+ auto c = make_vector<result_t>(n * n);
267
+ auto c_ref = make_vector<result_t>(n * n);
268
+
269
+ for (auto start = test_start_time(); within_time_budget(start);) {
270
+ fill_random(generator, a);
271
+
272
+ // Run kernel being tested
273
+ kernel_fn(a.raw_values_data(), n, k, a_stride, c.raw_values_data(), c_stride, 0, n);
274
+
275
+ // Compute reference using nk:: template
276
+ nk::jaccards_symmetric<scalar_t, result_t, nk::no_simd_k>(a.values_data(), n, k, a_stride, c_ref.values_data(),
277
+ n * sizeof(result_t));
278
+
279
+ // Check upper triangle only
280
+ for (std::size_t i = 0; i < n; i++)
281
+ for (std::size_t j = i; j < n; j++) stats.accumulate(c[i * n + j], c_ref[i * n + j]);
282
+ }
283
+ return stats;
284
+ }
285
+
286
+ /**
287
+ * @brief Test batched angular distance computation with packed B matrix.
288
+ * Angular distance: 1 - dot(a,b) / sqrt(sumsq(a) * sumsq(b))
289
+ */
290
+ template <typename scalar_type_>
291
+ error_stats_t test_angulars_packed(typename scalar_type_::dots_packed_size_kernel_t packed_size_fn,
292
+ typename scalar_type_::dots_pack_kernel_t pack_fn,
293
+ typename scalar_type_::angulars_packed_kernel_t angulars_fn) {
294
+ using scalar_t = scalar_type_;
295
+ using result_t = typename scalar_t::angular_result_t;
296
+ using reference_t = reference_for<scalar_t, result_t>;
297
+
298
+ error_stats_t stats(comparison_family_t::mixed_precision_reduction_k);
299
+ std::mt19937 generator(global_config.seed);
300
+
301
+ std::size_t m = global_config.matrix_height, n = global_config.matrix_width;
302
+ std::size_t const dims_per_value = nk::dimensions_per_value<scalar_t>();
303
+ std::size_t k_values = nk::divide_round_up(global_config.matrix_depth, dims_per_value);
304
+ std::size_t k = k_values * dims_per_value;
305
+ std::size_t a_stride = k_values * sizeof(scalar_t);
306
+ std::size_t b_stride = k_values * sizeof(scalar_t);
307
+ std::size_t c_stride = n * sizeof(result_t);
308
+
309
+ auto a = make_vector<scalar_t>(m * k), b = make_vector<scalar_t>(n * k);
310
+ auto c = make_vector<result_t>(m * n);
311
+ auto c_ref = make_vector<reference_t>(m * n);
312
+
313
+ nk_size_t packed_size = packed_size_fn(n, k);
314
+ auto b_packed = make_vector<char>(packed_size);
315
+
316
+ nk_size_t ref_packed_size = nk::dots_packed_size<scalar_t, nk::no_simd_k>(n, k);
317
+ auto b_packed_ref = make_vector<char>(ref_packed_size);
318
+ auto a_sumsqs = make_vector<reference_t>(m);
319
+ auto b_sumsqs = make_vector<reference_t>(n);
320
+
321
+ for (auto start = test_start_time(); within_time_budget(start);) {
322
+ fill_random(generator, a);
323
+ fill_random(generator, b);
324
+
325
+ // Run kernel being tested
326
+ pack_fn(b.raw_values_data(), n, k, b_stride, b_packed.raw_values_data());
327
+ angulars_fn(a.raw_values_data(), b_packed.raw_values_data(), c.raw_values_data(), m, n, k, a_stride, c_stride);
328
+
329
+ // Reference: compute dot products in reference precision
330
+ nk::dots_pack<scalar_t, nk::no_simd_k>(b.values_data(), n, k, b_stride, b_packed_ref.raw_values_data());
331
+ nk::dots_packed<scalar_t, reference_t, nk::no_simd_k>(a.values_data(), b_packed_ref.raw_values_data(),
332
+ c_ref.values_data(), m, n, k, a_stride,
333
+ n * sizeof(reference_t));
334
+
335
+ // Compute sumsqs using reduce_moments
336
+ reference_t sum_unused;
337
+ for (std::size_t i = 0; i < m; ++i)
338
+ nk::reduce_moments<scalar_t, reference_t, reference_t, nk::no_simd_k>(
339
+ a.values_data() + i * k_values, k, sizeof(scalar_t), &sum_unused, a_sumsqs.values_data() + i);
340
+ for (std::size_t j = 0; j < n; ++j)
341
+ nk::reduce_moments<scalar_t, reference_t, reference_t, nk::no_simd_k>(
342
+ b.values_data() + j * k_values, k, sizeof(scalar_t), &sum_unused, b_sumsqs.values_data() + j);
343
+
344
+ // Convert dots to angular distances: 1 - dot / sqrt(sumsq_a * sumsq_b)
345
+ for (std::size_t i = 0; i < m; ++i)
346
+ for (std::size_t j = 0; j < n; ++j) {
347
+ reference_t ab_sumsq = a_sumsqs[i] * b_sumsqs[j];
348
+ reference_t &c_cell = c_ref[i * n + j];
349
+ c_cell = ab_sumsq > reference_t(0) ? (reference_t(1) - c_cell * ab_sumsq.rsqrt()) : reference_t(0);
350
+ }
351
+
352
+ for (std::size_t i = 0; i < m * n; i++) stats.accumulate(c[i], c_ref[i]);
353
+ }
354
+ return stats;
355
+ }
356
+
357
+ /**
358
+ * @brief Test batched euclidean distance computation with packed B matrix.
359
+ * Euclidean distance: sqrt(max(0, sumsq(a) + sumsq(b) - 2*dot(a,b)))
360
+ */
361
+ template <typename scalar_type_>
362
+ error_stats_t test_euclideans_packed(typename scalar_type_::dots_packed_size_kernel_t packed_size_fn,
363
+ typename scalar_type_::dots_pack_kernel_t pack_fn,
364
+ typename scalar_type_::euclideans_packed_kernel_t euclideans_fn) {
365
+ using scalar_t = scalar_type_;
366
+ using result_t = typename scalar_t::euclidean_result_t;
367
+ using reference_t = reference_for<scalar_t, result_t>;
368
+
369
+ error_stats_t stats(comparison_family_t::mixed_precision_reduction_k);
370
+ std::mt19937 generator(global_config.seed);
371
+
372
+ std::size_t m = global_config.matrix_height, n = global_config.matrix_width;
373
+ std::size_t const dims_per_value = nk::dimensions_per_value<scalar_t>();
374
+ std::size_t k_values = nk::divide_round_up(global_config.matrix_depth, dims_per_value);
375
+ std::size_t k = k_values * dims_per_value;
376
+ std::size_t a_stride = k_values * sizeof(scalar_t);
377
+ std::size_t b_stride = k_values * sizeof(scalar_t);
378
+ std::size_t c_stride = n * sizeof(result_t);
379
+
380
+ auto a = make_vector<scalar_t>(m * k), b = make_vector<scalar_t>(n * k);
381
+ auto c = make_vector<result_t>(m * n);
382
+ auto c_ref = make_vector<reference_t>(m * n);
383
+
384
+ nk_size_t packed_size = packed_size_fn(n, k);
385
+ auto b_packed = make_vector<char>(packed_size);
386
+
387
+ nk_size_t ref_packed_size = nk::dots_packed_size<scalar_t, nk::no_simd_k>(n, k);
388
+ auto b_packed_ref = make_vector<char>(ref_packed_size);
389
+ auto a_sumsqs = make_vector<reference_t>(m);
390
+ auto b_sumsqs = make_vector<reference_t>(n);
391
+
392
+ for (auto start = test_start_time(); within_time_budget(start);) {
393
+ fill_random(generator, a);
394
+ fill_random(generator, b);
395
+
396
+ // Run kernel being tested
397
+ pack_fn(b.raw_values_data(), n, k, b_stride, b_packed.raw_values_data());
398
+ euclideans_fn(a.raw_values_data(), b_packed.raw_values_data(), c.raw_values_data(), m, n, k, a_stride,
399
+ c_stride);
400
+
401
+ // Reference: compute dot products in reference precision
402
+ nk::dots_pack<scalar_t, nk::no_simd_k>(b.values_data(), n, k, b_stride, b_packed_ref.raw_values_data());
403
+ nk::dots_packed<scalar_t, reference_t, nk::no_simd_k>(a.values_data(), b_packed_ref.raw_values_data(),
404
+ c_ref.values_data(), m, n, k, a_stride,
405
+ n * sizeof(reference_t));
406
+
407
+ // Compute sumsqs using reduce_moments
408
+ reference_t sum_unused;
409
+ for (std::size_t i = 0; i < m; ++i)
410
+ nk::reduce_moments<scalar_t, reference_t, reference_t, nk::no_simd_k>(
411
+ a.values_data() + i * k_values, k, sizeof(scalar_t), &sum_unused, a_sumsqs.values_data() + i);
412
+ for (std::size_t j = 0; j < n; ++j)
413
+ nk::reduce_moments<scalar_t, reference_t, reference_t, nk::no_simd_k>(
414
+ b.values_data() + j * k_values, k, sizeof(scalar_t), &sum_unused, b_sumsqs.values_data() + j);
415
+
416
+ // Convert dots to euclidean distances: sqrt(max(0, sumsq_a + sumsq_b - 2*dot))
417
+ for (std::size_t i = 0; i < m; ++i)
418
+ for (std::size_t j = 0; j < n; ++j) {
419
+ reference_t &c_cell = c_ref[i * n + j];
420
+ reference_t diff = a_sumsqs[i] + b_sumsqs[j] - reference_t(2) * c_cell;
421
+ c_cell = diff > reference_t(0) ? diff.sqrt() : reference_t(0);
422
+ }
423
+
424
+ for (std::size_t i = 0; i < m * n; i++) stats.accumulate(c[i], c_ref[i]);
425
+ }
426
+ return stats;
427
+ }
428
+
429
+ /**
430
+ * @brief Test symmetric angular distance matrix computation.
431
+ */
432
+ template <typename scalar_type_>
433
+ error_stats_t test_angulars_symmetric(typename scalar_type_::angulars_symmetric_kernel_t kernel_fn) {
434
+ using scalar_t = scalar_type_;
435
+ using result_t = typename scalar_t::angular_result_t;
436
+ using reference_t = reference_for<scalar_t, result_t>;
437
+
438
+ error_stats_t stats(comparison_family_t::mixed_precision_reduction_k);
439
+ std::mt19937 generator(global_config.seed);
440
+
441
+ std::size_t n = global_config.matrix_height;
442
+ std::size_t const dims_per_value = nk::dimensions_per_value<scalar_t>();
443
+ std::size_t k_values = nk::divide_round_up(global_config.matrix_depth, dims_per_value);
444
+ std::size_t k = k_values * dims_per_value;
445
+ std::size_t a_stride = k_values * sizeof(scalar_t);
446
+ std::size_t c_stride = n * sizeof(result_t);
447
+
448
+ auto a = make_vector<scalar_t>(n * k);
449
+ auto c = make_vector<result_t>(n * n);
450
+ auto c_ref = make_vector<reference_t>(n * n);
451
+ auto sumsqs = make_vector<reference_t>(n);
452
+
453
+ for (auto start = test_start_time(); within_time_budget(start);) {
454
+ fill_random(generator, a);
455
+
456
+ // Run kernel being tested
457
+ kernel_fn(a.raw_values_data(), n, k, a_stride, c.raw_values_data(), c_stride, 0, n);
458
+
459
+ // Reference: compute dots symmetric in reference precision
460
+ nk::dots_symmetric<scalar_t, reference_t, nk::no_simd_k>(a.values_data(), n, k, a_stride, c_ref.values_data(),
461
+ n * sizeof(reference_t));
462
+
463
+ // Compute sumsqs using reduce_moments
464
+ reference_t sum_unused;
465
+ for (std::size_t i = 0; i < n; ++i)
466
+ nk::reduce_moments<scalar_t, reference_t, reference_t, nk::no_simd_k>(
467
+ a.values_data() + i * k_values, k, sizeof(scalar_t), &sum_unused, sumsqs.values_data() + i);
468
+
469
+ // Convert dots to angular distances: diagonal=0, upper triangle uses formula
470
+ for (std::size_t i = 0; i < n; ++i) {
471
+ c_ref[i * n + i] = reference_t(0);
472
+ for (std::size_t j = i + 1; j < n; ++j) {
473
+ reference_t ab_sumsq = sumsqs[i] * sumsqs[j];
474
+ reference_t &c_cell = c_ref[i * n + j];
475
+ c_cell = ab_sumsq > reference_t(0) ? (reference_t(1) - c_cell * ab_sumsq.rsqrt()) : reference_t(0);
476
+ }
477
+ }
478
+
479
+ // Only check upper triangle and diagonal
480
+ for (std::size_t i = 0; i < n; i++)
481
+ for (std::size_t j = i; j < n; j++) stats.accumulate(c[i * n + j], c_ref[i * n + j]);
482
+ }
483
+ return stats;
484
+ }
485
+
486
+ /**
487
+ * @brief Test symmetric euclidean distance matrix computation.
488
+ */
489
+ template <typename scalar_type_>
490
+ error_stats_t test_euclideans_symmetric(typename scalar_type_::euclideans_symmetric_kernel_t kernel_fn) {
491
+ using scalar_t = scalar_type_;
492
+ using result_t = typename scalar_t::euclidean_result_t;
493
+ using reference_t = reference_for<scalar_t, result_t>;
494
+
495
+ error_stats_t stats(comparison_family_t::mixed_precision_reduction_k);
496
+ std::mt19937 generator(global_config.seed);
497
+
498
+ std::size_t n = global_config.matrix_height;
499
+ std::size_t const dims_per_value = nk::dimensions_per_value<scalar_t>();
500
+ std::size_t k_values = nk::divide_round_up(global_config.matrix_depth, dims_per_value);
501
+ std::size_t k = k_values * dims_per_value;
502
+ std::size_t a_stride = k_values * sizeof(scalar_t);
503
+ std::size_t c_stride = n * sizeof(result_t);
504
+
505
+ auto a = make_vector<scalar_t>(n * k);
506
+ auto c = make_vector<result_t>(n * n);
507
+ auto c_ref = make_vector<reference_t>(n * n);
508
+ auto sumsqs = make_vector<reference_t>(n);
509
+
510
+ for (auto start = test_start_time(); within_time_budget(start);) {
511
+ fill_random(generator, a);
512
+
513
+ // Run kernel being tested
514
+ kernel_fn(a.raw_values_data(), n, k, a_stride, c.raw_values_data(), c_stride, 0, n);
515
+
516
+ // Reference: compute dots symmetric in reference precision
517
+ nk::dots_symmetric<scalar_t, reference_t, nk::no_simd_k>(a.values_data(), n, k, a_stride, c_ref.values_data(),
518
+ n * sizeof(reference_t));
519
+
520
+ // Compute sumsqs using reduce_moments
521
+ reference_t sum_unused;
522
+ for (std::size_t i = 0; i < n; ++i)
523
+ nk::reduce_moments<scalar_t, reference_t, reference_t, nk::no_simd_k>(
524
+ a.values_data() + i * k_values, k, sizeof(scalar_t), &sum_unused, sumsqs.values_data() + i);
525
+
526
+ // Convert dots to euclidean distances: diagonal=0, upper triangle uses formula
527
+ for (std::size_t i = 0; i < n; ++i) {
528
+ c_ref[i * n + i] = reference_t(0);
529
+ for (std::size_t j = i + 1; j < n; ++j) {
530
+ reference_t &c_cell = c_ref[i * n + j];
531
+ reference_t diff = sumsqs[i] + sumsqs[j] - reference_t(2) * c_cell;
532
+ c_cell = diff > reference_t(0) ? diff.sqrt() : reference_t(0);
533
+ }
534
+ }
535
+
536
+ // Only check upper triangle and diagonal
537
+ for (std::size_t i = 0; i < n; i++)
538
+ for (std::size_t j = i; j < n; j++) stats.accumulate(c[i * n + j], c_ref[i * n + j]);
539
+ }
540
+ return stats;
541
+ }
542
+
543
+ // Forward declarations for cross functions
544
+ void test_cross_serial();
545
+ void test_cross_x86();
546
+ void test_cross_amx();
547
+ void test_cross_arm();
548
+ void test_cross_sme();
549
+ void test_cross_blas();
550
+
551
+ #endif // NK_TEST_CROSS_HPP