usearch 2.21.4 → 2.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (602) hide show
  1. package/README.md +24 -24
  2. package/binding.gyp +15 -37
  3. package/c/CMakeLists.txt +4 -5
  4. package/c/README.md +7 -7
  5. package/c/lib.cpp +32 -14
  6. package/c/test.c +83 -1
  7. package/c/usearch.h +24 -3
  8. package/cpp/CMakeLists.txt +4 -0
  9. package/cpp/README.md +5 -5
  10. package/cpp/bench.cpp +97 -116
  11. package/cpp/test.cpp +117 -20
  12. package/include/usearch/index.hpp +224 -48
  13. package/include/usearch/index_dense.hpp +105 -40
  14. package/include/usearch/index_plugins.hpp +1387 -204
  15. package/javascript/dist/cjs/usearch.d.ts +8 -3
  16. package/javascript/dist/cjs/usearch.js +12 -4
  17. package/javascript/dist/esm/usearch.d.ts +8 -3
  18. package/javascript/dist/esm/usearch.js +12 -4
  19. package/javascript/lib.cpp +17 -0
  20. package/javascript/usearch.ts +14 -6
  21. package/numkong/.clang-tidy +30 -0
  22. package/{simsimd → numkong}/.cmake-format.py +18 -0
  23. package/numkong/.editorconfig +12 -0
  24. package/numkong/.git-blame-ignore-revs +123 -0
  25. package/numkong/.mailmap +15 -0
  26. package/numkong/.spi.yml +11 -0
  27. package/numkong/.swift-format +14 -0
  28. package/numkong/CITATION.cff +81 -0
  29. package/numkong/CONTRIBUTING.md +500 -0
  30. package/numkong/Cargo.toml +54 -0
  31. package/numkong/MANIFEST.in +8 -0
  32. package/numkong/Package.swift +84 -0
  33. package/numkong/README.md +569 -0
  34. package/numkong/bench/README.md +217 -0
  35. package/numkong/bench/bench-browser.html +323 -0
  36. package/numkong/bench/bench.cpp +344 -0
  37. package/numkong/bench/bench.hpp +816 -0
  38. package/numkong/bench/bench.js +148 -0
  39. package/numkong/bench/bench.mjs +616 -0
  40. package/numkong/bench/bench_attention.cpp +113 -0
  41. package/numkong/bench/bench_cast.cpp +264 -0
  42. package/numkong/bench/bench_cross_amx.cpp +62 -0
  43. package/numkong/bench/bench_cross_arm.cpp +245 -0
  44. package/numkong/bench/bench_cross_blas.cpp +309 -0
  45. package/numkong/bench/bench_cross_loongarch.cpp +106 -0
  46. package/numkong/bench/bench_cross_power.cpp +84 -0
  47. package/numkong/bench/bench_cross_rvv.cpp +121 -0
  48. package/numkong/bench/bench_cross_serial.cpp +151 -0
  49. package/numkong/bench/bench_cross_sme.cpp +163 -0
  50. package/numkong/bench/bench_cross_wasm.cpp +142 -0
  51. package/numkong/bench/bench_cross_x86.cpp +455 -0
  52. package/numkong/bench/bench_curved.cpp +210 -0
  53. package/numkong/bench/bench_dot.cpp +315 -0
  54. package/numkong/bench/bench_each.cpp +503 -0
  55. package/numkong/bench/bench_geospatial.cpp +112 -0
  56. package/numkong/bench/bench_maxsim.cpp +154 -0
  57. package/numkong/bench/bench_mesh.cpp +148 -0
  58. package/numkong/bench/bench_probability.cpp +60 -0
  59. package/numkong/bench/bench_reduce.cpp +371 -0
  60. package/numkong/bench/bench_set.cpp +73 -0
  61. package/numkong/bench/bench_sparse.cpp +198 -0
  62. package/numkong/bench/bench_spatial.cpp +347 -0
  63. package/numkong/bench/bench_trigonometry.cpp +137 -0
  64. package/numkong/bench/swift/Bench.swift +506 -0
  65. package/numkong/binding.gyp +169 -0
  66. package/numkong/build.rs +484 -0
  67. package/numkong/c/dispatch.h +512 -0
  68. package/numkong/c/dispatch_bf16.c +447 -0
  69. package/numkong/c/dispatch_bf16c.c +52 -0
  70. package/numkong/c/dispatch_e2m3.c +296 -0
  71. package/numkong/c/dispatch_e3m2.c +284 -0
  72. package/numkong/c/dispatch_e4m3.c +318 -0
  73. package/numkong/c/dispatch_e5m2.c +316 -0
  74. package/numkong/c/dispatch_f16.c +452 -0
  75. package/numkong/c/dispatch_f16c.c +58 -0
  76. package/numkong/c/dispatch_f32.c +434 -0
  77. package/numkong/c/dispatch_f32c.c +99 -0
  78. package/numkong/c/dispatch_f64.c +348 -0
  79. package/numkong/c/dispatch_f64c.c +98 -0
  80. package/numkong/c/dispatch_i16.c +96 -0
  81. package/numkong/c/dispatch_i32.c +89 -0
  82. package/numkong/c/dispatch_i4.c +153 -0
  83. package/numkong/c/dispatch_i64.c +86 -0
  84. package/numkong/c/dispatch_i8.c +348 -0
  85. package/numkong/c/dispatch_other.c +348 -0
  86. package/numkong/c/dispatch_u1.c +193 -0
  87. package/numkong/c/dispatch_u16.c +124 -0
  88. package/numkong/c/dispatch_u32.c +118 -0
  89. package/numkong/c/dispatch_u4.c +153 -0
  90. package/numkong/c/dispatch_u64.c +102 -0
  91. package/numkong/c/dispatch_u8.c +364 -0
  92. package/numkong/c/numkong.c +940 -0
  93. package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
  94. package/numkong/cmake/nk_isa_probe.cmake +90 -0
  95. package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
  96. package/numkong/cmake/nk_math_lib.cmake +46 -0
  97. package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
  98. package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
  99. package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
  100. package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
  101. package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
  102. package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
  103. package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
  104. package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
  105. package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
  106. package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
  107. package/numkong/cmake/toolchain-wasi.cmake +77 -0
  108. package/numkong/cmake/toolchain-wasm.cmake +70 -0
  109. package/numkong/cmake/toolchain-wasm64.cmake +62 -0
  110. package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
  111. package/numkong/include/README.md +643 -0
  112. package/numkong/include/module.modulemap +129 -0
  113. package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
  114. package/numkong/include/numkong/attention/sme.h +2075 -0
  115. package/numkong/include/numkong/attention.h +49 -0
  116. package/numkong/include/numkong/capabilities.h +930 -0
  117. package/numkong/include/numkong/cast/README.md +262 -0
  118. package/numkong/include/numkong/cast/diamond.h +64 -0
  119. package/numkong/include/numkong/cast/haswell.h +823 -0
  120. package/numkong/include/numkong/cast/icelake.h +475 -0
  121. package/numkong/include/numkong/cast/loongsonasx.h +252 -0
  122. package/numkong/include/numkong/cast/neon.h +1174 -0
  123. package/numkong/include/numkong/cast/powervsx.h +449 -0
  124. package/numkong/include/numkong/cast/rvv.h +970 -0
  125. package/numkong/include/numkong/cast/sapphire.h +262 -0
  126. package/numkong/include/numkong/cast/serial.h +2336 -0
  127. package/numkong/include/numkong/cast/skylake.h +915 -0
  128. package/numkong/include/numkong/cast/v128relaxed.h +537 -0
  129. package/numkong/include/numkong/cast.h +254 -0
  130. package/numkong/include/numkong/cast.hpp +44 -0
  131. package/numkong/include/numkong/curved/README.md +223 -0
  132. package/numkong/include/numkong/curved/genoa.h +182 -0
  133. package/numkong/include/numkong/curved/haswell.h +276 -0
  134. package/numkong/include/numkong/curved/neon.h +329 -0
  135. package/numkong/include/numkong/curved/neonbfdot.h +211 -0
  136. package/numkong/include/numkong/curved/rvv.h +305 -0
  137. package/numkong/include/numkong/curved/serial.h +207 -0
  138. package/numkong/include/numkong/curved/skylake.h +457 -0
  139. package/numkong/include/numkong/curved/smef64.h +530 -0
  140. package/numkong/include/numkong/curved.h +513 -0
  141. package/numkong/include/numkong/curved.hpp +144 -0
  142. package/numkong/include/numkong/dot/README.md +442 -0
  143. package/numkong/include/numkong/dot/alder.h +563 -0
  144. package/numkong/include/numkong/dot/diamond.h +158 -0
  145. package/numkong/include/numkong/dot/genoa.h +289 -0
  146. package/numkong/include/numkong/dot/haswell.h +1723 -0
  147. package/numkong/include/numkong/dot/icelake.h +997 -0
  148. package/numkong/include/numkong/dot/loongsonasx.h +671 -0
  149. package/numkong/include/numkong/dot/neon.h +869 -0
  150. package/numkong/include/numkong/dot/neonbfdot.h +243 -0
  151. package/numkong/include/numkong/dot/neonfhm.h +358 -0
  152. package/numkong/include/numkong/dot/neonfp8.h +323 -0
  153. package/numkong/include/numkong/dot/neonsdot.h +622 -0
  154. package/numkong/include/numkong/dot/powervsx.h +752 -0
  155. package/numkong/include/numkong/dot/rvv.h +722 -0
  156. package/numkong/include/numkong/dot/rvvbb.h +72 -0
  157. package/numkong/include/numkong/dot/rvvbf16.h +123 -0
  158. package/numkong/include/numkong/dot/rvvhalf.h +129 -0
  159. package/numkong/include/numkong/dot/sapphire.h +141 -0
  160. package/numkong/include/numkong/dot/serial.h +874 -0
  161. package/numkong/include/numkong/dot/sierra.h +405 -0
  162. package/numkong/include/numkong/dot/skylake.h +1116 -0
  163. package/numkong/include/numkong/dot/sve.h +420 -0
  164. package/numkong/include/numkong/dot/svebfdot.h +75 -0
  165. package/numkong/include/numkong/dot/svehalf.h +168 -0
  166. package/numkong/include/numkong/dot/svesdot.h +90 -0
  167. package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
  168. package/numkong/include/numkong/dot.h +1136 -0
  169. package/numkong/include/numkong/dot.hpp +94 -0
  170. package/numkong/include/numkong/dots/README.md +496 -0
  171. package/numkong/include/numkong/dots/alder.h +117 -0
  172. package/numkong/include/numkong/dots/diamond.h +86 -0
  173. package/numkong/include/numkong/dots/genoa.h +100 -0
  174. package/numkong/include/numkong/dots/graniteamx.h +733 -0
  175. package/numkong/include/numkong/dots/haswell.h +310 -0
  176. package/numkong/include/numkong/dots/icelake.h +180 -0
  177. package/numkong/include/numkong/dots/loongsonasx.h +176 -0
  178. package/numkong/include/numkong/dots/neon.h +123 -0
  179. package/numkong/include/numkong/dots/neonbfdot.h +59 -0
  180. package/numkong/include/numkong/dots/neonfhm.h +96 -0
  181. package/numkong/include/numkong/dots/neonfp8.h +99 -0
  182. package/numkong/include/numkong/dots/neonsdot.h +144 -0
  183. package/numkong/include/numkong/dots/powervsx.h +194 -0
  184. package/numkong/include/numkong/dots/rvv.h +2593 -0
  185. package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
  186. package/numkong/include/numkong/dots/serial.h +2867 -0
  187. package/numkong/include/numkong/dots/sierra.h +100 -0
  188. package/numkong/include/numkong/dots/skylake.h +207 -0
  189. package/numkong/include/numkong/dots/sme.h +5041 -0
  190. package/numkong/include/numkong/dots/smebi32.h +477 -0
  191. package/numkong/include/numkong/dots/smef64.h +1328 -0
  192. package/numkong/include/numkong/dots/smehalf.h +47 -0
  193. package/numkong/include/numkong/dots/v128relaxed.h +317 -0
  194. package/numkong/include/numkong/dots.h +3110 -0
  195. package/numkong/include/numkong/dots.hpp +641 -0
  196. package/numkong/include/numkong/each/README.md +465 -0
  197. package/numkong/include/numkong/each/haswell.h +1658 -0
  198. package/numkong/include/numkong/each/icelake.h +272 -0
  199. package/numkong/include/numkong/each/neon.h +1138 -0
  200. package/numkong/include/numkong/each/neonbfdot.h +211 -0
  201. package/numkong/include/numkong/each/neonhalf.h +318 -0
  202. package/numkong/include/numkong/each/rvv.h +1121 -0
  203. package/numkong/include/numkong/each/sapphire.h +343 -0
  204. package/numkong/include/numkong/each/serial.h +282 -0
  205. package/numkong/include/numkong/each/skylake.h +1562 -0
  206. package/numkong/include/numkong/each/v128relaxed.h +562 -0
  207. package/numkong/include/numkong/each.h +2232 -0
  208. package/numkong/include/numkong/each.hpp +434 -0
  209. package/numkong/include/numkong/geospatial/README.md +147 -0
  210. package/numkong/include/numkong/geospatial/haswell.h +633 -0
  211. package/numkong/include/numkong/geospatial/neon.h +615 -0
  212. package/numkong/include/numkong/geospatial/rvv.h +701 -0
  213. package/numkong/include/numkong/geospatial/serial.h +309 -0
  214. package/numkong/include/numkong/geospatial/skylake.h +613 -0
  215. package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
  216. package/numkong/include/numkong/geospatial.h +453 -0
  217. package/numkong/include/numkong/geospatial.hpp +235 -0
  218. package/numkong/include/numkong/matrix.hpp +336 -0
  219. package/numkong/include/numkong/maxsim/README.md +187 -0
  220. package/numkong/include/numkong/maxsim/alder.h +511 -0
  221. package/numkong/include/numkong/maxsim/genoa.h +115 -0
  222. package/numkong/include/numkong/maxsim/haswell.h +553 -0
  223. package/numkong/include/numkong/maxsim/icelake.h +480 -0
  224. package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
  225. package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
  226. package/numkong/include/numkong/maxsim/serial.h +490 -0
  227. package/numkong/include/numkong/maxsim/sme.h +993 -0
  228. package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
  229. package/numkong/include/numkong/maxsim.h +571 -0
  230. package/numkong/include/numkong/maxsim.hpp +133 -0
  231. package/numkong/include/numkong/mesh/README.md +219 -0
  232. package/numkong/include/numkong/mesh/haswell.h +2013 -0
  233. package/numkong/include/numkong/mesh/neon.h +1821 -0
  234. package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
  235. package/numkong/include/numkong/mesh/rvv.h +936 -0
  236. package/numkong/include/numkong/mesh/serial.h +721 -0
  237. package/numkong/include/numkong/mesh/skylake.h +2344 -0
  238. package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
  239. package/numkong/include/numkong/mesh.h +666 -0
  240. package/numkong/include/numkong/mesh.hpp +701 -0
  241. package/numkong/include/numkong/numkong.h +78 -0
  242. package/numkong/include/numkong/numkong.hpp +58 -0
  243. package/numkong/include/numkong/probability/README.md +177 -0
  244. package/numkong/include/numkong/probability/haswell.h +267 -0
  245. package/numkong/include/numkong/probability/neon.h +255 -0
  246. package/numkong/include/numkong/probability/rvv.h +414 -0
  247. package/numkong/include/numkong/probability/serial.h +181 -0
  248. package/numkong/include/numkong/probability/skylake.h +324 -0
  249. package/numkong/include/numkong/probability.h +380 -0
  250. package/numkong/include/numkong/probability.hpp +120 -0
  251. package/numkong/include/numkong/random.h +50 -0
  252. package/numkong/include/numkong/random.hpp +285 -0
  253. package/numkong/include/numkong/reduce/README.md +552 -0
  254. package/numkong/include/numkong/reduce/alder.h +636 -0
  255. package/numkong/include/numkong/reduce/genoa.h +201 -0
  256. package/numkong/include/numkong/reduce/haswell.h +3785 -0
  257. package/numkong/include/numkong/reduce/icelake.h +549 -0
  258. package/numkong/include/numkong/reduce/neon.h +3980 -0
  259. package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
  260. package/numkong/include/numkong/reduce/neonfhm.h +293 -0
  261. package/numkong/include/numkong/reduce/neonsdot.h +357 -0
  262. package/numkong/include/numkong/reduce/rvv.h +3533 -0
  263. package/numkong/include/numkong/reduce/serial.h +753 -0
  264. package/numkong/include/numkong/reduce/sierra.h +338 -0
  265. package/numkong/include/numkong/reduce/skylake.h +3794 -0
  266. package/numkong/include/numkong/reduce/sve.h +52 -0
  267. package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
  268. package/numkong/include/numkong/reduce.h +1582 -0
  269. package/numkong/include/numkong/reduce.hpp +778 -0
  270. package/numkong/include/numkong/scalar/README.md +89 -0
  271. package/numkong/include/numkong/scalar/haswell.h +122 -0
  272. package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
  273. package/numkong/include/numkong/scalar/neon.h +122 -0
  274. package/numkong/include/numkong/scalar/neonhalf.h +70 -0
  275. package/numkong/include/numkong/scalar/powervsx.h +96 -0
  276. package/numkong/include/numkong/scalar/rvv.h +211 -0
  277. package/numkong/include/numkong/scalar/sapphire.h +74 -0
  278. package/numkong/include/numkong/scalar/serial.h +332 -0
  279. package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
  280. package/numkong/include/numkong/scalar.h +696 -0
  281. package/numkong/include/numkong/set/README.md +179 -0
  282. package/numkong/include/numkong/set/haswell.h +334 -0
  283. package/numkong/include/numkong/set/icelake.h +485 -0
  284. package/numkong/include/numkong/set/loongsonasx.h +181 -0
  285. package/numkong/include/numkong/set/neon.h +363 -0
  286. package/numkong/include/numkong/set/powervsx.h +326 -0
  287. package/numkong/include/numkong/set/rvv.h +226 -0
  288. package/numkong/include/numkong/set/rvvbb.h +117 -0
  289. package/numkong/include/numkong/set/serial.h +174 -0
  290. package/numkong/include/numkong/set/sve.h +187 -0
  291. package/numkong/include/numkong/set/v128relaxed.h +240 -0
  292. package/numkong/include/numkong/set.h +471 -0
  293. package/numkong/include/numkong/set.hpp +114 -0
  294. package/numkong/include/numkong/sets/README.md +149 -0
  295. package/numkong/include/numkong/sets/haswell.h +63 -0
  296. package/numkong/include/numkong/sets/icelake.h +66 -0
  297. package/numkong/include/numkong/sets/loongsonasx.h +52 -0
  298. package/numkong/include/numkong/sets/neon.h +61 -0
  299. package/numkong/include/numkong/sets/powervsx.h +65 -0
  300. package/numkong/include/numkong/sets/serial.h +43 -0
  301. package/numkong/include/numkong/sets/smebi32.h +1135 -0
  302. package/numkong/include/numkong/sets/v128relaxed.h +58 -0
  303. package/numkong/include/numkong/sets.h +382 -0
  304. package/numkong/include/numkong/sparse/README.md +156 -0
  305. package/numkong/include/numkong/sparse/icelake.h +463 -0
  306. package/numkong/include/numkong/sparse/neon.h +288 -0
  307. package/numkong/include/numkong/sparse/serial.h +117 -0
  308. package/numkong/include/numkong/sparse/sve2.h +504 -0
  309. package/numkong/include/numkong/sparse/turin.h +322 -0
  310. package/numkong/include/numkong/sparse.h +363 -0
  311. package/numkong/include/numkong/sparse.hpp +113 -0
  312. package/numkong/include/numkong/spatial/README.md +439 -0
  313. package/numkong/include/numkong/spatial/alder.h +604 -0
  314. package/numkong/include/numkong/spatial/diamond.h +240 -0
  315. package/numkong/include/numkong/spatial/genoa.h +222 -0
  316. package/numkong/include/numkong/spatial/haswell.h +979 -0
  317. package/numkong/include/numkong/spatial/icelake.h +1067 -0
  318. package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
  319. package/numkong/include/numkong/spatial/neon.h +846 -0
  320. package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
  321. package/numkong/include/numkong/spatial/neonfp8.h +258 -0
  322. package/numkong/include/numkong/spatial/neonsdot.h +429 -0
  323. package/numkong/include/numkong/spatial/powervsx.h +738 -0
  324. package/numkong/include/numkong/spatial/rvv.h +991 -0
  325. package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
  326. package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
  327. package/numkong/include/numkong/spatial/serial.h +347 -0
  328. package/numkong/include/numkong/spatial/sierra.h +516 -0
  329. package/numkong/include/numkong/spatial/skylake.h +605 -0
  330. package/numkong/include/numkong/spatial/sve.h +246 -0
  331. package/numkong/include/numkong/spatial/svebfdot.h +125 -0
  332. package/numkong/include/numkong/spatial/svehalf.h +136 -0
  333. package/numkong/include/numkong/spatial/svesdot.h +143 -0
  334. package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
  335. package/numkong/include/numkong/spatial.h +1681 -0
  336. package/numkong/include/numkong/spatial.hpp +183 -0
  337. package/numkong/include/numkong/spatials/README.md +580 -0
  338. package/numkong/include/numkong/spatials/alder.h +94 -0
  339. package/numkong/include/numkong/spatials/diamond.h +82 -0
  340. package/numkong/include/numkong/spatials/genoa.h +94 -0
  341. package/numkong/include/numkong/spatials/graniteamx.h +173 -0
  342. package/numkong/include/numkong/spatials/haswell.h +219 -0
  343. package/numkong/include/numkong/spatials/icelake.h +113 -0
  344. package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
  345. package/numkong/include/numkong/spatials/neon.h +109 -0
  346. package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
  347. package/numkong/include/numkong/spatials/neonfhm.h +92 -0
  348. package/numkong/include/numkong/spatials/neonfp8.h +111 -0
  349. package/numkong/include/numkong/spatials/neonsdot.h +143 -0
  350. package/numkong/include/numkong/spatials/powervsx.h +153 -0
  351. package/numkong/include/numkong/spatials/rvv.h +1976 -0
  352. package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
  353. package/numkong/include/numkong/spatials/serial.h +248 -0
  354. package/numkong/include/numkong/spatials/sierra.h +96 -0
  355. package/numkong/include/numkong/spatials/skylake.h +184 -0
  356. package/numkong/include/numkong/spatials/sme.h +1927 -0
  357. package/numkong/include/numkong/spatials/smef64.h +483 -0
  358. package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
  359. package/numkong/include/numkong/spatials.h +3374 -0
  360. package/numkong/include/numkong/spatials.hpp +509 -0
  361. package/numkong/include/numkong/tensor.hpp +1981 -0
  362. package/numkong/include/numkong/trigonometry/README.md +184 -0
  363. package/numkong/include/numkong/trigonometry/haswell.h +653 -0
  364. package/numkong/include/numkong/trigonometry/neon.h +638 -0
  365. package/numkong/include/numkong/trigonometry/rvv.h +700 -0
  366. package/numkong/include/numkong/trigonometry/serial.h +703 -0
  367. package/numkong/include/numkong/trigonometry/skylake.h +725 -0
  368. package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
  369. package/numkong/include/numkong/trigonometry.h +467 -0
  370. package/numkong/include/numkong/trigonometry.hpp +166 -0
  371. package/numkong/include/numkong/types.h +1695 -0
  372. package/numkong/include/numkong/types.hpp +6027 -0
  373. package/numkong/include/numkong/vector.hpp +766 -0
  374. package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
  375. package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
  376. package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
  377. package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
  378. package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
  379. package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
  380. package/numkong/javascript/README.md +254 -0
  381. package/numkong/javascript/node-gyp-build.d.ts +4 -0
  382. package/numkong/javascript/numkong-browser.ts +40 -0
  383. package/numkong/javascript/numkong-wasm.ts +750 -0
  384. package/numkong/javascript/numkong.c +712 -0
  385. package/numkong/javascript/numkong.ts +613 -0
  386. package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
  387. package/numkong/javascript/tsconfig-cjs.json +13 -0
  388. package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
  389. package/numkong/javascript/types.ts +784 -0
  390. package/numkong/numkong.gypi +104 -0
  391. package/numkong/package.json +108 -0
  392. package/numkong/probes/arm_neon.c +8 -0
  393. package/numkong/probes/arm_neon_bfdot.c +9 -0
  394. package/numkong/probes/arm_neon_fhm.c +9 -0
  395. package/numkong/probes/arm_neon_half.c +8 -0
  396. package/numkong/probes/arm_neon_sdot.c +9 -0
  397. package/numkong/probes/arm_neonfp8.c +9 -0
  398. package/numkong/probes/arm_sme.c +16 -0
  399. package/numkong/probes/arm_sme2.c +16 -0
  400. package/numkong/probes/arm_sme2p1.c +16 -0
  401. package/numkong/probes/arm_sme_bf16.c +16 -0
  402. package/numkong/probes/arm_sme_bi32.c +16 -0
  403. package/numkong/probes/arm_sme_f64.c +16 -0
  404. package/numkong/probes/arm_sme_fa64.c +14 -0
  405. package/numkong/probes/arm_sme_half.c +16 -0
  406. package/numkong/probes/arm_sme_lut2.c +15 -0
  407. package/numkong/probes/arm_sve.c +18 -0
  408. package/numkong/probes/arm_sve2.c +20 -0
  409. package/numkong/probes/arm_sve2p1.c +18 -0
  410. package/numkong/probes/arm_sve_bfdot.c +20 -0
  411. package/numkong/probes/arm_sve_half.c +18 -0
  412. package/numkong/probes/arm_sve_sdot.c +21 -0
  413. package/numkong/probes/loongarch_lasx.c +12 -0
  414. package/numkong/probes/power_vsx.c +12 -0
  415. package/numkong/probes/probe.js +127 -0
  416. package/numkong/probes/riscv_rvv.c +14 -0
  417. package/numkong/probes/riscv_rvv_bb.c +15 -0
  418. package/numkong/probes/riscv_rvv_bf16.c +17 -0
  419. package/numkong/probes/riscv_rvv_half.c +14 -0
  420. package/numkong/probes/wasm_v128relaxed.c +11 -0
  421. package/numkong/probes/x86_alder.c +17 -0
  422. package/numkong/probes/x86_diamond.c +17 -0
  423. package/numkong/probes/x86_genoa.c +17 -0
  424. package/numkong/probes/x86_graniteamx.c +19 -0
  425. package/numkong/probes/x86_haswell.c +11 -0
  426. package/numkong/probes/x86_icelake.c +17 -0
  427. package/numkong/probes/x86_sapphire.c +16 -0
  428. package/numkong/probes/x86_sapphireamx.c +18 -0
  429. package/numkong/probes/x86_sierra.c +17 -0
  430. package/numkong/probes/x86_skylake.c +15 -0
  431. package/numkong/probes/x86_turin.c +17 -0
  432. package/numkong/rust/README.md +698 -0
  433. package/numkong/rust/capabilities.rs +96 -0
  434. package/numkong/rust/cast.rs +314 -0
  435. package/numkong/rust/curved.rs +391 -0
  436. package/numkong/rust/each.rs +2721 -0
  437. package/numkong/rust/geospatial.rs +343 -0
  438. package/numkong/rust/matrix.rs +5424 -0
  439. package/numkong/rust/maxsim.rs +540 -0
  440. package/numkong/rust/mesh.rs +837 -0
  441. package/numkong/rust/numkong.rs +409 -0
  442. package/numkong/rust/probability.rs +272 -0
  443. package/numkong/rust/reduce.rs +1249 -0
  444. package/numkong/rust/set.rs +194 -0
  445. package/numkong/rust/sparse.rs +513 -0
  446. package/numkong/rust/spatial.rs +1815 -0
  447. package/numkong/rust/tensor.rs +7565 -0
  448. package/numkong/rust/types.rs +3666 -0
  449. package/numkong/rust/vector.rs +1899 -0
  450. package/numkong/rustfmt.toml +2 -0
  451. package/numkong/swift/Matrix.swift +1388 -0
  452. package/numkong/swift/MaxSim.swift +151 -0
  453. package/numkong/swift/NumKong.swift +283 -0
  454. package/numkong/swift/Numerics.swift +329 -0
  455. package/numkong/swift/README.md +433 -0
  456. package/numkong/swift/Scalar.swift +741 -0
  457. package/numkong/swift/Tensor.swift +209 -0
  458. package/numkong/test/README.md +315 -0
  459. package/numkong/test/playwright.config.ts +16 -0
  460. package/numkong/test/swift/Test.swift +534 -0
  461. package/numkong/test/test-browser-bundle-runner.mjs +36 -0
  462. package/numkong/test/test-browser-bundle.html +188 -0
  463. package/numkong/test/test-browser-runner.mjs +43 -0
  464. package/numkong/test/test-browser.html +305 -0
  465. package/numkong/test/test-dtypes.mjs +453 -0
  466. package/numkong/test/test-wasm.mjs +267 -0
  467. package/numkong/test/test.cpp +442 -0
  468. package/numkong/test/test.hpp +580 -0
  469. package/numkong/test/test.mjs +363 -0
  470. package/numkong/test/test_base.py +1041 -0
  471. package/numkong/test/test_cast.cpp +242 -0
  472. package/numkong/test/test_cross.hpp +551 -0
  473. package/numkong/test/test_cross.py +467 -0
  474. package/numkong/test/test_cross_amx.cpp +50 -0
  475. package/numkong/test/test_cross_arm.cpp +225 -0
  476. package/numkong/test/test_cross_blas.cpp +354 -0
  477. package/numkong/test/test_cross_loongarch.cpp +90 -0
  478. package/numkong/test/test_cross_power.cpp +73 -0
  479. package/numkong/test/test_cross_rvv.cpp +109 -0
  480. package/numkong/test/test_cross_serial.cpp +181 -0
  481. package/numkong/test/test_cross_sme.cpp +148 -0
  482. package/numkong/test/test_cross_wasm.cpp +141 -0
  483. package/numkong/test/test_cross_x86.cpp +442 -0
  484. package/numkong/test/test_curved.cpp +182 -0
  485. package/numkong/test/test_curved.py +207 -0
  486. package/numkong/test/test_dot.cpp +353 -0
  487. package/numkong/test/test_dot.py +296 -0
  488. package/numkong/test/test_each.cpp +437 -0
  489. package/numkong/test/test_each.py +756 -0
  490. package/numkong/test/test_geospatial.cpp +155 -0
  491. package/numkong/test/test_geospatial.py +241 -0
  492. package/numkong/test/test_maxsim.cpp +138 -0
  493. package/numkong/test/test_maxsim.py +209 -0
  494. package/numkong/test/test_mesh.cpp +203 -0
  495. package/numkong/test/test_mesh.py +394 -0
  496. package/numkong/test/test_probability.cpp +136 -0
  497. package/numkong/test/test_probability.py +166 -0
  498. package/numkong/test/test_reduce.cpp +563 -0
  499. package/numkong/test/test_reduce.py +781 -0
  500. package/numkong/test/test_set.cpp +151 -0
  501. package/numkong/test/test_set.py +120 -0
  502. package/numkong/test/test_similarities.py +579 -0
  503. package/numkong/test/test_sparse.cpp +121 -0
  504. package/numkong/test/test_sparse.py +118 -0
  505. package/numkong/test/test_spatial.cpp +518 -0
  506. package/numkong/test/test_spatial.py +269 -0
  507. package/numkong/test/test_tensor.cpp +884 -0
  508. package/numkong/test/test_tensor.py +1417 -0
  509. package/numkong/test/test_trigonometry.cpp +156 -0
  510. package/numkong/test/test_trigonometry.py +180 -0
  511. package/package.json +7 -8
  512. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  513. package/prebuilds/linux-arm64/usearch.node +0 -0
  514. package/prebuilds/linux-x64/usearch.node +0 -0
  515. package/fp16/CMakeLists.txt +0 -176
  516. package/fp16/LICENSE +0 -11
  517. package/fp16/README.md +0 -20
  518. package/fp16/bench/alt-element.cc +0 -89
  519. package/fp16/bench/from-alt-array.cc +0 -175
  520. package/fp16/bench/from-ieee-array.cc +0 -399
  521. package/fp16/bench/ieee-element.cc +0 -272
  522. package/fp16/bench/to-alt-array.cc +0 -91
  523. package/fp16/bench/to-ieee-array.cc +0 -303
  524. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  525. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  526. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  527. package/fp16/configure.py +0 -65
  528. package/fp16/confu.yaml +0 -8
  529. package/fp16/include/fp16/__init__.py +0 -0
  530. package/fp16/include/fp16/avx.py +0 -50
  531. package/fp16/include/fp16/avx2.py +0 -53
  532. package/fp16/include/fp16/bitcasts.h +0 -92
  533. package/fp16/include/fp16/fp16.h +0 -451
  534. package/fp16/include/fp16/psimd.h +0 -131
  535. package/fp16/include/fp16.h +0 -11
  536. package/fp16/jni/Android.mk +0 -6
  537. package/fp16/jni/Application.mk +0 -4
  538. package/fp16/test/alt-from-fp32-value.cc +0 -498
  539. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  540. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  541. package/fp16/test/alt-to-fp32-value.cc +0 -348
  542. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  543. package/fp16/test/bitcasts.cc +0 -56
  544. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  545. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  546. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  547. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  548. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  549. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  550. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  551. package/fp16/test/peachpy/stubs.py +0 -38
  552. package/fp16/test/tables.cc +0 -530
  553. package/fp16/test/tables.h +0 -13
  554. package/fp16/third-party/THHalf.h +0 -92
  555. package/fp16/third-party/eigen-half.h +0 -170
  556. package/fp16/third-party/float16-compressor.h +0 -80
  557. package/fp16/third-party/half.hpp +0 -2916
  558. package/fp16/third-party/npy-halffloat.h +0 -328
  559. package/simsimd/.git-blame-ignore-revs +0 -2
  560. package/simsimd/CONTRIBUTING.md +0 -321
  561. package/simsimd/Cargo.toml +0 -49
  562. package/simsimd/MANIFEST.in +0 -4
  563. package/simsimd/Package.swift +0 -28
  564. package/simsimd/README.md +0 -1493
  565. package/simsimd/binding.gyp +0 -35
  566. package/simsimd/build.rs +0 -70
  567. package/simsimd/c/lib.c +0 -374
  568. package/simsimd/include/module.modulemap +0 -4
  569. package/simsimd/include/simsimd/binary.h +0 -486
  570. package/simsimd/include/simsimd/curved.h +0 -1541
  571. package/simsimd/include/simsimd/dot.h +0 -1853
  572. package/simsimd/include/simsimd/elementwise.h +0 -2465
  573. package/simsimd/include/simsimd/geospatial.h +0 -43
  574. package/simsimd/include/simsimd/mesh.h +0 -69
  575. package/simsimd/include/simsimd/probability.h +0 -606
  576. package/simsimd/include/simsimd/simsimd.h +0 -2567
  577. package/simsimd/include/simsimd/sparse.h +0 -1384
  578. package/simsimd/include/simsimd/spatial.h +0 -2335
  579. package/simsimd/include/simsimd/types.h +0 -666
  580. package/simsimd/javascript/fallback.ts +0 -233
  581. package/simsimd/javascript/lib.c +0 -125
  582. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  583. package/simsimd/javascript/simsimd.ts +0 -179
  584. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  585. package/simsimd/package-lock.json +0 -1761
  586. package/simsimd/package.json +0 -61
  587. package/simsimd/rust/lib.rs +0 -1821
  588. package/simsimd/scripts/bench.cxx +0 -1170
  589. package/simsimd/scripts/bench.ipynb +0 -187
  590. package/simsimd/scripts/bench.js +0 -127
  591. package/simsimd/scripts/bench.rs +0 -876
  592. package/simsimd/scripts/bench_vectors.py +0 -734
  593. package/simsimd/scripts/bench_vectors_live.py +0 -213
  594. package/simsimd/scripts/test.c +0 -187
  595. package/simsimd/scripts/test.mjs +0 -220
  596. package/simsimd/scripts/test.py +0 -1505
  597. package/simsimd/swift/SimSIMD.swift +0 -149
  598. package/simsimd/swift/Test.swift +0 -128
  599. /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
  600. /package/{simsimd → numkong}/LICENSE +0 -0
  601. /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
  602. /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
