usearch 2.21.4 → 2.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (602) hide show
  1. package/README.md +24 -24
  2. package/binding.gyp +15 -37
  3. package/c/CMakeLists.txt +4 -5
  4. package/c/README.md +7 -7
  5. package/c/lib.cpp +32 -14
  6. package/c/test.c +83 -1
  7. package/c/usearch.h +24 -3
  8. package/cpp/CMakeLists.txt +4 -0
  9. package/cpp/README.md +5 -5
  10. package/cpp/bench.cpp +97 -116
  11. package/cpp/test.cpp +117 -20
  12. package/include/usearch/index.hpp +224 -48
  13. package/include/usearch/index_dense.hpp +105 -40
  14. package/include/usearch/index_plugins.hpp +1387 -204
  15. package/javascript/dist/cjs/usearch.d.ts +8 -3
  16. package/javascript/dist/cjs/usearch.js +12 -4
  17. package/javascript/dist/esm/usearch.d.ts +8 -3
  18. package/javascript/dist/esm/usearch.js +12 -4
  19. package/javascript/lib.cpp +17 -0
  20. package/javascript/usearch.ts +14 -6
  21. package/numkong/.clang-tidy +30 -0
  22. package/{simsimd → numkong}/.cmake-format.py +18 -0
  23. package/numkong/.editorconfig +12 -0
  24. package/numkong/.git-blame-ignore-revs +123 -0
  25. package/numkong/.mailmap +15 -0
  26. package/numkong/.spi.yml +11 -0
  27. package/numkong/.swift-format +14 -0
  28. package/numkong/CITATION.cff +81 -0
  29. package/numkong/CONTRIBUTING.md +500 -0
  30. package/numkong/Cargo.toml +54 -0
  31. package/numkong/MANIFEST.in +8 -0
  32. package/numkong/Package.swift +84 -0
  33. package/numkong/README.md +569 -0
  34. package/numkong/bench/README.md +217 -0
  35. package/numkong/bench/bench-browser.html +323 -0
  36. package/numkong/bench/bench.cpp +344 -0
  37. package/numkong/bench/bench.hpp +816 -0
  38. package/numkong/bench/bench.js +148 -0
  39. package/numkong/bench/bench.mjs +616 -0
  40. package/numkong/bench/bench_attention.cpp +113 -0
  41. package/numkong/bench/bench_cast.cpp +264 -0
  42. package/numkong/bench/bench_cross_amx.cpp +62 -0
  43. package/numkong/bench/bench_cross_arm.cpp +245 -0
  44. package/numkong/bench/bench_cross_blas.cpp +309 -0
  45. package/numkong/bench/bench_cross_loongarch.cpp +106 -0
  46. package/numkong/bench/bench_cross_power.cpp +84 -0
  47. package/numkong/bench/bench_cross_rvv.cpp +121 -0
  48. package/numkong/bench/bench_cross_serial.cpp +151 -0
  49. package/numkong/bench/bench_cross_sme.cpp +163 -0
  50. package/numkong/bench/bench_cross_wasm.cpp +142 -0
  51. package/numkong/bench/bench_cross_x86.cpp +455 -0
  52. package/numkong/bench/bench_curved.cpp +210 -0
  53. package/numkong/bench/bench_dot.cpp +315 -0
  54. package/numkong/bench/bench_each.cpp +503 -0
  55. package/numkong/bench/bench_geospatial.cpp +112 -0
  56. package/numkong/bench/bench_maxsim.cpp +154 -0
  57. package/numkong/bench/bench_mesh.cpp +148 -0
  58. package/numkong/bench/bench_probability.cpp +60 -0
  59. package/numkong/bench/bench_reduce.cpp +371 -0
  60. package/numkong/bench/bench_set.cpp +73 -0
  61. package/numkong/bench/bench_sparse.cpp +198 -0
  62. package/numkong/bench/bench_spatial.cpp +347 -0
  63. package/numkong/bench/bench_trigonometry.cpp +137 -0
  64. package/numkong/bench/swift/Bench.swift +506 -0
  65. package/numkong/binding.gyp +169 -0
  66. package/numkong/build.rs +484 -0
  67. package/numkong/c/dispatch.h +512 -0
  68. package/numkong/c/dispatch_bf16.c +447 -0
  69. package/numkong/c/dispatch_bf16c.c +52 -0
  70. package/numkong/c/dispatch_e2m3.c +296 -0
  71. package/numkong/c/dispatch_e3m2.c +284 -0
  72. package/numkong/c/dispatch_e4m3.c +318 -0
  73. package/numkong/c/dispatch_e5m2.c +316 -0
  74. package/numkong/c/dispatch_f16.c +452 -0
  75. package/numkong/c/dispatch_f16c.c +58 -0
  76. package/numkong/c/dispatch_f32.c +434 -0
  77. package/numkong/c/dispatch_f32c.c +99 -0
  78. package/numkong/c/dispatch_f64.c +348 -0
  79. package/numkong/c/dispatch_f64c.c +98 -0
  80. package/numkong/c/dispatch_i16.c +96 -0
  81. package/numkong/c/dispatch_i32.c +89 -0
  82. package/numkong/c/dispatch_i4.c +153 -0
  83. package/numkong/c/dispatch_i64.c +86 -0
  84. package/numkong/c/dispatch_i8.c +348 -0
  85. package/numkong/c/dispatch_other.c +348 -0
  86. package/numkong/c/dispatch_u1.c +193 -0
  87. package/numkong/c/dispatch_u16.c +124 -0
  88. package/numkong/c/dispatch_u32.c +118 -0
  89. package/numkong/c/dispatch_u4.c +153 -0
  90. package/numkong/c/dispatch_u64.c +102 -0
  91. package/numkong/c/dispatch_u8.c +364 -0
  92. package/numkong/c/numkong.c +940 -0
  93. package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
  94. package/numkong/cmake/nk_isa_probe.cmake +90 -0
  95. package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
  96. package/numkong/cmake/nk_math_lib.cmake +46 -0
  97. package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
  98. package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
  99. package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
  100. package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
  101. package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
  102. package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
  103. package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
  104. package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
  105. package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
  106. package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
  107. package/numkong/cmake/toolchain-wasi.cmake +77 -0
  108. package/numkong/cmake/toolchain-wasm.cmake +70 -0
  109. package/numkong/cmake/toolchain-wasm64.cmake +62 -0
  110. package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
  111. package/numkong/include/README.md +643 -0
  112. package/numkong/include/module.modulemap +129 -0
  113. package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
  114. package/numkong/include/numkong/attention/sme.h +2075 -0
  115. package/numkong/include/numkong/attention.h +49 -0
  116. package/numkong/include/numkong/capabilities.h +930 -0
  117. package/numkong/include/numkong/cast/README.md +262 -0
  118. package/numkong/include/numkong/cast/diamond.h +64 -0
  119. package/numkong/include/numkong/cast/haswell.h +823 -0
  120. package/numkong/include/numkong/cast/icelake.h +475 -0
  121. package/numkong/include/numkong/cast/loongsonasx.h +252 -0
  122. package/numkong/include/numkong/cast/neon.h +1174 -0
  123. package/numkong/include/numkong/cast/powervsx.h +449 -0
  124. package/numkong/include/numkong/cast/rvv.h +970 -0
  125. package/numkong/include/numkong/cast/sapphire.h +262 -0
  126. package/numkong/include/numkong/cast/serial.h +2336 -0
  127. package/numkong/include/numkong/cast/skylake.h +915 -0
  128. package/numkong/include/numkong/cast/v128relaxed.h +537 -0
  129. package/numkong/include/numkong/cast.h +254 -0
  130. package/numkong/include/numkong/cast.hpp +44 -0
  131. package/numkong/include/numkong/curved/README.md +223 -0
  132. package/numkong/include/numkong/curved/genoa.h +182 -0
  133. package/numkong/include/numkong/curved/haswell.h +276 -0
  134. package/numkong/include/numkong/curved/neon.h +329 -0
  135. package/numkong/include/numkong/curved/neonbfdot.h +211 -0
  136. package/numkong/include/numkong/curved/rvv.h +305 -0
  137. package/numkong/include/numkong/curved/serial.h +207 -0
  138. package/numkong/include/numkong/curved/skylake.h +457 -0
  139. package/numkong/include/numkong/curved/smef64.h +530 -0
  140. package/numkong/include/numkong/curved.h +513 -0
  141. package/numkong/include/numkong/curved.hpp +144 -0
  142. package/numkong/include/numkong/dot/README.md +442 -0
  143. package/numkong/include/numkong/dot/alder.h +563 -0
  144. package/numkong/include/numkong/dot/diamond.h +158 -0
  145. package/numkong/include/numkong/dot/genoa.h +289 -0
  146. package/numkong/include/numkong/dot/haswell.h +1723 -0
  147. package/numkong/include/numkong/dot/icelake.h +997 -0
  148. package/numkong/include/numkong/dot/loongsonasx.h +671 -0
  149. package/numkong/include/numkong/dot/neon.h +869 -0
  150. package/numkong/include/numkong/dot/neonbfdot.h +243 -0
  151. package/numkong/include/numkong/dot/neonfhm.h +358 -0
  152. package/numkong/include/numkong/dot/neonfp8.h +323 -0
  153. package/numkong/include/numkong/dot/neonsdot.h +622 -0
  154. package/numkong/include/numkong/dot/powervsx.h +752 -0
  155. package/numkong/include/numkong/dot/rvv.h +722 -0
  156. package/numkong/include/numkong/dot/rvvbb.h +72 -0
  157. package/numkong/include/numkong/dot/rvvbf16.h +123 -0
  158. package/numkong/include/numkong/dot/rvvhalf.h +129 -0
  159. package/numkong/include/numkong/dot/sapphire.h +141 -0
  160. package/numkong/include/numkong/dot/serial.h +874 -0
  161. package/numkong/include/numkong/dot/sierra.h +405 -0
  162. package/numkong/include/numkong/dot/skylake.h +1116 -0
  163. package/numkong/include/numkong/dot/sve.h +420 -0
  164. package/numkong/include/numkong/dot/svebfdot.h +75 -0
  165. package/numkong/include/numkong/dot/svehalf.h +168 -0
  166. package/numkong/include/numkong/dot/svesdot.h +90 -0
  167. package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
  168. package/numkong/include/numkong/dot.h +1136 -0
  169. package/numkong/include/numkong/dot.hpp +94 -0
  170. package/numkong/include/numkong/dots/README.md +496 -0
  171. package/numkong/include/numkong/dots/alder.h +117 -0
  172. package/numkong/include/numkong/dots/diamond.h +86 -0
  173. package/numkong/include/numkong/dots/genoa.h +100 -0
  174. package/numkong/include/numkong/dots/graniteamx.h +733 -0
  175. package/numkong/include/numkong/dots/haswell.h +310 -0
  176. package/numkong/include/numkong/dots/icelake.h +180 -0
  177. package/numkong/include/numkong/dots/loongsonasx.h +176 -0
  178. package/numkong/include/numkong/dots/neon.h +123 -0
  179. package/numkong/include/numkong/dots/neonbfdot.h +59 -0
  180. package/numkong/include/numkong/dots/neonfhm.h +96 -0
  181. package/numkong/include/numkong/dots/neonfp8.h +99 -0
  182. package/numkong/include/numkong/dots/neonsdot.h +144 -0
  183. package/numkong/include/numkong/dots/powervsx.h +194 -0
  184. package/numkong/include/numkong/dots/rvv.h +2593 -0
  185. package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
  186. package/numkong/include/numkong/dots/serial.h +2867 -0
  187. package/numkong/include/numkong/dots/sierra.h +100 -0
  188. package/numkong/include/numkong/dots/skylake.h +207 -0
  189. package/numkong/include/numkong/dots/sme.h +5041 -0
  190. package/numkong/include/numkong/dots/smebi32.h +477 -0
  191. package/numkong/include/numkong/dots/smef64.h +1328 -0
  192. package/numkong/include/numkong/dots/smehalf.h +47 -0
  193. package/numkong/include/numkong/dots/v128relaxed.h +317 -0
  194. package/numkong/include/numkong/dots.h +3110 -0
  195. package/numkong/include/numkong/dots.hpp +641 -0
  196. package/numkong/include/numkong/each/README.md +465 -0
  197. package/numkong/include/numkong/each/haswell.h +1658 -0
  198. package/numkong/include/numkong/each/icelake.h +272 -0
  199. package/numkong/include/numkong/each/neon.h +1138 -0
  200. package/numkong/include/numkong/each/neonbfdot.h +211 -0
  201. package/numkong/include/numkong/each/neonhalf.h +318 -0
  202. package/numkong/include/numkong/each/rvv.h +1121 -0
  203. package/numkong/include/numkong/each/sapphire.h +343 -0
  204. package/numkong/include/numkong/each/serial.h +282 -0
  205. package/numkong/include/numkong/each/skylake.h +1562 -0
  206. package/numkong/include/numkong/each/v128relaxed.h +562 -0
  207. package/numkong/include/numkong/each.h +2232 -0
  208. package/numkong/include/numkong/each.hpp +434 -0
  209. package/numkong/include/numkong/geospatial/README.md +147 -0
  210. package/numkong/include/numkong/geospatial/haswell.h +633 -0
  211. package/numkong/include/numkong/geospatial/neon.h +615 -0
  212. package/numkong/include/numkong/geospatial/rvv.h +701 -0
  213. package/numkong/include/numkong/geospatial/serial.h +309 -0
  214. package/numkong/include/numkong/geospatial/skylake.h +613 -0
  215. package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
  216. package/numkong/include/numkong/geospatial.h +453 -0
  217. package/numkong/include/numkong/geospatial.hpp +235 -0
  218. package/numkong/include/numkong/matrix.hpp +336 -0
  219. package/numkong/include/numkong/maxsim/README.md +187 -0
  220. package/numkong/include/numkong/maxsim/alder.h +511 -0
  221. package/numkong/include/numkong/maxsim/genoa.h +115 -0
  222. package/numkong/include/numkong/maxsim/haswell.h +553 -0
  223. package/numkong/include/numkong/maxsim/icelake.h +480 -0
  224. package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
  225. package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
  226. package/numkong/include/numkong/maxsim/serial.h +490 -0
  227. package/numkong/include/numkong/maxsim/sme.h +993 -0
  228. package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
  229. package/numkong/include/numkong/maxsim.h +571 -0
  230. package/numkong/include/numkong/maxsim.hpp +133 -0
  231. package/numkong/include/numkong/mesh/README.md +219 -0
  232. package/numkong/include/numkong/mesh/haswell.h +2013 -0
  233. package/numkong/include/numkong/mesh/neon.h +1821 -0
  234. package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
  235. package/numkong/include/numkong/mesh/rvv.h +936 -0
  236. package/numkong/include/numkong/mesh/serial.h +721 -0
  237. package/numkong/include/numkong/mesh/skylake.h +2344 -0
  238. package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
  239. package/numkong/include/numkong/mesh.h +666 -0
  240. package/numkong/include/numkong/mesh.hpp +701 -0
  241. package/numkong/include/numkong/numkong.h +78 -0
  242. package/numkong/include/numkong/numkong.hpp +58 -0
  243. package/numkong/include/numkong/probability/README.md +177 -0
  244. package/numkong/include/numkong/probability/haswell.h +267 -0
  245. package/numkong/include/numkong/probability/neon.h +255 -0
  246. package/numkong/include/numkong/probability/rvv.h +414 -0
  247. package/numkong/include/numkong/probability/serial.h +181 -0
  248. package/numkong/include/numkong/probability/skylake.h +324 -0
  249. package/numkong/include/numkong/probability.h +380 -0
  250. package/numkong/include/numkong/probability.hpp +120 -0
  251. package/numkong/include/numkong/random.h +50 -0
  252. package/numkong/include/numkong/random.hpp +285 -0
  253. package/numkong/include/numkong/reduce/README.md +552 -0
  254. package/numkong/include/numkong/reduce/alder.h +636 -0
  255. package/numkong/include/numkong/reduce/genoa.h +201 -0
  256. package/numkong/include/numkong/reduce/haswell.h +3785 -0
  257. package/numkong/include/numkong/reduce/icelake.h +549 -0
  258. package/numkong/include/numkong/reduce/neon.h +3980 -0
  259. package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
  260. package/numkong/include/numkong/reduce/neonfhm.h +293 -0
  261. package/numkong/include/numkong/reduce/neonsdot.h +357 -0
  262. package/numkong/include/numkong/reduce/rvv.h +3533 -0
  263. package/numkong/include/numkong/reduce/serial.h +753 -0
  264. package/numkong/include/numkong/reduce/sierra.h +338 -0
  265. package/numkong/include/numkong/reduce/skylake.h +3794 -0
  266. package/numkong/include/numkong/reduce/sve.h +52 -0
  267. package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
  268. package/numkong/include/numkong/reduce.h +1582 -0
  269. package/numkong/include/numkong/reduce.hpp +778 -0
  270. package/numkong/include/numkong/scalar/README.md +89 -0
  271. package/numkong/include/numkong/scalar/haswell.h +122 -0
  272. package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
  273. package/numkong/include/numkong/scalar/neon.h +122 -0
  274. package/numkong/include/numkong/scalar/neonhalf.h +70 -0
  275. package/numkong/include/numkong/scalar/powervsx.h +96 -0
  276. package/numkong/include/numkong/scalar/rvv.h +211 -0
  277. package/numkong/include/numkong/scalar/sapphire.h +74 -0
  278. package/numkong/include/numkong/scalar/serial.h +332 -0
  279. package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
  280. package/numkong/include/numkong/scalar.h +696 -0
  281. package/numkong/include/numkong/set/README.md +179 -0
  282. package/numkong/include/numkong/set/haswell.h +334 -0
  283. package/numkong/include/numkong/set/icelake.h +485 -0
  284. package/numkong/include/numkong/set/loongsonasx.h +181 -0
  285. package/numkong/include/numkong/set/neon.h +363 -0
  286. package/numkong/include/numkong/set/powervsx.h +326 -0
  287. package/numkong/include/numkong/set/rvv.h +226 -0
  288. package/numkong/include/numkong/set/rvvbb.h +117 -0
  289. package/numkong/include/numkong/set/serial.h +174 -0
  290. package/numkong/include/numkong/set/sve.h +187 -0
  291. package/numkong/include/numkong/set/v128relaxed.h +240 -0
  292. package/numkong/include/numkong/set.h +471 -0
  293. package/numkong/include/numkong/set.hpp +114 -0
  294. package/numkong/include/numkong/sets/README.md +149 -0
  295. package/numkong/include/numkong/sets/haswell.h +63 -0
  296. package/numkong/include/numkong/sets/icelake.h +66 -0
  297. package/numkong/include/numkong/sets/loongsonasx.h +52 -0
  298. package/numkong/include/numkong/sets/neon.h +61 -0
  299. package/numkong/include/numkong/sets/powervsx.h +65 -0
  300. package/numkong/include/numkong/sets/serial.h +43 -0
  301. package/numkong/include/numkong/sets/smebi32.h +1135 -0
  302. package/numkong/include/numkong/sets/v128relaxed.h +58 -0
  303. package/numkong/include/numkong/sets.h +382 -0
  304. package/numkong/include/numkong/sparse/README.md +156 -0
  305. package/numkong/include/numkong/sparse/icelake.h +463 -0
  306. package/numkong/include/numkong/sparse/neon.h +288 -0
  307. package/numkong/include/numkong/sparse/serial.h +117 -0
  308. package/numkong/include/numkong/sparse/sve2.h +504 -0
  309. package/numkong/include/numkong/sparse/turin.h +322 -0
  310. package/numkong/include/numkong/sparse.h +363 -0
  311. package/numkong/include/numkong/sparse.hpp +113 -0
  312. package/numkong/include/numkong/spatial/README.md +439 -0
  313. package/numkong/include/numkong/spatial/alder.h +604 -0
  314. package/numkong/include/numkong/spatial/diamond.h +240 -0
  315. package/numkong/include/numkong/spatial/genoa.h +222 -0
  316. package/numkong/include/numkong/spatial/haswell.h +979 -0
  317. package/numkong/include/numkong/spatial/icelake.h +1067 -0
  318. package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
  319. package/numkong/include/numkong/spatial/neon.h +846 -0
  320. package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
  321. package/numkong/include/numkong/spatial/neonfp8.h +258 -0
  322. package/numkong/include/numkong/spatial/neonsdot.h +429 -0
  323. package/numkong/include/numkong/spatial/powervsx.h +738 -0
  324. package/numkong/include/numkong/spatial/rvv.h +991 -0
  325. package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
  326. package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
  327. package/numkong/include/numkong/spatial/serial.h +347 -0
  328. package/numkong/include/numkong/spatial/sierra.h +516 -0
  329. package/numkong/include/numkong/spatial/skylake.h +605 -0
  330. package/numkong/include/numkong/spatial/sve.h +246 -0
  331. package/numkong/include/numkong/spatial/svebfdot.h +125 -0
  332. package/numkong/include/numkong/spatial/svehalf.h +136 -0
  333. package/numkong/include/numkong/spatial/svesdot.h +143 -0
  334. package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
  335. package/numkong/include/numkong/spatial.h +1681 -0
  336. package/numkong/include/numkong/spatial.hpp +183 -0
  337. package/numkong/include/numkong/spatials/README.md +580 -0
  338. package/numkong/include/numkong/spatials/alder.h +94 -0
  339. package/numkong/include/numkong/spatials/diamond.h +82 -0
  340. package/numkong/include/numkong/spatials/genoa.h +94 -0
  341. package/numkong/include/numkong/spatials/graniteamx.h +173 -0
  342. package/numkong/include/numkong/spatials/haswell.h +219 -0
  343. package/numkong/include/numkong/spatials/icelake.h +113 -0
  344. package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
  345. package/numkong/include/numkong/spatials/neon.h +109 -0
  346. package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
  347. package/numkong/include/numkong/spatials/neonfhm.h +92 -0
  348. package/numkong/include/numkong/spatials/neonfp8.h +111 -0
  349. package/numkong/include/numkong/spatials/neonsdot.h +143 -0
  350. package/numkong/include/numkong/spatials/powervsx.h +153 -0
  351. package/numkong/include/numkong/spatials/rvv.h +1976 -0
  352. package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
  353. package/numkong/include/numkong/spatials/serial.h +248 -0
  354. package/numkong/include/numkong/spatials/sierra.h +96 -0
  355. package/numkong/include/numkong/spatials/skylake.h +184 -0
  356. package/numkong/include/numkong/spatials/sme.h +1927 -0
  357. package/numkong/include/numkong/spatials/smef64.h +483 -0
  358. package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
  359. package/numkong/include/numkong/spatials.h +3374 -0
  360. package/numkong/include/numkong/spatials.hpp +509 -0
  361. package/numkong/include/numkong/tensor.hpp +1981 -0
  362. package/numkong/include/numkong/trigonometry/README.md +184 -0
  363. package/numkong/include/numkong/trigonometry/haswell.h +653 -0
  364. package/numkong/include/numkong/trigonometry/neon.h +638 -0
  365. package/numkong/include/numkong/trigonometry/rvv.h +700 -0
  366. package/numkong/include/numkong/trigonometry/serial.h +703 -0
  367. package/numkong/include/numkong/trigonometry/skylake.h +725 -0
  368. package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
  369. package/numkong/include/numkong/trigonometry.h +467 -0
  370. package/numkong/include/numkong/trigonometry.hpp +166 -0
  371. package/numkong/include/numkong/types.h +1695 -0
  372. package/numkong/include/numkong/types.hpp +6027 -0
  373. package/numkong/include/numkong/vector.hpp +766 -0
  374. package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
  375. package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
  376. package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
  377. package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
  378. package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
  379. package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
  380. package/numkong/javascript/README.md +254 -0
  381. package/numkong/javascript/node-gyp-build.d.ts +4 -0
  382. package/numkong/javascript/numkong-browser.ts +40 -0
  383. package/numkong/javascript/numkong-wasm.ts +750 -0
  384. package/numkong/javascript/numkong.c +712 -0
  385. package/numkong/javascript/numkong.ts +613 -0
  386. package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
  387. package/numkong/javascript/tsconfig-cjs.json +13 -0
  388. package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
  389. package/numkong/javascript/types.ts +784 -0
  390. package/numkong/numkong.gypi +104 -0
  391. package/numkong/package.json +108 -0
  392. package/numkong/probes/arm_neon.c +8 -0
  393. package/numkong/probes/arm_neon_bfdot.c +9 -0
  394. package/numkong/probes/arm_neon_fhm.c +9 -0
  395. package/numkong/probes/arm_neon_half.c +8 -0
  396. package/numkong/probes/arm_neon_sdot.c +9 -0
  397. package/numkong/probes/arm_neonfp8.c +9 -0
  398. package/numkong/probes/arm_sme.c +16 -0
  399. package/numkong/probes/arm_sme2.c +16 -0
  400. package/numkong/probes/arm_sme2p1.c +16 -0
  401. package/numkong/probes/arm_sme_bf16.c +16 -0
  402. package/numkong/probes/arm_sme_bi32.c +16 -0
  403. package/numkong/probes/arm_sme_f64.c +16 -0
  404. package/numkong/probes/arm_sme_fa64.c +14 -0
  405. package/numkong/probes/arm_sme_half.c +16 -0
  406. package/numkong/probes/arm_sme_lut2.c +15 -0
  407. package/numkong/probes/arm_sve.c +18 -0
  408. package/numkong/probes/arm_sve2.c +20 -0
  409. package/numkong/probes/arm_sve2p1.c +18 -0
  410. package/numkong/probes/arm_sve_bfdot.c +20 -0
  411. package/numkong/probes/arm_sve_half.c +18 -0
  412. package/numkong/probes/arm_sve_sdot.c +21 -0
  413. package/numkong/probes/loongarch_lasx.c +12 -0
  414. package/numkong/probes/power_vsx.c +12 -0
  415. package/numkong/probes/probe.js +127 -0
  416. package/numkong/probes/riscv_rvv.c +14 -0
  417. package/numkong/probes/riscv_rvv_bb.c +15 -0
  418. package/numkong/probes/riscv_rvv_bf16.c +17 -0
  419. package/numkong/probes/riscv_rvv_half.c +14 -0
  420. package/numkong/probes/wasm_v128relaxed.c +11 -0
  421. package/numkong/probes/x86_alder.c +17 -0
  422. package/numkong/probes/x86_diamond.c +17 -0
  423. package/numkong/probes/x86_genoa.c +17 -0
  424. package/numkong/probes/x86_graniteamx.c +19 -0
  425. package/numkong/probes/x86_haswell.c +11 -0
  426. package/numkong/probes/x86_icelake.c +17 -0
  427. package/numkong/probes/x86_sapphire.c +16 -0
  428. package/numkong/probes/x86_sapphireamx.c +18 -0
  429. package/numkong/probes/x86_sierra.c +17 -0
  430. package/numkong/probes/x86_skylake.c +15 -0
  431. package/numkong/probes/x86_turin.c +17 -0
  432. package/numkong/rust/README.md +698 -0
  433. package/numkong/rust/capabilities.rs +96 -0
  434. package/numkong/rust/cast.rs +314 -0
  435. package/numkong/rust/curved.rs +391 -0
  436. package/numkong/rust/each.rs +2721 -0
  437. package/numkong/rust/geospatial.rs +343 -0
  438. package/numkong/rust/matrix.rs +5424 -0
  439. package/numkong/rust/maxsim.rs +540 -0
  440. package/numkong/rust/mesh.rs +837 -0
  441. package/numkong/rust/numkong.rs +409 -0
  442. package/numkong/rust/probability.rs +272 -0
  443. package/numkong/rust/reduce.rs +1249 -0
  444. package/numkong/rust/set.rs +194 -0
  445. package/numkong/rust/sparse.rs +513 -0
  446. package/numkong/rust/spatial.rs +1815 -0
  447. package/numkong/rust/tensor.rs +7565 -0
  448. package/numkong/rust/types.rs +3666 -0
  449. package/numkong/rust/vector.rs +1899 -0
  450. package/numkong/rustfmt.toml +2 -0
  451. package/numkong/swift/Matrix.swift +1388 -0
  452. package/numkong/swift/MaxSim.swift +151 -0
  453. package/numkong/swift/NumKong.swift +283 -0
  454. package/numkong/swift/Numerics.swift +329 -0
  455. package/numkong/swift/README.md +433 -0
  456. package/numkong/swift/Scalar.swift +741 -0
  457. package/numkong/swift/Tensor.swift +209 -0
  458. package/numkong/test/README.md +315 -0
  459. package/numkong/test/playwright.config.ts +16 -0
  460. package/numkong/test/swift/Test.swift +534 -0
  461. package/numkong/test/test-browser-bundle-runner.mjs +36 -0
  462. package/numkong/test/test-browser-bundle.html +188 -0
  463. package/numkong/test/test-browser-runner.mjs +43 -0
  464. package/numkong/test/test-browser.html +305 -0
  465. package/numkong/test/test-dtypes.mjs +453 -0
  466. package/numkong/test/test-wasm.mjs +267 -0
  467. package/numkong/test/test.cpp +442 -0
  468. package/numkong/test/test.hpp +580 -0
  469. package/numkong/test/test.mjs +363 -0
  470. package/numkong/test/test_base.py +1041 -0
  471. package/numkong/test/test_cast.cpp +242 -0
  472. package/numkong/test/test_cross.hpp +551 -0
  473. package/numkong/test/test_cross.py +467 -0
  474. package/numkong/test/test_cross_amx.cpp +50 -0
  475. package/numkong/test/test_cross_arm.cpp +225 -0
  476. package/numkong/test/test_cross_blas.cpp +354 -0
  477. package/numkong/test/test_cross_loongarch.cpp +90 -0
  478. package/numkong/test/test_cross_power.cpp +73 -0
  479. package/numkong/test/test_cross_rvv.cpp +109 -0
  480. package/numkong/test/test_cross_serial.cpp +181 -0
  481. package/numkong/test/test_cross_sme.cpp +148 -0
  482. package/numkong/test/test_cross_wasm.cpp +141 -0
  483. package/numkong/test/test_cross_x86.cpp +442 -0
  484. package/numkong/test/test_curved.cpp +182 -0
  485. package/numkong/test/test_curved.py +207 -0
  486. package/numkong/test/test_dot.cpp +353 -0
  487. package/numkong/test/test_dot.py +296 -0
  488. package/numkong/test/test_each.cpp +437 -0
  489. package/numkong/test/test_each.py +756 -0
  490. package/numkong/test/test_geospatial.cpp +155 -0
  491. package/numkong/test/test_geospatial.py +241 -0
  492. package/numkong/test/test_maxsim.cpp +138 -0
  493. package/numkong/test/test_maxsim.py +209 -0
  494. package/numkong/test/test_mesh.cpp +203 -0
  495. package/numkong/test/test_mesh.py +394 -0
  496. package/numkong/test/test_probability.cpp +136 -0
  497. package/numkong/test/test_probability.py +166 -0
  498. package/numkong/test/test_reduce.cpp +563 -0
  499. package/numkong/test/test_reduce.py +781 -0
  500. package/numkong/test/test_set.cpp +151 -0
  501. package/numkong/test/test_set.py +120 -0
  502. package/numkong/test/test_similarities.py +579 -0
  503. package/numkong/test/test_sparse.cpp +121 -0
  504. package/numkong/test/test_sparse.py +118 -0
  505. package/numkong/test/test_spatial.cpp +518 -0
  506. package/numkong/test/test_spatial.py +269 -0
  507. package/numkong/test/test_tensor.cpp +884 -0
  508. package/numkong/test/test_tensor.py +1417 -0
  509. package/numkong/test/test_trigonometry.cpp +156 -0
  510. package/numkong/test/test_trigonometry.py +180 -0
  511. package/package.json +7 -8
  512. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  513. package/prebuilds/linux-arm64/usearch.node +0 -0
  514. package/prebuilds/linux-x64/usearch.node +0 -0
  515. package/fp16/CMakeLists.txt +0 -176
  516. package/fp16/LICENSE +0 -11
  517. package/fp16/README.md +0 -20
  518. package/fp16/bench/alt-element.cc +0 -89
  519. package/fp16/bench/from-alt-array.cc +0 -175
  520. package/fp16/bench/from-ieee-array.cc +0 -399
  521. package/fp16/bench/ieee-element.cc +0 -272
  522. package/fp16/bench/to-alt-array.cc +0 -91
  523. package/fp16/bench/to-ieee-array.cc +0 -303
  524. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  525. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  526. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  527. package/fp16/configure.py +0 -65
  528. package/fp16/confu.yaml +0 -8
  529. package/fp16/include/fp16/__init__.py +0 -0
  530. package/fp16/include/fp16/avx.py +0 -50
  531. package/fp16/include/fp16/avx2.py +0 -53
  532. package/fp16/include/fp16/bitcasts.h +0 -92
  533. package/fp16/include/fp16/fp16.h +0 -451
  534. package/fp16/include/fp16/psimd.h +0 -131
  535. package/fp16/include/fp16.h +0 -11
  536. package/fp16/jni/Android.mk +0 -6
  537. package/fp16/jni/Application.mk +0 -4
  538. package/fp16/test/alt-from-fp32-value.cc +0 -498
  539. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  540. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  541. package/fp16/test/alt-to-fp32-value.cc +0 -348
  542. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  543. package/fp16/test/bitcasts.cc +0 -56
  544. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  545. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  546. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  547. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  548. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  549. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  550. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  551. package/fp16/test/peachpy/stubs.py +0 -38
  552. package/fp16/test/tables.cc +0 -530
  553. package/fp16/test/tables.h +0 -13
  554. package/fp16/third-party/THHalf.h +0 -92
  555. package/fp16/third-party/eigen-half.h +0 -170
  556. package/fp16/third-party/float16-compressor.h +0 -80
  557. package/fp16/third-party/half.hpp +0 -2916
  558. package/fp16/third-party/npy-halffloat.h +0 -328
  559. package/simsimd/.git-blame-ignore-revs +0 -2
  560. package/simsimd/CONTRIBUTING.md +0 -321
  561. package/simsimd/Cargo.toml +0 -49
  562. package/simsimd/MANIFEST.in +0 -4
  563. package/simsimd/Package.swift +0 -28
  564. package/simsimd/README.md +0 -1493
  565. package/simsimd/binding.gyp +0 -35
  566. package/simsimd/build.rs +0 -70
  567. package/simsimd/c/lib.c +0 -374
  568. package/simsimd/include/module.modulemap +0 -4
  569. package/simsimd/include/simsimd/binary.h +0 -486
  570. package/simsimd/include/simsimd/curved.h +0 -1541
  571. package/simsimd/include/simsimd/dot.h +0 -1853
  572. package/simsimd/include/simsimd/elementwise.h +0 -2465
  573. package/simsimd/include/simsimd/geospatial.h +0 -43
  574. package/simsimd/include/simsimd/mesh.h +0 -69
  575. package/simsimd/include/simsimd/probability.h +0 -606
  576. package/simsimd/include/simsimd/simsimd.h +0 -2567
  577. package/simsimd/include/simsimd/sparse.h +0 -1384
  578. package/simsimd/include/simsimd/spatial.h +0 -2335
  579. package/simsimd/include/simsimd/types.h +0 -666
  580. package/simsimd/javascript/fallback.ts +0 -233
  581. package/simsimd/javascript/lib.c +0 -125
  582. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  583. package/simsimd/javascript/simsimd.ts +0 -179
  584. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  585. package/simsimd/package-lock.json +0 -1761
  586. package/simsimd/package.json +0 -61
  587. package/simsimd/rust/lib.rs +0 -1821
  588. package/simsimd/scripts/bench.cxx +0 -1170
  589. package/simsimd/scripts/bench.ipynb +0 -187
  590. package/simsimd/scripts/bench.js +0 -127
  591. package/simsimd/scripts/bench.rs +0 -876
  592. package/simsimd/scripts/bench_vectors.py +0 -734
  593. package/simsimd/scripts/bench_vectors_live.py +0 -213
  594. package/simsimd/scripts/test.c +0 -187
  595. package/simsimd/scripts/test.mjs +0 -220
  596. package/simsimd/scripts/test.py +0 -1505
  597. package/simsimd/swift/SimSIMD.swift +0 -149
  598. package/simsimd/swift/Test.swift +0 -128
  599. /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
  600. /package/{simsimd → numkong}/LICENSE +0 -0
  601. /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
  602. /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
