usearch 2.21.3 → 2.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (602) hide show
  1. package/README.md +24 -24
  2. package/binding.gyp +15 -37
  3. package/c/CMakeLists.txt +4 -5
  4. package/c/README.md +7 -7
  5. package/c/lib.cpp +32 -14
  6. package/c/test.c +83 -1
  7. package/c/usearch.h +24 -3
  8. package/cpp/CMakeLists.txt +4 -0
  9. package/cpp/README.md +5 -5
  10. package/cpp/bench.cpp +97 -116
  11. package/cpp/test.cpp +117 -20
  12. package/include/usearch/index.hpp +235 -52
  13. package/include/usearch/index_dense.hpp +105 -40
  14. package/include/usearch/index_plugins.hpp +1387 -204
  15. package/javascript/dist/cjs/usearch.d.ts +8 -3
  16. package/javascript/dist/cjs/usearch.js +12 -4
  17. package/javascript/dist/esm/usearch.d.ts +8 -3
  18. package/javascript/dist/esm/usearch.js +12 -4
  19. package/javascript/lib.cpp +17 -0
  20. package/javascript/usearch.ts +14 -6
  21. package/numkong/.clang-tidy +30 -0
  22. package/{simsimd → numkong}/.cmake-format.py +18 -0
  23. package/numkong/.editorconfig +12 -0
  24. package/numkong/.git-blame-ignore-revs +123 -0
  25. package/numkong/.mailmap +15 -0
  26. package/numkong/.spi.yml +11 -0
  27. package/numkong/.swift-format +14 -0
  28. package/numkong/CITATION.cff +81 -0
  29. package/numkong/CONTRIBUTING.md +500 -0
  30. package/numkong/Cargo.toml +54 -0
  31. package/numkong/MANIFEST.in +8 -0
  32. package/numkong/Package.swift +84 -0
  33. package/numkong/README.md +569 -0
  34. package/numkong/bench/README.md +217 -0
  35. package/numkong/bench/bench-browser.html +323 -0
  36. package/numkong/bench/bench.cpp +344 -0
  37. package/numkong/bench/bench.hpp +816 -0
  38. package/numkong/bench/bench.js +148 -0
  39. package/numkong/bench/bench.mjs +616 -0
  40. package/numkong/bench/bench_attention.cpp +113 -0
  41. package/numkong/bench/bench_cast.cpp +264 -0
  42. package/numkong/bench/bench_cross_amx.cpp +62 -0
  43. package/numkong/bench/bench_cross_arm.cpp +245 -0
  44. package/numkong/bench/bench_cross_blas.cpp +309 -0
  45. package/numkong/bench/bench_cross_loongarch.cpp +106 -0
  46. package/numkong/bench/bench_cross_power.cpp +84 -0
  47. package/numkong/bench/bench_cross_rvv.cpp +121 -0
  48. package/numkong/bench/bench_cross_serial.cpp +151 -0
  49. package/numkong/bench/bench_cross_sme.cpp +163 -0
  50. package/numkong/bench/bench_cross_wasm.cpp +142 -0
  51. package/numkong/bench/bench_cross_x86.cpp +455 -0
  52. package/numkong/bench/bench_curved.cpp +210 -0
  53. package/numkong/bench/bench_dot.cpp +315 -0
  54. package/numkong/bench/bench_each.cpp +503 -0
  55. package/numkong/bench/bench_geospatial.cpp +112 -0
  56. package/numkong/bench/bench_maxsim.cpp +154 -0
  57. package/numkong/bench/bench_mesh.cpp +148 -0
  58. package/numkong/bench/bench_probability.cpp +60 -0
  59. package/numkong/bench/bench_reduce.cpp +371 -0
  60. package/numkong/bench/bench_set.cpp +73 -0
  61. package/numkong/bench/bench_sparse.cpp +198 -0
  62. package/numkong/bench/bench_spatial.cpp +347 -0
  63. package/numkong/bench/bench_trigonometry.cpp +137 -0
  64. package/numkong/bench/swift/Bench.swift +506 -0
  65. package/numkong/binding.gyp +169 -0
  66. package/numkong/build.rs +484 -0
  67. package/numkong/c/dispatch.h +512 -0
  68. package/numkong/c/dispatch_bf16.c +447 -0
  69. package/numkong/c/dispatch_bf16c.c +52 -0
  70. package/numkong/c/dispatch_e2m3.c +296 -0
  71. package/numkong/c/dispatch_e3m2.c +284 -0
  72. package/numkong/c/dispatch_e4m3.c +318 -0
  73. package/numkong/c/dispatch_e5m2.c +316 -0
  74. package/numkong/c/dispatch_f16.c +452 -0
  75. package/numkong/c/dispatch_f16c.c +58 -0
  76. package/numkong/c/dispatch_f32.c +434 -0
  77. package/numkong/c/dispatch_f32c.c +99 -0
  78. package/numkong/c/dispatch_f64.c +348 -0
  79. package/numkong/c/dispatch_f64c.c +98 -0
  80. package/numkong/c/dispatch_i16.c +96 -0
  81. package/numkong/c/dispatch_i32.c +89 -0
  82. package/numkong/c/dispatch_i4.c +153 -0
  83. package/numkong/c/dispatch_i64.c +86 -0
  84. package/numkong/c/dispatch_i8.c +348 -0
  85. package/numkong/c/dispatch_other.c +348 -0
  86. package/numkong/c/dispatch_u1.c +193 -0
  87. package/numkong/c/dispatch_u16.c +124 -0
  88. package/numkong/c/dispatch_u32.c +118 -0
  89. package/numkong/c/dispatch_u4.c +153 -0
  90. package/numkong/c/dispatch_u64.c +102 -0
  91. package/numkong/c/dispatch_u8.c +364 -0
  92. package/numkong/c/numkong.c +940 -0
  93. package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
  94. package/numkong/cmake/nk_isa_probe.cmake +90 -0
  95. package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
  96. package/numkong/cmake/nk_math_lib.cmake +46 -0
  97. package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
  98. package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
  99. package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
  100. package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
  101. package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
  102. package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
  103. package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
  104. package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
  105. package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
  106. package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
  107. package/numkong/cmake/toolchain-wasi.cmake +77 -0
  108. package/numkong/cmake/toolchain-wasm.cmake +70 -0
  109. package/numkong/cmake/toolchain-wasm64.cmake +62 -0
  110. package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
  111. package/numkong/include/README.md +643 -0
  112. package/numkong/include/module.modulemap +129 -0
  113. package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
  114. package/numkong/include/numkong/attention/sme.h +2075 -0
  115. package/numkong/include/numkong/attention.h +49 -0
  116. package/numkong/include/numkong/capabilities.h +930 -0
  117. package/numkong/include/numkong/cast/README.md +262 -0
  118. package/numkong/include/numkong/cast/diamond.h +64 -0
  119. package/numkong/include/numkong/cast/haswell.h +823 -0
  120. package/numkong/include/numkong/cast/icelake.h +475 -0
  121. package/numkong/include/numkong/cast/loongsonasx.h +252 -0
  122. package/numkong/include/numkong/cast/neon.h +1174 -0
  123. package/numkong/include/numkong/cast/powervsx.h +449 -0
  124. package/numkong/include/numkong/cast/rvv.h +970 -0
  125. package/numkong/include/numkong/cast/sapphire.h +262 -0
  126. package/numkong/include/numkong/cast/serial.h +2336 -0
  127. package/numkong/include/numkong/cast/skylake.h +915 -0
  128. package/numkong/include/numkong/cast/v128relaxed.h +537 -0
  129. package/numkong/include/numkong/cast.h +254 -0
  130. package/numkong/include/numkong/cast.hpp +44 -0
  131. package/numkong/include/numkong/curved/README.md +223 -0
  132. package/numkong/include/numkong/curved/genoa.h +182 -0
  133. package/numkong/include/numkong/curved/haswell.h +276 -0
  134. package/numkong/include/numkong/curved/neon.h +329 -0
  135. package/numkong/include/numkong/curved/neonbfdot.h +211 -0
  136. package/numkong/include/numkong/curved/rvv.h +305 -0
  137. package/numkong/include/numkong/curved/serial.h +207 -0
  138. package/numkong/include/numkong/curved/skylake.h +457 -0
  139. package/numkong/include/numkong/curved/smef64.h +530 -0
  140. package/numkong/include/numkong/curved.h +513 -0
  141. package/numkong/include/numkong/curved.hpp +144 -0
  142. package/numkong/include/numkong/dot/README.md +442 -0
  143. package/numkong/include/numkong/dot/alder.h +563 -0
  144. package/numkong/include/numkong/dot/diamond.h +158 -0
  145. package/numkong/include/numkong/dot/genoa.h +289 -0
  146. package/numkong/include/numkong/dot/haswell.h +1723 -0
  147. package/numkong/include/numkong/dot/icelake.h +997 -0
  148. package/numkong/include/numkong/dot/loongsonasx.h +671 -0
  149. package/numkong/include/numkong/dot/neon.h +869 -0
  150. package/numkong/include/numkong/dot/neonbfdot.h +243 -0
  151. package/numkong/include/numkong/dot/neonfhm.h +358 -0
  152. package/numkong/include/numkong/dot/neonfp8.h +323 -0
  153. package/numkong/include/numkong/dot/neonsdot.h +622 -0
  154. package/numkong/include/numkong/dot/powervsx.h +752 -0
  155. package/numkong/include/numkong/dot/rvv.h +722 -0
  156. package/numkong/include/numkong/dot/rvvbb.h +72 -0
  157. package/numkong/include/numkong/dot/rvvbf16.h +123 -0
  158. package/numkong/include/numkong/dot/rvvhalf.h +129 -0
  159. package/numkong/include/numkong/dot/sapphire.h +141 -0
  160. package/numkong/include/numkong/dot/serial.h +874 -0
  161. package/numkong/include/numkong/dot/sierra.h +405 -0
  162. package/numkong/include/numkong/dot/skylake.h +1116 -0
  163. package/numkong/include/numkong/dot/sve.h +420 -0
  164. package/numkong/include/numkong/dot/svebfdot.h +75 -0
  165. package/numkong/include/numkong/dot/svehalf.h +168 -0
  166. package/numkong/include/numkong/dot/svesdot.h +90 -0
  167. package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
  168. package/numkong/include/numkong/dot.h +1136 -0
  169. package/numkong/include/numkong/dot.hpp +94 -0
  170. package/numkong/include/numkong/dots/README.md +496 -0
  171. package/numkong/include/numkong/dots/alder.h +117 -0
  172. package/numkong/include/numkong/dots/diamond.h +86 -0
  173. package/numkong/include/numkong/dots/genoa.h +100 -0
  174. package/numkong/include/numkong/dots/graniteamx.h +733 -0
  175. package/numkong/include/numkong/dots/haswell.h +310 -0
  176. package/numkong/include/numkong/dots/icelake.h +180 -0
  177. package/numkong/include/numkong/dots/loongsonasx.h +176 -0
  178. package/numkong/include/numkong/dots/neon.h +123 -0
  179. package/numkong/include/numkong/dots/neonbfdot.h +59 -0
  180. package/numkong/include/numkong/dots/neonfhm.h +96 -0
  181. package/numkong/include/numkong/dots/neonfp8.h +99 -0
  182. package/numkong/include/numkong/dots/neonsdot.h +144 -0
  183. package/numkong/include/numkong/dots/powervsx.h +194 -0
  184. package/numkong/include/numkong/dots/rvv.h +2593 -0
  185. package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
  186. package/numkong/include/numkong/dots/serial.h +2867 -0
  187. package/numkong/include/numkong/dots/sierra.h +100 -0
  188. package/numkong/include/numkong/dots/skylake.h +207 -0
  189. package/numkong/include/numkong/dots/sme.h +5041 -0
  190. package/numkong/include/numkong/dots/smebi32.h +477 -0
  191. package/numkong/include/numkong/dots/smef64.h +1328 -0
  192. package/numkong/include/numkong/dots/smehalf.h +47 -0
  193. package/numkong/include/numkong/dots/v128relaxed.h +317 -0
  194. package/numkong/include/numkong/dots.h +3110 -0
  195. package/numkong/include/numkong/dots.hpp +641 -0
  196. package/numkong/include/numkong/each/README.md +465 -0
  197. package/numkong/include/numkong/each/haswell.h +1658 -0
  198. package/numkong/include/numkong/each/icelake.h +272 -0
  199. package/numkong/include/numkong/each/neon.h +1138 -0
  200. package/numkong/include/numkong/each/neonbfdot.h +211 -0
  201. package/numkong/include/numkong/each/neonhalf.h +318 -0
  202. package/numkong/include/numkong/each/rvv.h +1121 -0
  203. package/numkong/include/numkong/each/sapphire.h +343 -0
  204. package/numkong/include/numkong/each/serial.h +282 -0
  205. package/numkong/include/numkong/each/skylake.h +1562 -0
  206. package/numkong/include/numkong/each/v128relaxed.h +562 -0
  207. package/numkong/include/numkong/each.h +2232 -0
  208. package/numkong/include/numkong/each.hpp +434 -0
  209. package/numkong/include/numkong/geospatial/README.md +147 -0
  210. package/numkong/include/numkong/geospatial/haswell.h +633 -0
  211. package/numkong/include/numkong/geospatial/neon.h +615 -0
  212. package/numkong/include/numkong/geospatial/rvv.h +701 -0
  213. package/numkong/include/numkong/geospatial/serial.h +309 -0
  214. package/numkong/include/numkong/geospatial/skylake.h +613 -0
  215. package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
  216. package/numkong/include/numkong/geospatial.h +453 -0
  217. package/numkong/include/numkong/geospatial.hpp +235 -0
  218. package/numkong/include/numkong/matrix.hpp +336 -0
  219. package/numkong/include/numkong/maxsim/README.md +187 -0
  220. package/numkong/include/numkong/maxsim/alder.h +511 -0
  221. package/numkong/include/numkong/maxsim/genoa.h +115 -0
  222. package/numkong/include/numkong/maxsim/haswell.h +553 -0
  223. package/numkong/include/numkong/maxsim/icelake.h +480 -0
  224. package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
  225. package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
  226. package/numkong/include/numkong/maxsim/serial.h +490 -0
  227. package/numkong/include/numkong/maxsim/sme.h +993 -0
  228. package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
  229. package/numkong/include/numkong/maxsim.h +571 -0
  230. package/numkong/include/numkong/maxsim.hpp +133 -0
  231. package/numkong/include/numkong/mesh/README.md +219 -0
  232. package/numkong/include/numkong/mesh/haswell.h +2013 -0
  233. package/numkong/include/numkong/mesh/neon.h +1821 -0
  234. package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
  235. package/numkong/include/numkong/mesh/rvv.h +936 -0
  236. package/numkong/include/numkong/mesh/serial.h +721 -0
  237. package/numkong/include/numkong/mesh/skylake.h +2344 -0
  238. package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
  239. package/numkong/include/numkong/mesh.h +666 -0
  240. package/numkong/include/numkong/mesh.hpp +701 -0
  241. package/numkong/include/numkong/numkong.h +78 -0
  242. package/numkong/include/numkong/numkong.hpp +58 -0
  243. package/numkong/include/numkong/probability/README.md +177 -0
  244. package/numkong/include/numkong/probability/haswell.h +267 -0
  245. package/numkong/include/numkong/probability/neon.h +255 -0
  246. package/numkong/include/numkong/probability/rvv.h +414 -0
  247. package/numkong/include/numkong/probability/serial.h +181 -0
  248. package/numkong/include/numkong/probability/skylake.h +324 -0
  249. package/numkong/include/numkong/probability.h +380 -0
  250. package/numkong/include/numkong/probability.hpp +120 -0
  251. package/numkong/include/numkong/random.h +50 -0
  252. package/numkong/include/numkong/random.hpp +285 -0
  253. package/numkong/include/numkong/reduce/README.md +552 -0
  254. package/numkong/include/numkong/reduce/alder.h +636 -0
  255. package/numkong/include/numkong/reduce/genoa.h +201 -0
  256. package/numkong/include/numkong/reduce/haswell.h +3785 -0
  257. package/numkong/include/numkong/reduce/icelake.h +549 -0
  258. package/numkong/include/numkong/reduce/neon.h +3980 -0
  259. package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
  260. package/numkong/include/numkong/reduce/neonfhm.h +293 -0
  261. package/numkong/include/numkong/reduce/neonsdot.h +357 -0
  262. package/numkong/include/numkong/reduce/rvv.h +3533 -0
  263. package/numkong/include/numkong/reduce/serial.h +753 -0
  264. package/numkong/include/numkong/reduce/sierra.h +338 -0
  265. package/numkong/include/numkong/reduce/skylake.h +3794 -0
  266. package/numkong/include/numkong/reduce/sve.h +52 -0
  267. package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
  268. package/numkong/include/numkong/reduce.h +1582 -0
  269. package/numkong/include/numkong/reduce.hpp +778 -0
  270. package/numkong/include/numkong/scalar/README.md +89 -0
  271. package/numkong/include/numkong/scalar/haswell.h +122 -0
  272. package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
  273. package/numkong/include/numkong/scalar/neon.h +122 -0
  274. package/numkong/include/numkong/scalar/neonhalf.h +70 -0
  275. package/numkong/include/numkong/scalar/powervsx.h +96 -0
  276. package/numkong/include/numkong/scalar/rvv.h +211 -0
  277. package/numkong/include/numkong/scalar/sapphire.h +74 -0
  278. package/numkong/include/numkong/scalar/serial.h +332 -0
  279. package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
  280. package/numkong/include/numkong/scalar.h +696 -0
  281. package/numkong/include/numkong/set/README.md +179 -0
  282. package/numkong/include/numkong/set/haswell.h +334 -0
  283. package/numkong/include/numkong/set/icelake.h +485 -0
  284. package/numkong/include/numkong/set/loongsonasx.h +181 -0
  285. package/numkong/include/numkong/set/neon.h +363 -0
  286. package/numkong/include/numkong/set/powervsx.h +326 -0
  287. package/numkong/include/numkong/set/rvv.h +226 -0
  288. package/numkong/include/numkong/set/rvvbb.h +117 -0
  289. package/numkong/include/numkong/set/serial.h +174 -0
  290. package/numkong/include/numkong/set/sve.h +187 -0
  291. package/numkong/include/numkong/set/v128relaxed.h +240 -0
  292. package/numkong/include/numkong/set.h +471 -0
  293. package/numkong/include/numkong/set.hpp +114 -0
  294. package/numkong/include/numkong/sets/README.md +149 -0
  295. package/numkong/include/numkong/sets/haswell.h +63 -0
  296. package/numkong/include/numkong/sets/icelake.h +66 -0
  297. package/numkong/include/numkong/sets/loongsonasx.h +52 -0
  298. package/numkong/include/numkong/sets/neon.h +61 -0
  299. package/numkong/include/numkong/sets/powervsx.h +65 -0
  300. package/numkong/include/numkong/sets/serial.h +43 -0
  301. package/numkong/include/numkong/sets/smebi32.h +1135 -0
  302. package/numkong/include/numkong/sets/v128relaxed.h +58 -0
  303. package/numkong/include/numkong/sets.h +382 -0
  304. package/numkong/include/numkong/sparse/README.md +156 -0
  305. package/numkong/include/numkong/sparse/icelake.h +463 -0
  306. package/numkong/include/numkong/sparse/neon.h +288 -0
  307. package/numkong/include/numkong/sparse/serial.h +117 -0
  308. package/numkong/include/numkong/sparse/sve2.h +504 -0
  309. package/numkong/include/numkong/sparse/turin.h +322 -0
  310. package/numkong/include/numkong/sparse.h +363 -0
  311. package/numkong/include/numkong/sparse.hpp +113 -0
  312. package/numkong/include/numkong/spatial/README.md +439 -0
  313. package/numkong/include/numkong/spatial/alder.h +604 -0
  314. package/numkong/include/numkong/spatial/diamond.h +240 -0
  315. package/numkong/include/numkong/spatial/genoa.h +222 -0
  316. package/numkong/include/numkong/spatial/haswell.h +979 -0
  317. package/numkong/include/numkong/spatial/icelake.h +1067 -0
  318. package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
  319. package/numkong/include/numkong/spatial/neon.h +846 -0
  320. package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
  321. package/numkong/include/numkong/spatial/neonfp8.h +258 -0
  322. package/numkong/include/numkong/spatial/neonsdot.h +429 -0
  323. package/numkong/include/numkong/spatial/powervsx.h +738 -0
  324. package/numkong/include/numkong/spatial/rvv.h +991 -0
  325. package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
  326. package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
  327. package/numkong/include/numkong/spatial/serial.h +347 -0
  328. package/numkong/include/numkong/spatial/sierra.h +516 -0
  329. package/numkong/include/numkong/spatial/skylake.h +605 -0
  330. package/numkong/include/numkong/spatial/sve.h +246 -0
  331. package/numkong/include/numkong/spatial/svebfdot.h +125 -0
  332. package/numkong/include/numkong/spatial/svehalf.h +136 -0
  333. package/numkong/include/numkong/spatial/svesdot.h +143 -0
  334. package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
  335. package/numkong/include/numkong/spatial.h +1681 -0
  336. package/numkong/include/numkong/spatial.hpp +183 -0
  337. package/numkong/include/numkong/spatials/README.md +580 -0
  338. package/numkong/include/numkong/spatials/alder.h +94 -0
  339. package/numkong/include/numkong/spatials/diamond.h +82 -0
  340. package/numkong/include/numkong/spatials/genoa.h +94 -0
  341. package/numkong/include/numkong/spatials/graniteamx.h +173 -0
  342. package/numkong/include/numkong/spatials/haswell.h +219 -0
  343. package/numkong/include/numkong/spatials/icelake.h +113 -0
  344. package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
  345. package/numkong/include/numkong/spatials/neon.h +109 -0
  346. package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
  347. package/numkong/include/numkong/spatials/neonfhm.h +92 -0
  348. package/numkong/include/numkong/spatials/neonfp8.h +111 -0
  349. package/numkong/include/numkong/spatials/neonsdot.h +143 -0
  350. package/numkong/include/numkong/spatials/powervsx.h +153 -0
  351. package/numkong/include/numkong/spatials/rvv.h +1976 -0
  352. package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
  353. package/numkong/include/numkong/spatials/serial.h +248 -0
  354. package/numkong/include/numkong/spatials/sierra.h +96 -0
  355. package/numkong/include/numkong/spatials/skylake.h +184 -0
  356. package/numkong/include/numkong/spatials/sme.h +1927 -0
  357. package/numkong/include/numkong/spatials/smef64.h +483 -0
  358. package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
  359. package/numkong/include/numkong/spatials.h +3374 -0
  360. package/numkong/include/numkong/spatials.hpp +509 -0
  361. package/numkong/include/numkong/tensor.hpp +1981 -0
  362. package/numkong/include/numkong/trigonometry/README.md +184 -0
  363. package/numkong/include/numkong/trigonometry/haswell.h +653 -0
  364. package/numkong/include/numkong/trigonometry/neon.h +638 -0
  365. package/numkong/include/numkong/trigonometry/rvv.h +700 -0
  366. package/numkong/include/numkong/trigonometry/serial.h +703 -0
  367. package/numkong/include/numkong/trigonometry/skylake.h +725 -0
  368. package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
  369. package/numkong/include/numkong/trigonometry.h +467 -0
  370. package/numkong/include/numkong/trigonometry.hpp +166 -0
  371. package/numkong/include/numkong/types.h +1695 -0
  372. package/numkong/include/numkong/types.hpp +6027 -0
  373. package/numkong/include/numkong/vector.hpp +766 -0
  374. package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
  375. package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
  376. package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
  377. package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
  378. package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
  379. package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
  380. package/numkong/javascript/README.md +254 -0
  381. package/numkong/javascript/node-gyp-build.d.ts +4 -0
  382. package/numkong/javascript/numkong-browser.ts +40 -0
  383. package/numkong/javascript/numkong-wasm.ts +750 -0
  384. package/numkong/javascript/numkong.c +712 -0
  385. package/numkong/javascript/numkong.ts +613 -0
  386. package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
  387. package/numkong/javascript/tsconfig-cjs.json +13 -0
  388. package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
  389. package/numkong/javascript/types.ts +784 -0
  390. package/numkong/numkong.gypi +104 -0
  391. package/numkong/package.json +108 -0
  392. package/numkong/probes/arm_neon.c +8 -0
  393. package/numkong/probes/arm_neon_bfdot.c +9 -0
  394. package/numkong/probes/arm_neon_fhm.c +9 -0
  395. package/numkong/probes/arm_neon_half.c +8 -0
  396. package/numkong/probes/arm_neon_sdot.c +9 -0
  397. package/numkong/probes/arm_neonfp8.c +9 -0
  398. package/numkong/probes/arm_sme.c +16 -0
  399. package/numkong/probes/arm_sme2.c +16 -0
  400. package/numkong/probes/arm_sme2p1.c +16 -0
  401. package/numkong/probes/arm_sme_bf16.c +16 -0
  402. package/numkong/probes/arm_sme_bi32.c +16 -0
  403. package/numkong/probes/arm_sme_f64.c +16 -0
  404. package/numkong/probes/arm_sme_fa64.c +14 -0
  405. package/numkong/probes/arm_sme_half.c +16 -0
  406. package/numkong/probes/arm_sme_lut2.c +15 -0
  407. package/numkong/probes/arm_sve.c +18 -0
  408. package/numkong/probes/arm_sve2.c +20 -0
  409. package/numkong/probes/arm_sve2p1.c +18 -0
  410. package/numkong/probes/arm_sve_bfdot.c +20 -0
  411. package/numkong/probes/arm_sve_half.c +18 -0
  412. package/numkong/probes/arm_sve_sdot.c +21 -0
  413. package/numkong/probes/loongarch_lasx.c +12 -0
  414. package/numkong/probes/power_vsx.c +12 -0
  415. package/numkong/probes/probe.js +127 -0
  416. package/numkong/probes/riscv_rvv.c +14 -0
  417. package/numkong/probes/riscv_rvv_bb.c +15 -0
  418. package/numkong/probes/riscv_rvv_bf16.c +17 -0
  419. package/numkong/probes/riscv_rvv_half.c +14 -0
  420. package/numkong/probes/wasm_v128relaxed.c +11 -0
  421. package/numkong/probes/x86_alder.c +17 -0
  422. package/numkong/probes/x86_diamond.c +17 -0
  423. package/numkong/probes/x86_genoa.c +17 -0
  424. package/numkong/probes/x86_graniteamx.c +19 -0
  425. package/numkong/probes/x86_haswell.c +11 -0
  426. package/numkong/probes/x86_icelake.c +17 -0
  427. package/numkong/probes/x86_sapphire.c +16 -0
  428. package/numkong/probes/x86_sapphireamx.c +18 -0
  429. package/numkong/probes/x86_sierra.c +17 -0
  430. package/numkong/probes/x86_skylake.c +15 -0
  431. package/numkong/probes/x86_turin.c +17 -0
  432. package/numkong/rust/README.md +698 -0
  433. package/numkong/rust/capabilities.rs +96 -0
  434. package/numkong/rust/cast.rs +314 -0
  435. package/numkong/rust/curved.rs +391 -0
  436. package/numkong/rust/each.rs +2721 -0
  437. package/numkong/rust/geospatial.rs +343 -0
  438. package/numkong/rust/matrix.rs +5424 -0
  439. package/numkong/rust/maxsim.rs +540 -0
  440. package/numkong/rust/mesh.rs +837 -0
  441. package/numkong/rust/numkong.rs +409 -0
  442. package/numkong/rust/probability.rs +272 -0
  443. package/numkong/rust/reduce.rs +1249 -0
  444. package/numkong/rust/set.rs +194 -0
  445. package/numkong/rust/sparse.rs +513 -0
  446. package/numkong/rust/spatial.rs +1815 -0
  447. package/numkong/rust/tensor.rs +7565 -0
  448. package/numkong/rust/types.rs +3666 -0
  449. package/numkong/rust/vector.rs +1899 -0
  450. package/numkong/rustfmt.toml +2 -0
  451. package/numkong/swift/Matrix.swift +1388 -0
  452. package/numkong/swift/MaxSim.swift +151 -0
  453. package/numkong/swift/NumKong.swift +283 -0
  454. package/numkong/swift/Numerics.swift +329 -0
  455. package/numkong/swift/README.md +433 -0
  456. package/numkong/swift/Scalar.swift +741 -0
  457. package/numkong/swift/Tensor.swift +209 -0
  458. package/numkong/test/README.md +315 -0
  459. package/numkong/test/playwright.config.ts +16 -0
  460. package/numkong/test/swift/Test.swift +534 -0
  461. package/numkong/test/test-browser-bundle-runner.mjs +36 -0
  462. package/numkong/test/test-browser-bundle.html +188 -0
  463. package/numkong/test/test-browser-runner.mjs +43 -0
  464. package/numkong/test/test-browser.html +305 -0
  465. package/numkong/test/test-dtypes.mjs +453 -0
  466. package/numkong/test/test-wasm.mjs +267 -0
  467. package/numkong/test/test.cpp +442 -0
  468. package/numkong/test/test.hpp +580 -0
  469. package/numkong/test/test.mjs +363 -0
  470. package/numkong/test/test_base.py +1041 -0
  471. package/numkong/test/test_cast.cpp +242 -0
  472. package/numkong/test/test_cross.hpp +551 -0
  473. package/numkong/test/test_cross.py +467 -0
  474. package/numkong/test/test_cross_amx.cpp +50 -0
  475. package/numkong/test/test_cross_arm.cpp +225 -0
  476. package/numkong/test/test_cross_blas.cpp +354 -0
  477. package/numkong/test/test_cross_loongarch.cpp +90 -0
  478. package/numkong/test/test_cross_power.cpp +73 -0
  479. package/numkong/test/test_cross_rvv.cpp +109 -0
  480. package/numkong/test/test_cross_serial.cpp +181 -0
  481. package/numkong/test/test_cross_sme.cpp +148 -0
  482. package/numkong/test/test_cross_wasm.cpp +141 -0
  483. package/numkong/test/test_cross_x86.cpp +442 -0
  484. package/numkong/test/test_curved.cpp +182 -0
  485. package/numkong/test/test_curved.py +207 -0
  486. package/numkong/test/test_dot.cpp +353 -0
  487. package/numkong/test/test_dot.py +296 -0
  488. package/numkong/test/test_each.cpp +437 -0
  489. package/numkong/test/test_each.py +756 -0
  490. package/numkong/test/test_geospatial.cpp +155 -0
  491. package/numkong/test/test_geospatial.py +241 -0
  492. package/numkong/test/test_maxsim.cpp +138 -0
  493. package/numkong/test/test_maxsim.py +209 -0
  494. package/numkong/test/test_mesh.cpp +203 -0
  495. package/numkong/test/test_mesh.py +394 -0
  496. package/numkong/test/test_probability.cpp +136 -0
  497. package/numkong/test/test_probability.py +166 -0
  498. package/numkong/test/test_reduce.cpp +563 -0
  499. package/numkong/test/test_reduce.py +781 -0
  500. package/numkong/test/test_set.cpp +151 -0
  501. package/numkong/test/test_set.py +120 -0
  502. package/numkong/test/test_similarities.py +579 -0
  503. package/numkong/test/test_sparse.cpp +121 -0
  504. package/numkong/test/test_sparse.py +118 -0
  505. package/numkong/test/test_spatial.cpp +518 -0
  506. package/numkong/test/test_spatial.py +269 -0
  507. package/numkong/test/test_tensor.cpp +884 -0
  508. package/numkong/test/test_tensor.py +1417 -0
  509. package/numkong/test/test_trigonometry.cpp +156 -0
  510. package/numkong/test/test_trigonometry.py +180 -0
  511. package/package.json +7 -8
  512. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  513. package/prebuilds/linux-arm64/usearch.node +0 -0
  514. package/prebuilds/linux-x64/usearch.node +0 -0
  515. package/fp16/CMakeLists.txt +0 -176
  516. package/fp16/LICENSE +0 -11
  517. package/fp16/README.md +0 -20
  518. package/fp16/bench/alt-element.cc +0 -89
  519. package/fp16/bench/from-alt-array.cc +0 -175
  520. package/fp16/bench/from-ieee-array.cc +0 -399
  521. package/fp16/bench/ieee-element.cc +0 -272
  522. package/fp16/bench/to-alt-array.cc +0 -91
  523. package/fp16/bench/to-ieee-array.cc +0 -303
  524. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  525. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  526. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  527. package/fp16/configure.py +0 -65
  528. package/fp16/confu.yaml +0 -8
  529. package/fp16/include/fp16/__init__.py +0 -0
  530. package/fp16/include/fp16/avx.py +0 -50
  531. package/fp16/include/fp16/avx2.py +0 -53
  532. package/fp16/include/fp16/bitcasts.h +0 -92
  533. package/fp16/include/fp16/fp16.h +0 -451
  534. package/fp16/include/fp16/psimd.h +0 -131
  535. package/fp16/include/fp16.h +0 -11
  536. package/fp16/jni/Android.mk +0 -6
  537. package/fp16/jni/Application.mk +0 -4
  538. package/fp16/test/alt-from-fp32-value.cc +0 -498
  539. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  540. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  541. package/fp16/test/alt-to-fp32-value.cc +0 -348
  542. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  543. package/fp16/test/bitcasts.cc +0 -56
  544. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  545. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  546. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  547. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  548. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  549. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  550. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  551. package/fp16/test/peachpy/stubs.py +0 -38
  552. package/fp16/test/tables.cc +0 -530
  553. package/fp16/test/tables.h +0 -13
  554. package/fp16/third-party/THHalf.h +0 -92
  555. package/fp16/third-party/eigen-half.h +0 -170
  556. package/fp16/third-party/float16-compressor.h +0 -80
  557. package/fp16/third-party/half.hpp +0 -2916
  558. package/fp16/third-party/npy-halffloat.h +0 -328
  559. package/simsimd/.git-blame-ignore-revs +0 -2
  560. package/simsimd/CONTRIBUTING.md +0 -321
  561. package/simsimd/Cargo.toml +0 -49
  562. package/simsimd/MANIFEST.in +0 -4
  563. package/simsimd/Package.swift +0 -28
  564. package/simsimd/README.md +0 -1493
  565. package/simsimd/binding.gyp +0 -35
  566. package/simsimd/build.rs +0 -70
  567. package/simsimd/c/lib.c +0 -374
  568. package/simsimd/include/module.modulemap +0 -4
  569. package/simsimd/include/simsimd/binary.h +0 -486
  570. package/simsimd/include/simsimd/curved.h +0 -1541
  571. package/simsimd/include/simsimd/dot.h +0 -1853
  572. package/simsimd/include/simsimd/elementwise.h +0 -2465
  573. package/simsimd/include/simsimd/geospatial.h +0 -43
  574. package/simsimd/include/simsimd/mesh.h +0 -69
  575. package/simsimd/include/simsimd/probability.h +0 -606
  576. package/simsimd/include/simsimd/simsimd.h +0 -2567
  577. package/simsimd/include/simsimd/sparse.h +0 -1384
  578. package/simsimd/include/simsimd/spatial.h +0 -2335
  579. package/simsimd/include/simsimd/types.h +0 -666
  580. package/simsimd/javascript/fallback.ts +0 -233
  581. package/simsimd/javascript/lib.c +0 -125
  582. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  583. package/simsimd/javascript/simsimd.ts +0 -179
  584. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  585. package/simsimd/package-lock.json +0 -1761
  586. package/simsimd/package.json +0 -61
  587. package/simsimd/rust/lib.rs +0 -1821
  588. package/simsimd/scripts/bench.cxx +0 -1170
  589. package/simsimd/scripts/bench.ipynb +0 -187
  590. package/simsimd/scripts/bench.js +0 -127
  591. package/simsimd/scripts/bench.rs +0 -876
  592. package/simsimd/scripts/bench_vectors.py +0 -734
  593. package/simsimd/scripts/bench_vectors_live.py +0 -213
  594. package/simsimd/scripts/test.c +0 -187
  595. package/simsimd/scripts/test.mjs +0 -220
  596. package/simsimd/scripts/test.py +0 -1505
  597. package/simsimd/swift/SimSIMD.swift +0 -149
  598. package/simsimd/swift/Test.swift +0 -128
  599. /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
  600. /package/{simsimd → numkong}/LICENSE +0 -0
  601. /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
  602. /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
