usearch 2.21.3 → 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.
- package/README.md +24 -24
- package/binding.gyp +15 -37
- package/c/CMakeLists.txt +4 -5
- package/c/README.md +7 -7
- package/c/lib.cpp +32 -14
- package/c/test.c +83 -1
- package/c/usearch.h +24 -3
- package/cpp/CMakeLists.txt +4 -0
- package/cpp/README.md +5 -5
- package/cpp/bench.cpp +97 -116
- package/cpp/test.cpp +117 -20
- package/include/usearch/index.hpp +235 -52
- package/include/usearch/index_dense.hpp +105 -40
- package/include/usearch/index_plugins.hpp +1387 -204
- package/javascript/dist/cjs/usearch.d.ts +8 -3
- package/javascript/dist/cjs/usearch.js +12 -4
- package/javascript/dist/esm/usearch.d.ts +8 -3
- package/javascript/dist/esm/usearch.js +12 -4
- package/javascript/lib.cpp +17 -0
- package/javascript/usearch.ts +14 -6
- package/numkong/.clang-tidy +30 -0
- package/{simsimd → numkong}/.cmake-format.py +18 -0
- package/numkong/.editorconfig +12 -0
- package/numkong/.git-blame-ignore-revs +123 -0
- package/numkong/.mailmap +15 -0
- package/numkong/.spi.yml +11 -0
- package/numkong/.swift-format +14 -0
- package/numkong/CITATION.cff +81 -0
- package/numkong/CONTRIBUTING.md +500 -0
- package/numkong/Cargo.toml +54 -0
- package/numkong/MANIFEST.in +8 -0
- package/numkong/Package.swift +84 -0
- package/numkong/README.md +569 -0
- package/numkong/bench/README.md +217 -0
- package/numkong/bench/bench-browser.html +323 -0
- package/numkong/bench/bench.cpp +344 -0
- package/numkong/bench/bench.hpp +816 -0
- package/numkong/bench/bench.js +148 -0
- package/numkong/bench/bench.mjs +616 -0
- package/numkong/bench/bench_attention.cpp +113 -0
- package/numkong/bench/bench_cast.cpp +264 -0
- package/numkong/bench/bench_cross_amx.cpp +62 -0
- package/numkong/bench/bench_cross_arm.cpp +245 -0
- package/numkong/bench/bench_cross_blas.cpp +309 -0
- package/numkong/bench/bench_cross_loongarch.cpp +106 -0
- package/numkong/bench/bench_cross_power.cpp +84 -0
- package/numkong/bench/bench_cross_rvv.cpp +121 -0
- package/numkong/bench/bench_cross_serial.cpp +151 -0
- package/numkong/bench/bench_cross_sme.cpp +163 -0
- package/numkong/bench/bench_cross_wasm.cpp +142 -0
- package/numkong/bench/bench_cross_x86.cpp +455 -0
- package/numkong/bench/bench_curved.cpp +210 -0
- package/numkong/bench/bench_dot.cpp +315 -0
- package/numkong/bench/bench_each.cpp +503 -0
- package/numkong/bench/bench_geospatial.cpp +112 -0
- package/numkong/bench/bench_maxsim.cpp +154 -0
- package/numkong/bench/bench_mesh.cpp +148 -0
- package/numkong/bench/bench_probability.cpp +60 -0
- package/numkong/bench/bench_reduce.cpp +371 -0
- package/numkong/bench/bench_set.cpp +73 -0
- package/numkong/bench/bench_sparse.cpp +198 -0
- package/numkong/bench/bench_spatial.cpp +347 -0
- package/numkong/bench/bench_trigonometry.cpp +137 -0
- package/numkong/bench/swift/Bench.swift +506 -0
- package/numkong/binding.gyp +169 -0
- package/numkong/build.rs +484 -0
- package/numkong/c/dispatch.h +512 -0
- package/numkong/c/dispatch_bf16.c +447 -0
- package/numkong/c/dispatch_bf16c.c +52 -0
- package/numkong/c/dispatch_e2m3.c +296 -0
- package/numkong/c/dispatch_e3m2.c +284 -0
- package/numkong/c/dispatch_e4m3.c +318 -0
- package/numkong/c/dispatch_e5m2.c +316 -0
- package/numkong/c/dispatch_f16.c +452 -0
- package/numkong/c/dispatch_f16c.c +58 -0
- package/numkong/c/dispatch_f32.c +434 -0
- package/numkong/c/dispatch_f32c.c +99 -0
- package/numkong/c/dispatch_f64.c +348 -0
- package/numkong/c/dispatch_f64c.c +98 -0
- package/numkong/c/dispatch_i16.c +96 -0
- package/numkong/c/dispatch_i32.c +89 -0
- package/numkong/c/dispatch_i4.c +153 -0
- package/numkong/c/dispatch_i64.c +86 -0
- package/numkong/c/dispatch_i8.c +348 -0
- package/numkong/c/dispatch_other.c +348 -0
- package/numkong/c/dispatch_u1.c +193 -0
- package/numkong/c/dispatch_u16.c +124 -0
- package/numkong/c/dispatch_u32.c +118 -0
- package/numkong/c/dispatch_u4.c +153 -0
- package/numkong/c/dispatch_u64.c +102 -0
- package/numkong/c/dispatch_u8.c +364 -0
- package/numkong/c/numkong.c +940 -0
- package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
- package/numkong/cmake/nk_isa_probe.cmake +90 -0
- package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_math_lib.cmake +46 -0
- package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
- package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
- package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
- package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
- package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
- package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
- package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
- package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
- package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
- package/numkong/cmake/toolchain-wasi.cmake +77 -0
- package/numkong/cmake/toolchain-wasm.cmake +70 -0
- package/numkong/cmake/toolchain-wasm64.cmake +62 -0
- package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
- package/numkong/include/README.md +643 -0
- package/numkong/include/module.modulemap +129 -0
- package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
- package/numkong/include/numkong/attention/sme.h +2075 -0
- package/numkong/include/numkong/attention.h +49 -0
- package/numkong/include/numkong/capabilities.h +930 -0
- package/numkong/include/numkong/cast/README.md +262 -0
- package/numkong/include/numkong/cast/diamond.h +64 -0
- package/numkong/include/numkong/cast/haswell.h +823 -0
- package/numkong/include/numkong/cast/icelake.h +475 -0
- package/numkong/include/numkong/cast/loongsonasx.h +252 -0
- package/numkong/include/numkong/cast/neon.h +1174 -0
- package/numkong/include/numkong/cast/powervsx.h +449 -0
- package/numkong/include/numkong/cast/rvv.h +970 -0
- package/numkong/include/numkong/cast/sapphire.h +262 -0
- package/numkong/include/numkong/cast/serial.h +2336 -0
- package/numkong/include/numkong/cast/skylake.h +915 -0
- package/numkong/include/numkong/cast/v128relaxed.h +537 -0
- package/numkong/include/numkong/cast.h +254 -0
- package/numkong/include/numkong/cast.hpp +44 -0
- package/numkong/include/numkong/curved/README.md +223 -0
- package/numkong/include/numkong/curved/genoa.h +182 -0
- package/numkong/include/numkong/curved/haswell.h +276 -0
- package/numkong/include/numkong/curved/neon.h +329 -0
- package/numkong/include/numkong/curved/neonbfdot.h +211 -0
- package/numkong/include/numkong/curved/rvv.h +305 -0
- package/numkong/include/numkong/curved/serial.h +207 -0
- package/numkong/include/numkong/curved/skylake.h +457 -0
- package/numkong/include/numkong/curved/smef64.h +530 -0
- package/numkong/include/numkong/curved.h +513 -0
- package/numkong/include/numkong/curved.hpp +144 -0
- package/numkong/include/numkong/dot/README.md +442 -0
- package/numkong/include/numkong/dot/alder.h +563 -0
- package/numkong/include/numkong/dot/diamond.h +158 -0
- package/numkong/include/numkong/dot/genoa.h +289 -0
- package/numkong/include/numkong/dot/haswell.h +1723 -0
- package/numkong/include/numkong/dot/icelake.h +997 -0
- package/numkong/include/numkong/dot/loongsonasx.h +671 -0
- package/numkong/include/numkong/dot/neon.h +869 -0
- package/numkong/include/numkong/dot/neonbfdot.h +243 -0
- package/numkong/include/numkong/dot/neonfhm.h +358 -0
- package/numkong/include/numkong/dot/neonfp8.h +323 -0
- package/numkong/include/numkong/dot/neonsdot.h +622 -0
- package/numkong/include/numkong/dot/powervsx.h +752 -0
- package/numkong/include/numkong/dot/rvv.h +722 -0
- package/numkong/include/numkong/dot/rvvbb.h +72 -0
- package/numkong/include/numkong/dot/rvvbf16.h +123 -0
- package/numkong/include/numkong/dot/rvvhalf.h +129 -0
- package/numkong/include/numkong/dot/sapphire.h +141 -0
- package/numkong/include/numkong/dot/serial.h +874 -0
- package/numkong/include/numkong/dot/sierra.h +405 -0
- package/numkong/include/numkong/dot/skylake.h +1116 -0
- package/numkong/include/numkong/dot/sve.h +420 -0
- package/numkong/include/numkong/dot/svebfdot.h +75 -0
- package/numkong/include/numkong/dot/svehalf.h +168 -0
- package/numkong/include/numkong/dot/svesdot.h +90 -0
- package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
- package/numkong/include/numkong/dot.h +1136 -0
- package/numkong/include/numkong/dot.hpp +94 -0
- package/numkong/include/numkong/dots/README.md +496 -0
- package/numkong/include/numkong/dots/alder.h +117 -0
- package/numkong/include/numkong/dots/diamond.h +86 -0
- package/numkong/include/numkong/dots/genoa.h +100 -0
- package/numkong/include/numkong/dots/graniteamx.h +733 -0
- package/numkong/include/numkong/dots/haswell.h +310 -0
- package/numkong/include/numkong/dots/icelake.h +180 -0
- package/numkong/include/numkong/dots/loongsonasx.h +176 -0
- package/numkong/include/numkong/dots/neon.h +123 -0
- package/numkong/include/numkong/dots/neonbfdot.h +59 -0
- package/numkong/include/numkong/dots/neonfhm.h +96 -0
- package/numkong/include/numkong/dots/neonfp8.h +99 -0
- package/numkong/include/numkong/dots/neonsdot.h +144 -0
- package/numkong/include/numkong/dots/powervsx.h +194 -0
- package/numkong/include/numkong/dots/rvv.h +2593 -0
- package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
- package/numkong/include/numkong/dots/serial.h +2867 -0
- package/numkong/include/numkong/dots/sierra.h +100 -0
- package/numkong/include/numkong/dots/skylake.h +207 -0
- package/numkong/include/numkong/dots/sme.h +5041 -0
- package/numkong/include/numkong/dots/smebi32.h +477 -0
- package/numkong/include/numkong/dots/smef64.h +1328 -0
- package/numkong/include/numkong/dots/smehalf.h +47 -0
- package/numkong/include/numkong/dots/v128relaxed.h +317 -0
- package/numkong/include/numkong/dots.h +3110 -0
- package/numkong/include/numkong/dots.hpp +641 -0
- package/numkong/include/numkong/each/README.md +465 -0
- package/numkong/include/numkong/each/haswell.h +1658 -0
- package/numkong/include/numkong/each/icelake.h +272 -0
- package/numkong/include/numkong/each/neon.h +1138 -0
- package/numkong/include/numkong/each/neonbfdot.h +211 -0
- package/numkong/include/numkong/each/neonhalf.h +318 -0
- package/numkong/include/numkong/each/rvv.h +1121 -0
- package/numkong/include/numkong/each/sapphire.h +343 -0
- package/numkong/include/numkong/each/serial.h +282 -0
- package/numkong/include/numkong/each/skylake.h +1562 -0
- package/numkong/include/numkong/each/v128relaxed.h +562 -0
- package/numkong/include/numkong/each.h +2232 -0
- package/numkong/include/numkong/each.hpp +434 -0
- package/numkong/include/numkong/geospatial/README.md +147 -0
- package/numkong/include/numkong/geospatial/haswell.h +633 -0
- package/numkong/include/numkong/geospatial/neon.h +615 -0
- package/numkong/include/numkong/geospatial/rvv.h +701 -0
- package/numkong/include/numkong/geospatial/serial.h +309 -0
- package/numkong/include/numkong/geospatial/skylake.h +613 -0
- package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
- package/numkong/include/numkong/geospatial.h +453 -0
- package/numkong/include/numkong/geospatial.hpp +235 -0
- package/numkong/include/numkong/matrix.hpp +336 -0
- package/numkong/include/numkong/maxsim/README.md +187 -0
- package/numkong/include/numkong/maxsim/alder.h +511 -0
- package/numkong/include/numkong/maxsim/genoa.h +115 -0
- package/numkong/include/numkong/maxsim/haswell.h +553 -0
- package/numkong/include/numkong/maxsim/icelake.h +480 -0
- package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
- package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
- package/numkong/include/numkong/maxsim/serial.h +490 -0
- package/numkong/include/numkong/maxsim/sme.h +993 -0
- package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
- package/numkong/include/numkong/maxsim.h +571 -0
- package/numkong/include/numkong/maxsim.hpp +133 -0
- package/numkong/include/numkong/mesh/README.md +219 -0
- package/numkong/include/numkong/mesh/haswell.h +2013 -0
- package/numkong/include/numkong/mesh/neon.h +1821 -0
- package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
- package/numkong/include/numkong/mesh/rvv.h +936 -0
- package/numkong/include/numkong/mesh/serial.h +721 -0
- package/numkong/include/numkong/mesh/skylake.h +2344 -0
- package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
- package/numkong/include/numkong/mesh.h +666 -0
- package/numkong/include/numkong/mesh.hpp +701 -0
- package/numkong/include/numkong/numkong.h +78 -0
- package/numkong/include/numkong/numkong.hpp +58 -0
- package/numkong/include/numkong/probability/README.md +177 -0
- package/numkong/include/numkong/probability/haswell.h +267 -0
- package/numkong/include/numkong/probability/neon.h +255 -0
- package/numkong/include/numkong/probability/rvv.h +414 -0
- package/numkong/include/numkong/probability/serial.h +181 -0
- package/numkong/include/numkong/probability/skylake.h +324 -0
- package/numkong/include/numkong/probability.h +380 -0
- package/numkong/include/numkong/probability.hpp +120 -0
- package/numkong/include/numkong/random.h +50 -0
- package/numkong/include/numkong/random.hpp +285 -0
- package/numkong/include/numkong/reduce/README.md +552 -0
- package/numkong/include/numkong/reduce/alder.h +636 -0
- package/numkong/include/numkong/reduce/genoa.h +201 -0
- package/numkong/include/numkong/reduce/haswell.h +3785 -0
- package/numkong/include/numkong/reduce/icelake.h +549 -0
- package/numkong/include/numkong/reduce/neon.h +3980 -0
- package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
- package/numkong/include/numkong/reduce/neonfhm.h +293 -0
- package/numkong/include/numkong/reduce/neonsdot.h +357 -0
- package/numkong/include/numkong/reduce/rvv.h +3533 -0
- package/numkong/include/numkong/reduce/serial.h +753 -0
- package/numkong/include/numkong/reduce/sierra.h +338 -0
- package/numkong/include/numkong/reduce/skylake.h +3794 -0
- package/numkong/include/numkong/reduce/sve.h +52 -0
- package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
- package/numkong/include/numkong/reduce.h +1582 -0
- package/numkong/include/numkong/reduce.hpp +778 -0
- package/numkong/include/numkong/scalar/README.md +89 -0
- package/numkong/include/numkong/scalar/haswell.h +122 -0
- package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
- package/numkong/include/numkong/scalar/neon.h +122 -0
- package/numkong/include/numkong/scalar/neonhalf.h +70 -0
- package/numkong/include/numkong/scalar/powervsx.h +96 -0
- package/numkong/include/numkong/scalar/rvv.h +211 -0
- package/numkong/include/numkong/scalar/sapphire.h +74 -0
- package/numkong/include/numkong/scalar/serial.h +332 -0
- package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
- package/numkong/include/numkong/scalar.h +696 -0
- package/numkong/include/numkong/set/README.md +179 -0
- package/numkong/include/numkong/set/haswell.h +334 -0
- package/numkong/include/numkong/set/icelake.h +485 -0
- package/numkong/include/numkong/set/loongsonasx.h +181 -0
- package/numkong/include/numkong/set/neon.h +363 -0
- package/numkong/include/numkong/set/powervsx.h +326 -0
- package/numkong/include/numkong/set/rvv.h +226 -0
- package/numkong/include/numkong/set/rvvbb.h +117 -0
- package/numkong/include/numkong/set/serial.h +174 -0
- package/numkong/include/numkong/set/sve.h +187 -0
- package/numkong/include/numkong/set/v128relaxed.h +240 -0
- package/numkong/include/numkong/set.h +471 -0
- package/numkong/include/numkong/set.hpp +114 -0
- package/numkong/include/numkong/sets/README.md +149 -0
- package/numkong/include/numkong/sets/haswell.h +63 -0
- package/numkong/include/numkong/sets/icelake.h +66 -0
- package/numkong/include/numkong/sets/loongsonasx.h +52 -0
- package/numkong/include/numkong/sets/neon.h +61 -0
- package/numkong/include/numkong/sets/powervsx.h +65 -0
- package/numkong/include/numkong/sets/serial.h +43 -0
- package/numkong/include/numkong/sets/smebi32.h +1135 -0
- package/numkong/include/numkong/sets/v128relaxed.h +58 -0
- package/numkong/include/numkong/sets.h +382 -0
- package/numkong/include/numkong/sparse/README.md +156 -0
- package/numkong/include/numkong/sparse/icelake.h +463 -0
- package/numkong/include/numkong/sparse/neon.h +288 -0
- package/numkong/include/numkong/sparse/serial.h +117 -0
- package/numkong/include/numkong/sparse/sve2.h +504 -0
- package/numkong/include/numkong/sparse/turin.h +322 -0
- package/numkong/include/numkong/sparse.h +363 -0
- package/numkong/include/numkong/sparse.hpp +113 -0
- package/numkong/include/numkong/spatial/README.md +439 -0
- package/numkong/include/numkong/spatial/alder.h +604 -0
- package/numkong/include/numkong/spatial/diamond.h +240 -0
- package/numkong/include/numkong/spatial/genoa.h +222 -0
- package/numkong/include/numkong/spatial/haswell.h +979 -0
- package/numkong/include/numkong/spatial/icelake.h +1067 -0
- package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
- package/numkong/include/numkong/spatial/neon.h +846 -0
- package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
- package/numkong/include/numkong/spatial/neonfp8.h +258 -0
- package/numkong/include/numkong/spatial/neonsdot.h +429 -0
- package/numkong/include/numkong/spatial/powervsx.h +738 -0
- package/numkong/include/numkong/spatial/rvv.h +991 -0
- package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
- package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
- package/numkong/include/numkong/spatial/serial.h +347 -0
- package/numkong/include/numkong/spatial/sierra.h +516 -0
- package/numkong/include/numkong/spatial/skylake.h +605 -0
- package/numkong/include/numkong/spatial/sve.h +246 -0
- package/numkong/include/numkong/spatial/svebfdot.h +125 -0
- package/numkong/include/numkong/spatial/svehalf.h +136 -0
- package/numkong/include/numkong/spatial/svesdot.h +143 -0
- package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
- package/numkong/include/numkong/spatial.h +1681 -0
- package/numkong/include/numkong/spatial.hpp +183 -0
- package/numkong/include/numkong/spatials/README.md +580 -0
- package/numkong/include/numkong/spatials/alder.h +94 -0
- package/numkong/include/numkong/spatials/diamond.h +82 -0
- package/numkong/include/numkong/spatials/genoa.h +94 -0
- package/numkong/include/numkong/spatials/graniteamx.h +173 -0
- package/numkong/include/numkong/spatials/haswell.h +219 -0
- package/numkong/include/numkong/spatials/icelake.h +113 -0
- package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
- package/numkong/include/numkong/spatials/neon.h +109 -0
- package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
- package/numkong/include/numkong/spatials/neonfhm.h +92 -0
- package/numkong/include/numkong/spatials/neonfp8.h +111 -0
- package/numkong/include/numkong/spatials/neonsdot.h +143 -0
- package/numkong/include/numkong/spatials/powervsx.h +153 -0
- package/numkong/include/numkong/spatials/rvv.h +1976 -0
- package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
- package/numkong/include/numkong/spatials/serial.h +248 -0
- package/numkong/include/numkong/spatials/sierra.h +96 -0
- package/numkong/include/numkong/spatials/skylake.h +184 -0
- package/numkong/include/numkong/spatials/sme.h +1927 -0
- package/numkong/include/numkong/spatials/smef64.h +483 -0
- package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
- package/numkong/include/numkong/spatials.h +3374 -0
- package/numkong/include/numkong/spatials.hpp +509 -0
- package/numkong/include/numkong/tensor.hpp +1981 -0
- package/numkong/include/numkong/trigonometry/README.md +184 -0
- package/numkong/include/numkong/trigonometry/haswell.h +653 -0
- package/numkong/include/numkong/trigonometry/neon.h +638 -0
- package/numkong/include/numkong/trigonometry/rvv.h +700 -0
- package/numkong/include/numkong/trigonometry/serial.h +703 -0
- package/numkong/include/numkong/trigonometry/skylake.h +725 -0
- package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
- package/numkong/include/numkong/trigonometry.h +467 -0
- package/numkong/include/numkong/trigonometry.hpp +166 -0
- package/numkong/include/numkong/types.h +1695 -0
- package/numkong/include/numkong/types.hpp +6027 -0
- package/numkong/include/numkong/vector.hpp +766 -0
- package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
- package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
- package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
- package/numkong/javascript/README.md +254 -0
- package/numkong/javascript/node-gyp-build.d.ts +4 -0
- package/numkong/javascript/numkong-browser.ts +40 -0
- package/numkong/javascript/numkong-wasm.ts +750 -0
- package/numkong/javascript/numkong.c +712 -0
- package/numkong/javascript/numkong.ts +613 -0
- package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
- package/numkong/javascript/tsconfig-cjs.json +13 -0
- package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
- package/numkong/javascript/types.ts +784 -0
- package/numkong/numkong.gypi +104 -0
- package/numkong/package.json +108 -0
- package/numkong/probes/arm_neon.c +8 -0
- package/numkong/probes/arm_neon_bfdot.c +9 -0
- package/numkong/probes/arm_neon_fhm.c +9 -0
- package/numkong/probes/arm_neon_half.c +8 -0
- package/numkong/probes/arm_neon_sdot.c +9 -0
- package/numkong/probes/arm_neonfp8.c +9 -0
- package/numkong/probes/arm_sme.c +16 -0
- package/numkong/probes/arm_sme2.c +16 -0
- package/numkong/probes/arm_sme2p1.c +16 -0
- package/numkong/probes/arm_sme_bf16.c +16 -0
- package/numkong/probes/arm_sme_bi32.c +16 -0
- package/numkong/probes/arm_sme_f64.c +16 -0
- package/numkong/probes/arm_sme_fa64.c +14 -0
- package/numkong/probes/arm_sme_half.c +16 -0
- package/numkong/probes/arm_sme_lut2.c +15 -0
- package/numkong/probes/arm_sve.c +18 -0
- package/numkong/probes/arm_sve2.c +20 -0
- package/numkong/probes/arm_sve2p1.c +18 -0
- package/numkong/probes/arm_sve_bfdot.c +20 -0
- package/numkong/probes/arm_sve_half.c +18 -0
- package/numkong/probes/arm_sve_sdot.c +21 -0
- package/numkong/probes/loongarch_lasx.c +12 -0
- package/numkong/probes/power_vsx.c +12 -0
- package/numkong/probes/probe.js +127 -0
- package/numkong/probes/riscv_rvv.c +14 -0
- package/numkong/probes/riscv_rvv_bb.c +15 -0
- package/numkong/probes/riscv_rvv_bf16.c +17 -0
- package/numkong/probes/riscv_rvv_half.c +14 -0
- package/numkong/probes/wasm_v128relaxed.c +11 -0
- package/numkong/probes/x86_alder.c +17 -0
- package/numkong/probes/x86_diamond.c +17 -0
- package/numkong/probes/x86_genoa.c +17 -0
- package/numkong/probes/x86_graniteamx.c +19 -0
- package/numkong/probes/x86_haswell.c +11 -0
- package/numkong/probes/x86_icelake.c +17 -0
- package/numkong/probes/x86_sapphire.c +16 -0
- package/numkong/probes/x86_sapphireamx.c +18 -0
- package/numkong/probes/x86_sierra.c +17 -0
- package/numkong/probes/x86_skylake.c +15 -0
- package/numkong/probes/x86_turin.c +17 -0
- package/numkong/rust/README.md +698 -0
- package/numkong/rust/capabilities.rs +96 -0
- package/numkong/rust/cast.rs +314 -0
- package/numkong/rust/curved.rs +391 -0
- package/numkong/rust/each.rs +2721 -0
- package/numkong/rust/geospatial.rs +343 -0
- package/numkong/rust/matrix.rs +5424 -0
- package/numkong/rust/maxsim.rs +540 -0
- package/numkong/rust/mesh.rs +837 -0
- package/numkong/rust/numkong.rs +409 -0
- package/numkong/rust/probability.rs +272 -0
- package/numkong/rust/reduce.rs +1249 -0
- package/numkong/rust/set.rs +194 -0
- package/numkong/rust/sparse.rs +513 -0
- package/numkong/rust/spatial.rs +1815 -0
- package/numkong/rust/tensor.rs +7565 -0
- package/numkong/rust/types.rs +3666 -0
- package/numkong/rust/vector.rs +1899 -0
- package/numkong/rustfmt.toml +2 -0
- package/numkong/swift/Matrix.swift +1388 -0
- package/numkong/swift/MaxSim.swift +151 -0
- package/numkong/swift/NumKong.swift +283 -0
- package/numkong/swift/Numerics.swift +329 -0
- package/numkong/swift/README.md +433 -0
- package/numkong/swift/Scalar.swift +741 -0
- package/numkong/swift/Tensor.swift +209 -0
- package/numkong/test/README.md +315 -0
- package/numkong/test/playwright.config.ts +16 -0
- package/numkong/test/swift/Test.swift +534 -0
- package/numkong/test/test-browser-bundle-runner.mjs +36 -0
- package/numkong/test/test-browser-bundle.html +188 -0
- package/numkong/test/test-browser-runner.mjs +43 -0
- package/numkong/test/test-browser.html +305 -0
- package/numkong/test/test-dtypes.mjs +453 -0
- package/numkong/test/test-wasm.mjs +267 -0
- package/numkong/test/test.cpp +442 -0
- package/numkong/test/test.hpp +580 -0
- package/numkong/test/test.mjs +363 -0
- package/numkong/test/test_base.py +1041 -0
- package/numkong/test/test_cast.cpp +242 -0
- package/numkong/test/test_cross.hpp +551 -0
- package/numkong/test/test_cross.py +467 -0
- package/numkong/test/test_cross_amx.cpp +50 -0
- package/numkong/test/test_cross_arm.cpp +225 -0
- package/numkong/test/test_cross_blas.cpp +354 -0
- package/numkong/test/test_cross_loongarch.cpp +90 -0
- package/numkong/test/test_cross_power.cpp +73 -0
- package/numkong/test/test_cross_rvv.cpp +109 -0
- package/numkong/test/test_cross_serial.cpp +181 -0
- package/numkong/test/test_cross_sme.cpp +148 -0
- package/numkong/test/test_cross_wasm.cpp +141 -0
- package/numkong/test/test_cross_x86.cpp +442 -0
- package/numkong/test/test_curved.cpp +182 -0
- package/numkong/test/test_curved.py +207 -0
- package/numkong/test/test_dot.cpp +353 -0
- package/numkong/test/test_dot.py +296 -0
- package/numkong/test/test_each.cpp +437 -0
- package/numkong/test/test_each.py +756 -0
- package/numkong/test/test_geospatial.cpp +155 -0
- package/numkong/test/test_geospatial.py +241 -0
- package/numkong/test/test_maxsim.cpp +138 -0
- package/numkong/test/test_maxsim.py +209 -0
- package/numkong/test/test_mesh.cpp +203 -0
- package/numkong/test/test_mesh.py +394 -0
- package/numkong/test/test_probability.cpp +136 -0
- package/numkong/test/test_probability.py +166 -0
- package/numkong/test/test_reduce.cpp +563 -0
- package/numkong/test/test_reduce.py +781 -0
- package/numkong/test/test_set.cpp +151 -0
- package/numkong/test/test_set.py +120 -0
- package/numkong/test/test_similarities.py +579 -0
- package/numkong/test/test_sparse.cpp +121 -0
- package/numkong/test/test_sparse.py +118 -0
- package/numkong/test/test_spatial.cpp +518 -0
- package/numkong/test/test_spatial.py +269 -0
- package/numkong/test/test_tensor.cpp +884 -0
- package/numkong/test/test_tensor.py +1417 -0
- package/numkong/test/test_trigonometry.cpp +156 -0
- package/numkong/test/test_trigonometry.py +180 -0
- package/package.json +7 -8
- package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
- package/prebuilds/linux-arm64/usearch.node +0 -0
- package/prebuilds/linux-x64/usearch.node +0 -0
- package/fp16/CMakeLists.txt +0 -176
- package/fp16/LICENSE +0 -11
- package/fp16/README.md +0 -20
- package/fp16/bench/alt-element.cc +0 -89
- package/fp16/bench/from-alt-array.cc +0 -175
- package/fp16/bench/from-ieee-array.cc +0 -399
- package/fp16/bench/ieee-element.cc +0 -272
- package/fp16/bench/to-alt-array.cc +0 -91
- package/fp16/bench/to-ieee-array.cc +0 -303
- package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
- package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
- package/fp16/cmake/DownloadPSimd.cmake +0 -15
- package/fp16/configure.py +0 -65
- package/fp16/confu.yaml +0 -8
- package/fp16/include/fp16/__init__.py +0 -0
- package/fp16/include/fp16/avx.py +0 -50
- package/fp16/include/fp16/avx2.py +0 -53
- package/fp16/include/fp16/bitcasts.h +0 -92
- package/fp16/include/fp16/fp16.h +0 -451
- package/fp16/include/fp16/psimd.h +0 -131
- package/fp16/include/fp16.h +0 -11
- package/fp16/jni/Android.mk +0 -6
- package/fp16/jni/Application.mk +0 -4
- package/fp16/test/alt-from-fp32-value.cc +0 -498
- package/fp16/test/alt-to-fp32-bits.cc +0 -263
- package/fp16/test/alt-to-fp32-psimd.cc +0 -145
- package/fp16/test/alt-to-fp32-value.cc +0 -348
- package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
- package/fp16/test/bitcasts.cc +0 -56
- package/fp16/test/ieee-from-fp32-value.cc +0 -523
- package/fp16/test/ieee-to-fp32-bits.cc +0 -333
- package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
- package/fp16/test/ieee-to-fp32-value.cc +0 -420
- package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
- package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
- package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
- package/fp16/test/peachpy/stubs.py +0 -38
- package/fp16/test/tables.cc +0 -530
- package/fp16/test/tables.h +0 -13
- package/fp16/third-party/THHalf.h +0 -92
- package/fp16/third-party/eigen-half.h +0 -170
- package/fp16/third-party/float16-compressor.h +0 -80
- package/fp16/third-party/half.hpp +0 -2916
- package/fp16/third-party/npy-halffloat.h +0 -328
- package/simsimd/.git-blame-ignore-revs +0 -2
- package/simsimd/CONTRIBUTING.md +0 -321
- package/simsimd/Cargo.toml +0 -49
- package/simsimd/MANIFEST.in +0 -4
- package/simsimd/Package.swift +0 -28
- package/simsimd/README.md +0 -1493
- package/simsimd/binding.gyp +0 -35
- package/simsimd/build.rs +0 -70
- package/simsimd/c/lib.c +0 -374
- package/simsimd/include/module.modulemap +0 -4
- package/simsimd/include/simsimd/binary.h +0 -486
- package/simsimd/include/simsimd/curved.h +0 -1541
- package/simsimd/include/simsimd/dot.h +0 -1853
- package/simsimd/include/simsimd/elementwise.h +0 -2465
- package/simsimd/include/simsimd/geospatial.h +0 -43
- package/simsimd/include/simsimd/mesh.h +0 -69
- package/simsimd/include/simsimd/probability.h +0 -606
- package/simsimd/include/simsimd/simsimd.h +0 -2567
- package/simsimd/include/simsimd/sparse.h +0 -1384
- package/simsimd/include/simsimd/spatial.h +0 -2335
- package/simsimd/include/simsimd/types.h +0 -666
- package/simsimd/javascript/fallback.ts +0 -233
- package/simsimd/javascript/lib.c +0 -125
- package/simsimd/javascript/node-gyp-build.d.ts +0 -1
- package/simsimd/javascript/simsimd.ts +0 -179
- package/simsimd/javascript/tsconfig-cjs.json +0 -8
- package/simsimd/package-lock.json +0 -1761
- package/simsimd/package.json +0 -61
- package/simsimd/rust/lib.rs +0 -1821
- package/simsimd/scripts/bench.cxx +0 -1170
- package/simsimd/scripts/bench.ipynb +0 -187
- package/simsimd/scripts/bench.js +0 -127
- package/simsimd/scripts/bench.rs +0 -876
- package/simsimd/scripts/bench_vectors.py +0 -734
- package/simsimd/scripts/bench_vectors_live.py +0 -213
- package/simsimd/scripts/test.c +0 -187
- package/simsimd/scripts/test.mjs +0 -220
- package/simsimd/scripts/test.py +0 -1505
- package/simsimd/swift/SimSIMD.swift +0 -149
- package/simsimd/swift/Test.swift +0 -128
- /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
- /package/{simsimd → numkong}/LICENSE +0 -0
- /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
- /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
|
@@ -0,0 +1,1249 @@
|
|
|
1
|
+
//! Statistical reductions: moments (sum/sum-of-squares) and min/max.
|
|
2
|
+
//!
|
|
3
|
+
//! This module provides:
|
|
4
|
+
//!
|
|
5
|
+
//! - [`ReduceMoments`]: Sum and sum-of-squares over a strided slice
|
|
6
|
+
//! - [`ReduceMinMax`]: Minimum and maximum over a strided slice
|
|
7
|
+
//! - [`Reductions`]: Blanket trait combining `ReduceMoments + ReduceMinMax`
|
|
8
|
+
|
|
9
|
+
use crate::types::{bf16, e2m3, e3m2, e4m3, e5m2, f16, i4x2, u1x8, u4x2, StorageElement};
|
|
10
|
+
|
|
11
|
+
#[link(name = "numkong")]
|
|
12
|
+
extern "C" {
|
|
13
|
+
// Reductions: moments (sum + sum-of-squares)
|
|
14
|
+
fn nk_reduce_moments_f64(
|
|
15
|
+
data: *const f64,
|
|
16
|
+
count: usize,
|
|
17
|
+
stride_bytes: usize,
|
|
18
|
+
sum: *mut f64,
|
|
19
|
+
sumsq: *mut f64,
|
|
20
|
+
);
|
|
21
|
+
fn nk_reduce_moments_f32(
|
|
22
|
+
data: *const f32,
|
|
23
|
+
count: usize,
|
|
24
|
+
stride_bytes: usize,
|
|
25
|
+
sum: *mut f64,
|
|
26
|
+
sumsq: *mut f64,
|
|
27
|
+
);
|
|
28
|
+
fn nk_reduce_moments_i8(
|
|
29
|
+
data: *const i8,
|
|
30
|
+
count: usize,
|
|
31
|
+
stride_bytes: usize,
|
|
32
|
+
sum: *mut i64,
|
|
33
|
+
sumsq: *mut u64,
|
|
34
|
+
);
|
|
35
|
+
fn nk_reduce_moments_u8(
|
|
36
|
+
data: *const u8,
|
|
37
|
+
count: usize,
|
|
38
|
+
stride_bytes: usize,
|
|
39
|
+
sum: *mut u64,
|
|
40
|
+
sumsq: *mut u64,
|
|
41
|
+
);
|
|
42
|
+
fn nk_reduce_moments_i16(
|
|
43
|
+
data: *const i16,
|
|
44
|
+
count: usize,
|
|
45
|
+
stride_bytes: usize,
|
|
46
|
+
sum: *mut i64,
|
|
47
|
+
sumsq: *mut u64,
|
|
48
|
+
);
|
|
49
|
+
fn nk_reduce_moments_u16(
|
|
50
|
+
data: *const u16,
|
|
51
|
+
count: usize,
|
|
52
|
+
stride_bytes: usize,
|
|
53
|
+
sum: *mut u64,
|
|
54
|
+
sumsq: *mut u64,
|
|
55
|
+
);
|
|
56
|
+
fn nk_reduce_moments_i32(
|
|
57
|
+
data: *const i32,
|
|
58
|
+
count: usize,
|
|
59
|
+
stride_bytes: usize,
|
|
60
|
+
sum: *mut i64,
|
|
61
|
+
sumsq: *mut u64,
|
|
62
|
+
);
|
|
63
|
+
fn nk_reduce_moments_u32(
|
|
64
|
+
data: *const u32,
|
|
65
|
+
count: usize,
|
|
66
|
+
stride_bytes: usize,
|
|
67
|
+
sum: *mut u64,
|
|
68
|
+
sumsq: *mut u64,
|
|
69
|
+
);
|
|
70
|
+
fn nk_reduce_moments_i64(
|
|
71
|
+
data: *const i64,
|
|
72
|
+
count: usize,
|
|
73
|
+
stride_bytes: usize,
|
|
74
|
+
sum: *mut i64,
|
|
75
|
+
sumsq: *mut u64,
|
|
76
|
+
);
|
|
77
|
+
fn nk_reduce_moments_u64(
|
|
78
|
+
data: *const u64,
|
|
79
|
+
count: usize,
|
|
80
|
+
stride_bytes: usize,
|
|
81
|
+
sum: *mut u64,
|
|
82
|
+
sumsq: *mut u64,
|
|
83
|
+
);
|
|
84
|
+
fn nk_reduce_moments_f16(
|
|
85
|
+
data: *const f16,
|
|
86
|
+
count: usize,
|
|
87
|
+
stride_bytes: usize,
|
|
88
|
+
sum: *mut f32,
|
|
89
|
+
sumsq: *mut f32,
|
|
90
|
+
);
|
|
91
|
+
fn nk_reduce_moments_bf16(
|
|
92
|
+
data: *const bf16,
|
|
93
|
+
count: usize,
|
|
94
|
+
stride_bytes: usize,
|
|
95
|
+
sum: *mut f32,
|
|
96
|
+
sumsq: *mut f32,
|
|
97
|
+
);
|
|
98
|
+
fn nk_reduce_moments_e4m3(
|
|
99
|
+
data: *const e4m3,
|
|
100
|
+
count: usize,
|
|
101
|
+
stride_bytes: usize,
|
|
102
|
+
sum: *mut f32,
|
|
103
|
+
sumsq: *mut f32,
|
|
104
|
+
);
|
|
105
|
+
fn nk_reduce_moments_e5m2(
|
|
106
|
+
data: *const e5m2,
|
|
107
|
+
count: usize,
|
|
108
|
+
stride_bytes: usize,
|
|
109
|
+
sum: *mut f32,
|
|
110
|
+
sumsq: *mut f32,
|
|
111
|
+
);
|
|
112
|
+
fn nk_reduce_moments_e2m3(
|
|
113
|
+
data: *const e2m3,
|
|
114
|
+
count: usize,
|
|
115
|
+
stride_bytes: usize,
|
|
116
|
+
sum: *mut f32,
|
|
117
|
+
sumsq: *mut f32,
|
|
118
|
+
);
|
|
119
|
+
fn nk_reduce_moments_e3m2(
|
|
120
|
+
data: *const e3m2,
|
|
121
|
+
count: usize,
|
|
122
|
+
stride_bytes: usize,
|
|
123
|
+
sum: *mut f32,
|
|
124
|
+
sumsq: *mut f32,
|
|
125
|
+
);
|
|
126
|
+
fn nk_reduce_moments_i4(
|
|
127
|
+
data: *const i4x2,
|
|
128
|
+
count: usize,
|
|
129
|
+
stride_bytes: usize,
|
|
130
|
+
sum: *mut i64,
|
|
131
|
+
sumsq: *mut u64,
|
|
132
|
+
);
|
|
133
|
+
fn nk_reduce_moments_u4(
|
|
134
|
+
data: *const u4x2,
|
|
135
|
+
count: usize,
|
|
136
|
+
stride_bytes: usize,
|
|
137
|
+
sum: *mut u64,
|
|
138
|
+
sumsq: *mut u64,
|
|
139
|
+
);
|
|
140
|
+
fn nk_reduce_moments_u1(
|
|
141
|
+
data: *const u1x8,
|
|
142
|
+
count: usize,
|
|
143
|
+
stride_bytes: usize,
|
|
144
|
+
sum: *mut u64,
|
|
145
|
+
sumsq: *mut u64,
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// Reductions: minmax (min + max + argmin + argmax)
|
|
149
|
+
fn nk_reduce_minmax_f64(
|
|
150
|
+
data: *const f64,
|
|
151
|
+
count: usize,
|
|
152
|
+
stride_bytes: usize,
|
|
153
|
+
min_val: *mut f64,
|
|
154
|
+
min_idx: *mut usize,
|
|
155
|
+
max_val: *mut f64,
|
|
156
|
+
max_idx: *mut usize,
|
|
157
|
+
);
|
|
158
|
+
fn nk_reduce_minmax_f32(
|
|
159
|
+
data: *const f32,
|
|
160
|
+
count: usize,
|
|
161
|
+
stride_bytes: usize,
|
|
162
|
+
min_val: *mut f32,
|
|
163
|
+
min_idx: *mut usize,
|
|
164
|
+
max_val: *mut f32,
|
|
165
|
+
max_idx: *mut usize,
|
|
166
|
+
);
|
|
167
|
+
fn nk_reduce_minmax_i8(
|
|
168
|
+
data: *const i8,
|
|
169
|
+
count: usize,
|
|
170
|
+
stride_bytes: usize,
|
|
171
|
+
min_val: *mut i8,
|
|
172
|
+
min_idx: *mut usize,
|
|
173
|
+
max_val: *mut i8,
|
|
174
|
+
max_idx: *mut usize,
|
|
175
|
+
);
|
|
176
|
+
fn nk_reduce_minmax_u8(
|
|
177
|
+
data: *const u8,
|
|
178
|
+
count: usize,
|
|
179
|
+
stride_bytes: usize,
|
|
180
|
+
min_val: *mut u8,
|
|
181
|
+
min_idx: *mut usize,
|
|
182
|
+
max_val: *mut u8,
|
|
183
|
+
max_idx: *mut usize,
|
|
184
|
+
);
|
|
185
|
+
fn nk_reduce_minmax_i16(
|
|
186
|
+
data: *const i16,
|
|
187
|
+
count: usize,
|
|
188
|
+
stride_bytes: usize,
|
|
189
|
+
min_val: *mut i16,
|
|
190
|
+
min_idx: *mut usize,
|
|
191
|
+
max_val: *mut i16,
|
|
192
|
+
max_idx: *mut usize,
|
|
193
|
+
);
|
|
194
|
+
fn nk_reduce_minmax_u16(
|
|
195
|
+
data: *const u16,
|
|
196
|
+
count: usize,
|
|
197
|
+
stride_bytes: usize,
|
|
198
|
+
min_val: *mut u16,
|
|
199
|
+
min_idx: *mut usize,
|
|
200
|
+
max_val: *mut u16,
|
|
201
|
+
max_idx: *mut usize,
|
|
202
|
+
);
|
|
203
|
+
fn nk_reduce_minmax_i32(
|
|
204
|
+
data: *const i32,
|
|
205
|
+
count: usize,
|
|
206
|
+
stride_bytes: usize,
|
|
207
|
+
min_val: *mut i32,
|
|
208
|
+
min_idx: *mut usize,
|
|
209
|
+
max_val: *mut i32,
|
|
210
|
+
max_idx: *mut usize,
|
|
211
|
+
);
|
|
212
|
+
fn nk_reduce_minmax_u32(
|
|
213
|
+
data: *const u32,
|
|
214
|
+
count: usize,
|
|
215
|
+
stride_bytes: usize,
|
|
216
|
+
min_val: *mut u32,
|
|
217
|
+
min_idx: *mut usize,
|
|
218
|
+
max_val: *mut u32,
|
|
219
|
+
max_idx: *mut usize,
|
|
220
|
+
);
|
|
221
|
+
fn nk_reduce_minmax_i64(
|
|
222
|
+
data: *const i64,
|
|
223
|
+
count: usize,
|
|
224
|
+
stride_bytes: usize,
|
|
225
|
+
min_val: *mut i64,
|
|
226
|
+
min_idx: *mut usize,
|
|
227
|
+
max_val: *mut i64,
|
|
228
|
+
max_idx: *mut usize,
|
|
229
|
+
);
|
|
230
|
+
fn nk_reduce_minmax_u64(
|
|
231
|
+
data: *const u64,
|
|
232
|
+
count: usize,
|
|
233
|
+
stride_bytes: usize,
|
|
234
|
+
min_val: *mut u64,
|
|
235
|
+
min_idx: *mut usize,
|
|
236
|
+
max_val: *mut u64,
|
|
237
|
+
max_idx: *mut usize,
|
|
238
|
+
);
|
|
239
|
+
fn nk_reduce_minmax_f16(
|
|
240
|
+
data: *const f16,
|
|
241
|
+
count: usize,
|
|
242
|
+
stride_bytes: usize,
|
|
243
|
+
min_val: *mut f16,
|
|
244
|
+
min_idx: *mut usize,
|
|
245
|
+
max_val: *mut f16,
|
|
246
|
+
max_idx: *mut usize,
|
|
247
|
+
);
|
|
248
|
+
fn nk_reduce_minmax_bf16(
|
|
249
|
+
data: *const bf16,
|
|
250
|
+
count: usize,
|
|
251
|
+
stride_bytes: usize,
|
|
252
|
+
min_val: *mut bf16,
|
|
253
|
+
min_idx: *mut usize,
|
|
254
|
+
max_val: *mut bf16,
|
|
255
|
+
max_idx: *mut usize,
|
|
256
|
+
);
|
|
257
|
+
fn nk_reduce_minmax_e4m3(
|
|
258
|
+
data: *const e4m3,
|
|
259
|
+
count: usize,
|
|
260
|
+
stride_bytes: usize,
|
|
261
|
+
min_val: *mut e4m3,
|
|
262
|
+
min_idx: *mut usize,
|
|
263
|
+
max_val: *mut e4m3,
|
|
264
|
+
max_idx: *mut usize,
|
|
265
|
+
);
|
|
266
|
+
fn nk_reduce_minmax_e5m2(
|
|
267
|
+
data: *const e5m2,
|
|
268
|
+
count: usize,
|
|
269
|
+
stride_bytes: usize,
|
|
270
|
+
min_val: *mut e5m2,
|
|
271
|
+
min_idx: *mut usize,
|
|
272
|
+
max_val: *mut e5m2,
|
|
273
|
+
max_idx: *mut usize,
|
|
274
|
+
);
|
|
275
|
+
fn nk_reduce_minmax_e2m3(
|
|
276
|
+
data: *const e2m3,
|
|
277
|
+
count: usize,
|
|
278
|
+
stride_bytes: usize,
|
|
279
|
+
min_val: *mut e2m3,
|
|
280
|
+
min_idx: *mut usize,
|
|
281
|
+
max_val: *mut e2m3,
|
|
282
|
+
max_idx: *mut usize,
|
|
283
|
+
);
|
|
284
|
+
fn nk_reduce_minmax_e3m2(
|
|
285
|
+
data: *const e3m2,
|
|
286
|
+
count: usize,
|
|
287
|
+
stride_bytes: usize,
|
|
288
|
+
min_val: *mut e3m2,
|
|
289
|
+
min_idx: *mut usize,
|
|
290
|
+
max_val: *mut e3m2,
|
|
291
|
+
max_idx: *mut usize,
|
|
292
|
+
);
|
|
293
|
+
fn nk_reduce_minmax_i4(
|
|
294
|
+
data: *const i4x2,
|
|
295
|
+
count: usize,
|
|
296
|
+
stride_bytes: usize,
|
|
297
|
+
min_val: *mut i8,
|
|
298
|
+
min_idx: *mut usize,
|
|
299
|
+
max_val: *mut i8,
|
|
300
|
+
max_idx: *mut usize,
|
|
301
|
+
);
|
|
302
|
+
fn nk_reduce_minmax_u4(
|
|
303
|
+
data: *const u4x2,
|
|
304
|
+
count: usize,
|
|
305
|
+
stride_bytes: usize,
|
|
306
|
+
min_val: *mut u8,
|
|
307
|
+
min_idx: *mut usize,
|
|
308
|
+
max_val: *mut u8,
|
|
309
|
+
max_idx: *mut usize,
|
|
310
|
+
);
|
|
311
|
+
fn nk_reduce_minmax_u1(
|
|
312
|
+
data: *const u1x8,
|
|
313
|
+
count: usize,
|
|
314
|
+
stride_bytes: usize,
|
|
315
|
+
min_val: *mut u8,
|
|
316
|
+
min_idx: *mut usize,
|
|
317
|
+
max_val: *mut u8,
|
|
318
|
+
max_idx: *mut usize,
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/// Compute first and second moments (sum and sum-of-squares) with stride support.
|
|
323
|
+
///
|
|
324
|
+
/// Returns `(sum, sum_of_squares)` for all elements in a slice, with optional striding.
|
|
325
|
+
/// The output types may be wider than the input to avoid overflow.
|
|
326
|
+
pub trait ReduceMoments: StorageElement {
|
|
327
|
+
/// Type for the sum output.
|
|
328
|
+
type SumOutput: StorageElement;
|
|
329
|
+
/// Type for the sum-of-squares output.
|
|
330
|
+
type SumSqOutput: StorageElement;
|
|
331
|
+
/// Compute `(sum, sum_of_squares)` for raw pointer input with the given stride in bytes.
|
|
332
|
+
///
|
|
333
|
+
/// # Safety
|
|
334
|
+
/// `data` must point to at least one reachable element when `count > 0`, and every logical
|
|
335
|
+
/// element addressed by `count` and `stride_bytes` must be valid to read.
|
|
336
|
+
unsafe fn reduce_moments_raw(
|
|
337
|
+
data: *const Self,
|
|
338
|
+
count: usize,
|
|
339
|
+
stride_bytes: usize,
|
|
340
|
+
) -> (Self::SumOutput, Self::SumSqOutput);
|
|
341
|
+
/// Compute `(sum, sum_of_squares)` for `data` with the given stride (in bytes).
|
|
342
|
+
/// Use `stride_bytes = size_of::<Self>()` for contiguous data.
|
|
343
|
+
fn reduce_moments(data: &[Self], stride_bytes: usize) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
344
|
+
unsafe { Self::reduce_moments_raw(data.as_ptr(), data.len(), stride_bytes) }
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
unsafe fn reduce_moments_via_ffi<Scalar, Sum: Default, SumSq: Default>(
|
|
349
|
+
data: *const Scalar,
|
|
350
|
+
count: usize,
|
|
351
|
+
stride_bytes: usize,
|
|
352
|
+
ffi: unsafe extern "C" fn(*const Scalar, usize, usize, *mut Sum, *mut SumSq),
|
|
353
|
+
) -> (Sum, SumSq)
|
|
354
|
+
where
|
|
355
|
+
Scalar: StorageElement,
|
|
356
|
+
{
|
|
357
|
+
let mut sum: Sum = Default::default();
|
|
358
|
+
let mut sumsq: SumSq = Default::default();
|
|
359
|
+
ffi(
|
|
360
|
+
data,
|
|
361
|
+
count * Scalar::dimensions_per_value(),
|
|
362
|
+
stride_bytes,
|
|
363
|
+
&mut sum,
|
|
364
|
+
&mut sumsq,
|
|
365
|
+
);
|
|
366
|
+
(sum, sumsq)
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
impl ReduceMoments for f64 {
|
|
370
|
+
type SumOutput = f64;
|
|
371
|
+
type SumSqOutput = f64;
|
|
372
|
+
|
|
373
|
+
unsafe fn reduce_moments_raw(
|
|
374
|
+
data: *const Self,
|
|
375
|
+
count: usize,
|
|
376
|
+
stride_bytes: usize,
|
|
377
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
378
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_f64)
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
impl ReduceMoments for f32 {
|
|
383
|
+
type SumOutput = f64;
|
|
384
|
+
type SumSqOutput = f64;
|
|
385
|
+
|
|
386
|
+
unsafe fn reduce_moments_raw(
|
|
387
|
+
data: *const Self,
|
|
388
|
+
count: usize,
|
|
389
|
+
stride_bytes: usize,
|
|
390
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
391
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_f32)
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
impl ReduceMoments for i8 {
|
|
396
|
+
type SumOutput = i64;
|
|
397
|
+
type SumSqOutput = u64;
|
|
398
|
+
|
|
399
|
+
unsafe fn reduce_moments_raw(
|
|
400
|
+
data: *const Self,
|
|
401
|
+
count: usize,
|
|
402
|
+
stride_bytes: usize,
|
|
403
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
404
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_i8)
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
impl ReduceMoments for u8 {
|
|
409
|
+
type SumOutput = u64;
|
|
410
|
+
type SumSqOutput = u64;
|
|
411
|
+
|
|
412
|
+
unsafe fn reduce_moments_raw(
|
|
413
|
+
data: *const Self,
|
|
414
|
+
count: usize,
|
|
415
|
+
stride_bytes: usize,
|
|
416
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
417
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_u8)
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
impl ReduceMoments for i16 {
|
|
422
|
+
type SumOutput = i64;
|
|
423
|
+
type SumSqOutput = u64;
|
|
424
|
+
|
|
425
|
+
unsafe fn reduce_moments_raw(
|
|
426
|
+
data: *const Self,
|
|
427
|
+
count: usize,
|
|
428
|
+
stride_bytes: usize,
|
|
429
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
430
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_i16)
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
impl ReduceMoments for u16 {
|
|
435
|
+
type SumOutput = u64;
|
|
436
|
+
type SumSqOutput = u64;
|
|
437
|
+
|
|
438
|
+
unsafe fn reduce_moments_raw(
|
|
439
|
+
data: *const Self,
|
|
440
|
+
count: usize,
|
|
441
|
+
stride_bytes: usize,
|
|
442
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
443
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_u16)
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
impl ReduceMoments for i32 {
|
|
448
|
+
type SumOutput = i64;
|
|
449
|
+
type SumSqOutput = u64;
|
|
450
|
+
|
|
451
|
+
unsafe fn reduce_moments_raw(
|
|
452
|
+
data: *const Self,
|
|
453
|
+
count: usize,
|
|
454
|
+
stride_bytes: usize,
|
|
455
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
456
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_i32)
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
impl ReduceMoments for u32 {
|
|
461
|
+
type SumOutput = u64;
|
|
462
|
+
type SumSqOutput = u64;
|
|
463
|
+
|
|
464
|
+
unsafe fn reduce_moments_raw(
|
|
465
|
+
data: *const Self,
|
|
466
|
+
count: usize,
|
|
467
|
+
stride_bytes: usize,
|
|
468
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
469
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_u32)
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
impl ReduceMoments for i64 {
|
|
474
|
+
type SumOutput = i64;
|
|
475
|
+
type SumSqOutput = u64;
|
|
476
|
+
|
|
477
|
+
unsafe fn reduce_moments_raw(
|
|
478
|
+
data: *const Self,
|
|
479
|
+
count: usize,
|
|
480
|
+
stride_bytes: usize,
|
|
481
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
482
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_i64)
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
impl ReduceMoments for u64 {
|
|
487
|
+
type SumOutput = u64;
|
|
488
|
+
type SumSqOutput = u64;
|
|
489
|
+
|
|
490
|
+
unsafe fn reduce_moments_raw(
|
|
491
|
+
data: *const Self,
|
|
492
|
+
count: usize,
|
|
493
|
+
stride_bytes: usize,
|
|
494
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
495
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_u64)
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
impl ReduceMoments for f16 {
|
|
500
|
+
type SumOutput = f32;
|
|
501
|
+
type SumSqOutput = f32;
|
|
502
|
+
|
|
503
|
+
unsafe fn reduce_moments_raw(
|
|
504
|
+
data: *const Self,
|
|
505
|
+
count: usize,
|
|
506
|
+
stride_bytes: usize,
|
|
507
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
508
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_f16)
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
impl ReduceMoments for bf16 {
|
|
513
|
+
type SumOutput = f32;
|
|
514
|
+
type SumSqOutput = f32;
|
|
515
|
+
|
|
516
|
+
unsafe fn reduce_moments_raw(
|
|
517
|
+
data: *const Self,
|
|
518
|
+
count: usize,
|
|
519
|
+
stride_bytes: usize,
|
|
520
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
521
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_bf16)
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
impl ReduceMoments for e4m3 {
|
|
526
|
+
type SumOutput = f32;
|
|
527
|
+
type SumSqOutput = f32;
|
|
528
|
+
|
|
529
|
+
unsafe fn reduce_moments_raw(
|
|
530
|
+
data: *const Self,
|
|
531
|
+
count: usize,
|
|
532
|
+
stride_bytes: usize,
|
|
533
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
534
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_e4m3)
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
impl ReduceMoments for e5m2 {
|
|
539
|
+
type SumOutput = f32;
|
|
540
|
+
type SumSqOutput = f32;
|
|
541
|
+
|
|
542
|
+
unsafe fn reduce_moments_raw(
|
|
543
|
+
data: *const Self,
|
|
544
|
+
count: usize,
|
|
545
|
+
stride_bytes: usize,
|
|
546
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
547
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_e5m2)
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
impl ReduceMoments for e2m3 {
|
|
552
|
+
type SumOutput = f32;
|
|
553
|
+
type SumSqOutput = f32;
|
|
554
|
+
|
|
555
|
+
unsafe fn reduce_moments_raw(
|
|
556
|
+
data: *const Self,
|
|
557
|
+
count: usize,
|
|
558
|
+
stride_bytes: usize,
|
|
559
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
560
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_e2m3)
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
impl ReduceMoments for e3m2 {
|
|
565
|
+
type SumOutput = f32;
|
|
566
|
+
type SumSqOutput = f32;
|
|
567
|
+
|
|
568
|
+
unsafe fn reduce_moments_raw(
|
|
569
|
+
data: *const Self,
|
|
570
|
+
count: usize,
|
|
571
|
+
stride_bytes: usize,
|
|
572
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
573
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_e3m2)
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
impl ReduceMoments for i4x2 {
|
|
578
|
+
type SumOutput = i64;
|
|
579
|
+
type SumSqOutput = u64;
|
|
580
|
+
|
|
581
|
+
unsafe fn reduce_moments_raw(
|
|
582
|
+
data: *const Self,
|
|
583
|
+
count: usize,
|
|
584
|
+
stride_bytes: usize,
|
|
585
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
586
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_i4)
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
impl ReduceMoments for u4x2 {
|
|
591
|
+
type SumOutput = u64;
|
|
592
|
+
type SumSqOutput = u64;
|
|
593
|
+
|
|
594
|
+
unsafe fn reduce_moments_raw(
|
|
595
|
+
data: *const Self,
|
|
596
|
+
count: usize,
|
|
597
|
+
stride_bytes: usize,
|
|
598
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
599
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_u4)
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
impl ReduceMoments for u1x8 {
|
|
604
|
+
type SumOutput = u64;
|
|
605
|
+
type SumSqOutput = u64;
|
|
606
|
+
|
|
607
|
+
unsafe fn reduce_moments_raw(
|
|
608
|
+
data: *const Self,
|
|
609
|
+
count: usize,
|
|
610
|
+
stride_bytes: usize,
|
|
611
|
+
) -> (Self::SumOutput, Self::SumSqOutput) {
|
|
612
|
+
reduce_moments_via_ffi(data, count, stride_bytes, nk_reduce_moments_u1)
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/// Find minimum and maximum values with their indices, with stride support.
|
|
617
|
+
///
|
|
618
|
+
/// Returns `Some((min_value, min_index, max_value, max_index))` for all elements in a slice,
|
|
619
|
+
/// or `None` if all elements are NaN (for NaN-masking formats).
|
|
620
|
+
/// The output value type matches the logical reduced scalar type.
|
|
621
|
+
pub trait ReduceMinMax: StorageElement {
|
|
622
|
+
/// Output type for the min/max values — matches the C layer's native type.
|
|
623
|
+
type Output: StorageElement;
|
|
624
|
+
/// Whether `NK_SIZE_MAX` indicates that the reduction produced no value.
|
|
625
|
+
const NONE_ON_SENTINEL: bool;
|
|
626
|
+
/// Returns `Some((min_value, min_index, max_value, max_index))` for raw pointer input with the
|
|
627
|
+
/// specified stride, or `None` if all elements are NaN.
|
|
628
|
+
///
|
|
629
|
+
/// # Safety
|
|
630
|
+
/// `data` must point to at least one reachable element when `count > 0`, and every logical
|
|
631
|
+
/// element addressed by `count` and `stride_bytes` must be valid to read.
|
|
632
|
+
unsafe fn reduce_minmax_raw(
|
|
633
|
+
data: *const Self,
|
|
634
|
+
count: usize,
|
|
635
|
+
stride_bytes: usize,
|
|
636
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)>;
|
|
637
|
+
/// Returns `Some((min_value, min_index, max_value, max_index))` for the given data with the
|
|
638
|
+
/// specified stride, or `None` if all elements are NaN.
|
|
639
|
+
fn reduce_minmax(
|
|
640
|
+
data: &[Self],
|
|
641
|
+
stride_bytes: usize,
|
|
642
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
643
|
+
unsafe { Self::reduce_minmax_raw(data.as_ptr(), data.len(), stride_bytes) }
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
unsafe fn reduce_minmax_via_ffi<Scalar, Out: Default>(
|
|
648
|
+
data: *const Scalar,
|
|
649
|
+
count: usize,
|
|
650
|
+
stride_bytes: usize,
|
|
651
|
+
none_on_sentinel: bool,
|
|
652
|
+
ffi: unsafe extern "C" fn(
|
|
653
|
+
*const Scalar,
|
|
654
|
+
usize,
|
|
655
|
+
usize,
|
|
656
|
+
*mut Out,
|
|
657
|
+
*mut usize,
|
|
658
|
+
*mut Out,
|
|
659
|
+
*mut usize,
|
|
660
|
+
),
|
|
661
|
+
) -> Option<(Out, usize, Out, usize)>
|
|
662
|
+
where
|
|
663
|
+
Scalar: StorageElement,
|
|
664
|
+
{
|
|
665
|
+
let mut min_value: Out = Default::default();
|
|
666
|
+
let mut min_index: usize = 0;
|
|
667
|
+
let mut max_value: Out = Default::default();
|
|
668
|
+
let mut max_index: usize = 0;
|
|
669
|
+
ffi(
|
|
670
|
+
data,
|
|
671
|
+
count * Scalar::dimensions_per_value(),
|
|
672
|
+
stride_bytes,
|
|
673
|
+
&mut min_value,
|
|
674
|
+
&mut min_index,
|
|
675
|
+
&mut max_value,
|
|
676
|
+
&mut max_index,
|
|
677
|
+
);
|
|
678
|
+
if none_on_sentinel && min_index == usize::MAX {
|
|
679
|
+
return None;
|
|
680
|
+
}
|
|
681
|
+
Some((min_value, min_index, max_value, max_index))
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
impl ReduceMinMax for f64 {
|
|
685
|
+
type Output = f64;
|
|
686
|
+
const NONE_ON_SENTINEL: bool = true;
|
|
687
|
+
|
|
688
|
+
unsafe fn reduce_minmax_raw(
|
|
689
|
+
data: *const Self,
|
|
690
|
+
count: usize,
|
|
691
|
+
stride_bytes: usize,
|
|
692
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
693
|
+
reduce_minmax_via_ffi(
|
|
694
|
+
data,
|
|
695
|
+
count,
|
|
696
|
+
stride_bytes,
|
|
697
|
+
Self::NONE_ON_SENTINEL,
|
|
698
|
+
nk_reduce_minmax_f64,
|
|
699
|
+
)
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
impl ReduceMinMax for f32 {
|
|
704
|
+
type Output = f32;
|
|
705
|
+
const NONE_ON_SENTINEL: bool = true;
|
|
706
|
+
|
|
707
|
+
unsafe fn reduce_minmax_raw(
|
|
708
|
+
data: *const Self,
|
|
709
|
+
count: usize,
|
|
710
|
+
stride_bytes: usize,
|
|
711
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
712
|
+
reduce_minmax_via_ffi(
|
|
713
|
+
data,
|
|
714
|
+
count,
|
|
715
|
+
stride_bytes,
|
|
716
|
+
Self::NONE_ON_SENTINEL,
|
|
717
|
+
nk_reduce_minmax_f32,
|
|
718
|
+
)
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
impl ReduceMinMax for i8 {
|
|
723
|
+
type Output = i8;
|
|
724
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
725
|
+
|
|
726
|
+
unsafe fn reduce_minmax_raw(
|
|
727
|
+
data: *const Self,
|
|
728
|
+
count: usize,
|
|
729
|
+
stride_bytes: usize,
|
|
730
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
731
|
+
reduce_minmax_via_ffi(
|
|
732
|
+
data,
|
|
733
|
+
count,
|
|
734
|
+
stride_bytes,
|
|
735
|
+
Self::NONE_ON_SENTINEL,
|
|
736
|
+
nk_reduce_minmax_i8,
|
|
737
|
+
)
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
impl ReduceMinMax for u8 {
|
|
742
|
+
type Output = u8;
|
|
743
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
744
|
+
|
|
745
|
+
unsafe fn reduce_minmax_raw(
|
|
746
|
+
data: *const Self,
|
|
747
|
+
count: usize,
|
|
748
|
+
stride_bytes: usize,
|
|
749
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
750
|
+
reduce_minmax_via_ffi(
|
|
751
|
+
data,
|
|
752
|
+
count,
|
|
753
|
+
stride_bytes,
|
|
754
|
+
Self::NONE_ON_SENTINEL,
|
|
755
|
+
nk_reduce_minmax_u8,
|
|
756
|
+
)
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
impl ReduceMinMax for i16 {
|
|
761
|
+
type Output = i16;
|
|
762
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
763
|
+
|
|
764
|
+
unsafe fn reduce_minmax_raw(
|
|
765
|
+
data: *const Self,
|
|
766
|
+
count: usize,
|
|
767
|
+
stride_bytes: usize,
|
|
768
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
769
|
+
reduce_minmax_via_ffi(
|
|
770
|
+
data,
|
|
771
|
+
count,
|
|
772
|
+
stride_bytes,
|
|
773
|
+
Self::NONE_ON_SENTINEL,
|
|
774
|
+
nk_reduce_minmax_i16,
|
|
775
|
+
)
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
impl ReduceMinMax for u16 {
|
|
780
|
+
type Output = u16;
|
|
781
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
782
|
+
|
|
783
|
+
unsafe fn reduce_minmax_raw(
|
|
784
|
+
data: *const Self,
|
|
785
|
+
count: usize,
|
|
786
|
+
stride_bytes: usize,
|
|
787
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
788
|
+
reduce_minmax_via_ffi(
|
|
789
|
+
data,
|
|
790
|
+
count,
|
|
791
|
+
stride_bytes,
|
|
792
|
+
Self::NONE_ON_SENTINEL,
|
|
793
|
+
nk_reduce_minmax_u16,
|
|
794
|
+
)
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
impl ReduceMinMax for i32 {
|
|
799
|
+
type Output = i32;
|
|
800
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
801
|
+
|
|
802
|
+
unsafe fn reduce_minmax_raw(
|
|
803
|
+
data: *const Self,
|
|
804
|
+
count: usize,
|
|
805
|
+
stride_bytes: usize,
|
|
806
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
807
|
+
reduce_minmax_via_ffi(
|
|
808
|
+
data,
|
|
809
|
+
count,
|
|
810
|
+
stride_bytes,
|
|
811
|
+
Self::NONE_ON_SENTINEL,
|
|
812
|
+
nk_reduce_minmax_i32,
|
|
813
|
+
)
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
impl ReduceMinMax for u32 {
|
|
818
|
+
type Output = u32;
|
|
819
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
820
|
+
|
|
821
|
+
unsafe fn reduce_minmax_raw(
|
|
822
|
+
data: *const Self,
|
|
823
|
+
count: usize,
|
|
824
|
+
stride_bytes: usize,
|
|
825
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
826
|
+
reduce_minmax_via_ffi(
|
|
827
|
+
data,
|
|
828
|
+
count,
|
|
829
|
+
stride_bytes,
|
|
830
|
+
Self::NONE_ON_SENTINEL,
|
|
831
|
+
nk_reduce_minmax_u32,
|
|
832
|
+
)
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
impl ReduceMinMax for i64 {
|
|
837
|
+
type Output = i64;
|
|
838
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
839
|
+
|
|
840
|
+
unsafe fn reduce_minmax_raw(
|
|
841
|
+
data: *const Self,
|
|
842
|
+
count: usize,
|
|
843
|
+
stride_bytes: usize,
|
|
844
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
845
|
+
reduce_minmax_via_ffi(
|
|
846
|
+
data,
|
|
847
|
+
count,
|
|
848
|
+
stride_bytes,
|
|
849
|
+
Self::NONE_ON_SENTINEL,
|
|
850
|
+
nk_reduce_minmax_i64,
|
|
851
|
+
)
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
impl ReduceMinMax for u64 {
|
|
856
|
+
type Output = u64;
|
|
857
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
858
|
+
|
|
859
|
+
unsafe fn reduce_minmax_raw(
|
|
860
|
+
data: *const Self,
|
|
861
|
+
count: usize,
|
|
862
|
+
stride_bytes: usize,
|
|
863
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
864
|
+
reduce_minmax_via_ffi(
|
|
865
|
+
data,
|
|
866
|
+
count,
|
|
867
|
+
stride_bytes,
|
|
868
|
+
Self::NONE_ON_SENTINEL,
|
|
869
|
+
nk_reduce_minmax_u64,
|
|
870
|
+
)
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
impl ReduceMinMax for f16 {
|
|
875
|
+
type Output = f16;
|
|
876
|
+
const NONE_ON_SENTINEL: bool = true;
|
|
877
|
+
|
|
878
|
+
unsafe fn reduce_minmax_raw(
|
|
879
|
+
data: *const Self,
|
|
880
|
+
count: usize,
|
|
881
|
+
stride_bytes: usize,
|
|
882
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
883
|
+
reduce_minmax_via_ffi(
|
|
884
|
+
data,
|
|
885
|
+
count,
|
|
886
|
+
stride_bytes,
|
|
887
|
+
Self::NONE_ON_SENTINEL,
|
|
888
|
+
nk_reduce_minmax_f16,
|
|
889
|
+
)
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
impl ReduceMinMax for bf16 {
|
|
894
|
+
type Output = bf16;
|
|
895
|
+
const NONE_ON_SENTINEL: bool = true;
|
|
896
|
+
|
|
897
|
+
unsafe fn reduce_minmax_raw(
|
|
898
|
+
data: *const Self,
|
|
899
|
+
count: usize,
|
|
900
|
+
stride_bytes: usize,
|
|
901
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
902
|
+
reduce_minmax_via_ffi(
|
|
903
|
+
data,
|
|
904
|
+
count,
|
|
905
|
+
stride_bytes,
|
|
906
|
+
Self::NONE_ON_SENTINEL,
|
|
907
|
+
nk_reduce_minmax_bf16,
|
|
908
|
+
)
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
impl ReduceMinMax for e4m3 {
|
|
913
|
+
type Output = e4m3;
|
|
914
|
+
const NONE_ON_SENTINEL: bool = true;
|
|
915
|
+
|
|
916
|
+
unsafe fn reduce_minmax_raw(
|
|
917
|
+
data: *const Self,
|
|
918
|
+
count: usize,
|
|
919
|
+
stride_bytes: usize,
|
|
920
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
921
|
+
reduce_minmax_via_ffi(
|
|
922
|
+
data,
|
|
923
|
+
count,
|
|
924
|
+
stride_bytes,
|
|
925
|
+
Self::NONE_ON_SENTINEL,
|
|
926
|
+
nk_reduce_minmax_e4m3,
|
|
927
|
+
)
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
impl ReduceMinMax for e5m2 {
|
|
932
|
+
type Output = e5m2;
|
|
933
|
+
const NONE_ON_SENTINEL: bool = true;
|
|
934
|
+
|
|
935
|
+
unsafe fn reduce_minmax_raw(
|
|
936
|
+
data: *const Self,
|
|
937
|
+
count: usize,
|
|
938
|
+
stride_bytes: usize,
|
|
939
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
940
|
+
reduce_minmax_via_ffi(
|
|
941
|
+
data,
|
|
942
|
+
count,
|
|
943
|
+
stride_bytes,
|
|
944
|
+
Self::NONE_ON_SENTINEL,
|
|
945
|
+
nk_reduce_minmax_e5m2,
|
|
946
|
+
)
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
impl ReduceMinMax for e2m3 {
|
|
951
|
+
type Output = e2m3;
|
|
952
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
953
|
+
|
|
954
|
+
unsafe fn reduce_minmax_raw(
|
|
955
|
+
data: *const Self,
|
|
956
|
+
count: usize,
|
|
957
|
+
stride_bytes: usize,
|
|
958
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
959
|
+
reduce_minmax_via_ffi(
|
|
960
|
+
data,
|
|
961
|
+
count,
|
|
962
|
+
stride_bytes,
|
|
963
|
+
Self::NONE_ON_SENTINEL,
|
|
964
|
+
nk_reduce_minmax_e2m3,
|
|
965
|
+
)
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
impl ReduceMinMax for e3m2 {
|
|
970
|
+
type Output = e3m2;
|
|
971
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
972
|
+
|
|
973
|
+
unsafe fn reduce_minmax_raw(
|
|
974
|
+
data: *const Self,
|
|
975
|
+
count: usize,
|
|
976
|
+
stride_bytes: usize,
|
|
977
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
978
|
+
reduce_minmax_via_ffi(
|
|
979
|
+
data,
|
|
980
|
+
count,
|
|
981
|
+
stride_bytes,
|
|
982
|
+
Self::NONE_ON_SENTINEL,
|
|
983
|
+
nk_reduce_minmax_e3m2,
|
|
984
|
+
)
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
impl ReduceMinMax for i4x2 {
|
|
989
|
+
type Output = i8;
|
|
990
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
991
|
+
|
|
992
|
+
unsafe fn reduce_minmax_raw(
|
|
993
|
+
data: *const Self,
|
|
994
|
+
count: usize,
|
|
995
|
+
stride_bytes: usize,
|
|
996
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
997
|
+
reduce_minmax_via_ffi(
|
|
998
|
+
data,
|
|
999
|
+
count,
|
|
1000
|
+
stride_bytes,
|
|
1001
|
+
Self::NONE_ON_SENTINEL,
|
|
1002
|
+
nk_reduce_minmax_i4,
|
|
1003
|
+
)
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
impl ReduceMinMax for u4x2 {
|
|
1008
|
+
type Output = u8;
|
|
1009
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
1010
|
+
|
|
1011
|
+
unsafe fn reduce_minmax_raw(
|
|
1012
|
+
data: *const Self,
|
|
1013
|
+
count: usize,
|
|
1014
|
+
stride_bytes: usize,
|
|
1015
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
1016
|
+
reduce_minmax_via_ffi(
|
|
1017
|
+
data,
|
|
1018
|
+
count,
|
|
1019
|
+
stride_bytes,
|
|
1020
|
+
Self::NONE_ON_SENTINEL,
|
|
1021
|
+
nk_reduce_minmax_u4,
|
|
1022
|
+
)
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
impl ReduceMinMax for u1x8 {
|
|
1027
|
+
type Output = u8;
|
|
1028
|
+
const NONE_ON_SENTINEL: bool = false;
|
|
1029
|
+
|
|
1030
|
+
unsafe fn reduce_minmax_raw(
|
|
1031
|
+
data: *const Self,
|
|
1032
|
+
count: usize,
|
|
1033
|
+
stride_bytes: usize,
|
|
1034
|
+
) -> Option<(Self::Output, usize, Self::Output, usize)> {
|
|
1035
|
+
reduce_minmax_via_ffi(
|
|
1036
|
+
data,
|
|
1037
|
+
count,
|
|
1038
|
+
stride_bytes,
|
|
1039
|
+
Self::NONE_ON_SENTINEL,
|
|
1040
|
+
nk_reduce_minmax_u1,
|
|
1041
|
+
)
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
/// `Reductions` bundles reduction operations: ReduceMoments and ReduceMinMax.
|
|
1046
|
+
pub trait Reductions: ReduceMoments + ReduceMinMax {}
|
|
1047
|
+
impl<Scalar: ReduceMoments + ReduceMinMax> Reductions for Scalar {}
|
|
1048
|
+
|
|
1049
|
+
#[cfg(test)]
|
|
1050
|
+
mod tests {
|
|
1051
|
+
use super::*;
|
|
1052
|
+
use crate::types::{
|
|
1053
|
+
assert_close, bf16, e2m3, e3m2, e4m3, e5m2, f16, FloatLike, NumberLike, TestableType,
|
|
1054
|
+
};
|
|
1055
|
+
|
|
1056
|
+
// region: ReduceMoments
|
|
1057
|
+
|
|
1058
|
+
fn check_reduce_moments<Scalar>(input_values: &[f32])
|
|
1059
|
+
where
|
|
1060
|
+
Scalar: FloatLike + TestableType + ReduceMoments,
|
|
1061
|
+
Scalar::SumOutput: FloatLike,
|
|
1062
|
+
Scalar::SumSqOutput: FloatLike,
|
|
1063
|
+
{
|
|
1064
|
+
let data: Vec<Scalar> = input_values.iter().map(|&v| Scalar::from_f32(v)).collect();
|
|
1065
|
+
let stride_bytes = core::mem::size_of::<Scalar>();
|
|
1066
|
+
let (actual_sum, actual_sumsq) = Scalar::reduce_moments(&data, stride_bytes);
|
|
1067
|
+
let expected_sum: f64 = input_values.iter().map(|&v| v as f64).sum();
|
|
1068
|
+
let expected_sumsq: f64 = input_values.iter().map(|&v| (v as f64) * (v as f64)).sum();
|
|
1069
|
+
let sample_count = input_values.len() as f64;
|
|
1070
|
+
assert_close(
|
|
1071
|
+
actual_sum.to_f64(),
|
|
1072
|
+
expected_sum,
|
|
1073
|
+
Scalar::atol() * sample_count,
|
|
1074
|
+
Scalar::rtol(),
|
|
1075
|
+
&format!("reduce_moments<{}> sum", core::any::type_name::<Scalar>()),
|
|
1076
|
+
);
|
|
1077
|
+
assert_close(
|
|
1078
|
+
actual_sumsq.to_f64(),
|
|
1079
|
+
expected_sumsq,
|
|
1080
|
+
Scalar::atol() * sample_count,
|
|
1081
|
+
Scalar::rtol(),
|
|
1082
|
+
&format!("reduce_moments<{}> sumsq", core::any::type_name::<Scalar>()),
|
|
1083
|
+
);
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
#[test]
|
|
1087
|
+
fn moments_reduction() {
|
|
1088
|
+
// Float types — SumOutput/SumSqOutput are FloatLike (f32 or f64)
|
|
1089
|
+
let input_values = &[1.0, 2.0, 3.0, 4.0, 5.0];
|
|
1090
|
+
check_reduce_moments::<f64>(input_values);
|
|
1091
|
+
check_reduce_moments::<f32>(input_values);
|
|
1092
|
+
check_reduce_moments::<f16>(input_values);
|
|
1093
|
+
check_reduce_moments::<bf16>(input_values);
|
|
1094
|
+
check_reduce_moments::<e4m3>(input_values);
|
|
1095
|
+
check_reduce_moments::<e5m2>(&[1.0, 2.0, 3.0]);
|
|
1096
|
+
check_reduce_moments::<e2m3>(&[1.0, 2.0, 3.0]);
|
|
1097
|
+
check_reduce_moments::<e3m2>(&[1.0, 2.0, 3.0]);
|
|
1098
|
+
|
|
1099
|
+
// Integer types — now also go through generics with FloatLike for i64/u64
|
|
1100
|
+
let signed = &[1.0_f32, -2.0, 3.0, -4.0, 5.0];
|
|
1101
|
+
let unsigned = &[1.0_f32, 2.0, 3.0, 4.0, 5.0];
|
|
1102
|
+
check_reduce_moments::<i8>(signed);
|
|
1103
|
+
check_reduce_moments::<u8>(unsigned);
|
|
1104
|
+
check_reduce_moments::<i16>(signed);
|
|
1105
|
+
check_reduce_moments::<u16>(unsigned);
|
|
1106
|
+
check_reduce_moments::<i32>(signed);
|
|
1107
|
+
check_reduce_moments::<u32>(unsigned);
|
|
1108
|
+
check_reduce_moments::<i64>(signed);
|
|
1109
|
+
check_reduce_moments::<u64>(unsigned);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
// endregion
|
|
1113
|
+
|
|
1114
|
+
// region: ReduceMinMax
|
|
1115
|
+
|
|
1116
|
+
fn check_reduce_minmax<Scalar>(input_values: &[f32])
|
|
1117
|
+
where
|
|
1118
|
+
Scalar: FloatLike + TestableType + ReduceMinMax,
|
|
1119
|
+
Scalar::Output: FloatLike,
|
|
1120
|
+
{
|
|
1121
|
+
let data: Vec<Scalar> = input_values.iter().map(|&v| Scalar::from_f32(v)).collect();
|
|
1122
|
+
let stride_bytes = core::mem::size_of::<Scalar>();
|
|
1123
|
+
let result = Scalar::reduce_minmax(&data, stride_bytes);
|
|
1124
|
+
assert!(result.is_some(), "Expected Some for non-NaN input");
|
|
1125
|
+
let (actual_min, actual_min_index, actual_max, actual_max_index) = result.unwrap();
|
|
1126
|
+
let (expected_min_index, expected_min) = input_values
|
|
1127
|
+
.iter()
|
|
1128
|
+
.enumerate()
|
|
1129
|
+
.min_by(|left, right| left.1.partial_cmp(right.1).unwrap())
|
|
1130
|
+
.unwrap();
|
|
1131
|
+
let (expected_max_index, expected_max) = input_values
|
|
1132
|
+
.iter()
|
|
1133
|
+
.enumerate()
|
|
1134
|
+
.max_by(|left, right| left.1.partial_cmp(right.1).unwrap())
|
|
1135
|
+
.unwrap();
|
|
1136
|
+
assert_close(
|
|
1137
|
+
actual_min.to_f64(),
|
|
1138
|
+
*expected_min as f64,
|
|
1139
|
+
Scalar::atol(),
|
|
1140
|
+
0.0,
|
|
1141
|
+
&format!("reduce_minmax<{}> min", core::any::type_name::<Scalar>()),
|
|
1142
|
+
);
|
|
1143
|
+
assert_eq!(
|
|
1144
|
+
actual_min_index,
|
|
1145
|
+
expected_min_index,
|
|
1146
|
+
"reduce_minmax<{}> min_index",
|
|
1147
|
+
core::any::type_name::<Scalar>()
|
|
1148
|
+
);
|
|
1149
|
+
assert_close(
|
|
1150
|
+
actual_max.to_f64(),
|
|
1151
|
+
*expected_max as f64,
|
|
1152
|
+
Scalar::atol(),
|
|
1153
|
+
0.0,
|
|
1154
|
+
&format!("reduce_minmax<{}> max", core::any::type_name::<Scalar>()),
|
|
1155
|
+
);
|
|
1156
|
+
assert_eq!(
|
|
1157
|
+
actual_max_index,
|
|
1158
|
+
expected_max_index,
|
|
1159
|
+
"reduce_minmax<{}> max_index",
|
|
1160
|
+
core::any::type_name::<Scalar>()
|
|
1161
|
+
);
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
#[test]
|
|
1165
|
+
fn minmax_reduction() {
|
|
1166
|
+
// All FloatLike types — Output is also FloatLike
|
|
1167
|
+
let input_values = &[3.0, 1.0, 4.0, 1.5, 5.0, 2.0];
|
|
1168
|
+
check_reduce_minmax::<f64>(input_values);
|
|
1169
|
+
check_reduce_minmax::<f32>(input_values);
|
|
1170
|
+
check_reduce_minmax::<f16>(input_values);
|
|
1171
|
+
check_reduce_minmax::<bf16>(input_values);
|
|
1172
|
+
check_reduce_minmax::<e4m3>(input_values);
|
|
1173
|
+
check_reduce_minmax::<e5m2>(input_values);
|
|
1174
|
+
check_reduce_minmax::<e2m3>(&[3.0, 1.0, 4.0, 1.5, 5.0, 2.0]);
|
|
1175
|
+
check_reduce_minmax::<e3m2>(input_values);
|
|
1176
|
+
check_reduce_minmax::<i8>(input_values);
|
|
1177
|
+
check_reduce_minmax::<u8>(input_values);
|
|
1178
|
+
check_reduce_minmax::<i32>(input_values);
|
|
1179
|
+
check_reduce_minmax::<u32>(input_values);
|
|
1180
|
+
|
|
1181
|
+
// i16, u16, i64, u64 — now also go through generics with FloatLike
|
|
1182
|
+
check_reduce_minmax::<i16>(&[3.0, -1.0, 4.0, -5.0, 2.0]);
|
|
1183
|
+
check_reduce_minmax::<u16>(&[3.0, 1.0, 4.0, 5.0, 2.0]);
|
|
1184
|
+
check_reduce_minmax::<i64>(&[3.0, -1.0, 4.0, -5.0, 2.0]);
|
|
1185
|
+
check_reduce_minmax::<u64>(&[3.0, 1.0, 4.0, 5.0, 2.0]);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
#[test]
|
|
1189
|
+
fn minmax_reduction_all_nan() {
|
|
1190
|
+
let nan_f64: Vec<f64> = vec![f64::NAN; 16];
|
|
1191
|
+
assert_eq!(
|
|
1192
|
+
f64::reduce_minmax(&nan_f64, core::mem::size_of::<f64>()),
|
|
1193
|
+
None
|
|
1194
|
+
);
|
|
1195
|
+
|
|
1196
|
+
let nan_f32: Vec<f32> = vec![f32::NAN; 16];
|
|
1197
|
+
assert_eq!(
|
|
1198
|
+
f32::reduce_minmax(&nan_f32, core::mem::size_of::<f32>()),
|
|
1199
|
+
None
|
|
1200
|
+
);
|
|
1201
|
+
|
|
1202
|
+
let nan_f16: Vec<f16> = vec![f16::NAN; 16];
|
|
1203
|
+
assert_eq!(
|
|
1204
|
+
f16::reduce_minmax(&nan_f16, core::mem::size_of::<f16>()),
|
|
1205
|
+
None
|
|
1206
|
+
);
|
|
1207
|
+
|
|
1208
|
+
let nan_bf16: Vec<bf16> = vec![bf16::NAN; 16];
|
|
1209
|
+
assert_eq!(
|
|
1210
|
+
bf16::reduce_minmax(&nan_bf16, core::mem::size_of::<bf16>()),
|
|
1211
|
+
None
|
|
1212
|
+
);
|
|
1213
|
+
|
|
1214
|
+
let nan_e4m3: Vec<e4m3> = vec![e4m3::NAN; 16];
|
|
1215
|
+
assert_eq!(
|
|
1216
|
+
e4m3::reduce_minmax(&nan_e4m3, core::mem::size_of::<e4m3>()),
|
|
1217
|
+
None
|
|
1218
|
+
);
|
|
1219
|
+
|
|
1220
|
+
let nan_e5m2: Vec<e5m2> = vec![e5m2::NAN; 16];
|
|
1221
|
+
assert_eq!(
|
|
1222
|
+
e5m2::reduce_minmax(&nan_e5m2, core::mem::size_of::<e5m2>()),
|
|
1223
|
+
None
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
#[test]
|
|
1228
|
+
fn minmax_reduction_mixed_nan() {
|
|
1229
|
+
let data = vec![f64::NAN, 3.0, f64::NAN, 1.0, f64::NAN, 5.0];
|
|
1230
|
+
let result = f64::reduce_minmax(&data, core::mem::size_of::<f64>());
|
|
1231
|
+
assert!(result.is_some());
|
|
1232
|
+
let (min_value, min_index, max_value, max_index) = result.unwrap();
|
|
1233
|
+
assert_close(min_value, 1.0, 1e-10, 0.0, "mixed min");
|
|
1234
|
+
assert_eq!(min_index, 3);
|
|
1235
|
+
assert_close(max_value, 5.0, 1e-10, 0.0, "mixed max");
|
|
1236
|
+
assert_eq!(max_index, 5);
|
|
1237
|
+
|
|
1238
|
+
let data_f32: Vec<f32> = vec![f32::NAN, 3.0, f32::NAN, 1.0, f32::NAN, 5.0];
|
|
1239
|
+
let result_f32 = f32::reduce_minmax(&data_f32, core::mem::size_of::<f32>());
|
|
1240
|
+
assert!(result_f32.is_some());
|
|
1241
|
+
let (min_value, min_index, max_value, max_index) = result_f32.unwrap();
|
|
1242
|
+
assert_close(min_value as f64, 1.0, 1e-5, 0.0, "mixed f32 min");
|
|
1243
|
+
assert_eq!(min_index, 3);
|
|
1244
|
+
assert_close(max_value as f64, 5.0, 1e-5, 0.0, "mixed f32 max");
|
|
1245
|
+
assert_eq!(max_index, 5);
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
// endregion
|
|
1249
|
+
}
|