@@ -0,0 +1,3110 @@
1
+ /**
2
+ * @brief SIMD-accelerated Batched Dot Products.
3
+ * @file include/numkong/dots.h
4
+ * @author Ash Vardanian
5
+ * @date September 14, 2024
6
+ *
7
+ * Implements batch dot-product kernels computing C[m × n] = A[m × k] × B[n × k]ᵀ
8
+ * with row-major A and arbitrary B, optimized for ML inference and similarity workloads.
9
+ *
10
+ * Primary Use Cases (1-to-N focus):
11
+ *
12
+ * - k-NN search: ‖a-b‖² = ‖a‖² + ‖b‖² - 2(a × b)
13
+ * - Cosine similarity: (a × b) / (‖a‖ × ‖b‖)
14
+ * - Sparse attention patterns
15
+ * - Embedding similarity matrices
16
+ * - k-means clustering, DBSCAN, hierarchical clustering
17
+ *
18
+ * It implements several operations:
19
+ *
20
+ * - "dots_packed" - computing dot-products where the B matrix is pre-packed into optimal form
21
+ * - "dots_packed_size" - which estimates the memory requirements for external `malloc`
22
+ * - "dots_pack" - to perform the pre-processing
23
+ * - "dots_compact" - optional helpers to normalize or downcast into original precision
24
+ * - "dots_symmetric" - for A × Aᵀ Gram matrix multiplication
25
+ *
26
+ * If the original "dots_packed" is analogous to "GEMM" (General Matrix Multiplication) in BLAS,
27
+ * the "dots_symmetric" is similar to the "SYRK" (the Symmetric rank-k update of a matrix).
28
+ *
29
+ * For dtypes:
30
+ *
31
+ * - f64: 64-bit IEEE floating point numbers → 64-bit floats
32
+ * - f32: 32-bit IEEE floating point numbers → 64-bit floats
33
+ * - f16: 16-bit IEEE floating point numbers → 32-bit floats
34
+ * - bf16: 16-bit brain floating point numbers → 32-bit floats
35
+ * - e4m3: 8-bit e4m3 floating point numbers → 32-bit floats
36
+ * - e5m2: 8-bit e5m2 floating point numbers → 32-bit floats
37
+ * - e2m3: 8-bit e2m3 floating point numbers (MX) → 32-bit floats
38
+ * - e3m2: 8-bit e3m2 floating point numbers (MX) → 32-bit floats
39
+ * - i8: 8-bit signed integers → 32-bit signed integers
40
+ * - u8: 8-bit unsigned integers → 32-bit unsigned integers
41
+ * - i4: 4-bit signed integers (packed pairs) → 32-bit signed integers
42
+ * - u4: 4-bit unsigned integers (packed pairs) → 32-bit unsigned integers
43
+ * - u1: 1-bit binary (packed octets) → 32-bit unsigned integers
44
+ *
45
+ * For hardware architectures:
46
+ *
47
+ * - Arm: NEON, NEON+HALF, NEON+FHM, NEON+BF16, NEON+SDOT, SVE, SME, SME+F64, SME+BI32
48
+ * - x86: Haswell, Skylake, Ice Lake, Genoa, Sapphire Rapids (AMX), Sierra Forest
49
+ * - RISC-V: RVV
50
+ *
51
+ * @section numerical_stability Numerical Stability
52
+ *
53
+ * - f64: Dot2 (Ogita-Rump-Oishi) on the accurate backends, otherwise native f64 FMA accumulation.
54
+ * - f32: public outputs widen to f64. Packed and symmetric kernels keep payloads narrow but widen accumulation.
55
+ * - bf16/f16: f32 accumulation. VDPBF16PS on Genoa does bf16×bf16→f32 natively.
56
+ * - e2m3/e3m2: f16 intermediate with flush to f32 every 128 elements (Sapphire).
57
+ * - i8: i32 accumulation. AMX TDPBSSD gives i8×i8→i32 tiles. Overflows at k > ~131K.
58
+ * - u1: Popcount, exact.
59
+ *
60
+ * @section memory_layout Memory Layout and Transpose Semantics
61
+ *
62
+ * All matrices use row-major storage. Column-major is NOT supported.
63
+ * The kernel computes C = A × Bᵀ where:
64
+ *
65
+ * - A is (m × k): m rows, k columns, stride = a_stride bytes between rows
66
+ * - B is (n × k): n rows, k columns, stride = b_stride bytes between rows
67
+ * - C is (m × n): m rows, n columns, stride = c_stride bytes between rows
68
+ *
69
+ * This means C[i,j] = dot(row i of A, row j of B) = Σₗ A[i,l] × B[j,l].
70
+ *
71
+ * All strides are in bytes.
72
+ *
73
+ * To compute standard A × B (where B is k × n), pass Bᵀ to the packing function:
74
+ *
75
+ * @code{.c}
76
+ * // Standard matmul: C[m × n] = A[m × k] × B[k × n]
77
+ * // B is stored row-major as k rows of n elements
78
+ * // Treat it as Bᵀ: n rows of k elements with stride = sizeof(element)
79
+ * nk_dots_pack_bf16(b, width, depth, sizeof(nk_bf16_t), b_packed);
80
+ * nk_dots_packed_bf16(a, b_packed, c, height, width, depth, a_stride, c_stride);
81
+ * // Result: C = A × (Bᵀ)ᵀ = A × B
82
+ * @endcode
83
+ *
84
+ * @section two_phase_api Two-Phase API for Static Weights
85
+ *
86
+ * Matrix multiplication hardware (AMX, SME) requires specific data layouts that differ
87
+ * from standard row-major ordering. Since one matrix (typically weights in neural networks)
88
+ * is often static, we provide a two-phase API: pack once, multiply many times.
89
+ *
90
+ * @code{.c}
91
+ * // Similarity search: C[m × n] = queries[m × k] × database[n × k]ᵀ
92
+ * // Both matrices stored row-major, each row is one vector of dimension k
93
+ * nk_size_t packed_bytes = nk_dots_packed_size_bf16(width, depth);
94
+ * void *b_packed = malloc(packed_bytes);
95
+ * nk_dots_pack_bf16(database, width, depth, depth * sizeof(nk_bf16_t), b_packed);
96
+ * nk_dots_packed_bf16(queries, b_packed, c, height, width, depth, ...);
97
+ * // Result: C[i,j] = dot(query i, database vector j)
98
+ * @endcode
99
+ *
100
+ * The packed format is opaque and backend-specific. AMX expects (16 × 32) tiles with interleaved
101
+ * pairs, while NEON/SVE use arrangements optimized for their vector lengths.
102
+ *
103
+ * @section why_int8 Why INT8 and Not UINT8?
104
+ *
105
+ * Unsigned 8-bit integers were considered but deprioritized. The industry has converged on
106
+ * signed INT8 as the standard for quantized inference:
107
+ *
108
+ * Framework Default Notes
109
+ * PyTorch qint8 New X86 backend uses INT8 via oneDNN
110
+ * TensorFlow Lite int8 Actively removing UINT8 support
111
+ * ONNX Runtime S8S8 "Should be the first choice"
112
+ * TensorRT INT8 Symmetric [-128,127], no UINT8 option
113
+ * ARM CMSIS-NN int8 Follows TFLite INT8 spec exactly
114
+ *
115
+ * @section why_no_scaling Why No Alpha/Beta Scaling?
116
+ *
117
+ * BLAS-style `C = α × A × B + β × C` scaling was considered but omitted. While useful for scientific
118
+ * computing (iterative solvers, matrix factorizations), it's rarely used in ML inference where
119
+ * frameworks handle such operations via graph fusion. More importantly, on chips with separate
120
+ * physical registers for vector and matrix operations (like AMX), moving scalars between register
121
+ * files adds transfer latency that negates any benefit.
122
+ *
123
+ * @section why_no_pad Why Not Pad N Dimension to Eliminate Edge Handling?
124
+ *
125
+ * Padding N to a tile-aligned boundary (multiple of 16) during packing was considered to eliminate
126
+ * the separate AVX-512 edge kernel for N remainder rows. While this sounds simpler ("pure AMX"),
127
+ * it actually increases code size by ~125 lines because:
128
+ *
129
+ * - The AVX-512 edge fallback is compact (~40 lines) and handles both full-M × N-edge and
130
+ * M-edge × N-edge cases through a single reusable function
131
+ * - Replacing it with "AMX + masked stores" requires verbose tile handling code duplicated
132
+ * across all 4 multiply functions (aligned/misaligned × BF16/I8)
133
+ * - Each function needs a new "trailing N tile for full M blocks" section (~50 lines each)
134
+ *
135
+ * The current hybrid layout (AMX for full tiles, AVX-512 for edges) is more maintainable despite
136
+ * being conceptually less uniform. Memory overhead of the edge region is negligible (<2% worst case).
137
+ *
138
+ * @section x86_instructions Relevant x86 Instructions
139
+ *
140
+ * Low-precision matmul relies on VPMADD* (AVX2), VNNI dot-products, and BF16 dot-products
141
+ * on AVX-512. Zen4 improves throughput by dual-issuing many integer ops on FP ports.
142
+ *
143
+ * Intrinsic Instruction Haswell Genoa
144
+ * _mm256_maddubs_epi16 VPMADDUBSW (YMM, YMM, YMM) 5cy @ p0 3cy @ p01
145
+ * _mm256_madd_epi16 VPMADDWD (YMM, YMM, YMM) 5cy @ p0 3cy @ p01
146
+ * _mm256_dpbusd_epi32 VPDPBUSD (YMM, K, YMM, YMM) n/a 4cy @ p01
147
+ * _mm256_dpwssds_epi32 VPDPWSSDS (YMM, K, YMM, YMM) n/a 4cy @ p01
148
+ * _mm256_dpbf16_ps VDPBF16PS (YMM, YMM, YMM) n/a 6cy @ p01
149
+ *
150
+ * AMX tile ops (TDPBF16PS/TDPBUSD/TDPBSSD) are not covered by the uops.info 2022 dataset.
151
+ *
152
+ * @section references References
153
+ *
154
+ * - x86 intrinsics: https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html
155
+ * - Arm intrinsics: https://developer.arm.com/architectures/instruction-sets/intrinsics/
156
+ * - uops.info: https://uops.info/
157
+ * - Matrix Multiplication in 40 lines: https://en.algorithmica.org/hpc/algorithms/matmul/
158
+ * - LLaMA CPU optimization: https://justine.lol/matmul/
159
+ * - SME outer-product notes: https://github.com/tzakharko/m4-sme-exploration
160
+ *
161
+ */
162
+ #ifndef NK_DOTS_H
163
+ #define NK_DOTS_H
164
+
165
+ #include "numkong/types.h"
166
+
167
+ #if defined(__cplusplus)
168
+ extern "C" {
169
+ #endif
170
+
171
+ /**
172
+ * @brief Returns packed buffer size in bytes for second multiplier matrix (B).
173
+ * @param[in] width The number of rows in B (output columns).
174
+ * @param[in] depth The number of columns in B.
175
+ * @note The packed layout is backend-specific and must be produced by the matching pack function.
176
+ */
177
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_bf16(nk_size_t width, nk_size_t depth);
178
+ /** @copydoc nk_dots_packed_size_bf16 */
179
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_f16(nk_size_t width, nk_size_t depth);
180
+ /** @copydoc nk_dots_packed_size_bf16 */
181
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_e4m3(nk_size_t width, nk_size_t depth);
182
+ /** @copydoc nk_dots_packed_size_bf16 */
183
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_e5m2(nk_size_t width, nk_size_t depth);
184
+ /** @copydoc nk_dots_packed_size_bf16 */
185
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_e2m3(nk_size_t width, nk_size_t depth);
186
+ /** @copydoc nk_dots_packed_size_bf16 */
187
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_e3m2(nk_size_t width, nk_size_t depth);
188
+ /** @copydoc nk_dots_packed_size_bf16 */
189
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_f32(nk_size_t width, nk_size_t depth);
190
+ /** @copydoc nk_dots_packed_size_bf16 */
191
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_f64(nk_size_t width, nk_size_t depth);
192
+ /** @copydoc nk_dots_packed_size_bf16 */
193
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_i8(nk_size_t width, nk_size_t depth);
194
+ /** @copydoc nk_dots_packed_size_bf16 */
195
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_u8(nk_size_t width, nk_size_t depth);
196
+ /** @copydoc nk_dots_packed_size_bf16 */
197
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_i4(nk_size_t width, nk_size_t depth);
198
+ /** @copydoc nk_dots_packed_size_bf16 */
199
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_u4(nk_size_t width, nk_size_t depth);
200
+ /** @copydoc nk_dots_packed_size_bf16 */
201
+ NK_DYNAMIC nk_size_t nk_dots_packed_size_u1(nk_size_t width, nk_size_t depth);
202
+
203
+ /**
204
+ * @brief Packs the second multiplier (B) matrix into a backend-specific layout.
205
+ * @param[in] b The input B matrix in row-major order.
206
+ * @param[in] width The number of rows in B (output columns).
207
+ * @param[in] depth The number of columns in B.
208
+ * @param[in] b_stride The row stride in bytes for B.
209
+ * @param[out] b_packed The output packed buffer from nk_dots_packed_size_bf16.
210
+ */
211
+ NK_DYNAMIC void nk_dots_pack_bf16(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
212
+ void *b_packed);
213
+ /** @copydoc nk_dots_pack_bf16 */
214
+ NK_DYNAMIC void nk_dots_pack_f16(nk_f16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
215
+ void *b_packed);
216
+ /** @copydoc nk_dots_pack_bf16 */
217
+ NK_DYNAMIC void nk_dots_pack_e4m3(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
218
+ void *b_packed);
219
+ /** @copydoc nk_dots_pack_bf16 */
220
+ NK_DYNAMIC void nk_dots_pack_e5m2(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
221
+ void *b_packed);
222
+ /** @copydoc nk_dots_pack_bf16 */
223
+ NK_DYNAMIC void nk_dots_pack_e2m3(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
224
+ void *b_packed);
225
+ /** @copydoc nk_dots_pack_bf16 */
226
+ NK_DYNAMIC void nk_dots_pack_e3m2(nk_e3m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
227
+ void *b_packed);
228
+ /** @copydoc nk_dots_pack_bf16 */
229
+ NK_DYNAMIC void nk_dots_pack_f32(nk_f32_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
230
+ void *b_packed);
231
+ /** @copydoc nk_dots_pack_bf16 */
232
+ NK_DYNAMIC void nk_dots_pack_f64(nk_f64_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
233
+ void *b_packed);
234
+ /** @copydoc nk_dots_pack_bf16 */
235
+ NK_DYNAMIC void nk_dots_pack_i8(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride, void *b_packed);
236
+ /** @copydoc nk_dots_pack_bf16 */
237
+ NK_DYNAMIC void nk_dots_pack_u8(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride, void *b_packed);
238
+ /** @copydoc nk_dots_pack_bf16 */
239
+ NK_DYNAMIC void nk_dots_pack_i4(nk_i4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
240
+ void *b_packed);
241
+ /** @copydoc nk_dots_pack_bf16 */
242
+ NK_DYNAMIC void nk_dots_pack_u4(nk_u4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
243
+ void *b_packed);
244
+ /** @copydoc nk_dots_pack_bf16 */
245
+ NK_DYNAMIC void nk_dots_pack_u1(nk_u1x8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
246
+ void *b_packed);
247
+
248
+ /**
249
+ * @brief Computes C = A × Bᵀ using packed second multiplier matrix (B), accumulating into C.
250
+ * @param[in] a The input A matrix in row-major order.
251
+ * @param[in] b_packed The packed B matrix produced.
252
+ * @param[out] c The output C matrix in row-major order.
253
+ * @param[in] height The number of rows in A.
254
+ * @param[in] width The number of rows in B (output columns).
255
+ * @param[in] depth The shared inner dimension.
256
+ * @param[in] a_stride The row stride in bytes for A.
257
+ * @param[in] c_stride The row stride in bytes for C.
258
+ */
259
+ NK_DYNAMIC void nk_dots_packed_bf16(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
260
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
261
+ /** @copydoc nk_dots_packed_bf16 */
262
+ NK_DYNAMIC void nk_dots_packed_f16(nk_f16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
263
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
264
+ /** @copydoc nk_dots_packed_bf16 */
265
+ NK_DYNAMIC void nk_dots_packed_e4m3(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
266
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
267
+ /** @copydoc nk_dots_packed_bf16 */
268
+ NK_DYNAMIC void nk_dots_packed_e5m2(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
269
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
270
+ /** @copydoc nk_dots_packed_bf16 */
271
+ NK_DYNAMIC void nk_dots_packed_e2m3(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
272
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
273
+ /** @copydoc nk_dots_packed_bf16 */
274
+ NK_DYNAMIC void nk_dots_packed_e3m2(nk_e3m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
275
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
276
+ /** @copydoc nk_dots_packed_bf16 */
277
+ NK_DYNAMIC void nk_dots_packed_f32(nk_f32_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
278
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
279
+ /** @copydoc nk_dots_packed_bf16 */
280
+ NK_DYNAMIC void nk_dots_packed_f64(nk_f64_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
281
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
282
+ /** @copydoc nk_dots_packed_bf16 */
283
+ NK_DYNAMIC void nk_dots_packed_i8(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
284
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
285
+ /** @copydoc nk_dots_packed_bf16 */
286
+ NK_DYNAMIC void nk_dots_packed_u8(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
287
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
288
+ /** @copydoc nk_dots_packed_bf16 */
289
+ NK_DYNAMIC void nk_dots_packed_i4(nk_i4x2_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
290
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
291
+ /** @copydoc nk_dots_packed_bf16 */
292
+ NK_DYNAMIC void nk_dots_packed_u4(nk_u4x2_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
293
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
294
+ /** @copydoc nk_dots_packed_bf16 */
295
+ NK_DYNAMIC void nk_dots_packed_u1(nk_u1x8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
296
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
297
+
298
+ /**
299
+ * @brief Computes C = A × Aᵀ symmetric Gram matrix.
300
+ * @param[in] vectors Input matrix of row vectors in row-major order.
301
+ * @param[in] vectors_count Number of vectors (rows) in the input matrix.
302
+ * @param[in] depth Dimension of each vector (columns).
303
+ * @param[in] stride Row stride in bytes for the input matrix.
304
+ * @param[out] result Output symmetric matrix (vectors_count × vectors_count).
305
+ * @param[in] result_stride Row stride in bytes for the result matrix.
306
+ * @param[in] row_start Starting row offset of results to compute (needed for parallelism).
307
+ * @param[in] row_count Number of rows of results to compute (needed for parallelism).
308
+ */
309
+ NK_DYNAMIC void nk_dots_symmetric_bf16(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
310
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
311
+ nk_size_t row_count);
312
+ /** @copydoc nk_dots_symmetric_bf16 */
313
+ NK_DYNAMIC void nk_dots_symmetric_f16(nk_f16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
314
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
315
+ nk_size_t row_count);
316
+ /** @copydoc nk_dots_symmetric_bf16 */
317
+ NK_DYNAMIC void nk_dots_symmetric_e4m3(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
318
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
319
+ nk_size_t row_count);
320
+ /** @copydoc nk_dots_symmetric_bf16 */
321
+ NK_DYNAMIC void nk_dots_symmetric_e5m2(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
322
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
323
+ nk_size_t row_count);
324
+ /** @copydoc nk_dots_symmetric_bf16 */
325
+ NK_DYNAMIC void nk_dots_symmetric_e2m3(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
326
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
327
+ nk_size_t row_count);
328
+ /** @copydoc nk_dots_symmetric_bf16 */
329
+ NK_DYNAMIC void nk_dots_symmetric_e3m2(nk_e3m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
330
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
331
+ nk_size_t row_count);
332
+ /** @copydoc nk_dots_symmetric_bf16 */
333
+ NK_DYNAMIC void nk_dots_symmetric_f32(nk_f32_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
334
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride, nk_size_t row_start,
335
+ nk_size_t row_count);
336
+ /** @copydoc nk_dots_symmetric_bf16 */
337
+ NK_DYNAMIC void nk_dots_symmetric_f64(nk_f64_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
338
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride, nk_size_t row_start,
339
+ nk_size_t row_count);
340
+ /** @copydoc nk_dots_symmetric_bf16 */
341
+ NK_DYNAMIC void nk_dots_symmetric_i8(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth, nk_size_t stride,
342
+ nk_i32_t *result, nk_size_t result_stride, nk_size_t row_start,
343
+ nk_size_t row_count);
344
+ /** @copydoc nk_dots_symmetric_bf16 */
345
+ NK_DYNAMIC void nk_dots_symmetric_u8(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth, nk_size_t stride,
346
+ nk_u32_t *result, nk_size_t result_stride, nk_size_t row_start,
347
+ nk_size_t row_count);
348
+ /** @copydoc nk_dots_symmetric_bf16 */
349
+ NK_DYNAMIC void nk_dots_symmetric_i4(nk_i4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
350
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride, nk_size_t row_start,
351
+ nk_size_t row_count);
352
+ /** @copydoc nk_dots_symmetric_bf16 */
353
+ NK_DYNAMIC void nk_dots_symmetric_u4(nk_u4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
354
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride, nk_size_t row_start,
355
+ nk_size_t row_count);
356
+ /** @copydoc nk_dots_symmetric_bf16 */
357
+ NK_DYNAMIC void nk_dots_symmetric_u1(nk_u1x8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
358
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride, nk_size_t row_start,
359
+ nk_size_t row_count);
360
+
361
+ /** @copydoc nk_dots_packed_size_f32 */
362
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f32_serial(nk_size_t width, nk_size_t depth);
363
+ /** @copydoc nk_dots_pack_f32 */
364
+ NK_PUBLIC void nk_dots_pack_f32_serial(nk_f32_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
365
+ void *b_packed);
366
+ /** @copydoc nk_dots_packed_f32 */
367
+ NK_PUBLIC void nk_dots_packed_f32_serial(nk_f32_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
368
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
369
+ /** @copydoc nk_dots_symmetric_f32 */
370
+ NK_PUBLIC void nk_dots_symmetric_f32_serial(nk_f32_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
371
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
372
+ nk_size_t row_start, nk_size_t row_count);
373
+
374
+ /** @copydoc nk_dots_packed_size_f64 */
375
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f64_serial(nk_size_t width, nk_size_t depth);
376
+ /** @copydoc nk_dots_pack_f64 */
377
+ NK_PUBLIC void nk_dots_pack_f64_serial(nk_f64_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
378
+ void *b_packed);
379
+ /** @copydoc nk_dots_packed_f64 */
380
+ NK_PUBLIC void nk_dots_packed_f64_serial(nk_f64_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
381
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
382
+ /** @copydoc nk_dots_symmetric_f64 */
383
+ NK_PUBLIC void nk_dots_symmetric_f64_serial(nk_f64_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
384
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
385
+ nk_size_t row_start, nk_size_t row_count);
386
+
387
+ /** @copydoc nk_dots_packed_size_f16 */
388
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f16_serial(nk_size_t width, nk_size_t depth);
389
+ /** @copydoc nk_dots_pack_f16 */
390
+ NK_PUBLIC void nk_dots_pack_f16_serial(nk_f16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
391
+ void *b_packed);
392
+ /** @copydoc nk_dots_packed_f16 */
393
+ NK_PUBLIC void nk_dots_packed_f16_serial(nk_f16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
394
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
395
+ /** @copydoc nk_dots_symmetric_f16 */
396
+ NK_PUBLIC void nk_dots_symmetric_f16_serial(nk_f16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
397
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
398
+ nk_size_t row_start, nk_size_t row_count);
399
+
400
+ /** @copydoc nk_dots_packed_size_bf16 */
401
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16_serial(nk_size_t width, nk_size_t depth);
402
+ /** @copydoc nk_dots_pack_bf16 */
403
+ NK_PUBLIC void nk_dots_pack_bf16_serial(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
404
+ void *b_packed);
405
+ /** @copydoc nk_dots_packed_bf16 */
406
+ NK_PUBLIC void nk_dots_packed_bf16_serial(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
407
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
408
+ /** @copydoc nk_dots_symmetric_bf16 */
409
+ NK_PUBLIC void nk_dots_symmetric_bf16_serial(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
410
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
411
+ nk_size_t row_start, nk_size_t row_count);
412
+
413
+ /** @copydoc nk_dots_packed_size_i8 */
414
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8_serial(nk_size_t width, nk_size_t depth);
415
+ /** @copydoc nk_dots_pack_i8 */
416
+ NK_PUBLIC void nk_dots_pack_i8_serial(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
417
+ void *b_packed);
418
+ /** @copydoc nk_dots_packed_i8 */
419
+ NK_PUBLIC void nk_dots_packed_i8_serial(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
420
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
421
+ /** @copydoc nk_dots_symmetric_i8 */
422
+ NK_PUBLIC void nk_dots_symmetric_i8_serial(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
423
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
424
+ nk_size_t row_start, nk_size_t row_count);
425
+
426
+ /** @copydoc nk_dots_packed_size_u8 */
427
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8_serial(nk_size_t width, nk_size_t depth);
428
+ /** @copydoc nk_dots_pack_u8 */
429
+ NK_PUBLIC void nk_dots_pack_u8_serial(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
430
+ void *b_packed);
431
+ /** @copydoc nk_dots_packed_u8 */
432
+ NK_PUBLIC void nk_dots_packed_u8_serial(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
433
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
434
+ /** @copydoc nk_dots_symmetric_u8 */
435
+ NK_PUBLIC void nk_dots_symmetric_u8_serial(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
436
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
437
+ nk_size_t row_start, nk_size_t row_count);
438
+
439
+ /** @copydoc nk_dots_packed_size_u4 */
440
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u4_serial(nk_size_t width, nk_size_t depth);
441
+ /** @copydoc nk_dots_pack_u4 */
442
+ NK_PUBLIC void nk_dots_pack_u4_serial(nk_u4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
443
+ void *b_packed);
444
+ /** @copydoc nk_dots_packed_u4 */
445
+ NK_PUBLIC void nk_dots_packed_u4_serial(nk_u4x2_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
446
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
447
+ /** @copydoc nk_dots_symmetric_u4 */
448
+ NK_PUBLIC void nk_dots_symmetric_u4_serial(nk_u4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
449
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
450
+ nk_size_t row_start, nk_size_t row_count);
451
+
452
+ /** @copydoc nk_dots_packed_size_u1 */
453
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u1_serial(nk_size_t width, nk_size_t depth);
454
+ /** @copydoc nk_dots_pack_u1 */
455
+ NK_PUBLIC void nk_dots_pack_u1_serial(nk_u1x8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
456
+ void *b_packed);
457
+ /** @copydoc nk_dots_packed_u1 */
458
+ NK_PUBLIC void nk_dots_packed_u1_serial(nk_u1x8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
459
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
460
+ /** @copydoc nk_dots_symmetric_u1 */
461
+ NK_PUBLIC void nk_dots_symmetric_u1_serial(nk_u1x8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
462
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
463
+ nk_size_t row_start, nk_size_t row_count);
464
+
465
+ /** @copydoc nk_dots_packed_size_i4 */
466
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i4_serial(nk_size_t width, nk_size_t depth);
467
+ /** @copydoc nk_dots_pack_i4 */
468
+ NK_PUBLIC void nk_dots_pack_i4_serial(nk_i4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
469
+ void *b_packed);
470
+ /** @copydoc nk_dots_packed_i4 */
471
+ NK_PUBLIC void nk_dots_packed_i4_serial(nk_i4x2_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
472
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
473
+ /** @copydoc nk_dots_symmetric_i4 */
474
+ NK_PUBLIC void nk_dots_symmetric_i4_serial(nk_i4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
475
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
476
+ nk_size_t row_start, nk_size_t row_count);
477
+ /** @copydoc nk_dots_symmetric_e4m3 */
478
+ NK_PUBLIC void nk_dots_symmetric_e4m3_serial(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
479
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
480
+ nk_size_t row_start, nk_size_t row_count);
481
+ /** @copydoc nk_dots_symmetric_e5m2 */
482
+ NK_PUBLIC void nk_dots_symmetric_e5m2_serial(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
483
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
484
+ nk_size_t row_start, nk_size_t row_count);
485
+ /** @copydoc nk_dots_symmetric_e2m3 */
486
+ NK_PUBLIC void nk_dots_symmetric_e2m3_serial(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
487
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
488
+ nk_size_t row_start, nk_size_t row_count);
489
+ /** @copydoc nk_dots_symmetric_e3m2 */
490
+ NK_PUBLIC void nk_dots_symmetric_e3m2_serial(nk_e3m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
491
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
492
+ nk_size_t row_start, nk_size_t row_count);
493
+ /** @copydoc nk_dots_packed_size_e2m3 */
494
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e2m3_serial(nk_size_t width, nk_size_t depth);
495
+ /** @copydoc nk_dots_pack_e2m3 */
496
+ NK_PUBLIC void nk_dots_pack_e2m3_serial(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
497
+ void *b_packed);
498
+ /** @copydoc nk_dots_packed_e2m3 */
499
+ NK_PUBLIC void nk_dots_packed_e2m3_serial(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
500
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
501
+ /** @copydoc nk_dots_packed_size_e3m2 */
502
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e3m2_serial(nk_size_t width, nk_size_t depth);
503
+ /** @copydoc nk_dots_pack_e3m2 */
504
+ NK_PUBLIC void nk_dots_pack_e3m2_serial(nk_e3m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
505
+ void *b_packed);
506
+ /** @copydoc nk_dots_packed_e3m2 */
507
+ NK_PUBLIC void nk_dots_packed_e3m2_serial(nk_e3m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
508
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
509
+
510
+ /* Genoa backends using AVX-512 with BF16 extensions.
511
+ * These use VDPBF16PS for BF16 dot products.
512
+ * Packing interleaves elements for SIMD broadcast patterns.
513
+ */
514
+ #if NK_TARGET_GENOA
515
+ /** @copydoc nk_dots_packed_size_bf16 */
516
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16_genoa(nk_size_t width, nk_size_t depth);
517
+ /** @copydoc nk_dots_pack_bf16 */
518
+ NK_PUBLIC void nk_dots_pack_bf16_genoa(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
519
+ void *b_packed);
520
+ /** @copydoc nk_dots_packed_bf16 */
521
+ NK_PUBLIC void nk_dots_packed_bf16_genoa(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
522
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
523
+ /** @copydoc nk_dots_symmetric_bf16 */
524
+ NK_PUBLIC void nk_dots_symmetric_bf16_genoa(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
525
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
526
+ nk_size_t row_start, nk_size_t row_count);
527
+
528
+ /** @copydoc nk_dots_packed_size_e4m3 */
529
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e4m3_genoa(nk_size_t width, nk_size_t depth);
530
+ /** @copydoc nk_dots_pack_e4m3 */
531
+ NK_PUBLIC void nk_dots_pack_e4m3_genoa(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
532
+ void *b_packed);
533
+ /** @copydoc nk_dots_packed_e4m3 */
534
+ NK_PUBLIC void nk_dots_packed_e4m3_genoa(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
535
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
536
+ /** @copydoc nk_dots_packed_size_e5m2 */
537
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e5m2_genoa(nk_size_t width, nk_size_t depth);
538
+ /** @copydoc nk_dots_pack_e5m2 */
539
+ NK_PUBLIC void nk_dots_pack_e5m2_genoa(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
540
+ void *b_packed);
541
+ /** @copydoc nk_dots_packed_e5m2 */
542
+ NK_PUBLIC void nk_dots_packed_e5m2_genoa(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
543
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
544
+ /** @copydoc nk_dots_symmetric_e4m3 */
545
+ NK_PUBLIC void nk_dots_symmetric_e4m3_genoa(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
546
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
547
+ nk_size_t row_start, nk_size_t row_count);
548
+ /** @copydoc nk_dots_symmetric_e5m2 */
549
+ NK_PUBLIC void nk_dots_symmetric_e5m2_genoa(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
550
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
551
+ nk_size_t row_start, nk_size_t row_count);
552
+ #endif // NK_TARGET_GENOA
553
+
554
+ #if NK_TARGET_DIAMOND
555
+ /** @copydoc nk_dots_packed_size_e4m3 */
556
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e4m3_diamond(nk_size_t width, nk_size_t depth);
557
+ /** @copydoc nk_dots_pack_e4m3 */
558
+ NK_PUBLIC void nk_dots_pack_e4m3_diamond(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
559
+ void *b_packed);
560
+ /** @copydoc nk_dots_packed_e4m3 */
561
+ NK_PUBLIC void nk_dots_packed_e4m3_diamond(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
562
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
563
+ /** @copydoc nk_dots_packed_size_e5m2 */
564
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e5m2_diamond(nk_size_t width, nk_size_t depth);
565
+ /** @copydoc nk_dots_pack_e5m2 */
566
+ NK_PUBLIC void nk_dots_pack_e5m2_diamond(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
567
+ void *b_packed);
568
+ /** @copydoc nk_dots_packed_e5m2 */
569
+ NK_PUBLIC void nk_dots_packed_e5m2_diamond(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
570
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
571
+ /** @copydoc nk_dots_symmetric_e4m3 */
572
+ NK_PUBLIC void nk_dots_symmetric_e4m3_diamond(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
573
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
574
+ nk_size_t row_start, nk_size_t row_count);
575
+ /** @copydoc nk_dots_symmetric_e5m2 */
576
+ NK_PUBLIC void nk_dots_symmetric_e5m2_diamond(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
577
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
578
+ nk_size_t row_start, nk_size_t row_count);
579
+ #endif // NK_TARGET_DIAMOND
580
+
581
+ /* Sapphire Rapids backends using Intel AMX (Advanced Matrix Extensions).
582
+ * AMX provides 8 tile registers (TMM0-TMM7), each holding up to 1KB of data.
583
+ * Tiles are configured as 16 rows × 64 bytes, enabling (16 × 32) BF16 or (16 × 64) INT8 tiles.
584
+ * Packing arranges data into AMX-native tile layout with pair interleaving for TDPBF16PS.
585
+ */
586
+ #if NK_TARGET_SAPPHIREAMX
587
+ /** @copydoc nk_dots_packed_size_bf16 */
588
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16_sapphireamx(nk_size_t width, nk_size_t depth);
589
+ /** @copydoc nk_dots_pack_bf16 */
590
+ NK_PUBLIC void nk_dots_pack_bf16_sapphireamx(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
591
+ void *b_packed);
592
+ /** @copydoc nk_dots_packed_bf16 */
593
+ NK_PUBLIC void nk_dots_packed_bf16_sapphireamx(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
594
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride,
595
+ nk_size_t c_stride);
596
+ /** @copydoc nk_dots_symmetric_bf16 */
597
+ NK_PUBLIC void nk_dots_symmetric_bf16_sapphireamx(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
598
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
599
+ nk_size_t row_start, nk_size_t row_count);
600
+
601
+ /** @copydoc nk_dots_packed_size_i8 */
602
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8_sapphireamx(nk_size_t width, nk_size_t depth);
603
+ /** @copydoc nk_dots_pack_i8 */
604
+ NK_PUBLIC void nk_dots_pack_i8_sapphireamx(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
605
+ void *b_packed);
606
+ /** @copydoc nk_dots_packed_i8 */
607
+ NK_PUBLIC void nk_dots_packed_i8_sapphireamx(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
608
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
609
+ /** @copydoc nk_dots_symmetric_i8 */
610
+ NK_PUBLIC void nk_dots_symmetric_i8_sapphireamx(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
611
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
612
+ nk_size_t row_start, nk_size_t row_count);
613
+
614
+ /** @copydoc nk_dots_packed_size_e4m3 */
615
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e4m3_sapphireamx(nk_size_t width, nk_size_t depth);
616
+ /** @copydoc nk_dots_pack_e4m3 */
617
+ NK_PUBLIC void nk_dots_pack_e4m3_sapphireamx(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
618
+ void *b_packed);
619
+ /** @copydoc nk_dots_packed_e4m3 */
620
+ NK_PUBLIC void nk_dots_packed_e4m3_sapphireamx(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
621
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride,
622
+ nk_size_t c_stride);
623
+
624
+ /** @copydoc nk_dots_symmetric_e4m3 */
625
+ NK_PUBLIC void nk_dots_symmetric_e4m3_sapphireamx(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
626
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
627
+ nk_size_t row_start, nk_size_t row_count);
628
+
629
+ /** @copydoc nk_dots_packed_size_e5m2 */
630
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e5m2_sapphireamx(nk_size_t width, nk_size_t depth);
631
+ /** @copydoc nk_dots_pack_e5m2 */
632
+ NK_PUBLIC void nk_dots_pack_e5m2_sapphireamx(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
633
+ void *b_packed);
634
+ /** @copydoc nk_dots_packed_e5m2 */
635
+ NK_PUBLIC void nk_dots_packed_e5m2_sapphireamx(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
636
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride,
637
+ nk_size_t c_stride);
638
+ /** @copydoc nk_dots_symmetric_e5m2 */
639
+ NK_PUBLIC void nk_dots_symmetric_e5m2_sapphireamx(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
640
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
641
+ nk_size_t row_start, nk_size_t row_count);
642
+ /** @copydoc nk_dots_packed_size_e2m3 */
643
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e2m3_sapphireamx(nk_size_t width, nk_size_t depth);
644
+ /** @copydoc nk_dots_pack_e2m3 */
645
+ NK_PUBLIC void nk_dots_pack_e2m3_sapphireamx(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
646
+ void *b_packed);
647
+ /** @copydoc nk_dots_packed_e2m3 */
648
+ NK_PUBLIC void nk_dots_packed_e2m3_sapphireamx(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
649
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride,
650
+ nk_size_t c_stride);
651
+ /** @copydoc nk_dots_symmetric_e2m3 */
652
+ NK_PUBLIC void nk_dots_symmetric_e2m3_sapphireamx(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
653
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
654
+ nk_size_t row_start, nk_size_t row_count);
655
+
656
+ /** @copydoc nk_dots_packed_size_e3m2 */
657
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e3m2_sapphireamx(nk_size_t width, nk_size_t depth);
658
+ /** @copydoc nk_dots_pack_e3m2 */
659
+ NK_PUBLIC void nk_dots_pack_e3m2_sapphireamx(nk_e3m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
660
+ void *b_packed);
661
+ /** @copydoc nk_dots_packed_e3m2 */
662
+ NK_PUBLIC void nk_dots_packed_e3m2_sapphireamx(nk_e3m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
663
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride,
664
+ nk_size_t c_stride);
665
+ /** @copydoc nk_dots_symmetric_e3m2 */
666
+ NK_PUBLIC void nk_dots_symmetric_e3m2_sapphireamx(nk_e3m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
667
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
668
+ nk_size_t row_start, nk_size_t row_count);
669
+
670
+ /** @copydoc nk_dots_packed_size_u8 */
671
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8_sapphireamx(nk_size_t width, nk_size_t depth);
672
+ /** @copydoc nk_dots_pack_u8 */
673
+ NK_PUBLIC void nk_dots_pack_u8_sapphireamx(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
674
+ void *b_packed);
675
+ /** @copydoc nk_dots_packed_u8 */
676
+ NK_PUBLIC void nk_dots_packed_u8_sapphireamx(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
677
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
678
+ /** @copydoc nk_dots_symmetric_u8 */
679
+ NK_PUBLIC void nk_dots_symmetric_u8_sapphireamx(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
680
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
681
+ nk_size_t row_start, nk_size_t row_count);
682
+ #endif // NK_TARGET_SAPPHIREAMX
683
+
684
+ /* Granite Rapids backends using Intel AMX-FP16 (Advanced Matrix Extensions with FP16 support).
685
+ * AMX-FP16 adds TDPFP16PS (FP16×FP16→FP32 tile multiply-accumulate), same tile geometry as BF16.
686
+ * The F32 Ozaki kernel splits F32 inputs into 2 FP16 halves for ~35-40 bit effective precision.
687
+ */
688
+ #if NK_TARGET_GRANITEAMX
689
+ /** @copydoc nk_dots_packed_size_f16 */
690
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f16_graniteamx(nk_size_t width, nk_size_t depth);
691
+ /** @copydoc nk_dots_pack_f16 */
692
+ NK_PUBLIC void nk_dots_pack_f16_graniteamx(nk_f16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
693
+ void *b_packed);
694
+ /** @copydoc nk_dots_packed_f16 */
695
+ NK_PUBLIC void nk_dots_packed_f16_graniteamx(nk_f16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
696
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
697
+ /** @copydoc nk_dots_symmetric_f16 */
698
+ NK_PUBLIC void nk_dots_symmetric_f16_graniteamx(nk_f16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
699
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
700
+ nk_size_t row_start, nk_size_t row_count);
701
+ #endif // NK_TARGET_GRANITEAMX
702
+
703
+ /* ARM SME backends using Scalable Matrix Extension.
704
+ * SME provides ZA tile registers for outer product operations.
705
+ * F16/BF16/I8/U8/E4M3 use ZA32 tiles, F32/F64 use ZA64 tiles (FEAT_SME_F64F64).
706
+ */
707
+ #if NK_TARGET_SME
708
+ /** @copydoc nk_dots_packed_size_f16 */
709
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f16_sme(nk_size_t width, nk_size_t depth);
710
+ /** @copydoc nk_dots_pack_f16 */
711
+ NK_PUBLIC void nk_dots_pack_f16_sme(nk_f16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
712
+ void *b_packed);
713
+ /** @copydoc nk_dots_packed_f16 */
714
+ NK_PUBLIC void nk_dots_packed_f16_sme(nk_f16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
715
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
716
+ /** @copydoc nk_dots_symmetric_f16 */
717
+ NK_PUBLIC void nk_dots_symmetric_f16_sme(nk_f16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
718
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
719
+ nk_size_t row_start, nk_size_t row_count);
720
+
721
+ /** @copydoc nk_dots_packed_size_bf16 */
722
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16_sme(nk_size_t width, nk_size_t depth);
723
+ /** @copydoc nk_dots_pack_bf16 */
724
+ NK_PUBLIC void nk_dots_pack_bf16_sme(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
725
+ void *b_packed);
726
+ /** @copydoc nk_dots_packed_bf16 */
727
+ NK_PUBLIC void nk_dots_packed_bf16_sme(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
728
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
729
+ /** @copydoc nk_dots_symmetric_bf16 */
730
+ NK_PUBLIC void nk_dots_symmetric_bf16_sme(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
731
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
732
+ nk_size_t row_start, nk_size_t row_count);
733
+
734
+ /** @copydoc nk_dots_packed_size_i8 */
735
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8_sme(nk_size_t width, nk_size_t depth);
736
+ /** @copydoc nk_dots_pack_i8 */
737
+ NK_PUBLIC void nk_dots_pack_i8_sme(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
738
+ void *b_packed);
739
+ /** @copydoc nk_dots_packed_i8 */
740
+ NK_PUBLIC void nk_dots_packed_i8_sme(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
741
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
742
+ /** @copydoc nk_dots_symmetric_i8 */
743
+ NK_PUBLIC void nk_dots_symmetric_i8_sme(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
744
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
745
+ nk_size_t row_start, nk_size_t row_count);
746
+
747
+ /** @copydoc nk_dots_packed_size_u8 */
748
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8_sme(nk_size_t width, nk_size_t depth);
749
+ /** @copydoc nk_dots_pack_u8 */
750
+ NK_PUBLIC void nk_dots_pack_u8_sme(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
751
+ void *b_packed);
752
+ /** @copydoc nk_dots_packed_u8 */
753
+ NK_PUBLIC void nk_dots_packed_u8_sme(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
754
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
755
+ /** @copydoc nk_dots_symmetric_u8 */
756
+ NK_PUBLIC void nk_dots_symmetric_u8_sme(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
757
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
758
+ nk_size_t row_start, nk_size_t row_count);
759
+
760
+ /** @copydoc nk_dots_packed_size_e4m3 */
761
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e4m3_sme(nk_size_t width, nk_size_t depth);
762
+ /** @copydoc nk_dots_pack_e4m3 */
763
+ NK_PUBLIC void nk_dots_pack_e4m3_sme(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
764
+ void *b_packed);
765
+ /** @copydoc nk_dots_packed_e4m3 */
766
+ NK_PUBLIC void nk_dots_packed_e4m3_sme(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
767
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
768
+ /** @copydoc nk_dots_symmetric_e4m3 */
769
+ NK_PUBLIC void nk_dots_symmetric_e4m3_sme(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
770
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
771
+ nk_size_t row_start, nk_size_t row_count);
772
+
773
+ /** @copydoc nk_dots_packed_size_e5m2 */
774
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e5m2_sme(nk_size_t width, nk_size_t depth);
775
+ /** @copydoc nk_dots_pack_e5m2 */
776
+ NK_PUBLIC void nk_dots_pack_e5m2_sme(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
777
+ void *b_packed);
778
+ /** @copydoc nk_dots_packed_e5m2 */
779
+ NK_PUBLIC void nk_dots_packed_e5m2_sme(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
780
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
781
+ /** @copydoc nk_dots_symmetric_e5m2 */
782
+ NK_PUBLIC void nk_dots_symmetric_e5m2_sme(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
783
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
784
+ nk_size_t row_start, nk_size_t row_count);
785
+
786
+ /** @copydoc nk_dots_packed_size_u4 */
787
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u4_sme(nk_size_t width, nk_size_t depth);
788
+ /** @copydoc nk_dots_pack_u4 */
789
+ NK_PUBLIC void nk_dots_pack_u4_sme(nk_u4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
790
+ void *b_packed);
791
+ /** @copydoc nk_dots_packed_u4 */
792
+ NK_PUBLIC void nk_dots_packed_u4_sme(nk_u4x2_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
793
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
794
+ /** @copydoc nk_dots_symmetric_u4 */
795
+ NK_PUBLIC void nk_dots_symmetric_u4_sme(nk_u4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
796
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
797
+ nk_size_t row_start, nk_size_t row_count);
798
+
799
+ /** @copydoc nk_dots_packed_size_i4 */
800
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i4_sme(nk_size_t width, nk_size_t depth);
801
+ /** @copydoc nk_dots_pack_i4 */
802
+ NK_PUBLIC void nk_dots_pack_i4_sme(nk_i4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
803
+ void *b_packed);
804
+ /** @copydoc nk_dots_packed_i4 */
805
+ NK_PUBLIC void nk_dots_packed_i4_sme(nk_i4x2_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
806
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
807
+ /** @copydoc nk_dots_symmetric_i4 */
808
+ NK_PUBLIC void nk_dots_symmetric_i4_sme(nk_i4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
809
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
810
+ nk_size_t row_start, nk_size_t row_count);
811
+
812
+ /** @copydoc nk_dots_packed_size_e2m3 */
813
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e2m3_sme(nk_size_t width, nk_size_t depth);
814
+ /** @copydoc nk_dots_pack_e2m3 */
815
+ NK_PUBLIC void nk_dots_pack_e2m3_sme(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
816
+ void *b_packed);
817
+ /** @copydoc nk_dots_packed_e2m3 */
818
+ NK_PUBLIC void nk_dots_packed_e2m3_sme(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
819
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
820
+ /** @copydoc nk_dots_symmetric_e2m3 */
821
+ NK_PUBLIC void nk_dots_symmetric_e2m3_sme(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
822
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
823
+ nk_size_t row_start, nk_size_t row_count);
824
+
825
+ /** @copydoc nk_dots_packed_size_e3m2 */
826
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e3m2_sme(nk_size_t width, nk_size_t depth);
827
+ /** @copydoc nk_dots_pack_e3m2 */
828
+ NK_PUBLIC void nk_dots_pack_e3m2_sme(nk_e3m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
829
+ void *b_packed);
830
+ /** @copydoc nk_dots_packed_e3m2 */
831
+ NK_PUBLIC void nk_dots_packed_e3m2_sme(nk_e3m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
832
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
833
+ /** @copydoc nk_dots_symmetric_e3m2 */
834
+ NK_PUBLIC void nk_dots_symmetric_e3m2_sme(nk_e3m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
835
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
836
+ nk_size_t row_start, nk_size_t row_count);
837
+ #endif // NK_TARGET_SME
838
+
839
+ /* ARM SME with integer-accumulating binary outer products.
840
+ * Used for packed 1-bit dot products backed by ZA32.
841
+ */
842
+ #if NK_TARGET_SMEBI32
843
+ /** @copydoc nk_dots_packed_size_u1 */
844
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u1_smebi32(nk_size_t width, nk_size_t depth);
845
+ /** @copydoc nk_dots_pack_u1 */
846
+ NK_PUBLIC void nk_dots_pack_u1_smebi32(nk_u1x8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
847
+ void *b_packed);
848
+ /** @copydoc nk_dots_packed_u1 */
849
+ NK_PUBLIC void nk_dots_packed_u1_smebi32(nk_u1x8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
850
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
851
+ /** @copydoc nk_dots_symmetric_u1 */
852
+ NK_PUBLIC void nk_dots_symmetric_u1_smebi32(nk_u1x8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
853
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
854
+ nk_size_t row_start, nk_size_t row_count);
855
+ #endif // NK_TARGET_SMEBI32
856
+
857
+ /* ARM SME with FEAT_SME_F64F64 (F32/F64 with F64 accumulators).
858
+ * Requires Apple M4 or equivalent with F64 outer product support.
859
+ */
860
+ #if NK_TARGET_SMEF64
861
+ /** @copydoc nk_dots_packed_size_f32 */
862
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f32_smef64(nk_size_t width, nk_size_t depth);
863
+ /** @copydoc nk_dots_pack_f32 */
864
+ NK_PUBLIC void nk_dots_pack_f32_smef64(nk_f32_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
865
+ void *b_packed);
866
+ /** @copydoc nk_dots_packed_f32 */
867
+ NK_PUBLIC void nk_dots_packed_f32_smef64(nk_f32_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
868
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
869
+ /** @copydoc nk_dots_symmetric_f32 */
870
+ NK_PUBLIC void nk_dots_symmetric_f32_smef64(nk_f32_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
871
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
872
+ nk_size_t row_start, nk_size_t row_count);
873
+
874
+ /** @copydoc nk_dots_packed_size_f64 */
875
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f64_smef64(nk_size_t width, nk_size_t depth);
876
+ /** @copydoc nk_dots_pack_f64 */
877
+ NK_PUBLIC void nk_dots_pack_f64_smef64(nk_f64_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
878
+ void *b_packed);
879
+ /** @copydoc nk_dots_packed_f64 */
880
+ NK_PUBLIC void nk_dots_packed_f64_smef64(nk_f64_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
881
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
882
+ /** @copydoc nk_dots_symmetric_f64 */
883
+ NK_PUBLIC void nk_dots_symmetric_f64_smef64(nk_f64_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
884
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
885
+ nk_size_t row_start, nk_size_t row_count);
886
+ #endif // NK_TARGET_SMEF64
887
+
888
+ /* Haswell backends using AVX2 (Intel Core 4th gen).
889
+ * Supports F32/F64 via FMA, F16/BF16/FP8 via software emulation, I8/U8 via VPMADDUBSW+VPADDD.
890
+ */
891
+ #if NK_TARGET_HASWELL
892
+ /** @copydoc nk_dots_packed_size_f32 */
893
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f32_haswell(nk_size_t width, nk_size_t depth);
894
+ /** @copydoc nk_dots_pack_f32 */
895
+ NK_PUBLIC void nk_dots_pack_f32_haswell(nk_f32_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
896
+ void *b_packed);
897
+ /** @copydoc nk_dots_packed_f32 */
898
+ NK_PUBLIC void nk_dots_packed_f32_haswell(nk_f32_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
899
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
900
+ /** @copydoc nk_dots_symmetric_f32 */
901
+ NK_PUBLIC void nk_dots_symmetric_f32_haswell(nk_f32_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
902
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
903
+ nk_size_t row_start, nk_size_t row_count);
904
+ /** @copydoc nk_dots_packed_size_f64 */
905
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f64_haswell(nk_size_t width, nk_size_t depth);
906
+ /** @copydoc nk_dots_pack_f64 */
907
+ NK_PUBLIC void nk_dots_pack_f64_haswell(nk_f64_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
908
+ void *b_packed);
909
+ /** @copydoc nk_dots_packed_f64 */
910
+ NK_PUBLIC void nk_dots_packed_f64_haswell(nk_f64_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
911
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
912
+ /** @copydoc nk_dots_symmetric_f64 */
913
+ NK_PUBLIC void nk_dots_symmetric_f64_haswell(nk_f64_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
914
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
915
+ nk_size_t row_start, nk_size_t row_count);
916
+ /** @copydoc nk_dots_packed_size_f16 */
917
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f16_haswell(nk_size_t width, nk_size_t depth);
918
+ /** @copydoc nk_dots_pack_f16 */
919
+ NK_PUBLIC void nk_dots_pack_f16_haswell(nk_f16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
920
+ void *b_packed);
921
+ /** @copydoc nk_dots_packed_f16 */
922
+ NK_PUBLIC void nk_dots_packed_f16_haswell(nk_f16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
923
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
924
+ /** @copydoc nk_dots_symmetric_f16 */
925
+ NK_PUBLIC void nk_dots_symmetric_f16_haswell(nk_f16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
926
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
927
+ nk_size_t row_start, nk_size_t row_count);
928
+ /** @copydoc nk_dots_packed_size_bf16 */
929
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16_haswell(nk_size_t width, nk_size_t depth);
930
+ /** @copydoc nk_dots_pack_bf16 */
931
+ NK_PUBLIC void nk_dots_pack_bf16_haswell(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
932
+ void *b_packed);
933
+ /** @copydoc nk_dots_packed_bf16 */
934
+ NK_PUBLIC void nk_dots_packed_bf16_haswell(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
935
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
936
+ /** @copydoc nk_dots_symmetric_bf16 */
937
+ NK_PUBLIC void nk_dots_symmetric_bf16_haswell(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
938
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
939
+ nk_size_t row_start, nk_size_t row_count);
940
+ /** @copydoc nk_dots_packed_size_e4m3 */
941
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e4m3_haswell(nk_size_t width, nk_size_t depth);
942
+ /** @copydoc nk_dots_pack_e4m3 */
943
+ NK_PUBLIC void nk_dots_pack_e4m3_haswell(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
944
+ void *b_packed);
945
+ /** @copydoc nk_dots_packed_e4m3 */
946
+ NK_PUBLIC void nk_dots_packed_e4m3_haswell(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
947
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
948
+ /** @copydoc nk_dots_symmetric_e4m3 */
949
+ NK_PUBLIC void nk_dots_symmetric_e4m3_haswell(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
950
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
951
+ nk_size_t row_start, nk_size_t row_count);
952
+ /** @copydoc nk_dots_packed_size_e5m2 */
953
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e5m2_haswell(nk_size_t width, nk_size_t depth);
954
+ /** @copydoc nk_dots_pack_e5m2 */
955
+ NK_PUBLIC void nk_dots_pack_e5m2_haswell(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
956
+ void *b_packed);
957
+ /** @copydoc nk_dots_packed_e5m2 */
958
+ NK_PUBLIC void nk_dots_packed_e5m2_haswell(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
959
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
960
+ /** @copydoc nk_dots_symmetric_e5m2 */
961
+ NK_PUBLIC void nk_dots_symmetric_e5m2_haswell(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
962
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
963
+ nk_size_t row_start, nk_size_t row_count);
964
+ /** @copydoc nk_dots_packed_size_e2m3 */
965
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e2m3_haswell(nk_size_t width, nk_size_t depth);
966
+ /** @copydoc nk_dots_pack_e2m3 */
967
+ NK_PUBLIC void nk_dots_pack_e2m3_haswell(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
968
+ void *b_packed);
969
+ /** @copydoc nk_dots_packed_e2m3 */
970
+ NK_PUBLIC void nk_dots_packed_e2m3_haswell(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
971
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
972
+ /** @copydoc nk_dots_symmetric_e2m3 */
973
+ NK_PUBLIC void nk_dots_symmetric_e2m3_haswell(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
974
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
975
+ nk_size_t row_start, nk_size_t row_count);
976
+ /** @copydoc nk_dots_packed_size_e3m2 */
977
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e3m2_haswell(nk_size_t width, nk_size_t depth);
978
+ /** @copydoc nk_dots_pack_e3m2 */
979
+ NK_PUBLIC void nk_dots_pack_e3m2_haswell(nk_e3m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
980
+ void *b_packed);
981
+ /** @copydoc nk_dots_packed_e3m2 */
982
+ NK_PUBLIC void nk_dots_packed_e3m2_haswell(nk_e3m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
983
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
984
+ /** @copydoc nk_dots_symmetric_e3m2 */
985
+ NK_PUBLIC void nk_dots_symmetric_e3m2_haswell(nk_e3m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
986
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
987
+ nk_size_t row_start, nk_size_t row_count);
988
+ /** @copydoc nk_dots_packed_size_i8 */
989
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8_haswell(nk_size_t width, nk_size_t depth);
990
+ /** @copydoc nk_dots_pack_i8 */
991
+ NK_PUBLIC void nk_dots_pack_i8_haswell(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
992
+ void *b_packed);
993
+ /** @copydoc nk_dots_packed_i8 */
994
+ NK_PUBLIC void nk_dots_packed_i8_haswell(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
995
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
996
+ /** @copydoc nk_dots_symmetric_i8 */
997
+ NK_PUBLIC void nk_dots_symmetric_i8_haswell(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
998
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
999
+ nk_size_t row_start, nk_size_t row_count);
1000
+ /** @copydoc nk_dots_packed_size_u8 */
1001
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8_haswell(nk_size_t width, nk_size_t depth);
1002
+ /** @copydoc nk_dots_pack_u8 */
1003
+ NK_PUBLIC void nk_dots_pack_u8_haswell(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1004
+ void *b_packed);
1005
+ /** @copydoc nk_dots_packed_u8 */
1006
+ NK_PUBLIC void nk_dots_packed_u8_haswell(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1007
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1008
+ /** @copydoc nk_dots_symmetric_u8 */
1009
+ NK_PUBLIC void nk_dots_symmetric_u8_haswell(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1010
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1011
+ nk_size_t row_start, nk_size_t row_count);
1012
+ /** @copydoc nk_dots_packed_size_u1 */
1013
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u1_haswell(nk_size_t width, nk_size_t depth);
1014
+ /** @copydoc nk_dots_pack_u1 */
1015
+ NK_PUBLIC void nk_dots_pack_u1_haswell(nk_u1x8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1016
+ void *b_packed);
1017
+ /** @copydoc nk_dots_packed_u1 */
1018
+ NK_PUBLIC void nk_dots_packed_u1_haswell(nk_u1x8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1019
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1020
+ /** @copydoc nk_dots_symmetric_u1 */
1021
+ NK_PUBLIC void nk_dots_symmetric_u1_haswell(nk_u1x8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1022
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1023
+ nk_size_t row_start, nk_size_t row_count);
1024
+ /** @copydoc nk_dots_packed_size_i4 */
1025
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i4_haswell(nk_size_t width, nk_size_t depth);
1026
+ /** @copydoc nk_dots_pack_i4 */
1027
+ NK_PUBLIC void nk_dots_pack_i4_haswell(nk_i4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1028
+ void *b_packed);
1029
+ /** @copydoc nk_dots_packed_i4 */
1030
+ NK_PUBLIC void nk_dots_packed_i4_haswell(nk_i4x2_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
1031
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1032
+ /** @copydoc nk_dots_symmetric_i4 */
1033
+ NK_PUBLIC void nk_dots_symmetric_i4_haswell(nk_i4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1034
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
1035
+ nk_size_t row_start, nk_size_t row_count);
1036
+ /** @copydoc nk_dots_packed_size_u4 */
1037
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u4_haswell(nk_size_t width, nk_size_t depth);
1038
+ /** @copydoc nk_dots_pack_u4 */
1039
+ NK_PUBLIC void nk_dots_pack_u4_haswell(nk_u4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1040
+ void *b_packed);
1041
+ /** @copydoc nk_dots_packed_u4 */
1042
+ NK_PUBLIC void nk_dots_packed_u4_haswell(nk_u4x2_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1043
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1044
+ /** @copydoc nk_dots_symmetric_u4 */
1045
+ NK_PUBLIC void nk_dots_symmetric_u4_haswell(nk_u4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1046
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1047
+ nk_size_t row_start, nk_size_t row_count);
1048
+ #endif // NK_TARGET_HASWELL
1049
+
1050
+ /* Skylake backends using AVX-512 (Intel Core 6th gen+).
1051
+ * Provides 512-bit vectors (16× f32, 8× f64), supporting F32/F64/F16/BF16/FP8 with FMA.
1052
+ */
1053
+ #if NK_TARGET_SKYLAKE
1054
+ /** @copydoc nk_dots_packed_size_f64 */
1055
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f64_skylake(nk_size_t width, nk_size_t depth);
1056
+ /** @copydoc nk_dots_pack_f64 */
1057
+ NK_PUBLIC void nk_dots_pack_f64_skylake(nk_f64_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1058
+ void *b_packed);
1059
+ /** @copydoc nk_dots_packed_f64 */
1060
+ NK_PUBLIC void nk_dots_packed_f64_skylake(nk_f64_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
1061
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1062
+ /** @copydoc nk_dots_symmetric_f64 */
1063
+ NK_PUBLIC void nk_dots_symmetric_f64_skylake(nk_f64_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1064
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
1065
+ nk_size_t row_start, nk_size_t row_count);
1066
+ /** @copydoc nk_dots_packed_size_f32 */
1067
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f32_skylake(nk_size_t width, nk_size_t depth);
1068
+ /** @copydoc nk_dots_pack_f32 */
1069
+ NK_PUBLIC void nk_dots_pack_f32_skylake(nk_f32_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1070
+ void *b_packed);
1071
+ /** @copydoc nk_dots_packed_f32 */
1072
+ NK_PUBLIC void nk_dots_packed_f32_skylake(nk_f32_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
1073
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1074
+ /** @copydoc nk_dots_symmetric_f32 */
1075
+ NK_PUBLIC void nk_dots_symmetric_f32_skylake(nk_f32_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1076
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
1077
+ nk_size_t row_start, nk_size_t row_count);
1078
+ /** @copydoc nk_dots_packed_size_bf16 */
1079
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16_skylake(nk_size_t width, nk_size_t depth);
1080
+ /** @copydoc nk_dots_pack_bf16 */
1081
+ NK_PUBLIC void nk_dots_pack_bf16_skylake(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1082
+ void *b_packed);
1083
+ /** @copydoc nk_dots_packed_bf16 */
1084
+ NK_PUBLIC void nk_dots_packed_bf16_skylake(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1085
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1086
+ /** @copydoc nk_dots_symmetric_bf16 */
1087
+ NK_PUBLIC void nk_dots_symmetric_bf16_skylake(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1088
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1089
+ nk_size_t row_start, nk_size_t row_count);
1090
+ /** @copydoc nk_dots_packed_size_f16 */
1091
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f16_skylake(nk_size_t width, nk_size_t depth);
1092
+ /** @copydoc nk_dots_pack_f16 */
1093
+ NK_PUBLIC void nk_dots_pack_f16_skylake(nk_f16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1094
+ void *b_packed);
1095
+ /** @copydoc nk_dots_packed_f16 */
1096
+ NK_PUBLIC void nk_dots_packed_f16_skylake(nk_f16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1097
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1098
+ /** @copydoc nk_dots_symmetric_f16 */
1099
+ NK_PUBLIC void nk_dots_symmetric_f16_skylake(nk_f16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1100
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1101
+ nk_size_t row_start, nk_size_t row_count);
1102
+ /** @copydoc nk_dots_packed_size_e4m3 */
1103
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e4m3_skylake(nk_size_t width, nk_size_t depth);
1104
+ /** @copydoc nk_dots_pack_e4m3 */
1105
+ NK_PUBLIC void nk_dots_pack_e4m3_skylake(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1106
+ void *b_packed);
1107
+ /** @copydoc nk_dots_packed_e4m3 */
1108
+ NK_PUBLIC void nk_dots_packed_e4m3_skylake(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1109
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1110
+ /** @copydoc nk_dots_symmetric_e4m3 */
1111
+ NK_PUBLIC void nk_dots_symmetric_e4m3_skylake(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1112
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1113
+ nk_size_t row_start, nk_size_t row_count);
1114
+ /** @copydoc nk_dots_packed_size_e5m2 */
1115
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e5m2_skylake(nk_size_t width, nk_size_t depth);
1116
+ /** @copydoc nk_dots_pack_e5m2 */
1117
+ NK_PUBLIC void nk_dots_pack_e5m2_skylake(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1118
+ void *b_packed);
1119
+ /** @copydoc nk_dots_packed_e5m2 */
1120
+ NK_PUBLIC void nk_dots_packed_e5m2_skylake(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1121
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1122
+ /** @copydoc nk_dots_symmetric_e5m2 */
1123
+ NK_PUBLIC void nk_dots_symmetric_e5m2_skylake(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1124
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1125
+ nk_size_t row_start, nk_size_t row_count);
1126
+ /** @copydoc nk_dots_packed_size_e2m3 */
1127
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e2m3_skylake(nk_size_t width, nk_size_t depth);
1128
+ /** @copydoc nk_dots_pack_e2m3 */
1129
+ NK_PUBLIC void nk_dots_pack_e2m3_skylake(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1130
+ void *b_packed);
1131
+ /** @copydoc nk_dots_packed_e2m3 */
1132
+ NK_PUBLIC void nk_dots_packed_e2m3_skylake(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1133
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1134
+ /** @copydoc nk_dots_symmetric_e2m3 */
1135
+ NK_PUBLIC void nk_dots_symmetric_e2m3_skylake(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1136
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1137
+ nk_size_t row_start, nk_size_t row_count);
1138
+ /** @copydoc nk_dots_packed_size_e3m2 */
1139
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e3m2_skylake(nk_size_t width, nk_size_t depth);
1140
+ /** @copydoc nk_dots_pack_e3m2 */
1141
+ NK_PUBLIC void nk_dots_pack_e3m2_skylake(nk_e3m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1142
+ void *b_packed);
1143
+ /** @copydoc nk_dots_packed_e3m2 */
1144
+ NK_PUBLIC void nk_dots_packed_e3m2_skylake(nk_e3m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1145
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1146
+ /** @copydoc nk_dots_symmetric_e3m2 */
1147
+ NK_PUBLIC void nk_dots_symmetric_e3m2_skylake(nk_e3m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1148
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1149
+ nk_size_t row_start, nk_size_t row_count);
1150
+ #endif // NK_TARGET_SKYLAKE
1151
+
1152
+ /* Ice Lake backends using AVX-512 with VNNI (Vector Neural Network Instructions).
1153
+ * Adds VPDPBUSD for I8/U8, VPDPWSSD for I4/U4 with efficient dot products.
1154
+ */
1155
+ #if NK_TARGET_ICELAKE
1156
+ /** @copydoc nk_dots_packed_size_i8 */
1157
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8_icelake(nk_size_t width, nk_size_t depth);
1158
+ /** @copydoc nk_dots_pack_i8 */
1159
+ NK_PUBLIC void nk_dots_pack_i8_icelake(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1160
+ void *b_packed);
1161
+ /** @copydoc nk_dots_packed_i8 */
1162
+ NK_PUBLIC void nk_dots_packed_i8_icelake(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
1163
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1164
+ /** @copydoc nk_dots_symmetric_i8 */
1165
+ NK_PUBLIC void nk_dots_symmetric_i8_icelake(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1166
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
1167
+ nk_size_t row_start, nk_size_t row_count);
1168
+ /** @copydoc nk_dots_packed_size_u8 */
1169
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8_icelake(nk_size_t width, nk_size_t depth);
1170
+ /** @copydoc nk_dots_pack_u8 */
1171
+ NK_PUBLIC void nk_dots_pack_u8_icelake(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1172
+ void *b_packed);
1173
+ /** @copydoc nk_dots_packed_u8 */
1174
+ NK_PUBLIC void nk_dots_packed_u8_icelake(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1175
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1176
+ /** @copydoc nk_dots_symmetric_u8 */
1177
+ NK_PUBLIC void nk_dots_symmetric_u8_icelake(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1178
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1179
+ nk_size_t row_start, nk_size_t row_count);
1180
+ /** @copydoc nk_dots_packed_size_i4 */
1181
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i4_icelake(nk_size_t width, nk_size_t depth);
1182
+ /** @copydoc nk_dots_pack_i4 */
1183
+ NK_PUBLIC void nk_dots_pack_i4_icelake(nk_i4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1184
+ void *b_packed);
1185
+ /** @copydoc nk_dots_packed_i4 */
1186
+ NK_PUBLIC void nk_dots_packed_i4_icelake(nk_i4x2_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
1187
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1188
+ /** @copydoc nk_dots_symmetric_i4 */
1189
+ NK_PUBLIC void nk_dots_symmetric_i4_icelake(nk_i4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1190
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
1191
+ nk_size_t row_start, nk_size_t row_count);
1192
+ /** @copydoc nk_dots_packed_size_u4 */
1193
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u4_icelake(nk_size_t width, nk_size_t depth);
1194
+ /** @copydoc nk_dots_pack_u4 */
1195
+ NK_PUBLIC void nk_dots_pack_u4_icelake(nk_u4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1196
+ void *b_packed);
1197
+ /** @copydoc nk_dots_packed_u4 */
1198
+ NK_PUBLIC void nk_dots_packed_u4_icelake(nk_u4x2_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1199
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1200
+ /** @copydoc nk_dots_symmetric_u4 */
1201
+ NK_PUBLIC void nk_dots_symmetric_u4_icelake(nk_u4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1202
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1203
+ nk_size_t row_start, nk_size_t row_count);
1204
+ /** @copydoc nk_dots_packed_size_u1 */
1205
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u1_icelake(nk_size_t width, nk_size_t depth);
1206
+ /** @copydoc nk_dots_pack_u1 */
1207
+ NK_PUBLIC void nk_dots_pack_u1_icelake(nk_u1x8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1208
+ void *b_packed);
1209
+ /** @copydoc nk_dots_packed_u1 */
1210
+ NK_PUBLIC void nk_dots_packed_u1_icelake(nk_u1x8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1211
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1212
+ /** @copydoc nk_dots_symmetric_u1 */
1213
+ NK_PUBLIC void nk_dots_symmetric_u1_icelake(nk_u1x8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1214
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1215
+ nk_size_t row_start, nk_size_t row_count);
1216
+ #endif // NK_TARGET_ICELAKE
1217
+
1218
+ /* Alder backends using AMX with TDPB[SU]SD / TDPBF16PS.
1219
+ * Optimized for I8/U8 via AMX integer tiles, E2M3 via AMX BF16 tiles.
1220
+ */
1221
+ #if NK_TARGET_ALDER
1222
+ /** @copydoc nk_dots_packed_size_i8 */
1223
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8_alder(nk_size_t width, nk_size_t depth);
1224
+ /** @copydoc nk_dots_pack_i8 */
1225
+ NK_PUBLIC void nk_dots_pack_i8_alder(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1226
+ void *b_packed);
1227
+ /** @copydoc nk_dots_packed_i8 */
1228
+ NK_PUBLIC void nk_dots_packed_i8_alder(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
1229
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1230
+ /** @copydoc nk_dots_symmetric_i8 */
1231
+ NK_PUBLIC void nk_dots_symmetric_i8_alder(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1232
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
1233
+ nk_size_t row_start, nk_size_t row_count);
1234
+ /** @copydoc nk_dots_packed_size_u8 */
1235
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8_alder(nk_size_t width, nk_size_t depth);
1236
+ /** @copydoc nk_dots_pack_u8 */
1237
+ NK_PUBLIC void nk_dots_pack_u8_alder(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1238
+ void *b_packed);
1239
+ /** @copydoc nk_dots_packed_u8 */
1240
+ NK_PUBLIC void nk_dots_packed_u8_alder(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1241
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1242
+ /** @copydoc nk_dots_symmetric_u8 */
1243
+ NK_PUBLIC void nk_dots_symmetric_u8_alder(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1244
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1245
+ nk_size_t row_start, nk_size_t row_count);
1246
+ /** @copydoc nk_dots_packed_size_e2m3 */
1247
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e2m3_alder(nk_size_t width, nk_size_t depth);
1248
+ /** @copydoc nk_dots_pack_e2m3 */
1249
+ NK_PUBLIC void nk_dots_pack_e2m3_alder(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1250
+ void *b_packed);
1251
+ /** @copydoc nk_dots_packed_e2m3 */
1252
+ NK_PUBLIC void nk_dots_packed_e2m3_alder(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1253
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1254
+ /** @copydoc nk_dots_symmetric_e2m3 */
1255
+ NK_PUBLIC void nk_dots_symmetric_e2m3_alder(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1256
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1257
+ nk_size_t row_start, nk_size_t row_count);
1258
+ #endif // NK_TARGET_ALDER
1259
+
1260
+ /* Sierra backends using AVX10.2 with VMPSADBW.
1261
+ * Optimized for I8/U8 via VMPSADBW (vector multiply-sum of absolute differences).
1262
+ */
1263
+ #if NK_TARGET_SIERRA
1264
+ /** @copydoc nk_dots_packed_size_i8 */
1265
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8_sierra(nk_size_t width, nk_size_t depth);
1266
+ /** @copydoc nk_dots_pack_i8 */
1267
+ NK_PUBLIC void nk_dots_pack_i8_sierra(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1268
+ void *b_packed);
1269
+ /** @copydoc nk_dots_packed_i8 */
1270
+ NK_PUBLIC void nk_dots_packed_i8_sierra(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
1271
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1272
+ /** @copydoc nk_dots_symmetric_i8 */
1273
+ NK_PUBLIC void nk_dots_symmetric_i8_sierra(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1274
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
1275
+ nk_size_t row_start, nk_size_t row_count);
1276
+ /** @copydoc nk_dots_packed_size_u8 */
1277
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8_sierra(nk_size_t width, nk_size_t depth);
1278
+ /** @copydoc nk_dots_pack_u8 */
1279
+ NK_PUBLIC void nk_dots_pack_u8_sierra(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1280
+ void *b_packed);
1281
+ /** @copydoc nk_dots_packed_u8 */
1282
+ NK_PUBLIC void nk_dots_packed_u8_sierra(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1283
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1284
+ /** @copydoc nk_dots_symmetric_u8 */
1285
+ NK_PUBLIC void nk_dots_symmetric_u8_sierra(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1286
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1287
+ nk_size_t row_start, nk_size_t row_count);
1288
+ /** @copydoc nk_dots_packed_size_e2m3 */
1289
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e2m3_sierra(nk_size_t width, nk_size_t depth);
1290
+ /** @copydoc nk_dots_pack_e2m3 */
1291
+ NK_PUBLIC void nk_dots_pack_e2m3_sierra(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1292
+ void *b_packed);
1293
+ /** @copydoc nk_dots_packed_e2m3 */
1294
+ NK_PUBLIC void nk_dots_packed_e2m3_sierra(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1295
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1296
+ /** @copydoc nk_dots_symmetric_e2m3 */
1297
+ NK_PUBLIC void nk_dots_symmetric_e2m3_sierra(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1298
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1299
+ nk_size_t row_start, nk_size_t row_count);
1300
+ #endif // NK_TARGET_SIERRA
1301
+
1302
+ /* WASM Relaxed SIMD backends using wasm_i32x4_relaxed_dot_i8x16_i7x16_add.
1303
+ * Covers I8/U8/E2M3 (depth_simd_dimensions=16), BF16/F32 (4), F64 (2).
1304
+ */
1305
+ #if NK_TARGET_V128RELAXED
1306
+ /** @copydoc nk_dots_packed_size_i8 */
1307
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8_v128relaxed(nk_size_t width, nk_size_t depth);
1308
+ /** @copydoc nk_dots_pack_i8 */
1309
+ NK_PUBLIC void nk_dots_pack_i8_v128relaxed(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1310
+ void *b_packed);
1311
+ /** @copydoc nk_dots_packed_i8 */
1312
+ NK_PUBLIC void nk_dots_packed_i8_v128relaxed(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
1313
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1314
+ /** @copydoc nk_dots_symmetric_i8 */
1315
+ NK_PUBLIC void nk_dots_symmetric_i8_v128relaxed(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1316
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
1317
+ nk_size_t row_start, nk_size_t row_count);
1318
+ /** @copydoc nk_dots_packed_size_u8 */
1319
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8_v128relaxed(nk_size_t width, nk_size_t depth);
1320
+ /** @copydoc nk_dots_pack_u8 */
1321
+ NK_PUBLIC void nk_dots_pack_u8_v128relaxed(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1322
+ void *b_packed);
1323
+ /** @copydoc nk_dots_packed_u8 */
1324
+ NK_PUBLIC void nk_dots_packed_u8_v128relaxed(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1325
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1326
+ /** @copydoc nk_dots_symmetric_u8 */
1327
+ NK_PUBLIC void nk_dots_symmetric_u8_v128relaxed(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1328
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1329
+ nk_size_t row_start, nk_size_t row_count);
1330
+ /** @copydoc nk_dots_packed_size_e2m3 */
1331
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e2m3_v128relaxed(nk_size_t width, nk_size_t depth);
1332
+ /** @copydoc nk_dots_pack_e2m3 */
1333
+ NK_PUBLIC void nk_dots_pack_e2m3_v128relaxed(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1334
+ void *b_packed);
1335
+ /** @copydoc nk_dots_packed_e2m3 */
1336
+ NK_PUBLIC void nk_dots_packed_e2m3_v128relaxed(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1337
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride,
1338
+ nk_size_t c_stride);
1339
+ /** @copydoc nk_dots_symmetric_e2m3 */
1340
+ NK_PUBLIC void nk_dots_symmetric_e2m3_v128relaxed(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1341
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1342
+ nk_size_t row_start, nk_size_t row_count);
1343
+ /** @copydoc nk_dots_packed_size_bf16 */
1344
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16_v128relaxed(nk_size_t width, nk_size_t depth);
1345
+ /** @copydoc nk_dots_pack_bf16 */
1346
+ NK_PUBLIC void nk_dots_pack_bf16_v128relaxed(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1347
+ void *b_packed);
1348
+ /** @copydoc nk_dots_packed_bf16 */
1349
+ NK_PUBLIC void nk_dots_packed_bf16_v128relaxed(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1350
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride,
1351
+ nk_size_t c_stride);
1352
+ /** @copydoc nk_dots_symmetric_bf16 */
1353
+ NK_PUBLIC void nk_dots_symmetric_bf16_v128relaxed(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1354
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1355
+ nk_size_t row_start, nk_size_t row_count);
1356
+ /** @copydoc nk_dots_packed_size_f32 */
1357
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f32_v128relaxed(nk_size_t width, nk_size_t depth);
1358
+ /** @copydoc nk_dots_pack_f32 */
1359
+ NK_PUBLIC void nk_dots_pack_f32_v128relaxed(nk_f32_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1360
+ void *b_packed);
1361
+ /** @copydoc nk_dots_packed_f32 */
1362
+ NK_PUBLIC void nk_dots_packed_f32_v128relaxed(nk_f32_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
1363
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1364
+ /** @copydoc nk_dots_symmetric_f32 */
1365
+ NK_PUBLIC void nk_dots_symmetric_f32_v128relaxed(nk_f32_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1366
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
1367
+ nk_size_t row_start, nk_size_t row_count);
1368
+ /** @copydoc nk_dots_packed_size_f64 */
1369
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f64_v128relaxed(nk_size_t width, nk_size_t depth);
1370
+ /** @copydoc nk_dots_pack_f64 */
1371
+ NK_PUBLIC void nk_dots_pack_f64_v128relaxed(nk_f64_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1372
+ void *b_packed);
1373
+ /** @copydoc nk_dots_packed_f64 */
1374
+ NK_PUBLIC void nk_dots_packed_f64_v128relaxed(nk_f64_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
1375
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1376
+ /** @copydoc nk_dots_symmetric_f64 */
1377
+ NK_PUBLIC void nk_dots_symmetric_f64_v128relaxed(nk_f64_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1378
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
1379
+ nk_size_t row_start, nk_size_t row_count);
1380
+ /** @copydoc nk_dots_packed_size_bf16 */
1381
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e4m3_v128relaxed(nk_size_t width, nk_size_t depth);
1382
+ /** @copydoc nk_dots_pack_bf16 */
1383
+ NK_PUBLIC void nk_dots_pack_e4m3_v128relaxed(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1384
+ void *b_packed);
1385
+ /** @copydoc nk_dots_packed_bf16 */
1386
+ NK_PUBLIC void nk_dots_packed_e4m3_v128relaxed(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1387
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride,
1388
+ nk_size_t c_stride);
1389
+ /** @copydoc nk_dots_symmetric_bf16 */
1390
+ NK_PUBLIC void nk_dots_symmetric_e4m3_v128relaxed(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1391
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1392
+ nk_size_t row_start, nk_size_t row_count);
1393
+ /** @copydoc nk_dots_packed_size_bf16 */
1394
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e5m2_v128relaxed(nk_size_t width, nk_size_t depth);
1395
+ /** @copydoc nk_dots_pack_bf16 */
1396
+ NK_PUBLIC void nk_dots_pack_e5m2_v128relaxed(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1397
+ void *b_packed);
1398
+ /** @copydoc nk_dots_packed_bf16 */
1399
+ NK_PUBLIC void nk_dots_packed_e5m2_v128relaxed(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1400
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride,
1401
+ nk_size_t c_stride);
1402
+ /** @copydoc nk_dots_symmetric_bf16 */
1403
+ NK_PUBLIC void nk_dots_symmetric_e5m2_v128relaxed(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1404
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1405
+ nk_size_t row_start, nk_size_t row_count);
1406
+ /** @copydoc nk_dots_packed_size_bf16 */
1407
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u4_v128relaxed(nk_size_t width, nk_size_t depth);
1408
+ /** @copydoc nk_dots_pack_bf16 */
1409
+ NK_PUBLIC void nk_dots_pack_u4_v128relaxed(nk_u4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1410
+ void *b_packed);
1411
+ /** @copydoc nk_dots_packed_bf16 */
1412
+ NK_PUBLIC void nk_dots_packed_u4_v128relaxed(nk_u4x2_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1413
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1414
+ /** @copydoc nk_dots_symmetric_bf16 */
1415
+ NK_PUBLIC void nk_dots_symmetric_u4_v128relaxed(nk_u4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1416
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1417
+ nk_size_t row_start, nk_size_t row_count);
1418
+ /** @copydoc nk_dots_packed_size_bf16 */
1419
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i4_v128relaxed(nk_size_t width, nk_size_t depth);
1420
+ /** @copydoc nk_dots_pack_bf16 */
1421
+ NK_PUBLIC void nk_dots_pack_i4_v128relaxed(nk_i4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1422
+ void *b_packed);
1423
+ /** @copydoc nk_dots_packed_bf16 */
1424
+ NK_PUBLIC void nk_dots_packed_i4_v128relaxed(nk_i4x2_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
1425
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1426
+ /** @copydoc nk_dots_symmetric_bf16 */
1427
+ NK_PUBLIC void nk_dots_symmetric_i4_v128relaxed(nk_i4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1428
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
1429
+ nk_size_t row_start, nk_size_t row_count);
1430
+ /** @copydoc nk_dots_packed_size_u1 */
1431
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u1_v128relaxed(nk_size_t width, nk_size_t depth);
1432
+ /** @copydoc nk_dots_pack_u1 */
1433
+ NK_PUBLIC void nk_dots_pack_u1_v128relaxed(nk_u1x8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1434
+ void *b_packed);
1435
+ /** @copydoc nk_dots_packed_u1 */
1436
+ NK_PUBLIC void nk_dots_packed_u1_v128relaxed(nk_u1x8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1437
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1438
+ /** @copydoc nk_dots_symmetric_u1 */
1439
+ NK_PUBLIC void nk_dots_symmetric_u1_v128relaxed(nk_u1x8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1440
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1441
+ nk_size_t row_start, nk_size_t row_count);
1442
+ #endif // NK_TARGET_V128RELAXED
1443
+
1444
+ /* ARM NEON backends (base NEON with F32/F64 support).
1445
+ * Uses FMLA for F32 dots, FMLA (scalar) for F64.
1446
+ */
1447
+ #if NK_TARGET_NEON
1448
+ /** @copydoc nk_dots_packed_size_f32 */
1449
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f32_neon(nk_size_t width, nk_size_t depth);
1450
+ /** @copydoc nk_dots_pack_f32 */
1451
+ NK_PUBLIC void nk_dots_pack_f32_neon(nk_f32_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1452
+ void *b_packed);
1453
+ /** @copydoc nk_dots_packed_f32 */
1454
+ NK_PUBLIC void nk_dots_packed_f32_neon(nk_f32_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
1455
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1456
+ /** @copydoc nk_dots_symmetric_f32 */
1457
+ NK_PUBLIC void nk_dots_symmetric_f32_neon(nk_f32_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1458
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
1459
+ nk_size_t row_start, nk_size_t row_count);
1460
+ /** @copydoc nk_dots_packed_size_f64 */
1461
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f64_neon(nk_size_t width, nk_size_t depth);
1462
+ /** @copydoc nk_dots_pack_f64 */
1463
+ NK_PUBLIC void nk_dots_pack_f64_neon(nk_f64_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1464
+ void *b_packed);
1465
+ /** @copydoc nk_dots_packed_f64 */
1466
+ NK_PUBLIC void nk_dots_packed_f64_neon(nk_f64_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
1467
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1468
+ /** @copydoc nk_dots_symmetric_f64 */
1469
+ NK_PUBLIC void nk_dots_symmetric_f64_neon(nk_f64_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1470
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
1471
+ nk_size_t row_start, nk_size_t row_count);
1472
+ /** @copydoc nk_dots_packed_size_u1 */
1473
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u1_neon(nk_size_t width, nk_size_t depth);
1474
+ /** @copydoc nk_dots_pack_u1 */
1475
+ NK_PUBLIC void nk_dots_pack_u1_neon(nk_u1x8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1476
+ void *b_packed);
1477
+ /** @copydoc nk_dots_packed_u1 */
1478
+ NK_PUBLIC void nk_dots_packed_u1_neon(nk_u1x8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1479
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1480
+ /** @copydoc nk_dots_symmetric_u1 */
1481
+ NK_PUBLIC void nk_dots_symmetric_u1_neon(nk_u1x8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1482
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1483
+ nk_size_t row_start, nk_size_t row_count);
1484
+ /** @copydoc nk_dots_packed_size_f16 */
1485
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f16_neon(nk_size_t width, nk_size_t depth);
1486
+ /** @copydoc nk_dots_pack_f16 */
1487
+ NK_PUBLIC void nk_dots_pack_f16_neon(nk_f16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1488
+ void *b_packed);
1489
+ /** @copydoc nk_dots_packed_f16 */
1490
+ NK_PUBLIC void nk_dots_packed_f16_neon(nk_f16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1491
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1492
+ /** @copydoc nk_dots_symmetric_f16 */
1493
+ NK_PUBLIC void nk_dots_symmetric_f16_neon(nk_f16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1494
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1495
+ nk_size_t row_start, nk_size_t row_count);
1496
+ /** @copydoc nk_dots_packed_size_bf16 */
1497
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16_neon(nk_size_t width, nk_size_t depth);
1498
+ /** @copydoc nk_dots_pack_bf16 */
1499
+ NK_PUBLIC void nk_dots_pack_bf16_neon(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1500
+ void *b_packed);
1501
+ /** @copydoc nk_dots_packed_bf16 */
1502
+ NK_PUBLIC void nk_dots_packed_bf16_neon(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1503
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1504
+ /** @copydoc nk_dots_symmetric_bf16 */
1505
+ NK_PUBLIC void nk_dots_symmetric_bf16_neon(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1506
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1507
+ nk_size_t row_start, nk_size_t row_count);
1508
+ #endif // NK_TARGET_NEON
1509
+
1510
+ /* ARM NEON with BF16 dot product (ARMv8.6-A BF16).
1511
+ * Uses BFDOT/BFMMLA for efficient BF16 matrix operations.
1512
+ */
1513
+ #if NK_TARGET_NEONBFDOT
1514
+ /** @copydoc nk_dots_packed_size_bf16 */
1515
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16_neonbfdot(nk_size_t width, nk_size_t depth);
1516
+ /** @copydoc nk_dots_pack_bf16 */
1517
+ NK_PUBLIC void nk_dots_pack_bf16_neonbfdot(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1518
+ void *b_packed);
1519
+ /** @copydoc nk_dots_packed_bf16 */
1520
+ NK_PUBLIC void nk_dots_packed_bf16_neonbfdot(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1521
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1522
+ /** @copydoc nk_dots_symmetric_bf16 */
1523
+ NK_PUBLIC void nk_dots_symmetric_bf16_neonbfdot(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1524
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1525
+ nk_size_t row_start, nk_size_t row_count);
1526
+ #endif // NK_TARGET_NEONBFDOT
1527
+
1528
+ /* ARM NEON with signed/unsigned dot product (ARMv8.2-A DotProd).
1529
+ * Provides SDOT/UDOT for I8/U8 vector dot products.
1530
+ */
1531
+ #if NK_TARGET_NEONSDOT
1532
+ /** @copydoc nk_dots_packed_size_i8 */
1533
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8_neonsdot(nk_size_t width, nk_size_t depth);
1534
+ /** @copydoc nk_dots_pack_i8 */
1535
+ NK_PUBLIC void nk_dots_pack_i8_neonsdot(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1536
+ void *b_packed);
1537
+ /** @copydoc nk_dots_packed_i8 */
1538
+ NK_PUBLIC void nk_dots_packed_i8_neonsdot(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
1539
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1540
+ /** @copydoc nk_dots_symmetric_i8 */
1541
+ NK_PUBLIC void nk_dots_symmetric_i8_neonsdot(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1542
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
1543
+ nk_size_t row_start, nk_size_t row_count);
1544
+ /** @copydoc nk_dots_packed_size_u8 */
1545
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8_neonsdot(nk_size_t width, nk_size_t depth);
1546
+ /** @copydoc nk_dots_pack_u8 */
1547
+ NK_PUBLIC void nk_dots_pack_u8_neonsdot(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1548
+ void *b_packed);
1549
+ /** @copydoc nk_dots_packed_u8 */
1550
+ NK_PUBLIC void nk_dots_packed_u8_neonsdot(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1551
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1552
+ /** @copydoc nk_dots_symmetric_u8 */
1553
+ NK_PUBLIC void nk_dots_symmetric_u8_neonsdot(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1554
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1555
+ nk_size_t row_start, nk_size_t row_count);
1556
+ #endif // NK_TARGET_NEONSDOT
1557
+
1558
+ /* ARM NEON with FP16 FML (fused multiply-long, ARMv8.2-A FP16FML).
1559
+ * Uses FMLAL/FMLSL for F16 and custom FP8 (E2M3/E3M2) operations.
1560
+ */
1561
+ #if NK_TARGET_NEONFHM
1562
+ /** @copydoc nk_dots_packed_size_f16 */
1563
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f16_neonfhm(nk_size_t width, nk_size_t depth);
1564
+ /** @copydoc nk_dots_pack_f16 */
1565
+ NK_PUBLIC void nk_dots_pack_f16_neonfhm(nk_f16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1566
+ void *b_packed);
1567
+ /** @copydoc nk_dots_packed_f16 */
1568
+ NK_PUBLIC void nk_dots_packed_f16_neonfhm(nk_f16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1569
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1570
+ /** @copydoc nk_dots_symmetric_f16 */
1571
+ NK_PUBLIC void nk_dots_symmetric_f16_neonfhm(nk_f16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1572
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1573
+ nk_size_t row_start, nk_size_t row_count);
1574
+ /** @copydoc nk_dots_packed_size_e4m3 */
1575
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e4m3_neonfhm(nk_size_t width, nk_size_t depth);
1576
+ /** @copydoc nk_dots_pack_e4m3 */
1577
+ NK_PUBLIC void nk_dots_pack_e4m3_neonfhm(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1578
+ void *b_packed);
1579
+ /** @copydoc nk_dots_packed_e4m3 */
1580
+ NK_PUBLIC void nk_dots_packed_e4m3_neonfhm(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1581
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1582
+ /** @copydoc nk_dots_symmetric_e4m3 */
1583
+ NK_PUBLIC void nk_dots_symmetric_e4m3_neonfhm(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1584
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1585
+ nk_size_t row_start, nk_size_t row_count);
1586
+ /** @copydoc nk_dots_packed_size_e5m2 */
1587
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e5m2_neonfhm(nk_size_t width, nk_size_t depth);
1588
+ /** @copydoc nk_dots_pack_e5m2 */
1589
+ NK_PUBLIC void nk_dots_pack_e5m2_neonfhm(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1590
+ void *b_packed);
1591
+ /** @copydoc nk_dots_packed_e5m2 */
1592
+ NK_PUBLIC void nk_dots_packed_e5m2_neonfhm(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1593
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1594
+ /** @copydoc nk_dots_symmetric_e5m2 */
1595
+ NK_PUBLIC void nk_dots_symmetric_e5m2_neonfhm(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1596
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1597
+ nk_size_t row_start, nk_size_t row_count);
1598
+ #endif // NK_TARGET_NEONFHM
1599
+
1600
+ /* ARM NEON with FP8 (ARMv9.2-A FP8).
1601
+ * Uses native FP8 dot-product instructions for E4M3/E5M2/E2M3/E3M2 operations.
1602
+ */
1603
+ #if NK_TARGET_NEONFP8
1604
+ /** @copydoc nk_dots_packed_size_e4m3 */
1605
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e4m3_neonfp8(nk_size_t width, nk_size_t depth);
1606
+ /** @copydoc nk_dots_pack_e4m3 */
1607
+ NK_PUBLIC void nk_dots_pack_e4m3_neonfp8(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1608
+ void *b_packed);
1609
+ /** @copydoc nk_dots_packed_e4m3 */
1610
+ NK_PUBLIC void nk_dots_packed_e4m3_neonfp8(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1611
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1612
+ /** @copydoc nk_dots_symmetric_e4m3 */
1613
+ NK_PUBLIC void nk_dots_symmetric_e4m3_neonfp8(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1614
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1615
+ nk_size_t row_start, nk_size_t row_count);
1616
+ /** @copydoc nk_dots_packed_size_e5m2 */
1617
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e5m2_neonfp8(nk_size_t width, nk_size_t depth);
1618
+ /** @copydoc nk_dots_pack_e5m2 */
1619
+ NK_PUBLIC void nk_dots_pack_e5m2_neonfp8(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1620
+ void *b_packed);
1621
+ /** @copydoc nk_dots_packed_e5m2 */
1622
+ NK_PUBLIC void nk_dots_packed_e5m2_neonfp8(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1623
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1624
+ /** @copydoc nk_dots_symmetric_e5m2 */
1625
+ NK_PUBLIC void nk_dots_symmetric_e5m2_neonfp8(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1626
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1627
+ nk_size_t row_start, nk_size_t row_count);
1628
+ /** @copydoc nk_dots_packed_size_e2m3 */
1629
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e2m3_neonfp8(nk_size_t width, nk_size_t depth);
1630
+ /** @copydoc nk_dots_pack_e2m3 */
1631
+ NK_PUBLIC void nk_dots_pack_e2m3_neonfp8(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1632
+ void *b_packed);
1633
+ /** @copydoc nk_dots_packed_e2m3 */
1634
+ NK_PUBLIC void nk_dots_packed_e2m3_neonfp8(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1635
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1636
+ /** @copydoc nk_dots_symmetric_e2m3 */
1637
+ NK_PUBLIC void nk_dots_symmetric_e2m3_neonfp8(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1638
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1639
+ nk_size_t row_start, nk_size_t row_count);
1640
+ /** @copydoc nk_dots_packed_size_e3m2 */
1641
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e3m2_neonfp8(nk_size_t width, nk_size_t depth);
1642
+ /** @copydoc nk_dots_pack_e3m2 */
1643
+ NK_PUBLIC void nk_dots_pack_e3m2_neonfp8(nk_e3m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1644
+ void *b_packed);
1645
+ /** @copydoc nk_dots_packed_e3m2 */
1646
+ NK_PUBLIC void nk_dots_packed_e3m2_neonfp8(nk_e3m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1647
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1648
+ /** @copydoc nk_dots_symmetric_e3m2 */
1649
+ NK_PUBLIC void nk_dots_symmetric_e3m2_neonfp8(nk_e3m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1650
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1651
+ nk_size_t row_start, nk_size_t row_count);
1652
+ #endif // NK_TARGET_NEONFP8
1653
+
1654
+ #if NK_TARGET_RVV
1655
+ /** @copydoc nk_dots_packed_size_e2m3 */
1656
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e2m3_rvv(nk_size_t width, nk_size_t depth);
1657
+ /** @copydoc nk_dots_pack_e2m3 */
1658
+ NK_PUBLIC void nk_dots_pack_e2m3_rvv(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1659
+ void *b_packed);
1660
+ /** @copydoc nk_dots_packed_e2m3 */
1661
+ NK_PUBLIC void nk_dots_packed_e2m3_rvv(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1662
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1663
+ /** @copydoc nk_dots_symmetric_e2m3 */
1664
+ NK_PUBLIC void nk_dots_symmetric_e2m3_rvv(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1665
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1666
+ nk_size_t row_start, nk_size_t row_count);
1667
+ /** @copydoc nk_dots_packed_size_e3m2 */
1668
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e3m2_rvv(nk_size_t width, nk_size_t depth);
1669
+ /** @copydoc nk_dots_pack_e3m2 */
1670
+ NK_PUBLIC void nk_dots_pack_e3m2_rvv(nk_e3m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1671
+ void *b_packed);
1672
+ /** @copydoc nk_dots_packed_e3m2 */
1673
+ NK_PUBLIC void nk_dots_packed_e3m2_rvv(nk_e3m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1674
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1675
+ /** @copydoc nk_dots_symmetric_e3m2 */
1676
+ NK_PUBLIC void nk_dots_symmetric_e3m2_rvv(nk_e3m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1677
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1678
+ nk_size_t row_start, nk_size_t row_count);
1679
+ /** @copydoc nk_dots_packed_size_f32 */
1680
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f32_rvv(nk_size_t width, nk_size_t depth);
1681
+ /** @copydoc nk_dots_pack_f32 */
1682
+ NK_PUBLIC void nk_dots_pack_f32_rvv(nk_f32_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1683
+ void *b_packed);
1684
+ /** @copydoc nk_dots_packed_f32 */
1685
+ NK_PUBLIC void nk_dots_packed_f32_rvv(nk_f32_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
1686
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1687
+ /** @copydoc nk_dots_symmetric_f32 */
1688
+ NK_PUBLIC void nk_dots_symmetric_f32_rvv(nk_f32_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1689
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
1690
+ nk_size_t row_start, nk_size_t row_count);
1691
+ /** @copydoc nk_dots_packed_size_f64 */
1692
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f64_rvv(nk_size_t width, nk_size_t depth);
1693
+ /** @copydoc nk_dots_pack_f64 */
1694
+ NK_PUBLIC void nk_dots_pack_f64_rvv(nk_f64_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1695
+ void *b_packed);
1696
+ /** @copydoc nk_dots_packed_f64 */
1697
+ NK_PUBLIC void nk_dots_packed_f64_rvv(nk_f64_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
1698
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1699
+ /** @copydoc nk_dots_symmetric_f64 */
1700
+ NK_PUBLIC void nk_dots_symmetric_f64_rvv(nk_f64_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1701
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
1702
+ nk_size_t row_start, nk_size_t row_count);
1703
+ /** @copydoc nk_dots_packed_size_bf16 */
1704
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16_rvv(nk_size_t width, nk_size_t depth);
1705
+ /** @copydoc nk_dots_pack_bf16 */
1706
+ NK_PUBLIC void nk_dots_pack_bf16_rvv(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1707
+ void *b_packed);
1708
+ /** @copydoc nk_dots_packed_bf16 */
1709
+ NK_PUBLIC void nk_dots_packed_bf16_rvv(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1710
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1711
+ /** @copydoc nk_dots_symmetric_bf16 */
1712
+ NK_PUBLIC void nk_dots_symmetric_bf16_rvv(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1713
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1714
+ nk_size_t row_start, nk_size_t row_count);
1715
+ /** @copydoc nk_dots_packed_size_f16 */
1716
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f16_rvv(nk_size_t width, nk_size_t depth);
1717
+ /** @copydoc nk_dots_pack_f16 */
1718
+ NK_PUBLIC void nk_dots_pack_f16_rvv(nk_f16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1719
+ void *b_packed);
1720
+ /** @copydoc nk_dots_packed_f16 */
1721
+ NK_PUBLIC void nk_dots_packed_f16_rvv(nk_f16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1722
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1723
+ /** @copydoc nk_dots_symmetric_f16 */
1724
+ NK_PUBLIC void nk_dots_symmetric_f16_rvv(nk_f16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1725
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1726
+ nk_size_t row_start, nk_size_t row_count);
1727
+ /** @copydoc nk_dots_packed_size_i8 */
1728
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8_rvv(nk_size_t width, nk_size_t depth);
1729
+ /** @copydoc nk_dots_pack_i8 */
1730
+ NK_PUBLIC void nk_dots_pack_i8_rvv(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1731
+ void *b_packed);
1732
+ /** @copydoc nk_dots_packed_i8 */
1733
+ NK_PUBLIC void nk_dots_packed_i8_rvv(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
1734
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1735
+ /** @copydoc nk_dots_symmetric_i8 */
1736
+ NK_PUBLIC void nk_dots_symmetric_i8_rvv(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1737
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
1738
+ nk_size_t row_start, nk_size_t row_count);
1739
+ /** @copydoc nk_dots_packed_size_u8 */
1740
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8_rvv(nk_size_t width, nk_size_t depth);
1741
+ /** @copydoc nk_dots_pack_u8 */
1742
+ NK_PUBLIC void nk_dots_pack_u8_rvv(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1743
+ void *b_packed);
1744
+ /** @copydoc nk_dots_packed_u8 */
1745
+ NK_PUBLIC void nk_dots_packed_u8_rvv(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1746
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1747
+ /** @copydoc nk_dots_symmetric_u8 */
1748
+ NK_PUBLIC void nk_dots_symmetric_u8_rvv(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1749
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1750
+ nk_size_t row_start, nk_size_t row_count);
1751
+ /** @copydoc nk_dots_packed_size_e4m3 */
1752
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e4m3_rvv(nk_size_t width, nk_size_t depth);
1753
+ /** @copydoc nk_dots_pack_e4m3 */
1754
+ NK_PUBLIC void nk_dots_pack_e4m3_rvv(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1755
+ void *b_packed);
1756
+ /** @copydoc nk_dots_packed_e4m3 */
1757
+ NK_PUBLIC void nk_dots_packed_e4m3_rvv(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1758
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1759
+ /** @copydoc nk_dots_symmetric_e4m3 */
1760
+ NK_PUBLIC void nk_dots_symmetric_e4m3_rvv(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1761
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1762
+ nk_size_t row_start, nk_size_t row_count);
1763
+ /** @copydoc nk_dots_packed_size_e5m2 */
1764
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e5m2_rvv(nk_size_t width, nk_size_t depth);
1765
+ /** @copydoc nk_dots_pack_e5m2 */
1766
+ NK_PUBLIC void nk_dots_pack_e5m2_rvv(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1767
+ void *b_packed);
1768
+ /** @copydoc nk_dots_packed_e5m2 */
1769
+ NK_PUBLIC void nk_dots_packed_e5m2_rvv(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1770
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1771
+ /** @copydoc nk_dots_symmetric_e5m2 */
1772
+ NK_PUBLIC void nk_dots_symmetric_e5m2_rvv(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1773
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1774
+ nk_size_t row_start, nk_size_t row_count);
1775
+ #endif // NK_TARGET_RVV
1776
+
1777
+ /* Loongson LASX backends using 256-bit SIMD (LoongArch).
1778
+ */
1779
+ #if NK_TARGET_LOONGSONASX
1780
+ /** @copydoc nk_dots_packed_size_f32 */
1781
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f32_loongsonasx(nk_size_t width, nk_size_t depth);
1782
+ /** @copydoc nk_dots_pack_f32 */
1783
+ NK_PUBLIC void nk_dots_pack_f32_loongsonasx(nk_f32_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1784
+ void *b_packed);
1785
+ /** @copydoc nk_dots_packed_f32 */
1786
+ NK_PUBLIC void nk_dots_packed_f32_loongsonasx(nk_f32_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
1787
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1788
+ /** @copydoc nk_dots_symmetric_f32 */
1789
+ NK_PUBLIC void nk_dots_symmetric_f32_loongsonasx(nk_f32_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1790
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
1791
+ nk_size_t row_start, nk_size_t row_count);
1792
+ /** @copydoc nk_dots_packed_size_f64 */
1793
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f64_loongsonasx(nk_size_t width, nk_size_t depth);
1794
+ /** @copydoc nk_dots_pack_f64 */
1795
+ NK_PUBLIC void nk_dots_pack_f64_loongsonasx(nk_f64_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1796
+ void *b_packed);
1797
+ /** @copydoc nk_dots_packed_f64 */
1798
+ NK_PUBLIC void nk_dots_packed_f64_loongsonasx(nk_f64_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
1799
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1800
+ /** @copydoc nk_dots_symmetric_f64 */
1801
+ NK_PUBLIC void nk_dots_symmetric_f64_loongsonasx(nk_f64_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1802
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride,
1803
+ nk_size_t row_start, nk_size_t row_count);
1804
+ /** @copydoc nk_dots_packed_size_f16 */
1805
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f16_loongsonasx(nk_size_t width, nk_size_t depth);
1806
+ /** @copydoc nk_dots_pack_f16 */
1807
+ NK_PUBLIC void nk_dots_pack_f16_loongsonasx(nk_f16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1808
+ void *b_packed);
1809
+ /** @copydoc nk_dots_packed_f16 */
1810
+ NK_PUBLIC void nk_dots_packed_f16_loongsonasx(nk_f16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1811
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1812
+ /** @copydoc nk_dots_symmetric_f16 */
1813
+ NK_PUBLIC void nk_dots_symmetric_f16_loongsonasx(nk_f16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1814
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1815
+ nk_size_t row_start, nk_size_t row_count);
1816
+ /** @copydoc nk_dots_packed_size_bf16 */
1817
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16_loongsonasx(nk_size_t width, nk_size_t depth);
1818
+ /** @copydoc nk_dots_pack_bf16 */
1819
+ NK_PUBLIC void nk_dots_pack_bf16_loongsonasx(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1820
+ void *b_packed);
1821
+ /** @copydoc nk_dots_packed_bf16 */
1822
+ NK_PUBLIC void nk_dots_packed_bf16_loongsonasx(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
1823
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride,
1824
+ nk_size_t c_stride);
1825
+ /** @copydoc nk_dots_symmetric_bf16 */
1826
+ NK_PUBLIC void nk_dots_symmetric_bf16_loongsonasx(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1827
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride,
1828
+ nk_size_t row_start, nk_size_t row_count);
1829
+ /** @copydoc nk_dots_packed_size_i8 */
1830
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8_loongsonasx(nk_size_t width, nk_size_t depth);
1831
+ /** @copydoc nk_dots_pack_i8 */
1832
+ NK_PUBLIC void nk_dots_pack_i8_loongsonasx(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1833
+ void *b_packed);
1834
+ /** @copydoc nk_dots_packed_i8 */
1835
+ NK_PUBLIC void nk_dots_packed_i8_loongsonasx(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
1836
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1837
+ /** @copydoc nk_dots_symmetric_i8 */
1838
+ NK_PUBLIC void nk_dots_symmetric_i8_loongsonasx(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1839
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride,
1840
+ nk_size_t row_start, nk_size_t row_count);
1841
+ /** @copydoc nk_dots_packed_size_u8 */
1842
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8_loongsonasx(nk_size_t width, nk_size_t depth);
1843
+ /** @copydoc nk_dots_pack_u8 */
1844
+ NK_PUBLIC void nk_dots_pack_u8_loongsonasx(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1845
+ void *b_packed);
1846
+ /** @copydoc nk_dots_packed_u8 */
1847
+ NK_PUBLIC void nk_dots_packed_u8_loongsonasx(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1848
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1849
+ /** @copydoc nk_dots_symmetric_u8 */
1850
+ NK_PUBLIC void nk_dots_symmetric_u8_loongsonasx(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1851
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1852
+ nk_size_t row_start, nk_size_t row_count);
1853
+ /** @copydoc nk_dots_packed_size_u1 */
1854
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u1_loongsonasx(nk_size_t width, nk_size_t depth);
1855
+ /** @copydoc nk_dots_pack_u1 */
1856
+ NK_PUBLIC void nk_dots_pack_u1_loongsonasx(nk_u1x8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1857
+ void *b_packed);
1858
+ /** @copydoc nk_dots_packed_u1 */
1859
+ NK_PUBLIC void nk_dots_packed_u1_loongsonasx(nk_u1x8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
1860
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride);
1861
+ /** @copydoc nk_dots_symmetric_u1 */
1862
+ NK_PUBLIC void nk_dots_symmetric_u1_loongsonasx(nk_u1x8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
1863
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride,
1864
+ nk_size_t row_start, nk_size_t row_count);
1865
+ #endif // NK_TARGET_LOONGSONASX
1866
+
1867
+ #if defined(__cplusplus)
1868
+ } // extern "C"
1869
+ #endif
1870
+
1871
+ #include "numkong/dots/serial.h"
1872
+ #include "numkong/dots/haswell.h"
1873
+ #include "numkong/dots/skylake.h"
1874
+ #include "numkong/dots/icelake.h"
1875
+ #include "numkong/dots/alder.h"
1876
+ #include "numkong/dots/sierra.h"
1877
+ #include "numkong/dots/genoa.h"
1878
+ #include "numkong/dots/diamond.h"
1879
+ #include "numkong/dots/sapphireamx.h"
1880
+ #include "numkong/dots/graniteamx.h"
1881
+ #include "numkong/dots/neon.h"
1882
+ #include "numkong/dots/neonsdot.h"
1883
+ #include "numkong/dots/neonfhm.h"
1884
+ #include "numkong/dots/neonfp8.h"
1885
+ #include "numkong/dots/neonbfdot.h"
1886
+ #include "numkong/dots/sme.h"
1887
+ #include "numkong/dots/smef64.h"
1888
+ #include "numkong/dots/smebi32.h"
1889
+ #include "numkong/dots/rvv.h"
1890
+ #include "numkong/dots/powervsx.h"
1891
+ #include "numkong/dots/v128relaxed.h"
1892
+ #include "numkong/dots/loongsonasx.h"
1893
+
1894
+ #if defined(__cplusplus)
1895
+ extern "C" {
1896
+ #endif
1897
+
1898
+ #if !NK_DYNAMIC_DISPATCH
1899
+
1900
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f32(nk_size_t width, nk_size_t depth) {
1901
+ #if NK_TARGET_SMEF64
1902
+ return nk_dots_packed_size_f32_smef64(width, depth);
1903
+ #elif NK_TARGET_SKYLAKE
1904
+ return nk_dots_packed_size_f32_skylake(width, depth);
1905
+ #elif NK_TARGET_HASWELL
1906
+ return nk_dots_packed_size_f32_haswell(width, depth);
1907
+ #elif NK_TARGET_NEON
1908
+ return nk_dots_packed_size_f32_neon(width, depth);
1909
+ #elif NK_TARGET_POWERVSX
1910
+ return nk_dots_packed_size_f32_powervsx(width, depth);
1911
+ #elif NK_TARGET_RVV
1912
+ return nk_dots_packed_size_f32_rvv(width, depth);
1913
+ #elif NK_TARGET_V128RELAXED
1914
+ return nk_dots_packed_size_f32_v128relaxed(width, depth);
1915
+ #else
1916
+ return nk_dots_packed_size_f32_serial(width, depth);
1917
+ #endif
1918
+ }
1919
+
1920
+ NK_PUBLIC void nk_dots_pack_f32(nk_f32_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1921
+ void *b_packed) {
1922
+ #if NK_TARGET_SMEF64
1923
+ nk_dots_pack_f32_smef64(b, width, depth, b_stride, b_packed);
1924
+ #elif NK_TARGET_SKYLAKE
1925
+ nk_dots_pack_f32_skylake(b, width, depth, b_stride, b_packed);
1926
+ #elif NK_TARGET_HASWELL
1927
+ nk_dots_pack_f32_haswell(b, width, depth, b_stride, b_packed);
1928
+ #elif NK_TARGET_NEON
1929
+ nk_dots_pack_f32_neon(b, width, depth, b_stride, b_packed);
1930
+ #elif NK_TARGET_POWERVSX
1931
+ nk_dots_pack_f32_powervsx(b, width, depth, b_stride, b_packed);
1932
+ #elif NK_TARGET_RVV
1933
+ nk_dots_pack_f32_rvv(b, width, depth, b_stride, b_packed);
1934
+ #elif NK_TARGET_V128RELAXED
1935
+ nk_dots_pack_f32_v128relaxed(b, width, depth, b_stride, b_packed);
1936
+ #else
1937
+ nk_dots_pack_f32_serial(b, width, depth, b_stride, b_packed);
1938
+ #endif
1939
+ }
1940
+
1941
+ NK_PUBLIC void nk_dots_packed_f32(nk_f32_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
1942
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
1943
+ #if NK_TARGET_SMEF64
1944
+ nk_dots_packed_f32_smef64(a, b_packed, c, height, width, depth, a_stride, c_stride);
1945
+ #elif NK_TARGET_SKYLAKE
1946
+ nk_dots_packed_f32_skylake(a, b_packed, c, height, width, depth, a_stride, c_stride);
1947
+ #elif NK_TARGET_HASWELL
1948
+ nk_dots_packed_f32_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
1949
+ #elif NK_TARGET_NEON
1950
+ nk_dots_packed_f32_neon(a, b_packed, c, height, width, depth, a_stride, c_stride);
1951
+ #elif NK_TARGET_POWERVSX
1952
+ nk_dots_packed_f32_powervsx(a, b_packed, c, height, width, depth, a_stride, c_stride);
1953
+ #elif NK_TARGET_RVV
1954
+ nk_dots_packed_f32_rvv(a, b_packed, c, height, width, depth, a_stride, c_stride);
1955
+ #elif NK_TARGET_V128RELAXED
1956
+ nk_dots_packed_f32_v128relaxed(a, b_packed, c, height, width, depth, a_stride, c_stride);
1957
+ #else
1958
+ nk_dots_packed_f32_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
1959
+ #endif
1960
+ }
1961
+
1962
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f64(nk_size_t width, nk_size_t depth) {
1963
+ #if NK_TARGET_SMEF64
1964
+ return nk_dots_packed_size_f64_smef64(width, depth);
1965
+ #elif NK_TARGET_SKYLAKE
1966
+ return nk_dots_packed_size_f64_skylake(width, depth);
1967
+ #elif NK_TARGET_HASWELL
1968
+ return nk_dots_packed_size_f64_haswell(width, depth);
1969
+ #elif NK_TARGET_NEON
1970
+ return nk_dots_packed_size_f64_neon(width, depth);
1971
+ #elif NK_TARGET_POWERVSX
1972
+ return nk_dots_packed_size_f64_powervsx(width, depth);
1973
+ #elif NK_TARGET_RVV
1974
+ return nk_dots_packed_size_f64_rvv(width, depth);
1975
+ #elif NK_TARGET_V128RELAXED
1976
+ return nk_dots_packed_size_f64_v128relaxed(width, depth);
1977
+ #else
1978
+ return nk_dots_packed_size_f64_serial(width, depth);
1979
+ #endif
1980
+ }
1981
+
1982
+ NK_PUBLIC void nk_dots_pack_f64(nk_f64_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
1983
+ void *b_packed) {
1984
+ #if NK_TARGET_SMEF64
1985
+ nk_dots_pack_f64_smef64(b, width, depth, b_stride, b_packed);
1986
+ #elif NK_TARGET_SKYLAKE
1987
+ nk_dots_pack_f64_skylake(b, width, depth, b_stride, b_packed);
1988
+ #elif NK_TARGET_HASWELL
1989
+ nk_dots_pack_f64_haswell(b, width, depth, b_stride, b_packed);
1990
+ #elif NK_TARGET_NEON
1991
+ nk_dots_pack_f64_neon(b, width, depth, b_stride, b_packed);
1992
+ #elif NK_TARGET_POWERVSX
1993
+ nk_dots_pack_f64_powervsx(b, width, depth, b_stride, b_packed);
1994
+ #elif NK_TARGET_RVV
1995
+ nk_dots_pack_f64_rvv(b, width, depth, b_stride, b_packed);
1996
+ #elif NK_TARGET_V128RELAXED
1997
+ nk_dots_pack_f64_v128relaxed(b, width, depth, b_stride, b_packed);
1998
+ #else
1999
+ nk_dots_pack_f64_serial(b, width, depth, b_stride, b_packed);
2000
+ #endif
2001
+ }
2002
+
2003
+ NK_PUBLIC void nk_dots_packed_f64(nk_f64_t const *a, void const *b_packed, nk_f64_t *c, nk_size_t height,
2004
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2005
+ #if NK_TARGET_SMEF64
2006
+ nk_dots_packed_f64_smef64(a, b_packed, c, height, width, depth, a_stride, c_stride);
2007
+ #elif NK_TARGET_SKYLAKE
2008
+ nk_dots_packed_f64_skylake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2009
+ #elif NK_TARGET_HASWELL
2010
+ nk_dots_packed_f64_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2011
+ #elif NK_TARGET_NEON
2012
+ nk_dots_packed_f64_neon(a, b_packed, c, height, width, depth, a_stride, c_stride);
2013
+ #elif NK_TARGET_POWERVSX
2014
+ nk_dots_packed_f64_powervsx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2015
+ #elif NK_TARGET_RVV
2016
+ nk_dots_packed_f64_rvv(a, b_packed, c, height, width, depth, a_stride, c_stride);
2017
+ #elif NK_TARGET_V128RELAXED
2018
+ nk_dots_packed_f64_v128relaxed(a, b_packed, c, height, width, depth, a_stride, c_stride);
2019
+ #else
2020
+ nk_dots_packed_f64_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2021
+ #endif
2022
+ }
2023
+
2024
+ NK_PUBLIC nk_size_t nk_dots_packed_size_f16(nk_size_t width, nk_size_t depth) {
2025
+ #if NK_TARGET_GRANITEAMX
2026
+ return nk_dots_packed_size_f16_graniteamx(width, depth);
2027
+ #elif NK_TARGET_SME
2028
+ return nk_dots_packed_size_f16_sme(width, depth);
2029
+ #elif NK_TARGET_NEONFHM
2030
+ return nk_dots_packed_size_f16_neonfhm(width, depth);
2031
+ #elif NK_TARGET_NEON
2032
+ return nk_dots_packed_size_f16_neon(width, depth);
2033
+ #elif NK_TARGET_SKYLAKE
2034
+ return nk_dots_packed_size_f16_skylake(width, depth);
2035
+ #elif NK_TARGET_HASWELL
2036
+ return nk_dots_packed_size_f16_haswell(width, depth);
2037
+ #elif NK_TARGET_POWERVSX
2038
+ return nk_dots_packed_size_f16_powervsx(width, depth);
2039
+ #elif NK_TARGET_RVV
2040
+ return nk_dots_packed_size_f16_rvv(width, depth);
2041
+ #else
2042
+ return nk_dots_packed_size_f16_serial(width, depth);
2043
+ #endif
2044
+ }
2045
+
2046
+ NK_PUBLIC void nk_dots_pack_f16(nk_f16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
2047
+ void *b_packed) {
2048
+ #if NK_TARGET_GRANITEAMX
2049
+ nk_dots_pack_f16_graniteamx(b, width, depth, b_stride, b_packed);
2050
+ #elif NK_TARGET_SME
2051
+ nk_dots_pack_f16_sme(b, width, depth, b_stride, b_packed);
2052
+ #elif NK_TARGET_NEONFHM
2053
+ nk_dots_pack_f16_neonfhm(b, width, depth, b_stride, b_packed);
2054
+ #elif NK_TARGET_NEON
2055
+ nk_dots_pack_f16_neon(b, width, depth, b_stride, b_packed);
2056
+ #elif NK_TARGET_SKYLAKE
2057
+ nk_dots_pack_f16_skylake(b, width, depth, b_stride, b_packed);
2058
+ #elif NK_TARGET_HASWELL
2059
+ nk_dots_pack_f16_haswell(b, width, depth, b_stride, b_packed);
2060
+ #elif NK_TARGET_POWERVSX
2061
+ nk_dots_pack_f16_powervsx(b, width, depth, b_stride, b_packed);
2062
+ #elif NK_TARGET_RVV
2063
+ nk_dots_pack_f16_rvv(b, width, depth, b_stride, b_packed);
2064
+ #else
2065
+ nk_dots_pack_f16_serial(b, width, depth, b_stride, b_packed);
2066
+ #endif
2067
+ }
2068
+
2069
+ NK_PUBLIC void nk_dots_packed_f16(nk_f16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
2070
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2071
+ #if NK_TARGET_GRANITEAMX
2072
+ nk_dots_packed_f16_graniteamx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2073
+ #elif NK_TARGET_SME
2074
+ nk_dots_packed_f16_sme(a, b_packed, c, height, width, depth, a_stride, c_stride);
2075
+ #elif NK_TARGET_NEONFHM
2076
+ nk_dots_packed_f16_neonfhm(a, b_packed, c, height, width, depth, a_stride, c_stride);
2077
+ #elif NK_TARGET_NEON
2078
+ nk_dots_packed_f16_neon(a, b_packed, c, height, width, depth, a_stride, c_stride);
2079
+ #elif NK_TARGET_SKYLAKE
2080
+ nk_dots_packed_f16_skylake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2081
+ #elif NK_TARGET_HASWELL
2082
+ nk_dots_packed_f16_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2083
+ #elif NK_TARGET_POWERVSX
2084
+ nk_dots_packed_f16_powervsx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2085
+ #elif NK_TARGET_RVV
2086
+ nk_dots_packed_f16_rvv(a, b_packed, c, height, width, depth, a_stride, c_stride);
2087
+ #else
2088
+ nk_dots_packed_f16_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2089
+ #endif
2090
+ }
2091
+
2092
+ NK_PUBLIC nk_size_t nk_dots_packed_size_bf16(nk_size_t width, nk_size_t depth) {
2093
+ #if NK_TARGET_SME
2094
+ return nk_dots_packed_size_bf16_sme(width, depth);
2095
+ #elif NK_TARGET_SAPPHIREAMX
2096
+ return nk_dots_packed_size_bf16_sapphireamx(width, depth);
2097
+ #elif NK_TARGET_NEONBFDOT
2098
+ return nk_dots_packed_size_bf16_neonbfdot(width, depth);
2099
+ #elif NK_TARGET_GENOA
2100
+ return nk_dots_packed_size_bf16_genoa(width, depth);
2101
+ #elif NK_TARGET_SKYLAKE
2102
+ return nk_dots_packed_size_bf16_skylake(width, depth);
2103
+ #elif NK_TARGET_HASWELL
2104
+ return nk_dots_packed_size_bf16_haswell(width, depth);
2105
+ #elif NK_TARGET_POWERVSX
2106
+ return nk_dots_packed_size_bf16_powervsx(width, depth);
2107
+ #elif NK_TARGET_RVV
2108
+ return nk_dots_packed_size_bf16_rvv(width, depth);
2109
+ #elif NK_TARGET_V128RELAXED
2110
+ return nk_dots_packed_size_bf16_v128relaxed(width, depth);
2111
+ #else
2112
+ return nk_dots_packed_size_bf16_serial(width, depth);
2113
+ #endif
2114
+ }
2115
+
2116
+ NK_PUBLIC void nk_dots_pack_bf16(nk_bf16_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
2117
+ void *b_packed) {
2118
+ #if NK_TARGET_SME
2119
+ nk_dots_pack_bf16_sme(b, width, depth, b_stride, b_packed);
2120
+ #elif NK_TARGET_SAPPHIREAMX
2121
+ nk_dots_pack_bf16_sapphireamx(b, width, depth, b_stride, b_packed);
2122
+ #elif NK_TARGET_NEONBFDOT
2123
+ nk_dots_pack_bf16_neonbfdot(b, width, depth, b_stride, b_packed);
2124
+ #elif NK_TARGET_GENOA
2125
+ nk_dots_pack_bf16_genoa(b, width, depth, b_stride, b_packed);
2126
+ #elif NK_TARGET_SKYLAKE
2127
+ nk_dots_pack_bf16_skylake(b, width, depth, b_stride, b_packed);
2128
+ #elif NK_TARGET_HASWELL
2129
+ nk_dots_pack_bf16_haswell(b, width, depth, b_stride, b_packed);
2130
+ #elif NK_TARGET_POWERVSX
2131
+ nk_dots_pack_bf16_powervsx(b, width, depth, b_stride, b_packed);
2132
+ #elif NK_TARGET_RVV
2133
+ nk_dots_pack_bf16_rvv(b, width, depth, b_stride, b_packed);
2134
+ #elif NK_TARGET_V128RELAXED
2135
+ nk_dots_pack_bf16_v128relaxed(b, width, depth, b_stride, b_packed);
2136
+ #else
2137
+ nk_dots_pack_bf16_serial(b, width, depth, b_stride, b_packed);
2138
+ #endif
2139
+ }
2140
+
2141
+ NK_PUBLIC void nk_dots_packed_bf16(nk_bf16_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
2142
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2143
+ #if NK_TARGET_SME
2144
+ nk_dots_packed_bf16_sme(a, b_packed, c, height, width, depth, a_stride, c_stride);
2145
+ #elif NK_TARGET_SAPPHIREAMX
2146
+ nk_dots_packed_bf16_sapphireamx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2147
+ #elif NK_TARGET_NEONBFDOT
2148
+ nk_dots_packed_bf16_neonbfdot(a, b_packed, c, height, width, depth, a_stride, c_stride);
2149
+ #elif NK_TARGET_GENOA
2150
+ nk_dots_packed_bf16_genoa(a, b_packed, c, height, width, depth, a_stride, c_stride);
2151
+ #elif NK_TARGET_SKYLAKE
2152
+ nk_dots_packed_bf16_skylake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2153
+ #elif NK_TARGET_HASWELL
2154
+ nk_dots_packed_bf16_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2155
+ #elif NK_TARGET_POWERVSX
2156
+ nk_dots_packed_bf16_powervsx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2157
+ #elif NK_TARGET_RVV
2158
+ nk_dots_packed_bf16_rvv(a, b_packed, c, height, width, depth, a_stride, c_stride);
2159
+ #elif NK_TARGET_V128RELAXED
2160
+ nk_dots_packed_bf16_v128relaxed(a, b_packed, c, height, width, depth, a_stride, c_stride);
2161
+ #else
2162
+ nk_dots_packed_bf16_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2163
+ #endif
2164
+ }
2165
+
2166
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i8(nk_size_t width, nk_size_t depth) {
2167
+ #if NK_TARGET_SME
2168
+ return nk_dots_packed_size_i8_sme(width, depth);
2169
+ #elif NK_TARGET_SAPPHIREAMX
2170
+ return nk_dots_packed_size_i8_sapphireamx(width, depth);
2171
+ #elif NK_TARGET_NEONSDOT
2172
+ return nk_dots_packed_size_i8_neonsdot(width, depth);
2173
+ #elif NK_TARGET_ICELAKE
2174
+ return nk_dots_packed_size_i8_icelake(width, depth);
2175
+ #elif NK_TARGET_SIERRA
2176
+ return nk_dots_packed_size_i8_sierra(width, depth);
2177
+ #elif NK_TARGET_ALDER
2178
+ return nk_dots_packed_size_i8_alder(width, depth);
2179
+ #elif NK_TARGET_HASWELL
2180
+ return nk_dots_packed_size_i8_haswell(width, depth);
2181
+ #elif NK_TARGET_POWERVSX
2182
+ return nk_dots_packed_size_i8_powervsx(width, depth);
2183
+ #elif NK_TARGET_RVV
2184
+ return nk_dots_packed_size_i8_rvv(width, depth);
2185
+ #elif NK_TARGET_V128RELAXED
2186
+ return nk_dots_packed_size_i8_v128relaxed(width, depth);
2187
+ #else
2188
+ return nk_dots_packed_size_i8_serial(width, depth);
2189
+ #endif
2190
+ }
2191
+
2192
+ NK_PUBLIC void nk_dots_pack_i8(nk_i8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride, void *b_packed) {
2193
+ #if NK_TARGET_SME
2194
+ nk_dots_pack_i8_sme(b, width, depth, b_stride, b_packed);
2195
+ #elif NK_TARGET_SAPPHIREAMX
2196
+ nk_dots_pack_i8_sapphireamx(b, width, depth, b_stride, b_packed);
2197
+ #elif NK_TARGET_NEONSDOT
2198
+ nk_dots_pack_i8_neonsdot(b, width, depth, b_stride, b_packed);
2199
+ #elif NK_TARGET_ICELAKE
2200
+ nk_dots_pack_i8_icelake(b, width, depth, b_stride, b_packed);
2201
+ #elif NK_TARGET_SIERRA
2202
+ nk_dots_pack_i8_sierra(b, width, depth, b_stride, b_packed);
2203
+ #elif NK_TARGET_ALDER
2204
+ nk_dots_pack_i8_alder(b, width, depth, b_stride, b_packed);
2205
+ #elif NK_TARGET_HASWELL
2206
+ nk_dots_pack_i8_haswell(b, width, depth, b_stride, b_packed);
2207
+ #elif NK_TARGET_POWERVSX
2208
+ nk_dots_pack_i8_powervsx(b, width, depth, b_stride, b_packed);
2209
+ #elif NK_TARGET_RVV
2210
+ nk_dots_pack_i8_rvv(b, width, depth, b_stride, b_packed);
2211
+ #elif NK_TARGET_V128RELAXED
2212
+ nk_dots_pack_i8_v128relaxed(b, width, depth, b_stride, b_packed);
2213
+ #else
2214
+ nk_dots_pack_i8_serial(b, width, depth, b_stride, b_packed);
2215
+ #endif
2216
+ }
2217
+
2218
+ NK_PUBLIC void nk_dots_packed_i8(nk_i8_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height, nk_size_t width,
2219
+ nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2220
+ #if NK_TARGET_SME
2221
+ nk_dots_packed_i8_sme(a, b_packed, c, height, width, depth, a_stride, c_stride);
2222
+ #elif NK_TARGET_SAPPHIREAMX
2223
+ nk_dots_packed_i8_sapphireamx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2224
+ #elif NK_TARGET_NEONSDOT
2225
+ nk_dots_packed_i8_neonsdot(a, b_packed, c, height, width, depth, a_stride, c_stride);
2226
+ #elif NK_TARGET_ICELAKE
2227
+ nk_dots_packed_i8_icelake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2228
+ #elif NK_TARGET_SIERRA
2229
+ nk_dots_packed_i8_sierra(a, b_packed, c, height, width, depth, a_stride, c_stride);
2230
+ #elif NK_TARGET_ALDER
2231
+ nk_dots_packed_i8_alder(a, b_packed, c, height, width, depth, a_stride, c_stride);
2232
+ #elif NK_TARGET_HASWELL
2233
+ nk_dots_packed_i8_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2234
+ #elif NK_TARGET_POWERVSX
2235
+ nk_dots_packed_i8_powervsx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2236
+ #elif NK_TARGET_RVV
2237
+ nk_dots_packed_i8_rvv(a, b_packed, c, height, width, depth, a_stride, c_stride);
2238
+ #elif NK_TARGET_V128RELAXED
2239
+ nk_dots_packed_i8_v128relaxed(a, b_packed, c, height, width, depth, a_stride, c_stride);
2240
+ #else
2241
+ nk_dots_packed_i8_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2242
+ #endif
2243
+ }
2244
+
2245
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u8(nk_size_t width, nk_size_t depth) {
2246
+ #if NK_TARGET_SME
2247
+ return nk_dots_packed_size_u8_sme(width, depth);
2248
+ #elif NK_TARGET_SAPPHIREAMX
2249
+ return nk_dots_packed_size_u8_sapphireamx(width, depth);
2250
+ #elif NK_TARGET_NEONSDOT
2251
+ return nk_dots_packed_size_u8_neonsdot(width, depth);
2252
+ #elif NK_TARGET_ICELAKE
2253
+ return nk_dots_packed_size_u8_icelake(width, depth);
2254
+ #elif NK_TARGET_SIERRA
2255
+ return nk_dots_packed_size_u8_sierra(width, depth);
2256
+ #elif NK_TARGET_ALDER
2257
+ return nk_dots_packed_size_u8_alder(width, depth);
2258
+ #elif NK_TARGET_HASWELL
2259
+ return nk_dots_packed_size_u8_haswell(width, depth);
2260
+ #elif NK_TARGET_POWERVSX
2261
+ return nk_dots_packed_size_u8_powervsx(width, depth);
2262
+ #elif NK_TARGET_RVV
2263
+ return nk_dots_packed_size_u8_rvv(width, depth);
2264
+ #elif NK_TARGET_V128RELAXED
2265
+ return nk_dots_packed_size_u8_v128relaxed(width, depth);
2266
+ #else
2267
+ return nk_dots_packed_size_u8_serial(width, depth);
2268
+ #endif
2269
+ }
2270
+
2271
+ NK_PUBLIC void nk_dots_pack_u8(nk_u8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride, void *b_packed) {
2272
+ #if NK_TARGET_SME
2273
+ nk_dots_pack_u8_sme(b, width, depth, b_stride, b_packed);
2274
+ #elif NK_TARGET_SAPPHIREAMX
2275
+ nk_dots_pack_u8_sapphireamx(b, width, depth, b_stride, b_packed);
2276
+ #elif NK_TARGET_NEONSDOT
2277
+ nk_dots_pack_u8_neonsdot(b, width, depth, b_stride, b_packed);
2278
+ #elif NK_TARGET_ICELAKE
2279
+ nk_dots_pack_u8_icelake(b, width, depth, b_stride, b_packed);
2280
+ #elif NK_TARGET_SIERRA
2281
+ nk_dots_pack_u8_sierra(b, width, depth, b_stride, b_packed);
2282
+ #elif NK_TARGET_ALDER
2283
+ nk_dots_pack_u8_alder(b, width, depth, b_stride, b_packed);
2284
+ #elif NK_TARGET_HASWELL
2285
+ nk_dots_pack_u8_haswell(b, width, depth, b_stride, b_packed);
2286
+ #elif NK_TARGET_POWERVSX
2287
+ nk_dots_pack_u8_powervsx(b, width, depth, b_stride, b_packed);
2288
+ #elif NK_TARGET_RVV
2289
+ nk_dots_pack_u8_rvv(b, width, depth, b_stride, b_packed);
2290
+ #elif NK_TARGET_V128RELAXED
2291
+ nk_dots_pack_u8_v128relaxed(b, width, depth, b_stride, b_packed);
2292
+ #else
2293
+ nk_dots_pack_u8_serial(b, width, depth, b_stride, b_packed);
2294
+ #endif
2295
+ }
2296
+
2297
+ NK_PUBLIC void nk_dots_packed_u8(nk_u8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height, nk_size_t width,
2298
+ nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2299
+ #if NK_TARGET_SME
2300
+ nk_dots_packed_u8_sme(a, b_packed, c, height, width, depth, a_stride, c_stride);
2301
+ #elif NK_TARGET_SAPPHIREAMX
2302
+ nk_dots_packed_u8_sapphireamx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2303
+ #elif NK_TARGET_NEONSDOT
2304
+ nk_dots_packed_u8_neonsdot(a, b_packed, c, height, width, depth, a_stride, c_stride);
2305
+ #elif NK_TARGET_ICELAKE
2306
+ nk_dots_packed_u8_icelake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2307
+ #elif NK_TARGET_SIERRA
2308
+ nk_dots_packed_u8_sierra(a, b_packed, c, height, width, depth, a_stride, c_stride);
2309
+ #elif NK_TARGET_ALDER
2310
+ nk_dots_packed_u8_alder(a, b_packed, c, height, width, depth, a_stride, c_stride);
2311
+ #elif NK_TARGET_HASWELL
2312
+ nk_dots_packed_u8_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2313
+ #elif NK_TARGET_POWERVSX
2314
+ nk_dots_packed_u8_powervsx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2315
+ #elif NK_TARGET_RVV
2316
+ nk_dots_packed_u8_rvv(a, b_packed, c, height, width, depth, a_stride, c_stride);
2317
+ #elif NK_TARGET_V128RELAXED
2318
+ nk_dots_packed_u8_v128relaxed(a, b_packed, c, height, width, depth, a_stride, c_stride);
2319
+ #else
2320
+ nk_dots_packed_u8_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2321
+ #endif
2322
+ }
2323
+
2324
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e4m3(nk_size_t width, nk_size_t depth) {
2325
+ #if NK_TARGET_SME
2326
+ return nk_dots_packed_size_e4m3_sme(width, depth);
2327
+ #elif NK_TARGET_SAPPHIREAMX
2328
+ return nk_dots_packed_size_e4m3_sapphireamx(width, depth);
2329
+ #elif NK_TARGET_NEONFP8
2330
+ return nk_dots_packed_size_e4m3_neonfp8(width, depth);
2331
+ #elif NK_TARGET_NEONFHM
2332
+ return nk_dots_packed_size_e4m3_neonfhm(width, depth);
2333
+ #elif NK_TARGET_DIAMOND
2334
+ return nk_dots_packed_size_e4m3_diamond(width, depth);
2335
+ #elif NK_TARGET_GENOA
2336
+ return nk_dots_packed_size_e4m3_genoa(width, depth);
2337
+ #elif NK_TARGET_SKYLAKE
2338
+ return nk_dots_packed_size_e4m3_skylake(width, depth);
2339
+ #elif NK_TARGET_HASWELL
2340
+ return nk_dots_packed_size_e4m3_haswell(width, depth);
2341
+ #elif NK_TARGET_RVV
2342
+ return nk_dots_packed_size_e4m3_rvv(width, depth);
2343
+ #elif NK_TARGET_V128RELAXED
2344
+ return nk_dots_packed_size_e4m3_v128relaxed(width, depth);
2345
+ #else
2346
+ return nk_dots_packed_size_e4m3_serial(width, depth);
2347
+ #endif
2348
+ }
2349
+
2350
+ NK_PUBLIC void nk_dots_pack_e4m3(nk_e4m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
2351
+ void *b_packed) {
2352
+ #if NK_TARGET_SME
2353
+ nk_dots_pack_e4m3_sme(b, width, depth, b_stride, b_packed);
2354
+ #elif NK_TARGET_SAPPHIREAMX
2355
+ nk_dots_pack_e4m3_sapphireamx(b, width, depth, b_stride, b_packed);
2356
+ #elif NK_TARGET_NEONFP8
2357
+ nk_dots_pack_e4m3_neonfp8(b, width, depth, b_stride, b_packed);
2358
+ #elif NK_TARGET_NEONFHM
2359
+ nk_dots_pack_e4m3_neonfhm(b, width, depth, b_stride, b_packed);
2360
+ #elif NK_TARGET_DIAMOND
2361
+ nk_dots_pack_e4m3_diamond(b, width, depth, b_stride, b_packed);
2362
+ #elif NK_TARGET_GENOA
2363
+ nk_dots_pack_e4m3_genoa(b, width, depth, b_stride, b_packed);
2364
+ #elif NK_TARGET_SKYLAKE
2365
+ nk_dots_pack_e4m3_skylake(b, width, depth, b_stride, b_packed);
2366
+ #elif NK_TARGET_HASWELL
2367
+ nk_dots_pack_e4m3_haswell(b, width, depth, b_stride, b_packed);
2368
+ #elif NK_TARGET_RVV
2369
+ nk_dots_pack_e4m3_rvv(b, width, depth, b_stride, b_packed);
2370
+ #elif NK_TARGET_V128RELAXED
2371
+ nk_dots_pack_e4m3_v128relaxed(b, width, depth, b_stride, b_packed);
2372
+ #else
2373
+ nk_dots_pack_e4m3_serial(b, width, depth, b_stride, b_packed);
2374
+ #endif
2375
+ }
2376
+
2377
+ NK_PUBLIC void nk_dots_packed_e4m3(nk_e4m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
2378
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2379
+ #if NK_TARGET_SME
2380
+ nk_dots_packed_e4m3_sme(a, b_packed, c, height, width, depth, a_stride, c_stride);
2381
+ #elif NK_TARGET_SAPPHIREAMX
2382
+ nk_dots_packed_e4m3_sapphireamx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2383
+ #elif NK_TARGET_NEONFP8
2384
+ nk_dots_packed_e4m3_neonfp8(a, b_packed, c, height, width, depth, a_stride, c_stride);
2385
+ #elif NK_TARGET_NEONFHM
2386
+ nk_dots_packed_e4m3_neonfhm(a, b_packed, c, height, width, depth, a_stride, c_stride);
2387
+ #elif NK_TARGET_DIAMOND
2388
+ nk_dots_packed_e4m3_diamond(a, b_packed, c, height, width, depth, a_stride, c_stride);
2389
+ #elif NK_TARGET_GENOA
2390
+ nk_dots_packed_e4m3_genoa(a, b_packed, c, height, width, depth, a_stride, c_stride);
2391
+ #elif NK_TARGET_SKYLAKE
2392
+ nk_dots_packed_e4m3_skylake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2393
+ #elif NK_TARGET_HASWELL
2394
+ nk_dots_packed_e4m3_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2395
+ #elif NK_TARGET_RVV
2396
+ nk_dots_packed_e4m3_rvv(a, b_packed, c, height, width, depth, a_stride, c_stride);
2397
+ #elif NK_TARGET_V128RELAXED
2398
+ nk_dots_packed_e4m3_v128relaxed(a, b_packed, c, height, width, depth, a_stride, c_stride);
2399
+ #else
2400
+ nk_dots_packed_e4m3_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2401
+ #endif
2402
+ }
2403
+
2404
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e5m2(nk_size_t width, nk_size_t depth) {
2405
+ #if NK_TARGET_SME
2406
+ return nk_dots_packed_size_e5m2_sme(width, depth);
2407
+ #elif NK_TARGET_SAPPHIREAMX
2408
+ return nk_dots_packed_size_e5m2_sapphireamx(width, depth);
2409
+ #elif NK_TARGET_NEONFP8
2410
+ return nk_dots_packed_size_e5m2_neonfp8(width, depth);
2411
+ #elif NK_TARGET_NEONFHM
2412
+ return nk_dots_packed_size_e5m2_neonfhm(width, depth);
2413
+ #elif NK_TARGET_DIAMOND
2414
+ return nk_dots_packed_size_e5m2_diamond(width, depth);
2415
+ #elif NK_TARGET_GENOA
2416
+ return nk_dots_packed_size_e5m2_genoa(width, depth);
2417
+ #elif NK_TARGET_SKYLAKE
2418
+ return nk_dots_packed_size_e5m2_skylake(width, depth);
2419
+ #elif NK_TARGET_HASWELL
2420
+ return nk_dots_packed_size_e5m2_haswell(width, depth);
2421
+ #elif NK_TARGET_RVV
2422
+ return nk_dots_packed_size_e5m2_rvv(width, depth);
2423
+ #elif NK_TARGET_V128RELAXED
2424
+ return nk_dots_packed_size_e5m2_v128relaxed(width, depth);
2425
+ #else
2426
+ return nk_dots_packed_size_e5m2_serial(width, depth);
2427
+ #endif
2428
+ }
2429
+
2430
+ NK_PUBLIC void nk_dots_pack_e5m2(nk_e5m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
2431
+ void *b_packed) {
2432
+ #if NK_TARGET_SME
2433
+ nk_dots_pack_e5m2_sme(b, width, depth, b_stride, b_packed);
2434
+ #elif NK_TARGET_SAPPHIREAMX
2435
+ nk_dots_pack_e5m2_sapphireamx(b, width, depth, b_stride, b_packed);
2436
+ #elif NK_TARGET_NEONFP8
2437
+ nk_dots_pack_e5m2_neonfp8(b, width, depth, b_stride, b_packed);
2438
+ #elif NK_TARGET_NEONFHM
2439
+ nk_dots_pack_e5m2_neonfhm(b, width, depth, b_stride, b_packed);
2440
+ #elif NK_TARGET_DIAMOND
2441
+ nk_dots_pack_e5m2_diamond(b, width, depth, b_stride, b_packed);
2442
+ #elif NK_TARGET_GENOA
2443
+ nk_dots_pack_e5m2_genoa(b, width, depth, b_stride, b_packed);
2444
+ #elif NK_TARGET_SKYLAKE
2445
+ nk_dots_pack_e5m2_skylake(b, width, depth, b_stride, b_packed);
2446
+ #elif NK_TARGET_HASWELL
2447
+ nk_dots_pack_e5m2_haswell(b, width, depth, b_stride, b_packed);
2448
+ #elif NK_TARGET_RVV
2449
+ nk_dots_pack_e5m2_rvv(b, width, depth, b_stride, b_packed);
2450
+ #elif NK_TARGET_V128RELAXED
2451
+ nk_dots_pack_e5m2_v128relaxed(b, width, depth, b_stride, b_packed);
2452
+ #else
2453
+ nk_dots_pack_e5m2_serial(b, width, depth, b_stride, b_packed);
2454
+ #endif
2455
+ }
2456
+
2457
+ NK_PUBLIC void nk_dots_packed_e5m2(nk_e5m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
2458
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2459
+ #if NK_TARGET_SME
2460
+ nk_dots_packed_e5m2_sme(a, b_packed, c, height, width, depth, a_stride, c_stride);
2461
+ #elif NK_TARGET_SAPPHIREAMX
2462
+ nk_dots_packed_e5m2_sapphireamx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2463
+ #elif NK_TARGET_NEONFP8
2464
+ nk_dots_packed_e5m2_neonfp8(a, b_packed, c, height, width, depth, a_stride, c_stride);
2465
+ #elif NK_TARGET_NEONFHM
2466
+ nk_dots_packed_e5m2_neonfhm(a, b_packed, c, height, width, depth, a_stride, c_stride);
2467
+ #elif NK_TARGET_DIAMOND
2468
+ nk_dots_packed_e5m2_diamond(a, b_packed, c, height, width, depth, a_stride, c_stride);
2469
+ #elif NK_TARGET_GENOA
2470
+ nk_dots_packed_e5m2_genoa(a, b_packed, c, height, width, depth, a_stride, c_stride);
2471
+ #elif NK_TARGET_SKYLAKE
2472
+ nk_dots_packed_e5m2_skylake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2473
+ #elif NK_TARGET_HASWELL
2474
+ nk_dots_packed_e5m2_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2475
+ #elif NK_TARGET_RVV
2476
+ nk_dots_packed_e5m2_rvv(a, b_packed, c, height, width, depth, a_stride, c_stride);
2477
+ #elif NK_TARGET_V128RELAXED
2478
+ nk_dots_packed_e5m2_v128relaxed(a, b_packed, c, height, width, depth, a_stride, c_stride);
2479
+ #else
2480
+ nk_dots_packed_e5m2_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2481
+ #endif
2482
+ }
2483
+
2484
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e2m3(nk_size_t width, nk_size_t depth) {
2485
+ #if NK_TARGET_SME
2486
+ return nk_dots_packed_size_e2m3_sme(width, depth);
2487
+ #elif NK_TARGET_SAPPHIREAMX
2488
+ return nk_dots_packed_size_e2m3_sapphireamx(width, depth);
2489
+ #elif NK_TARGET_NEONFP8
2490
+ return nk_dots_packed_size_e2m3_neonfp8(width, depth);
2491
+ #elif NK_TARGET_SKYLAKE
2492
+ return nk_dots_packed_size_e2m3_skylake(width, depth);
2493
+ #elif NK_TARGET_SIERRA
2494
+ return nk_dots_packed_size_e2m3_sierra(width, depth);
2495
+ #elif NK_TARGET_ALDER
2496
+ return nk_dots_packed_size_e2m3_alder(width, depth);
2497
+ #elif NK_TARGET_HASWELL
2498
+ return nk_dots_packed_size_e2m3_haswell(width, depth);
2499
+ #elif NK_TARGET_RVV
2500
+ return nk_dots_packed_size_e2m3_rvv(width, depth);
2501
+ #elif NK_TARGET_V128RELAXED
2502
+ return nk_dots_packed_size_e2m3_v128relaxed(width, depth);
2503
+ #else
2504
+ return nk_dots_packed_size_e2m3_serial(width, depth);
2505
+ #endif
2506
+ }
2507
+
2508
+ NK_PUBLIC void nk_dots_pack_e2m3(nk_e2m3_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
2509
+ void *b_packed) {
2510
+ #if NK_TARGET_SME
2511
+ nk_dots_pack_e2m3_sme(b, width, depth, b_stride, b_packed);
2512
+ #elif NK_TARGET_SAPPHIREAMX
2513
+ nk_dots_pack_e2m3_sapphireamx(b, width, depth, b_stride, b_packed);
2514
+ #elif NK_TARGET_NEONFP8
2515
+ nk_dots_pack_e2m3_neonfp8(b, width, depth, b_stride, b_packed);
2516
+ #elif NK_TARGET_SKYLAKE
2517
+ nk_dots_pack_e2m3_skylake(b, width, depth, b_stride, b_packed);
2518
+ #elif NK_TARGET_SIERRA
2519
+ nk_dots_pack_e2m3_sierra(b, width, depth, b_stride, b_packed);
2520
+ #elif NK_TARGET_ALDER
2521
+ nk_dots_pack_e2m3_alder(b, width, depth, b_stride, b_packed);
2522
+ #elif NK_TARGET_HASWELL
2523
+ nk_dots_pack_e2m3_haswell(b, width, depth, b_stride, b_packed);
2524
+ #elif NK_TARGET_RVV
2525
+ nk_dots_pack_e2m3_rvv(b, width, depth, b_stride, b_packed);
2526
+ #elif NK_TARGET_V128RELAXED
2527
+ nk_dots_pack_e2m3_v128relaxed(b, width, depth, b_stride, b_packed);
2528
+ #else
2529
+ nk_dots_pack_e2m3_serial(b, width, depth, b_stride, b_packed);
2530
+ #endif
2531
+ }
2532
+
2533
+ NK_PUBLIC void nk_dots_packed_e2m3(nk_e2m3_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
2534
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2535
+ #if NK_TARGET_SME
2536
+ nk_dots_packed_e2m3_sme(a, b_packed, c, height, width, depth, a_stride, c_stride);
2537
+ #elif NK_TARGET_SAPPHIREAMX
2538
+ nk_dots_packed_e2m3_sapphireamx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2539
+ #elif NK_TARGET_NEONFP8
2540
+ nk_dots_packed_e2m3_neonfp8(a, b_packed, c, height, width, depth, a_stride, c_stride);
2541
+ #elif NK_TARGET_SKYLAKE
2542
+ nk_dots_packed_e2m3_skylake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2543
+ #elif NK_TARGET_SIERRA
2544
+ nk_dots_packed_e2m3_sierra(a, b_packed, c, height, width, depth, a_stride, c_stride);
2545
+ #elif NK_TARGET_ALDER
2546
+ nk_dots_packed_e2m3_alder(a, b_packed, c, height, width, depth, a_stride, c_stride);
2547
+ #elif NK_TARGET_HASWELL
2548
+ nk_dots_packed_e2m3_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2549
+ #elif NK_TARGET_RVV
2550
+ nk_dots_packed_e2m3_rvv(a, b_packed, c, height, width, depth, a_stride, c_stride);
2551
+ #elif NK_TARGET_V128RELAXED
2552
+ nk_dots_packed_e2m3_v128relaxed(a, b_packed, c, height, width, depth, a_stride, c_stride);
2553
+ #else
2554
+ nk_dots_packed_e2m3_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2555
+ #endif
2556
+ }
2557
+
2558
+ NK_PUBLIC nk_size_t nk_dots_packed_size_e3m2(nk_size_t width, nk_size_t depth) {
2559
+ #if NK_TARGET_SME
2560
+ return nk_dots_packed_size_e3m2_sme(width, depth);
2561
+ #elif NK_TARGET_SAPPHIREAMX
2562
+ return nk_dots_packed_size_e3m2_sapphireamx(width, depth);
2563
+ #elif NK_TARGET_NEONFP8
2564
+ return nk_dots_packed_size_e3m2_neonfp8(width, depth);
2565
+ #elif NK_TARGET_SKYLAKE
2566
+ return nk_dots_packed_size_e3m2_skylake(width, depth);
2567
+ #elif NK_TARGET_HASWELL
2568
+ return nk_dots_packed_size_e3m2_haswell(width, depth);
2569
+ #elif NK_TARGET_RVV
2570
+ return nk_dots_packed_size_e3m2_rvv(width, depth);
2571
+ #else
2572
+ return nk_dots_packed_size_e3m2_serial(width, depth);
2573
+ #endif
2574
+ }
2575
+
2576
+ NK_PUBLIC void nk_dots_pack_e3m2(nk_e3m2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
2577
+ void *b_packed) {
2578
+ #if NK_TARGET_SME
2579
+ nk_dots_pack_e3m2_sme(b, width, depth, b_stride, b_packed);
2580
+ #elif NK_TARGET_SAPPHIREAMX
2581
+ nk_dots_pack_e3m2_sapphireamx(b, width, depth, b_stride, b_packed);
2582
+ #elif NK_TARGET_NEONFP8
2583
+ nk_dots_pack_e3m2_neonfp8(b, width, depth, b_stride, b_packed);
2584
+ #elif NK_TARGET_SKYLAKE
2585
+ nk_dots_pack_e3m2_skylake(b, width, depth, b_stride, b_packed);
2586
+ #elif NK_TARGET_HASWELL
2587
+ nk_dots_pack_e3m2_haswell(b, width, depth, b_stride, b_packed);
2588
+ #elif NK_TARGET_RVV
2589
+ nk_dots_pack_e3m2_rvv(b, width, depth, b_stride, b_packed);
2590
+ #else
2591
+ nk_dots_pack_e3m2_serial(b, width, depth, b_stride, b_packed);
2592
+ #endif
2593
+ }
2594
+
2595
+ NK_PUBLIC void nk_dots_packed_e3m2(nk_e3m2_t const *a, void const *b_packed, nk_f32_t *c, nk_size_t height,
2596
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2597
+ #if NK_TARGET_SME
2598
+ nk_dots_packed_e3m2_sme(a, b_packed, c, height, width, depth, a_stride, c_stride);
2599
+ #elif NK_TARGET_SAPPHIREAMX
2600
+ nk_dots_packed_e3m2_sapphireamx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2601
+ #elif NK_TARGET_NEONFP8
2602
+ nk_dots_packed_e3m2_neonfp8(a, b_packed, c, height, width, depth, a_stride, c_stride);
2603
+ #elif NK_TARGET_SKYLAKE
2604
+ nk_dots_packed_e3m2_skylake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2605
+ #elif NK_TARGET_HASWELL
2606
+ nk_dots_packed_e3m2_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2607
+ #elif NK_TARGET_RVV
2608
+ nk_dots_packed_e3m2_rvv(a, b_packed, c, height, width, depth, a_stride, c_stride);
2609
+ #else
2610
+ nk_dots_packed_e3m2_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2611
+ #endif
2612
+ }
2613
+
2614
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u4(nk_size_t width, nk_size_t depth) {
2615
+ #if NK_TARGET_SME
2616
+ return nk_dots_packed_size_u4_sme(width, depth);
2617
+ #elif NK_TARGET_ICELAKE
2618
+ return nk_dots_packed_size_u4_icelake(width, depth);
2619
+ #elif NK_TARGET_NEONSDOT
2620
+ return nk_dots_packed_size_u4_neonsdot(width, depth);
2621
+ #elif NK_TARGET_HASWELL
2622
+ return nk_dots_packed_size_u4_haswell(width, depth);
2623
+ #elif NK_TARGET_V128RELAXED
2624
+ return nk_dots_packed_size_u4_v128relaxed(width, depth);
2625
+ #else
2626
+ return nk_dots_packed_size_u4_serial(width, depth);
2627
+ #endif
2628
+ }
2629
+
2630
+ NK_PUBLIC void nk_dots_pack_u4(nk_u4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
2631
+ void *b_packed) {
2632
+ #if NK_TARGET_SME
2633
+ nk_dots_pack_u4_sme(b, width, depth, b_stride, b_packed);
2634
+ #elif NK_TARGET_ICELAKE
2635
+ nk_dots_pack_u4_icelake(b, width, depth, b_stride, b_packed);
2636
+ #elif NK_TARGET_NEONSDOT
2637
+ nk_dots_pack_u4_neonsdot(b, width, depth, b_stride, b_packed);
2638
+ #elif NK_TARGET_HASWELL
2639
+ nk_dots_pack_u4_haswell(b, width, depth, b_stride, b_packed);
2640
+ #elif NK_TARGET_V128RELAXED
2641
+ nk_dots_pack_u4_v128relaxed(b, width, depth, b_stride, b_packed);
2642
+ #else
2643
+ nk_dots_pack_u4_serial(b, width, depth, b_stride, b_packed);
2644
+ #endif
2645
+ }
2646
+
2647
+ NK_PUBLIC void nk_dots_packed_u4(nk_u4x2_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
2648
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2649
+ #if NK_TARGET_SME
2650
+ nk_dots_packed_u4_sme(a, b_packed, c, height, width, depth, a_stride, c_stride);
2651
+ #elif NK_TARGET_ICELAKE
2652
+ nk_dots_packed_u4_icelake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2653
+ #elif NK_TARGET_NEONSDOT
2654
+ nk_dots_packed_u4_neonsdot(a, b_packed, c, height, width, depth, a_stride, c_stride);
2655
+ #elif NK_TARGET_HASWELL
2656
+ nk_dots_packed_u4_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2657
+ #elif NK_TARGET_V128RELAXED
2658
+ nk_dots_packed_u4_v128relaxed(a, b_packed, c, height, width, depth, a_stride, c_stride);
2659
+ #else
2660
+ nk_dots_packed_u4_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2661
+ #endif
2662
+ }
2663
+
2664
+ NK_PUBLIC nk_size_t nk_dots_packed_size_u1(nk_size_t width, nk_size_t depth) {
2665
+ #if NK_TARGET_SMEBI32
2666
+ return nk_dots_packed_size_u1_smebi32(width, depth);
2667
+ #elif NK_TARGET_ICELAKE
2668
+ return nk_dots_packed_size_u1_icelake(width, depth);
2669
+ #elif NK_TARGET_HASWELL
2670
+ return nk_dots_packed_size_u1_haswell(width, depth);
2671
+ #elif NK_TARGET_NEON
2672
+ return nk_dots_packed_size_u1_neon(width, depth);
2673
+ #elif NK_TARGET_POWERVSX
2674
+ return nk_dots_packed_size_u1_powervsx(width, depth);
2675
+ #elif NK_TARGET_LOONGSONASX
2676
+ return nk_dots_packed_size_u1_loongsonasx(width, depth);
2677
+ #elif NK_TARGET_V128RELAXED
2678
+ return nk_dots_packed_size_u1_v128relaxed(width, depth);
2679
+ #else
2680
+ return nk_dots_packed_size_u1_serial(width, depth);
2681
+ #endif
2682
+ }
2683
+
2684
+ NK_PUBLIC void nk_dots_pack_u1(nk_u1x8_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
2685
+ void *b_packed) {
2686
+ #if NK_TARGET_SMEBI32
2687
+ nk_dots_pack_u1_smebi32(b, width, depth, b_stride, b_packed);
2688
+ #elif NK_TARGET_ICELAKE
2689
+ nk_dots_pack_u1_icelake(b, width, depth, b_stride, b_packed);
2690
+ #elif NK_TARGET_HASWELL
2691
+ nk_dots_pack_u1_haswell(b, width, depth, b_stride, b_packed);
2692
+ #elif NK_TARGET_NEON
2693
+ nk_dots_pack_u1_neon(b, width, depth, b_stride, b_packed);
2694
+ #elif NK_TARGET_POWERVSX
2695
+ nk_dots_pack_u1_powervsx(b, width, depth, b_stride, b_packed);
2696
+ #elif NK_TARGET_LOONGSONASX
2697
+ nk_dots_pack_u1_loongsonasx(b, width, depth, b_stride, b_packed);
2698
+ #elif NK_TARGET_V128RELAXED
2699
+ nk_dots_pack_u1_v128relaxed(b, width, depth, b_stride, b_packed);
2700
+ #else
2701
+ nk_dots_pack_u1_serial(b, width, depth, b_stride, b_packed);
2702
+ #endif
2703
+ }
2704
+
2705
+ NK_PUBLIC void nk_dots_packed_u1(nk_u1x8_t const *a, void const *b_packed, nk_u32_t *c, nk_size_t height,
2706
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2707
+ #if NK_TARGET_SMEBI32
2708
+ nk_dots_packed_u1_smebi32(a, b_packed, c, height, width, depth, a_stride, c_stride);
2709
+ #elif NK_TARGET_ICELAKE
2710
+ nk_dots_packed_u1_icelake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2711
+ #elif NK_TARGET_HASWELL
2712
+ nk_dots_packed_u1_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2713
+ #elif NK_TARGET_NEON
2714
+ nk_dots_packed_u1_neon(a, b_packed, c, height, width, depth, a_stride, c_stride);
2715
+ #elif NK_TARGET_POWERVSX
2716
+ nk_dots_packed_u1_powervsx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2717
+ #elif NK_TARGET_LOONGSONASX
2718
+ nk_dots_packed_u1_loongsonasx(a, b_packed, c, height, width, depth, a_stride, c_stride);
2719
+ #elif NK_TARGET_V128RELAXED
2720
+ nk_dots_packed_u1_v128relaxed(a, b_packed, c, height, width, depth, a_stride, c_stride);
2721
+ #else
2722
+ nk_dots_packed_u1_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2723
+ #endif
2724
+ }
2725
+
2726
+ NK_PUBLIC nk_size_t nk_dots_packed_size_i4(nk_size_t width, nk_size_t depth) {
2727
+ #if NK_TARGET_SME
2728
+ return nk_dots_packed_size_i4_sme(width, depth);
2729
+ #elif NK_TARGET_ICELAKE
2730
+ return nk_dots_packed_size_i4_icelake(width, depth);
2731
+ #elif NK_TARGET_NEONSDOT
2732
+ return nk_dots_packed_size_i4_neonsdot(width, depth);
2733
+ #elif NK_TARGET_HASWELL
2734
+ return nk_dots_packed_size_i4_haswell(width, depth);
2735
+ #elif NK_TARGET_V128RELAXED
2736
+ return nk_dots_packed_size_i4_v128relaxed(width, depth);
2737
+ #else
2738
+ return nk_dots_packed_size_i4_serial(width, depth);
2739
+ #endif
2740
+ }
2741
+
2742
+ NK_PUBLIC void nk_dots_pack_i4(nk_i4x2_t const *b, nk_size_t width, nk_size_t depth, nk_size_t b_stride,
2743
+ void *b_packed) {
2744
+ #if NK_TARGET_SME
2745
+ nk_dots_pack_i4_sme(b, width, depth, b_stride, b_packed);
2746
+ #elif NK_TARGET_ICELAKE
2747
+ nk_dots_pack_i4_icelake(b, width, depth, b_stride, b_packed);
2748
+ #elif NK_TARGET_NEONSDOT
2749
+ nk_dots_pack_i4_neonsdot(b, width, depth, b_stride, b_packed);
2750
+ #elif NK_TARGET_HASWELL
2751
+ nk_dots_pack_i4_haswell(b, width, depth, b_stride, b_packed);
2752
+ #elif NK_TARGET_V128RELAXED
2753
+ nk_dots_pack_i4_v128relaxed(b, width, depth, b_stride, b_packed);
2754
+ #else
2755
+ nk_dots_pack_i4_serial(b, width, depth, b_stride, b_packed);
2756
+ #endif
2757
+ }
2758
+
2759
+ NK_PUBLIC void nk_dots_packed_i4(nk_i4x2_t const *a, void const *b_packed, nk_i32_t *c, nk_size_t height,
2760
+ nk_size_t width, nk_size_t depth, nk_size_t a_stride, nk_size_t c_stride) {
2761
+ #if NK_TARGET_SME
2762
+ nk_dots_packed_i4_sme(a, b_packed, c, height, width, depth, a_stride, c_stride);
2763
+ #elif NK_TARGET_ICELAKE
2764
+ nk_dots_packed_i4_icelake(a, b_packed, c, height, width, depth, a_stride, c_stride);
2765
+ #elif NK_TARGET_NEONSDOT
2766
+ nk_dots_packed_i4_neonsdot(a, b_packed, c, height, width, depth, a_stride, c_stride);
2767
+ #elif NK_TARGET_HASWELL
2768
+ nk_dots_packed_i4_haswell(a, b_packed, c, height, width, depth, a_stride, c_stride);
2769
+ #elif NK_TARGET_V128RELAXED
2770
+ nk_dots_packed_i4_v128relaxed(a, b_packed, c, height, width, depth, a_stride, c_stride);
2771
+ #else
2772
+ nk_dots_packed_i4_serial(a, b_packed, c, height, width, depth, a_stride, c_stride);
2773
+ #endif
2774
+ }
2775
+
2776
+ NK_PUBLIC void nk_dots_symmetric_f16(nk_f16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
2777
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
2778
+ nk_size_t row_count) {
2779
+ #if NK_TARGET_SME
2780
+ nk_dots_symmetric_f16_sme(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2781
+ #elif NK_TARGET_NEON
2782
+ nk_dots_symmetric_f16_neon(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2783
+ #elif NK_TARGET_NEONFHM
2784
+ nk_dots_symmetric_f16_neonfhm(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2785
+ #elif NK_TARGET_SKYLAKE
2786
+ nk_dots_symmetric_f16_skylake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2787
+ #elif NK_TARGET_HASWELL
2788
+ nk_dots_symmetric_f16_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2789
+ #elif NK_TARGET_POWERVSX
2790
+ nk_dots_symmetric_f16_powervsx(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2791
+ #elif NK_TARGET_RVV
2792
+ nk_dots_symmetric_f16_rvv(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2793
+ #else
2794
+ nk_dots_symmetric_f16_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2795
+ #endif
2796
+ }
2797
+
2798
+ NK_PUBLIC void nk_dots_symmetric_bf16(nk_bf16_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
2799
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
2800
+ nk_size_t row_count) {
2801
+ #if NK_TARGET_SME
2802
+ nk_dots_symmetric_bf16_sme(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2803
+ #elif NK_TARGET_SAPPHIREAMX
2804
+ nk_dots_symmetric_bf16_sapphireamx(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2805
+ row_count);
2806
+ #elif NK_TARGET_NEONBFDOT
2807
+ nk_dots_symmetric_bf16_neonbfdot(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2808
+ row_count);
2809
+ #elif NK_TARGET_GENOA
2810
+ nk_dots_symmetric_bf16_genoa(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2811
+ #elif NK_TARGET_SKYLAKE
2812
+ nk_dots_symmetric_bf16_skylake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2813
+ #elif NK_TARGET_HASWELL
2814
+ nk_dots_symmetric_bf16_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2815
+ #elif NK_TARGET_POWERVSX
2816
+ nk_dots_symmetric_bf16_powervsx(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2817
+ #elif NK_TARGET_RVV
2818
+ nk_dots_symmetric_bf16_rvv(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2819
+ #elif NK_TARGET_V128RELAXED
2820
+ nk_dots_symmetric_bf16_v128relaxed(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2821
+ row_count);
2822
+ #else
2823
+ nk_dots_symmetric_bf16_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2824
+ #endif
2825
+ }
2826
+
2827
+ NK_PUBLIC void nk_dots_symmetric_i8(nk_i8_t const *vectors, nk_size_t vectors_count, nk_size_t depth, nk_size_t stride,
2828
+ nk_i32_t *result, nk_size_t result_stride, nk_size_t row_start,
2829
+ nk_size_t row_count) {
2830
+ #if NK_TARGET_SME
2831
+ nk_dots_symmetric_i8_sme(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2832
+ #elif NK_TARGET_SAPPHIREAMX
2833
+ nk_dots_symmetric_i8_sapphireamx(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2834
+ row_count);
2835
+ #elif NK_TARGET_NEONSDOT
2836
+ nk_dots_symmetric_i8_neonsdot(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2837
+ #elif NK_TARGET_ICELAKE
2838
+ nk_dots_symmetric_i8_icelake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2839
+ #elif NK_TARGET_SIERRA
2840
+ nk_dots_symmetric_i8_sierra(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2841
+ #elif NK_TARGET_ALDER
2842
+ nk_dots_symmetric_i8_alder(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2843
+ #elif NK_TARGET_HASWELL
2844
+ nk_dots_symmetric_i8_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2845
+ #elif NK_TARGET_POWERVSX
2846
+ nk_dots_symmetric_i8_powervsx(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2847
+ #elif NK_TARGET_RVV
2848
+ nk_dots_symmetric_i8_rvv(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2849
+ #elif NK_TARGET_V128RELAXED
2850
+ nk_dots_symmetric_i8_v128relaxed(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2851
+ row_count);
2852
+ #else
2853
+ nk_dots_symmetric_i8_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2854
+ #endif
2855
+ }
2856
+
2857
+ NK_PUBLIC void nk_dots_symmetric_u8(nk_u8_t const *vectors, nk_size_t vectors_count, nk_size_t depth, nk_size_t stride,
2858
+ nk_u32_t *result, nk_size_t result_stride, nk_size_t row_start,
2859
+ nk_size_t row_count) {
2860
+ #if NK_TARGET_SME
2861
+ nk_dots_symmetric_u8_sme(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2862
+ #elif NK_TARGET_SAPPHIREAMX
2863
+ nk_dots_symmetric_u8_sapphireamx(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2864
+ row_count);
2865
+ #elif NK_TARGET_ICELAKE
2866
+ nk_dots_symmetric_u8_icelake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2867
+ #elif NK_TARGET_SIERRA
2868
+ nk_dots_symmetric_u8_sierra(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2869
+ #elif NK_TARGET_ALDER
2870
+ nk_dots_symmetric_u8_alder(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2871
+ #elif NK_TARGET_NEONSDOT
2872
+ nk_dots_symmetric_u8_neonsdot(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2873
+ #elif NK_TARGET_HASWELL
2874
+ nk_dots_symmetric_u8_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2875
+ #elif NK_TARGET_POWERVSX
2876
+ nk_dots_symmetric_u8_powervsx(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2877
+ #elif NK_TARGET_RVV
2878
+ nk_dots_symmetric_u8_rvv(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2879
+ #elif NK_TARGET_V128RELAXED
2880
+ nk_dots_symmetric_u8_v128relaxed(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2881
+ row_count);
2882
+ #else
2883
+ nk_dots_symmetric_u8_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2884
+ #endif
2885
+ }
2886
+
2887
+ NK_PUBLIC void nk_dots_symmetric_e4m3(nk_e4m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
2888
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
2889
+ nk_size_t row_count) {
2890
+ #if NK_TARGET_SME
2891
+ nk_dots_symmetric_e4m3_sme(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2892
+ #elif NK_TARGET_NEONFP8
2893
+ nk_dots_symmetric_e4m3_neonfp8(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2894
+ #elif NK_TARGET_NEONFHM
2895
+ nk_dots_symmetric_e4m3_neonfhm(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2896
+ #elif NK_TARGET_SAPPHIREAMX
2897
+ nk_dots_symmetric_e4m3_sapphireamx(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2898
+ row_count);
2899
+ #elif NK_TARGET_DIAMOND
2900
+ nk_dots_symmetric_e4m3_diamond(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2901
+ #elif NK_TARGET_GENOA
2902
+ nk_dots_symmetric_e4m3_genoa(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2903
+ #elif NK_TARGET_SKYLAKE
2904
+ nk_dots_symmetric_e4m3_skylake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2905
+ #elif NK_TARGET_HASWELL
2906
+ nk_dots_symmetric_e4m3_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2907
+ #elif NK_TARGET_RVV
2908
+ nk_dots_symmetric_e4m3_rvv(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2909
+ #elif NK_TARGET_V128RELAXED
2910
+ nk_dots_symmetric_e4m3_v128relaxed(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2911
+ row_count);
2912
+ #else
2913
+ nk_dots_symmetric_e4m3_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2914
+ #endif
2915
+ }
2916
+
2917
+ NK_PUBLIC void nk_dots_symmetric_e5m2(nk_e5m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
2918
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
2919
+ nk_size_t row_count) {
2920
+ #if NK_TARGET_SME
2921
+ nk_dots_symmetric_e5m2_sme(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2922
+ #elif NK_TARGET_NEONFP8
2923
+ nk_dots_symmetric_e5m2_neonfp8(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2924
+ #elif NK_TARGET_NEONFHM
2925
+ nk_dots_symmetric_e5m2_neonfhm(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2926
+ #elif NK_TARGET_SAPPHIREAMX
2927
+ nk_dots_symmetric_e5m2_sapphireamx(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2928
+ row_count);
2929
+ #elif NK_TARGET_DIAMOND
2930
+ nk_dots_symmetric_e5m2_diamond(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2931
+ #elif NK_TARGET_GENOA
2932
+ nk_dots_symmetric_e5m2_genoa(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2933
+ #elif NK_TARGET_SKYLAKE
2934
+ nk_dots_symmetric_e5m2_skylake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2935
+ #elif NK_TARGET_HASWELL
2936
+ nk_dots_symmetric_e5m2_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2937
+ #elif NK_TARGET_RVV
2938
+ nk_dots_symmetric_e5m2_rvv(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2939
+ #elif NK_TARGET_V128RELAXED
2940
+ nk_dots_symmetric_e5m2_v128relaxed(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2941
+ row_count);
2942
+ #else
2943
+ nk_dots_symmetric_e5m2_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2944
+ #endif
2945
+ }
2946
+
2947
+ NK_PUBLIC void nk_dots_symmetric_e2m3(nk_e2m3_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
2948
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
2949
+ nk_size_t row_count) {
2950
+ #if NK_TARGET_SME
2951
+ nk_dots_symmetric_e2m3_sme(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2952
+ #elif NK_TARGET_SAPPHIREAMX
2953
+ nk_dots_symmetric_e2m3_sapphireamx(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2954
+ row_count);
2955
+ #elif NK_TARGET_NEONFP8
2956
+ nk_dots_symmetric_e2m3_neonfp8(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2957
+ #elif NK_TARGET_SKYLAKE
2958
+ nk_dots_symmetric_e2m3_skylake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2959
+ #elif NK_TARGET_SIERRA
2960
+ nk_dots_symmetric_e2m3_sierra(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2961
+ #elif NK_TARGET_ALDER
2962
+ nk_dots_symmetric_e2m3_alder(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2963
+ #elif NK_TARGET_HASWELL
2964
+ nk_dots_symmetric_e2m3_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2965
+ #elif NK_TARGET_RVV
2966
+ nk_dots_symmetric_e2m3_rvv(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2967
+ #elif NK_TARGET_V128RELAXED
2968
+ nk_dots_symmetric_e2m3_v128relaxed(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2969
+ row_count);
2970
+ #else
2971
+ nk_dots_symmetric_e2m3_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2972
+ #endif
2973
+ }
2974
+
2975
+ NK_PUBLIC void nk_dots_symmetric_e3m2(nk_e3m2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
2976
+ nk_size_t stride, nk_f32_t *result, nk_size_t result_stride, nk_size_t row_start,
2977
+ nk_size_t row_count) {
2978
+ #if NK_TARGET_SME
2979
+ nk_dots_symmetric_e3m2_sme(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2980
+ #elif NK_TARGET_SAPPHIREAMX
2981
+ nk_dots_symmetric_e3m2_sapphireamx(vectors, vectors_count, depth, stride, result, result_stride, row_start,
2982
+ row_count);
2983
+ #elif NK_TARGET_NEONFP8
2984
+ nk_dots_symmetric_e3m2_neonfp8(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2985
+ #elif NK_TARGET_SKYLAKE
2986
+ nk_dots_symmetric_e3m2_skylake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2987
+ #elif NK_TARGET_HASWELL
2988
+ nk_dots_symmetric_e3m2_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2989
+ #elif NK_TARGET_RVV
2990
+ nk_dots_symmetric_e3m2_rvv(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2991
+ #else
2992
+ nk_dots_symmetric_e3m2_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
2993
+ #endif
2994
+ }
2995
+
2996
+ NK_PUBLIC void nk_dots_symmetric_u4(nk_u4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
2997
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride, nk_size_t row_start,
2998
+ nk_size_t row_count) {
2999
+ #if NK_TARGET_SME
3000
+ nk_dots_symmetric_u4_sme(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3001
+ #elif NK_TARGET_ICELAKE
3002
+ nk_dots_symmetric_u4_icelake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3003
+ #elif NK_TARGET_NEONSDOT
3004
+ nk_dots_symmetric_u4_neonsdot(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3005
+ #elif NK_TARGET_HASWELL
3006
+ nk_dots_symmetric_u4_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3007
+ #elif NK_TARGET_V128RELAXED
3008
+ nk_dots_symmetric_u4_v128relaxed(vectors, vectors_count, depth, stride, result, result_stride, row_start,
3009
+ row_count);
3010
+ #else
3011
+ nk_dots_symmetric_u4_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3012
+ #endif
3013
+ }
3014
+
3015
+ NK_PUBLIC void nk_dots_symmetric_u1(nk_u1x8_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
3016
+ nk_size_t stride, nk_u32_t *result, nk_size_t result_stride, nk_size_t row_start,
3017
+ nk_size_t row_count) {
3018
+ #if NK_TARGET_SMEBI32
3019
+ nk_dots_symmetric_u1_smebi32(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3020
+ #elif NK_TARGET_ICELAKE
3021
+ nk_dots_symmetric_u1_icelake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3022
+ #elif NK_TARGET_HASWELL
3023
+ nk_dots_symmetric_u1_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3024
+ #elif NK_TARGET_NEON
3025
+ nk_dots_symmetric_u1_neon(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3026
+ #elif NK_TARGET_POWERVSX
3027
+ nk_dots_symmetric_u1_powervsx(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3028
+ #elif NK_TARGET_LOONGSONASX
3029
+ nk_dots_symmetric_u1_loongsonasx(vectors, vectors_count, depth, stride, result, result_stride, row_start,
3030
+ row_count);
3031
+ #elif NK_TARGET_V128RELAXED
3032
+ nk_dots_symmetric_u1_v128relaxed(vectors, vectors_count, depth, stride, result, result_stride, row_start,
3033
+ row_count);
3034
+ #else
3035
+ nk_dots_symmetric_u1_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3036
+ #endif
3037
+ }
3038
+
3039
+ NK_PUBLIC void nk_dots_symmetric_i4(nk_i4x2_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
3040
+ nk_size_t stride, nk_i32_t *result, nk_size_t result_stride, nk_size_t row_start,
3041
+ nk_size_t row_count) {
3042
+ #if NK_TARGET_SME
3043
+ nk_dots_symmetric_i4_sme(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3044
+ #elif NK_TARGET_ICELAKE
3045
+ nk_dots_symmetric_i4_icelake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3046
+ #elif NK_TARGET_NEONSDOT
3047
+ nk_dots_symmetric_i4_neonsdot(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3048
+ #elif NK_TARGET_HASWELL
3049
+ nk_dots_symmetric_i4_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3050
+ #elif NK_TARGET_V128RELAXED
3051
+ nk_dots_symmetric_i4_v128relaxed(vectors, vectors_count, depth, stride, result, result_stride, row_start,
3052
+ row_count);
3053
+ #else
3054
+ nk_dots_symmetric_i4_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3055
+ #endif
3056
+ }
3057
+
3058
+ NK_PUBLIC void nk_dots_symmetric_f32(nk_f32_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
3059
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride, nk_size_t row_start,
3060
+ nk_size_t row_count) {
3061
+ #if NK_TARGET_SMEF64
3062
+ nk_dots_symmetric_f32_smef64(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3063
+ #elif NK_TARGET_SKYLAKE
3064
+ nk_dots_symmetric_f32_skylake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3065
+ #elif NK_TARGET_HASWELL
3066
+ nk_dots_symmetric_f32_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3067
+ #elif NK_TARGET_NEON
3068
+ nk_dots_symmetric_f32_neon(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3069
+ #elif NK_TARGET_POWERVSX
3070
+ nk_dots_symmetric_f32_powervsx(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3071
+ #elif NK_TARGET_RVV
3072
+ nk_dots_symmetric_f32_rvv(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3073
+ #elif NK_TARGET_V128RELAXED
3074
+ nk_dots_symmetric_f32_v128relaxed(vectors, vectors_count, depth, stride, result, result_stride, row_start,
3075
+ row_count);
3076
+ #else
3077
+ nk_dots_symmetric_f32_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3078
+ #endif
3079
+ }
3080
+
3081
+ NK_PUBLIC void nk_dots_symmetric_f64(nk_f64_t const *vectors, nk_size_t vectors_count, nk_size_t depth,
3082
+ nk_size_t stride, nk_f64_t *result, nk_size_t result_stride, nk_size_t row_start,
3083
+ nk_size_t row_count) {
3084
+ #if NK_TARGET_SMEF64
3085
+ nk_dots_symmetric_f64_smef64(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3086
+ #elif NK_TARGET_SKYLAKE
3087
+ nk_dots_symmetric_f64_skylake(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3088
+ #elif NK_TARGET_HASWELL
3089
+ nk_dots_symmetric_f64_haswell(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3090
+ #elif NK_TARGET_NEON
3091
+ nk_dots_symmetric_f64_neon(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3092
+ #elif NK_TARGET_POWERVSX
3093
+ nk_dots_symmetric_f64_powervsx(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3094
+ #elif NK_TARGET_RVV
3095
+ nk_dots_symmetric_f64_rvv(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3096
+ #elif NK_TARGET_V128RELAXED
3097
+ nk_dots_symmetric_f64_v128relaxed(vectors, vectors_count, depth, stride, result, result_stride, row_start,
3098
+ row_count);
3099
+ #else
3100
+ nk_dots_symmetric_f64_serial(vectors, vectors_count, depth, stride, result, result_stride, row_start, row_count);
3101
+ #endif
3102
+ }
3103
+
3104
+ #endif // !NK_DYNAMIC_DISPATCH
3105
+
3106
+ #if defined(__cplusplus)
3107
+ } // extern "C"
3108
+ #endif
3109
+
3110
+ #endif