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,343 @@
1
+ /**
2
+ * @brief SIMD-accelerated Elementwise Arithmetic for Sapphire Rapids.
3
+ * @file include/numkong/each/sapphire.h
4
+ * @author Ash Vardanian
5
+ * @date December 27, 2025
6
+ *
7
+ * @sa include/numkong/each.h
8
+ *
9
+ * @section sapphire_elementwise_instructions Relevant Instructions
10
+ *
11
+ * Intrinsic Instruction Sapphire Genoa
12
+ * _mm512_add_ph VADDPH (ZMM, ZMM, ZMM) 4cy @ p05 3cy @ p01
13
+ * _mm512_mul_ph VMULPH (ZMM, ZMM, ZMM) 4cy @ p05 3cy @ p01
14
+ * _mm512_fmadd_ph VFMADD (ZMM, ZMM, ZMM) 4cy @ p05 4cy @ p01
15
+ * _mm512_cvtepi16_ph VCVTW2PH (ZMM, ZMM) 4cy @ p05 4cy @ p01
16
+ * _mm512_cvtph_epi16 VCVTPH2W (ZMM, ZMM) 4cy @ p05 4cy @ p01
17
+ * _mm512_cvtepi8_epi16 VPMOVSXBW (ZMM, YMM) 3cy @ p5 3cy @ p12
18
+ * _mm512_cvtsepi16_epi8 VPMOVSWB (YMM, ZMM) 4cy @ p5 4cy @ p12
19
+ * _mm512_packus_epi16 VPACKUSWB (ZMM, ZMM, ZMM) 1cy @ p5 1cy @ p12
20
+ * _mm256_add_ph VADDPH (YMM, YMM, YMM) 4cy @ p05 3cy @ p01
21
+ * _mm512_maskz_loadu_epi16 VMOVDQU16 (ZMM {K}, M512) 7cy @ p23 7cy @ p23
22
+ * _mm512_mask_storeu_epi16 VMOVDQU16 (M512 {K}, ZMM) 4cy @ p4 4cy @ p4
23
+ */
24
+ #ifndef NK_EACH_SAPPHIRE_H
25
+ #define NK_EACH_SAPPHIRE_H
26
+
27
+ #if NK_TARGET_X8664_
28
+ #if NK_TARGET_SAPPHIRE
29
+
30
+ #include "numkong/types.h"
31
+ #include "numkong/cast/sapphire.h" // `nk_f32_to_f16_sapphire`
32
+
33
+ #if defined(__cplusplus)
34
+ extern "C" {
35
+ #endif
36
+
37
+ #if defined(__clang__)
38
+ #pragma clang attribute push(__attribute__((target("avx2,avx512f,avx512vl,avx512bw,avx512fp16,f16c,fma,bmi,bmi2"))), \
39
+ apply_to = function)
40
+ #elif defined(__GNUC__)
41
+ #pragma GCC push_options
42
+ #pragma GCC target("avx2", "avx512f", "avx512vl", "avx512bw", "avx512fp16", "f16c", "fma", "bmi", "bmi2")
43
+ #endif
44
+
45
+ NK_PUBLIC void nk_each_sum_f16_sapphire(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f16_t *result) {
46
+ __mmask32 mask = 0xFFFFFFFF;
47
+ __m512h a_f16_vec, b_f16_vec;
48
+ __m512h sum_f16_vec;
49
+ nk_each_sum_f16_sapphire_cycle:
50
+ if (n < 32) {
51
+ mask = (__mmask32)_bzhi_u32(0xFFFFFFFF, n);
52
+ a_f16_vec = _mm512_castsi512_ph(_mm512_maskz_loadu_epi16(mask, a));
53
+ b_f16_vec = _mm512_castsi512_ph(_mm512_maskz_loadu_epi16(mask, b));
54
+ n = 0;
55
+ }
56
+ else {
57
+ a_f16_vec = _mm512_castsi512_ph(_mm512_loadu_epi16(a));
58
+ b_f16_vec = _mm512_castsi512_ph(_mm512_loadu_epi16(b));
59
+ a += 32, b += 32, n -= 32;
60
+ }
61
+ sum_f16_vec = _mm512_add_ph(a_f16_vec, b_f16_vec);
62
+ _mm512_mask_storeu_epi16(result, mask, _mm512_castph_si512(sum_f16_vec));
63
+ result += 32;
64
+ if (n) goto nk_each_sum_f16_sapphire_cycle;
65
+ }
66
+
67
+ NK_PUBLIC void nk_each_scale_u8_sapphire(nk_u8_t const *a, nk_size_t n, nk_f32_t const *alpha, nk_f32_t const *beta,
68
+ nk_u8_t *result) {
69
+ short alpha_short, beta_short;
70
+ nk_f32_to_f16_sapphire(alpha, (nk_f16_t *)&alpha_short);
71
+ nk_f32_to_f16_sapphire(beta, (nk_f16_t *)&beta_short);
72
+ __mmask64 mask = 0xFFFFFFFFFFFFFFFFull;
73
+ __m512h alpha_f16x32 = _mm512_castsi512_ph(_mm512_set1_epi16(alpha_short));
74
+ __m512h beta_f16x32 = _mm512_castsi512_ph(_mm512_set1_epi16(beta_short));
75
+ __m512i a_u8x64, result_u8x64;
76
+ __m512h a_low_f16x32, a_high_f16x32;
77
+ __m512h result_low_f16x32, result_high_f16x32;
78
+ __m512i result_low_i16x32, result_high_i16x32;
79
+ nk_each_scale_u8_sapphire_cycle:
80
+ if (n < 64) {
81
+ mask = (__mmask64)_bzhi_u64(0xFFFFFFFFFFFFFFFFull, n);
82
+ a_u8x64 = _mm512_maskz_loadu_epi8(mask, a);
83
+ n = 0;
84
+ }
85
+ else {
86
+ a_u8x64 = _mm512_loadu_epi8(a);
87
+ a += 64, n -= 64;
88
+ }
89
+ // Upcast:
90
+ a_low_f16x32 = _mm512_cvtepi16_ph(_mm512_unpacklo_epi8(a_u8x64, _mm512_setzero_si512()));
91
+ a_high_f16x32 = _mm512_cvtepi16_ph(_mm512_unpackhi_epi8(a_u8x64, _mm512_setzero_si512()));
92
+ // Scale:
93
+ result_low_f16x32 = _mm512_fmadd_ph(a_low_f16x32, alpha_f16x32, beta_f16x32);
94
+ result_high_f16x32 = _mm512_fmadd_ph(a_high_f16x32, alpha_f16x32, beta_f16x32);
95
+ // Downcast:
96
+ result_low_i16x32 = _mm512_cvtph_epi16(result_low_f16x32);
97
+ result_high_i16x32 = _mm512_cvtph_epi16(result_high_f16x32);
98
+ result_u8x64 = _mm512_packus_epi16(result_low_i16x32, result_high_i16x32);
99
+ _mm512_mask_storeu_epi8(result, mask, result_u8x64);
100
+ result += 64;
101
+ if (n) goto nk_each_scale_u8_sapphire_cycle;
102
+ }
103
+
104
+ NK_PUBLIC void nk_each_blend_u8_sapphire( //
105
+ nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, //
106
+ nk_f32_t const *alpha, nk_f32_t const *beta, nk_u8_t *result) {
107
+
108
+ nk_f32_t alpha_val = *alpha;
109
+ nk_f32_t beta_val = *beta;
110
+
111
+ // There are several special cases we may want to implement:
112
+ // 1. Simple addition, when both weights are equal to 1.0.
113
+ if (alpha_val == 1 && beta_val == 1) {
114
+ // In this case we can avoid expensive multiplications.
115
+ nk_each_sum_u8_icelake(a, b, n, result);
116
+ return;
117
+ }
118
+ // 2. Just scaling, when one of the weights is equal to zero.
119
+ else if (alpha_val == 0 || beta_val == 0) {
120
+ // In this case we can avoid half of the load instructions.
121
+ nk_f32_t zero = 0;
122
+ if (beta_val == 0) { nk_each_scale_u8_sapphire(a, n, alpha, &zero, result); }
123
+ else { nk_each_scale_u8_sapphire(b, n, beta, &zero, result); }
124
+ return;
125
+ }
126
+
127
+ // The general case.
128
+ short alpha_short, beta_short;
129
+ nk_f32_to_f16_sapphire(&alpha_val, (nk_f16_t *)&alpha_short);
130
+ nk_f32_to_f16_sapphire(&beta_val, (nk_f16_t *)&beta_short);
131
+ __mmask64 mask = 0xFFFFFFFFFFFFFFFFull;
132
+ __m512h alpha_f16x32 = _mm512_castsi512_ph(_mm512_set1_epi16(alpha_short));
133
+ __m512h beta_f16x32 = _mm512_castsi512_ph(_mm512_set1_epi16(beta_short));
134
+ __m512i a_u8x64, b_u8x64, result_u8x64;
135
+ __m512h a_low_f16x32, a_high_f16x32, b_low_f16x32, b_high_f16x32;
136
+ __m512h a_scaled_low_f16x32, a_scaled_high_f16x32, result_low_f16x32, result_high_f16x32;
137
+ __m512i result_low_i16x32, result_high_i16x32;
138
+ nk_each_blend_u8_sapphire_cycle:
139
+ if (n < 64) {
140
+ mask = (__mmask64)_bzhi_u64(0xFFFFFFFFFFFFFFFFull, n);
141
+ a_u8x64 = _mm512_maskz_loadu_epi8(mask, a);
142
+ b_u8x64 = _mm512_maskz_loadu_epi8(mask, b);
143
+ n = 0;
144
+ }
145
+ else {
146
+ a_u8x64 = _mm512_loadu_epi8(a);
147
+ b_u8x64 = _mm512_loadu_epi8(b);
148
+ a += 64, b += 64, n -= 64;
149
+ }
150
+ // Upcast:
151
+ a_low_f16x32 = _mm512_cvtepi16_ph(_mm512_unpacklo_epi8(a_u8x64, _mm512_setzero_si512()));
152
+ a_high_f16x32 = _mm512_cvtepi16_ph(_mm512_unpackhi_epi8(a_u8x64, _mm512_setzero_si512()));
153
+ b_low_f16x32 = _mm512_cvtepi16_ph(_mm512_unpacklo_epi8(b_u8x64, _mm512_setzero_si512()));
154
+ b_high_f16x32 = _mm512_cvtepi16_ph(_mm512_unpackhi_epi8(b_u8x64, _mm512_setzero_si512()));
155
+ // Scale:
156
+ a_scaled_low_f16x32 = _mm512_mul_ph(a_low_f16x32, alpha_f16x32);
157
+ a_scaled_high_f16x32 = _mm512_mul_ph(a_high_f16x32, alpha_f16x32);
158
+ // Add:
159
+ result_low_f16x32 = _mm512_fmadd_ph(b_low_f16x32, beta_f16x32, a_scaled_low_f16x32);
160
+ result_high_f16x32 = _mm512_fmadd_ph(b_high_f16x32, beta_f16x32, a_scaled_high_f16x32);
161
+ // Downcast:
162
+ result_low_i16x32 = _mm512_cvtph_epi16(result_low_f16x32);
163
+ result_high_i16x32 = _mm512_cvtph_epi16(result_high_f16x32);
164
+ result_u8x64 = _mm512_packus_epi16(result_low_i16x32, result_high_i16x32);
165
+ _mm512_mask_storeu_epi8(result, mask, result_u8x64);
166
+ result += 64;
167
+ if (n) goto nk_each_blend_u8_sapphire_cycle;
168
+ }
169
+
170
+ NK_PUBLIC void nk_each_scale_i8_sapphire(nk_i8_t const *a, nk_size_t n, nk_f32_t const *alpha, nk_f32_t const *beta,
171
+ nk_i8_t *result) {
172
+ short alpha_short, beta_short;
173
+ nk_f32_to_f16_sapphire(alpha, (nk_f16_t *)&alpha_short);
174
+ nk_f32_to_f16_sapphire(beta, (nk_f16_t *)&beta_short);
175
+ __mmask64 mask = 0xFFFFFFFFFFFFFFFFull;
176
+ __m512h alpha_f16x32 = _mm512_castsi512_ph(_mm512_set1_epi16(alpha_short));
177
+ __m512h beta_f16x32 = _mm512_castsi512_ph(_mm512_set1_epi16(beta_short));
178
+ __m256i a_low_i8x32, a_high_i8x32;
179
+ __m512i result_i8x64;
180
+ __m512h a_low_f16x32, a_high_f16x32;
181
+ __m512h result_low_f16x32, result_high_f16x32;
182
+ __m512i result_low_i16x32, result_high_i16x32;
183
+ nk_each_scale_i8_sapphire_cycle:
184
+ if (n < 64) {
185
+ // Tail: use masked 512-bit load and extract (runs once)
186
+ mask = (__mmask64)_bzhi_u64(0xFFFFFFFFFFFFFFFFull, n);
187
+ __m512i a_i8x64 = _mm512_maskz_loadu_epi8(mask, a);
188
+ a_low_i8x32 = _mm512_castsi512_si256(a_i8x64);
189
+ a_high_i8x32 = _mm512_extracti64x4_epi64(a_i8x64, 1);
190
+ n = 0;
191
+ }
192
+ else {
193
+ // Hot path: 2×256-bit loads to avoid VEXTRACTI64X4 (Port 5)
194
+ a_low_i8x32 = _mm256_loadu_epi8(a);
195
+ a_high_i8x32 = _mm256_loadu_epi8(a + 32);
196
+ a += 64, n -= 64;
197
+ }
198
+ // Upcast from 256-bit halves:
199
+ a_low_f16x32 = _mm512_cvtepi16_ph(_mm512_cvtepi8_epi16(a_low_i8x32));
200
+ a_high_f16x32 = _mm512_cvtepi16_ph(_mm512_cvtepi8_epi16(a_high_i8x32));
201
+ // Scale:
202
+ result_low_f16x32 = _mm512_fmadd_ph(a_low_f16x32, alpha_f16x32, beta_f16x32);
203
+ result_high_f16x32 = _mm512_fmadd_ph(a_high_f16x32, alpha_f16x32, beta_f16x32);
204
+ // Downcast:
205
+ result_low_i16x32 = _mm512_cvtph_epi16(result_low_f16x32);
206
+ result_high_i16x32 = _mm512_cvtph_epi16(result_high_f16x32);
207
+ result_i8x64 = _mm512_inserti64x4(_mm512_castsi256_si512(_mm512_cvtsepi16_epi8(result_low_i16x32)),
208
+ _mm512_cvtsepi16_epi8(result_high_i16x32), 1);
209
+ _mm512_mask_storeu_epi8(result, mask, result_i8x64);
210
+ result += 64;
211
+ if (n) goto nk_each_scale_i8_sapphire_cycle;
212
+ }
213
+
214
+ NK_PUBLIC void nk_each_blend_i8_sapphire( //
215
+ nk_i8_t const *a, nk_i8_t const *b, nk_size_t n, //
216
+ nk_f32_t const *alpha, nk_f32_t const *beta, nk_i8_t *result) {
217
+
218
+ nk_f32_t alpha_val = *alpha;
219
+ nk_f32_t beta_val = *beta;
220
+
221
+ // There are several special cases we may want to implement:
222
+ // 1. Simple addition, when both weights are equal to 1.0.
223
+ if (alpha_val == 1 && beta_val == 1) {
224
+ // In this case we can avoid expensive multiplications.
225
+ nk_each_sum_i8_icelake(a, b, n, result);
226
+ return;
227
+ }
228
+ // 2. Just scaling, when one of the weights is equal to zero.
229
+ else if (alpha_val == 0 || beta_val == 0) {
230
+ // In this case we can avoid half of the load instructions.
231
+ nk_f32_t zero = 0;
232
+ if (beta_val == 0) { nk_each_scale_i8_sapphire(a, n, alpha, &zero, result); }
233
+ else { nk_each_scale_i8_sapphire(b, n, beta, &zero, result); }
234
+ return;
235
+ }
236
+
237
+ // The general case.
238
+ short alpha_short, beta_short;
239
+ nk_f32_to_f16_sapphire(&alpha_val, (nk_f16_t *)&alpha_short);
240
+ nk_f32_to_f16_sapphire(&beta_val, (nk_f16_t *)&beta_short);
241
+ __mmask64 mask = 0xFFFFFFFFFFFFFFFFull;
242
+ __m512h alpha_f16x32 = _mm512_castsi512_ph(_mm512_set1_epi16(alpha_short));
243
+ __m512h beta_f16x32 = _mm512_castsi512_ph(_mm512_set1_epi16(beta_short));
244
+ __m256i a_low_i8x32, a_high_i8x32, b_low_i8x32, b_high_i8x32;
245
+ __m512i result_i8x64;
246
+ __m512h a_low_f16x32, a_high_f16x32, b_low_f16x32, b_high_f16x32;
247
+ __m512h a_scaled_low_f16x32, a_scaled_high_f16x32, result_low_f16x32, result_high_f16x32;
248
+ __m512i result_low_i16x32, result_high_i16x32;
249
+ nk_each_blend_i8_sapphire_cycle:
250
+ if (n < 64) {
251
+ // Tail: use masked 512-bit loads and extract (runs once)
252
+ mask = (__mmask64)_bzhi_u64(0xFFFFFFFFFFFFFFFFull, n);
253
+ __m512i a_i8x64 = _mm512_maskz_loadu_epi8(mask, a);
254
+ __m512i b_i8x64 = _mm512_maskz_loadu_epi8(mask, b);
255
+ a_low_i8x32 = _mm512_castsi512_si256(a_i8x64);
256
+ a_high_i8x32 = _mm512_extracti64x4_epi64(a_i8x64, 1);
257
+ b_low_i8x32 = _mm512_castsi512_si256(b_i8x64);
258
+ b_high_i8x32 = _mm512_extracti64x4_epi64(b_i8x64, 1);
259
+ n = 0;
260
+ }
261
+ else {
262
+ // Hot path: 2×256-bit loads per vector to avoid VEXTRACTI64X4 (Port 5)
263
+ a_low_i8x32 = _mm256_loadu_epi8(a);
264
+ a_high_i8x32 = _mm256_loadu_epi8(a + 32);
265
+ b_low_i8x32 = _mm256_loadu_epi8(b);
266
+ b_high_i8x32 = _mm256_loadu_epi8(b + 32);
267
+ a += 64, b += 64, n -= 64;
268
+ }
269
+ // Upcast from 256-bit halves:
270
+ a_low_f16x32 = _mm512_cvtepi16_ph(_mm512_cvtepi8_epi16(a_low_i8x32));
271
+ a_high_f16x32 = _mm512_cvtepi16_ph(_mm512_cvtepi8_epi16(a_high_i8x32));
272
+ b_low_f16x32 = _mm512_cvtepi16_ph(_mm512_cvtepi8_epi16(b_low_i8x32));
273
+ b_high_f16x32 = _mm512_cvtepi16_ph(_mm512_cvtepi8_epi16(b_high_i8x32));
274
+ // Scale:
275
+ a_scaled_low_f16x32 = _mm512_mul_ph(a_low_f16x32, alpha_f16x32);
276
+ a_scaled_high_f16x32 = _mm512_mul_ph(a_high_f16x32, alpha_f16x32);
277
+ // Add:
278
+ result_low_f16x32 = _mm512_fmadd_ph(b_low_f16x32, beta_f16x32, a_scaled_low_f16x32);
279
+ result_high_f16x32 = _mm512_fmadd_ph(b_high_f16x32, beta_f16x32, a_scaled_high_f16x32);
280
+ // Downcast:
281
+ result_low_i16x32 = _mm512_cvtph_epi16(result_low_f16x32);
282
+ result_high_i16x32 = _mm512_cvtph_epi16(result_high_f16x32);
283
+ result_i8x64 = _mm512_inserti64x4(_mm512_castsi256_si512(_mm512_cvtsepi16_epi8(result_low_i16x32)),
284
+ _mm512_cvtsepi16_epi8(result_high_i16x32), 1);
285
+ _mm512_mask_storeu_epi8(result, mask, result_i8x64);
286
+ result += 64;
287
+ if (n) goto nk_each_blend_i8_sapphire_cycle;
288
+ }
289
+
290
+ NK_PUBLIC void nk_each_sum_e4m3_sapphire(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_e4m3_t *result) {
291
+ __m256i a_e4m3x32, b_e4m3x32;
292
+ __m256h a_low_f16x16, a_high_f16x16, b_low_f16x16, b_high_f16x16;
293
+ __m256h sum_low_f16x16, sum_high_f16x16;
294
+ __m128i result_low_e4m3x16, result_high_e4m3x16;
295
+ __mmask32 mask = 0xFFFFFFFF;
296
+ nk_each_sum_e4m3_sapphire_cycle:
297
+ if (n < 32) {
298
+ mask = (__mmask32)_bzhi_u32(0xFFFFFFFF, (unsigned int)n);
299
+ a_e4m3x32 = _mm256_maskz_loadu_epi8(mask, a);
300
+ b_e4m3x32 = _mm256_maskz_loadu_epi8(mask, b);
301
+ n = 0;
302
+ }
303
+ else {
304
+ a_e4m3x32 = _mm256_loadu_si256((__m256i const *)a);
305
+ b_e4m3x32 = _mm256_loadu_si256((__m256i const *)b);
306
+ a += 32, b += 32, n -= 32;
307
+ }
308
+
309
+ // Convert e4m3x16 → f16x16 (two halves)
310
+ a_low_f16x16 = nk_e4m3x16_to_f16x16_sapphire_(_mm256_castsi256_si128(a_e4m3x32));
311
+ a_high_f16x16 = nk_e4m3x16_to_f16x16_sapphire_(_mm256_extracti128_si256(a_e4m3x32, 1));
312
+ b_low_f16x16 = nk_e4m3x16_to_f16x16_sapphire_(_mm256_castsi256_si128(b_e4m3x32));
313
+ b_high_f16x16 = nk_e4m3x16_to_f16x16_sapphire_(_mm256_extracti128_si256(b_e4m3x32, 1));
314
+
315
+ // Add in F16 - e4m3 sum is safe (max 896 < 65504)
316
+ sum_low_f16x16 = _mm256_add_ph(a_low_f16x16, b_low_f16x16);
317
+ sum_high_f16x16 = _mm256_add_ph(a_high_f16x16, b_high_f16x16);
318
+
319
+ // Convert f16x16 → e4m3x16
320
+ result_low_e4m3x16 = nk_f16x16_to_e4m3x16_sapphire_(sum_low_f16x16);
321
+ result_high_e4m3x16 = nk_f16x16_to_e4m3x16_sapphire_(sum_high_f16x16);
322
+
323
+ // Pack and store
324
+ __m256i result_e4m3x32 = _mm256_inserti128_si256(_mm256_castsi128_si256(result_low_e4m3x16), result_high_e4m3x16,
325
+ 1);
326
+ _mm256_mask_storeu_epi8(result, mask, result_e4m3x32);
327
+ result += 32;
328
+ if (n) goto nk_each_sum_e4m3_sapphire_cycle;
329
+ }
330
+
331
+ #if defined(__clang__)
332
+ #pragma clang attribute pop
333
+ #elif defined(__GNUC__)
334
+ #pragma GCC pop_options
335
+ #endif
336
+
337
+ #if defined(__cplusplus)
338
+ } // extern "C"
339
+ #endif
340
+
341
+ #endif // NK_TARGET_SAPPHIRE
342
+ #endif // NK_TARGET_X8664_
343
+ #endif // NK_EACH_SAPPHIRE_H
@@ -0,0 +1,282 @@
1
+ /**
2
+ * @brief SWAR-accelerated Elementwise Arithmetic for SIMD-free CPUs.
3
+ * @file include/numkong/each/serial.h
4
+ * @author Ash Vardanian
5
+ * @date December 27, 2025
6
+ *
7
+ * @sa include/numkong/each.h
8
+ */
9
+ #ifndef NK_EACH_SERIAL_H
10
+ #define NK_EACH_SERIAL_H
11
+
12
+ #include "numkong/types.h"
13
+ #include "numkong/cast/serial.h" // `nk_f16_to_f32_serial`
14
+
15
+ #if defined(__cplusplus)
16
+ extern "C" {
17
+ #endif
18
+
19
+ #define nk_define_each_scale_(input_type, accumulator_type, load_and_convert, convert_and_store) \
20
+ NK_PUBLIC void nk_each_scale_##input_type##_serial( \
21
+ nk_##input_type##_t const *a, nk_size_t n, nk_##accumulator_type##_t const *alpha, \
22
+ nk_##accumulator_type##_t const *beta, nk_##input_type##_t *result) { \
23
+ nk_##accumulator_type##_t alpha_val = *alpha; \
24
+ nk_##accumulator_type##_t beta_val = *beta; \
25
+ nk_##accumulator_type##_t ai, sum; \
26
+ for (nk_size_t i = 0; i != n; ++i) { \
27
+ load_and_convert(a + i, &ai); \
28
+ sum = (nk_##accumulator_type##_t)(alpha_val * ai + beta_val); \
29
+ convert_and_store(&sum, result + i); \
30
+ } \
31
+ }
32
+ #define nk_define_each_sum_(input_type, accumulator_type, load_and_convert, convert_and_store) \
33
+ NK_PUBLIC void nk_each_sum_##input_type##_serial(nk_##input_type##_t const *a, nk_##input_type##_t const *b, \
34
+ nk_size_t n, nk_##input_type##_t *result) { \
35
+ nk_##accumulator_type##_t ai, bi, sum; \
36
+ for (nk_size_t i = 0; i != n; ++i) { \
37
+ load_and_convert(a + i, &ai); \
38
+ load_and_convert(b + i, &bi); \
39
+ sum = ai + bi; \
40
+ convert_and_store(&sum, result + i); \
41
+ } \
42
+ }
43
+
44
+ #define nk_define_each_blend_(input_type, accumulator_type, load_and_convert, convert_and_store) \
45
+ NK_PUBLIC void nk_each_blend_##input_type##_serial( \
46
+ nk_##input_type##_t const *a, nk_##input_type##_t const *b, nk_size_t n, \
47
+ nk_##accumulator_type##_t const *alpha, nk_##accumulator_type##_t const *beta, nk_##input_type##_t *result) { \
48
+ nk_##accumulator_type##_t alpha_val = *alpha; \
49
+ nk_##accumulator_type##_t beta_val = *beta; \
50
+ nk_##accumulator_type##_t ai, bi, ai_scaled, bi_scaled, sum; \
51
+ for (nk_size_t i = 0; i != n; ++i) { \
52
+ load_and_convert(a + i, &ai); \
53
+ load_and_convert(b + i, &bi); \
54
+ ai_scaled = ai * alpha_val; \
55
+ bi_scaled = bi * beta_val; \
56
+ sum = ai_scaled + bi_scaled; \
57
+ convert_and_store(&sum, result + i); \
58
+ } \
59
+ }
60
+
61
+ #define nk_define_each_fma_(input_type, accumulator_type, load_and_convert, convert_and_store) \
62
+ NK_PUBLIC void nk_each_fma_##input_type##_serial( \
63
+ nk_##input_type##_t const *a, nk_##input_type##_t const *b, nk_##input_type##_t const *c, nk_size_t n, \
64
+ nk_##accumulator_type##_t const *alpha, nk_##accumulator_type##_t const *beta, nk_##input_type##_t *result) { \
65
+ nk_##accumulator_type##_t alpha_val = *alpha; \
66
+ nk_##accumulator_type##_t beta_val = *beta; \
67
+ nk_##accumulator_type##_t ai, bi, ci, abi_scaled, ci_scaled, sum; \
68
+ for (nk_size_t i = 0; i != n; ++i) { \
69
+ load_and_convert(a + i, &ai); \
70
+ load_and_convert(b + i, &bi); \
71
+ load_and_convert(c + i, &ci); \
72
+ abi_scaled = ai * bi * alpha_val; \
73
+ ci_scaled = ci * beta_val; \
74
+ sum = abi_scaled + ci_scaled; \
75
+ convert_and_store(&sum, result + i); \
76
+ } \
77
+ }
78
+
79
+ /* Optimize serial fallbacks for size — see dots/serial.h for rationale. */
80
+ #if defined(NDEBUG)
81
+ #if defined(_MSC_VER)
82
+ #pragma optimize("s", on)
83
+ #elif defined(__clang__)
84
+ #pragma clang attribute push(__attribute__((minsize)), apply_to = function)
85
+ #elif defined(__GNUC__)
86
+ #pragma GCC push_options
87
+ #pragma GCC optimize("Os")
88
+ #endif
89
+ #endif
90
+
91
+ nk_define_each_sum_(f64, f64, nk_assign_from_to_, nk_assign_from_to_) // nk_each_sum_f64_serial
92
+ nk_define_each_sum_(f32, f32, nk_assign_from_to_, nk_assign_from_to_) // nk_each_sum_f32_serial
93
+ nk_define_each_sum_(f16, f32, nk_f16_to_f32_serial, nk_f32_to_f16_serial) // nk_each_sum_f16_serial
94
+ nk_define_each_sum_(bf16, f32, nk_bf16_to_f32_serial, nk_f32_to_bf16_serial) // nk_each_sum_bf16_serial
95
+ nk_define_each_sum_(e4m3, f32, nk_e4m3_to_f32_serial, nk_f32_to_e4m3_serial) // nk_each_sum_e4m3_serial
96
+ nk_define_each_sum_(e5m2, f32, nk_e5m2_to_f32_serial, nk_f32_to_e5m2_serial) // nk_each_sum_e5m2_serial
97
+ nk_define_each_sum_(e2m3, f32, nk_e2m3_to_f32_serial, nk_f32_to_e2m3_serial) // nk_each_sum_e2m3_serial
98
+ nk_define_each_sum_(e3m2, f32, nk_e3m2_to_f32_serial, nk_f32_to_e3m2_serial) // nk_each_sum_e3m2_serial
99
+ nk_define_each_sum_(i8, i64, nk_assign_from_to_, nk_i64_to_i8_serial) // nk_each_sum_i8_serial
100
+ nk_define_each_sum_(u8, i64, nk_assign_from_to_, nk_i64_to_u8_serial) // nk_each_sum_u8_serial
101
+ nk_define_each_sum_(i16, i64, nk_assign_from_to_, nk_i64_to_i16_serial) // nk_each_sum_i16_serial
102
+ nk_define_each_sum_(u16, i64, nk_assign_from_to_, nk_i64_to_u16_serial) // nk_each_sum_u16_serial
103
+ nk_define_each_sum_(i32, i64, nk_assign_from_to_, nk_i64_to_i32_serial) // nk_each_sum_i32_serial
104
+ nk_define_each_sum_(u32, i64, nk_assign_from_to_, nk_i64_to_u32_serial) // nk_each_sum_u32_serial
105
+ nk_define_each_sum_(i64, i64, nk_assign_from_to_, nk_assign_from_to_) // nk_each_sum_i64_serial
106
+ nk_define_each_sum_(u64, u64, nk_assign_from_to_, nk_assign_from_to_) // nk_each_sum_u64_serial
107
+
108
+ nk_define_each_scale_(f64, f64, nk_assign_from_to_, nk_assign_from_to_) // nk_each_scale_f64_serial
109
+ nk_define_each_scale_(f32, f32, nk_assign_from_to_, nk_assign_from_to_) // nk_each_scale_f32_serial
110
+ nk_define_each_scale_(f16, f32, nk_f16_to_f32_serial, nk_f32_to_f16_serial) // nk_each_scale_f16_serial
111
+ nk_define_each_scale_(bf16, f32, nk_bf16_to_f32_serial, nk_f32_to_bf16_serial) // nk_each_scale_bf16_serial
112
+ nk_define_each_scale_(e4m3, f32, nk_e4m3_to_f32_serial, nk_f32_to_e4m3_serial) // nk_each_scale_e4m3_serial
113
+ nk_define_each_scale_(e5m2, f32, nk_e5m2_to_f32_serial, nk_f32_to_e5m2_serial) // nk_each_scale_e5m2_serial
114
+ nk_define_each_scale_(e2m3, f32, nk_e2m3_to_f32_serial, nk_f32_to_e2m3_serial) // nk_each_scale_e2m3_serial
115
+ nk_define_each_scale_(e3m2, f32, nk_e3m2_to_f32_serial, nk_f32_to_e3m2_serial) // nk_each_scale_e3m2_serial
116
+ nk_define_each_scale_(i8, f32, nk_assign_from_to_, nk_f32_to_i8_serial) // nk_each_scale_i8_serial
117
+ nk_define_each_scale_(u8, f32, nk_assign_from_to_, nk_f32_to_u8_serial) // nk_each_scale_u8_serial
118
+ nk_define_each_scale_(i16, f32, nk_assign_from_to_, nk_f32_to_i16_serial) // nk_each_scale_i16_serial
119
+ nk_define_each_scale_(u16, f32, nk_assign_from_to_, nk_f32_to_u16_serial) // nk_each_scale_u16_serial
120
+ nk_define_each_scale_(i32, f64, nk_assign_from_to_, nk_f64_to_i32_serial) // nk_each_scale_i32_serial
121
+ nk_define_each_scale_(u32, f64, nk_assign_from_to_, nk_f64_to_u32_serial) // nk_each_scale_u32_serial
122
+ nk_define_each_scale_(i64, f64, nk_f64_from_i64_, nk_f64_to_i64_serial) // nk_each_scale_i64_serial
123
+ nk_define_each_scale_(u64, f64, nk_f64_from_u64_, nk_f64_to_u64_serial) // nk_each_scale_u64_serial
124
+
125
+ nk_define_each_blend_(f64, f64, nk_assign_from_to_, nk_assign_from_to_) // nk_each_blend_f64_serial
126
+ nk_define_each_blend_(f32, f32, nk_assign_from_to_, nk_assign_from_to_) // nk_each_blend_f32_serial
127
+ nk_define_each_blend_(f16, f32, nk_f16_to_f32_serial, nk_f32_to_f16_serial) // nk_each_blend_f16_serial
128
+ nk_define_each_blend_(bf16, f32, nk_bf16_to_f32_serial, nk_f32_to_bf16_serial) // nk_each_blend_bf16_serial
129
+ nk_define_each_blend_(e4m3, f32, nk_e4m3_to_f32_serial, nk_f32_to_e4m3_serial) // nk_each_blend_e4m3_serial
130
+ nk_define_each_blend_(e5m2, f32, nk_e5m2_to_f32_serial, nk_f32_to_e5m2_serial) // nk_each_blend_e5m2_serial
131
+ nk_define_each_blend_(e2m3, f32, nk_e2m3_to_f32_serial, nk_f32_to_e2m3_serial) // nk_each_blend_e2m3_serial
132
+ nk_define_each_blend_(e3m2, f32, nk_e3m2_to_f32_serial, nk_f32_to_e3m2_serial) // nk_each_blend_e3m2_serial
133
+ nk_define_each_blend_(i8, f32, nk_assign_from_to_, nk_f32_to_i8_serial) // nk_each_blend_i8_serial
134
+ nk_define_each_blend_(u8, f32, nk_assign_from_to_, nk_f32_to_u8_serial) // nk_each_blend_u8_serial
135
+ nk_define_each_blend_(i16, f32, nk_assign_from_to_, nk_f32_to_i16_serial) // nk_each_blend_i16_serial
136
+ nk_define_each_blend_(u16, f32, nk_assign_from_to_, nk_f32_to_u16_serial) // nk_each_blend_u16_serial
137
+ nk_define_each_blend_(i32, f64, nk_assign_from_to_, nk_f64_to_i32_serial) // nk_each_blend_i32_serial
138
+ nk_define_each_blend_(u32, f64, nk_assign_from_to_, nk_f64_to_u32_serial) // nk_each_blend_u32_serial
139
+ nk_define_each_blend_(i64, f64, nk_f64_from_i64_, nk_f64_to_i64_serial) // nk_each_blend_i64_serial
140
+ nk_define_each_blend_(u64, f64, nk_f64_from_u64_, nk_f64_to_u64_serial) // nk_each_blend_u64_serial
141
+
142
+ nk_define_each_fma_(f64, f64, nk_assign_from_to_, nk_assign_from_to_) // nk_each_fma_f64_serial
143
+ nk_define_each_fma_(f32, f32, nk_assign_from_to_, nk_assign_from_to_) // nk_each_fma_f32_serial
144
+ nk_define_each_fma_(f16, f32, nk_f16_to_f32_serial, nk_f32_to_f16_serial) // nk_each_fma_f16_serial
145
+ nk_define_each_fma_(bf16, f32, nk_bf16_to_f32_serial, nk_f32_to_bf16_serial) // nk_each_fma_bf16_serial
146
+ nk_define_each_fma_(e4m3, f32, nk_e4m3_to_f32_serial, nk_f32_to_e4m3_serial) // nk_each_fma_e4m3_serial
147
+ nk_define_each_fma_(e5m2, f32, nk_e5m2_to_f32_serial, nk_f32_to_e5m2_serial) // nk_each_fma_e5m2_serial
148
+ nk_define_each_fma_(e2m3, f32, nk_e2m3_to_f32_serial, nk_f32_to_e2m3_serial) // nk_each_fma_e2m3_serial
149
+ nk_define_each_fma_(e3m2, f32, nk_e3m2_to_f32_serial, nk_f32_to_e3m2_serial) // nk_each_fma_e3m2_serial
150
+ nk_define_each_fma_(i8, f32, nk_assign_from_to_, nk_f32_to_i8_serial) // nk_each_fma_i8_serial
151
+ nk_define_each_fma_(u8, f32, nk_assign_from_to_, nk_f32_to_u8_serial) // nk_each_fma_u8_serial
152
+ nk_define_each_fma_(i16, f32, nk_assign_from_to_, nk_f32_to_i16_serial) // nk_each_fma_i16_serial
153
+ nk_define_each_fma_(u16, f32, nk_assign_from_to_, nk_f32_to_u16_serial) // nk_each_fma_u16_serial
154
+ nk_define_each_fma_(i32, f64, nk_assign_from_to_, nk_f64_to_i32_serial) // nk_each_fma_i32_serial
155
+ nk_define_each_fma_(u32, f64, nk_assign_from_to_, nk_f64_to_u32_serial) // nk_each_fma_u32_serial
156
+ nk_define_each_fma_(i64, f64, nk_f64_from_i64_, nk_f64_to_i64_serial) // nk_each_fma_i64_serial
157
+ nk_define_each_fma_(u64, f64, nk_f64_from_u64_, nk_f64_to_u64_serial) // nk_each_fma_u64_serial
158
+
159
+ #undef nk_define_each_scale_
160
+ #undef nk_define_each_sum_
161
+ #undef nk_define_each_blend_
162
+ #undef nk_define_each_fma_
163
+
164
+ NK_DYNAMIC void nk_each_sum_f32(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f32_t *result);
165
+
166
+ NK_PUBLIC void nk_each_sum_f32c_serial(nk_f32c_t const *a, nk_f32c_t const *b, nk_size_t n, nk_f32c_t *result) {
167
+ nk_each_sum_f32((nk_f32_t const *)a, (nk_f32_t const *)b, 2 * n, (nk_f32_t *)result);
168
+ }
169
+
170
+ NK_PUBLIC void nk_each_sum_f64c_serial(nk_f64c_t const *a, nk_f64c_t const *b, nk_size_t n, nk_f64c_t *result) {
171
+ nk_each_sum_f64((nk_f64_t const *)a, (nk_f64_t const *)b, 2 * n, (nk_f64_t *)result);
172
+ }
173
+
174
+ NK_DYNAMIC void nk_each_sum_f64(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
175
+
176
+ NK_PUBLIC void nk_each_scale_f32c_serial(nk_f32c_t const *a, nk_size_t n, nk_f32c_t const *alpha, nk_f32c_t const *beta,
177
+ nk_f32c_t *result) {
178
+ nk_f32_t alpha_real = alpha->real, alpha_imag = alpha->imag;
179
+ nk_f32_t beta_real = beta->real, beta_imag = beta->imag;
180
+ for (nk_size_t i = 0; i != n; ++i) {
181
+ nk_f32_t a_real = a[i].real, a_imag = a[i].imag;
182
+ result[i].real = alpha_real * a_real - alpha_imag * a_imag + beta_real;
183
+ result[i].imag = alpha_real * a_imag + alpha_imag * a_real + beta_imag;
184
+ }
185
+ }
186
+
187
+ NK_PUBLIC void nk_each_scale_f64c_serial(nk_f64c_t const *a, nk_size_t n, nk_f64c_t const *alpha, nk_f64c_t const *beta,
188
+ nk_f64c_t *result) {
189
+ nk_f64_t alpha_real = alpha->real, alpha_imag = alpha->imag;
190
+ nk_f64_t beta_real = beta->real, beta_imag = beta->imag;
191
+ for (nk_size_t i = 0; i != n; ++i) {
192
+ nk_f64_t a_real = a[i].real, a_imag = a[i].imag;
193
+ result[i].real = alpha_real * a_real - alpha_imag * a_imag + beta_real;
194
+ result[i].imag = alpha_real * a_imag + alpha_imag * a_real + beta_imag;
195
+ }
196
+ }
197
+
198
+ NK_PUBLIC void nk_each_blend_f32c_serial(nk_f32c_t const *a, nk_f32c_t const *b, nk_size_t n, nk_f32c_t const *alpha,
199
+ nk_f32c_t const *beta, nk_f32c_t *result) {
200
+ nk_f32_t alpha_real = alpha->real, alpha_imag = alpha->imag;
201
+ nk_f32_t beta_real = beta->real, beta_imag = beta->imag;
202
+ for (nk_size_t i = 0; i != n; ++i) {
203
+ nk_f32_t a_real = a[i].real, a_imag = a[i].imag;
204
+ nk_f32_t b_real = b[i].real, b_imag = b[i].imag;
205
+ nk_f32_t alpha_a_real = alpha_real * a_real - alpha_imag * a_imag;
206
+ nk_f32_t alpha_a_imag = alpha_real * a_imag + alpha_imag * a_real;
207
+ nk_f32_t beta_b_real = beta_real * b_real - beta_imag * b_imag;
208
+ nk_f32_t beta_b_imag = beta_real * b_imag + beta_imag * b_real;
209
+ result[i].real = alpha_a_real + beta_b_real;
210
+ result[i].imag = alpha_a_imag + beta_b_imag;
211
+ }
212
+ }
213
+
214
+ NK_PUBLIC void nk_each_blend_f64c_serial(nk_f64c_t const *a, nk_f64c_t const *b, nk_size_t n, nk_f64c_t const *alpha,
215
+ nk_f64c_t const *beta, nk_f64c_t *result) {
216
+ nk_f64_t alpha_real = alpha->real, alpha_imag = alpha->imag;
217
+ nk_f64_t beta_real = beta->real, beta_imag = beta->imag;
218
+ for (nk_size_t i = 0; i != n; ++i) {
219
+ nk_f64_t a_real = a[i].real, a_imag = a[i].imag;
220
+ nk_f64_t b_real = b[i].real, b_imag = b[i].imag;
221
+ nk_f64_t alpha_a_real = alpha_real * a_real - alpha_imag * a_imag;
222
+ nk_f64_t alpha_a_imag = alpha_real * a_imag + alpha_imag * a_real;
223
+ nk_f64_t beta_b_real = beta_real * b_real - beta_imag * b_imag;
224
+ nk_f64_t beta_b_imag = beta_real * b_imag + beta_imag * b_real;
225
+ result[i].real = alpha_a_real + beta_b_real;
226
+ result[i].imag = alpha_a_imag + beta_b_imag;
227
+ }
228
+ }
229
+
230
+ NK_PUBLIC void nk_each_fma_f32c_serial(nk_f32c_t const *a, nk_f32c_t const *b, nk_f32c_t const *c, nk_size_t n,
231
+ nk_f32c_t const *alpha, nk_f32c_t const *beta, nk_f32c_t *result) {
232
+ nk_f32_t alpha_real = alpha->real, alpha_imag = alpha->imag;
233
+ nk_f32_t beta_real = beta->real, beta_imag = beta->imag;
234
+ for (nk_size_t i = 0; i != n; ++i) {
235
+ nk_f32_t a_real = a[i].real, a_imag = a[i].imag;
236
+ nk_f32_t b_real = b[i].real, b_imag = b[i].imag;
237
+ nk_f32_t c_real = c[i].real, c_imag = c[i].imag;
238
+ nk_f32_t product_real = a_real * b_real - a_imag * b_imag;
239
+ nk_f32_t product_imag = a_real * b_imag + a_imag * b_real;
240
+ nk_f32_t alpha_product_real = alpha_real * product_real - alpha_imag * product_imag;
241
+ nk_f32_t alpha_product_imag = alpha_real * product_imag + alpha_imag * product_real;
242
+ nk_f32_t beta_c_real = beta_real * c_real - beta_imag * c_imag;
243
+ nk_f32_t beta_c_imag = beta_real * c_imag + beta_imag * c_real;
244
+ result[i].real = alpha_product_real + beta_c_real;
245
+ result[i].imag = alpha_product_imag + beta_c_imag;
246
+ }
247
+ }
248
+
249
+ NK_PUBLIC void nk_each_fma_f64c_serial(nk_f64c_t const *a, nk_f64c_t const *b, nk_f64c_t const *c, nk_size_t n,
250
+ nk_f64c_t const *alpha, nk_f64c_t const *beta, nk_f64c_t *result) {
251
+ nk_f64_t alpha_real = alpha->real, alpha_imag = alpha->imag;
252
+ nk_f64_t beta_real = beta->real, beta_imag = beta->imag;
253
+ for (nk_size_t i = 0; i != n; ++i) {
254
+ nk_f64_t a_real = a[i].real, a_imag = a[i].imag;
255
+ nk_f64_t b_real = b[i].real, b_imag = b[i].imag;
256
+ nk_f64_t c_real = c[i].real, c_imag = c[i].imag;
257
+ nk_f64_t product_real = a_real * b_real - a_imag * b_imag;
258
+ nk_f64_t product_imag = a_real * b_imag + a_imag * b_real;
259
+ nk_f64_t alpha_product_real = alpha_real * product_real - alpha_imag * product_imag;
260
+ nk_f64_t alpha_product_imag = alpha_real * product_imag + alpha_imag * product_real;
261
+ nk_f64_t beta_c_real = beta_real * c_real - beta_imag * c_imag;
262
+ nk_f64_t beta_c_imag = beta_real * c_imag + beta_imag * c_real;
263
+ result[i].real = alpha_product_real + beta_c_real;
264
+ result[i].imag = alpha_product_imag + beta_c_imag;
265
+ }
266
+ }
267
+
268
+ #if defined(NDEBUG)
269
+ #if defined(_MSC_VER)
270
+ #pragma optimize("", on)
271
+ #elif defined(__clang__)
272
+ #pragma clang attribute pop
273
+ #elif defined(__GNUC__)
274
+ #pragma GCC pop_options
275
+ #endif
276
+ #endif
277
+
278
+ #if defined(__cplusplus)
279
+ } // extern "C"
280
+ #endif
281
+
282
+ #endif // NK_EACH_SERIAL_H