usearch 2.21.4 → 2.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. package/README.md +65 -69
  2. package/binding.gyp +15 -37
  3. package/c/CMakeLists.txt +4 -5
  4. package/c/README.md +8 -8
  5. package/c/lib.cpp +32 -14
  6. package/c/test.c +124 -1
  7. package/c/usearch.h +24 -3
  8. package/cpp/CMakeLists.txt +4 -0
  9. package/cpp/README.md +5 -5
  10. package/cpp/bench.cpp +97 -116
  11. package/cpp/test.cpp +117 -20
  12. package/include/usearch/index.hpp +224 -48
  13. package/include/usearch/index_dense.hpp +105 -40
  14. package/include/usearch/index_plugins.hpp +1387 -204
  15. package/javascript/README.md +1 -1
  16. package/javascript/dist/cjs/usearch.d.ts +8 -3
  17. package/javascript/dist/cjs/usearch.js +12 -4
  18. package/javascript/dist/esm/usearch.d.ts +8 -3
  19. package/javascript/dist/esm/usearch.js +12 -4
  20. package/javascript/lib.cpp +17 -0
  21. package/javascript/usearch.test.js +117 -94
  22. package/javascript/usearch.ts +14 -6
  23. package/numkong/.clang-tidy +30 -0
  24. package/{simsimd → numkong}/.cmake-format.py +18 -0
  25. package/numkong/.editorconfig +12 -0
  26. package/numkong/.git-blame-ignore-revs +123 -0
  27. package/numkong/.mailmap +15 -0
  28. package/numkong/.spi.yml +11 -0
  29. package/numkong/.swift-format +14 -0
  30. package/numkong/CITATION.cff +81 -0
  31. package/numkong/CONTRIBUTING.md +500 -0
  32. package/numkong/Cargo.toml +54 -0
  33. package/numkong/MANIFEST.in +8 -0
  34. package/numkong/Package.swift +84 -0
  35. package/numkong/README.md +569 -0
  36. package/numkong/bench/README.md +217 -0
  37. package/numkong/bench/bench-browser.html +323 -0
  38. package/numkong/bench/bench.cpp +344 -0
  39. package/numkong/bench/bench.hpp +816 -0
  40. package/numkong/bench/bench.js +148 -0
  41. package/numkong/bench/bench.mjs +616 -0
  42. package/numkong/bench/bench_attention.cpp +113 -0
  43. package/numkong/bench/bench_cast.cpp +264 -0
  44. package/numkong/bench/bench_cross_amx.cpp +62 -0
  45. package/numkong/bench/bench_cross_arm.cpp +245 -0
  46. package/numkong/bench/bench_cross_blas.cpp +309 -0
  47. package/numkong/bench/bench_cross_loongarch.cpp +106 -0
  48. package/numkong/bench/bench_cross_power.cpp +84 -0
  49. package/numkong/bench/bench_cross_rvv.cpp +121 -0
  50. package/numkong/bench/bench_cross_serial.cpp +151 -0
  51. package/numkong/bench/bench_cross_sme.cpp +163 -0
  52. package/numkong/bench/bench_cross_wasm.cpp +142 -0
  53. package/numkong/bench/bench_cross_x86.cpp +455 -0
  54. package/numkong/bench/bench_curved.cpp +210 -0
  55. package/numkong/bench/bench_dot.cpp +315 -0
  56. package/numkong/bench/bench_each.cpp +503 -0
  57. package/numkong/bench/bench_geospatial.cpp +112 -0
  58. package/numkong/bench/bench_maxsim.cpp +154 -0
  59. package/numkong/bench/bench_mesh.cpp +148 -0
  60. package/numkong/bench/bench_probability.cpp +60 -0
  61. package/numkong/bench/bench_reduce.cpp +371 -0
  62. package/numkong/bench/bench_set.cpp +73 -0
  63. package/numkong/bench/bench_sparse.cpp +198 -0
  64. package/numkong/bench/bench_spatial.cpp +347 -0
  65. package/numkong/bench/bench_trigonometry.cpp +137 -0
  66. package/numkong/bench/swift/Bench.swift +506 -0
  67. package/numkong/binding.gyp +169 -0
  68. package/numkong/build.rs +484 -0
  69. package/numkong/c/dispatch.h +512 -0
  70. package/numkong/c/dispatch_bf16.c +447 -0
  71. package/numkong/c/dispatch_bf16c.c +52 -0
  72. package/numkong/c/dispatch_e2m3.c +296 -0
  73. package/numkong/c/dispatch_e3m2.c +284 -0
  74. package/numkong/c/dispatch_e4m3.c +318 -0
  75. package/numkong/c/dispatch_e5m2.c +316 -0
  76. package/numkong/c/dispatch_f16.c +452 -0
  77. package/numkong/c/dispatch_f16c.c +58 -0
  78. package/numkong/c/dispatch_f32.c +434 -0
  79. package/numkong/c/dispatch_f32c.c +99 -0
  80. package/numkong/c/dispatch_f64.c +348 -0
  81. package/numkong/c/dispatch_f64c.c +98 -0
  82. package/numkong/c/dispatch_i16.c +96 -0
  83. package/numkong/c/dispatch_i32.c +89 -0
  84. package/numkong/c/dispatch_i4.c +153 -0
  85. package/numkong/c/dispatch_i64.c +86 -0
  86. package/numkong/c/dispatch_i8.c +348 -0
  87. package/numkong/c/dispatch_other.c +348 -0
  88. package/numkong/c/dispatch_u1.c +193 -0
  89. package/numkong/c/dispatch_u16.c +124 -0
  90. package/numkong/c/dispatch_u32.c +118 -0
  91. package/numkong/c/dispatch_u4.c +153 -0
  92. package/numkong/c/dispatch_u64.c +102 -0
  93. package/numkong/c/dispatch_u8.c +364 -0
  94. package/numkong/c/numkong.c +940 -0
  95. package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
  96. package/numkong/cmake/nk_isa_probe.cmake +90 -0
  97. package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
  98. package/numkong/cmake/nk_math_lib.cmake +46 -0
  99. package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
  100. package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
  101. package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
  102. package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
  103. package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
  104. package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
  105. package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
  106. package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
  107. package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
  108. package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
  109. package/numkong/cmake/toolchain-wasi.cmake +77 -0
  110. package/numkong/cmake/toolchain-wasm.cmake +70 -0
  111. package/numkong/cmake/toolchain-wasm64.cmake +62 -0
  112. package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
  113. package/numkong/include/README.md +643 -0
  114. package/numkong/include/module.modulemap +129 -0
  115. package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
  116. package/numkong/include/numkong/attention/sme.h +2075 -0
  117. package/numkong/include/numkong/attention.h +49 -0
  118. package/numkong/include/numkong/capabilities.h +930 -0
  119. package/numkong/include/numkong/cast/README.md +262 -0
  120. package/numkong/include/numkong/cast/diamond.h +64 -0
  121. package/numkong/include/numkong/cast/haswell.h +823 -0
  122. package/numkong/include/numkong/cast/icelake.h +475 -0
  123. package/numkong/include/numkong/cast/loongsonasx.h +252 -0
  124. package/numkong/include/numkong/cast/neon.h +1174 -0
  125. package/numkong/include/numkong/cast/powervsx.h +449 -0
  126. package/numkong/include/numkong/cast/rvv.h +970 -0
  127. package/numkong/include/numkong/cast/sapphire.h +262 -0
  128. package/numkong/include/numkong/cast/serial.h +2336 -0
  129. package/numkong/include/numkong/cast/skylake.h +915 -0
  130. package/numkong/include/numkong/cast/v128relaxed.h +537 -0
  131. package/numkong/include/numkong/cast.h +254 -0
  132. package/numkong/include/numkong/cast.hpp +44 -0
  133. package/numkong/include/numkong/curved/README.md +223 -0
  134. package/numkong/include/numkong/curved/genoa.h +182 -0
  135. package/numkong/include/numkong/curved/haswell.h +276 -0
  136. package/numkong/include/numkong/curved/neon.h +329 -0
  137. package/numkong/include/numkong/curved/neonbfdot.h +211 -0
  138. package/numkong/include/numkong/curved/rvv.h +305 -0
  139. package/numkong/include/numkong/curved/serial.h +207 -0
  140. package/numkong/include/numkong/curved/skylake.h +457 -0
  141. package/numkong/include/numkong/curved/smef64.h +530 -0
  142. package/numkong/include/numkong/curved.h +513 -0
  143. package/numkong/include/numkong/curved.hpp +144 -0
  144. package/numkong/include/numkong/dot/README.md +442 -0
  145. package/numkong/include/numkong/dot/alder.h +563 -0
  146. package/numkong/include/numkong/dot/diamond.h +158 -0
  147. package/numkong/include/numkong/dot/genoa.h +289 -0
  148. package/numkong/include/numkong/dot/haswell.h +1723 -0
  149. package/numkong/include/numkong/dot/icelake.h +997 -0
  150. package/numkong/include/numkong/dot/loongsonasx.h +671 -0
  151. package/numkong/include/numkong/dot/neon.h +869 -0
  152. package/numkong/include/numkong/dot/neonbfdot.h +243 -0
  153. package/numkong/include/numkong/dot/neonfhm.h +358 -0
  154. package/numkong/include/numkong/dot/neonfp8.h +323 -0
  155. package/numkong/include/numkong/dot/neonsdot.h +622 -0
  156. package/numkong/include/numkong/dot/powervsx.h +752 -0
  157. package/numkong/include/numkong/dot/rvv.h +722 -0
  158. package/numkong/include/numkong/dot/rvvbb.h +72 -0
  159. package/numkong/include/numkong/dot/rvvbf16.h +123 -0
  160. package/numkong/include/numkong/dot/rvvhalf.h +129 -0
  161. package/numkong/include/numkong/dot/sapphire.h +141 -0
  162. package/numkong/include/numkong/dot/serial.h +874 -0
  163. package/numkong/include/numkong/dot/sierra.h +405 -0
  164. package/numkong/include/numkong/dot/skylake.h +1116 -0
  165. package/numkong/include/numkong/dot/sve.h +420 -0
  166. package/numkong/include/numkong/dot/svebfdot.h +75 -0
  167. package/numkong/include/numkong/dot/svehalf.h +168 -0
  168. package/numkong/include/numkong/dot/svesdot.h +90 -0
  169. package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
  170. package/numkong/include/numkong/dot.h +1136 -0
  171. package/numkong/include/numkong/dot.hpp +94 -0
  172. package/numkong/include/numkong/dots/README.md +496 -0
  173. package/numkong/include/numkong/dots/alder.h +117 -0
  174. package/numkong/include/numkong/dots/diamond.h +86 -0
  175. package/numkong/include/numkong/dots/genoa.h +100 -0
  176. package/numkong/include/numkong/dots/graniteamx.h +733 -0
  177. package/numkong/include/numkong/dots/haswell.h +310 -0
  178. package/numkong/include/numkong/dots/icelake.h +180 -0
  179. package/numkong/include/numkong/dots/loongsonasx.h +176 -0
  180. package/numkong/include/numkong/dots/neon.h +123 -0
  181. package/numkong/include/numkong/dots/neonbfdot.h +59 -0
  182. package/numkong/include/numkong/dots/neonfhm.h +96 -0
  183. package/numkong/include/numkong/dots/neonfp8.h +99 -0
  184. package/numkong/include/numkong/dots/neonsdot.h +144 -0
  185. package/numkong/include/numkong/dots/powervsx.h +194 -0
  186. package/numkong/include/numkong/dots/rvv.h +2593 -0
  187. package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
  188. package/numkong/include/numkong/dots/serial.h +2867 -0
  189. package/numkong/include/numkong/dots/sierra.h +100 -0
  190. package/numkong/include/numkong/dots/skylake.h +207 -0
  191. package/numkong/include/numkong/dots/sme.h +5041 -0
  192. package/numkong/include/numkong/dots/smebi32.h +477 -0
  193. package/numkong/include/numkong/dots/smef64.h +1328 -0
  194. package/numkong/include/numkong/dots/smehalf.h +47 -0
  195. package/numkong/include/numkong/dots/v128relaxed.h +317 -0
  196. package/numkong/include/numkong/dots.h +3110 -0
  197. package/numkong/include/numkong/dots.hpp +641 -0
  198. package/numkong/include/numkong/each/README.md +465 -0
  199. package/numkong/include/numkong/each/haswell.h +1658 -0
  200. package/numkong/include/numkong/each/icelake.h +272 -0
  201. package/numkong/include/numkong/each/neon.h +1138 -0
  202. package/numkong/include/numkong/each/neonbfdot.h +211 -0
  203. package/numkong/include/numkong/each/neonhalf.h +318 -0
  204. package/numkong/include/numkong/each/rvv.h +1121 -0
  205. package/numkong/include/numkong/each/sapphire.h +343 -0
  206. package/numkong/include/numkong/each/serial.h +282 -0
  207. package/numkong/include/numkong/each/skylake.h +1562 -0
  208. package/numkong/include/numkong/each/v128relaxed.h +562 -0
  209. package/numkong/include/numkong/each.h +2232 -0
  210. package/numkong/include/numkong/each.hpp +434 -0
  211. package/numkong/include/numkong/geospatial/README.md +147 -0
  212. package/numkong/include/numkong/geospatial/haswell.h +633 -0
  213. package/numkong/include/numkong/geospatial/neon.h +615 -0
  214. package/numkong/include/numkong/geospatial/rvv.h +701 -0
  215. package/numkong/include/numkong/geospatial/serial.h +309 -0
  216. package/numkong/include/numkong/geospatial/skylake.h +613 -0
  217. package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
  218. package/numkong/include/numkong/geospatial.h +453 -0
  219. package/numkong/include/numkong/geospatial.hpp +235 -0
  220. package/numkong/include/numkong/matrix.hpp +336 -0
  221. package/numkong/include/numkong/maxsim/README.md +187 -0
  222. package/numkong/include/numkong/maxsim/alder.h +511 -0
  223. package/numkong/include/numkong/maxsim/genoa.h +115 -0
  224. package/numkong/include/numkong/maxsim/haswell.h +553 -0
  225. package/numkong/include/numkong/maxsim/icelake.h +480 -0
  226. package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
  227. package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
  228. package/numkong/include/numkong/maxsim/serial.h +490 -0
  229. package/numkong/include/numkong/maxsim/sme.h +993 -0
  230. package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
  231. package/numkong/include/numkong/maxsim.h +571 -0
  232. package/numkong/include/numkong/maxsim.hpp +133 -0
  233. package/numkong/include/numkong/mesh/README.md +219 -0
  234. package/numkong/include/numkong/mesh/haswell.h +2013 -0
  235. package/numkong/include/numkong/mesh/neon.h +1821 -0
  236. package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
  237. package/numkong/include/numkong/mesh/rvv.h +936 -0
  238. package/numkong/include/numkong/mesh/serial.h +721 -0
  239. package/numkong/include/numkong/mesh/skylake.h +2344 -0
  240. package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
  241. package/numkong/include/numkong/mesh.h +666 -0
  242. package/numkong/include/numkong/mesh.hpp +701 -0
  243. package/numkong/include/numkong/numkong.h +78 -0
  244. package/numkong/include/numkong/numkong.hpp +58 -0
  245. package/numkong/include/numkong/probability/README.md +177 -0
  246. package/numkong/include/numkong/probability/haswell.h +267 -0
  247. package/numkong/include/numkong/probability/neon.h +255 -0
  248. package/numkong/include/numkong/probability/rvv.h +414 -0
  249. package/numkong/include/numkong/probability/serial.h +181 -0
  250. package/numkong/include/numkong/probability/skylake.h +324 -0
  251. package/numkong/include/numkong/probability.h +380 -0
  252. package/numkong/include/numkong/probability.hpp +120 -0
  253. package/numkong/include/numkong/random.h +50 -0
  254. package/numkong/include/numkong/random.hpp +285 -0
  255. package/numkong/include/numkong/reduce/README.md +552 -0
  256. package/numkong/include/numkong/reduce/alder.h +636 -0
  257. package/numkong/include/numkong/reduce/genoa.h +201 -0
  258. package/numkong/include/numkong/reduce/haswell.h +3785 -0
  259. package/numkong/include/numkong/reduce/icelake.h +549 -0
  260. package/numkong/include/numkong/reduce/neon.h +3980 -0
  261. package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
  262. package/numkong/include/numkong/reduce/neonfhm.h +293 -0
  263. package/numkong/include/numkong/reduce/neonsdot.h +357 -0
  264. package/numkong/include/numkong/reduce/rvv.h +3533 -0
  265. package/numkong/include/numkong/reduce/serial.h +753 -0
  266. package/numkong/include/numkong/reduce/sierra.h +338 -0
  267. package/numkong/include/numkong/reduce/skylake.h +3794 -0
  268. package/numkong/include/numkong/reduce/sve.h +52 -0
  269. package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
  270. package/numkong/include/numkong/reduce.h +1582 -0
  271. package/numkong/include/numkong/reduce.hpp +778 -0
  272. package/numkong/include/numkong/scalar/README.md +89 -0
  273. package/numkong/include/numkong/scalar/haswell.h +122 -0
  274. package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
  275. package/numkong/include/numkong/scalar/neon.h +122 -0
  276. package/numkong/include/numkong/scalar/neonhalf.h +70 -0
  277. package/numkong/include/numkong/scalar/powervsx.h +96 -0
  278. package/numkong/include/numkong/scalar/rvv.h +211 -0
  279. package/numkong/include/numkong/scalar/sapphire.h +74 -0
  280. package/numkong/include/numkong/scalar/serial.h +332 -0
  281. package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
  282. package/numkong/include/numkong/scalar.h +696 -0
  283. package/numkong/include/numkong/set/README.md +179 -0
  284. package/numkong/include/numkong/set/haswell.h +334 -0
  285. package/numkong/include/numkong/set/icelake.h +485 -0
  286. package/numkong/include/numkong/set/loongsonasx.h +181 -0
  287. package/numkong/include/numkong/set/neon.h +363 -0
  288. package/numkong/include/numkong/set/powervsx.h +326 -0
  289. package/numkong/include/numkong/set/rvv.h +226 -0
  290. package/numkong/include/numkong/set/rvvbb.h +117 -0
  291. package/numkong/include/numkong/set/serial.h +174 -0
  292. package/numkong/include/numkong/set/sve.h +187 -0
  293. package/numkong/include/numkong/set/v128relaxed.h +240 -0
  294. package/numkong/include/numkong/set.h +471 -0
  295. package/numkong/include/numkong/set.hpp +114 -0
  296. package/numkong/include/numkong/sets/README.md +149 -0
  297. package/numkong/include/numkong/sets/haswell.h +63 -0
  298. package/numkong/include/numkong/sets/icelake.h +66 -0
  299. package/numkong/include/numkong/sets/loongsonasx.h +52 -0
  300. package/numkong/include/numkong/sets/neon.h +61 -0
  301. package/numkong/include/numkong/sets/powervsx.h +65 -0
  302. package/numkong/include/numkong/sets/serial.h +43 -0
  303. package/numkong/include/numkong/sets/smebi32.h +1135 -0
  304. package/numkong/include/numkong/sets/v128relaxed.h +58 -0
  305. package/numkong/include/numkong/sets.h +382 -0
  306. package/numkong/include/numkong/sparse/README.md +156 -0
  307. package/numkong/include/numkong/sparse/icelake.h +463 -0
  308. package/numkong/include/numkong/sparse/neon.h +288 -0
  309. package/numkong/include/numkong/sparse/serial.h +117 -0
  310. package/numkong/include/numkong/sparse/sve2.h +504 -0
  311. package/numkong/include/numkong/sparse/turin.h +322 -0
  312. package/numkong/include/numkong/sparse.h +363 -0
  313. package/numkong/include/numkong/sparse.hpp +113 -0
  314. package/numkong/include/numkong/spatial/README.md +439 -0
  315. package/numkong/include/numkong/spatial/alder.h +604 -0
  316. package/numkong/include/numkong/spatial/diamond.h +240 -0
  317. package/numkong/include/numkong/spatial/genoa.h +222 -0
  318. package/numkong/include/numkong/spatial/haswell.h +979 -0
  319. package/numkong/include/numkong/spatial/icelake.h +1067 -0
  320. package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
  321. package/numkong/include/numkong/spatial/neon.h +846 -0
  322. package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
  323. package/numkong/include/numkong/spatial/neonfp8.h +258 -0
  324. package/numkong/include/numkong/spatial/neonsdot.h +429 -0
  325. package/numkong/include/numkong/spatial/powervsx.h +738 -0
  326. package/numkong/include/numkong/spatial/rvv.h +991 -0
  327. package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
  328. package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
  329. package/numkong/include/numkong/spatial/serial.h +347 -0
  330. package/numkong/include/numkong/spatial/sierra.h +516 -0
  331. package/numkong/include/numkong/spatial/skylake.h +605 -0
  332. package/numkong/include/numkong/spatial/sve.h +246 -0
  333. package/numkong/include/numkong/spatial/svebfdot.h +125 -0
  334. package/numkong/include/numkong/spatial/svehalf.h +136 -0
  335. package/numkong/include/numkong/spatial/svesdot.h +143 -0
  336. package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
  337. package/numkong/include/numkong/spatial.h +1681 -0
  338. package/numkong/include/numkong/spatial.hpp +183 -0
  339. package/numkong/include/numkong/spatials/README.md +580 -0
  340. package/numkong/include/numkong/spatials/alder.h +94 -0
  341. package/numkong/include/numkong/spatials/diamond.h +82 -0
  342. package/numkong/include/numkong/spatials/genoa.h +94 -0
  343. package/numkong/include/numkong/spatials/graniteamx.h +173 -0
  344. package/numkong/include/numkong/spatials/haswell.h +219 -0
  345. package/numkong/include/numkong/spatials/icelake.h +113 -0
  346. package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
  347. package/numkong/include/numkong/spatials/neon.h +109 -0
  348. package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
  349. package/numkong/include/numkong/spatials/neonfhm.h +92 -0
  350. package/numkong/include/numkong/spatials/neonfp8.h +111 -0
  351. package/numkong/include/numkong/spatials/neonsdot.h +143 -0
  352. package/numkong/include/numkong/spatials/powervsx.h +153 -0
  353. package/numkong/include/numkong/spatials/rvv.h +1976 -0
  354. package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
  355. package/numkong/include/numkong/spatials/serial.h +248 -0
  356. package/numkong/include/numkong/spatials/sierra.h +96 -0
  357. package/numkong/include/numkong/spatials/skylake.h +184 -0
  358. package/numkong/include/numkong/spatials/sme.h +1927 -0
  359. package/numkong/include/numkong/spatials/smef64.h +483 -0
  360. package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
  361. package/numkong/include/numkong/spatials.h +3374 -0
  362. package/numkong/include/numkong/spatials.hpp +509 -0
  363. package/numkong/include/numkong/tensor.hpp +1981 -0
  364. package/numkong/include/numkong/trigonometry/README.md +184 -0
  365. package/numkong/include/numkong/trigonometry/haswell.h +653 -0
  366. package/numkong/include/numkong/trigonometry/neon.h +638 -0
  367. package/numkong/include/numkong/trigonometry/rvv.h +700 -0
  368. package/numkong/include/numkong/trigonometry/serial.h +703 -0
  369. package/numkong/include/numkong/trigonometry/skylake.h +725 -0
  370. package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
  371. package/numkong/include/numkong/trigonometry.h +467 -0
  372. package/numkong/include/numkong/trigonometry.hpp +166 -0
  373. package/numkong/include/numkong/types.h +1695 -0
  374. package/numkong/include/numkong/types.hpp +6027 -0
  375. package/numkong/include/numkong/vector.hpp +766 -0
  376. package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
  377. package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
  378. package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
  379. package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
  380. package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
  381. package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
  382. package/numkong/javascript/README.md +254 -0
  383. package/numkong/javascript/node-gyp-build.d.ts +4 -0
  384. package/numkong/javascript/numkong-browser.ts +40 -0
  385. package/numkong/javascript/numkong-wasm.ts +750 -0
  386. package/numkong/javascript/numkong.c +712 -0
  387. package/numkong/javascript/numkong.ts +613 -0
  388. package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
  389. package/numkong/javascript/tsconfig-cjs.json +13 -0
  390. package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
  391. package/numkong/javascript/types.ts +784 -0
  392. package/numkong/numkong.gypi +104 -0
  393. package/numkong/package.json +108 -0
  394. package/numkong/probes/arm_neon.c +8 -0
  395. package/numkong/probes/arm_neon_bfdot.c +9 -0
  396. package/numkong/probes/arm_neon_fhm.c +9 -0
  397. package/numkong/probes/arm_neon_half.c +8 -0
  398. package/numkong/probes/arm_neon_sdot.c +9 -0
  399. package/numkong/probes/arm_neonfp8.c +9 -0
  400. package/numkong/probes/arm_sme.c +16 -0
  401. package/numkong/probes/arm_sme2.c +16 -0
  402. package/numkong/probes/arm_sme2p1.c +16 -0
  403. package/numkong/probes/arm_sme_bf16.c +16 -0
  404. package/numkong/probes/arm_sme_bi32.c +16 -0
  405. package/numkong/probes/arm_sme_f64.c +16 -0
  406. package/numkong/probes/arm_sme_fa64.c +14 -0
  407. package/numkong/probes/arm_sme_half.c +16 -0
  408. package/numkong/probes/arm_sme_lut2.c +15 -0
  409. package/numkong/probes/arm_sve.c +18 -0
  410. package/numkong/probes/arm_sve2.c +20 -0
  411. package/numkong/probes/arm_sve2p1.c +18 -0
  412. package/numkong/probes/arm_sve_bfdot.c +20 -0
  413. package/numkong/probes/arm_sve_half.c +18 -0
  414. package/numkong/probes/arm_sve_sdot.c +21 -0
  415. package/numkong/probes/loongarch_lasx.c +12 -0
  416. package/numkong/probes/power_vsx.c +12 -0
  417. package/numkong/probes/probe.js +127 -0
  418. package/numkong/probes/riscv_rvv.c +14 -0
  419. package/numkong/probes/riscv_rvv_bb.c +15 -0
  420. package/numkong/probes/riscv_rvv_bf16.c +17 -0
  421. package/numkong/probes/riscv_rvv_half.c +14 -0
  422. package/numkong/probes/wasm_v128relaxed.c +11 -0
  423. package/numkong/probes/x86_alder.c +17 -0
  424. package/numkong/probes/x86_diamond.c +17 -0
  425. package/numkong/probes/x86_genoa.c +17 -0
  426. package/numkong/probes/x86_graniteamx.c +19 -0
  427. package/numkong/probes/x86_haswell.c +11 -0
  428. package/numkong/probes/x86_icelake.c +17 -0
  429. package/numkong/probes/x86_sapphire.c +16 -0
  430. package/numkong/probes/x86_sapphireamx.c +18 -0
  431. package/numkong/probes/x86_sierra.c +17 -0
  432. package/numkong/probes/x86_skylake.c +15 -0
  433. package/numkong/probes/x86_turin.c +17 -0
  434. package/numkong/rust/README.md +698 -0
  435. package/numkong/rust/capabilities.rs +96 -0
  436. package/numkong/rust/cast.rs +314 -0
  437. package/numkong/rust/curved.rs +391 -0
  438. package/numkong/rust/each.rs +2721 -0
  439. package/numkong/rust/geospatial.rs +343 -0
  440. package/numkong/rust/matrix.rs +5424 -0
  441. package/numkong/rust/maxsim.rs +540 -0
  442. package/numkong/rust/mesh.rs +837 -0
  443. package/numkong/rust/numkong.rs +409 -0
  444. package/numkong/rust/probability.rs +272 -0
  445. package/numkong/rust/reduce.rs +1249 -0
  446. package/numkong/rust/set.rs +194 -0
  447. package/numkong/rust/sparse.rs +513 -0
  448. package/numkong/rust/spatial.rs +1815 -0
  449. package/numkong/rust/tensor.rs +7565 -0
  450. package/numkong/rust/types.rs +3666 -0
  451. package/numkong/rust/vector.rs +1899 -0
  452. package/numkong/rustfmt.toml +2 -0
  453. package/numkong/swift/Matrix.swift +1388 -0
  454. package/numkong/swift/MaxSim.swift +151 -0
  455. package/numkong/swift/NumKong.swift +283 -0
  456. package/numkong/swift/Numerics.swift +329 -0
  457. package/numkong/swift/README.md +433 -0
  458. package/numkong/swift/Scalar.swift +741 -0
  459. package/numkong/swift/Tensor.swift +209 -0
  460. package/numkong/test/README.md +315 -0
  461. package/numkong/test/playwright.config.ts +16 -0
  462. package/numkong/test/swift/Test.swift +534 -0
  463. package/numkong/test/test-browser-bundle-runner.mjs +36 -0
  464. package/numkong/test/test-browser-bundle.html +188 -0
  465. package/numkong/test/test-browser-runner.mjs +43 -0
  466. package/numkong/test/test-browser.html +305 -0
  467. package/numkong/test/test-dtypes.mjs +453 -0
  468. package/numkong/test/test-wasm.mjs +267 -0
  469. package/numkong/test/test.cpp +442 -0
  470. package/numkong/test/test.hpp +580 -0
  471. package/numkong/test/test.mjs +363 -0
  472. package/numkong/test/test_base.py +1041 -0
  473. package/numkong/test/test_cast.cpp +242 -0
  474. package/numkong/test/test_cross.hpp +551 -0
  475. package/numkong/test/test_cross.py +467 -0
  476. package/numkong/test/test_cross_amx.cpp +50 -0
  477. package/numkong/test/test_cross_arm.cpp +225 -0
  478. package/numkong/test/test_cross_blas.cpp +354 -0
  479. package/numkong/test/test_cross_loongarch.cpp +90 -0
  480. package/numkong/test/test_cross_power.cpp +73 -0
  481. package/numkong/test/test_cross_rvv.cpp +109 -0
  482. package/numkong/test/test_cross_serial.cpp +181 -0
  483. package/numkong/test/test_cross_sme.cpp +148 -0
  484. package/numkong/test/test_cross_wasm.cpp +141 -0
  485. package/numkong/test/test_cross_x86.cpp +442 -0
  486. package/numkong/test/test_curved.cpp +182 -0
  487. package/numkong/test/test_curved.py +207 -0
  488. package/numkong/test/test_dot.cpp +353 -0
  489. package/numkong/test/test_dot.py +296 -0
  490. package/numkong/test/test_each.cpp +437 -0
  491. package/numkong/test/test_each.py +756 -0
  492. package/numkong/test/test_geospatial.cpp +155 -0
  493. package/numkong/test/test_geospatial.py +241 -0
  494. package/numkong/test/test_maxsim.cpp +138 -0
  495. package/numkong/test/test_maxsim.py +209 -0
  496. package/numkong/test/test_mesh.cpp +203 -0
  497. package/numkong/test/test_mesh.py +394 -0
  498. package/numkong/test/test_probability.cpp +136 -0
  499. package/numkong/test/test_probability.py +166 -0
  500. package/numkong/test/test_reduce.cpp +563 -0
  501. package/numkong/test/test_reduce.py +781 -0
  502. package/numkong/test/test_set.cpp +151 -0
  503. package/numkong/test/test_set.py +120 -0
  504. package/numkong/test/test_similarities.py +579 -0
  505. package/numkong/test/test_sparse.cpp +121 -0
  506. package/numkong/test/test_sparse.py +118 -0
  507. package/numkong/test/test_spatial.cpp +518 -0
  508. package/numkong/test/test_spatial.py +269 -0
  509. package/numkong/test/test_tensor.cpp +884 -0
  510. package/numkong/test/test_tensor.py +1417 -0
  511. package/numkong/test/test_trigonometry.cpp +156 -0
  512. package/numkong/test/test_trigonometry.py +180 -0
  513. package/package.json +7 -8
  514. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  515. package/prebuilds/linux-arm64/usearch.node +0 -0
  516. package/prebuilds/linux-x64/usearch.node +0 -0
  517. package/fp16/CMakeLists.txt +0 -176
  518. package/fp16/LICENSE +0 -11
  519. package/fp16/README.md +0 -20
  520. package/fp16/bench/alt-element.cc +0 -89
  521. package/fp16/bench/from-alt-array.cc +0 -175
  522. package/fp16/bench/from-ieee-array.cc +0 -399
  523. package/fp16/bench/ieee-element.cc +0 -272
  524. package/fp16/bench/to-alt-array.cc +0 -91
  525. package/fp16/bench/to-ieee-array.cc +0 -303
  526. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  527. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  528. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  529. package/fp16/configure.py +0 -65
  530. package/fp16/confu.yaml +0 -8
  531. package/fp16/include/fp16/__init__.py +0 -0
  532. package/fp16/include/fp16/avx.py +0 -50
  533. package/fp16/include/fp16/avx2.py +0 -53
  534. package/fp16/include/fp16/bitcasts.h +0 -92
  535. package/fp16/include/fp16/fp16.h +0 -451
  536. package/fp16/include/fp16/psimd.h +0 -131
  537. package/fp16/include/fp16.h +0 -11
  538. package/fp16/jni/Android.mk +0 -6
  539. package/fp16/jni/Application.mk +0 -4
  540. package/fp16/test/alt-from-fp32-value.cc +0 -498
  541. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  542. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  543. package/fp16/test/alt-to-fp32-value.cc +0 -348
  544. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  545. package/fp16/test/bitcasts.cc +0 -56
  546. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  547. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  548. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  549. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  550. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  551. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  552. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  553. package/fp16/test/peachpy/stubs.py +0 -38
  554. package/fp16/test/tables.cc +0 -530
  555. package/fp16/test/tables.h +0 -13
  556. package/fp16/third-party/THHalf.h +0 -92
  557. package/fp16/third-party/eigen-half.h +0 -170
  558. package/fp16/third-party/float16-compressor.h +0 -80
  559. package/fp16/third-party/half.hpp +0 -2916
  560. package/fp16/third-party/npy-halffloat.h +0 -328
  561. package/simsimd/.git-blame-ignore-revs +0 -2
  562. package/simsimd/CONTRIBUTING.md +0 -321
  563. package/simsimd/Cargo.toml +0 -49
  564. package/simsimd/MANIFEST.in +0 -4
  565. package/simsimd/Package.swift +0 -28
  566. package/simsimd/README.md +0 -1493
  567. package/simsimd/binding.gyp +0 -35
  568. package/simsimd/build.rs +0 -70
  569. package/simsimd/c/lib.c +0 -374
  570. package/simsimd/include/module.modulemap +0 -4
  571. package/simsimd/include/simsimd/binary.h +0 -486
  572. package/simsimd/include/simsimd/curved.h +0 -1541
  573. package/simsimd/include/simsimd/dot.h +0 -1853
  574. package/simsimd/include/simsimd/elementwise.h +0 -2465
  575. package/simsimd/include/simsimd/geospatial.h +0 -43
  576. package/simsimd/include/simsimd/mesh.h +0 -69
  577. package/simsimd/include/simsimd/probability.h +0 -606
  578. package/simsimd/include/simsimd/simsimd.h +0 -2567
  579. package/simsimd/include/simsimd/sparse.h +0 -1384
  580. package/simsimd/include/simsimd/spatial.h +0 -2335
  581. package/simsimd/include/simsimd/types.h +0 -666
  582. package/simsimd/javascript/fallback.ts +0 -233
  583. package/simsimd/javascript/lib.c +0 -125
  584. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  585. package/simsimd/javascript/simsimd.ts +0 -179
  586. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  587. package/simsimd/package-lock.json +0 -1761
  588. package/simsimd/package.json +0 -61
  589. package/simsimd/rust/lib.rs +0 -1821
  590. package/simsimd/scripts/bench.cxx +0 -1170
  591. package/simsimd/scripts/bench.ipynb +0 -187
  592. package/simsimd/scripts/bench.js +0 -127
  593. package/simsimd/scripts/bench.rs +0 -876
  594. package/simsimd/scripts/bench_vectors.py +0 -734
  595. package/simsimd/scripts/bench_vectors_live.py +0 -213
  596. package/simsimd/scripts/test.c +0 -187
  597. package/simsimd/scripts/test.mjs +0 -220
  598. package/simsimd/scripts/test.py +0 -1505
  599. package/simsimd/swift/SimSIMD.swift +0 -149
  600. package/simsimd/swift/Test.swift +0 -128
  601. /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
  602. /package/{simsimd → numkong}/LICENSE +0 -0
  603. /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
  604. /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