@@ -0,0 +1,1681 @@
1
+ /**
2
+ * @brief SIMD-accelerated Spatial Similarity Measures.
3
+ * @file include/numkong/spatial.h
4
+ * @author Ash Vardanian
5
+ * @date March 14, 2023
6
+ *
7
+ * Contains following similarity measures:
8
+ *
9
+ * - L2 (Euclidean) regular and squared distance
10
+ * - Cosine (Angular) distance - @b not similarity!
11
+ *
12
+ * For dtypes:
13
+ *
14
+ * - f64: 64-bit IEEE floating point numbers → 64-bit floats
15
+ * - f32: 32-bit IEEE floating point numbers → 64-bit floats
16
+ * - f16: 16-bit IEEE floating point numbers → 32-bit floats
17
+ * - bf16: 16-bit brain floating point numbers → 32-bit floats
18
+ * - e4m3: 8-bit e4m3 floating point numbers → 32-bit floats
19
+ * - e5m2: 8-bit e5m2 floating point numbers → 32-bit floats
20
+ * - e2m3: 8-bit e2m3 floating point numbers (MX) → 32-bit floats
21
+ * - e3m2: 8-bit e3m2 floating point numbers (MX) → 32-bit floats
22
+ * - i8: 8-bit signed integers → 32-bit floats
23
+ * - u8: 8-bit unsigned integers → 32-bit floats
24
+ * - i4: 4-bit signed integers (packed pairs) → 32-bit floats
25
+ * - u4: 4-bit unsigned integers (packed pairs) → 32-bit floats
26
+ *
27
+ * For hardware architectures:
28
+ *
29
+ * - Arm: NEON, NEON+F16, NEON+BF16, NEON+SDOT, SVE, SVE+F16, SVE+BF16
30
+ * - x86: Haswell, Skylake, Ice Lake, Genoa, Sapphire Rapids, Sierra Forest
31
+ * - RISC-V: RVV, RVV+BF16, RVV+HALF
32
+ * - WASM: V128Relaxed
33
+ *
34
+ * @section numerical_stability Numerical Stability
35
+ *
36
+ * Serial kernels use compensated summation for dot, a_norm_sq, b_norm_sq — O(1) error growth regardless of vector
37
+ * dimension. `f32` public outputs widen to `f64`, so widened paths use `f64` arithmetic and `sqrt64`.
38
+ * Angular finalization uses rsqrt via magic constant + 3 Newton-Raphson iterations (f32,
39
+ * ~34.9 correct bits) or 4 iterations (f64, ~69.3 correct bits), then clamps result ≥ 0.
40
+ * L2 uses conditional `dist_sq > 0 ? sqrt(dist_sq) : 0` to avoid NaN from rounding.
41
+ * Integer types (i8/u8/i4/u4) accumulate squared differences in i32 — overflows at
42
+ * n > 2^31/65,025 ≈ 33K for i8 (max diff² = 255²). Output is cast to f32.
43
+ *
44
+ * @section streaming_api Streaming API
45
+ *
46
+ * Angular and L2 distances can be computed from a single dot-product stream and precomputed magnitudes.
47
+ * The streaming helpers operate on 512-bit blocks (`nk_b512_vec_t`) and only accumulate $A*B$.
48
+ * Finalization takes the magnitudes of the full vectors (L2 norms) and computes the distance.
49
+ * Let the following be computed over the full vectors:
50
+ *
51
+ * ab = Σᵢ (aᵢ × bᵢ)
52
+ * ‖a‖ = √(Σᵢ aᵢ²)
53
+ * ‖b‖ = √(Σᵢ bᵢ²)
54
+ *
55
+ * Finalization formulas:
56
+ *
57
+ * angular(a, b) = 1 − ab / (‖a‖ × ‖b‖)
58
+ * l2(a, b) = √( ‖a‖² + ‖b‖² − 2 × ab )
59
+ *
60
+ * The angular distance is clamped to ≥ 0, with a 0 result when both norms are zero and a 1 result when $ab$ is zero.
61
+ * L2 clamps the argument of the square root at 0 to avoid negative values from rounding.
62
+ *
63
+ * @code{.c}
64
+ * nk_b512_vec_t a_block, b_block;
65
+ * nk_f32_t a_norm = ..., b_norm = ...; // Precomputed L2 norms of full vectors
66
+ * nk_angular_f32x8_state_haswell_t state; // Often equivalent to dot-product state
67
+ * nk_angular_f32x8_init_haswell(&state);
68
+ * nk_angular_f32x8_update_haswell(&state, a_block, b_block);
69
+ * nk_angular_f32x8_finalize_haswell(&state, a_norm, b_norm, &distance);
70
+ * @endcode
71
+ *
72
+ * @section rsqrt_notes Reciprocal Square Root and Newton-Raphson Notes
73
+ *
74
+ * Angular distance normalization uses reciprocal square roots to avoid the
75
+ * latency of full sqrt/div pipelines. We refine the rsqrt estimate with one
76
+ * (x86) or two (Arm NEON) Newton-Raphson iterations to reduce error.
77
+ *
78
+ * Relevant instructions and caveats:
79
+ *
80
+ * Intrinsic Instruction Notes
81
+ * _mm_rsqrt_ps VRSQRTPS fast approx; refine with NR
82
+ * _mm_maskz_rsqrt14_pd VRSQRT14PD higher-precision approx; MSVC masked-only
83
+ * _mm_sqrt_ps/_mm_sqrt_pd VSQRTPS/VSQRTPD higher latency, sqrt/div unit
84
+ *
85
+ * Latency/port notes (rule of thumb):
86
+ * - On Intel client cores, sqrt/rsqrt execute on the divide/sqrt unit (often
87
+ * port 0) and can bottleneck tight loops.
88
+ * - NR refinement uses mul/FMA ports and amortizes well when `ab` is reduced
89
+ * to a scalar and reused for finalization.
90
+ * - Arm NEON `rsqrt` accuracy is coarse; we apply two refinement steps to keep
91
+ * angular distance error bounded.
92
+ *
93
+ * @section x86_instructions Relevant x86 Instructions
94
+ *
95
+ * AVX2 lacks signed 8-bit dot products, so Haswell widens to i16 and uses VPMADDWD.
96
+ * AVX-512 VNNI replaces that with VPDPWSSD. BF16 uses VDPBF16PS where available to avoid
97
+ * convert+FMA sequences; if the ISA lacks it, we fall back to f32 FMA in the AVX2/serial:
98
+ *
99
+ * Intrinsic Instruction Icelake Genoa
100
+ * _mm256_fmadd_ps VFMADD231PS (YMM, YMM, YMM) 4cy @ p01 4cy @ p01
101
+ * _mm256_fmadd_pd VFMADD231PD (YMM, YMM, YMM) 4cy @ p01 4cy @ p01
102
+ * _mm256_madd_epi16 VPMADDWD (YMM, YMM, YMM) 5cy @ p01 3cy @ p01
103
+ * _mm512_dpwssd_epi32 VPDPWSSD (ZMM, K, ZMM, ZMM) 5cy @ p05 4cy @ p01
104
+ * _mm512_dpbf16_ps VDPBF16PS (ZMM, K, ZMM, ZMM) n/a 6cy @ p01
105
+ * _mm_rsqrt_ps VRSQRTPS (XMM, XMM) 5cy @ p0 4cy @ p01
106
+ * _mm_maskz_rsqrt14_pd VRSQRT14PD (XMM, K, XMM) 4cy @ p0 5cy @ p01
107
+ * _mm_sqrt_ps VSQRTPS (XMM, XMM) 12cy @ p0 15cy @ p01
108
+ *
109
+ * @section arm_instructions Relevant Arm Instructions
110
+ *
111
+ * The NEON/SVE kernels in this header are structured around FMLA/SDOT/BFDOT loops,
112
+ * which is why we avoid mul+add splits and keep reductions to scalars before square roots.
113
+ * Dot-product kernels for i8/u8 are only built when the "dotprod+i8mm" target is enabled;
114
+ * otherwise we rely on the serial backends. BF16 kernels are enabled only with BF16 dot
115
+ * instructions skipping `vbfmlal` and `vbfmlalt` alternatives to limit shuffle overhead
116
+ * and code complexity.
117
+ *
118
+ * Intrinsic Instruction M1 Firestorm
119
+ * vfmaq_f32 FMLA.S (vec) 4c / 4c
120
+ * vfmaq_f64 FMLA.D (vec) 4c / 4c
121
+ * vdotq_s32 SDOT.B (vec) 3c / 4c
122
+ * vbfdotq_f32 BFDOT (vec) n/a
123
+ * vrsqrteq_f32 FRSQRTE.S (vec) 3c / 1c
124
+ * vrsqrtsq_f32 FRSQRTS.S (vec) 4c / 4c
125
+ * vsqrtq_f32 FSQRT.S (vec) 10c / 0.5c
126
+ *
127
+ * @section references References
128
+ *
129
+ * - x86 intrinsics: https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html
130
+ * - Arm intrinsics: https://developer.arm.com/architectures/instruction-sets/intrinsics/
131
+ *
132
+ */
133
+ #ifndef NK_SPATIAL_H
134
+ #define NK_SPATIAL_H
135
+
136
+ #include "numkong/types.h"
137
+
138
+ #if defined(__cplusplus)
139
+ extern "C" {
140
+ #endif
141
+
142
+ /**
143
+ * @brief L2 (Euclidean) distance between two vectors.
144
+ *
145
+ * @param[in] a The first vector.
146
+ * @param[in] b The second vector.
147
+ * @param[in] n The number of elements in each vector.
148
+ * @param[out] result The output distance value.
149
+ *
150
+ * @note The output distance value is non-negative.
151
+ * @note The output distance value is zero if and only if the two vectors are identical.
152
+ */
153
+ NK_DYNAMIC void nk_euclidean_f64(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
154
+ /** @copydoc nk_euclidean_f64 */
155
+ NK_DYNAMIC void nk_euclidean_f32(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
156
+ /** @copydoc nk_euclidean_f64 */
157
+ NK_DYNAMIC void nk_euclidean_f16(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
158
+ /** @copydoc nk_euclidean_f64 */
159
+ NK_DYNAMIC void nk_euclidean_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
160
+ /** @copydoc nk_euclidean_f64 */
161
+ NK_DYNAMIC void nk_euclidean_e4m3(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
162
+ /** @copydoc nk_euclidean_f64 */
163
+ NK_DYNAMIC void nk_euclidean_e5m2(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
164
+ /** @copydoc nk_euclidean_f64 */
165
+ NK_DYNAMIC void nk_euclidean_e2m3(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
166
+ /** @copydoc nk_euclidean_f64 */
167
+ NK_DYNAMIC void nk_euclidean_e3m2(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
168
+ /** @copydoc nk_euclidean_f64 */
169
+ NK_DYNAMIC void nk_euclidean_i8(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
170
+ /** @copydoc nk_euclidean_f64 */
171
+ NK_DYNAMIC void nk_euclidean_u8(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
172
+ /** @copydoc nk_euclidean_f64 */
173
+ NK_DYNAMIC void nk_euclidean_i4(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result);
174
+ /** @copydoc nk_euclidean_f64 */
175
+ NK_DYNAMIC void nk_euclidean_u4(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result);
176
+
177
+ /**
178
+ * @brief Squared L2 (Euclidean) distance between two vectors.
179
+ *
180
+ * @param[in] a The first vector.
181
+ * @param[in] b The second vector.
182
+ * @param[in] n The number of elements in each vector.
183
+ * @param[out] result The output distance value.
184
+ *
185
+ * @note The output distance value is non-negative.
186
+ * @note The output distance value is zero if and only if the two vectors are identical.
187
+ */
188
+ NK_DYNAMIC void nk_sqeuclidean_f64(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
189
+ /** @copydoc nk_sqeuclidean_f64 */
190
+ NK_DYNAMIC void nk_sqeuclidean_f32(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
191
+ /** @copydoc nk_sqeuclidean_f64 */
192
+ NK_DYNAMIC void nk_sqeuclidean_f16(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
193
+ /** @copydoc nk_sqeuclidean_f64 */
194
+ NK_DYNAMIC void nk_sqeuclidean_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
195
+ /** @copydoc nk_sqeuclidean_f64 */
196
+ NK_DYNAMIC void nk_sqeuclidean_e4m3(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
197
+ /** @copydoc nk_sqeuclidean_f64 */
198
+ NK_DYNAMIC void nk_sqeuclidean_e5m2(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
199
+ /** @copydoc nk_sqeuclidean_f64 */
200
+ NK_DYNAMIC void nk_sqeuclidean_e2m3(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
201
+ /** @copydoc nk_sqeuclidean_f64 */
202
+ NK_DYNAMIC void nk_sqeuclidean_e3m2(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
203
+ /** @copydoc nk_sqeuclidean_f64 */
204
+ NK_DYNAMIC void nk_sqeuclidean_i8(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_u32_t *result);
205
+ /** @copydoc nk_sqeuclidean_f64 */
206
+ NK_DYNAMIC void nk_sqeuclidean_u8(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
207
+ /** @copydoc nk_sqeuclidean_f64 */
208
+ NK_DYNAMIC void nk_sqeuclidean_i4(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_u32_t *result);
209
+ /** @copydoc nk_sqeuclidean_f64 */
210
+ NK_DYNAMIC void nk_sqeuclidean_u4(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_u32_t *result);
211
+
212
+ /**
213
+ * @brief Angular (cosine) distance between two vectors.
214
+ *
215
+ * @param[in] a The first vector.
216
+ * @param[in] b The second vector.
217
+ * @param[in] n The number of elements in each vector.
218
+ * @param[out] result The output distance value.
219
+ *
220
+ * @note The output distance value is non-negative.
221
+ * @note The output distance value is zero if and only if the two vectors are identical.
222
+ */
223
+ NK_DYNAMIC void nk_angular_f64(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
224
+ /** @copydoc nk_angular_f64 */
225
+ NK_DYNAMIC void nk_angular_f32(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
226
+ /** @copydoc nk_angular_f64 */
227
+ NK_DYNAMIC void nk_angular_f16(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
228
+ /** @copydoc nk_angular_f64 */
229
+ NK_DYNAMIC void nk_angular_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
230
+ /** @copydoc nk_angular_f64 */
231
+ NK_DYNAMIC void nk_angular_e4m3(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
232
+ /** @copydoc nk_angular_f64 */
233
+ NK_DYNAMIC void nk_angular_e5m2(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
234
+ /** @copydoc nk_angular_f64 */
235
+ NK_DYNAMIC void nk_angular_e2m3(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
236
+ /** @copydoc nk_angular_f64 */
237
+ NK_DYNAMIC void nk_angular_e3m2(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
238
+ /** @copydoc nk_angular_f64 */
239
+ NK_DYNAMIC void nk_angular_i8(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
240
+ /** @copydoc nk_angular_f64 */
241
+ NK_DYNAMIC void nk_angular_u8(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
242
+ /** @copydoc nk_angular_f64 */
243
+ NK_DYNAMIC void nk_angular_i4(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result);
244
+ /** @copydoc nk_angular_f64 */
245
+ NK_DYNAMIC void nk_angular_u4(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result);
246
+
247
+ /* Serial backends for all numeric types.
248
+ * By default they use 32-bit arithmetic, unless the arguments themselves contain 64-bit floats.
249
+ */
250
+ /** @copydoc nk_euclidean_f64 */
251
+ NK_PUBLIC void nk_euclidean_f64_serial(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
252
+ /** @copydoc nk_sqeuclidean_f64 */
253
+ NK_PUBLIC void nk_sqeuclidean_f64_serial(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
254
+ /** @copydoc nk_angular_f64 */
255
+ NK_PUBLIC void nk_angular_f64_serial(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
256
+ /** @copydoc nk_euclidean_f64 */
257
+ NK_PUBLIC void nk_euclidean_f32_serial(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
258
+ /** @copydoc nk_sqeuclidean_f64 */
259
+ NK_PUBLIC void nk_sqeuclidean_f32_serial(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
260
+ /** @copydoc nk_angular_f64 */
261
+ NK_PUBLIC void nk_angular_f32_serial(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
262
+ /** @copydoc nk_euclidean_f64 */
263
+ NK_PUBLIC void nk_euclidean_f16_serial(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
264
+ /** @copydoc nk_sqeuclidean_f64 */
265
+ NK_PUBLIC void nk_sqeuclidean_f16_serial(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
266
+ /** @copydoc nk_angular_f64 */
267
+ NK_PUBLIC void nk_angular_f16_serial(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
268
+ /** @copydoc nk_euclidean_f64 */
269
+ NK_PUBLIC void nk_euclidean_bf16_serial(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
270
+ /** @copydoc nk_sqeuclidean_f64 */
271
+ NK_PUBLIC void nk_sqeuclidean_bf16_serial(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
272
+ /** @copydoc nk_angular_f64 */
273
+ NK_PUBLIC void nk_angular_bf16_serial(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
274
+ /** @copydoc nk_euclidean_f64 */
275
+ NK_PUBLIC void nk_euclidean_e4m3_serial(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
276
+ /** @copydoc nk_sqeuclidean_f64 */
277
+ NK_PUBLIC void nk_sqeuclidean_e4m3_serial(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
278
+ /** @copydoc nk_angular_f64 */
279
+ NK_PUBLIC void nk_angular_e4m3_serial(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
280
+ /** @copydoc nk_euclidean_f64 */
281
+ NK_PUBLIC void nk_euclidean_e5m2_serial(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
282
+ /** @copydoc nk_sqeuclidean_f64 */
283
+ NK_PUBLIC void nk_sqeuclidean_e5m2_serial(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
284
+ /** @copydoc nk_angular_f64 */
285
+ NK_PUBLIC void nk_angular_e5m2_serial(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
286
+ /** @copydoc nk_euclidean_f64 */
287
+ NK_PUBLIC void nk_euclidean_i8_serial(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
288
+ /** @copydoc nk_sqeuclidean_f64 */
289
+ NK_PUBLIC void nk_sqeuclidean_i8_serial(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_u32_t *result);
290
+ /** @copydoc nk_angular_f64 */
291
+ NK_PUBLIC void nk_angular_i8_serial(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
292
+ /** @copydoc nk_euclidean_f64 */
293
+ NK_PUBLIC void nk_euclidean_u8_serial(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
294
+ /** @copydoc nk_sqeuclidean_f64 */
295
+ NK_PUBLIC void nk_sqeuclidean_u8_serial(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
296
+ /** @copydoc nk_angular_f64 */
297
+ NK_PUBLIC void nk_angular_u8_serial(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
298
+
299
+ /** @copydoc nk_euclidean_f64 */
300
+ NK_PUBLIC void nk_euclidean_i4_serial(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result);
301
+ /** @copydoc nk_sqeuclidean_f64 */
302
+ NK_PUBLIC void nk_sqeuclidean_i4_serial(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_u32_t *result);
303
+ /** @copydoc nk_angular_f64 */
304
+ NK_PUBLIC void nk_angular_i4_serial(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result);
305
+ /** @copydoc nk_euclidean_f64 */
306
+ NK_PUBLIC void nk_euclidean_u4_serial(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result);
307
+ /** @copydoc nk_sqeuclidean_f64 */
308
+ NK_PUBLIC void nk_sqeuclidean_u4_serial(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_u32_t *result);
309
+ /** @copydoc nk_angular_f64 */
310
+ NK_PUBLIC void nk_angular_u4_serial(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result);
311
+
312
+ /* SIMD-powered backends for Arm NEON, mostly using 32-bit arithmetic over 128-bit words.
313
+ * By far the most portable backend, covering most Arm v8 devices, over a billion phones, and almost all
314
+ * server CPUs produced before 2023.
315
+ */
316
+ #if NK_TARGET_NEON
317
+ /** @copydoc nk_euclidean_f64 */
318
+ NK_PUBLIC void nk_euclidean_f64_neon(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
319
+ /** @copydoc nk_sqeuclidean_f64 */
320
+ NK_PUBLIC void nk_sqeuclidean_f64_neon(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
321
+ /** @copydoc nk_angular_f64 */
322
+ NK_PUBLIC void nk_angular_f64_neon(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
323
+ /** @copydoc nk_euclidean_f64 */
324
+ NK_PUBLIC void nk_euclidean_f32_neon(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
325
+ /** @copydoc nk_sqeuclidean_f64 */
326
+ NK_PUBLIC void nk_sqeuclidean_f32_neon(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
327
+ /** @copydoc nk_angular_f64 */
328
+ NK_PUBLIC void nk_angular_f32_neon(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
329
+ /** @copydoc nk_euclidean_f64 */
330
+ NK_PUBLIC void nk_euclidean_bf16_neon(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
331
+ /** @copydoc nk_sqeuclidean_f64 */
332
+ NK_PUBLIC void nk_sqeuclidean_bf16_neon(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
333
+ /** @copydoc nk_angular_f64 */
334
+ NK_PUBLIC void nk_angular_bf16_neon(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
335
+ /** @copydoc nk_euclidean_f64 */
336
+ NK_PUBLIC void nk_euclidean_f16_neon(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
337
+ /** @copydoc nk_sqeuclidean_f64 */
338
+ NK_PUBLIC void nk_sqeuclidean_f16_neon(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
339
+ /** @copydoc nk_angular_f64 */
340
+ NK_PUBLIC void nk_angular_f16_neon(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
341
+ #endif // NK_TARGET_NEON
342
+
343
+ #if NK_TARGET_NEONBFDOT
344
+ /** @copydoc nk_euclidean_f64 */
345
+ NK_PUBLIC void nk_euclidean_bf16_neonbfdot(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
346
+ /** @copydoc nk_sqeuclidean_f64 */
347
+ NK_PUBLIC void nk_sqeuclidean_bf16_neonbfdot(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
348
+ /** @copydoc nk_angular_f64 */
349
+ NK_PUBLIC void nk_angular_bf16_neonbfdot(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
350
+ #endif // NK_TARGET_NEONBFDOT
351
+
352
+ #if NK_TARGET_NEONSDOT
353
+ /** @copydoc nk_euclidean_f64 */
354
+ NK_PUBLIC void nk_euclidean_i8_neonsdot(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
355
+ /** @copydoc nk_sqeuclidean_f64 */
356
+ NK_PUBLIC void nk_sqeuclidean_i8_neonsdot(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_u32_t *result);
357
+ /** @copydoc nk_angular_f64 */
358
+ NK_PUBLIC void nk_angular_i8_neonsdot(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
359
+ /** @copydoc nk_euclidean_f64 */
360
+ NK_PUBLIC void nk_euclidean_u8_neonsdot(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
361
+ /** @copydoc nk_sqeuclidean_f64 */
362
+ NK_PUBLIC void nk_sqeuclidean_u8_neonsdot(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
363
+ /** @copydoc nk_angular_f64 */
364
+ NK_PUBLIC void nk_angular_u8_neonsdot(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
365
+ /** @copydoc nk_euclidean_f64 */
366
+ NK_PUBLIC void nk_euclidean_i4_neonsdot(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result);
367
+ /** @copydoc nk_sqeuclidean_f64 */
368
+ NK_PUBLIC void nk_sqeuclidean_i4_neonsdot(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_u32_t *result);
369
+ /** @copydoc nk_angular_f64 */
370
+ NK_PUBLIC void nk_angular_i4_neonsdot(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result);
371
+ /** @copydoc nk_euclidean_f64 */
372
+ NK_PUBLIC void nk_euclidean_u4_neonsdot(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result);
373
+ /** @copydoc nk_sqeuclidean_f64 */
374
+ NK_PUBLIC void nk_sqeuclidean_u4_neonsdot(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_u32_t *result);
375
+ /** @copydoc nk_angular_f64 */
376
+ NK_PUBLIC void nk_angular_u4_neonsdot(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result);
377
+ #endif // NK_TARGET_NEONSDOT
378
+
379
+ #if NK_TARGET_SVESDOT
380
+ /** @copydoc nk_euclidean_f64 */
381
+ NK_PUBLIC void nk_euclidean_i8_svesdot(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
382
+ /** @copydoc nk_sqeuclidean_f64 */
383
+ NK_PUBLIC void nk_sqeuclidean_i8_svesdot(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_u32_t *result);
384
+ /** @copydoc nk_angular_f64 */
385
+ NK_PUBLIC void nk_angular_i8_svesdot(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
386
+ /** @copydoc nk_euclidean_f64 */
387
+ NK_PUBLIC void nk_euclidean_u8_svesdot(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
388
+ /** @copydoc nk_sqeuclidean_f64 */
389
+ NK_PUBLIC void nk_sqeuclidean_u8_svesdot(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
390
+ /** @copydoc nk_angular_f64 */
391
+ NK_PUBLIC void nk_angular_u8_svesdot(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
392
+ #endif // NK_TARGET_SVESDOT
393
+
394
+ #if NK_TARGET_NEONFP8
395
+ /** @copydoc nk_sqeuclidean_f64 */
396
+ NK_PUBLIC void nk_sqeuclidean_e4m3_neonfp8(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
397
+ /** @copydoc nk_euclidean_f64 */
398
+ NK_PUBLIC void nk_euclidean_e4m3_neonfp8(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
399
+ /** @copydoc nk_angular_f64 */
400
+ NK_PUBLIC void nk_angular_e4m3_neonfp8(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
401
+ /** @copydoc nk_sqeuclidean_f64 */
402
+ NK_PUBLIC void nk_sqeuclidean_e5m2_neonfp8(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
403
+ /** @copydoc nk_euclidean_f64 */
404
+ NK_PUBLIC void nk_euclidean_e5m2_neonfp8(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
405
+ /** @copydoc nk_angular_f64 */
406
+ NK_PUBLIC void nk_angular_e5m2_neonfp8(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
407
+ /** @copydoc nk_sqeuclidean_f64 */
408
+ NK_PUBLIC void nk_sqeuclidean_e2m3_neonfp8(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
409
+ /** @copydoc nk_euclidean_f64 */
410
+ NK_PUBLIC void nk_euclidean_e2m3_neonfp8(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
411
+ /** @copydoc nk_angular_f64 */
412
+ NK_PUBLIC void nk_angular_e2m3_neonfp8(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
413
+ /** @copydoc nk_sqeuclidean_f64 */
414
+ NK_PUBLIC void nk_sqeuclidean_e3m2_neonfp8(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
415
+ /** @copydoc nk_euclidean_f64 */
416
+ NK_PUBLIC void nk_euclidean_e3m2_neonfp8(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
417
+ /** @copydoc nk_angular_f64 */
418
+ NK_PUBLIC void nk_angular_e3m2_neonfp8(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
419
+ #endif // NK_TARGET_NEONFP8
420
+
421
+ /* SIMD-powered backends for Arm SVE, mostly using 32-bit arithmetic over variable-length platform-defined word sizes.
422
+ * Designed for Arm Graviton 3, Microsoft Cobalt, as well as Nvidia Grace and newer Ampere Altra CPUs.
423
+ */
424
+ #if NK_TARGET_SVE
425
+ /** @copydoc nk_euclidean_f64 */
426
+ NK_PUBLIC void nk_euclidean_f32_sve(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
427
+ /** @copydoc nk_sqeuclidean_f64 */
428
+ NK_PUBLIC void nk_sqeuclidean_f32_sve(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
429
+ /** @copydoc nk_angular_f64 */
430
+ NK_PUBLIC void nk_angular_f32_sve(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
431
+ /** @copydoc nk_euclidean_f64 */
432
+ NK_PUBLIC void nk_euclidean_f64_sve(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
433
+ /** @copydoc nk_sqeuclidean_f64 */
434
+ NK_PUBLIC void nk_sqeuclidean_f64_sve(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
435
+ /** @copydoc nk_angular_f64 */
436
+ NK_PUBLIC void nk_angular_f64_sve(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
437
+ #endif // NK_TARGET_SVE
438
+
439
+ #if NK_TARGET_SVEHALF
440
+ /** @copydoc nk_euclidean_f64 */
441
+ NK_PUBLIC void nk_euclidean_f16_svehalf(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
442
+ /** @copydoc nk_sqeuclidean_f64 */
443
+ NK_PUBLIC void nk_sqeuclidean_f16_svehalf(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
444
+ /** @copydoc nk_angular_f64 */
445
+ NK_PUBLIC void nk_angular_f16_svehalf(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
446
+ #endif // NK_TARGET_SVEHALF
447
+
448
+ #if NK_TARGET_SVEBFDOT
449
+ /** @copydoc nk_euclidean_f64 */
450
+ NK_PUBLIC void nk_euclidean_bf16_svebfdot(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
451
+ /** @copydoc nk_sqeuclidean_f64 */
452
+ NK_PUBLIC void nk_sqeuclidean_bf16_svebfdot(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
453
+ /** @copydoc nk_angular_f64 */
454
+ NK_PUBLIC void nk_angular_bf16_svebfdot(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
455
+ #endif // NK_TARGET_SVEBFDOT
456
+
457
+ /* SIMD-powered backends for AVX2 CPUs of Haswell generation and newer, using 32-bit arithmetic over 256-bit words.
458
+ * First demonstrated in 2011, at least one Haswell-based processor was still being sold in 2022 — the Pentium G3420.
459
+ * Practically all modern x86 CPUs support AVX2, FMA, and F16C, making it a perfect baseline for SIMD algorithms.
460
+ * On other hand, there is no need to implement AVX2 versions of `f32` and `f64` functions, as those are
461
+ * properly vectorized by recent compilers.
462
+ */
463
+ #if NK_TARGET_HASWELL
464
+ /** @copydoc nk_euclidean_f64 */
465
+ NK_PUBLIC void nk_euclidean_i8_haswell(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
466
+ /** @copydoc nk_sqeuclidean_f64 */
467
+ NK_PUBLIC void nk_sqeuclidean_i8_haswell(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_u32_t *result);
468
+ /** @copydoc nk_angular_f64 */
469
+ NK_PUBLIC void nk_angular_i8_haswell(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
470
+ /** @copydoc nk_euclidean_f64 */
471
+ NK_PUBLIC void nk_euclidean_u8_haswell(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
472
+ /** @copydoc nk_sqeuclidean_f64 */
473
+ NK_PUBLIC void nk_sqeuclidean_u8_haswell(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
474
+ /** @copydoc nk_angular_f64 */
475
+ NK_PUBLIC void nk_angular_u8_haswell(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
476
+ /** @copydoc nk_euclidean_f64 */
477
+ NK_PUBLIC void nk_euclidean_f16_haswell(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
478
+ /** @copydoc nk_sqeuclidean_f64 */
479
+ NK_PUBLIC void nk_sqeuclidean_f16_haswell(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
480
+ /** @copydoc nk_angular_f64 */
481
+ NK_PUBLIC void nk_angular_f16_haswell(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
482
+ /** @copydoc nk_euclidean_f64 */
483
+ NK_PUBLIC void nk_euclidean_bf16_haswell(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
484
+ /** @copydoc nk_sqeuclidean_f64 */
485
+ NK_PUBLIC void nk_sqeuclidean_bf16_haswell(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
486
+ /** @copydoc nk_angular_f64 */
487
+ NK_PUBLIC void nk_angular_bf16_haswell(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
488
+ /** @copydoc nk_euclidean_f64 */
489
+ NK_PUBLIC void nk_euclidean_f32_haswell(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
490
+ /** @copydoc nk_sqeuclidean_f64 */
491
+ NK_PUBLIC void nk_sqeuclidean_f32_haswell(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
492
+ /** @copydoc nk_angular_f64 */
493
+ NK_PUBLIC void nk_angular_f32_haswell(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
494
+ /** @copydoc nk_euclidean_f64 */
495
+ NK_PUBLIC void nk_euclidean_f64_haswell(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
496
+ /** @copydoc nk_sqeuclidean_f64 */
497
+ NK_PUBLIC void nk_sqeuclidean_f64_haswell(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
498
+ /** @copydoc nk_angular_f64 */
499
+ NK_PUBLIC void nk_angular_f64_haswell(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
500
+ #endif // NK_TARGET_HASWELL
501
+
502
+ /* SIMD-powered backends for AVX512 CPUs of Skylake generation and newer, using 32-bit arithmetic over 512-bit words.
503
+ * Skylake was launched in 2015, and discontinued in 2019. Skylake had support for F, CD, VL, DQ, and BW extensions,
504
+ * as well as masked operations. This is enough to supersede auto-vectorization on `f32` and `f64` types.
505
+ *
506
+ * Sadly, we can't effectively interleave different kinds of arithmetic instructions to utilize more ports:
507
+ *
508
+ * > Like Intel server architectures since Skylake-X, SPR cores feature two 512-bit FMA units, and organize them in a
509
+ * similar fashion. > One 512-bit FMA unit is created by fusing two 256-bit ones on port 0 and port 1. The other is
510
+ * added to port 5, as a server-specific > core extension. The FMA units on port 0 and 1 are configured into
511
+ * 2×256-bit or 1×512-bit mode depending on whether 512-bit FMA > instructions are present in the scheduler. That
512
+ * means a mix of 256-bit and 512-bit FMA instructions will not achieve higher IPC > than executing 512-bit
513
+ * instructions alone.
514
+ *
515
+ * Source: https://chipsandcheese.com/p/a-peek-at-sapphire-rapids
516
+ */
517
+ #if NK_TARGET_SKYLAKE
518
+ /** @copydoc nk_euclidean_f64 */
519
+ NK_PUBLIC void nk_euclidean_f32_skylake(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
520
+ /** @copydoc nk_sqeuclidean_f64 */
521
+ NK_PUBLIC void nk_sqeuclidean_f32_skylake(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
522
+ /** @copydoc nk_angular_f64 */
523
+ NK_PUBLIC void nk_angular_f32_skylake(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
524
+ /** @copydoc nk_euclidean_f64 */
525
+ NK_PUBLIC void nk_euclidean_f64_skylake(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
526
+ /** @copydoc nk_sqeuclidean_f64 */
527
+ NK_PUBLIC void nk_sqeuclidean_f64_skylake(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
528
+ /** @copydoc nk_angular_f64 */
529
+ NK_PUBLIC void nk_angular_f64_skylake(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
530
+ /** @copydoc nk_euclidean_f64 */
531
+ NK_PUBLIC void nk_euclidean_f16_skylake(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
532
+ /** @copydoc nk_sqeuclidean_f64 */
533
+ NK_PUBLIC void nk_sqeuclidean_f16_skylake(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
534
+ /** @copydoc nk_angular_f64 */
535
+ NK_PUBLIC void nk_angular_f16_skylake(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
536
+ /** @copydoc nk_euclidean_f64 */
537
+ NK_PUBLIC void nk_euclidean_e4m3_skylake(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
538
+ /** @copydoc nk_sqeuclidean_f64 */
539
+ NK_PUBLIC void nk_sqeuclidean_e4m3_skylake(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
540
+ /** @copydoc nk_angular_f64 */
541
+ NK_PUBLIC void nk_angular_e4m3_skylake(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
542
+ /** @copydoc nk_euclidean_f64 */
543
+ NK_PUBLIC void nk_euclidean_e5m2_skylake(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
544
+ /** @copydoc nk_sqeuclidean_f64 */
545
+ NK_PUBLIC void nk_sqeuclidean_e5m2_skylake(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
546
+ /** @copydoc nk_angular_f64 */
547
+ NK_PUBLIC void nk_angular_e5m2_skylake(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
548
+ #endif // NK_TARGET_SKYLAKE
549
+
550
+ /* SIMD-powered backends for AVX512 CPUs of Ice Lake generation and newer, using mixed arithmetic over 512-bit words.
551
+ * Ice Lake added VNNI, VPOPCNTDQ, IFMA, VBMI, VAES, GFNI, VBMI2, BITALG, VPCLMULQDQ, and other extensions for integral
552
+ * operations. Sapphire Rapids added tiled matrix operations, but we are most interested in the new mixed-precision FMA
553
+ * instructions.
554
+ */
555
+ #if NK_TARGET_ICELAKE
556
+ /** @copydoc nk_euclidean_f64 */
557
+ NK_PUBLIC void nk_euclidean_i4_icelake(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result);
558
+ /** @copydoc nk_sqeuclidean_f64 */
559
+ NK_PUBLIC void nk_sqeuclidean_i4_icelake(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_u32_t *result);
560
+ /** @copydoc nk_angular_f64 */
561
+ NK_PUBLIC void nk_angular_i4_icelake(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result);
562
+ /** @copydoc nk_euclidean_f64 */
563
+ NK_PUBLIC void nk_euclidean_u4_icelake(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result);
564
+ /** @copydoc nk_sqeuclidean_f64 */
565
+ NK_PUBLIC void nk_sqeuclidean_u4_icelake(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_u32_t *result);
566
+ /** @copydoc nk_angular_f64 */
567
+ NK_PUBLIC void nk_angular_u4_icelake(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result);
568
+ /** @copydoc nk_euclidean_f64 */
569
+ NK_PUBLIC void nk_euclidean_i8_icelake(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
570
+ /** @copydoc nk_sqeuclidean_f64 */
571
+ NK_PUBLIC void nk_sqeuclidean_i8_icelake(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_u32_t *result);
572
+ /** @copydoc nk_angular_f64 */
573
+ NK_PUBLIC void nk_angular_i8_icelake(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
574
+ /** @copydoc nk_euclidean_f64 */
575
+ NK_PUBLIC void nk_euclidean_u8_icelake(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
576
+ /** @copydoc nk_sqeuclidean_f64 */
577
+ NK_PUBLIC void nk_sqeuclidean_u8_icelake(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
578
+ /** @copydoc nk_angular_f64 */
579
+ NK_PUBLIC void nk_angular_u8_icelake(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
580
+ /** @copydoc nk_euclidean_f64 */
581
+ NK_PUBLIC void nk_euclidean_e4m3_icelake(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
582
+ /** @copydoc nk_sqeuclidean_f64 */
583
+ NK_PUBLIC void nk_sqeuclidean_e4m3_icelake(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
584
+ /** @copydoc nk_angular_f64 */
585
+ NK_PUBLIC void nk_angular_e4m3_icelake(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
586
+ /** @copydoc nk_euclidean_f64 */
587
+ NK_PUBLIC void nk_euclidean_e2m3_icelake(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
588
+ /** @copydoc nk_sqeuclidean_f64 */
589
+ NK_PUBLIC void nk_sqeuclidean_e2m3_icelake(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
590
+ /** @copydoc nk_angular_f64 */
591
+ NK_PUBLIC void nk_angular_e2m3_icelake(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
592
+ /** @copydoc nk_euclidean_f64 */
593
+ NK_PUBLIC void nk_euclidean_e3m2_icelake(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
594
+ /** @copydoc nk_sqeuclidean_f64 */
595
+ NK_PUBLIC void nk_sqeuclidean_e3m2_icelake(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
596
+ /** @copydoc nk_angular_f64 */
597
+ NK_PUBLIC void nk_angular_e3m2_icelake(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
598
+ #endif // NK_TARGET_ICELAKE
599
+
600
+ #if NK_TARGET_GENOA
601
+ /** @copydoc nk_euclidean_f64 */
602
+ NK_PUBLIC void nk_euclidean_bf16_genoa(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
603
+ /** @copydoc nk_sqeuclidean_f64 */
604
+ NK_PUBLIC void nk_sqeuclidean_bf16_genoa(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
605
+ /** @copydoc nk_angular_f64 */
606
+ NK_PUBLIC void nk_angular_bf16_genoa(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
607
+ /** @copydoc nk_euclidean_f64 */
608
+ NK_PUBLIC void nk_euclidean_e5m2_genoa(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
609
+ /** @copydoc nk_sqeuclidean_f64 */
610
+ NK_PUBLIC void nk_sqeuclidean_e5m2_genoa(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
611
+ /** @copydoc nk_angular_f64 */
612
+ NK_PUBLIC void nk_angular_e5m2_genoa(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
613
+ #endif // NK_TARGET_GENOA
614
+
615
+ #if NK_TARGET_DIAMOND
616
+ /** @copydoc nk_euclidean_f64 */
617
+ NK_PUBLIC void nk_euclidean_f16_diamond(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
618
+ /** @copydoc nk_sqeuclidean_f64 */
619
+ NK_PUBLIC void nk_sqeuclidean_f16_diamond(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
620
+ /** @copydoc nk_angular_f64 */
621
+ NK_PUBLIC void nk_angular_f16_diamond(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
622
+ /** @copydoc nk_euclidean_f64 */
623
+ NK_PUBLIC void nk_euclidean_e4m3_diamond(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
624
+ /** @copydoc nk_sqeuclidean_f64 */
625
+ NK_PUBLIC void nk_sqeuclidean_e4m3_diamond(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
626
+ /** @copydoc nk_angular_f64 */
627
+ NK_PUBLIC void nk_angular_e4m3_diamond(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
628
+ /** @copydoc nk_euclidean_f64 */
629
+ NK_PUBLIC void nk_euclidean_e5m2_diamond(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
630
+ /** @copydoc nk_sqeuclidean_f64 */
631
+ NK_PUBLIC void nk_sqeuclidean_e5m2_diamond(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
632
+ /** @copydoc nk_angular_f64 */
633
+ NK_PUBLIC void nk_angular_e5m2_diamond(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
634
+ #endif // NK_TARGET_DIAMOND
635
+
636
+ /* SIMD-powered backends for AVX-INT8-VNNI extensions on Xeon 6 CPUs, including Sierra Forest and Granite Rapids.
637
+ * The packs many "efficiency" cores into a single socket, avoiding heavy 512-bit operations, and focusing on
638
+ * 256-bit ones.
639
+ */
640
+ #if NK_TARGET_SIERRA
641
+ /** @copydoc nk_angular_f64 */
642
+ NK_PUBLIC void nk_angular_i8_sierra(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
643
+ /** @copydoc nk_euclidean_f64 */
644
+ NK_PUBLIC void nk_euclidean_i8_sierra(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
645
+ /** @copydoc nk_sqeuclidean_f64 */
646
+ NK_PUBLIC void nk_sqeuclidean_i8_sierra(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_u32_t *result);
647
+ /** @copydoc nk_angular_f64 */
648
+ NK_PUBLIC void nk_angular_u8_sierra(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
649
+ /** @copydoc nk_euclidean_f64 */
650
+ NK_PUBLIC void nk_euclidean_u8_sierra(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
651
+ /** @copydoc nk_sqeuclidean_f64 */
652
+ NK_PUBLIC void nk_sqeuclidean_u8_sierra(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
653
+ /** @copydoc nk_angular_f64 */
654
+ NK_PUBLIC void nk_angular_e2m3_sierra(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
655
+ /** @copydoc nk_euclidean_f64 */
656
+ NK_PUBLIC void nk_euclidean_e2m3_sierra(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
657
+ /** @copydoc nk_sqeuclidean_f64 */
658
+ NK_PUBLIC void nk_sqeuclidean_e2m3_sierra(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
659
+ /** @copydoc nk_euclidean_f64 */
660
+ NK_PUBLIC void nk_euclidean_e3m2_sierra(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
661
+ /** @copydoc nk_sqeuclidean_f64 */
662
+ NK_PUBLIC void nk_sqeuclidean_e3m2_sierra(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
663
+ /** @copydoc nk_angular_f64 */
664
+ NK_PUBLIC void nk_angular_e3m2_sierra(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
665
+ #endif // NK_TARGET_SIERRA
666
+
667
+ #if NK_TARGET_ALDER
668
+ /** @copydoc nk_angular_f64 */
669
+ NK_PUBLIC void nk_angular_i8_alder(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
670
+ /** @copydoc nk_euclidean_f64 */
671
+ NK_PUBLIC void nk_euclidean_i8_alder(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
672
+ /** @copydoc nk_sqeuclidean_f64 */
673
+ NK_PUBLIC void nk_sqeuclidean_i8_alder(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_u32_t *result);
674
+ /** @copydoc nk_angular_f64 */
675
+ NK_PUBLIC void nk_angular_u8_alder(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
676
+ /** @copydoc nk_euclidean_f64 */
677
+ NK_PUBLIC void nk_euclidean_u8_alder(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
678
+ /** @copydoc nk_sqeuclidean_f64 */
679
+ NK_PUBLIC void nk_sqeuclidean_u8_alder(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
680
+ /** @copydoc nk_angular_f64 */
681
+ NK_PUBLIC void nk_angular_e2m3_alder(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
682
+ /** @copydoc nk_euclidean_f64 */
683
+ NK_PUBLIC void nk_euclidean_e2m3_alder(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
684
+ /** @copydoc nk_sqeuclidean_f64 */
685
+ NK_PUBLIC void nk_sqeuclidean_e2m3_alder(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
686
+ /** @copydoc nk_angular_f64 */
687
+ NK_PUBLIC void nk_angular_e3m2_alder(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
688
+ /** @copydoc nk_euclidean_f64 */
689
+ NK_PUBLIC void nk_euclidean_e3m2_alder(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
690
+ /** @copydoc nk_sqeuclidean_f64 */
691
+ NK_PUBLIC void nk_sqeuclidean_e3m2_alder(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
692
+ #endif // NK_TARGET_ALDER
693
+
694
+ #if NK_TARGET_V128RELAXED
695
+ /** @copydoc nk_sqeuclidean_f64 */
696
+ NK_PUBLIC void nk_sqeuclidean_f32_v128relaxed(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
697
+ /** @copydoc nk_sqeuclidean_f64 */
698
+ NK_PUBLIC void nk_sqeuclidean_f64_v128relaxed(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
699
+ /** @copydoc nk_euclidean_f64 */
700
+ NK_PUBLIC void nk_euclidean_f32_v128relaxed(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
701
+ /** @copydoc nk_euclidean_f64 */
702
+ NK_PUBLIC void nk_euclidean_f64_v128relaxed(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
703
+ /** @copydoc nk_angular_f64 */
704
+ NK_PUBLIC void nk_angular_f32_v128relaxed(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
705
+ /** @copydoc nk_angular_f64 */
706
+ NK_PUBLIC void nk_angular_f64_v128relaxed(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
707
+ /** @copydoc nk_sqeuclidean_f64 */
708
+ NK_PUBLIC void nk_sqeuclidean_f16_v128relaxed(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
709
+ /** @copydoc nk_sqeuclidean_f64 */
710
+ NK_PUBLIC void nk_sqeuclidean_bf16_v128relaxed(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
711
+ /** @copydoc nk_euclidean_f64 */
712
+ NK_PUBLIC void nk_euclidean_f16_v128relaxed(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
713
+ /** @copydoc nk_euclidean_f64 */
714
+ NK_PUBLIC void nk_euclidean_bf16_v128relaxed(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
715
+ /** @copydoc nk_angular_f64 */
716
+ NK_PUBLIC void nk_angular_f16_v128relaxed(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
717
+ /** @copydoc nk_angular_f64 */
718
+ NK_PUBLIC void nk_angular_bf16_v128relaxed(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
719
+ /** @copydoc nk_sqeuclidean_f64 */
720
+ NK_PUBLIC void nk_sqeuclidean_u8_v128relaxed(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
721
+ /** @copydoc nk_euclidean_f64 */
722
+ NK_PUBLIC void nk_euclidean_u8_v128relaxed(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
723
+ /** @copydoc nk_angular_f64 */
724
+ NK_PUBLIC void nk_angular_u8_v128relaxed(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
725
+ /** @copydoc nk_sqeuclidean_f64 */
726
+ NK_PUBLIC void nk_sqeuclidean_i8_v128relaxed(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_u32_t *result);
727
+ /** @copydoc nk_euclidean_f64 */
728
+ NK_PUBLIC void nk_euclidean_i8_v128relaxed(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
729
+ /** @copydoc nk_angular_f64 */
730
+ NK_PUBLIC void nk_angular_i8_v128relaxed(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
731
+ /** @copydoc nk_sqeuclidean_f64 */
732
+ NK_PUBLIC void nk_sqeuclidean_e4m3_v128relaxed(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
733
+ /** @copydoc nk_euclidean_f64 */
734
+ NK_PUBLIC void nk_euclidean_e4m3_v128relaxed(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
735
+ /** @copydoc nk_angular_f64 */
736
+ NK_PUBLIC void nk_angular_e4m3_v128relaxed(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
737
+ /** @copydoc nk_sqeuclidean_f64 */
738
+ NK_PUBLIC void nk_sqeuclidean_e5m2_v128relaxed(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
739
+ /** @copydoc nk_euclidean_f64 */
740
+ NK_PUBLIC void nk_euclidean_e5m2_v128relaxed(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
741
+ /** @copydoc nk_angular_f64 */
742
+ NK_PUBLIC void nk_angular_e5m2_v128relaxed(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
743
+ /** @copydoc nk_sqeuclidean_f64 */
744
+ NK_PUBLIC void nk_sqeuclidean_e2m3_v128relaxed(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
745
+ /** @copydoc nk_euclidean_f64 */
746
+ NK_PUBLIC void nk_euclidean_e2m3_v128relaxed(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
747
+ /** @copydoc nk_angular_f64 */
748
+ NK_PUBLIC void nk_angular_e2m3_v128relaxed(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result);
749
+ /** @copydoc nk_sqeuclidean_f64 */
750
+ NK_PUBLIC void nk_sqeuclidean_e3m2_v128relaxed(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
751
+ /** @copydoc nk_euclidean_f64 */
752
+ NK_PUBLIC void nk_euclidean_e3m2_v128relaxed(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
753
+ /** @copydoc nk_angular_f64 */
754
+ NK_PUBLIC void nk_angular_e3m2_v128relaxed(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result);
755
+ #endif // NK_TARGET_V128RELAXED
756
+
757
+ /* SIMD-powered backends for RISC-V Vector extension, using scalable vector arithmetic.
758
+ * Designed for SiFive, T-Head, and other RISC-V processors with the V extension.
759
+ */
760
+ #if NK_TARGET_RVV
761
+ /** @copydoc nk_euclidean_f64 */
762
+ NK_PUBLIC void nk_euclidean_f64_rvv(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
763
+ /** @copydoc nk_sqeuclidean_f64 */
764
+ NK_PUBLIC void nk_sqeuclidean_f64_rvv(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
765
+ /** @copydoc nk_angular_f64 */
766
+ NK_PUBLIC void nk_angular_f64_rvv(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
767
+ /** @copydoc nk_euclidean_f64 */
768
+ NK_PUBLIC void nk_euclidean_f32_rvv(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
769
+ /** @copydoc nk_sqeuclidean_f64 */
770
+ NK_PUBLIC void nk_sqeuclidean_f32_rvv(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
771
+ /** @copydoc nk_angular_f64 */
772
+ NK_PUBLIC void nk_angular_f32_rvv(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
773
+ /** @copydoc nk_euclidean_f64 */
774
+ NK_PUBLIC void nk_euclidean_f16_rvv(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
775
+ /** @copydoc nk_sqeuclidean_f64 */
776
+ NK_PUBLIC void nk_sqeuclidean_f16_rvv(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
777
+ /** @copydoc nk_angular_f64 */
778
+ NK_PUBLIC void nk_angular_f16_rvv(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
779
+ /** @copydoc nk_euclidean_f64 */
780
+ NK_PUBLIC void nk_euclidean_bf16_rvv(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
781
+ /** @copydoc nk_sqeuclidean_f64 */
782
+ NK_PUBLIC void nk_sqeuclidean_bf16_rvv(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
783
+ /** @copydoc nk_angular_f64 */
784
+ NK_PUBLIC void nk_angular_bf16_rvv(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
785
+ /** @copydoc nk_euclidean_f64 */
786
+ NK_PUBLIC void nk_euclidean_e4m3_rvv(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
787
+ /** @copydoc nk_sqeuclidean_f64 */
788
+ NK_PUBLIC void nk_sqeuclidean_e4m3_rvv(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
789
+ /** @copydoc nk_angular_f64 */
790
+ NK_PUBLIC void nk_angular_e4m3_rvv(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result);
791
+ /** @copydoc nk_euclidean_f64 */
792
+ NK_PUBLIC void nk_euclidean_e5m2_rvv(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
793
+ /** @copydoc nk_sqeuclidean_f64 */
794
+ NK_PUBLIC void nk_sqeuclidean_e5m2_rvv(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
795
+ /** @copydoc nk_angular_f64 */
796
+ NK_PUBLIC void nk_angular_e5m2_rvv(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result);
797
+ /** @copydoc nk_euclidean_f64 */
798
+ NK_PUBLIC void nk_euclidean_i8_rvv(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
799
+ /** @copydoc nk_sqeuclidean_f64 */
800
+ NK_PUBLIC void nk_sqeuclidean_i8_rvv(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_u32_t *result);
801
+ /** @copydoc nk_angular_f64 */
802
+ NK_PUBLIC void nk_angular_i8_rvv(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result);
803
+ /** @copydoc nk_euclidean_f64 */
804
+ NK_PUBLIC void nk_euclidean_u8_rvv(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
805
+ /** @copydoc nk_sqeuclidean_f64 */
806
+ NK_PUBLIC void nk_sqeuclidean_u8_rvv(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
807
+ /** @copydoc nk_angular_f64 */
808
+ NK_PUBLIC void nk_angular_u8_rvv(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result);
809
+ /** @copydoc nk_euclidean_f64 */
810
+ NK_PUBLIC void nk_euclidean_i4_rvv(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result);
811
+ /** @copydoc nk_sqeuclidean_f64 */
812
+ NK_PUBLIC void nk_sqeuclidean_i4_rvv(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_u32_t *result);
813
+ /** @copydoc nk_angular_f64 */
814
+ NK_PUBLIC void nk_angular_i4_rvv(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result);
815
+ /** @copydoc nk_euclidean_f64 */
816
+ NK_PUBLIC void nk_euclidean_u4_rvv(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result);
817
+ /** @copydoc nk_sqeuclidean_f64 */
818
+ NK_PUBLIC void nk_sqeuclidean_u4_rvv(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_u32_t *result);
819
+ /** @copydoc nk_angular_f64 */
820
+ NK_PUBLIC void nk_angular_u4_rvv(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result);
821
+ #endif // NK_TARGET_RVV
822
+
823
+ #if NK_TARGET_RVVHALF
824
+ /** @copydoc nk_euclidean_f64 */
825
+ NK_PUBLIC void nk_euclidean_f16_rvvhalf(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
826
+ /** @copydoc nk_sqeuclidean_f64 */
827
+ NK_PUBLIC void nk_sqeuclidean_f16_rvvhalf(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
828
+ /** @copydoc nk_angular_f64 */
829
+ NK_PUBLIC void nk_angular_f16_rvvhalf(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
830
+ #endif // NK_TARGET_RVVHALF
831
+
832
+ #if NK_TARGET_RVVBF16
833
+ /** @copydoc nk_euclidean_f64 */
834
+ NK_PUBLIC void nk_euclidean_bf16_rvvbf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
835
+ /** @copydoc nk_sqeuclidean_f64 */
836
+ NK_PUBLIC void nk_sqeuclidean_bf16_rvvbf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
837
+ /** @copydoc nk_angular_f64 */
838
+ NK_PUBLIC void nk_angular_bf16_rvvbf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
839
+ #endif // NK_TARGET_RVVBF16
840
+
841
+ /** @brief Returns the output dtype for L2 (Euclidean) distance. */
842
+ NK_INTERNAL nk_dtype_t nk_euclidean_output_dtype(nk_dtype_t dtype) {
843
+ switch (dtype) {
844
+ case nk_f64_k: return nk_f64_k;
845
+ case nk_f32_k: return nk_f64_k;
846
+ case nk_f16_k: return nk_f32_k;
847
+ case nk_bf16_k: return nk_f32_k;
848
+ case nk_e4m3_k: return nk_f32_k;
849
+ case nk_e5m2_k: return nk_f32_k;
850
+ case nk_e2m3_k: return nk_f32_k;
851
+ case nk_e3m2_k: return nk_f32_k;
852
+ case nk_i8_k: return nk_f32_k;
853
+ case nk_u8_k: return nk_f32_k;
854
+ case nk_i4_k: return nk_f32_k;
855
+ case nk_u4_k: return nk_f32_k;
856
+ default: return nk_dtype_unknown_k;
857
+ }
858
+ }
859
+
860
+ /** @brief Returns the output dtype for L2 squared distance. */
861
+ NK_INTERNAL nk_dtype_t nk_sqeuclidean_output_dtype(nk_dtype_t dtype) {
862
+ switch (dtype) {
863
+ case nk_f64_k: return nk_f64_k;
864
+ case nk_f32_k: return nk_f64_k;
865
+ case nk_f16_k: return nk_f32_k;
866
+ case nk_bf16_k: return nk_f32_k;
867
+ case nk_e4m3_k: return nk_f32_k;
868
+ case nk_e5m2_k: return nk_f32_k;
869
+ case nk_e2m3_k: return nk_f32_k;
870
+ case nk_e3m2_k: return nk_f32_k;
871
+ case nk_i8_k: return nk_u32_k;
872
+ case nk_u8_k: return nk_u32_k;
873
+ case nk_i4_k: return nk_u32_k;
874
+ case nk_u4_k: return nk_u32_k;
875
+ default: return nk_dtype_unknown_k;
876
+ }
877
+ }
878
+
879
+ /** @brief Returns the output dtype for angular/cosine distance. */
880
+ NK_INTERNAL nk_dtype_t nk_angular_output_dtype(nk_dtype_t dtype) {
881
+ switch (dtype) {
882
+ case nk_f64_k: return nk_f64_k;
883
+ case nk_f32_k: return nk_f64_k;
884
+ case nk_f16_k: return nk_f32_k;
885
+ case nk_bf16_k: return nk_f32_k;
886
+ case nk_e4m3_k: return nk_f32_k;
887
+ case nk_e5m2_k: return nk_f32_k;
888
+ case nk_e2m3_k: return nk_f32_k;
889
+ case nk_e3m2_k: return nk_f32_k;
890
+ case nk_i8_k: return nk_f32_k;
891
+ case nk_u8_k: return nk_f32_k;
892
+ case nk_i4_k: return nk_f32_k;
893
+ case nk_u4_k: return nk_f32_k;
894
+ default: return nk_dtype_unknown_k;
895
+ }
896
+ }
897
+
898
+ #if defined(__cplusplus)
899
+ } // extern "C"
900
+ #endif
901
+
902
+ #include "numkong/spatial/serial.h"
903
+ #include "numkong/spatial/neon.h"
904
+ #include "numkong/spatial/neonbfdot.h"
905
+ #include "numkong/spatial/neonsdot.h"
906
+ #include "numkong/spatial/sve.h"
907
+ #include "numkong/spatial/svehalf.h"
908
+ #include "numkong/spatial/svebfdot.h"
909
+ #include "numkong/spatial/svesdot.h"
910
+ #include "numkong/spatial/neonfp8.h"
911
+ #include "numkong/spatial/haswell.h"
912
+ #include "numkong/spatial/skylake.h"
913
+ #include "numkong/spatial/genoa.h"
914
+ #include "numkong/spatial/diamond.h"
915
+ #include "numkong/spatial/icelake.h"
916
+ #include "numkong/spatial/alder.h"
917
+ #include "numkong/spatial/sierra.h"
918
+ #include "numkong/spatial/rvv.h"
919
+ #include "numkong/spatial/rvvhalf.h"
920
+ #include "numkong/spatial/rvvbf16.h"
921
+ #include "numkong/spatial/v128relaxed.h"
922
+ #include "numkong/spatial/powervsx.h"
923
+ #include "numkong/spatial/loongsonasx.h"
924
+
925
+ #if defined(__cplusplus)
926
+ extern "C" {
927
+ #endif
928
+
929
+ #if !NK_DYNAMIC_DISPATCH
930
+
931
+ NK_PUBLIC void nk_euclidean_f64(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result) {
932
+ #if NK_TARGET_V128RELAXED
933
+ nk_euclidean_f64_v128relaxed(a, b, n, result);
934
+ #elif NK_TARGET_POWERVSX
935
+ nk_euclidean_f64_powervsx(a, b, n, result);
936
+ #elif NK_TARGET_LOONGSONASX
937
+ nk_euclidean_f64_loongsonasx(a, b, n, result);
938
+ #elif NK_TARGET_RVV
939
+ nk_euclidean_f64_rvv(a, b, n, result);
940
+ #elif NK_TARGET_SVE
941
+ nk_euclidean_f64_sve(a, b, n, result);
942
+ #elif NK_TARGET_NEON
943
+ nk_euclidean_f64_neon(a, b, n, result);
944
+ #elif NK_TARGET_SKYLAKE
945
+ nk_euclidean_f64_skylake(a, b, n, result);
946
+ #elif NK_TARGET_HASWELL
947
+ nk_euclidean_f64_haswell(a, b, n, result);
948
+ #else
949
+ nk_euclidean_f64_serial(a, b, n, result);
950
+ #endif
951
+ }
952
+
953
+ NK_PUBLIC void nk_sqeuclidean_f64(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result) {
954
+ #if NK_TARGET_V128RELAXED
955
+ nk_sqeuclidean_f64_v128relaxed(a, b, n, result);
956
+ #elif NK_TARGET_POWERVSX
957
+ nk_sqeuclidean_f64_powervsx(a, b, n, result);
958
+ #elif NK_TARGET_LOONGSONASX
959
+ nk_sqeuclidean_f64_loongsonasx(a, b, n, result);
960
+ #elif NK_TARGET_RVV
961
+ nk_sqeuclidean_f64_rvv(a, b, n, result);
962
+ #elif NK_TARGET_SVE
963
+ nk_sqeuclidean_f64_sve(a, b, n, result);
964
+ #elif NK_TARGET_NEON
965
+ nk_sqeuclidean_f64_neon(a, b, n, result);
966
+ #elif NK_TARGET_SKYLAKE
967
+ nk_sqeuclidean_f64_skylake(a, b, n, result);
968
+ #elif NK_TARGET_HASWELL
969
+ nk_sqeuclidean_f64_haswell(a, b, n, result);
970
+ #else
971
+ nk_sqeuclidean_f64_serial(a, b, n, result);
972
+ #endif
973
+ }
974
+
975
+ NK_PUBLIC void nk_angular_f64(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result) {
976
+ #if NK_TARGET_V128RELAXED
977
+ nk_angular_f64_v128relaxed(a, b, n, result);
978
+ #elif NK_TARGET_POWERVSX
979
+ nk_angular_f64_powervsx(a, b, n, result);
980
+ #elif NK_TARGET_LOONGSONASX
981
+ nk_angular_f64_loongsonasx(a, b, n, result);
982
+ #elif NK_TARGET_RVV
983
+ nk_angular_f64_rvv(a, b, n, result);
984
+ #elif NK_TARGET_SVE
985
+ nk_angular_f64_sve(a, b, n, result);
986
+ #elif NK_TARGET_NEON
987
+ nk_angular_f64_neon(a, b, n, result);
988
+ #elif NK_TARGET_SKYLAKE
989
+ nk_angular_f64_skylake(a, b, n, result);
990
+ #elif NK_TARGET_HASWELL
991
+ nk_angular_f64_haswell(a, b, n, result);
992
+ #else
993
+ nk_angular_f64_serial(a, b, n, result);
994
+ #endif
995
+ }
996
+
997
+ NK_PUBLIC void nk_euclidean_f32(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result) {
998
+ #if NK_TARGET_V128RELAXED
999
+ nk_euclidean_f32_v128relaxed(a, b, n, result);
1000
+ #elif NK_TARGET_POWERVSX
1001
+ nk_euclidean_f32_powervsx(a, b, n, result);
1002
+ #elif NK_TARGET_LOONGSONASX
1003
+ nk_euclidean_f32_loongsonasx(a, b, n, result);
1004
+ #elif NK_TARGET_RVV
1005
+ nk_euclidean_f32_rvv(a, b, n, result);
1006
+ #elif NK_TARGET_SVE
1007
+ nk_euclidean_f32_sve(a, b, n, result);
1008
+ #elif NK_TARGET_NEON
1009
+ nk_euclidean_f32_neon(a, b, n, result);
1010
+ #elif NK_TARGET_SKYLAKE
1011
+ nk_euclidean_f32_skylake(a, b, n, result);
1012
+ #elif NK_TARGET_HASWELL
1013
+ nk_euclidean_f32_haswell(a, b, n, result);
1014
+ #else
1015
+ nk_euclidean_f32_serial(a, b, n, result);
1016
+ #endif
1017
+ }
1018
+
1019
+ NK_PUBLIC void nk_sqeuclidean_f32(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result) {
1020
+ #if NK_TARGET_V128RELAXED
1021
+ nk_sqeuclidean_f32_v128relaxed(a, b, n, result);
1022
+ #elif NK_TARGET_POWERVSX
1023
+ nk_sqeuclidean_f32_powervsx(a, b, n, result);
1024
+ #elif NK_TARGET_LOONGSONASX
1025
+ nk_sqeuclidean_f32_loongsonasx(a, b, n, result);
1026
+ #elif NK_TARGET_RVV
1027
+ nk_sqeuclidean_f32_rvv(a, b, n, result);
1028
+ #elif NK_TARGET_SVE
1029
+ nk_sqeuclidean_f32_sve(a, b, n, result);
1030
+ #elif NK_TARGET_NEON
1031
+ nk_sqeuclidean_f32_neon(a, b, n, result);
1032
+ #elif NK_TARGET_SKYLAKE
1033
+ nk_sqeuclidean_f32_skylake(a, b, n, result);
1034
+ #elif NK_TARGET_HASWELL
1035
+ nk_sqeuclidean_f32_haswell(a, b, n, result);
1036
+ #else
1037
+ nk_sqeuclidean_f32_serial(a, b, n, result);
1038
+ #endif
1039
+ }
1040
+
1041
+ NK_PUBLIC void nk_angular_f32(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result) {
1042
+ #if NK_TARGET_V128RELAXED
1043
+ nk_angular_f32_v128relaxed(a, b, n, result);
1044
+ #elif NK_TARGET_POWERVSX
1045
+ nk_angular_f32_powervsx(a, b, n, result);
1046
+ #elif NK_TARGET_LOONGSONASX
1047
+ nk_angular_f32_loongsonasx(a, b, n, result);
1048
+ #elif NK_TARGET_RVV
1049
+ nk_angular_f32_rvv(a, b, n, result);
1050
+ #elif NK_TARGET_SVE
1051
+ nk_angular_f32_sve(a, b, n, result);
1052
+ #elif NK_TARGET_NEON
1053
+ nk_angular_f32_neon(a, b, n, result);
1054
+ #elif NK_TARGET_SKYLAKE
1055
+ nk_angular_f32_skylake(a, b, n, result);
1056
+ #elif NK_TARGET_HASWELL
1057
+ nk_angular_f32_haswell(a, b, n, result);
1058
+ #else
1059
+ nk_angular_f32_serial(a, b, n, result);
1060
+ #endif
1061
+ }
1062
+
1063
+ NK_PUBLIC void nk_euclidean_f16(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result) {
1064
+ #if NK_TARGET_V128RELAXED
1065
+ nk_euclidean_f16_v128relaxed(a, b, n, result);
1066
+ #elif NK_TARGET_POWERVSX
1067
+ nk_euclidean_f16_powervsx(a, b, n, result);
1068
+ #elif NK_TARGET_RVVHALF
1069
+ nk_euclidean_f16_rvvhalf(a, b, n, result);
1070
+ #elif NK_TARGET_RVV
1071
+ nk_euclidean_f16_rvv(a, b, n, result);
1072
+ #elif NK_TARGET_SVEHALF
1073
+ nk_euclidean_f16_svehalf(a, b, n, result);
1074
+ #elif NK_TARGET_NEON
1075
+ nk_euclidean_f16_neon(a, b, n, result);
1076
+ #elif NK_TARGET_DIAMOND
1077
+ nk_euclidean_f16_diamond(a, b, n, result);
1078
+ #elif NK_TARGET_SKYLAKE
1079
+ nk_euclidean_f16_skylake(a, b, n, result);
1080
+ #elif NK_TARGET_HASWELL
1081
+ nk_euclidean_f16_haswell(a, b, n, result);
1082
+ #else
1083
+ nk_euclidean_f16_serial(a, b, n, result);
1084
+ #endif
1085
+ }
1086
+
1087
+ NK_PUBLIC void nk_sqeuclidean_f16(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result) {
1088
+ #if NK_TARGET_V128RELAXED
1089
+ nk_sqeuclidean_f16_v128relaxed(a, b, n, result);
1090
+ #elif NK_TARGET_POWERVSX
1091
+ nk_sqeuclidean_f16_powervsx(a, b, n, result);
1092
+ #elif NK_TARGET_RVVHALF
1093
+ nk_sqeuclidean_f16_rvvhalf(a, b, n, result);
1094
+ #elif NK_TARGET_RVV
1095
+ nk_sqeuclidean_f16_rvv(a, b, n, result);
1096
+ #elif NK_TARGET_SVEHALF
1097
+ nk_sqeuclidean_f16_svehalf(a, b, n, result);
1098
+ #elif NK_TARGET_NEON
1099
+ nk_sqeuclidean_f16_neon(a, b, n, result);
1100
+ #elif NK_TARGET_DIAMOND
1101
+ nk_sqeuclidean_f16_diamond(a, b, n, result);
1102
+ #elif NK_TARGET_SKYLAKE
1103
+ nk_sqeuclidean_f16_skylake(a, b, n, result);
1104
+ #elif NK_TARGET_HASWELL
1105
+ nk_sqeuclidean_f16_haswell(a, b, n, result);
1106
+ #else
1107
+ nk_sqeuclidean_f16_serial(a, b, n, result);
1108
+ #endif
1109
+ }
1110
+
1111
+ NK_PUBLIC void nk_angular_f16(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result) {
1112
+ #if NK_TARGET_V128RELAXED
1113
+ nk_angular_f16_v128relaxed(a, b, n, result);
1114
+ #elif NK_TARGET_POWERVSX
1115
+ nk_angular_f16_powervsx(a, b, n, result);
1116
+ #elif NK_TARGET_RVVHALF
1117
+ nk_angular_f16_rvvhalf(a, b, n, result);
1118
+ #elif NK_TARGET_RVV
1119
+ nk_angular_f16_rvv(a, b, n, result);
1120
+ #elif NK_TARGET_SVEHALF
1121
+ nk_angular_f16_svehalf(a, b, n, result);
1122
+ #elif NK_TARGET_NEON
1123
+ nk_angular_f16_neon(a, b, n, result);
1124
+ #elif NK_TARGET_DIAMOND
1125
+ nk_angular_f16_diamond(a, b, n, result);
1126
+ #elif NK_TARGET_SKYLAKE
1127
+ nk_angular_f16_skylake(a, b, n, result);
1128
+ #elif NK_TARGET_HASWELL
1129
+ nk_angular_f16_haswell(a, b, n, result);
1130
+ #else
1131
+ nk_angular_f16_serial(a, b, n, result);
1132
+ #endif
1133
+ }
1134
+
1135
+ NK_PUBLIC void nk_euclidean_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result) {
1136
+ #if NK_TARGET_V128RELAXED
1137
+ nk_euclidean_bf16_v128relaxed(a, b, n, result);
1138
+ #elif NK_TARGET_POWERVSX
1139
+ nk_euclidean_bf16_powervsx(a, b, n, result);
1140
+ #elif NK_TARGET_LOONGSONASX
1141
+ nk_euclidean_bf16_loongsonasx(a, b, n, result);
1142
+ #elif NK_TARGET_RVVBF16
1143
+ nk_euclidean_bf16_rvvbf16(a, b, n, result);
1144
+ #elif NK_TARGET_RVV
1145
+ nk_euclidean_bf16_rvv(a, b, n, result);
1146
+ #elif NK_TARGET_SVEBFDOT
1147
+ nk_euclidean_bf16_svebfdot(a, b, n, result);
1148
+ #elif NK_TARGET_NEONBFDOT
1149
+ nk_euclidean_bf16_neonbfdot(a, b, n, result);
1150
+ #elif NK_TARGET_GENOA
1151
+ nk_euclidean_bf16_genoa(a, b, n, result);
1152
+ #elif NK_TARGET_HASWELL
1153
+ nk_euclidean_bf16_haswell(a, b, n, result);
1154
+ #else
1155
+ nk_euclidean_bf16_serial(a, b, n, result);
1156
+ #endif
1157
+ }
1158
+
1159
+ NK_PUBLIC void nk_sqeuclidean_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result) {
1160
+ #if NK_TARGET_V128RELAXED
1161
+ nk_sqeuclidean_bf16_v128relaxed(a, b, n, result);
1162
+ #elif NK_TARGET_POWERVSX
1163
+ nk_sqeuclidean_bf16_powervsx(a, b, n, result);
1164
+ #elif NK_TARGET_LOONGSONASX
1165
+ nk_sqeuclidean_bf16_loongsonasx(a, b, n, result);
1166
+ #elif NK_TARGET_RVVBF16
1167
+ nk_sqeuclidean_bf16_rvvbf16(a, b, n, result);
1168
+ #elif NK_TARGET_RVV
1169
+ nk_sqeuclidean_bf16_rvv(a, b, n, result);
1170
+ #elif NK_TARGET_SVEBFDOT
1171
+ nk_sqeuclidean_bf16_svebfdot(a, b, n, result);
1172
+ #elif NK_TARGET_NEONBFDOT
1173
+ nk_sqeuclidean_bf16_neonbfdot(a, b, n, result);
1174
+ #elif NK_TARGET_GENOA
1175
+ nk_sqeuclidean_bf16_genoa(a, b, n, result);
1176
+ #elif NK_TARGET_HASWELL
1177
+ nk_sqeuclidean_bf16_haswell(a, b, n, result);
1178
+ #else
1179
+ nk_sqeuclidean_bf16_serial(a, b, n, result);
1180
+ #endif
1181
+ }
1182
+
1183
+ NK_PUBLIC void nk_angular_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result) {
1184
+ #if NK_TARGET_V128RELAXED
1185
+ nk_angular_bf16_v128relaxed(a, b, n, result);
1186
+ #elif NK_TARGET_POWERVSX
1187
+ nk_angular_bf16_powervsx(a, b, n, result);
1188
+ #elif NK_TARGET_LOONGSONASX
1189
+ nk_angular_bf16_loongsonasx(a, b, n, result);
1190
+ #elif NK_TARGET_RVVBF16
1191
+ nk_angular_bf16_rvvbf16(a, b, n, result);
1192
+ #elif NK_TARGET_RVV
1193
+ nk_angular_bf16_rvv(a, b, n, result);
1194
+ #elif NK_TARGET_SVEBFDOT
1195
+ nk_angular_bf16_svebfdot(a, b, n, result);
1196
+ #elif NK_TARGET_NEONBFDOT
1197
+ nk_angular_bf16_neonbfdot(a, b, n, result);
1198
+ #elif NK_TARGET_GENOA
1199
+ nk_angular_bf16_genoa(a, b, n, result);
1200
+ #elif NK_TARGET_HASWELL
1201
+ nk_angular_bf16_haswell(a, b, n, result);
1202
+ #else
1203
+ nk_angular_bf16_serial(a, b, n, result);
1204
+ #endif
1205
+ }
1206
+
1207
+ NK_PUBLIC void nk_euclidean_e4m3(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result) {
1208
+ #if NK_TARGET_NEONFP8
1209
+ nk_euclidean_e4m3_neonfp8(a, b, n, result);
1210
+ #elif NK_TARGET_DIAMOND
1211
+ nk_euclidean_e4m3_diamond(a, b, n, result);
1212
+ #elif NK_TARGET_ICELAKE
1213
+ nk_euclidean_e4m3_icelake(a, b, n, result);
1214
+ #elif NK_TARGET_SKYLAKE
1215
+ nk_euclidean_e4m3_skylake(a, b, n, result);
1216
+ #elif NK_TARGET_RVV
1217
+ nk_euclidean_e4m3_rvv(a, b, n, result);
1218
+ #elif NK_TARGET_V128RELAXED
1219
+ nk_euclidean_e4m3_v128relaxed(a, b, n, result);
1220
+ #else
1221
+ nk_euclidean_e4m3_serial(a, b, n, result);
1222
+ #endif
1223
+ }
1224
+
1225
+ NK_PUBLIC void nk_sqeuclidean_e4m3(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result) {
1226
+ #if NK_TARGET_NEONFP8
1227
+ nk_sqeuclidean_e4m3_neonfp8(a, b, n, result);
1228
+ #elif NK_TARGET_DIAMOND
1229
+ nk_sqeuclidean_e4m3_diamond(a, b, n, result);
1230
+ #elif NK_TARGET_ICELAKE
1231
+ nk_sqeuclidean_e4m3_icelake(a, b, n, result);
1232
+ #elif NK_TARGET_SKYLAKE
1233
+ nk_sqeuclidean_e4m3_skylake(a, b, n, result);
1234
+ #elif NK_TARGET_RVV
1235
+ nk_sqeuclidean_e4m3_rvv(a, b, n, result);
1236
+ #elif NK_TARGET_V128RELAXED
1237
+ nk_sqeuclidean_e4m3_v128relaxed(a, b, n, result);
1238
+ #else
1239
+ nk_sqeuclidean_e4m3_serial(a, b, n, result);
1240
+ #endif
1241
+ }
1242
+
1243
+ NK_PUBLIC void nk_angular_e4m3(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result) {
1244
+ #if NK_TARGET_NEONFP8
1245
+ nk_angular_e4m3_neonfp8(a, b, n, result);
1246
+ #elif NK_TARGET_DIAMOND
1247
+ nk_angular_e4m3_diamond(a, b, n, result);
1248
+ #elif NK_TARGET_ICELAKE
1249
+ nk_angular_e4m3_icelake(a, b, n, result);
1250
+ #elif NK_TARGET_SKYLAKE
1251
+ nk_angular_e4m3_skylake(a, b, n, result);
1252
+ #elif NK_TARGET_RVV
1253
+ nk_angular_e4m3_rvv(a, b, n, result);
1254
+ #elif NK_TARGET_V128RELAXED
1255
+ nk_angular_e4m3_v128relaxed(a, b, n, result);
1256
+ #else
1257
+ nk_angular_e4m3_serial(a, b, n, result);
1258
+ #endif
1259
+ }
1260
+
1261
+ NK_PUBLIC void nk_euclidean_e5m2(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result) {
1262
+ #if NK_TARGET_NEONFP8
1263
+ nk_euclidean_e5m2_neonfp8(a, b, n, result);
1264
+ #elif NK_TARGET_DIAMOND
1265
+ nk_euclidean_e5m2_diamond(a, b, n, result);
1266
+ #elif NK_TARGET_GENOA
1267
+ nk_euclidean_e5m2_genoa(a, b, n, result);
1268
+ #elif NK_TARGET_SKYLAKE
1269
+ nk_euclidean_e5m2_skylake(a, b, n, result);
1270
+ #elif NK_TARGET_RVV
1271
+ nk_euclidean_e5m2_rvv(a, b, n, result);
1272
+ #elif NK_TARGET_V128RELAXED
1273
+ nk_euclidean_e5m2_v128relaxed(a, b, n, result);
1274
+ #else
1275
+ nk_euclidean_e5m2_serial(a, b, n, result);
1276
+ #endif
1277
+ }
1278
+
1279
+ NK_PUBLIC void nk_sqeuclidean_e5m2(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result) {
1280
+ #if NK_TARGET_NEONFP8
1281
+ nk_sqeuclidean_e5m2_neonfp8(a, b, n, result);
1282
+ #elif NK_TARGET_DIAMOND
1283
+ nk_sqeuclidean_e5m2_diamond(a, b, n, result);
1284
+ #elif NK_TARGET_GENOA
1285
+ nk_sqeuclidean_e5m2_genoa(a, b, n, result);
1286
+ #elif NK_TARGET_SKYLAKE
1287
+ nk_sqeuclidean_e5m2_skylake(a, b, n, result);
1288
+ #elif NK_TARGET_RVV
1289
+ nk_sqeuclidean_e5m2_rvv(a, b, n, result);
1290
+ #elif NK_TARGET_V128RELAXED
1291
+ nk_sqeuclidean_e5m2_v128relaxed(a, b, n, result);
1292
+ #else
1293
+ nk_sqeuclidean_e5m2_serial(a, b, n, result);
1294
+ #endif
1295
+ }
1296
+
1297
+ NK_PUBLIC void nk_angular_e5m2(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result) {
1298
+ #if NK_TARGET_NEONFP8
1299
+ nk_angular_e5m2_neonfp8(a, b, n, result);
1300
+ #elif NK_TARGET_DIAMOND
1301
+ nk_angular_e5m2_diamond(a, b, n, result);
1302
+ #elif NK_TARGET_GENOA
1303
+ nk_angular_e5m2_genoa(a, b, n, result);
1304
+ #elif NK_TARGET_SKYLAKE
1305
+ nk_angular_e5m2_skylake(a, b, n, result);
1306
+ #elif NK_TARGET_RVV
1307
+ nk_angular_e5m2_rvv(a, b, n, result);
1308
+ #elif NK_TARGET_V128RELAXED
1309
+ nk_angular_e5m2_v128relaxed(a, b, n, result);
1310
+ #else
1311
+ nk_angular_e5m2_serial(a, b, n, result);
1312
+ #endif
1313
+ }
1314
+
1315
+ NK_PUBLIC void nk_euclidean_e2m3(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result) {
1316
+ #if NK_TARGET_NEONFP8
1317
+ nk_euclidean_e2m3_neonfp8(a, b, n, result);
1318
+ #elif NK_TARGET_ICELAKE
1319
+ nk_euclidean_e2m3_icelake(a, b, n, result);
1320
+ #elif NK_TARGET_SKYLAKE
1321
+ nk_euclidean_e2m3_skylake(a, b, n, result);
1322
+ #elif NK_TARGET_SIERRA
1323
+ nk_euclidean_e2m3_sierra(a, b, n, result);
1324
+ #elif NK_TARGET_ALDER
1325
+ nk_euclidean_e2m3_alder(a, b, n, result);
1326
+ #elif NK_TARGET_HASWELL
1327
+ nk_euclidean_e2m3_haswell(a, b, n, result);
1328
+ #elif NK_TARGET_NEON
1329
+ nk_euclidean_e2m3_neon(a, b, n, result);
1330
+ #elif NK_TARGET_V128RELAXED
1331
+ nk_euclidean_e2m3_v128relaxed(a, b, n, result);
1332
+ #else
1333
+ nk_euclidean_e2m3_serial(a, b, n, result);
1334
+ #endif
1335
+ }
1336
+
1337
+ NK_PUBLIC void nk_sqeuclidean_e2m3(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result) {
1338
+ #if NK_TARGET_NEONFP8
1339
+ nk_sqeuclidean_e2m3_neonfp8(a, b, n, result);
1340
+ #elif NK_TARGET_ICELAKE
1341
+ nk_sqeuclidean_e2m3_icelake(a, b, n, result);
1342
+ #elif NK_TARGET_SKYLAKE
1343
+ nk_sqeuclidean_e2m3_skylake(a, b, n, result);
1344
+ #elif NK_TARGET_SIERRA
1345
+ nk_sqeuclidean_e2m3_sierra(a, b, n, result);
1346
+ #elif NK_TARGET_ALDER
1347
+ nk_sqeuclidean_e2m3_alder(a, b, n, result);
1348
+ #elif NK_TARGET_HASWELL
1349
+ nk_sqeuclidean_e2m3_haswell(a, b, n, result);
1350
+ #elif NK_TARGET_NEON
1351
+ nk_sqeuclidean_e2m3_neon(a, b, n, result);
1352
+ #elif NK_TARGET_V128RELAXED
1353
+ nk_sqeuclidean_e2m3_v128relaxed(a, b, n, result);
1354
+ #else
1355
+ nk_sqeuclidean_e2m3_serial(a, b, n, result);
1356
+ #endif
1357
+ }
1358
+
1359
+ NK_PUBLIC void nk_angular_e2m3(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result) {
1360
+ #if NK_TARGET_NEONFP8
1361
+ nk_angular_e2m3_neonfp8(a, b, n, result);
1362
+ #elif NK_TARGET_ICELAKE
1363
+ nk_angular_e2m3_icelake(a, b, n, result);
1364
+ #elif NK_TARGET_SKYLAKE
1365
+ nk_angular_e2m3_skylake(a, b, n, result);
1366
+ #elif NK_TARGET_SIERRA
1367
+ nk_angular_e2m3_sierra(a, b, n, result);
1368
+ #elif NK_TARGET_ALDER
1369
+ nk_angular_e2m3_alder(a, b, n, result);
1370
+ #elif NK_TARGET_HASWELL
1371
+ nk_angular_e2m3_haswell(a, b, n, result);
1372
+ #elif NK_TARGET_NEON
1373
+ nk_angular_e2m3_neon(a, b, n, result);
1374
+ #elif NK_TARGET_V128RELAXED
1375
+ nk_angular_e2m3_v128relaxed(a, b, n, result);
1376
+ #else
1377
+ nk_angular_e2m3_serial(a, b, n, result);
1378
+ #endif
1379
+ }
1380
+
1381
+ NK_PUBLIC void nk_euclidean_e3m2(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result) {
1382
+ #if NK_TARGET_NEONFP8
1383
+ nk_euclidean_e3m2_neonfp8(a, b, n, result);
1384
+ #elif NK_TARGET_ICELAKE
1385
+ nk_euclidean_e3m2_icelake(a, b, n, result);
1386
+ #elif NK_TARGET_SKYLAKE
1387
+ nk_euclidean_e3m2_skylake(a, b, n, result);
1388
+ #elif NK_TARGET_SIERRA
1389
+ nk_euclidean_e3m2_sierra(a, b, n, result);
1390
+ #elif NK_TARGET_ALDER
1391
+ nk_euclidean_e3m2_alder(a, b, n, result);
1392
+ #elif NK_TARGET_HASWELL
1393
+ nk_euclidean_e3m2_haswell(a, b, n, result);
1394
+ #elif NK_TARGET_NEON
1395
+ nk_euclidean_e3m2_neon(a, b, n, result);
1396
+ #elif NK_TARGET_V128RELAXED
1397
+ nk_euclidean_e3m2_v128relaxed(a, b, n, result);
1398
+ #else
1399
+ nk_euclidean_e3m2_serial(a, b, n, result);
1400
+ #endif
1401
+ }
1402
+
1403
+ NK_PUBLIC void nk_sqeuclidean_e3m2(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result) {
1404
+ #if NK_TARGET_NEONFP8
1405
+ nk_sqeuclidean_e3m2_neonfp8(a, b, n, result);
1406
+ #elif NK_TARGET_ICELAKE
1407
+ nk_sqeuclidean_e3m2_icelake(a, b, n, result);
1408
+ #elif NK_TARGET_SKYLAKE
1409
+ nk_sqeuclidean_e3m2_skylake(a, b, n, result);
1410
+ #elif NK_TARGET_SIERRA
1411
+ nk_sqeuclidean_e3m2_sierra(a, b, n, result);
1412
+ #elif NK_TARGET_ALDER
1413
+ nk_sqeuclidean_e3m2_alder(a, b, n, result);
1414
+ #elif NK_TARGET_HASWELL
1415
+ nk_sqeuclidean_e3m2_haswell(a, b, n, result);
1416
+ #elif NK_TARGET_NEON
1417
+ nk_sqeuclidean_e3m2_neon(a, b, n, result);
1418
+ #elif NK_TARGET_V128RELAXED
1419
+ nk_sqeuclidean_e3m2_v128relaxed(a, b, n, result);
1420
+ #else
1421
+ nk_sqeuclidean_e3m2_serial(a, b, n, result);
1422
+ #endif
1423
+ }
1424
+
1425
+ NK_PUBLIC void nk_angular_e3m2(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result) {
1426
+ #if NK_TARGET_NEONFP8
1427
+ nk_angular_e3m2_neonfp8(a, b, n, result);
1428
+ #elif NK_TARGET_ICELAKE
1429
+ nk_angular_e3m2_icelake(a, b, n, result);
1430
+ #elif NK_TARGET_SKYLAKE
1431
+ nk_angular_e3m2_skylake(a, b, n, result);
1432
+ #elif NK_TARGET_SIERRA
1433
+ nk_angular_e3m2_sierra(a, b, n, result);
1434
+ #elif NK_TARGET_ALDER
1435
+ nk_angular_e3m2_alder(a, b, n, result);
1436
+ #elif NK_TARGET_HASWELL
1437
+ nk_angular_e3m2_haswell(a, b, n, result);
1438
+ #elif NK_TARGET_NEON
1439
+ nk_angular_e3m2_neon(a, b, n, result);
1440
+ #elif NK_TARGET_V128RELAXED
1441
+ nk_angular_e3m2_v128relaxed(a, b, n, result);
1442
+ #else
1443
+ nk_angular_e3m2_serial(a, b, n, result);
1444
+ #endif
1445
+ }
1446
+
1447
+ NK_PUBLIC void nk_euclidean_i8(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result) {
1448
+ #if NK_TARGET_RVV
1449
+ nk_euclidean_i8_rvv(a, b, n, result);
1450
+ #elif NK_TARGET_POWERVSX
1451
+ nk_euclidean_i8_powervsx(a, b, n, result);
1452
+ #elif NK_TARGET_LOONGSONASX
1453
+ nk_euclidean_i8_loongsonasx(a, b, n, result);
1454
+ #elif NK_TARGET_SVESDOT
1455
+ nk_euclidean_i8_svesdot(a, b, n, result);
1456
+ #elif NK_TARGET_NEONSDOT
1457
+ nk_euclidean_i8_neonsdot(a, b, n, result);
1458
+ #elif NK_TARGET_ICELAKE
1459
+ nk_euclidean_i8_icelake(a, b, n, result);
1460
+ #elif NK_TARGET_SIERRA
1461
+ nk_euclidean_i8_sierra(a, b, n, result);
1462
+ #elif NK_TARGET_ALDER
1463
+ nk_euclidean_i8_alder(a, b, n, result);
1464
+ #elif NK_TARGET_HASWELL
1465
+ nk_euclidean_i8_haswell(a, b, n, result);
1466
+ #elif NK_TARGET_V128RELAXED
1467
+ nk_euclidean_i8_v128relaxed(a, b, n, result);
1468
+ #else
1469
+ nk_euclidean_i8_serial(a, b, n, result);
1470
+ #endif
1471
+ }
1472
+
1473
+ NK_PUBLIC void nk_sqeuclidean_i8(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_u32_t *result) {
1474
+ #if NK_TARGET_RVV
1475
+ nk_sqeuclidean_i8_rvv(a, b, n, result);
1476
+ #elif NK_TARGET_POWERVSX
1477
+ nk_sqeuclidean_i8_powervsx(a, b, n, result);
1478
+ #elif NK_TARGET_LOONGSONASX
1479
+ nk_sqeuclidean_i8_loongsonasx(a, b, n, result);
1480
+ #elif NK_TARGET_SVESDOT
1481
+ nk_sqeuclidean_i8_svesdot(a, b, n, result);
1482
+ #elif NK_TARGET_NEONSDOT
1483
+ nk_sqeuclidean_i8_neonsdot(a, b, n, result);
1484
+ #elif NK_TARGET_ICELAKE
1485
+ nk_sqeuclidean_i8_icelake(a, b, n, result);
1486
+ #elif NK_TARGET_SIERRA
1487
+ nk_sqeuclidean_i8_sierra(a, b, n, result);
1488
+ #elif NK_TARGET_ALDER
1489
+ nk_sqeuclidean_i8_alder(a, b, n, result);
1490
+ #elif NK_TARGET_HASWELL
1491
+ nk_sqeuclidean_i8_haswell(a, b, n, result);
1492
+ #elif NK_TARGET_V128RELAXED
1493
+ nk_sqeuclidean_i8_v128relaxed(a, b, n, result);
1494
+ #else
1495
+ nk_sqeuclidean_i8_serial(a, b, n, result);
1496
+ #endif
1497
+ }
1498
+
1499
+ NK_PUBLIC void nk_angular_i8(nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, nk_f32_t *result) {
1500
+ #if NK_TARGET_RVV
1501
+ nk_angular_i8_rvv(a, b, n, result);
1502
+ #elif NK_TARGET_POWERVSX
1503
+ nk_angular_i8_powervsx(a, b, n, result);
1504
+ #elif NK_TARGET_LOONGSONASX
1505
+ nk_angular_i8_loongsonasx(a, b, n, result);
1506
+ #elif NK_TARGET_SVESDOT
1507
+ nk_angular_i8_svesdot(a, b, n, result);
1508
+ #elif NK_TARGET_NEONSDOT
1509
+ nk_angular_i8_neonsdot(a, b, n, result);
1510
+ #elif NK_TARGET_ICELAKE
1511
+ nk_angular_i8_icelake(a, b, n, result);
1512
+ #elif NK_TARGET_SIERRA
1513
+ nk_angular_i8_sierra(a, b, n, result);
1514
+ #elif NK_TARGET_ALDER
1515
+ nk_angular_i8_alder(a, b, n, result);
1516
+ #elif NK_TARGET_HASWELL
1517
+ nk_angular_i8_haswell(a, b, n, result);
1518
+ #elif NK_TARGET_V128RELAXED
1519
+ nk_angular_i8_v128relaxed(a, b, n, result);
1520
+ #else
1521
+ nk_angular_i8_serial(a, b, n, result);
1522
+ #endif
1523
+ }
1524
+
1525
+ NK_PUBLIC void nk_euclidean_u8(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result) {
1526
+ #if NK_TARGET_RVV
1527
+ nk_euclidean_u8_rvv(a, b, n, result);
1528
+ #elif NK_TARGET_POWERVSX
1529
+ nk_euclidean_u8_powervsx(a, b, n, result);
1530
+ #elif NK_TARGET_LOONGSONASX
1531
+ nk_euclidean_u8_loongsonasx(a, b, n, result);
1532
+ #elif NK_TARGET_SVESDOT
1533
+ nk_euclidean_u8_svesdot(a, b, n, result);
1534
+ #elif NK_TARGET_NEONSDOT
1535
+ nk_euclidean_u8_neonsdot(a, b, n, result);
1536
+ #elif NK_TARGET_ICELAKE
1537
+ nk_euclidean_u8_icelake(a, b, n, result);
1538
+ #elif NK_TARGET_SIERRA
1539
+ nk_euclidean_u8_sierra(a, b, n, result);
1540
+ #elif NK_TARGET_ALDER
1541
+ nk_euclidean_u8_alder(a, b, n, result);
1542
+ #elif NK_TARGET_HASWELL
1543
+ nk_euclidean_u8_haswell(a, b, n, result);
1544
+ #elif NK_TARGET_V128RELAXED
1545
+ nk_euclidean_u8_v128relaxed(a, b, n, result);
1546
+ #else
1547
+ nk_euclidean_u8_serial(a, b, n, result);
1548
+ #endif
1549
+ }
1550
+
1551
+ NK_PUBLIC void nk_sqeuclidean_u8(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result) {
1552
+ #if NK_TARGET_RVV
1553
+ nk_sqeuclidean_u8_rvv(a, b, n, result);
1554
+ #elif NK_TARGET_POWERVSX
1555
+ nk_sqeuclidean_u8_powervsx(a, b, n, result);
1556
+ #elif NK_TARGET_LOONGSONASX
1557
+ nk_sqeuclidean_u8_loongsonasx(a, b, n, result);
1558
+ #elif NK_TARGET_SVESDOT
1559
+ nk_sqeuclidean_u8_svesdot(a, b, n, result);
1560
+ #elif NK_TARGET_NEONSDOT
1561
+ nk_sqeuclidean_u8_neonsdot(a, b, n, result);
1562
+ #elif NK_TARGET_ICELAKE
1563
+ nk_sqeuclidean_u8_icelake(a, b, n, result);
1564
+ #elif NK_TARGET_SIERRA
1565
+ nk_sqeuclidean_u8_sierra(a, b, n, result);
1566
+ #elif NK_TARGET_ALDER
1567
+ nk_sqeuclidean_u8_alder(a, b, n, result);
1568
+ #elif NK_TARGET_HASWELL
1569
+ nk_sqeuclidean_u8_haswell(a, b, n, result);
1570
+ #elif NK_TARGET_V128RELAXED
1571
+ nk_sqeuclidean_u8_v128relaxed(a, b, n, result);
1572
+ #else
1573
+ nk_sqeuclidean_u8_serial(a, b, n, result);
1574
+ #endif
1575
+ }
1576
+
1577
+ NK_PUBLIC void nk_angular_u8(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_f32_t *result) {
1578
+ #if NK_TARGET_RVV
1579
+ nk_angular_u8_rvv(a, b, n, result);
1580
+ #elif NK_TARGET_POWERVSX
1581
+ nk_angular_u8_powervsx(a, b, n, result);
1582
+ #elif NK_TARGET_LOONGSONASX
1583
+ nk_angular_u8_loongsonasx(a, b, n, result);
1584
+ #elif NK_TARGET_SVESDOT
1585
+ nk_angular_u8_svesdot(a, b, n, result);
1586
+ #elif NK_TARGET_NEONSDOT
1587
+ nk_angular_u8_neonsdot(a, b, n, result);
1588
+ #elif NK_TARGET_ICELAKE
1589
+ nk_angular_u8_icelake(a, b, n, result);
1590
+ #elif NK_TARGET_SIERRA
1591
+ nk_angular_u8_sierra(a, b, n, result);
1592
+ #elif NK_TARGET_ALDER
1593
+ nk_angular_u8_alder(a, b, n, result);
1594
+ #elif NK_TARGET_HASWELL
1595
+ nk_angular_u8_haswell(a, b, n, result);
1596
+ #elif NK_TARGET_V128RELAXED
1597
+ nk_angular_u8_v128relaxed(a, b, n, result);
1598
+ #else
1599
+ nk_angular_u8_serial(a, b, n, result);
1600
+ #endif
1601
+ }
1602
+
1603
+ NK_PUBLIC void nk_euclidean_i4(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result) {
1604
+ #if NK_TARGET_ICELAKE
1605
+ nk_euclidean_i4_icelake(a, b, n, result);
1606
+ #elif NK_TARGET_NEONSDOT
1607
+ nk_euclidean_i4_neonsdot(a, b, n, result);
1608
+ #elif NK_TARGET_RVV
1609
+ nk_euclidean_i4_rvv(a, b, n, result);
1610
+ #else
1611
+ nk_euclidean_i4_serial(a, b, n, result);
1612
+ #endif
1613
+ }
1614
+
1615
+ NK_PUBLIC void nk_sqeuclidean_i4(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_u32_t *result) {
1616
+ #if NK_TARGET_ICELAKE
1617
+ nk_sqeuclidean_i4_icelake(a, b, n, result);
1618
+ #elif NK_TARGET_NEONSDOT
1619
+ nk_sqeuclidean_i4_neonsdot(a, b, n, result);
1620
+ #elif NK_TARGET_RVV
1621
+ nk_sqeuclidean_i4_rvv(a, b, n, result);
1622
+ #else
1623
+ nk_sqeuclidean_i4_serial(a, b, n, result);
1624
+ #endif
1625
+ }
1626
+
1627
+ NK_PUBLIC void nk_angular_i4(nk_i4x2_t const *a, nk_i4x2_t const *b, nk_size_t n, nk_f32_t *result) {
1628
+ #if NK_TARGET_ICELAKE
1629
+ nk_angular_i4_icelake(a, b, n, result);
1630
+ #elif NK_TARGET_NEONSDOT
1631
+ nk_angular_i4_neonsdot(a, b, n, result);
1632
+ #elif NK_TARGET_RVV
1633
+ nk_angular_i4_rvv(a, b, n, result);
1634
+ #else
1635
+ nk_angular_i4_serial(a, b, n, result);
1636
+ #endif
1637
+ }
1638
+
1639
+ NK_PUBLIC void nk_euclidean_u4(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result) {
1640
+ #if NK_TARGET_ICELAKE
1641
+ nk_euclidean_u4_icelake(a, b, n, result);
1642
+ #elif NK_TARGET_NEONSDOT
1643
+ nk_euclidean_u4_neonsdot(a, b, n, result);
1644
+ #elif NK_TARGET_RVV
1645
+ nk_euclidean_u4_rvv(a, b, n, result);
1646
+ #else
1647
+ nk_euclidean_u4_serial(a, b, n, result);
1648
+ #endif
1649
+ }
1650
+
1651
+ NK_PUBLIC void nk_sqeuclidean_u4(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_u32_t *result) {
1652
+ #if NK_TARGET_ICELAKE
1653
+ nk_sqeuclidean_u4_icelake(a, b, n, result);
1654
+ #elif NK_TARGET_NEONSDOT
1655
+ nk_sqeuclidean_u4_neonsdot(a, b, n, result);
1656
+ #elif NK_TARGET_RVV
1657
+ nk_sqeuclidean_u4_rvv(a, b, n, result);
1658
+ #else
1659
+ nk_sqeuclidean_u4_serial(a, b, n, result);
1660
+ #endif
1661
+ }
1662
+
1663
+ NK_PUBLIC void nk_angular_u4(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_size_t n, nk_f32_t *result) {
1664
+ #if NK_TARGET_ICELAKE
1665
+ nk_angular_u4_icelake(a, b, n, result);
1666
+ #elif NK_TARGET_NEONSDOT
1667
+ nk_angular_u4_neonsdot(a, b, n, result);
1668
+ #elif NK_TARGET_RVV
1669
+ nk_angular_u4_rvv(a, b, n, result);
1670
+ #else
1671
+ nk_angular_u4_serial(a, b, n, result);
1672
+ #endif
1673
+ }
1674
+
1675
+ #endif // !NK_DYNAMIC_DISPATCH
1676
+
1677
+ #if defined(__cplusplus)
1678
+ } // extern "C"
1679
+ #endif
1680
+
1681
+ #endif