@@ -0,0 +1,753 @@
1
+ /**
2
+ * @brief Serial fallbacks for the redesigned reduction API (moments + minmax).
3
+ * @file include/numkong/reduce/serial.h
4
+ * @author Ash Vardanian
5
+ * @date February 11, 2026
6
+ *
7
+ * @sa include/numkong/reduce.h
8
+ *
9
+ * Provides serial (non-SIMD) implementations of:
10
+ * - `nk_reduce_moments_*_serial` — sum + sum-of-squares in one pass
11
+ * - `nk_reduce_minmax_*_serial` — min + max with indices in one pass
12
+ */
13
+ #ifndef NK_REDUCE_SERIAL_H
14
+ #define NK_REDUCE_SERIAL_H
15
+
16
+ #include "numkong/types.h"
17
+ #include "numkong/scalar/serial.h"
18
+ #include "numkong/cast/serial.h"
19
+ #include "numkong/scalar/serial.h"
20
+
21
+ #if defined(__cplusplus)
22
+ extern "C" {
23
+ #endif
24
+
25
+ NK_INTERNAL nk_f64_t nk_reduce_sum_f64_serial_(nk_f64_t const *values, nk_f64_t const *compensations, int count) {
26
+ nk_f64_t running_sum = 0, accumulated_error = 0;
27
+ for (int i = 0; i < count; i++) {
28
+ // TwoSum: fold in values[i]
29
+ nk_f64_t tentative_sum = running_sum + values[i];
30
+ nk_f64_t virtual_addend = tentative_sum - running_sum;
31
+ accumulated_error += (running_sum - (tentative_sum - virtual_addend)) + (values[i] - virtual_addend);
32
+ running_sum = tentative_sum;
33
+ // TwoSum: fold in compensations[i]
34
+ tentative_sum = running_sum + compensations[i];
35
+ virtual_addend = tentative_sum - running_sum;
36
+ accumulated_error += (running_sum - (tentative_sum - virtual_addend)) + (compensations[i] - virtual_addend);
37
+ running_sum = tentative_sum;
38
+ }
39
+ return running_sum + accumulated_error;
40
+ }
41
+
42
+ NK_PUBLIC void nk_reduce_moments_f32_serial( //
43
+ nk_f32_t const *data, nk_size_t count, nk_size_t stride_bytes, //
44
+ nk_f64_t *sum_ptr, nk_f64_t *sumsq_ptr) {
45
+ nk_f64_t running_sum = 0, sum_compensation = 0;
46
+ nk_f64_t running_sumsq = 0, sumsq_compensation = 0;
47
+ unsigned char const *ptr = (unsigned char const *)data;
48
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
49
+ nk_f64_t val = (nk_f64_t)(*(nk_f32_t const *)ptr);
50
+ nk_f64_t tentative_sum = running_sum + val;
51
+ if (nk_f64_abs_(running_sum) >= nk_f64_abs_(val)) sum_compensation += (running_sum - tentative_sum) + val;
52
+ else sum_compensation += (val - tentative_sum) + running_sum;
53
+ running_sum = tentative_sum;
54
+
55
+ nk_f64_t squared_value = val * val;
56
+ nk_f64_t tentative_sumsq = running_sumsq + squared_value;
57
+ if (running_sumsq >= squared_value) sumsq_compensation += (running_sumsq - tentative_sumsq) + squared_value;
58
+ else sumsq_compensation += (squared_value - tentative_sumsq) + running_sumsq;
59
+ running_sumsq = tentative_sumsq;
60
+ }
61
+ *sum_ptr = running_sum + sum_compensation, *sumsq_ptr = running_sumsq + sumsq_compensation;
62
+ }
63
+
64
+ NK_PUBLIC void nk_reduce_moments_f64_serial( //
65
+ nk_f64_t const *data, nk_size_t count, nk_size_t stride_bytes, //
66
+ nk_f64_t *sum_ptr, nk_f64_t *sumsq_ptr) {
67
+ nk_f64_t running_sum = 0, sum_compensation = 0;
68
+ nk_f64_t running_sumsq = 0, sumsq_compensation = 0;
69
+ unsigned char const *ptr = (unsigned char const *)data;
70
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
71
+ nk_f64_t val = *(nk_f64_t const *)ptr;
72
+ nk_f64_t tentative_sum = running_sum + val;
73
+ if (nk_f64_abs_(running_sum) >= nk_f64_abs_(val)) sum_compensation += (running_sum - tentative_sum) + val;
74
+ else sum_compensation += (val - tentative_sum) + running_sum;
75
+ running_sum = tentative_sum;
76
+
77
+ nk_f64_t squared_value = val * val;
78
+ nk_f64_t tentative_sumsq = running_sumsq + squared_value;
79
+ if (running_sumsq >= squared_value) sumsq_compensation += (running_sumsq - tentative_sumsq) + squared_value;
80
+ else sumsq_compensation += (squared_value - tentative_sumsq) + running_sumsq;
81
+ running_sumsq = tentative_sumsq;
82
+ }
83
+ *sum_ptr = running_sum + sum_compensation, *sumsq_ptr = running_sumsq + sumsq_compensation;
84
+ }
85
+
86
+ NK_PUBLIC void nk_reduce_moments_i8_serial( //
87
+ nk_i8_t const *data, nk_size_t count, nk_size_t stride_bytes, //
88
+ nk_i64_t *sum_ptr, nk_u64_t *sumsq_ptr) {
89
+ nk_i64_t sum = 0;
90
+ nk_u64_t sumsq = 0;
91
+ unsigned char const *ptr = (unsigned char const *)data;
92
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
93
+ nk_i64_t val = (nk_i64_t)(*(nk_i8_t const *)ptr);
94
+ sum += val;
95
+ sumsq += (nk_u64_t)(val * val);
96
+ }
97
+ *sum_ptr = sum, *sumsq_ptr = sumsq;
98
+ }
99
+
100
+ NK_PUBLIC void nk_reduce_moments_u8_serial( //
101
+ nk_u8_t const *data, nk_size_t count, nk_size_t stride_bytes, //
102
+ nk_u64_t *sum_ptr, nk_u64_t *sumsq_ptr) {
103
+ nk_u64_t sum = 0, sumsq = 0;
104
+ unsigned char const *ptr = (unsigned char const *)data;
105
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
106
+ nk_u64_t val = (nk_u64_t)(*(nk_u8_t const *)ptr);
107
+ sum += val;
108
+ sumsq += val * val;
109
+ }
110
+ *sum_ptr = sum, *sumsq_ptr = sumsq;
111
+ }
112
+
113
+ NK_PUBLIC void nk_reduce_moments_i16_serial( //
114
+ nk_i16_t const *data, nk_size_t count, nk_size_t stride_bytes, //
115
+ nk_i64_t *sum_ptr, nk_u64_t *sumsq_ptr) {
116
+ nk_i64_t sum = 0;
117
+ nk_u64_t sumsq = 0;
118
+ unsigned char const *ptr = (unsigned char const *)data;
119
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
120
+ nk_i64_t val = (nk_i64_t)(*(nk_i16_t const *)ptr);
121
+ sum += val;
122
+ sumsq += (nk_u64_t)(val * val);
123
+ }
124
+ *sum_ptr = sum, *sumsq_ptr = sumsq;
125
+ }
126
+
127
+ NK_PUBLIC void nk_reduce_moments_u16_serial( //
128
+ nk_u16_t const *data, nk_size_t count, nk_size_t stride_bytes, //
129
+ nk_u64_t *sum_ptr, nk_u64_t *sumsq_ptr) {
130
+ nk_u64_t sum = 0, sumsq = 0;
131
+ unsigned char const *ptr = (unsigned char const *)data;
132
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
133
+ nk_u64_t val = (nk_u64_t)(*(nk_u16_t const *)ptr);
134
+ sum += val;
135
+ sumsq += val * val;
136
+ }
137
+ *sum_ptr = sum, *sumsq_ptr = sumsq;
138
+ }
139
+
140
+ NK_PUBLIC void nk_reduce_moments_i32_serial( //
141
+ nk_i32_t const *data, nk_size_t count, nk_size_t stride_bytes, //
142
+ nk_i64_t *sum_ptr, nk_u64_t *sumsq_ptr) {
143
+ nk_u64_t sum_low = 0;
144
+ nk_i64_t sum_high = 0;
145
+ nk_u64_t sumsq = 0;
146
+ unsigned char const *ptr = (unsigned char const *)data;
147
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
148
+ nk_i64_t val = (nk_i64_t)(*(nk_i32_t const *)ptr);
149
+ nk_u64_t product = (nk_u64_t)(val * val);
150
+ nk_u64_t sum_before = sum_low;
151
+ sum_low += (nk_u64_t)val;
152
+ if (sum_low < sum_before) sum_high++;
153
+ sum_high += (val >> 63);
154
+ sumsq = nk_u64_saturating_add_serial(sumsq, product);
155
+ }
156
+ nk_i64_t sum_low_signed = (nk_i64_t)sum_low;
157
+ if (sum_high == (sum_low_signed >> 63)) *sum_ptr = sum_low_signed;
158
+ else if (sum_high >= 0) *sum_ptr = NK_I64_MAX;
159
+ else *sum_ptr = NK_I64_MIN;
160
+ *sumsq_ptr = sumsq;
161
+ }
162
+
163
+ NK_PUBLIC void nk_reduce_moments_u32_serial( //
164
+ nk_u32_t const *data, nk_size_t count, nk_size_t stride_bytes, //
165
+ nk_u64_t *sum_ptr, nk_u64_t *sumsq_ptr) {
166
+ nk_u64_t sum = 0, sumsq = 0;
167
+ unsigned char const *ptr = (unsigned char const *)data;
168
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
169
+ nk_u64_t val = (nk_u64_t)(*(nk_u32_t const *)ptr);
170
+ nk_u64_t product = val * val;
171
+ sum = nk_u64_saturating_add_serial(sum, val);
172
+ sumsq = nk_u64_saturating_add_serial(sumsq, product);
173
+ }
174
+ *sum_ptr = sum, *sumsq_ptr = sumsq;
175
+ }
176
+
177
+ NK_PUBLIC void nk_reduce_moments_i64_serial( //
178
+ nk_i64_t const *data, nk_size_t count, nk_size_t stride_bytes, //
179
+ nk_i64_t *sum_ptr, nk_u64_t *sumsq_ptr) {
180
+ nk_u64_t sum_low = 0;
181
+ nk_i64_t sum_high = 0;
182
+ nk_u64_t sumsq = 0;
183
+ unsigned char const *ptr = (unsigned char const *)data;
184
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
185
+ nk_i64_t val = *(nk_i64_t const *)ptr;
186
+ nk_i64_t product = nk_i64_saturating_mul_serial(val, val);
187
+ nk_u64_t unsigned_product = (nk_u64_t)product;
188
+ sumsq = nk_u64_saturating_add_serial(sumsq, unsigned_product);
189
+ nk_u64_t sum_before = sum_low;
190
+ sum_low += (nk_u64_t)val;
191
+ if (sum_low < sum_before) sum_high++;
192
+ sum_high += (val >> 63);
193
+ }
194
+ nk_i64_t sum_low_signed = (nk_i64_t)sum_low;
195
+ if (sum_high == (sum_low_signed >> 63)) *sum_ptr = sum_low_signed;
196
+ else if (sum_high >= 0) *sum_ptr = NK_I64_MAX;
197
+ else *sum_ptr = NK_I64_MIN;
198
+ *sumsq_ptr = sumsq;
199
+ }
200
+
201
+ NK_PUBLIC void nk_reduce_moments_u64_serial( //
202
+ nk_u64_t const *data, nk_size_t count, nk_size_t stride_bytes, //
203
+ nk_u64_t *sum_ptr, nk_u64_t *sumsq_ptr) {
204
+ nk_u64_t sum = 0, sumsq = 0;
205
+ unsigned char const *ptr = (unsigned char const *)data;
206
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
207
+ nk_u64_t val = *(nk_u64_t const *)ptr;
208
+ nk_u64_t product = nk_u64_saturating_mul_serial(val, val);
209
+ sum = nk_u64_saturating_add_serial(sum, val);
210
+ sumsq = nk_u64_saturating_add_serial(sumsq, product);
211
+ }
212
+ *sum_ptr = sum, *sumsq_ptr = sumsq;
213
+ }
214
+
215
+ NK_PUBLIC void nk_reduce_moments_f16_serial( //
216
+ nk_f16_t const *data, nk_size_t count, nk_size_t stride_bytes, //
217
+ nk_f32_t *sum_ptr, nk_f32_t *sumsq_ptr) {
218
+ nk_f32_t running_sum = 0, sum_compensation = 0;
219
+ nk_f32_t running_sumsq = 0, sumsq_compensation = 0;
220
+ unsigned char const *ptr = (unsigned char const *)data;
221
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
222
+ nk_f32_t val;
223
+ nk_f16_to_f32_serial((nk_f16_t const *)ptr, &val);
224
+ nk_f32_t tentative_sum = running_sum + val;
225
+ nk_f32_t abs_running_sum = nk_f32_abs_(running_sum);
226
+ nk_f32_t abs_val = nk_f32_abs_(val);
227
+ if (abs_running_sum >= abs_val) sum_compensation += (running_sum - tentative_sum) + val;
228
+ else sum_compensation += (val - tentative_sum) + running_sum;
229
+ running_sum = tentative_sum;
230
+
231
+ nk_f32_t squared_value = val * val;
232
+ nk_f32_t tentative_sumsq = running_sumsq + squared_value;
233
+ if (running_sumsq >= squared_value) sumsq_compensation += (running_sumsq - tentative_sumsq) + squared_value;
234
+ else sumsq_compensation += (squared_value - tentative_sumsq) + running_sumsq;
235
+ running_sumsq = tentative_sumsq;
236
+ }
237
+ *sum_ptr = running_sum + sum_compensation, *sumsq_ptr = running_sumsq + sumsq_compensation;
238
+ }
239
+
240
+ NK_PUBLIC void nk_reduce_moments_bf16_serial( //
241
+ nk_bf16_t const *data, nk_size_t count, nk_size_t stride_bytes, //
242
+ nk_f32_t *sum_ptr, nk_f32_t *sumsq_ptr) {
243
+ nk_f32_t running_sum = 0, sum_compensation = 0;
244
+ nk_f32_t running_sumsq = 0, sumsq_compensation = 0;
245
+ unsigned char const *ptr = (unsigned char const *)data;
246
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
247
+ nk_f32_t val;
248
+ nk_bf16_to_f32_serial((nk_bf16_t const *)ptr, &val);
249
+ nk_f32_t tentative_sum = running_sum + val;
250
+ nk_f32_t abs_running_sum = nk_f32_abs_(running_sum);
251
+ nk_f32_t abs_val = nk_f32_abs_(val);
252
+ if (abs_running_sum >= abs_val) sum_compensation += (running_sum - tentative_sum) + val;
253
+ else sum_compensation += (val - tentative_sum) + running_sum;
254
+ running_sum = tentative_sum;
255
+
256
+ nk_f32_t squared_value = val * val;
257
+ nk_f32_t tentative_sumsq = running_sumsq + squared_value;
258
+ if (running_sumsq >= squared_value) sumsq_compensation += (running_sumsq - tentative_sumsq) + squared_value;
259
+ else sumsq_compensation += (squared_value - tentative_sumsq) + running_sumsq;
260
+ running_sumsq = tentative_sumsq;
261
+ }
262
+ *sum_ptr = running_sum + sum_compensation, *sumsq_ptr = running_sumsq + sumsq_compensation;
263
+ }
264
+
265
+ NK_PUBLIC void nk_reduce_moments_e4m3_serial( //
266
+ nk_e4m3_t const *data, nk_size_t count, nk_size_t stride_bytes, //
267
+ nk_f32_t *sum_ptr, nk_f32_t *sumsq_ptr) {
268
+ nk_f32_t running_sum = 0, sum_compensation = 0;
269
+ nk_f32_t running_sumsq = 0, sumsq_compensation = 0;
270
+ unsigned char const *ptr = (unsigned char const *)data;
271
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
272
+ nk_f32_t val;
273
+ nk_e4m3_to_f32_serial((nk_e4m3_t const *)ptr, &val);
274
+ nk_f32_t tentative_sum = running_sum + val;
275
+ nk_f32_t abs_running_sum = nk_f32_abs_(running_sum);
276
+ nk_f32_t abs_val = nk_f32_abs_(val);
277
+ if (abs_running_sum >= abs_val) sum_compensation += (running_sum - tentative_sum) + val;
278
+ else sum_compensation += (val - tentative_sum) + running_sum;
279
+ running_sum = tentative_sum;
280
+
281
+ nk_f32_t squared_value = val * val;
282
+ nk_f32_t tentative_sumsq = running_sumsq + squared_value;
283
+ if (running_sumsq >= squared_value) sumsq_compensation += (running_sumsq - tentative_sumsq) + squared_value;
284
+ else sumsq_compensation += (squared_value - tentative_sumsq) + running_sumsq;
285
+ running_sumsq = tentative_sumsq;
286
+ }
287
+ *sum_ptr = running_sum + sum_compensation, *sumsq_ptr = running_sumsq + sumsq_compensation;
288
+ }
289
+
290
+ NK_PUBLIC void nk_reduce_moments_e5m2_serial( //
291
+ nk_e5m2_t const *data, nk_size_t count, nk_size_t stride_bytes, //
292
+ nk_f32_t *sum_ptr, nk_f32_t *sumsq_ptr) {
293
+ nk_f32_t running_sum = 0, sum_compensation = 0;
294
+ nk_f32_t running_sumsq = 0, sumsq_compensation = 0;
295
+ unsigned char const *ptr = (unsigned char const *)data;
296
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
297
+ nk_f32_t val;
298
+ nk_e5m2_to_f32_serial((nk_e5m2_t const *)ptr, &val);
299
+ nk_f32_t tentative_sum = running_sum + val;
300
+ nk_f32_t abs_running_sum = nk_f32_abs_(running_sum);
301
+ nk_f32_t abs_val = nk_f32_abs_(val);
302
+ if (abs_running_sum >= abs_val) sum_compensation += (running_sum - tentative_sum) + val;
303
+ else sum_compensation += (val - tentative_sum) + running_sum;
304
+ running_sum = tentative_sum;
305
+
306
+ nk_f32_t squared_value = val * val;
307
+ nk_f32_t tentative_sumsq = running_sumsq + squared_value;
308
+ if (running_sumsq >= squared_value) sumsq_compensation += (running_sumsq - tentative_sumsq) + squared_value;
309
+ else sumsq_compensation += (squared_value - tentative_sumsq) + running_sumsq;
310
+ running_sumsq = tentative_sumsq;
311
+ }
312
+ *sum_ptr = running_sum + sum_compensation, *sumsq_ptr = running_sumsq + sumsq_compensation;
313
+ }
314
+
315
+ NK_PUBLIC void nk_reduce_moments_e2m3_serial( //
316
+ nk_e2m3_t const *data, nk_size_t count, nk_size_t stride_bytes, //
317
+ nk_f32_t *sum_ptr, nk_f32_t *sumsq_ptr) {
318
+ nk_f32_t running_sum = 0, sum_compensation = 0;
319
+ nk_f32_t running_sumsq = 0, sumsq_compensation = 0;
320
+ unsigned char const *ptr = (unsigned char const *)data;
321
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
322
+ nk_f32_t val;
323
+ nk_e2m3_to_f32_serial((nk_e2m3_t const *)ptr, &val);
324
+ nk_f32_t tentative_sum = running_sum + val;
325
+ nk_f32_t abs_running_sum = nk_f32_abs_(running_sum);
326
+ nk_f32_t abs_val = nk_f32_abs_(val);
327
+ if (abs_running_sum >= abs_val) sum_compensation += (running_sum - tentative_sum) + val;
328
+ else sum_compensation += (val - tentative_sum) + running_sum;
329
+ running_sum = tentative_sum;
330
+
331
+ nk_f32_t squared_value = val * val;
332
+ nk_f32_t tentative_sumsq = running_sumsq + squared_value;
333
+ if (running_sumsq >= squared_value) sumsq_compensation += (running_sumsq - tentative_sumsq) + squared_value;
334
+ else sumsq_compensation += (squared_value - tentative_sumsq) + running_sumsq;
335
+ running_sumsq = tentative_sumsq;
336
+ }
337
+ *sum_ptr = running_sum + sum_compensation, *sumsq_ptr = running_sumsq + sumsq_compensation;
338
+ }
339
+
340
+ NK_PUBLIC void nk_reduce_moments_e3m2_serial( //
341
+ nk_e3m2_t const *data, nk_size_t count, nk_size_t stride_bytes, //
342
+ nk_f32_t *sum_ptr, nk_f32_t *sumsq_ptr) {
343
+ nk_f32_t running_sum = 0, sum_compensation = 0;
344
+ nk_f32_t running_sumsq = 0, sumsq_compensation = 0;
345
+ unsigned char const *ptr = (unsigned char const *)data;
346
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
347
+ nk_f32_t val;
348
+ nk_e3m2_to_f32_serial((nk_e3m2_t const *)ptr, &val);
349
+ nk_f32_t tentative_sum = running_sum + val;
350
+ nk_f32_t abs_running_sum = nk_f32_abs_(running_sum);
351
+ nk_f32_t abs_val = nk_f32_abs_(val);
352
+ if (abs_running_sum >= abs_val) sum_compensation += (running_sum - tentative_sum) + val;
353
+ else sum_compensation += (val - tentative_sum) + running_sum;
354
+ running_sum = tentative_sum;
355
+
356
+ nk_f32_t squared_value = val * val;
357
+ nk_f32_t tentative_sumsq = running_sumsq + squared_value;
358
+ if (running_sumsq >= squared_value) sumsq_compensation += (running_sumsq - tentative_sumsq) + squared_value;
359
+ else sumsq_compensation += (squared_value - tentative_sumsq) + running_sumsq;
360
+ running_sumsq = tentative_sumsq;
361
+ }
362
+ *sum_ptr = running_sum + sum_compensation, *sumsq_ptr = running_sumsq + sumsq_compensation;
363
+ }
364
+
365
+ NK_PUBLIC void nk_reduce_moments_i4_serial( //
366
+ nk_i4x2_t const *data, nk_size_t count, nk_size_t stride_bytes, //
367
+ nk_i64_t *sum_ptr, nk_u64_t *sumsq_ptr) {
368
+ count = nk_size_round_up_to_multiple_(count, 2);
369
+ nk_i64_t sum = 0;
370
+ nk_u64_t sumsq = 0;
371
+ unsigned char const *ptr = (unsigned char const *)data;
372
+ for (nk_size_t i = 0; i < count; i += 2) {
373
+ unsigned char byte_val = ptr[(i / 2) * stride_bytes];
374
+ nk_i64_t low = (nk_i64_t)nk_i4x2_low_(byte_val);
375
+ nk_i64_t high = (nk_i64_t)nk_i4x2_high_(byte_val);
376
+ sum += low + high;
377
+ sumsq += (nk_u64_t)(low * low) + (nk_u64_t)(high * high);
378
+ }
379
+ *sum_ptr = sum, *sumsq_ptr = sumsq;
380
+ }
381
+
382
+ NK_PUBLIC void nk_reduce_moments_u4_serial( //
383
+ nk_u4x2_t const *data, nk_size_t count, nk_size_t stride_bytes, //
384
+ nk_u64_t *sum_ptr, nk_u64_t *sumsq_ptr) {
385
+ count = nk_size_round_up_to_multiple_(count, 2);
386
+ nk_u64_t sum = 0, sumsq = 0;
387
+ unsigned char const *ptr = (unsigned char const *)data;
388
+ for (nk_size_t i = 0; i < count; i += 2) {
389
+ unsigned char byte_val = ptr[(i / 2) * stride_bytes];
390
+ nk_u64_t low = nk_u4x2_low_(byte_val);
391
+ nk_u64_t high = nk_u4x2_high_(byte_val);
392
+ sum += low + high, sumsq += low * low + high * high;
393
+ }
394
+ *sum_ptr = sum, *sumsq_ptr = sumsq;
395
+ }
396
+
397
+ NK_PUBLIC void nk_reduce_moments_u1_serial( //
398
+ nk_u1x8_t const *data, nk_size_t count, nk_size_t stride_bytes, //
399
+ nk_u64_t *sum_ptr, nk_u64_t *sumsq_ptr) {
400
+ count = nk_size_round_up_to_multiple_(count, 8);
401
+ nk_u64_t sum = 0;
402
+ unsigned char const *ptr = (unsigned char const *)data;
403
+ for (nk_size_t i = 0; i < count; i += 8) {
404
+ unsigned char byte_val = ptr[(i / 8) * stride_bytes];
405
+ sum += nk_u64_popcount_(byte_val);
406
+ }
407
+ *sum_ptr = sum, *sumsq_ptr = sum; // 0^2 = 0, 1^2 = 1, so sumsq == sum
408
+ }
409
+
410
+ NK_PUBLIC void nk_reduce_minmax_f32_serial( //
411
+ nk_f32_t const *data, nk_size_t count, nk_size_t stride_bytes, //
412
+ nk_f32_t *min_value_ptr, nk_size_t *min_index_ptr, //
413
+ nk_f32_t *max_value_ptr, nk_size_t *max_index_ptr) {
414
+ unsigned char const *ptr = (unsigned char const *)data;
415
+ nk_f32_t min_value = NK_F32_MAX, max_value = NK_F32_MIN;
416
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
417
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
418
+ nk_f32_t val = *(nk_f32_t const *)ptr;
419
+ if (val < min_value) min_value = val, min_idx = i;
420
+ if (val > max_value) max_value = val, max_idx = i;
421
+ }
422
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
423
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
424
+ }
425
+
426
+ NK_PUBLIC void nk_reduce_minmax_f64_serial( //
427
+ nk_f64_t const *data, nk_size_t count, nk_size_t stride_bytes, //
428
+ nk_f64_t *min_value_ptr, nk_size_t *min_index_ptr, //
429
+ nk_f64_t *max_value_ptr, nk_size_t *max_index_ptr) {
430
+ unsigned char const *ptr = (unsigned char const *)data;
431
+ nk_f64_t min_value = NK_F64_MAX, max_value = NK_F64_MIN;
432
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
433
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
434
+ nk_f64_t val = *(nk_f64_t const *)ptr;
435
+ if (val < min_value) min_value = val, min_idx = i;
436
+ if (val > max_value) max_value = val, max_idx = i;
437
+ }
438
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
439
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
440
+ }
441
+
442
+ NK_PUBLIC void nk_reduce_minmax_i8_serial( //
443
+ nk_i8_t const *data, nk_size_t count, nk_size_t stride_bytes, //
444
+ nk_i8_t *min_value_ptr, nk_size_t *min_index_ptr, //
445
+ nk_i8_t *max_value_ptr, nk_size_t *max_index_ptr) {
446
+ unsigned char const *ptr = (unsigned char const *)data;
447
+ nk_i8_t min_value = NK_I8_MAX, max_value = NK_I8_MIN;
448
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
449
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
450
+ nk_i8_t val = *(nk_i8_t const *)ptr;
451
+ if (val < min_value) min_value = val, min_idx = i;
452
+ if (val > max_value) max_value = val, max_idx = i;
453
+ }
454
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
455
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
456
+ }
457
+
458
+ NK_PUBLIC void nk_reduce_minmax_u8_serial( //
459
+ nk_u8_t const *data, nk_size_t count, nk_size_t stride_bytes, //
460
+ nk_u8_t *min_value_ptr, nk_size_t *min_index_ptr, //
461
+ nk_u8_t *max_value_ptr, nk_size_t *max_index_ptr) {
462
+ unsigned char const *ptr = (unsigned char const *)data;
463
+ nk_u8_t min_value = NK_U8_MAX, max_value = NK_U8_MIN;
464
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
465
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
466
+ nk_u8_t val = *(nk_u8_t const *)ptr;
467
+ if (val < min_value) min_value = val, min_idx = i;
468
+ if (val > max_value) max_value = val, max_idx = i;
469
+ }
470
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
471
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
472
+ }
473
+
474
+ NK_PUBLIC void nk_reduce_minmax_i16_serial( //
475
+ nk_i16_t const *data, nk_size_t count, nk_size_t stride_bytes, //
476
+ nk_i16_t *min_value_ptr, nk_size_t *min_index_ptr, //
477
+ nk_i16_t *max_value_ptr, nk_size_t *max_index_ptr) {
478
+ unsigned char const *ptr = (unsigned char const *)data;
479
+ nk_i16_t min_value = NK_I16_MAX, max_value = NK_I16_MIN;
480
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
481
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
482
+ nk_i16_t val = *(nk_i16_t const *)ptr;
483
+ if (val < min_value) min_value = val, min_idx = i;
484
+ if (val > max_value) max_value = val, max_idx = i;
485
+ }
486
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
487
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
488
+ }
489
+
490
+ NK_PUBLIC void nk_reduce_minmax_u16_serial( //
491
+ nk_u16_t const *data, nk_size_t count, nk_size_t stride_bytes, //
492
+ nk_u16_t *min_value_ptr, nk_size_t *min_index_ptr, //
493
+ nk_u16_t *max_value_ptr, nk_size_t *max_index_ptr) {
494
+ unsigned char const *ptr = (unsigned char const *)data;
495
+ nk_u16_t min_value = NK_U16_MAX, max_value = NK_U16_MIN;
496
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
497
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
498
+ nk_u16_t val = *(nk_u16_t const *)ptr;
499
+ if (val < min_value) min_value = val, min_idx = i;
500
+ if (val > max_value) max_value = val, max_idx = i;
501
+ }
502
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
503
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
504
+ }
505
+
506
+ NK_PUBLIC void nk_reduce_minmax_i32_serial( //
507
+ nk_i32_t const *data, nk_size_t count, nk_size_t stride_bytes, //
508
+ nk_i32_t *min_value_ptr, nk_size_t *min_index_ptr, //
509
+ nk_i32_t *max_value_ptr, nk_size_t *max_index_ptr) {
510
+ unsigned char const *ptr = (unsigned char const *)data;
511
+ nk_i32_t min_value = NK_I32_MAX, max_value = NK_I32_MIN;
512
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
513
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
514
+ nk_i32_t val = *(nk_i32_t const *)ptr;
515
+ if (val < min_value) min_value = val, min_idx = i;
516
+ if (val > max_value) max_value = val, max_idx = i;
517
+ }
518
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
519
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
520
+ }
521
+
522
+ NK_PUBLIC void nk_reduce_minmax_u32_serial( //
523
+ nk_u32_t const *data, nk_size_t count, nk_size_t stride_bytes, //
524
+ nk_u32_t *min_value_ptr, nk_size_t *min_index_ptr, //
525
+ nk_u32_t *max_value_ptr, nk_size_t *max_index_ptr) {
526
+ unsigned char const *ptr = (unsigned char const *)data;
527
+ nk_u32_t min_value = NK_U32_MAX, max_value = NK_U32_MIN;
528
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
529
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
530
+ nk_u32_t val = *(nk_u32_t const *)ptr;
531
+ if (val < min_value) min_value = val, min_idx = i;
532
+ if (val > max_value) max_value = val, max_idx = i;
533
+ }
534
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
535
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
536
+ }
537
+
538
+ NK_PUBLIC void nk_reduce_minmax_i64_serial( //
539
+ nk_i64_t const *data, nk_size_t count, nk_size_t stride_bytes, //
540
+ nk_i64_t *min_value_ptr, nk_size_t *min_index_ptr, //
541
+ nk_i64_t *max_value_ptr, nk_size_t *max_index_ptr) {
542
+ unsigned char const *ptr = (unsigned char const *)data;
543
+ nk_i64_t min_value = NK_I64_MAX, max_value = NK_I64_MIN;
544
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
545
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
546
+ nk_i64_t val = *(nk_i64_t const *)ptr;
547
+ if (val < min_value) min_value = val, min_idx = i;
548
+ if (val > max_value) max_value = val, max_idx = i;
549
+ }
550
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
551
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
552
+ }
553
+
554
+ NK_PUBLIC void nk_reduce_minmax_u64_serial( //
555
+ nk_u64_t const *data, nk_size_t count, nk_size_t stride_bytes, //
556
+ nk_u64_t *min_value_ptr, nk_size_t *min_index_ptr, //
557
+ nk_u64_t *max_value_ptr, nk_size_t *max_index_ptr) {
558
+ unsigned char const *ptr = (unsigned char const *)data;
559
+ nk_u64_t min_value = NK_U64_MAX, max_value = NK_U64_MIN;
560
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
561
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
562
+ nk_u64_t val = *(nk_u64_t const *)ptr;
563
+ if (val < min_value) min_value = val, min_idx = i;
564
+ if (val > max_value) max_value = val, max_idx = i;
565
+ }
566
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
567
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
568
+ }
569
+
570
+ NK_PUBLIC void nk_reduce_minmax_f16_serial( //
571
+ nk_f16_t const *data, nk_size_t count, nk_size_t stride_bytes, //
572
+ nk_f16_t *min_value_ptr, nk_size_t *min_index_ptr, //
573
+ nk_f16_t *max_value_ptr, nk_size_t *max_index_ptr) {
574
+ unsigned char const *ptr = (unsigned char const *)data;
575
+ nk_f16_t min_value = NK_F16_MAX, max_value = NK_F16_MIN;
576
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
577
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
578
+ nk_f16_t raw_value = *(nk_f16_t const *)ptr;
579
+ if (nk_f16_is_nan_(raw_value)) continue;
580
+ if (min_idx == NK_SIZE_MAX || nk_f16_order_serial(raw_value, min_value) < 0) min_value = raw_value, min_idx = i;
581
+ if (max_idx == NK_SIZE_MAX || nk_f16_order_serial(raw_value, max_value) > 0) max_value = raw_value, max_idx = i;
582
+ }
583
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
584
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
585
+ }
586
+
587
+ NK_PUBLIC void nk_reduce_minmax_bf16_serial( //
588
+ nk_bf16_t const *data, nk_size_t count, nk_size_t stride_bytes, //
589
+ nk_bf16_t *min_value_ptr, nk_size_t *min_index_ptr, //
590
+ nk_bf16_t *max_value_ptr, nk_size_t *max_index_ptr) {
591
+ unsigned char const *ptr = (unsigned char const *)data;
592
+ nk_bf16_t min_value = NK_BF16_MAX, max_value = NK_BF16_MIN;
593
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
594
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
595
+ nk_bf16_t raw_value = *(nk_bf16_t const *)ptr;
596
+ if (nk_bf16_is_nan_(raw_value)) continue;
597
+ if (min_idx == NK_SIZE_MAX || nk_bf16_order_serial(raw_value, min_value) < 0)
598
+ min_value = raw_value, min_idx = i;
599
+ if (max_idx == NK_SIZE_MAX || nk_bf16_order_serial(raw_value, max_value) > 0)
600
+ max_value = raw_value, max_idx = i;
601
+ }
602
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
603
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
604
+ }
605
+
606
+ NK_PUBLIC void nk_reduce_minmax_e4m3_serial( //
607
+ nk_e4m3_t const *data, nk_size_t count, nk_size_t stride_bytes, //
608
+ nk_e4m3_t *min_value_ptr, nk_size_t *min_index_ptr, //
609
+ nk_e4m3_t *max_value_ptr, nk_size_t *max_index_ptr) {
610
+ unsigned char const *ptr = (unsigned char const *)data;
611
+ nk_e4m3_t min_value = NK_E4M3_MAX, max_value = NK_E4M3_MIN;
612
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
613
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
614
+ nk_e4m3_t raw_value = *(nk_e4m3_t const *)ptr;
615
+ if (nk_e4m3_is_nan_(raw_value)) continue;
616
+ if (min_idx == NK_SIZE_MAX || nk_e4m3_order_serial(raw_value, min_value) < 0)
617
+ min_value = raw_value, min_idx = i;
618
+ if (max_idx == NK_SIZE_MAX || nk_e4m3_order_serial(raw_value, max_value) > 0)
619
+ max_value = raw_value, max_idx = i;
620
+ }
621
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
622
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
623
+ }
624
+
625
+ NK_PUBLIC void nk_reduce_minmax_e5m2_serial( //
626
+ nk_e5m2_t const *data, nk_size_t count, nk_size_t stride_bytes, //
627
+ nk_e5m2_t *min_value_ptr, nk_size_t *min_index_ptr, //
628
+ nk_e5m2_t *max_value_ptr, nk_size_t *max_index_ptr) {
629
+ unsigned char const *ptr = (unsigned char const *)data;
630
+ nk_e5m2_t min_value = NK_E5M2_MAX, max_value = NK_E5M2_MIN;
631
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
632
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
633
+ nk_e5m2_t raw_value = *(nk_e5m2_t const *)ptr;
634
+ if (nk_e5m2_is_nan_(raw_value)) continue;
635
+ if (min_idx == NK_SIZE_MAX || nk_e5m2_order_serial(raw_value, min_value) < 0)
636
+ min_value = raw_value, min_idx = i;
637
+ if (max_idx == NK_SIZE_MAX || nk_e5m2_order_serial(raw_value, max_value) > 0)
638
+ max_value = raw_value, max_idx = i;
639
+ }
640
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
641
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
642
+ }
643
+
644
+ NK_PUBLIC void nk_reduce_minmax_e2m3_serial( //
645
+ nk_e2m3_t const *data, nk_size_t count, nk_size_t stride_bytes, //
646
+ nk_e2m3_t *min_value_ptr, nk_size_t *min_index_ptr, //
647
+ nk_e2m3_t *max_value_ptr, nk_size_t *max_index_ptr) {
648
+ unsigned char const *ptr = (unsigned char const *)data;
649
+ nk_e2m3_t min_value = NK_E2M3_MAX, max_value = NK_E2M3_MIN;
650
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
651
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
652
+ nk_e2m3_t raw_value = *(nk_e2m3_t const *)ptr;
653
+ if (nk_e2m3_order_serial(raw_value, min_value) < 0) min_value = raw_value, min_idx = i;
654
+ if (nk_e2m3_order_serial(raw_value, max_value) > 0) max_value = raw_value, max_idx = i;
655
+ }
656
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
657
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
658
+ }
659
+
660
+ NK_PUBLIC void nk_reduce_minmax_e3m2_serial( //
661
+ nk_e3m2_t const *data, nk_size_t count, nk_size_t stride_bytes, //
662
+ nk_e3m2_t *min_value_ptr, nk_size_t *min_index_ptr, //
663
+ nk_e3m2_t *max_value_ptr, nk_size_t *max_index_ptr) {
664
+ unsigned char const *ptr = (unsigned char const *)data;
665
+ nk_e3m2_t min_value = NK_E3M2_MAX, max_value = NK_E3M2_MIN;
666
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
667
+ for (nk_size_t i = 0; i < count; ++i, ptr += stride_bytes) {
668
+ nk_e3m2_t raw_value = *(nk_e3m2_t const *)ptr;
669
+ if (nk_e3m2_order_serial(raw_value, min_value) < 0) min_value = raw_value, min_idx = i;
670
+ if (nk_e3m2_order_serial(raw_value, max_value) > 0) max_value = raw_value, max_idx = i;
671
+ }
672
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
673
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
674
+ }
675
+
676
+ NK_PUBLIC void nk_reduce_minmax_i4_serial( //
677
+ nk_i4x2_t const *data, nk_size_t count, nk_size_t stride_bytes, //
678
+ nk_i8_t *min_value_ptr, nk_size_t *min_index_ptr, //
679
+ nk_i8_t *max_value_ptr, nk_size_t *max_index_ptr) {
680
+ count = nk_size_round_up_to_multiple_(count, 2);
681
+ unsigned char const *ptr = (unsigned char const *)data;
682
+ nk_i8_t min_value = 7, max_value = -8; // i4 range: -8 to 7
683
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
684
+ for (nk_size_t i = 0; i < count; ++i) {
685
+ nk_size_t byte_idx = i / 2;
686
+ unsigned char byte_val = ptr[byte_idx * stride_bytes];
687
+ nk_i8_t val = nk_i4x2_get_(byte_val, (int)(i & 1));
688
+ if (val < min_value) min_value = val, min_idx = i;
689
+ if (val > max_value) max_value = val, max_idx = i;
690
+ }
691
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
692
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
693
+ }
694
+
695
+ NK_PUBLIC void nk_reduce_minmax_u4_serial( //
696
+ nk_u4x2_t const *data, nk_size_t count, nk_size_t stride_bytes, //
697
+ nk_u8_t *min_value_ptr, nk_size_t *min_index_ptr, //
698
+ nk_u8_t *max_value_ptr, nk_size_t *max_index_ptr) {
699
+ count = nk_size_round_up_to_multiple_(count, 2);
700
+ unsigned char const *ptr = (unsigned char const *)data;
701
+ nk_u8_t min_value = 15, max_value = 0; // u4 range: 0 to 15
702
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
703
+ for (nk_size_t i = 0; i < count; ++i) {
704
+ nk_size_t byte_idx = i / 2;
705
+ unsigned char byte_val = ptr[byte_idx * stride_bytes];
706
+ nk_u8_t nibble = nk_u4x2_get_(byte_val, (int)(i & 1));
707
+ if (nibble < min_value) min_value = nibble, min_idx = i;
708
+ if (nibble > max_value) max_value = nibble, max_idx = i;
709
+ }
710
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
711
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
712
+ }
713
+
714
+ NK_PUBLIC void nk_reduce_minmax_u1_serial( //
715
+ nk_u1x8_t const *data, nk_size_t count, nk_size_t stride_bytes, //
716
+ nk_u8_t *min_value_ptr, nk_size_t *min_index_ptr, //
717
+ nk_u8_t *max_value_ptr, nk_size_t *max_index_ptr) {
718
+ count = nk_size_round_up_to_multiple_(count, 8);
719
+ unsigned char const *ptr = (unsigned char const *)data;
720
+ nk_u8_t min_value = 1, max_value = 0;
721
+ nk_size_t min_idx = NK_SIZE_MAX, max_idx = NK_SIZE_MAX;
722
+ for (nk_size_t i = 0; i < count; ++i) {
723
+ nk_size_t byte_idx = i / 8;
724
+ unsigned char byte_val = ptr[byte_idx * stride_bytes];
725
+ nk_u8_t bit = (byte_val >> (i % 8)) & 1;
726
+ if (bit < min_value) {
727
+ min_value = bit;
728
+ min_idx = i;
729
+ if (min_value == 0 && max_value == 1) {
730
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
731
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
732
+ return;
733
+ }
734
+ }
735
+ if (bit > max_value) {
736
+ max_value = bit;
737
+ max_idx = i;
738
+ if (min_value == 0 && max_value == 1) {
739
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
740
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
741
+ return;
742
+ }
743
+ }
744
+ }
745
+ *min_value_ptr = min_value, *min_index_ptr = min_idx;
746
+ *max_value_ptr = max_value, *max_index_ptr = max_idx;
747
+ }
748
+
749
+ #if defined(__cplusplus)
750
+ } // extern "C"
751
+ #endif
752
+
753
+ #endif // NK_REDUCE_SERIAL_H