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,605 @@
1
+ /**
2
+ * @brief SIMD-accelerated Spatial Similarity Measures for Skylake.
3
+ * @file include/numkong/spatial/skylake.h
4
+ * @author Ash Vardanian
5
+ * @date December 27, 2025
6
+ *
7
+ * @sa include/numkong/spatial.h
8
+ *
9
+ * @section spatial_skylake_instructions Key AVX-512 Spatial Instructions
10
+ *
11
+ * Intrinsic Instruction Skylake-X Genoa
12
+ * _mm512_fmadd_ps VFMADD132PS (ZMM, ZMM, ZMM) 4cy @ p05 4cy @ p01
13
+ * _mm512_sub_ps VSUBPS (ZMM, ZMM, ZMM) 4cy @ p05 3cy @ p23
14
+ * _mm512_rsqrt14_ps VRSQRT14PS (ZMM, ZMM) 7cy @ p0+p0+p05 5cy @ p01
15
+ * _mm512_sqrt_ps VSQRTPS (ZMM, ZMM) 20cy @ p0+p0+p05 15cy @ p01
16
+ *
17
+ * Distance computations benefit from Skylake-X's dual FMA units achieving 0.5cy throughput for
18
+ * fused multiply-add operations. VRSQRT14PS provides ~14-bit precision reciprocal square root;
19
+ * with Newton-Raphson refinement, this exceeds f32's 23-bit mantissa requirements.
20
+ */
21
+ #ifndef NK_SPATIAL_SKYLAKE_H
22
+ #define NK_SPATIAL_SKYLAKE_H
23
+
24
+ #if NK_TARGET_X8664_
25
+ #if NK_TARGET_SKYLAKE
26
+
27
+ #include "numkong/types.h"
28
+ #include "numkong/reduce/skylake.h" // `nk_reduce_add_f32x16_skylake_`
29
+ #include "numkong/dot/skylake.h" // `nk_dot_f64x8_state_skylake_t`
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
+ /** @brief Reciprocal square root of 16 floats with Newton-Raphson refinement (~28-bit precision). */
44
+ NK_INTERNAL __m512 nk_rsqrt_f32x16_skylake_(__m512 x) {
45
+ __m512 rsqrt_f32x16 = _mm512_rsqrt14_ps(x);
46
+ __m512 nr_f32x16 = _mm512_mul_ps(_mm512_mul_ps(x, rsqrt_f32x16), rsqrt_f32x16);
47
+ nr_f32x16 = _mm512_sub_ps(_mm512_set1_ps(3.0f), nr_f32x16);
48
+ return _mm512_mul_ps(_mm512_mul_ps(_mm512_set1_ps(0.5f), rsqrt_f32x16), nr_f32x16);
49
+ }
50
+
51
+ /** @brief Reciprocal square root of 8 doubles with Newton-Raphson refinement (~28-bit precision). */
52
+ NK_INTERNAL __m512d nk_rsqrt_f64x8_skylake_(__m512d x) {
53
+ __m512d rsqrt_f64x8 = _mm512_rsqrt14_pd(x);
54
+ __m512d nr_f64x8 = _mm512_mul_pd(_mm512_mul_pd(x, rsqrt_f64x8), rsqrt_f64x8);
55
+ nr_f64x8 = _mm512_sub_pd(_mm512_set1_pd(3.0), nr_f64x8);
56
+ return _mm512_mul_pd(_mm512_mul_pd(_mm512_set1_pd(0.5), rsqrt_f64x8), nr_f64x8);
57
+ }
58
+
59
+ #pragma region F32 and F64 Floats
60
+
61
+ NK_PUBLIC void nk_sqeuclidean_f32_skylake(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result) {
62
+ // Upcast to f64 for higher precision accumulation
63
+ __m512d sum_f64x8 = _mm512_setzero_pd();
64
+ __m256 a_f32x8, b_f32x8;
65
+
66
+ nk_sqeuclidean_f32_skylake_cycle:
67
+ if (n < 8) {
68
+ __mmask8 mask = (__mmask8)_bzhi_u32(0xFFFFFFFF, n);
69
+ a_f32x8 = _mm256_maskz_loadu_ps(mask, a);
70
+ b_f32x8 = _mm256_maskz_loadu_ps(mask, b);
71
+ n = 0;
72
+ }
73
+ else {
74
+ a_f32x8 = _mm256_loadu_ps(a);
75
+ b_f32x8 = _mm256_loadu_ps(b);
76
+ a += 8, b += 8, n -= 8;
77
+ }
78
+ __m512d a_f64x8 = _mm512_cvtps_pd(a_f32x8);
79
+ __m512d b_f64x8 = _mm512_cvtps_pd(b_f32x8);
80
+ __m512d diff_f64x8 = _mm512_sub_pd(a_f64x8, b_f64x8);
81
+ sum_f64x8 = _mm512_fmadd_pd(diff_f64x8, diff_f64x8, sum_f64x8);
82
+ if (n) goto nk_sqeuclidean_f32_skylake_cycle;
83
+
84
+ *result = _mm512_reduce_add_pd(sum_f64x8);
85
+ }
86
+
87
+ NK_PUBLIC void nk_euclidean_f32_skylake(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result) {
88
+ nk_sqeuclidean_f32_skylake(a, b, n, result);
89
+ *result = nk_f64_sqrt_haswell(*result);
90
+ }
91
+
92
+ NK_INTERNAL nk_f64_t nk_angular_normalize_f64_skylake_(nk_f64_t ab, nk_f64_t a2, nk_f64_t b2) {
93
+
94
+ // If both vectors have magnitude 0, the distance is 0.
95
+ if (a2 == 0 && b2 == 0) return 0;
96
+ // If any one of the vectors is 0, the square root of the product is 0,
97
+ // the division is illformed, and the result is 1.
98
+ else if (ab == 0) return 1;
99
+
100
+ // Design note: We use exact `_mm_sqrt_pd` instead of `_mm_rsqrt14_pd` approximation.
101
+ // The AVX-512 `_mm_rsqrt14_pd` has max relative error of 2⁻¹⁴ (~14 bits precision).
102
+ // Even with Newton-Raphson refinement (doubles precision to ~28 bits), this is
103
+ // insufficient for f64's 52-bit mantissa, causing ULP errors in the tens of millions.
104
+ // The `_mm_sqrt_pd` instruction provides full f64 precision.
105
+ //
106
+ // Precision comparison for 1536-dimensional vectors:
107
+ // DType rsqrt14+NR Error Exact sqrt Error
108
+ // float64 1.35e-11 ± 1.85e-11 ~0 (2 ULP max)
109
+ //
110
+ // https://web.archive.org/web/20210208132927/http://assemblyrequired.crashworks.org/timing-square-root/
111
+ __m128d squares_f64x2 = _mm_set_pd(a2, b2);
112
+ __m128d sqrts_f64x2 = _mm_sqrt_pd(squares_f64x2);
113
+ nk_f64_t a_sqrt = _mm_cvtsd_f64(_mm_unpackhi_pd(sqrts_f64x2, sqrts_f64x2));
114
+ nk_f64_t b_sqrt = _mm_cvtsd_f64(sqrts_f64x2);
115
+ nk_f64_t result = 1 - ab / (a_sqrt * b_sqrt);
116
+ return result > 0 ? result : 0;
117
+ }
118
+
119
+ NK_PUBLIC void nk_angular_f32_skylake(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result) {
120
+ // Upcast to f64 for higher precision accumulation
121
+ __m512d dot_f64x8 = _mm512_setzero_pd();
122
+ __m512d a_norm_sq_f64x8 = _mm512_setzero_pd();
123
+ __m512d b_norm_sq_f64x8 = _mm512_setzero_pd();
124
+ __m256 a_f32x8, b_f32x8;
125
+
126
+ nk_angular_f32_skylake_cycle:
127
+ if (n < 8) {
128
+ __mmask8 mask = (__mmask8)_bzhi_u32(0xFFFFFFFF, n);
129
+ a_f32x8 = _mm256_maskz_loadu_ps(mask, a);
130
+ b_f32x8 = _mm256_maskz_loadu_ps(mask, b);
131
+ n = 0;
132
+ }
133
+ else {
134
+ a_f32x8 = _mm256_loadu_ps(a);
135
+ b_f32x8 = _mm256_loadu_ps(b);
136
+ a += 8, b += 8, n -= 8;
137
+ }
138
+ __m512d a_f64x8 = _mm512_cvtps_pd(a_f32x8);
139
+ __m512d b_f64x8 = _mm512_cvtps_pd(b_f32x8);
140
+ dot_f64x8 = _mm512_fmadd_pd(a_f64x8, b_f64x8, dot_f64x8);
141
+ a_norm_sq_f64x8 = _mm512_fmadd_pd(a_f64x8, a_f64x8, a_norm_sq_f64x8);
142
+ b_norm_sq_f64x8 = _mm512_fmadd_pd(b_f64x8, b_f64x8, b_norm_sq_f64x8);
143
+ if (n) goto nk_angular_f32_skylake_cycle;
144
+
145
+ nk_f64_t dot_f64 = _mm512_reduce_add_pd(dot_f64x8);
146
+ nk_f64_t a_norm_sq_f64 = _mm512_reduce_add_pd(a_norm_sq_f64x8);
147
+ nk_f64_t b_norm_sq_f64 = _mm512_reduce_add_pd(b_norm_sq_f64x8);
148
+ *result = nk_angular_normalize_f64_skylake_(dot_f64, a_norm_sq_f64, b_norm_sq_f64);
149
+ }
150
+
151
+ NK_PUBLIC void nk_sqeuclidean_f64_skylake(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result) {
152
+ __m512d sum_f64x8 = _mm512_setzero_pd();
153
+ __m512d a_f64x8, b_f64x8;
154
+
155
+ nk_sqeuclidean_f64_skylake_cycle:
156
+ if (n < 8) {
157
+ __mmask8 mask = (__mmask8)_bzhi_u32(0xFFFFFFFF, n);
158
+ a_f64x8 = _mm512_maskz_loadu_pd(mask, a);
159
+ b_f64x8 = _mm512_maskz_loadu_pd(mask, b);
160
+ n = 0;
161
+ }
162
+ else {
163
+ a_f64x8 = _mm512_loadu_pd(a);
164
+ b_f64x8 = _mm512_loadu_pd(b);
165
+ a += 8, b += 8, n -= 8;
166
+ }
167
+ __m512d diff_f64x8 = _mm512_sub_pd(a_f64x8, b_f64x8);
168
+ sum_f64x8 = _mm512_fmadd_pd(diff_f64x8, diff_f64x8, sum_f64x8);
169
+ if (n) goto nk_sqeuclidean_f64_skylake_cycle;
170
+
171
+ *result = _mm512_reduce_add_pd(sum_f64x8);
172
+ }
173
+
174
+ NK_PUBLIC void nk_euclidean_f64_skylake(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result) {
175
+ nk_sqeuclidean_f64_skylake(a, b, n, result);
176
+ *result = nk_f64_sqrt_haswell(*result);
177
+ }
178
+
179
+ NK_PUBLIC void nk_angular_f64_skylake(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result) {
180
+ // Dot2 (Ogita-Rump-Oishi 2005) for cross-product a × b only - it may have cancellation.
181
+ // Self-products ‖a‖² and ‖b‖² use simple FMA - all terms are non-negative, no cancellation.
182
+ __m512d dot_sum_f64x8 = _mm512_setzero_pd();
183
+ __m512d dot_compensation_f64x8 = _mm512_setzero_pd();
184
+ __m512d a_norm_sq_f64x8 = _mm512_setzero_pd();
185
+ __m512d b_norm_sq_f64x8 = _mm512_setzero_pd();
186
+ __m512d a_f64x8, b_f64x8;
187
+
188
+ nk_angular_f64_skylake_cycle:
189
+ if (n < 8) {
190
+ __mmask8 mask = (__mmask8)_bzhi_u32(0xFFFFFFFF, n);
191
+ a_f64x8 = _mm512_maskz_loadu_pd(mask, a);
192
+ b_f64x8 = _mm512_maskz_loadu_pd(mask, b);
193
+ n = 0;
194
+ }
195
+ else {
196
+ a_f64x8 = _mm512_loadu_pd(a);
197
+ b_f64x8 = _mm512_loadu_pd(b);
198
+ a += 8, b += 8, n -= 8;
199
+ }
200
+ // TwoProd for cross-product: product = a * b, error = fma(a, b, -product)
201
+ __m512d x_f64x8 = _mm512_mul_pd(a_f64x8, b_f64x8);
202
+ __m512d product_error_f64x8 = _mm512_fmsub_pd(a_f64x8, b_f64x8, x_f64x8);
203
+ // Neumaier TwoSum: t = sum + x, with masked error recovery
204
+ __m512d tentative_sum_f64x8 = _mm512_add_pd(dot_sum_f64x8, x_f64x8);
205
+ __m512d abs_sum_f64x8 = _mm512_abs_pd(dot_sum_f64x8);
206
+ __m512d abs_x_f64x8 = _mm512_abs_pd(x_f64x8);
207
+ __mmask8 sum_ge_x = _mm512_cmp_pd_mask(abs_sum_f64x8, abs_x_f64x8, _CMP_GE_OQ);
208
+ // z = t - larger, error = smaller - z
209
+ __m512d virtual_addend_f64x8 = _mm512_sub_pd(tentative_sum_f64x8, x_f64x8);
210
+ virtual_addend_f64x8 = _mm512_mask_sub_pd(virtual_addend_f64x8, sum_ge_x, tentative_sum_f64x8, dot_sum_f64x8);
211
+ __m512d sum_error_f64x8 = _mm512_sub_pd(dot_sum_f64x8, virtual_addend_f64x8);
212
+ sum_error_f64x8 = _mm512_mask_sub_pd(sum_error_f64x8, sum_ge_x, x_f64x8, virtual_addend_f64x8);
213
+ dot_sum_f64x8 = tentative_sum_f64x8;
214
+ dot_compensation_f64x8 = _mm512_add_pd(dot_compensation_f64x8, _mm512_add_pd(sum_error_f64x8, product_error_f64x8));
215
+ // Simple FMA for self-products (no cancellation possible)
216
+ a_norm_sq_f64x8 = _mm512_fmadd_pd(a_f64x8, a_f64x8, a_norm_sq_f64x8);
217
+ b_norm_sq_f64x8 = _mm512_fmadd_pd(b_f64x8, b_f64x8, b_norm_sq_f64x8);
218
+ if (n) goto nk_angular_f64_skylake_cycle;
219
+
220
+ nk_f64_t dot_product_f64 = nk_dot_stable_sum_f64x8_skylake_(dot_sum_f64x8, dot_compensation_f64x8);
221
+ nk_f64_t a_norm_sq_f64 = _mm512_reduce_add_pd(a_norm_sq_f64x8);
222
+ nk_f64_t b_norm_sq_f64 = _mm512_reduce_add_pd(b_norm_sq_f64x8);
223
+ *result = nk_angular_normalize_f64_skylake_(dot_product_f64, a_norm_sq_f64, b_norm_sq_f64);
224
+ }
225
+
226
+ /** @brief Angular from_dot for native f64: 1 − dot / √(query_sumsq × target_sumsq) for 4 pairs. */
227
+ NK_INTERNAL void nk_angular_f64x4_from_dot_skylake_(nk_b256_vec_t dots, nk_f64_t query_sumsq,
228
+ nk_b256_vec_t target_sumsqs, nk_b256_vec_t *results) {
229
+ __m256d dots_f64x4 = dots.ymm_pd;
230
+ __m256d query_sumsq_f64x4 = _mm256_set1_pd(query_sumsq);
231
+ __m256d products_f64x4 = _mm256_mul_pd(query_sumsq_f64x4, target_sumsqs.ymm_pd);
232
+ __m256d sqrt_products_f64x4 = _mm256_sqrt_pd(products_f64x4);
233
+ __m256d normalized_f64x4 = _mm256_div_pd(dots_f64x4, sqrt_products_f64x4);
234
+ __m256d ones_f64x4 = _mm256_set1_pd(1.0);
235
+ __m256d angular_f64x4 = _mm256_sub_pd(ones_f64x4, normalized_f64x4);
236
+ results->ymm_pd = _mm256_max_pd(angular_f64x4, _mm256_setzero_pd());
237
+ }
238
+
239
+ /** @brief Euclidean from_dot for native f64: √(query_sumsq + target_sumsq − 2 × dot) for 4 pairs. */
240
+ NK_INTERNAL void nk_euclidean_f64x4_from_dot_skylake_(nk_b256_vec_t dots, nk_f64_t query_sumsq,
241
+ nk_b256_vec_t target_sumsqs, nk_b256_vec_t *results) {
242
+ __m256d dots_f64x4 = dots.ymm_pd;
243
+ __m256d query_sumsq_f64x4 = _mm256_set1_pd(query_sumsq);
244
+ __m256d two_f64x4 = _mm256_set1_pd(2.0);
245
+ __m256d sum_sq_f64x4 = _mm256_add_pd(query_sumsq_f64x4, target_sumsqs.ymm_pd);
246
+ __m256d dist_sq_f64x4 = _mm256_fnmadd_pd(two_f64x4, dots_f64x4, sum_sq_f64x4);
247
+ __m256d zeros_f64x4 = _mm256_setzero_pd();
248
+ __m256d clamped_f64x4 = _mm256_max_pd(dist_sq_f64x4, zeros_f64x4);
249
+ results->ymm_pd = _mm256_sqrt_pd(clamped_f64x4);
250
+ }
251
+
252
+ /** @brief Angular from_dot: f32 dots upcast to f64 for precision. Output via nk_b128_vec_t (f32). */
253
+ NK_INTERNAL void nk_angular_through_f64_from_dot_skylake_(nk_b128_vec_t dots, nk_f32_t query_sumsq,
254
+ nk_b128_vec_t target_sumsqs, nk_b128_vec_t *results) {
255
+ __m128 dots_f32x4 = dots.xmm_ps;
256
+ __m256d dots_f64x4 = _mm256_cvtps_pd(dots_f32x4);
257
+ __m256d query_sumsq_f64x4 = _mm256_set1_pd((nk_f64_t)query_sumsq);
258
+ __m256d target_sumsqs_f64x4 = _mm256_cvtps_pd(target_sumsqs.xmm_ps);
259
+ __m256d products_f64x4 = _mm256_mul_pd(query_sumsq_f64x4, target_sumsqs_f64x4);
260
+ __m256d sqrt_products_f64x4 = _mm256_sqrt_pd(products_f64x4);
261
+ __m256d normalized_f64x4 = _mm256_div_pd(dots_f64x4, sqrt_products_f64x4);
262
+ __m256d ones_f64x4 = _mm256_set1_pd(1.0);
263
+ __m256d angular_f64x4 = _mm256_sub_pd(ones_f64x4, normalized_f64x4);
264
+ angular_f64x4 = _mm256_max_pd(angular_f64x4, _mm256_setzero_pd());
265
+ results->xmm_ps = _mm256_cvtpd_ps(angular_f64x4);
266
+ }
267
+
268
+ /** @brief Euclidean from_dot: f32 dots upcast to f64 for precision. Output via nk_b128_vec_t (f32). */
269
+ NK_INTERNAL void nk_euclidean_through_f64_from_dot_skylake_(nk_b128_vec_t dots, nk_f32_t query_sumsq,
270
+ nk_b128_vec_t target_sumsqs, nk_b128_vec_t *results) {
271
+ __m128 dots_f32x4 = dots.xmm_ps;
272
+ __m256d dots_f64x4 = _mm256_cvtps_pd(dots_f32x4);
273
+ __m256d query_sumsq_f64x4 = _mm256_set1_pd((nk_f64_t)query_sumsq);
274
+ __m256d target_sumsqs_f64x4 = _mm256_cvtps_pd(target_sumsqs.xmm_ps);
275
+ __m256d two_f64x4 = _mm256_set1_pd(2.0);
276
+ __m256d sum_sq_f64x4 = _mm256_add_pd(query_sumsq_f64x4, target_sumsqs_f64x4);
277
+ __m256d dist_sq_f64x4 = _mm256_fnmadd_pd(two_f64x4, dots_f64x4, sum_sq_f64x4);
278
+ __m256d zeros_f64x4 = _mm256_setzero_pd();
279
+ __m256d clamped_f64x4 = _mm256_max_pd(dist_sq_f64x4, zeros_f64x4);
280
+ __m256d dist_f64x4 = _mm256_sqrt_pd(clamped_f64x4);
281
+ results->xmm_ps = _mm256_cvtpd_ps(dist_f64x4);
282
+ }
283
+
284
+ #pragma endregion F32 and F64 Floats
285
+ #pragma region F16 and BF16 Floats
286
+
287
+ NK_PUBLIC void nk_sqeuclidean_f16_skylake(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result) {
288
+ __m512 sum_f32x16 = _mm512_setzero_ps();
289
+ __m256i a_f16x16, b_f16x16;
290
+
291
+ nk_sqeuclidean_f16_skylake_cycle:
292
+ if (n < 16) {
293
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n);
294
+ a_f16x16 = _mm256_maskz_loadu_epi16(mask, a);
295
+ b_f16x16 = _mm256_maskz_loadu_epi16(mask, b);
296
+ n = 0;
297
+ }
298
+ else {
299
+ a_f16x16 = _mm256_loadu_si256((__m256i const *)a);
300
+ b_f16x16 = _mm256_loadu_si256((__m256i const *)b);
301
+ a += 16, b += 16, n -= 16;
302
+ }
303
+ __m512 a_f32x16 = _mm512_cvtph_ps(a_f16x16);
304
+ __m512 b_f32x16 = _mm512_cvtph_ps(b_f16x16);
305
+ __m512 diff_f32x16 = _mm512_sub_ps(a_f32x16, b_f32x16);
306
+ sum_f32x16 = _mm512_fmadd_ps(diff_f32x16, diff_f32x16, sum_f32x16);
307
+ if (n) goto nk_sqeuclidean_f16_skylake_cycle;
308
+
309
+ *result = nk_reduce_add_f32x16_skylake_(sum_f32x16);
310
+ }
311
+
312
+ NK_PUBLIC void nk_euclidean_f16_skylake(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result) {
313
+ nk_sqeuclidean_f16_skylake(a, b, n, result);
314
+ *result = nk_f32_sqrt_haswell(*result);
315
+ }
316
+
317
+ NK_PUBLIC void nk_angular_f16_skylake(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result) {
318
+ __m512 dot_f32x16 = _mm512_setzero_ps();
319
+ __m512 a_norm_sq_f32x16 = _mm512_setzero_ps();
320
+ __m512 b_norm_sq_f32x16 = _mm512_setzero_ps();
321
+ __m256i a_f16x16, b_f16x16;
322
+
323
+ nk_angular_f16_skylake_cycle:
324
+ if (n < 16) {
325
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n);
326
+ a_f16x16 = _mm256_maskz_loadu_epi16(mask, a);
327
+ b_f16x16 = _mm256_maskz_loadu_epi16(mask, b);
328
+ n = 0;
329
+ }
330
+ else {
331
+ a_f16x16 = _mm256_loadu_si256((__m256i const *)a);
332
+ b_f16x16 = _mm256_loadu_si256((__m256i const *)b);
333
+ a += 16, b += 16, n -= 16;
334
+ }
335
+ __m512 a_f32x16 = _mm512_cvtph_ps(a_f16x16);
336
+ __m512 b_f32x16 = _mm512_cvtph_ps(b_f16x16);
337
+ dot_f32x16 = _mm512_fmadd_ps(a_f32x16, b_f32x16, dot_f32x16);
338
+ a_norm_sq_f32x16 = _mm512_fmadd_ps(a_f32x16, a_f32x16, a_norm_sq_f32x16);
339
+ b_norm_sq_f32x16 = _mm512_fmadd_ps(b_f32x16, b_f32x16, b_norm_sq_f32x16);
340
+ if (n) goto nk_angular_f16_skylake_cycle;
341
+
342
+ nk_f32_t dot_f32 = nk_reduce_add_f32x16_skylake_(dot_f32x16);
343
+ nk_f32_t a_norm_sq_f32 = nk_reduce_add_f32x16_skylake_(a_norm_sq_f32x16);
344
+ nk_f32_t b_norm_sq_f32 = nk_reduce_add_f32x16_skylake_(b_norm_sq_f32x16);
345
+ *result = nk_angular_normalize_f32_haswell_(dot_f32, a_norm_sq_f32, b_norm_sq_f32);
346
+ }
347
+
348
+ NK_PUBLIC void nk_sqeuclidean_e4m3_skylake(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result) {
349
+ __m512 sum_f32x16 = _mm512_setzero_ps();
350
+ __m128i a_e4m3_u8x16, b_e4m3_u8x16;
351
+
352
+ nk_sqeuclidean_e4m3_skylake_cycle:
353
+ if (n < 16) {
354
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n);
355
+ a_e4m3_u8x16 = _mm_maskz_loadu_epi8(mask, a);
356
+ b_e4m3_u8x16 = _mm_maskz_loadu_epi8(mask, b);
357
+ n = 0;
358
+ }
359
+ else {
360
+ a_e4m3_u8x16 = _mm_loadu_si128((__m128i const *)a);
361
+ b_e4m3_u8x16 = _mm_loadu_si128((__m128i const *)b);
362
+ a += 16, b += 16, n -= 16;
363
+ }
364
+ __m512 a_f32x16 = nk_e4m3x16_to_f32x16_skylake_(a_e4m3_u8x16);
365
+ __m512 b_f32x16 = nk_e4m3x16_to_f32x16_skylake_(b_e4m3_u8x16);
366
+ __m512 diff_f32x16 = _mm512_sub_ps(a_f32x16, b_f32x16);
367
+ sum_f32x16 = _mm512_fmadd_ps(diff_f32x16, diff_f32x16, sum_f32x16);
368
+ if (n) goto nk_sqeuclidean_e4m3_skylake_cycle;
369
+
370
+ *result = nk_reduce_add_f32x16_skylake_(sum_f32x16);
371
+ }
372
+
373
+ NK_PUBLIC void nk_euclidean_e4m3_skylake(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result) {
374
+ nk_sqeuclidean_e4m3_skylake(a, b, n, result);
375
+ *result = nk_f32_sqrt_haswell(*result);
376
+ }
377
+
378
+ NK_PUBLIC void nk_angular_e4m3_skylake(nk_e4m3_t const *a, nk_e4m3_t const *b, nk_size_t n, nk_f32_t *result) {
379
+ __m512 dot_f32x16 = _mm512_setzero_ps();
380
+ __m512 a_norm_sq_f32x16 = _mm512_setzero_ps();
381
+ __m512 b_norm_sq_f32x16 = _mm512_setzero_ps();
382
+ __m128i a_e4m3_u8x16, b_e4m3_u8x16;
383
+
384
+ nk_angular_e4m3_skylake_cycle:
385
+ if (n < 16) {
386
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n);
387
+ a_e4m3_u8x16 = _mm_maskz_loadu_epi8(mask, a);
388
+ b_e4m3_u8x16 = _mm_maskz_loadu_epi8(mask, b);
389
+ n = 0;
390
+ }
391
+ else {
392
+ a_e4m3_u8x16 = _mm_loadu_si128((__m128i const *)a);
393
+ b_e4m3_u8x16 = _mm_loadu_si128((__m128i const *)b);
394
+ a += 16, b += 16, n -= 16;
395
+ }
396
+ __m512 a_f32x16 = nk_e4m3x16_to_f32x16_skylake_(a_e4m3_u8x16);
397
+ __m512 b_f32x16 = nk_e4m3x16_to_f32x16_skylake_(b_e4m3_u8x16);
398
+ dot_f32x16 = _mm512_fmadd_ps(a_f32x16, b_f32x16, dot_f32x16);
399
+ a_norm_sq_f32x16 = _mm512_fmadd_ps(a_f32x16, a_f32x16, a_norm_sq_f32x16);
400
+ b_norm_sq_f32x16 = _mm512_fmadd_ps(b_f32x16, b_f32x16, b_norm_sq_f32x16);
401
+ if (n) goto nk_angular_e4m3_skylake_cycle;
402
+
403
+ nk_f32_t dot_f32 = nk_reduce_add_f32x16_skylake_(dot_f32x16);
404
+ nk_f32_t a_norm_sq_f32 = nk_reduce_add_f32x16_skylake_(a_norm_sq_f32x16);
405
+ nk_f32_t b_norm_sq_f32 = nk_reduce_add_f32x16_skylake_(b_norm_sq_f32x16);
406
+ *result = nk_angular_normalize_f32_haswell_(dot_f32, a_norm_sq_f32, b_norm_sq_f32);
407
+ }
408
+
409
+ NK_PUBLIC void nk_sqeuclidean_e5m2_skylake(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result) {
410
+ __m512 sum_f32x16 = _mm512_setzero_ps();
411
+ __m128i a_e5m2_u8x16, b_e5m2_u8x16;
412
+
413
+ nk_sqeuclidean_e5m2_skylake_cycle:
414
+ if (n < 16) {
415
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n);
416
+ a_e5m2_u8x16 = _mm_maskz_loadu_epi8(mask, a);
417
+ b_e5m2_u8x16 = _mm_maskz_loadu_epi8(mask, b);
418
+ n = 0;
419
+ }
420
+ else {
421
+ a_e5m2_u8x16 = _mm_loadu_si128((__m128i const *)a);
422
+ b_e5m2_u8x16 = _mm_loadu_si128((__m128i const *)b);
423
+ a += 16, b += 16, n -= 16;
424
+ }
425
+ __m512 a_f32x16 = nk_e5m2x16_to_f32x16_skylake_(a_e5m2_u8x16);
426
+ __m512 b_f32x16 = nk_e5m2x16_to_f32x16_skylake_(b_e5m2_u8x16);
427
+ __m512 diff_f32x16 = _mm512_sub_ps(a_f32x16, b_f32x16);
428
+ sum_f32x16 = _mm512_fmadd_ps(diff_f32x16, diff_f32x16, sum_f32x16);
429
+ if (n) goto nk_sqeuclidean_e5m2_skylake_cycle;
430
+
431
+ *result = nk_reduce_add_f32x16_skylake_(sum_f32x16);
432
+ }
433
+
434
+ NK_PUBLIC void nk_euclidean_e5m2_skylake(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result) {
435
+ nk_sqeuclidean_e5m2_skylake(a, b, n, result);
436
+ *result = nk_f32_sqrt_haswell(*result);
437
+ }
438
+
439
+ NK_PUBLIC void nk_angular_e5m2_skylake(nk_e5m2_t const *a, nk_e5m2_t const *b, nk_size_t n, nk_f32_t *result) {
440
+ __m512 dot_f32x16 = _mm512_setzero_ps();
441
+ __m512 a_norm_sq_f32x16 = _mm512_setzero_ps();
442
+ __m512 b_norm_sq_f32x16 = _mm512_setzero_ps();
443
+ __m128i a_e5m2_u8x16, b_e5m2_u8x16;
444
+
445
+ nk_angular_e5m2_skylake_cycle:
446
+ if (n < 16) {
447
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n);
448
+ a_e5m2_u8x16 = _mm_maskz_loadu_epi8(mask, a);
449
+ b_e5m2_u8x16 = _mm_maskz_loadu_epi8(mask, b);
450
+ n = 0;
451
+ }
452
+ else {
453
+ a_e5m2_u8x16 = _mm_loadu_si128((__m128i const *)a);
454
+ b_e5m2_u8x16 = _mm_loadu_si128((__m128i const *)b);
455
+ a += 16, b += 16, n -= 16;
456
+ }
457
+ __m512 a_f32x16 = nk_e5m2x16_to_f32x16_skylake_(a_e5m2_u8x16);
458
+ __m512 b_f32x16 = nk_e5m2x16_to_f32x16_skylake_(b_e5m2_u8x16);
459
+ dot_f32x16 = _mm512_fmadd_ps(a_f32x16, b_f32x16, dot_f32x16);
460
+ a_norm_sq_f32x16 = _mm512_fmadd_ps(a_f32x16, a_f32x16, a_norm_sq_f32x16);
461
+ b_norm_sq_f32x16 = _mm512_fmadd_ps(b_f32x16, b_f32x16, b_norm_sq_f32x16);
462
+ if (n) goto nk_angular_e5m2_skylake_cycle;
463
+
464
+ nk_f32_t dot_f32 = nk_reduce_add_f32x16_skylake_(dot_f32x16);
465
+ nk_f32_t a_norm_sq_f32 = nk_reduce_add_f32x16_skylake_(a_norm_sq_f32x16);
466
+ nk_f32_t b_norm_sq_f32 = nk_reduce_add_f32x16_skylake_(b_norm_sq_f32x16);
467
+ *result = nk_angular_normalize_f32_haswell_(dot_f32, a_norm_sq_f32, b_norm_sq_f32);
468
+ }
469
+
470
+ NK_PUBLIC void nk_sqeuclidean_e2m3_skylake(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result) {
471
+ __m512 sum_f32x16 = _mm512_setzero_ps();
472
+ __m128i a_e2m3_u8x16, b_e2m3_u8x16;
473
+
474
+ nk_sqeuclidean_e2m3_skylake_cycle:
475
+ if (n < 16) {
476
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n);
477
+ a_e2m3_u8x16 = _mm_maskz_loadu_epi8(mask, a);
478
+ b_e2m3_u8x16 = _mm_maskz_loadu_epi8(mask, b);
479
+ n = 0;
480
+ }
481
+ else {
482
+ a_e2m3_u8x16 = _mm_loadu_si128((__m128i const *)a);
483
+ b_e2m3_u8x16 = _mm_loadu_si128((__m128i const *)b);
484
+ a += 16, b += 16, n -= 16;
485
+ }
486
+ __m512 a_f32x16 = nk_e2m3x16_to_f32x16_skylake_(a_e2m3_u8x16);
487
+ __m512 b_f32x16 = nk_e2m3x16_to_f32x16_skylake_(b_e2m3_u8x16);
488
+ __m512 diff_f32x16 = _mm512_sub_ps(a_f32x16, b_f32x16);
489
+ sum_f32x16 = _mm512_fmadd_ps(diff_f32x16, diff_f32x16, sum_f32x16);
490
+ if (n) goto nk_sqeuclidean_e2m3_skylake_cycle;
491
+
492
+ *result = nk_reduce_add_f32x16_skylake_(sum_f32x16);
493
+ }
494
+
495
+ NK_PUBLIC void nk_euclidean_e2m3_skylake(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result) {
496
+ nk_sqeuclidean_e2m3_skylake(a, b, n, result);
497
+ *result = nk_f32_sqrt_haswell(*result);
498
+ }
499
+
500
+ NK_PUBLIC void nk_angular_e2m3_skylake(nk_e2m3_t const *a, nk_e2m3_t const *b, nk_size_t n, nk_f32_t *result) {
501
+ __m512 dot_f32x16 = _mm512_setzero_ps();
502
+ __m512 a_norm_sq_f32x16 = _mm512_setzero_ps();
503
+ __m512 b_norm_sq_f32x16 = _mm512_setzero_ps();
504
+ __m128i a_e2m3_u8x16, b_e2m3_u8x16;
505
+
506
+ nk_angular_e2m3_skylake_cycle:
507
+ if (n < 16) {
508
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n);
509
+ a_e2m3_u8x16 = _mm_maskz_loadu_epi8(mask, a);
510
+ b_e2m3_u8x16 = _mm_maskz_loadu_epi8(mask, b);
511
+ n = 0;
512
+ }
513
+ else {
514
+ a_e2m3_u8x16 = _mm_loadu_si128((__m128i const *)a);
515
+ b_e2m3_u8x16 = _mm_loadu_si128((__m128i const *)b);
516
+ a += 16, b += 16, n -= 16;
517
+ }
518
+ __m512 a_f32x16 = nk_e2m3x16_to_f32x16_skylake_(a_e2m3_u8x16);
519
+ __m512 b_f32x16 = nk_e2m3x16_to_f32x16_skylake_(b_e2m3_u8x16);
520
+ dot_f32x16 = _mm512_fmadd_ps(a_f32x16, b_f32x16, dot_f32x16);
521
+ a_norm_sq_f32x16 = _mm512_fmadd_ps(a_f32x16, a_f32x16, a_norm_sq_f32x16);
522
+ b_norm_sq_f32x16 = _mm512_fmadd_ps(b_f32x16, b_f32x16, b_norm_sq_f32x16);
523
+ if (n) goto nk_angular_e2m3_skylake_cycle;
524
+
525
+ nk_f32_t dot_f32 = nk_reduce_add_f32x16_skylake_(dot_f32x16);
526
+ nk_f32_t a_norm_sq_f32 = nk_reduce_add_f32x16_skylake_(a_norm_sq_f32x16);
527
+ nk_f32_t b_norm_sq_f32 = nk_reduce_add_f32x16_skylake_(b_norm_sq_f32x16);
528
+ *result = nk_angular_normalize_f32_haswell_(dot_f32, a_norm_sq_f32, b_norm_sq_f32);
529
+ }
530
+
531
+ NK_PUBLIC void nk_sqeuclidean_e3m2_skylake(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result) {
532
+ __m512 sum_f32x16 = _mm512_setzero_ps();
533
+ __m128i a_e3m2_u8x16, b_e3m2_u8x16;
534
+
535
+ nk_sqeuclidean_e3m2_skylake_cycle:
536
+ if (n < 16) {
537
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n);
538
+ a_e3m2_u8x16 = _mm_maskz_loadu_epi8(mask, a);
539
+ b_e3m2_u8x16 = _mm_maskz_loadu_epi8(mask, b);
540
+ n = 0;
541
+ }
542
+ else {
543
+ a_e3m2_u8x16 = _mm_loadu_si128((__m128i const *)a);
544
+ b_e3m2_u8x16 = _mm_loadu_si128((__m128i const *)b);
545
+ a += 16, b += 16, n -= 16;
546
+ }
547
+ __m512 a_f32x16 = nk_e3m2x16_to_f32x16_skylake_(a_e3m2_u8x16);
548
+ __m512 b_f32x16 = nk_e3m2x16_to_f32x16_skylake_(b_e3m2_u8x16);
549
+ __m512 diff_f32x16 = _mm512_sub_ps(a_f32x16, b_f32x16);
550
+ sum_f32x16 = _mm512_fmadd_ps(diff_f32x16, diff_f32x16, sum_f32x16);
551
+ if (n) goto nk_sqeuclidean_e3m2_skylake_cycle;
552
+
553
+ *result = nk_reduce_add_f32x16_skylake_(sum_f32x16);
554
+ }
555
+
556
+ NK_PUBLIC void nk_euclidean_e3m2_skylake(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result) {
557
+ nk_sqeuclidean_e3m2_skylake(a, b, n, result);
558
+ *result = nk_f32_sqrt_haswell(*result);
559
+ }
560
+
561
+ NK_PUBLIC void nk_angular_e3m2_skylake(nk_e3m2_t const *a, nk_e3m2_t const *b, nk_size_t n, nk_f32_t *result) {
562
+ __m512 dot_f32x16 = _mm512_setzero_ps();
563
+ __m512 a_norm_sq_f32x16 = _mm512_setzero_ps();
564
+ __m512 b_norm_sq_f32x16 = _mm512_setzero_ps();
565
+ __m128i a_e3m2_u8x16, b_e3m2_u8x16;
566
+
567
+ nk_angular_e3m2_skylake_cycle:
568
+ if (n < 16) {
569
+ __mmask16 mask = (__mmask16)_bzhi_u32(0xFFFF, n);
570
+ a_e3m2_u8x16 = _mm_maskz_loadu_epi8(mask, a);
571
+ b_e3m2_u8x16 = _mm_maskz_loadu_epi8(mask, b);
572
+ n = 0;
573
+ }
574
+ else {
575
+ a_e3m2_u8x16 = _mm_loadu_si128((__m128i const *)a);
576
+ b_e3m2_u8x16 = _mm_loadu_si128((__m128i const *)b);
577
+ a += 16, b += 16, n -= 16;
578
+ }
579
+ __m512 a_f32x16 = nk_e3m2x16_to_f32x16_skylake_(a_e3m2_u8x16);
580
+ __m512 b_f32x16 = nk_e3m2x16_to_f32x16_skylake_(b_e3m2_u8x16);
581
+ dot_f32x16 = _mm512_fmadd_ps(a_f32x16, b_f32x16, dot_f32x16);
582
+ a_norm_sq_f32x16 = _mm512_fmadd_ps(a_f32x16, a_f32x16, a_norm_sq_f32x16);
583
+ b_norm_sq_f32x16 = _mm512_fmadd_ps(b_f32x16, b_f32x16, b_norm_sq_f32x16);
584
+ if (n) goto nk_angular_e3m2_skylake_cycle;
585
+
586
+ nk_f32_t dot_f32 = nk_reduce_add_f32x16_skylake_(dot_f32x16);
587
+ nk_f32_t a_norm_sq_f32 = nk_reduce_add_f32x16_skylake_(a_norm_sq_f32x16);
588
+ nk_f32_t b_norm_sq_f32 = nk_reduce_add_f32x16_skylake_(b_norm_sq_f32x16);
589
+ *result = nk_angular_normalize_f32_haswell_(dot_f32, a_norm_sq_f32, b_norm_sq_f32);
590
+ }
591
+
592
+ #if defined(__clang__)
593
+ #pragma clang attribute pop
594
+ #elif defined(__GNUC__)
595
+ #pragma GCC pop_options
596
+ #endif
597
+
598
+ #if defined(__cplusplus)
599
+ } // extern "C"
600
+ #endif
601
+
602
+ #pragma endregion F16 and BF16 Floats
603
+ #endif // NK_TARGET_SKYLAKE
604
+ #endif // NK_TARGET_X8664_
605
+ #endif // NK_SPATIAL_SKYLAKE_H