@@ -0,0 +1,725 @@
1
+ /**
2
+ * @brief SIMD-accelerated Trigonometric Functions for Skylake.
3
+ * @file include/numkong/trigonometry/skylake.h
4
+ * @author Ash Vardanian
5
+ * @date December 27, 2025
6
+ *
7
+ * @sa include/numkong/trigonometry.h
8
+ * @see https://sleef.org
9
+ *
10
+ * @section skylake_trig_instructions Key AVX-512 Trigonometry Instructions
11
+ *
12
+ * Intrinsic Instruction Skylake-X Genoa
13
+ * _mm512_fmadd_ps VFMADD132PS (ZMM, ZMM, ZMM) 4cy @ p05 4cy @ p01
14
+ * _mm512_mul_ps VMULPS (ZMM, ZMM, ZMM) 4cy @ p05 3cy @ p01
15
+ * _mm512_and_ps VANDPS (ZMM, ZMM, ZMM) 1cy @ p05 1cy @ p0123
16
+ * _mm512_cmp_ps_mask VCMPPS (K, ZMM, ZMM, I8) 4cy @ p5 5cy @ p01
17
+ * _mm512_roundscale_ps VRNDSCALEPS (ZMM, ZMM, I8) 8cy @ p05+p05 3cy @ p23
18
+ *
19
+ * Trigonometric functions use polynomial approximations evaluated via Horner's method with FMA chains.
20
+ * AVX-512 mask registers enable branchless range reduction and sign handling without blend overhead.
21
+ * Skylake-X's dual FMA units achieve 0.5cy throughput, processing 32 f32 sin/cos values per 8 cycles.
22
+ */
23
+ #ifndef NK_TRIGONOMETRY_SKYLAKE_H
24
+ #define NK_TRIGONOMETRY_SKYLAKE_H
25
+
26
+ #if NK_TARGET_X8664_
27
+ #if NK_TARGET_SKYLAKE
28
+
29
+ #include "numkong/types.h"
30
+
31
+ #if defined(__cplusplus)
32
+ extern "C" {
33
+ #endif
34
+
35
+ #if defined(__clang__)
36
+ #pragma clang attribute push(__attribute__((target("avx2,avx512f,avx512vl,avx512bw,avx512dq,f16c,fma,bmi,bmi2"))), \
37
+ apply_to = function)
38
+ #elif defined(__GNUC__)
39
+ #pragma GCC push_options
40
+ #pragma GCC target("avx2", "avx512f", "avx512vl", "avx512bw", "avx512dq", "f16c", "fma", "bmi", "bmi2")
41
+ #endif
42
+
43
+ NK_INTERNAL __m512 nk_sin_f32x16_skylake_(__m512 const angles_radians) {
44
+ // Cody-Waite constants for argument reduction
45
+ __m512 const pi_high_f32x16 = _mm512_set1_ps(3.1415927f);
46
+ __m512 const pi_low_f32x16 = _mm512_set1_ps(-8.742278e-8f);
47
+ __m512 const pi_reciprocal_f32x16 = _mm512_set1_ps(0.31830988618379067154f); // 1/π
48
+ // Degree-9 minimax coefficients
49
+ __m512 const coeff_9_f32x16 = _mm512_set1_ps(+2.7557319224e-6f);
50
+ __m512 const coeff_7_f32x16 = _mm512_set1_ps(-1.9841269841e-4f);
51
+ __m512 const coeff_5_f32x16 = _mm512_set1_ps(+8.3333293855e-3f);
52
+ __m512 const coeff_3_f32x16 = _mm512_set1_ps(-1.6666666641e-1f);
53
+
54
+ // Compute (multiples_of_pi_i32x16) = round(angle / π)
55
+ __m512 quotients_f32x16 = _mm512_mul_ps(angles_radians, pi_reciprocal_f32x16);
56
+ __m512 rounded_quotients_f32x16 = _mm512_roundscale_ps(quotients_f32x16,
57
+ _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
58
+ // Use explicit rounding to match roundscale (MXCSR-independent)
59
+ __m512i multiples_of_pi_i32x16 = _mm512_cvt_roundps_epi32(rounded_quotients_f32x16,
60
+ _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
61
+
62
+ // Cody-Waite range reduction
63
+ __m512 angles_f32x16 = _mm512_fnmadd_ps(rounded_quotients_f32x16, pi_high_f32x16, angles_radians);
64
+ angles_f32x16 = _mm512_fnmadd_ps(rounded_quotients_f32x16, pi_low_f32x16, angles_f32x16);
65
+ __m512 const angles_squared_f32x16 = _mm512_mul_ps(angles_f32x16, angles_f32x16);
66
+ __m512 const angles_cubed_f32x16 = _mm512_mul_ps(angles_f32x16, angles_squared_f32x16);
67
+
68
+ // Degree-9 polynomial via Horner's method
69
+ __m512 polynomials_f32x16 = coeff_9_f32x16;
70
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, angles_squared_f32x16, coeff_7_f32x16);
71
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, angles_squared_f32x16, coeff_5_f32x16);
72
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, angles_squared_f32x16, coeff_3_f32x16);
73
+
74
+ // If multiples_of_pi_i32x16 is odd, flip the sign of the results_f32x16
75
+ __mmask16 odd_mask = _mm512_test_epi32_mask(multiples_of_pi_i32x16, _mm512_set1_epi32(1));
76
+ __m512 results_f32x16 = _mm512_fmadd_ps(angles_cubed_f32x16, polynomials_f32x16, angles_f32x16);
77
+ results_f32x16 = _mm512_mask_sub_ps(results_f32x16, odd_mask, _mm512_setzero_ps(), results_f32x16);
78
+ return results_f32x16;
79
+ }
80
+
81
+ NK_INTERNAL __m512 nk_cos_f32x16_skylake_(__m512 const angles_radians) {
82
+ // Cody-Waite constants for argument reduction
83
+ __m512 const pi_high_f32x16 = _mm512_set1_ps(3.1415927f);
84
+ __m512 const pi_low_f32x16 = _mm512_set1_ps(-8.742278e-8f);
85
+ __m512 const pi_half_f32x16 = _mm512_set1_ps(1.57079632679489661923f); // π/2
86
+ __m512 const pi_reciprocal_f32x16 = _mm512_set1_ps(0.31830988618379067154f); // 1/π
87
+ // Degree-9 minimax coefficients
88
+ __m512 const coeff_9_f32x16 = _mm512_set1_ps(+2.7557319224e-6f);
89
+ __m512 const coeff_7_f32x16 = _mm512_set1_ps(-1.9841269841e-4f);
90
+ __m512 const coeff_5_f32x16 = _mm512_set1_ps(+8.3333293855e-3f);
91
+ __m512 const coeff_3_f32x16 = _mm512_set1_ps(-1.6666666641e-1f);
92
+
93
+ // Compute (multiples_of_pi_i32x16) = round((angle / π) - 0.5)
94
+ __m512 quotients_f32x16 = _mm512_fmsub_ps(angles_radians, pi_reciprocal_f32x16, _mm512_set1_ps(0.5f));
95
+ __m512 rounded_quotients_f32x16 = _mm512_roundscale_ps(quotients_f32x16,
96
+ _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
97
+ // Use explicit rounding to match roundscale (MXCSR-independent)
98
+ __m512i multiples_of_pi_i32x16 = _mm512_cvt_roundps_epi32(rounded_quotients_f32x16,
99
+ _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
100
+
101
+ // Cody-Waite range reduction: angle = angle_radians - (multiples * pi + pi/2)
102
+ __m512 const offset_f32x16 = _mm512_fmadd_ps(rounded_quotients_f32x16, pi_high_f32x16, pi_half_f32x16);
103
+ __m512 angles_f32x16 = _mm512_sub_ps(angles_radians, offset_f32x16);
104
+ angles_f32x16 = _mm512_fnmadd_ps(rounded_quotients_f32x16, pi_low_f32x16, angles_f32x16);
105
+ __m512 const angles_squared_f32x16 = _mm512_mul_ps(angles_f32x16, angles_f32x16);
106
+ __m512 const angles_cubed_f32x16 = _mm512_mul_ps(angles_f32x16, angles_squared_f32x16);
107
+
108
+ // Degree-9 polynomial via Horner's method
109
+ __m512 polynomials_f32x16 = coeff_9_f32x16;
110
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, angles_squared_f32x16, coeff_7_f32x16);
111
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, angles_squared_f32x16, coeff_5_f32x16);
112
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, angles_squared_f32x16, coeff_3_f32x16);
113
+ __m512 results_f32x16 = _mm512_fmadd_ps(angles_cubed_f32x16, polynomials_f32x16, angles_f32x16);
114
+
115
+ // If multiples_of_pi_i32x16 is even, flip the sign of the results_f32x16
116
+ __mmask16 even_mask = _mm512_testn_epi32_mask(multiples_of_pi_i32x16, _mm512_set1_epi32(1));
117
+ results_f32x16 = _mm512_mask_sub_ps(results_f32x16, even_mask, _mm512_setzero_ps(), results_f32x16);
118
+ return results_f32x16;
119
+ }
120
+
121
+ NK_INTERNAL __m512 nk_atan_f32x16_skylake_(__m512 const inputs) {
122
+ // Polynomial coefficients
123
+ __m512 const coeff_8_f32x16 = _mm512_set1_ps(-0.333331018686294555664062f);
124
+ __m512 const coeff_7_f32x16 = _mm512_set1_ps(+0.199926957488059997558594f);
125
+ __m512 const coeff_6_f32x16 = _mm512_set1_ps(-0.142027363181114196777344f);
126
+ __m512 const coeff_5_f32x16 = _mm512_set1_ps(+0.106347933411598205566406f);
127
+ __m512 const coeff_4_f32x16 = _mm512_set1_ps(-0.0748900920152664184570312f);
128
+ __m512 const coeff_3_f32x16 = _mm512_set1_ps(+0.0425049886107444763183594f);
129
+ __m512 const coeff_2_f32x16 = _mm512_set1_ps(-0.0159569028764963150024414f);
130
+ __m512 const coeff_1_f32x16 = _mm512_set1_ps(+0.00282363896258175373077393f);
131
+
132
+ // Adjust for quadrant
133
+ __m512 values_f32x16 = inputs;
134
+ __mmask16 const negative_mask = _mm512_fpclass_ps_mask(values_f32x16, 0x40);
135
+ values_f32x16 = _mm512_abs_ps(values_f32x16);
136
+ __mmask16 const reciprocal_mask = _mm512_cmp_ps_mask(values_f32x16, _mm512_set1_ps(1.0f), _CMP_GT_OS);
137
+ values_f32x16 = _mm512_mask_div_ps(values_f32x16, reciprocal_mask, _mm512_set1_ps(1.0f), values_f32x16);
138
+
139
+ // Argument reduction
140
+ __m512 const values_squared_f32x16 = _mm512_mul_ps(values_f32x16, values_f32x16);
141
+ __m512 const values_cubed_f32x16 = _mm512_mul_ps(values_f32x16, values_squared_f32x16);
142
+
143
+ // Polynomial evaluation
144
+ __m512 polynomials_f32x16 = coeff_1_f32x16;
145
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, values_squared_f32x16, coeff_2_f32x16);
146
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, values_squared_f32x16, coeff_3_f32x16);
147
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, values_squared_f32x16, coeff_4_f32x16);
148
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, values_squared_f32x16, coeff_5_f32x16);
149
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, values_squared_f32x16, coeff_6_f32x16);
150
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, values_squared_f32x16, coeff_7_f32x16);
151
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, values_squared_f32x16, coeff_8_f32x16);
152
+
153
+ // Adjust result_f32x16 for quadrants
154
+ __m512 result_f32x16 = _mm512_fmadd_ps(values_cubed_f32x16, polynomials_f32x16, values_f32x16);
155
+ result_f32x16 = _mm512_mask_sub_ps(result_f32x16, reciprocal_mask, _mm512_set1_ps(1.5707963267948966f),
156
+ result_f32x16);
157
+ result_f32x16 = _mm512_mask_sub_ps(result_f32x16, negative_mask, _mm512_setzero_ps(), result_f32x16);
158
+ return result_f32x16;
159
+ }
160
+
161
+ NK_INTERNAL __m512 nk_atan2_f32x16_skylake_(__m512 const ys_inputs, __m512 const xs_inputs) {
162
+ // Polynomial coefficients
163
+ __m512 const coeff_8_f32x16 = _mm512_set1_ps(-0.333331018686294555664062f);
164
+ __m512 const coeff_7_f32x16 = _mm512_set1_ps(+0.199926957488059997558594f);
165
+ __m512 const coeff_6_f32x16 = _mm512_set1_ps(-0.142027363181114196777344f);
166
+ __m512 const coeff_5_f32x16 = _mm512_set1_ps(+0.106347933411598205566406f);
167
+ __m512 const coeff_4_f32x16 = _mm512_set1_ps(-0.0748900920152664184570312f);
168
+ __m512 const coeff_3_f32x16 = _mm512_set1_ps(+0.0425049886107444763183594f);
169
+ __m512 const coeff_2_f32x16 = _mm512_set1_ps(-0.0159569028764963150024414f);
170
+ __m512 const coeff_1_f32x16 = _mm512_set1_ps(+0.00282363896258175373077393f);
171
+
172
+ // Quadrant adjustments normalizing to absolute values of x and y
173
+ __mmask16 const xs_negative_mask = _mm512_fpclass_ps_mask(xs_inputs, 0x40);
174
+ __m512 xs_f32x16 = _mm512_abs_ps(xs_inputs);
175
+ __m512 ys_f32x16 = _mm512_abs_ps(ys_inputs);
176
+ // Ensure proper fraction where the numerator is smaller than the denominator
177
+ __mmask16 const swap_mask = _mm512_cmp_ps_mask(ys_f32x16, xs_f32x16, _CMP_GT_OS);
178
+ __m512 temps_f32x16 = xs_f32x16;
179
+ xs_f32x16 = _mm512_mask_blend_ps(swap_mask, xs_f32x16, ys_f32x16);
180
+ ys_f32x16 = _mm512_mask_sub_ps(ys_f32x16, swap_mask, _mm512_setzero_ps(), temps_f32x16);
181
+
182
+ // Compute ratio_f32x16 and ratio²
183
+ __m512 const ratio_f32x16 = _mm512_div_ps(ys_f32x16, xs_f32x16);
184
+ __m512 const ratio_squared_f32x16 = _mm512_mul_ps(ratio_f32x16, ratio_f32x16);
185
+ __m512 const ratio_cubed_f32x16 = _mm512_mul_ps(ratio_f32x16, ratio_squared_f32x16);
186
+
187
+ // Polynomial evaluation
188
+ __m512 polynomials_f32x16 = coeff_1_f32x16;
189
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, ratio_squared_f32x16, coeff_2_f32x16);
190
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, ratio_squared_f32x16, coeff_3_f32x16);
191
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, ratio_squared_f32x16, coeff_4_f32x16);
192
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, ratio_squared_f32x16, coeff_5_f32x16);
193
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, ratio_squared_f32x16, coeff_6_f32x16);
194
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, ratio_squared_f32x16, coeff_7_f32x16);
195
+ polynomials_f32x16 = _mm512_fmadd_ps(polynomials_f32x16, ratio_squared_f32x16, coeff_8_f32x16);
196
+
197
+ // Compute quadrant_f32x16 value: 0 for x>=0 && !swap, 1 for x>=0 && swap,
198
+ // -2 for x<0 && !swap, -1 for x<0 && swap
199
+ __m512 results_f32x16 = _mm512_fmadd_ps(ratio_cubed_f32x16, polynomials_f32x16, ratio_f32x16);
200
+ __m512 quadrant_f32x16 = _mm512_setzero_ps();
201
+ __m512 neg_two_f32x16 = _mm512_set1_ps(-2.0f);
202
+ quadrant_f32x16 = _mm512_mask_blend_ps(xs_negative_mask, quadrant_f32x16, neg_two_f32x16);
203
+ __m512 one_f32x16 = _mm512_set1_ps(1.0f);
204
+ __m512 quadrant_incremented_f32x16 = _mm512_add_ps(quadrant_f32x16, one_f32x16);
205
+ quadrant_f32x16 = _mm512_mask_blend_ps(swap_mask, quadrant_f32x16, quadrant_incremented_f32x16);
206
+
207
+ // Adjust for quadrant_f32x16: result += quadrant_f32x16 * π/2
208
+ __m512 pi_half_f32x16 = _mm512_set1_ps(1.5707963267948966f);
209
+ results_f32x16 = _mm512_fmadd_ps(quadrant_f32x16, pi_half_f32x16, results_f32x16);
210
+
211
+ // Transfer sign from x (XOR with sign bit of x_input)
212
+ __m512 xs_sign_bits_f32x16 = _mm512_and_ps(xs_inputs, _mm512_set1_ps(-0.0f));
213
+ results_f32x16 = _mm512_xor_ps(results_f32x16, xs_sign_bits_f32x16);
214
+
215
+ // Transfer sign from y (XOR with sign bit of y_input)
216
+ __m512 ys_sign_bits_f32x16 = _mm512_and_ps(ys_inputs, _mm512_set1_ps(-0.0f));
217
+ results_f32x16 = _mm512_xor_ps(results_f32x16, ys_sign_bits_f32x16);
218
+
219
+ return results_f32x16;
220
+ }
221
+
222
+ NK_PUBLIC void nk_each_sin_f32_skylake(nk_f32_t const *ins, nk_size_t n, nk_f32_t *outs) {
223
+ nk_size_t i = 0;
224
+ for (; i + 16 <= n; i += 16) {
225
+ __m512 angles_f32x16 = _mm512_loadu_ps(ins + i);
226
+ __m512 results_f32x16 = nk_sin_f32x16_skylake_(angles_f32x16);
227
+ _mm512_storeu_ps(outs + i, results_f32x16);
228
+ }
229
+ if (i < n) {
230
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n - i);
231
+ __m512 angles_f32x16 = _mm512_maskz_loadu_ps(mask, ins + i);
232
+ __m512 results_f32x16 = nk_sin_f32x16_skylake_(angles_f32x16);
233
+ _mm512_mask_storeu_ps(outs + i, mask, results_f32x16);
234
+ }
235
+ }
236
+ NK_PUBLIC void nk_each_cos_f32_skylake(nk_f32_t const *ins, nk_size_t n, nk_f32_t *outs) {
237
+ nk_size_t i = 0;
238
+ for (; i + 16 <= n; i += 16) {
239
+ __m512 angles_f32x16 = _mm512_loadu_ps(ins + i);
240
+ __m512 results_f32x16 = nk_cos_f32x16_skylake_(angles_f32x16);
241
+ _mm512_storeu_ps(outs + i, results_f32x16);
242
+ }
243
+ if (i < n) {
244
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n - i);
245
+ __m512 angles_f32x16 = _mm512_maskz_loadu_ps(mask, ins + i);
246
+ __m512 results_f32x16 = nk_cos_f32x16_skylake_(angles_f32x16);
247
+ _mm512_mask_storeu_ps(outs + i, mask, results_f32x16);
248
+ }
249
+ }
250
+ NK_PUBLIC void nk_each_atan_f32_skylake(nk_f32_t const *ins, nk_size_t n, nk_f32_t *outs) {
251
+ nk_size_t i = 0;
252
+ for (; i + 16 <= n; i += 16) {
253
+ __m512 angles_f32x16 = _mm512_loadu_ps(ins + i);
254
+ __m512 results_f32x16 = nk_atan_f32x16_skylake_(angles_f32x16);
255
+ _mm512_storeu_ps(outs + i, results_f32x16);
256
+ }
257
+ if (i < n) {
258
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n - i);
259
+ __m512 angles_f32x16 = _mm512_maskz_loadu_ps(mask, ins + i);
260
+ __m512 results_f32x16 = nk_atan_f32x16_skylake_(angles_f32x16);
261
+ _mm512_mask_storeu_ps(outs + i, mask, results_f32x16);
262
+ }
263
+ }
264
+
265
+ NK_INTERNAL __m512d nk_sin_f64x8_skylake_(__m512d const angles_radians) {
266
+ // Constants for argument reduction
267
+ __m512d const pi_high_f64x8 = _mm512_set1_pd(3.141592653589793116); // High-digits part of π
268
+ __m512d const pi_low_f64x8 = _mm512_set1_pd(1.2246467991473532072e-16); // Low-digits part of π
269
+ __m512d const pi_reciprocal_f64x8 = _mm512_set1_pd(0.31830988618379067154); // 1/π
270
+
271
+ // Polynomial coefficients for sine/cosine approximation (minimax polynomial)
272
+ __m512d const coeff_0_f64x8 = _mm512_set1_pd(+0.00833333333333332974823815);
273
+ __m512d const coeff_1_f64x8 = _mm512_set1_pd(-0.000198412698412696162806809);
274
+ __m512d const coeff_2_f64x8 = _mm512_set1_pd(+2.75573192239198747630416e-06);
275
+ __m512d const coeff_3_f64x8 = _mm512_set1_pd(-2.50521083763502045810755e-08);
276
+ __m512d const coeff_4_f64x8 = _mm512_set1_pd(+1.60590430605664501629054e-10);
277
+ __m512d const coeff_5_f64x8 = _mm512_set1_pd(-7.64712219118158833288484e-13);
278
+ __m512d const coeff_6_f64x8 = _mm512_set1_pd(+2.81009972710863200091251e-15);
279
+ __m512d const coeff_7_f64x8 = _mm512_set1_pd(-7.97255955009037868891952e-18);
280
+ __m512d const coeff_8_f64x8 = _mm512_set1_pd(-0.166666666666666657414808);
281
+
282
+ // Compute (rounded_quotients_f64x8) = round(angle / π)
283
+ __m512d const quotients_f64x8 = _mm512_mul_pd(angles_radians, pi_reciprocal_f64x8);
284
+ __m512d const rounded_quotients_f64x8 = _mm512_roundscale_pd(quotients_f64x8,
285
+ _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
286
+
287
+ // Reduce the angle to: angle - (rounded_quotients_f64x8 * π_high + rounded_quotients_f64x8 * π_low)
288
+ __m512d angles_f64x8 = angles_radians;
289
+ angles_f64x8 = _mm512_fnmadd_pd(rounded_quotients_f64x8, pi_high_f64x8, angles_f64x8);
290
+ angles_f64x8 = _mm512_fnmadd_pd(rounded_quotients_f64x8, pi_low_f64x8, angles_f64x8);
291
+
292
+ // If rounded_quotients_f64x8 is odd (bit 0 set), negate the angle
293
+ // Use explicit rounding to match roundscale (MXCSR-independent)
294
+ __mmask8 const sign_flip_mask = _mm256_test_epi32_mask(
295
+ _mm512_cvt_roundpd_epi32(rounded_quotients_f64x8, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC),
296
+ _mm256_set1_epi32(1));
297
+ angles_f64x8 = _mm512_mask_sub_pd(angles_f64x8, sign_flip_mask, _mm512_setzero_pd(), angles_f64x8);
298
+
299
+ __m512d const angles_squared_f64x8 = _mm512_mul_pd(angles_f64x8, angles_f64x8);
300
+ __m512d const angles_cubed_f64x8 = _mm512_mul_pd(angles_f64x8, angles_squared_f64x8);
301
+ __m512d const angles_quadratic_f64x8 = _mm512_mul_pd(angles_squared_f64x8, angles_squared_f64x8);
302
+ __m512d const angles_octic_f64x8 = _mm512_mul_pd(angles_quadratic_f64x8, angles_quadratic_f64x8);
303
+
304
+ // Compute higher-degree polynomial terms
305
+ __m512d const poly_67_f64x8 = _mm512_fmadd_pd(angles_squared_f64x8, coeff_7_f64x8, coeff_6_f64x8);
306
+ __m512d const poly_45_f64x8 = _mm512_fmadd_pd(angles_squared_f64x8, coeff_5_f64x8, coeff_4_f64x8);
307
+ __m512d const poly_4567_f64x8 = _mm512_fmadd_pd(angles_quadratic_f64x8, poly_67_f64x8, poly_45_f64x8);
308
+
309
+ // Compute lower-degree polynomial terms
310
+ __m512d const poly_23_f64x8 = _mm512_fmadd_pd(angles_squared_f64x8, coeff_3_f64x8, coeff_2_f64x8);
311
+ __m512d const poly_01_f64x8 = _mm512_fmadd_pd(angles_squared_f64x8, coeff_1_f64x8, coeff_0_f64x8);
312
+ __m512d const poly_0123_f64x8 = _mm512_fmadd_pd(angles_quadratic_f64x8, poly_23_f64x8, poly_01_f64x8);
313
+
314
+ // Combine polynomial terms
315
+ __m512d results_f64x8 = _mm512_fmadd_pd(angles_octic_f64x8, poly_4567_f64x8, poly_0123_f64x8);
316
+ results_f64x8 = _mm512_fmadd_pd(results_f64x8, angles_squared_f64x8, coeff_8_f64x8);
317
+ results_f64x8 = _mm512_fmadd_pd(results_f64x8, angles_cubed_f64x8, angles_f64x8);
318
+
319
+ // Handle the special case of negative zero input
320
+ __mmask8 const non_zero_mask = _mm512_cmpneq_pd_mask(angles_radians, _mm512_setzero_pd());
321
+ results_f64x8 = _mm512_maskz_mov_pd(non_zero_mask, results_f64x8);
322
+ return results_f64x8;
323
+ }
324
+
325
+ NK_INTERNAL __m512d nk_cos_f64x8_skylake_(__m512d const angles_radians) {
326
+ // Constants for argument reduction
327
+ __m512d const pi_high_half_f64x8 = _mm512_set1_pd(3.141592653589793116 * 0.5); // High-digits part of π
328
+ __m512d const pi_low_half_f64x8 = _mm512_set1_pd(1.2246467991473532072e-16 * 0.5); // Low-digits part of π
329
+ __m512d const pi_reciprocal_f64x8 = _mm512_set1_pd(0.31830988618379067154); // 1/π
330
+
331
+ // Polynomial coefficients for sine/cosine approximation (minimax polynomial)
332
+ __m512d const coeff_0_f64x8 = _mm512_set1_pd(+0.00833333333333332974823815);
333
+ __m512d const coeff_1_f64x8 = _mm512_set1_pd(-0.000198412698412696162806809);
334
+ __m512d const coeff_2_f64x8 = _mm512_set1_pd(+2.75573192239198747630416e-06);
335
+ __m512d const coeff_3_f64x8 = _mm512_set1_pd(-2.50521083763502045810755e-08);
336
+ __m512d const coeff_4_f64x8 = _mm512_set1_pd(+1.60590430605664501629054e-10);
337
+ __m512d const coeff_5_f64x8 = _mm512_set1_pd(-7.64712219118158833288484e-13);
338
+ __m512d const coeff_6_f64x8 = _mm512_set1_pd(+2.81009972710863200091251e-15);
339
+ __m512d const coeff_7_f64x8 = _mm512_set1_pd(-7.97255955009037868891952e-18);
340
+ __m512d const coeff_8_f64x8 = _mm512_set1_pd(-0.166666666666666657414808);
341
+
342
+ // Compute (rounded_quotients_f64x8) = 2 * round(angle / π - 0.5) + 1
343
+ // Use fmsub: a*b - c = angles_f64x8 * (1/π) - 0.5
344
+ __m512d const quotients_f64x8 = _mm512_fmsub_pd(angles_radians, pi_reciprocal_f64x8, _mm512_set1_pd(0.5));
345
+ __m512d const rounded_quotients_f64x8 = _mm512_fmadd_pd( //
346
+ _mm512_set1_pd(2), //
347
+ _mm512_roundscale_pd(quotients_f64x8, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC), //
348
+ _mm512_set1_pd(1));
349
+
350
+ // Reduce the angle to: angle - (rounded_quotients_f64x8 * π_high + rounded_quotients_f64x8 * π_low)
351
+ __m512d angles_f64x8 = angles_radians;
352
+ angles_f64x8 = _mm512_fnmadd_pd(rounded_quotients_f64x8, pi_high_half_f64x8, angles_f64x8);
353
+ angles_f64x8 = _mm512_fnmadd_pd(rounded_quotients_f64x8, pi_low_half_f64x8, angles_f64x8);
354
+ // Use explicit rounding to match roundscale (MXCSR-independent)
355
+ __mmask8 const sign_flip_mask = _mm256_testn_epi32_mask(
356
+ _mm512_cvt_roundpd_epi32(rounded_quotients_f64x8, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC),
357
+ _mm256_set1_epi32(2));
358
+ angles_f64x8 = _mm512_mask_sub_pd(angles_f64x8, sign_flip_mask, _mm512_setzero_pd(), angles_f64x8);
359
+ __m512d const angles_squared_f64x8 = _mm512_mul_pd(angles_f64x8, angles_f64x8);
360
+ __m512d const angles_cubed_f64x8 = _mm512_mul_pd(angles_f64x8, angles_squared_f64x8);
361
+ __m512d const angles_quadratic_f64x8 = _mm512_mul_pd(angles_squared_f64x8, angles_squared_f64x8);
362
+ __m512d const angles_octic_f64x8 = _mm512_mul_pd(angles_quadratic_f64x8, angles_quadratic_f64x8);
363
+
364
+ // Compute higher-degree polynomial terms
365
+ __m512d const poly_67_f64x8 = _mm512_fmadd_pd(angles_squared_f64x8, coeff_7_f64x8, coeff_6_f64x8);
366
+ __m512d const poly_45_f64x8 = _mm512_fmadd_pd(angles_squared_f64x8, coeff_5_f64x8, coeff_4_f64x8);
367
+ __m512d const poly_4567_f64x8 = _mm512_fmadd_pd(angles_quadratic_f64x8, poly_67_f64x8, poly_45_f64x8);
368
+
369
+ // Compute lower-degree polynomial terms
370
+ __m512d const poly_23_f64x8 = _mm512_fmadd_pd(angles_squared_f64x8, coeff_3_f64x8, coeff_2_f64x8);
371
+ __m512d const poly_01_f64x8 = _mm512_fmadd_pd(angles_squared_f64x8, coeff_1_f64x8, coeff_0_f64x8);
372
+ __m512d const poly_0123_f64x8 = _mm512_fmadd_pd(angles_quadratic_f64x8, poly_23_f64x8, poly_01_f64x8);
373
+
374
+ // Combine polynomial terms
375
+ __m512d results_f64x8 = _mm512_fmadd_pd(angles_octic_f64x8, poly_4567_f64x8, poly_0123_f64x8);
376
+ results_f64x8 = _mm512_fmadd_pd(results_f64x8, angles_squared_f64x8, coeff_8_f64x8);
377
+ results_f64x8 = _mm512_fmadd_pd(results_f64x8, angles_cubed_f64x8, angles_f64x8);
378
+ return results_f64x8;
379
+ }
380
+
381
+ NK_INTERNAL __m512d nk_atan_f64x8_skylake_(__m512d const inputs) {
382
+ // Polynomial coefficients for atan approximation
383
+ __m512d const coeff_19_f64x8 = _mm512_set1_pd(-1.88796008463073496563746e-05);
384
+ __m512d const coeff_18_f64x8 = _mm512_set1_pd(+0.000209850076645816976906797);
385
+ __m512d const coeff_17_f64x8 = _mm512_set1_pd(-0.00110611831486672482563471);
386
+ __m512d const coeff_16_f64x8 = _mm512_set1_pd(+0.00370026744188713119232403);
387
+ __m512d const coeff_15_f64x8 = _mm512_set1_pd(-0.00889896195887655491740809);
388
+ __m512d const coeff_14_f64x8 = _mm512_set1_pd(+0.016599329773529201970117);
389
+ __m512d const coeff_13_f64x8 = _mm512_set1_pd(-0.0254517624932312641616861);
390
+ __m512d const coeff_12_f64x8 = _mm512_set1_pd(+0.0337852580001353069993897);
391
+ __m512d const coeff_11_f64x8 = _mm512_set1_pd(-0.0407629191276836500001934);
392
+ __m512d const coeff_10_f64x8 = _mm512_set1_pd(+0.0466667150077840625632675);
393
+ __m512d const coeff_9_f64x8 = _mm512_set1_pd(-0.0523674852303482457616113);
394
+ __m512d const coeff_8_f64x8 = _mm512_set1_pd(+0.0587666392926673580854313);
395
+ __m512d const coeff_7_f64x8 = _mm512_set1_pd(-0.0666573579361080525984562);
396
+ __m512d const coeff_6_f64x8 = _mm512_set1_pd(+0.0769219538311769618355029);
397
+ __m512d const coeff_5_f64x8 = _mm512_set1_pd(-0.090908995008245008229153);
398
+ __m512d const coeff_4_f64x8 = _mm512_set1_pd(+0.111111105648261418443745);
399
+ __m512d const coeff_3_f64x8 = _mm512_set1_pd(-0.14285714266771329383765);
400
+ __m512d const coeff_2_f64x8 = _mm512_set1_pd(+0.199999999996591265594148);
401
+ __m512d const coeff_1_f64x8 = _mm512_set1_pd(-0.333333333333311110369124);
402
+
403
+ // Quadrant adjustments
404
+ __mmask8 negative_mask = _mm512_cmp_pd_mask(inputs, _mm512_setzero_pd(), _CMP_LT_OS);
405
+ __m512d values_f64x8 = _mm512_abs_pd(inputs);
406
+ __mmask8 reciprocal_mask = _mm512_cmp_pd_mask(values_f64x8, _mm512_set1_pd(1.0), _CMP_GT_OS);
407
+ values_f64x8 = _mm512_mask_div_pd(values_f64x8, reciprocal_mask, _mm512_set1_pd(1.0), values_f64x8);
408
+ __m512d const values_squared_f64x8 = _mm512_mul_pd(values_f64x8, values_f64x8);
409
+ __m512d const values_cubed_f64x8 = _mm512_mul_pd(values_f64x8, values_squared_f64x8);
410
+
411
+ // Polynomial evaluation (argument reduction and approximation)
412
+ __m512d polynomials_f64x8 = coeff_19_f64x8;
413
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_18_f64x8);
414
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_17_f64x8);
415
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_16_f64x8);
416
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_15_f64x8);
417
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_14_f64x8);
418
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_13_f64x8);
419
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_12_f64x8);
420
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_11_f64x8);
421
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_10_f64x8);
422
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_9_f64x8);
423
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_8_f64x8);
424
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_7_f64x8);
425
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_6_f64x8);
426
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_5_f64x8);
427
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_4_f64x8);
428
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_3_f64x8);
429
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_2_f64x8);
430
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, values_squared_f64x8, coeff_1_f64x8);
431
+
432
+ // Compute atan approximation
433
+ __m512d result_f64x8 = _mm512_fmadd_pd(values_cubed_f64x8, polynomials_f64x8, values_f64x8);
434
+ result_f64x8 = _mm512_mask_sub_pd(result_f64x8, reciprocal_mask, _mm512_set1_pd(1.5707963267948966), result_f64x8);
435
+ result_f64x8 = _mm512_mask_sub_pd(result_f64x8, negative_mask, _mm512_setzero_pd(), result_f64x8);
436
+ return result_f64x8;
437
+ }
438
+
439
+ /**
440
+ * @brief AVX-512 implementation of atan2(y, x) for 8 double-precision values.
441
+ * @see Based on the f32x16 version with appropriate precision constants.
442
+ */
443
+ NK_INTERNAL __m512d nk_atan2_f64x8_skylake_(__m512d const ys_inputs, __m512d const xs_inputs) {
444
+ // Polynomial coefficients for atan approximation (higher precision than f32)
445
+ __m512d const coeff_19_f64x8 = _mm512_set1_pd(-1.88796008463073496563746e-05);
446
+ __m512d const coeff_18_f64x8 = _mm512_set1_pd(+0.000209850076645816976906797);
447
+ __m512d const coeff_17_f64x8 = _mm512_set1_pd(-0.00110611831486672482563471);
448
+ __m512d const coeff_16_f64x8 = _mm512_set1_pd(+0.00370026744188713119232403);
449
+ __m512d const coeff_15_f64x8 = _mm512_set1_pd(-0.00889896195887655491740809);
450
+ __m512d const coeff_14_f64x8 = _mm512_set1_pd(+0.016599329773529201970117);
451
+ __m512d const coeff_13_f64x8 = _mm512_set1_pd(-0.0254517624932312641616861);
452
+ __m512d const coeff_12_f64x8 = _mm512_set1_pd(+0.0337852580001353069993897);
453
+ __m512d const coeff_11_f64x8 = _mm512_set1_pd(-0.0407629191276836500001934);
454
+ __m512d const coeff_10_f64x8 = _mm512_set1_pd(+0.0466667150077840625632675);
455
+ __m512d const coeff_9_f64x8 = _mm512_set1_pd(-0.0523674852303482457616113);
456
+ __m512d const coeff_8_f64x8 = _mm512_set1_pd(+0.0587666392926673580854313);
457
+ __m512d const coeff_7_f64x8 = _mm512_set1_pd(-0.0666573579361080525984562);
458
+ __m512d const coeff_6_f64x8 = _mm512_set1_pd(+0.0769219538311769618355029);
459
+ __m512d const coeff_5_f64x8 = _mm512_set1_pd(-0.090908995008245008229153);
460
+ __m512d const coeff_4_f64x8 = _mm512_set1_pd(+0.111111105648261418443745);
461
+ __m512d const coeff_3_f64x8 = _mm512_set1_pd(-0.14285714266771329383765);
462
+ __m512d const coeff_2_f64x8 = _mm512_set1_pd(+0.199999999996591265594148);
463
+ __m512d const coeff_1_f64x8 = _mm512_set1_pd(-0.333333333333311110369124);
464
+
465
+ // Quadrant adjustments normalizing to absolute values of x and y
466
+ __mmask8 const xs_negative_mask = _mm512_cmp_pd_mask(xs_inputs, _mm512_setzero_pd(), _CMP_LT_OS);
467
+ __m512d xs_f64x8 = _mm512_abs_pd(xs_inputs);
468
+ __m512d ys_f64x8 = _mm512_abs_pd(ys_inputs);
469
+ // Ensure proper fraction where the numerator is smaller than the denominator
470
+ __mmask8 const swap_mask = _mm512_cmp_pd_mask(ys_f64x8, xs_f64x8, _CMP_GT_OS);
471
+ __m512d temps_f64x8 = xs_f64x8;
472
+ xs_f64x8 = _mm512_mask_blend_pd(swap_mask, xs_f64x8, ys_f64x8);
473
+ ys_f64x8 = _mm512_mask_sub_pd(ys_f64x8, swap_mask, _mm512_setzero_pd(), temps_f64x8);
474
+
475
+ // Compute ratio_f64x8 and ratio²
476
+ __m512d const ratio_f64x8 = _mm512_div_pd(ys_f64x8, xs_f64x8);
477
+ __m512d const ratio_squared_f64x8 = _mm512_mul_pd(ratio_f64x8, ratio_f64x8);
478
+ __m512d const ratio_cubed_f64x8 = _mm512_mul_pd(ratio_f64x8, ratio_squared_f64x8);
479
+
480
+ // Polynomial evaluation
481
+ __m512d polynomials_f64x8 = coeff_19_f64x8;
482
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_18_f64x8);
483
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_17_f64x8);
484
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_16_f64x8);
485
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_15_f64x8);
486
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_14_f64x8);
487
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_13_f64x8);
488
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_12_f64x8);
489
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_11_f64x8);
490
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_10_f64x8);
491
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_9_f64x8);
492
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_8_f64x8);
493
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_7_f64x8);
494
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_6_f64x8);
495
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_5_f64x8);
496
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_4_f64x8);
497
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_3_f64x8);
498
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_2_f64x8);
499
+ polynomials_f64x8 = _mm512_fmadd_pd(polynomials_f64x8, ratio_squared_f64x8, coeff_1_f64x8);
500
+
501
+ // Compute the result with quadrant_f64x8 adjustments
502
+ __m512d results_f64x8 = _mm512_fmadd_pd(ratio_cubed_f64x8, polynomials_f64x8, ratio_f64x8);
503
+
504
+ // Compute quadrant_f64x8 value: 0 for x>=0 && !swap, 1 for x>=0 && swap,
505
+ // -2 for x<0 && !swap, -1 for x<0 && swap
506
+ __m512d quadrant_f64x8 = _mm512_setzero_pd();
507
+ quadrant_f64x8 = _mm512_mask_blend_pd(xs_negative_mask, quadrant_f64x8, _mm512_set1_pd(-2.0));
508
+ __m512d quadrant_incremented_f64x8 = _mm512_add_pd(quadrant_f64x8, _mm512_set1_pd(1.0));
509
+ quadrant_f64x8 = _mm512_mask_blend_pd(swap_mask, quadrant_f64x8, quadrant_incremented_f64x8);
510
+
511
+ // Adjust for quadrant_f64x8: result += quadrant_f64x8 * π/2
512
+ results_f64x8 = _mm512_fmadd_pd(quadrant_f64x8, _mm512_set1_pd(1.5707963267948966), results_f64x8);
513
+
514
+ // Transfer sign from x (XOR with sign bit of x_input)
515
+ __m512d xs_sign_f64x8 = _mm512_and_pd(xs_inputs, _mm512_set1_pd(-0.0));
516
+ results_f64x8 = _mm512_xor_pd(results_f64x8, xs_sign_f64x8);
517
+
518
+ // Transfer sign from y (XOR with sign bit of y_input)
519
+ __m512d ys_sign_f64x8 = _mm512_and_pd(ys_inputs, _mm512_set1_pd(-0.0));
520
+ results_f64x8 = _mm512_xor_pd(results_f64x8, ys_sign_f64x8);
521
+
522
+ return results_f64x8;
523
+ }
524
+
525
+ NK_PUBLIC void nk_each_sin_f64_skylake(nk_f64_t const *ins, nk_size_t n, nk_f64_t *outs) {
526
+ nk_size_t i = 0;
527
+ for (; i + 8 <= n; i += 8) {
528
+ __m512d angles_f64x8 = _mm512_loadu_pd(ins + i);
529
+ __m512d results_f64x8 = nk_sin_f64x8_skylake_(angles_f64x8);
530
+ _mm512_storeu_pd(outs + i, results_f64x8);
531
+ }
532
+ if (i < n) {
533
+ __mmask8 mask = (__mmask8)_bzhi_u32(0xFFFF, n - i);
534
+ __m512d angles_f64x8 = _mm512_maskz_loadu_pd(mask, ins + i);
535
+ __m512d results_f64x8 = nk_sin_f64x8_skylake_(angles_f64x8);
536
+ _mm512_mask_storeu_pd(outs + i, mask, results_f64x8);
537
+ }
538
+ }
539
+ NK_PUBLIC void nk_each_cos_f64_skylake(nk_f64_t const *ins, nk_size_t n, nk_f64_t *outs) {
540
+ nk_size_t i = 0;
541
+ for (; i + 8 <= n; i += 8) {
542
+ __m512d angles_f64x8 = _mm512_loadu_pd(ins + i);
543
+ __m512d results_f64x8 = nk_cos_f64x8_skylake_(angles_f64x8);
544
+ _mm512_storeu_pd(outs + i, results_f64x8);
545
+ }
546
+ if (i < n) {
547
+ __mmask8 mask = (__mmask8)_bzhi_u32(0xFFFF, n - i);
548
+ __m512d angles_f64x8 = _mm512_maskz_loadu_pd(mask, ins + i);
549
+ __m512d results_f64x8 = nk_cos_f64x8_skylake_(angles_f64x8);
550
+ _mm512_mask_storeu_pd(outs + i, mask, results_f64x8);
551
+ }
552
+ }
553
+ NK_PUBLIC void nk_each_atan_f64_skylake(nk_f64_t const *ins, nk_size_t n, nk_f64_t *outs) {
554
+ nk_size_t i = 0;
555
+ for (; i + 8 <= n; i += 8) {
556
+ __m512d angles_f64x8 = _mm512_loadu_pd(ins + i);
557
+ __m512d results_f64x8 = nk_atan_f64x8_skylake_(angles_f64x8);
558
+ _mm512_storeu_pd(outs + i, results_f64x8);
559
+ }
560
+ if (i < n) {
561
+ __mmask8 mask = (__mmask8)_bzhi_u32(0xFFFF, n - i);
562
+ __m512d angles_f64x8 = _mm512_maskz_loadu_pd(mask, ins + i);
563
+ __m512d results_f64x8 = nk_atan_f64x8_skylake_(angles_f64x8);
564
+ _mm512_mask_storeu_pd(outs + i, mask, results_f64x8);
565
+ }
566
+ }
567
+
568
+ /**
569
+ * @brief Sine approximation for 16 f16 values via f32 upcasting.
570
+ *
571
+ * Degree-5 polynomial with Cody-Waite range reduction in f32.
572
+ * Takes __m256i (f16 data), returns __m256i (f16 result).
573
+ */
574
+ NK_INTERNAL __m256i nk_sin_f16x16_skylake_(__m256i angles_f16x16) {
575
+ __m512 angles_f32x16 = _mm512_cvtph_ps(angles_f16x16);
576
+ // Cody-Waite range reduction constants
577
+ __m512 pi_high_f32x16 = _mm512_set1_ps(3.1415927f);
578
+ __m512 pi_low_f32x16 = _mm512_set1_ps(-8.742278e-8f);
579
+ __m512 pi_recip_f32x16 = _mm512_set1_ps(0.31830988618f);
580
+ __m512 c3_f32x16 = _mm512_set1_ps(-1.6666666641e-1f);
581
+ __m512 c5_f32x16 = _mm512_set1_ps(8.3333293855e-3f);
582
+
583
+ __m512 quotient_f32x16 = _mm512_mul_ps(angles_f32x16, pi_recip_f32x16);
584
+ __m512 rounded_f32x16 = _mm512_roundscale_ps(quotient_f32x16, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
585
+ // Use explicit rounding to match roundscale (MXCSR-independent)
586
+ __m512i multiple_i32x16 = _mm512_cvt_roundps_epi32(rounded_f32x16, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
587
+
588
+ angles_f32x16 = _mm512_fnmadd_ps(rounded_f32x16, pi_high_f32x16, angles_f32x16);
589
+ angles_f32x16 = _mm512_fnmadd_ps(rounded_f32x16, pi_low_f32x16, angles_f32x16);
590
+
591
+ __m512 x2_f32x16 = _mm512_mul_ps(angles_f32x16, angles_f32x16);
592
+ __m512 poly_f32x16 = _mm512_fmadd_ps(c5_f32x16, x2_f32x16, c3_f32x16);
593
+ poly_f32x16 = _mm512_mul_ps(poly_f32x16, x2_f32x16);
594
+ __m512 result_f32x16 = _mm512_fmadd_ps(poly_f32x16, angles_f32x16, angles_f32x16);
595
+
596
+ __mmask16 odd_mask = _mm512_test_epi32_mask(multiple_i32x16, _mm512_set1_epi32(1));
597
+ result_f32x16 = _mm512_mask_sub_ps(result_f32x16, odd_mask, _mm512_setzero_ps(), result_f32x16);
598
+ return _mm512_cvtps_ph(result_f32x16, _MM_FROUND_TO_NEAREST_INT);
599
+ }
600
+
601
+ /**
602
+ * @brief Cosine approximation for 16 f16 values via f32 upcasting.
603
+ *
604
+ * Uses cos(x) = sin(x + pi/2) with Cody-Waite range reduction in f32.
605
+ */
606
+ NK_INTERNAL __m256i nk_cos_f16x16_skylake_(__m256i angles_f16x16) {
607
+ __m512 angles_f32x16 = _mm512_cvtph_ps(angles_f16x16);
608
+ __m512 pi_high_f32x16 = _mm512_set1_ps(3.1415927f);
609
+ __m512 pi_low_f32x16 = _mm512_set1_ps(-8.742278e-8f);
610
+ __m512 pi_half_f32x16 = _mm512_set1_ps(1.5707963268f);
611
+ __m512 pi_recip_f32x16 = _mm512_set1_ps(0.31830988618f);
612
+ __m512 half_f32x16 = _mm512_set1_ps(0.5f);
613
+ __m512 c3_f32x16 = _mm512_set1_ps(-1.6666666641e-1f);
614
+ __m512 c5_f32x16 = _mm512_set1_ps(8.3333293855e-3f);
615
+
616
+ __m512 quotient_f32x16 = _mm512_fmsub_ps(angles_f32x16, pi_recip_f32x16, half_f32x16);
617
+ __m512 rounded_f32x16 = _mm512_roundscale_ps(quotient_f32x16, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
618
+ // Use explicit rounding to match roundscale (MXCSR-independent)
619
+ __m512i multiple_i32x16 = _mm512_cvt_roundps_epi32(rounded_f32x16, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
620
+
621
+ __m512 shift_f32x16 = _mm512_fmadd_ps(rounded_f32x16, pi_high_f32x16, pi_half_f32x16);
622
+ angles_f32x16 = _mm512_sub_ps(angles_f32x16, shift_f32x16);
623
+ angles_f32x16 = _mm512_fnmadd_ps(rounded_f32x16, pi_low_f32x16, angles_f32x16);
624
+
625
+ __m512 x2_f32x16 = _mm512_mul_ps(angles_f32x16, angles_f32x16);
626
+ __m512 poly_f32x16 = _mm512_fmadd_ps(c5_f32x16, x2_f32x16, c3_f32x16);
627
+ poly_f32x16 = _mm512_mul_ps(poly_f32x16, x2_f32x16);
628
+ __m512 result_f32x16 = _mm512_fmadd_ps(poly_f32x16, angles_f32x16, angles_f32x16);
629
+
630
+ __mmask16 even_mask = _mm512_testn_epi32_mask(multiple_i32x16, _mm512_set1_epi32(1));
631
+ result_f32x16 = _mm512_mask_sub_ps(result_f32x16, even_mask, _mm512_setzero_ps(), result_f32x16);
632
+ return _mm512_cvtps_ph(result_f32x16, _MM_FROUND_TO_NEAREST_INT);
633
+ }
634
+
635
+ /**
636
+ * @brief Arctangent approximation for 16 f16 values via f32 upcasting.
637
+ *
638
+ * Degree-9 polynomial in f32 with quadrant adjustments.
639
+ */
640
+ NK_INTERNAL __m256i nk_atan_f16x16_skylake_(__m256i values_f16x16) {
641
+ __m512 values_f32x16 = _mm512_cvtph_ps(values_f16x16);
642
+ __m512 c3_f32x16 = _mm512_set1_ps(-0.3333333333f);
643
+ __m512 c5_f32x16 = _mm512_set1_ps(0.2f);
644
+ __m512 c7_f32x16 = _mm512_set1_ps(-0.1428571429f);
645
+ __m512 c9_f32x16 = _mm512_set1_ps(0.1111111111f);
646
+ __m512 pi_half_f32x16 = _mm512_set1_ps(1.5707963268f);
647
+ __m512 one_f32x16 = _mm512_set1_ps(1.0f);
648
+
649
+ __mmask16 negative_mask = _mm512_cmp_ps_mask(values_f32x16, _mm512_setzero_ps(), _CMP_LT_OS);
650
+ values_f32x16 = _mm512_abs_ps(values_f32x16);
651
+ __mmask16 reciprocal_mask = _mm512_cmp_ps_mask(values_f32x16, one_f32x16, _CMP_GT_OS);
652
+ values_f32x16 = _mm512_mask_div_ps(values_f32x16, reciprocal_mask, one_f32x16, values_f32x16);
653
+
654
+ __m512 x2_f32x16 = _mm512_mul_ps(values_f32x16, values_f32x16);
655
+ __m512 x3_f32x16 = _mm512_mul_ps(values_f32x16, x2_f32x16);
656
+
657
+ __m512 poly_f32x16 = c9_f32x16;
658
+ poly_f32x16 = _mm512_fmadd_ps(poly_f32x16, x2_f32x16, c7_f32x16);
659
+ poly_f32x16 = _mm512_fmadd_ps(poly_f32x16, x2_f32x16, c5_f32x16);
660
+ poly_f32x16 = _mm512_fmadd_ps(poly_f32x16, x2_f32x16, c3_f32x16);
661
+
662
+ __m512 result_f32x16 = _mm512_fmadd_ps(x3_f32x16, poly_f32x16, values_f32x16);
663
+ result_f32x16 = _mm512_mask_sub_ps(result_f32x16, reciprocal_mask, pi_half_f32x16, result_f32x16);
664
+ result_f32x16 = _mm512_mask_sub_ps(result_f32x16, negative_mask, _mm512_setzero_ps(), result_f32x16);
665
+ return _mm512_cvtps_ph(result_f32x16, _MM_FROUND_TO_NEAREST_INT);
666
+ }
667
+
668
+ NK_PUBLIC void nk_each_sin_f16_skylake(nk_f16_t const *ins, nk_size_t n, nk_f16_t *outs) {
669
+ nk_size_t i = 0;
670
+ for (; i + 16 <= n; i += 16) {
671
+ __m256i angles_f16x16 = _mm256_loadu_si256((__m256i const *)(ins + i));
672
+ __m256i result_f16x16 = nk_sin_f16x16_skylake_(angles_f16x16);
673
+ _mm256_storeu_si256((__m256i *)(outs + i), result_f16x16);
674
+ }
675
+ if (i < n) {
676
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n - i);
677
+ __m256i angles_f16x16 = _mm256_maskz_loadu_epi16(mask, ins + i);
678
+ __m256i result_f16x16 = nk_sin_f16x16_skylake_(angles_f16x16);
679
+ _mm256_mask_storeu_epi16(outs + i, mask, result_f16x16);
680
+ }
681
+ }
682
+
683
+ NK_PUBLIC void nk_each_cos_f16_skylake(nk_f16_t const *ins, nk_size_t n, nk_f16_t *outs) {
684
+ nk_size_t i = 0;
685
+ for (; i + 16 <= n; i += 16) {
686
+ __m256i angles_f16x16 = _mm256_loadu_si256((__m256i const *)(ins + i));
687
+ __m256i result_f16x16 = nk_cos_f16x16_skylake_(angles_f16x16);
688
+ _mm256_storeu_si256((__m256i *)(outs + i), result_f16x16);
689
+ }
690
+ if (i < n) {
691
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n - i);
692
+ __m256i angles_f16x16 = _mm256_maskz_loadu_epi16(mask, ins + i);
693
+ __m256i result_f16x16 = nk_cos_f16x16_skylake_(angles_f16x16);
694
+ _mm256_mask_storeu_epi16(outs + i, mask, result_f16x16);
695
+ }
696
+ }
697
+
698
+ NK_PUBLIC void nk_each_atan_f16_skylake(nk_f16_t const *ins, nk_size_t n, nk_f16_t *outs) {
699
+ nk_size_t i = 0;
700
+ for (; i + 16 <= n; i += 16) {
701
+ __m256i values_f16x16 = _mm256_loadu_si256((__m256i const *)(ins + i));
702
+ __m256i result_f16x16 = nk_atan_f16x16_skylake_(values_f16x16);
703
+ _mm256_storeu_si256((__m256i *)(outs + i), result_f16x16);
704
+ }
705
+ if (i < n) {
706
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n - i);
707
+ __m256i values_f16x16 = _mm256_maskz_loadu_epi16(mask, ins + i);
708
+ __m256i result_f16x16 = nk_atan_f16x16_skylake_(values_f16x16);
709
+ _mm256_mask_storeu_epi16(outs + i, mask, result_f16x16);
710
+ }
711
+ }
712
+
713
+ #if defined(__clang__)
714
+ #pragma clang attribute pop
715
+ #elif defined(__GNUC__)
716
+ #pragma GCC pop_options
717
+ #endif
718
+
719
+ #if defined(__cplusplus)
720
+ } // extern "C"
721
+ #endif
722
+
723
+ #endif // NK_TARGET_SKYLAKE
724
+ #endif // NK_TARGET_X8664_
725
+ #endif // NK_TRIGONOMETRY_SKYLAKE_H