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,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