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.
- 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 +224 -48
- 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,816 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @brief NumKong C++ Benchmark Suite using Google Benchmark - Header file.
|
|
3
|
+
* @file bench/bench.hpp
|
|
4
|
+
* @author Ash Vardanian
|
|
5
|
+
* @date March 14, 2023
|
|
6
|
+
*
|
|
7
|
+
* Comprehensive benchmarks for NumKong SIMD-optimized functions measuring
|
|
8
|
+
* throughput performance. This header contains measurement infrastructure
|
|
9
|
+
* and helper templates used across multiple benchmark files.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
#pragma once
|
|
13
|
+
|
|
14
|
+
#include <algorithm> // `std::min`, `std::max`
|
|
15
|
+
#include <bit> // `std::bit_floor`
|
|
16
|
+
#include <random> // `std::mt19937`
|
|
17
|
+
#include <string> // `std::string`, `std::to_string`
|
|
18
|
+
#include <vector> // `std::vector`
|
|
19
|
+
|
|
20
|
+
#include <benchmark/benchmark.h>
|
|
21
|
+
|
|
22
|
+
#if !defined(NK_ALLOW_ISA_REDIRECT)
|
|
23
|
+
#define NK_ALLOW_ISA_REDIRECT 0
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
#if !defined(NK_COMPARE_TO_MKL)
|
|
27
|
+
#define NK_COMPARE_TO_MKL 0
|
|
28
|
+
#endif
|
|
29
|
+
#if !defined(NK_COMPARE_TO_BLAS)
|
|
30
|
+
#define NK_COMPARE_TO_BLAS 0
|
|
31
|
+
#endif
|
|
32
|
+
#if !defined(NK_COMPARE_TO_ACCELERATE)
|
|
33
|
+
#define NK_COMPARE_TO_ACCELERATE 0
|
|
34
|
+
#endif
|
|
35
|
+
|
|
36
|
+
#if NK_COMPARE_TO_MKL
|
|
37
|
+
#include <mkl.h>
|
|
38
|
+
// MKL provides additional GEMM routines:
|
|
39
|
+
// - cblas_gemm_bf16bf16f32: BF16 inputs -> F32 output
|
|
40
|
+
// - cblas_hgemm: F16 GEMM (if available)
|
|
41
|
+
#elif NK_COMPARE_TO_ACCELERATE
|
|
42
|
+
#include <Accelerate/Accelerate.h> // Apple Accelerate framework
|
|
43
|
+
#elif NK_COMPARE_TO_BLAS
|
|
44
|
+
#include <cblas.h> // Generic CBLAS (OpenBLAS, etc.)
|
|
45
|
+
// OpenBLAS thread control (weak symbol to avoid link errors if not present)
|
|
46
|
+
extern "C" void openblas_set_num_threads(int) __attribute__((weak));
|
|
47
|
+
#endif
|
|
48
|
+
|
|
49
|
+
#include "numkong/types.hpp"
|
|
50
|
+
#include "numkong/tensor.hpp"
|
|
51
|
+
#include "numkong/random.hpp"
|
|
52
|
+
|
|
53
|
+
namespace bm = benchmark;
|
|
54
|
+
namespace nk = ashvardanian::numkong;
|
|
55
|
+
|
|
56
|
+
struct bench_config_t {
|
|
57
|
+
/** Vector dimension for dot products and spatial metrics. Override: `NK_DENSE_DIMENSIONS`. */
|
|
58
|
+
std::size_t dense_dimensions = 1536;
|
|
59
|
+
/** Curved metric dimensions (quadratic impact). Override: `NK_CURVED_DIMENSIONS`. */
|
|
60
|
+
std::size_t curved_dimensions = 64;
|
|
61
|
+
/** Number of 3D points for mesh metrics (RMSD, Kabsch). Override: `NK_MESH_POINTS`. */
|
|
62
|
+
std::size_t mesh_points = 1000;
|
|
63
|
+
/** GEMM M dimension. Override: `NK_MATRIX_HEIGHT`. */
|
|
64
|
+
std::size_t matrix_height = 1024;
|
|
65
|
+
/** GEMM N dimension. Override: `NK_MATRIX_WIDTH`. */
|
|
66
|
+
std::size_t matrix_width = 128;
|
|
67
|
+
/** GEMM K dimension. Override: `NK_MATRIX_DEPTH`. */
|
|
68
|
+
std::size_t matrix_depth = 1536;
|
|
69
|
+
/** Random seed for reproducible benchmarks. Override: `NK_SEED`. */
|
|
70
|
+
std::uint32_t seed = 42;
|
|
71
|
+
/** First sparse set size. Override: `NK_SPARSE_FIRST_LENGTH`. */
|
|
72
|
+
std::size_t sparse_first_length = 1024;
|
|
73
|
+
/** Second sparse set size. Override: `NK_SPARSE_SECOND_LENGTH`. */
|
|
74
|
+
std::size_t sparse_second_length = 8192;
|
|
75
|
+
/** Sparse intersection share [0.0, 1.0]. Override: `NK_SPARSE_INTERSECTION`. */
|
|
76
|
+
double sparse_intersection_share = 0.5;
|
|
77
|
+
/** Max angular separation in degrees for geospatial benchmarks. Override: `NK_MAX_COORD_ANGLE`. */
|
|
78
|
+
float max_coord_angle = 180.0f;
|
|
79
|
+
/** Memory budget in bytes for pre-allocated inputs. Override: `NK_BUDGET_MB`. */
|
|
80
|
+
#if defined(__wasi__)
|
|
81
|
+
std::size_t budget_bytes = std::size_t(32) * 1024 * 1024;
|
|
82
|
+
#else
|
|
83
|
+
std::size_t budget_bytes = std::size_t(1024) * 1024 * 1024;
|
|
84
|
+
#endif
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
extern bench_config_t bench_config;
|
|
88
|
+
|
|
89
|
+
inline std::mt19937 make_random_engine() { return std::mt19937(bench_config.seed); }
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @brief Compute byte count for `count` elements of `dtype`, handling sub-byte and complex types.
|
|
93
|
+
*
|
|
94
|
+
* Uses `nk_dtype_bits` to get the correct bits per element, then rounds up to whole bytes.
|
|
95
|
+
*/
|
|
96
|
+
inline std::size_t bench_dtype_bytes(nk_dtype_t dtype, std::size_t count) {
|
|
97
|
+
return nk::divide_round_up(count * nk_dtype_bits(dtype), std::size_t(NK_BITS_PER_BYTE));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @brief Compute the number of pre-allocated input sets that fit within `bench_budget`.
|
|
102
|
+
*
|
|
103
|
+
* Returns a power-of-two count in [1, 1024] so the benchmark loop can use
|
|
104
|
+
* `iterations & (count - 1)` as a fast modulo for input cycling.
|
|
105
|
+
*/
|
|
106
|
+
inline std::size_t bench_input_count(std::size_t bytes_per_set) {
|
|
107
|
+
std::size_t count = bench_config.budget_bytes / std::max(bytes_per_set, std::size_t(1));
|
|
108
|
+
count = std::min(count, std::size_t(1024));
|
|
109
|
+
count = std::max(std::bit_floor(count), std::size_t(1));
|
|
110
|
+
return count;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** @brief Factory function to allocate vectors, potentially raising bad-allocs. */
|
|
114
|
+
template <typename type_>
|
|
115
|
+
[[nodiscard]] nk::vector<type_> make_vector(std::size_t count) {
|
|
116
|
+
auto result = nk::vector<type_>::try_zeros(count);
|
|
117
|
+
#if defined(__cpp_exceptions) && __cpp_exceptions
|
|
118
|
+
if (result.empty() && count > 0) throw std::bad_alloc();
|
|
119
|
+
#else
|
|
120
|
+
if (result.empty() && count > 0) std::abort();
|
|
121
|
+
#endif
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @brief Factory function to allocate matrix buffers with correct size for sub-byte types.
|
|
127
|
+
*
|
|
128
|
+
* For sub-byte types (u4, i4, u1), calculates the actual number of raw_t elements needed
|
|
129
|
+
* to store a matrix of logical dimensions rows x cols.
|
|
130
|
+
*
|
|
131
|
+
* @tparam dtype_ The NumKong dtype (e.g., nk_u4_k, nk_i4_k)
|
|
132
|
+
* @param rows Number of logical rows
|
|
133
|
+
* @param cols Number of logical columns per row
|
|
134
|
+
* @return Vector with correct byte capacity for the matrix
|
|
135
|
+
*/
|
|
136
|
+
template <nk_dtype_t dtype_>
|
|
137
|
+
[[nodiscard]] nk::vector<typename nk::type_for<dtype_>::type> make_vector_for_matrix(std::size_t rows,
|
|
138
|
+
std::size_t cols) {
|
|
139
|
+
using type_ = typename nk::type_for<dtype_>::type;
|
|
140
|
+
using raw_t = typename type_::raw_t;
|
|
141
|
+
|
|
142
|
+
nk_size_t bits_per_element = nk_dtype_bits(dtype_);
|
|
143
|
+
nk_size_t bits_per_row = cols * bits_per_element;
|
|
144
|
+
nk_size_t bytes_per_row = nk::divide_round_up(bits_per_row, NK_BITS_PER_BYTE);
|
|
145
|
+
nk_size_t total_values = rows * bytes_per_row / sizeof(raw_t);
|
|
146
|
+
|
|
147
|
+
std::size_t total_dims = total_values * nk::dimensions_per_value<type_>();
|
|
148
|
+
auto result = nk::vector<type_>::try_zeros(total_dims);
|
|
149
|
+
#if defined(__cpp_exceptions) && __cpp_exceptions
|
|
150
|
+
if (result.empty() && total_dims > 0) throw std::bad_alloc();
|
|
151
|
+
#else
|
|
152
|
+
if (result.empty() && total_dims > 0) std::abort();
|
|
153
|
+
#endif
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @brief Measures the performance of a @b dense kernel function using Google Benchmark.
|
|
159
|
+
*
|
|
160
|
+
* Used by: bench_dot.cpp, bench_spatial.cpp, bench_set.cpp, bench_probability.cpp
|
|
161
|
+
*
|
|
162
|
+
* @param state The benchmark state object provided by Google Benchmark.
|
|
163
|
+
* @param kernel The kernel function to benchmark.
|
|
164
|
+
* @param dimensions The number of dimensions in the vectors.
|
|
165
|
+
*/
|
|
166
|
+
template <nk_dtype_t input_dtype_, nk_dtype_t output_dtype_, typename kernel_type_ = void>
|
|
167
|
+
void measure_dense(bm::State &state, kernel_type_ kernel, std::size_t dimensions) {
|
|
168
|
+
|
|
169
|
+
using input_t = typename nk::type_for<input_dtype_>::type;
|
|
170
|
+
using output_t = typename nk::type_for<output_dtype_>::type;
|
|
171
|
+
using input_vector_t = nk::vector<input_t>;
|
|
172
|
+
|
|
173
|
+
// Preallocate inputs: enough vector pairs to fit within bench_budget
|
|
174
|
+
std::size_t const vectors_count = bench_input_count(2 * bench_dtype_bytes(input_dtype_, dimensions));
|
|
175
|
+
std::vector<input_vector_t> first_vectors(vectors_count), second_vectors(vectors_count);
|
|
176
|
+
auto generator = make_random_engine();
|
|
177
|
+
for (std::size_t index = 0; index != vectors_count; ++index) {
|
|
178
|
+
first_vectors[index] = make_vector<input_t>(dimensions);
|
|
179
|
+
second_vectors[index] = make_vector<input_t>(dimensions);
|
|
180
|
+
nk::fill_uniform(generator, first_vectors[index].values_data(), first_vectors[index].size_values());
|
|
181
|
+
nk::fill_uniform(generator, second_vectors[index].values_data(), second_vectors[index].size_values());
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Benchmark loop
|
|
185
|
+
std::size_t iterations = 0;
|
|
186
|
+
for (auto _ : state) {
|
|
187
|
+
output_t output;
|
|
188
|
+
std::size_t const index = iterations & (vectors_count - 1);
|
|
189
|
+
kernel(first_vectors[index].raw_values_data(), second_vectors[index].raw_values_data(), dimensions,
|
|
190
|
+
&output.raw_);
|
|
191
|
+
bm::DoNotOptimize(output);
|
|
192
|
+
iterations++;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
state.counters["bytes"] = bm::Counter(2.0 * iterations * first_vectors[0].size_bytes(), bm::Counter::kIsRate);
|
|
196
|
+
state.counters["calls"] = bm::Counter(iterations, bm::Counter::kIsRate);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
template <nk_dtype_t input_dtype_, nk_dtype_t output_dtype_, typename kernel_type_ = void>
|
|
200
|
+
void run_dense(std::string name, kernel_type_ *kernel) {
|
|
201
|
+
std::string bench_name = name + "<" + std::to_string(bench_config.dense_dimensions) + "d>";
|
|
202
|
+
bm::RegisterBenchmark(bench_name.c_str(), measure_dense<input_dtype_, output_dtype_, kernel_type_ *>, kernel,
|
|
203
|
+
bench_config.dense_dimensions);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Batched dot products measurement for packed B matrix API
|
|
207
|
+
// Used by: all bench_cross_*.cpp files
|
|
208
|
+
template <nk_dtype_t input_dtype_>
|
|
209
|
+
void measure_dots_packed( //
|
|
210
|
+
bm::State &state, //
|
|
211
|
+
typename nk::type_for<input_dtype_>::type::dots_packed_size_kernel_t packed_size_fn, //
|
|
212
|
+
typename nk::type_for<input_dtype_>::type::dots_pack_kernel_t pack_fn, //
|
|
213
|
+
typename nk::type_for<input_dtype_>::type::dots_packed_kernel_t kernel, //
|
|
214
|
+
std::size_t m, std::size_t n, std::size_t k) {
|
|
215
|
+
|
|
216
|
+
using input_t = typename nk::type_for<input_dtype_>::type;
|
|
217
|
+
using output_t = typename input_t::dot_result_t;
|
|
218
|
+
using raw_input_t = typename input_t::raw_t;
|
|
219
|
+
using raw_output_t = typename output_t::raw_t;
|
|
220
|
+
|
|
221
|
+
// Calculate correct strides for sub-byte types (u4, i4, u1, etc.)
|
|
222
|
+
nk_size_t values_per_row = nk::divide_round_up(k, nk::dimensions_per_value<input_t>());
|
|
223
|
+
nk_size_t a_stride_bytes = values_per_row * sizeof(typename input_t::raw_t);
|
|
224
|
+
nk_size_t b_stride_bytes = values_per_row * sizeof(typename input_t::raw_t); // B is n x k, so k columns per row
|
|
225
|
+
nk_size_t packed_bytes = packed_size_fn(n, k);
|
|
226
|
+
|
|
227
|
+
// Preallocate multiple input sets within bench_budget for input diversity
|
|
228
|
+
std::size_t bytes_per_set = m * a_stride_bytes + n * b_stride_bytes + packed_bytes + m * n * sizeof(raw_output_t);
|
|
229
|
+
std::size_t const sets_count = bench_input_count(bytes_per_set);
|
|
230
|
+
|
|
231
|
+
struct gemm_set_t {
|
|
232
|
+
nk::vector<input_t> a, b;
|
|
233
|
+
std::vector<char> b_packed;
|
|
234
|
+
nk::vector<output_t> c;
|
|
235
|
+
};
|
|
236
|
+
std::vector<gemm_set_t> sets(sets_count);
|
|
237
|
+
auto generator = make_random_engine();
|
|
238
|
+
for (auto &s : sets) {
|
|
239
|
+
s.a = make_vector_for_matrix<input_dtype_>(m, k);
|
|
240
|
+
s.b = make_vector_for_matrix<input_dtype_>(n, k);
|
|
241
|
+
s.b_packed.resize(packed_bytes, 0);
|
|
242
|
+
s.c = make_vector<output_t>(m * n);
|
|
243
|
+
nk::fill_uniform(generator, s.a.values_data(), s.a.size_values());
|
|
244
|
+
nk::fill_uniform(generator, s.b.values_data(), s.b.size_values());
|
|
245
|
+
pack_fn(s.b.raw_values_data(), n, k, b_stride_bytes, s.b_packed.data());
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
std::size_t iterations = 0;
|
|
249
|
+
for (auto _ : state) {
|
|
250
|
+
auto &s = sets[iterations & (sets_count - 1)];
|
|
251
|
+
bm::DoNotOptimize(s.c.raw_values_data());
|
|
252
|
+
kernel(s.a.raw_values_data(), s.b_packed.data(), s.c.raw_values_data(), //
|
|
253
|
+
m, n, k, a_stride_bytes, n * sizeof(raw_output_t));
|
|
254
|
+
++iterations;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
state.counters["scalar-ops"] = bm::Counter(2.0 * iterations * m * n * k, bm::Counter::kIsRate);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
template <nk_dtype_t input_dtype_>
|
|
261
|
+
void run_dots_packed(std::string name, //
|
|
262
|
+
typename nk::type_for<input_dtype_>::type::dots_packed_size_kernel_t packed_size_fn,
|
|
263
|
+
typename nk::type_for<input_dtype_>::type::dots_pack_kernel_t pack_fn,
|
|
264
|
+
typename nk::type_for<input_dtype_>::type::dots_packed_kernel_t kernel) {
|
|
265
|
+
std::string bench_name = name + "<" + std::to_string(bench_config.matrix_height) + "x" +
|
|
266
|
+
std::to_string(bench_config.matrix_width) + "x" +
|
|
267
|
+
std::to_string(bench_config.matrix_depth) + ">";
|
|
268
|
+
bm::RegisterBenchmark(bench_name.c_str(), measure_dots_packed<input_dtype_>, packed_size_fn, pack_fn, kernel,
|
|
269
|
+
bench_config.matrix_height, bench_config.matrix_width, bench_config.matrix_depth);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
template <nk_dtype_t input_dtype_>
|
|
273
|
+
void measure_angulars_packed( //
|
|
274
|
+
bm::State &state, //
|
|
275
|
+
typename nk::type_for<input_dtype_>::type::dots_packed_size_kernel_t packed_size_fn, //
|
|
276
|
+
typename nk::type_for<input_dtype_>::type::dots_pack_kernel_t pack_fn, //
|
|
277
|
+
typename nk::type_for<input_dtype_>::type::angulars_packed_kernel_t kernel, //
|
|
278
|
+
std::size_t m, std::size_t n, std::size_t k) {
|
|
279
|
+
|
|
280
|
+
using input_t = typename nk::type_for<input_dtype_>::type;
|
|
281
|
+
using output_t = typename input_t::angular_result_t;
|
|
282
|
+
using raw_input_t = typename input_t::raw_t;
|
|
283
|
+
using raw_output_t = typename output_t::raw_t;
|
|
284
|
+
|
|
285
|
+
nk_size_t values_per_row = nk::divide_round_up(k, nk::dimensions_per_value<input_t>());
|
|
286
|
+
nk_size_t a_stride_bytes = values_per_row * sizeof(typename input_t::raw_t);
|
|
287
|
+
nk_size_t b_stride_bytes = values_per_row * sizeof(typename input_t::raw_t);
|
|
288
|
+
nk_size_t packed_bytes = packed_size_fn(n, k);
|
|
289
|
+
|
|
290
|
+
std::size_t bytes_per_set = m * a_stride_bytes + n * b_stride_bytes + packed_bytes + m * n * sizeof(raw_output_t);
|
|
291
|
+
std::size_t const sets_count = bench_input_count(bytes_per_set);
|
|
292
|
+
|
|
293
|
+
struct gemm_set_t {
|
|
294
|
+
nk::vector<input_t> a, b;
|
|
295
|
+
std::vector<char> b_packed;
|
|
296
|
+
nk::vector<output_t> c;
|
|
297
|
+
};
|
|
298
|
+
std::vector<gemm_set_t> sets(sets_count);
|
|
299
|
+
auto generator = make_random_engine();
|
|
300
|
+
for (auto &s : sets) {
|
|
301
|
+
s.a = make_vector_for_matrix<input_dtype_>(m, k);
|
|
302
|
+
s.b = make_vector_for_matrix<input_dtype_>(n, k);
|
|
303
|
+
s.b_packed.resize(packed_bytes, 0);
|
|
304
|
+
s.c = make_vector<output_t>(m * n);
|
|
305
|
+
nk::fill_uniform(generator, s.a.values_data(), s.a.size_values());
|
|
306
|
+
nk::fill_uniform(generator, s.b.values_data(), s.b.size_values());
|
|
307
|
+
pack_fn(s.b.raw_values_data(), n, k, b_stride_bytes, s.b_packed.data());
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
std::size_t iterations = 0;
|
|
311
|
+
for (auto _ : state) {
|
|
312
|
+
auto &s = sets[iterations & (sets_count - 1)];
|
|
313
|
+
bm::DoNotOptimize(s.c.raw_values_data());
|
|
314
|
+
kernel(s.a.raw_values_data(), s.b_packed.data(), s.c.raw_values_data(), //
|
|
315
|
+
m, n, k, a_stride_bytes, n * sizeof(raw_output_t));
|
|
316
|
+
++iterations;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
state.counters["scalar-ops"] = bm::Counter(2.0 * iterations * m * n * k, bm::Counter::kIsRate);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
template <nk_dtype_t input_dtype_>
|
|
323
|
+
void run_angulars_packed(std::string name, //
|
|
324
|
+
typename nk::type_for<input_dtype_>::type::dots_packed_size_kernel_t packed_size_fn,
|
|
325
|
+
typename nk::type_for<input_dtype_>::type::dots_pack_kernel_t pack_fn,
|
|
326
|
+
typename nk::type_for<input_dtype_>::type::angulars_packed_kernel_t kernel) {
|
|
327
|
+
std::string bench_name = name + "<" + std::to_string(bench_config.matrix_height) + "x" +
|
|
328
|
+
std::to_string(bench_config.matrix_width) + "x" +
|
|
329
|
+
std::to_string(bench_config.matrix_depth) + ">";
|
|
330
|
+
bm::RegisterBenchmark(bench_name.c_str(), measure_angulars_packed<input_dtype_>, packed_size_fn, pack_fn, kernel,
|
|
331
|
+
bench_config.matrix_height, bench_config.matrix_width, bench_config.matrix_depth);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
template <nk_dtype_t input_dtype_>
|
|
335
|
+
void measure_euclideans_packed( //
|
|
336
|
+
bm::State &state, //
|
|
337
|
+
typename nk::type_for<input_dtype_>::type::dots_packed_size_kernel_t packed_size_fn, //
|
|
338
|
+
typename nk::type_for<input_dtype_>::type::dots_pack_kernel_t pack_fn, //
|
|
339
|
+
typename nk::type_for<input_dtype_>::type::euclideans_packed_kernel_t kernel, //
|
|
340
|
+
std::size_t m, std::size_t n, std::size_t k) {
|
|
341
|
+
|
|
342
|
+
using input_t = typename nk::type_for<input_dtype_>::type;
|
|
343
|
+
using output_t = typename input_t::euclidean_result_t;
|
|
344
|
+
using raw_input_t = typename input_t::raw_t;
|
|
345
|
+
using raw_output_t = typename output_t::raw_t;
|
|
346
|
+
|
|
347
|
+
nk_size_t values_per_row = nk::divide_round_up(k, nk::dimensions_per_value<input_t>());
|
|
348
|
+
nk_size_t a_stride_bytes = values_per_row * sizeof(typename input_t::raw_t);
|
|
349
|
+
nk_size_t b_stride_bytes = values_per_row * sizeof(typename input_t::raw_t);
|
|
350
|
+
nk_size_t packed_bytes = packed_size_fn(n, k);
|
|
351
|
+
|
|
352
|
+
std::size_t bytes_per_set = m * a_stride_bytes + n * b_stride_bytes + packed_bytes + m * n * sizeof(raw_output_t);
|
|
353
|
+
std::size_t const sets_count = bench_input_count(bytes_per_set);
|
|
354
|
+
|
|
355
|
+
struct gemm_set_t {
|
|
356
|
+
nk::vector<input_t> a, b;
|
|
357
|
+
std::vector<char> b_packed;
|
|
358
|
+
nk::vector<output_t> c;
|
|
359
|
+
};
|
|
360
|
+
std::vector<gemm_set_t> sets(sets_count);
|
|
361
|
+
auto generator = make_random_engine();
|
|
362
|
+
for (auto &s : sets) {
|
|
363
|
+
s.a = make_vector_for_matrix<input_dtype_>(m, k);
|
|
364
|
+
s.b = make_vector_for_matrix<input_dtype_>(n, k);
|
|
365
|
+
s.b_packed.resize(packed_bytes, 0);
|
|
366
|
+
s.c = make_vector<output_t>(m * n);
|
|
367
|
+
nk::fill_uniform(generator, s.a.values_data(), s.a.size_values());
|
|
368
|
+
nk::fill_uniform(generator, s.b.values_data(), s.b.size_values());
|
|
369
|
+
pack_fn(s.b.raw_values_data(), n, k, b_stride_bytes, s.b_packed.data());
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
std::size_t iterations = 0;
|
|
373
|
+
for (auto _ : state) {
|
|
374
|
+
auto &s = sets[iterations & (sets_count - 1)];
|
|
375
|
+
bm::DoNotOptimize(s.c.raw_values_data());
|
|
376
|
+
kernel(s.a.raw_values_data(), s.b_packed.data(), s.c.raw_values_data(), //
|
|
377
|
+
m, n, k, a_stride_bytes, n * sizeof(raw_output_t));
|
|
378
|
+
++iterations;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
state.counters["scalar-ops"] = bm::Counter(2.0 * iterations * m * n * k, bm::Counter::kIsRate);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
template <nk_dtype_t input_dtype_>
|
|
385
|
+
void run_euclideans_packed(std::string name, //
|
|
386
|
+
typename nk::type_for<input_dtype_>::type::dots_packed_size_kernel_t packed_size_fn,
|
|
387
|
+
typename nk::type_for<input_dtype_>::type::dots_pack_kernel_t pack_fn,
|
|
388
|
+
typename nk::type_for<input_dtype_>::type::euclideans_packed_kernel_t kernel) {
|
|
389
|
+
std::string bench_name = name + "<" + std::to_string(bench_config.matrix_height) + "x" +
|
|
390
|
+
std::to_string(bench_config.matrix_width) + "x" +
|
|
391
|
+
std::to_string(bench_config.matrix_depth) + ">";
|
|
392
|
+
bm::RegisterBenchmark(bench_name.c_str(), measure_euclideans_packed<input_dtype_>, packed_size_fn, pack_fn, kernel,
|
|
393
|
+
bench_config.matrix_height, bench_config.matrix_width, bench_config.matrix_depth);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
template <nk_dtype_t input_dtype_>
|
|
397
|
+
void measure_dots_symmetric( //
|
|
398
|
+
bm::State &state, //
|
|
399
|
+
typename nk::type_for<input_dtype_>::type::dots_symmetric_kernel_t kernel, //
|
|
400
|
+
std::size_t n, std::size_t k) {
|
|
401
|
+
|
|
402
|
+
using input_t = typename nk::type_for<input_dtype_>::type;
|
|
403
|
+
using output_t = typename input_t::dot_result_t;
|
|
404
|
+
using raw_input_t = typename input_t::raw_t;
|
|
405
|
+
using raw_output_t = typename output_t::raw_t;
|
|
406
|
+
|
|
407
|
+
// Calculate correct strides for sub-byte types (u4, i4, u1, etc.)
|
|
408
|
+
nk_size_t input_values_per_row = nk::divide_round_up(k, nk::dimensions_per_value<input_t>());
|
|
409
|
+
nk_size_t input_stride_bytes = input_values_per_row * sizeof(typename input_t::raw_t);
|
|
410
|
+
nk_size_t output_stride_bytes = n * sizeof(raw_output_t);
|
|
411
|
+
|
|
412
|
+
// Preallocate multiple input sets within bench_budget
|
|
413
|
+
std::size_t bytes_per_set = n * input_stride_bytes + n * n * sizeof(raw_output_t);
|
|
414
|
+
std::size_t const sets_count = bench_input_count(bytes_per_set);
|
|
415
|
+
|
|
416
|
+
struct syrk_set_t {
|
|
417
|
+
nk::vector<input_t> a;
|
|
418
|
+
nk::vector<output_t> c;
|
|
419
|
+
};
|
|
420
|
+
std::vector<syrk_set_t> sets(sets_count);
|
|
421
|
+
auto generator = make_random_engine();
|
|
422
|
+
for (auto &s : sets) {
|
|
423
|
+
s.a = make_vector_for_matrix<input_dtype_>(n, k);
|
|
424
|
+
s.c = make_vector<output_t>(n * n);
|
|
425
|
+
nk::fill_uniform(generator, s.a.values_data(), s.a.size_values());
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
std::size_t iterations = 0;
|
|
429
|
+
for (auto _ : state) {
|
|
430
|
+
auto &s = sets[iterations & (sets_count - 1)];
|
|
431
|
+
bm::DoNotOptimize(s.c.raw_values_data());
|
|
432
|
+
kernel(s.a.raw_values_data(), n, k, input_stride_bytes, //
|
|
433
|
+
s.c.raw_values_data(), output_stride_bytes, 0, n);
|
|
434
|
+
++iterations;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
state.counters["scalar-ops"] = bm::Counter(1.0 * iterations * n * (n + 1) * k, bm::Counter::kIsRate);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
template <nk_dtype_t input_dtype_>
|
|
441
|
+
void run_dots_symmetric(std::string name, //
|
|
442
|
+
typename nk::type_for<input_dtype_>::type::dots_symmetric_kernel_t kernel) {
|
|
443
|
+
std::string bench_name = name + "<" + std::to_string(bench_config.matrix_height) + "x" +
|
|
444
|
+
std::to_string(bench_config.matrix_depth) + ">";
|
|
445
|
+
bm::RegisterBenchmark(bench_name.c_str(), measure_dots_symmetric<input_dtype_>, //
|
|
446
|
+
kernel, bench_config.matrix_height, bench_config.matrix_depth);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
template <nk_dtype_t input_dtype_>
|
|
450
|
+
void measure_angulars_symmetric( //
|
|
451
|
+
bm::State &state, //
|
|
452
|
+
typename nk::type_for<input_dtype_>::type::angulars_symmetric_kernel_t kernel, //
|
|
453
|
+
std::size_t n, std::size_t k) {
|
|
454
|
+
|
|
455
|
+
using input_t = typename nk::type_for<input_dtype_>::type;
|
|
456
|
+
using output_t = typename input_t::angular_result_t;
|
|
457
|
+
using raw_input_t = typename input_t::raw_t;
|
|
458
|
+
using raw_output_t = typename output_t::raw_t;
|
|
459
|
+
|
|
460
|
+
nk_size_t input_values_per_row = nk::divide_round_up(k, nk::dimensions_per_value<input_t>());
|
|
461
|
+
nk_size_t input_stride_bytes = input_values_per_row * sizeof(typename input_t::raw_t);
|
|
462
|
+
nk_size_t output_stride_bytes = n * sizeof(raw_output_t);
|
|
463
|
+
|
|
464
|
+
std::size_t bytes_per_set = n * input_stride_bytes + n * n * sizeof(raw_output_t);
|
|
465
|
+
std::size_t const sets_count = bench_input_count(bytes_per_set);
|
|
466
|
+
|
|
467
|
+
struct syrk_set_t {
|
|
468
|
+
nk::vector<input_t> a;
|
|
469
|
+
nk::vector<output_t> c;
|
|
470
|
+
};
|
|
471
|
+
std::vector<syrk_set_t> sets(sets_count);
|
|
472
|
+
auto generator = make_random_engine();
|
|
473
|
+
for (auto &s : sets) {
|
|
474
|
+
s.a = make_vector_for_matrix<input_dtype_>(n, k);
|
|
475
|
+
s.c = make_vector<output_t>(n * n);
|
|
476
|
+
nk::fill_uniform(generator, s.a.values_data(), s.a.size_values());
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
std::size_t iterations = 0;
|
|
480
|
+
for (auto _ : state) {
|
|
481
|
+
auto &s = sets[iterations & (sets_count - 1)];
|
|
482
|
+
bm::DoNotOptimize(s.c.raw_values_data());
|
|
483
|
+
kernel(s.a.raw_values_data(), n, k, input_stride_bytes, //
|
|
484
|
+
s.c.raw_values_data(), output_stride_bytes, 0, n);
|
|
485
|
+
++iterations;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
state.counters["scalar-ops"] = bm::Counter(1.0 * iterations * n * (n + 1) * k, bm::Counter::kIsRate);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
template <nk_dtype_t input_dtype_>
|
|
492
|
+
void run_angulars_symmetric(std::string name, //
|
|
493
|
+
typename nk::type_for<input_dtype_>::type::angulars_symmetric_kernel_t kernel) {
|
|
494
|
+
std::string bench_name = name + "<" + std::to_string(bench_config.matrix_height) + "x" +
|
|
495
|
+
std::to_string(bench_config.matrix_depth) + ">";
|
|
496
|
+
bm::RegisterBenchmark(bench_name.c_str(), measure_angulars_symmetric<input_dtype_>, //
|
|
497
|
+
kernel, bench_config.matrix_height, bench_config.matrix_depth);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
template <nk_dtype_t input_dtype_>
|
|
501
|
+
void measure_euclideans_symmetric( //
|
|
502
|
+
bm::State &state, //
|
|
503
|
+
typename nk::type_for<input_dtype_>::type::euclideans_symmetric_kernel_t kernel, //
|
|
504
|
+
std::size_t n, std::size_t k) {
|
|
505
|
+
|
|
506
|
+
using input_t = typename nk::type_for<input_dtype_>::type;
|
|
507
|
+
using output_t = typename input_t::euclidean_result_t;
|
|
508
|
+
using raw_input_t = typename input_t::raw_t;
|
|
509
|
+
using raw_output_t = typename output_t::raw_t;
|
|
510
|
+
|
|
511
|
+
nk_size_t input_values_per_row = nk::divide_round_up(k, nk::dimensions_per_value<input_t>());
|
|
512
|
+
nk_size_t input_stride_bytes = input_values_per_row * sizeof(typename input_t::raw_t);
|
|
513
|
+
nk_size_t output_stride_bytes = n * sizeof(raw_output_t);
|
|
514
|
+
|
|
515
|
+
std::size_t bytes_per_set = n * input_stride_bytes + n * n * sizeof(raw_output_t);
|
|
516
|
+
std::size_t const sets_count = bench_input_count(bytes_per_set);
|
|
517
|
+
|
|
518
|
+
struct syrk_set_t {
|
|
519
|
+
nk::vector<input_t> a;
|
|
520
|
+
nk::vector<output_t> c;
|
|
521
|
+
};
|
|
522
|
+
std::vector<syrk_set_t> sets(sets_count);
|
|
523
|
+
auto generator = make_random_engine();
|
|
524
|
+
for (auto &s : sets) {
|
|
525
|
+
s.a = make_vector_for_matrix<input_dtype_>(n, k);
|
|
526
|
+
s.c = make_vector<output_t>(n * n);
|
|
527
|
+
nk::fill_uniform(generator, s.a.values_data(), s.a.size_values());
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
std::size_t iterations = 0;
|
|
531
|
+
for (auto _ : state) {
|
|
532
|
+
auto &s = sets[iterations & (sets_count - 1)];
|
|
533
|
+
bm::DoNotOptimize(s.c.raw_values_data());
|
|
534
|
+
kernel(s.a.raw_values_data(), n, k, input_stride_bytes, //
|
|
535
|
+
s.c.raw_values_data(), output_stride_bytes, 0, n);
|
|
536
|
+
++iterations;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
state.counters["scalar-ops"] = bm::Counter(1.0 * iterations * n * (n + 1) * k, bm::Counter::kIsRate);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
template <nk_dtype_t input_dtype_>
|
|
543
|
+
void run_euclideans_symmetric(std::string name, //
|
|
544
|
+
typename nk::type_for<input_dtype_>::type::euclideans_symmetric_kernel_t kernel) {
|
|
545
|
+
std::string bench_name = name + "<" + std::to_string(bench_config.matrix_height) + "x" +
|
|
546
|
+
std::to_string(bench_config.matrix_depth) + ">";
|
|
547
|
+
bm::RegisterBenchmark(bench_name.c_str(), measure_euclideans_symmetric<input_dtype_>, //
|
|
548
|
+
kernel, bench_config.matrix_height, bench_config.matrix_depth);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* @brief Measure packed Hamming distance computation.
|
|
553
|
+
* Used by: all bench_cross_*.cpp files
|
|
554
|
+
*/
|
|
555
|
+
template <nk_dtype_t input_dtype_>
|
|
556
|
+
void measure_hammings_packed( //
|
|
557
|
+
bm::State &state, //
|
|
558
|
+
typename nk::type_for<input_dtype_>::type::hammings_packed_size_kernel_t packed_size_fn, //
|
|
559
|
+
typename nk::type_for<input_dtype_>::type::hammings_pack_kernel_t pack_fn, //
|
|
560
|
+
typename nk::type_for<input_dtype_>::type::hammings_packed_kernel_t kernel, //
|
|
561
|
+
std::size_t m, std::size_t n, std::size_t k) {
|
|
562
|
+
|
|
563
|
+
using input_t = typename nk::type_for<input_dtype_>::type;
|
|
564
|
+
using output_t = typename input_t::hamming_result_t;
|
|
565
|
+
using raw_input_t = typename input_t::raw_t;
|
|
566
|
+
using raw_output_t = typename output_t::raw_t;
|
|
567
|
+
|
|
568
|
+
// Calculate correct strides for binary data (k is in bits)
|
|
569
|
+
nk_size_t values_per_row = nk::divide_round_up(k, 8);
|
|
570
|
+
nk_size_t a_stride_bytes = values_per_row * sizeof(typename input_t::raw_t);
|
|
571
|
+
nk_size_t b_stride_bytes = values_per_row * sizeof(typename input_t::raw_t);
|
|
572
|
+
nk_size_t packed_bytes = packed_size_fn(n, k);
|
|
573
|
+
|
|
574
|
+
// Preallocate multiple input sets within bench_budget
|
|
575
|
+
std::size_t bytes_per_set = m * a_stride_bytes + n * b_stride_bytes + packed_bytes + m * n * sizeof(raw_output_t);
|
|
576
|
+
std::size_t const sets_count = bench_input_count(bytes_per_set);
|
|
577
|
+
|
|
578
|
+
struct hamming_set_t {
|
|
579
|
+
nk::vector<input_t> a, b;
|
|
580
|
+
std::vector<char> b_packed;
|
|
581
|
+
nk::vector<output_t> c;
|
|
582
|
+
};
|
|
583
|
+
std::vector<hamming_set_t> sets(sets_count);
|
|
584
|
+
auto generator = make_random_engine();
|
|
585
|
+
for (auto &s : sets) {
|
|
586
|
+
s.a = make_vector<input_t>(m * k);
|
|
587
|
+
s.b = make_vector<input_t>(n * k);
|
|
588
|
+
s.b_packed.resize(packed_bytes, 0);
|
|
589
|
+
s.c = make_vector<output_t>(m * n);
|
|
590
|
+
nk::fill_uniform(generator, s.a.values_data(), s.a.size_values());
|
|
591
|
+
nk::fill_uniform(generator, s.b.values_data(), s.b.size_values());
|
|
592
|
+
pack_fn(s.b.raw_values_data(), n, k, b_stride_bytes, s.b_packed.data());
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
std::size_t iterations = 0;
|
|
596
|
+
for (auto _ : state) {
|
|
597
|
+
auto &s = sets[iterations & (sets_count - 1)];
|
|
598
|
+
bm::DoNotOptimize(s.c.raw_values_data());
|
|
599
|
+
kernel(s.a.raw_values_data(), s.b_packed.data(), s.c.raw_values_data(), //
|
|
600
|
+
m, n, k, a_stride_bytes, n * sizeof(raw_output_t));
|
|
601
|
+
++iterations;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
state.counters["scalar-ops"] = bm::Counter(1.0 * iterations * m * n * k, bm::Counter::kIsRate);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* @brief Measure symmetric Hamming distance matrix computation.
|
|
609
|
+
*/
|
|
610
|
+
template <nk_dtype_t input_dtype_>
|
|
611
|
+
void measure_hammings_symmetric( //
|
|
612
|
+
bm::State &state, //
|
|
613
|
+
typename nk::type_for<input_dtype_>::type::hammings_symmetric_kernel_t kernel, //
|
|
614
|
+
std::size_t n, std::size_t k) {
|
|
615
|
+
|
|
616
|
+
using input_t = typename nk::type_for<input_dtype_>::type;
|
|
617
|
+
using output_t = typename input_t::hamming_result_t;
|
|
618
|
+
using raw_input_t = typename input_t::raw_t;
|
|
619
|
+
using raw_output_t = typename output_t::raw_t;
|
|
620
|
+
|
|
621
|
+
// Calculate correct strides for binary data (k is in bits)
|
|
622
|
+
nk_size_t input_values_per_row = nk::divide_round_up(k, 8);
|
|
623
|
+
nk_size_t input_stride_bytes = input_values_per_row * sizeof(typename input_t::raw_t);
|
|
624
|
+
nk_size_t output_stride_bytes = n * sizeof(raw_output_t);
|
|
625
|
+
|
|
626
|
+
// Preallocate multiple input sets within bench_budget
|
|
627
|
+
std::size_t bytes_per_set = n * input_stride_bytes + n * n * sizeof(raw_output_t);
|
|
628
|
+
std::size_t const sets_count = bench_input_count(bytes_per_set);
|
|
629
|
+
|
|
630
|
+
struct hamming_sym_set_t {
|
|
631
|
+
nk::vector<input_t> a;
|
|
632
|
+
nk::vector<output_t> c;
|
|
633
|
+
};
|
|
634
|
+
std::vector<hamming_sym_set_t> sets(sets_count);
|
|
635
|
+
auto generator = make_random_engine();
|
|
636
|
+
for (auto &s : sets) {
|
|
637
|
+
s.a = make_vector<input_t>(n * k);
|
|
638
|
+
s.c = make_vector<output_t>(n * n);
|
|
639
|
+
nk::fill_uniform(generator, s.a.values_data(), s.a.size_values());
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
std::size_t iterations = 0;
|
|
643
|
+
for (auto _ : state) {
|
|
644
|
+
auto &s = sets[iterations & (sets_count - 1)];
|
|
645
|
+
bm::DoNotOptimize(s.c.raw_values_data());
|
|
646
|
+
kernel(s.a.raw_values_data(), n, k, input_stride_bytes, //
|
|
647
|
+
s.c.raw_values_data(), output_stride_bytes, 0, n);
|
|
648
|
+
++iterations;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
state.counters["scalar-ops"] = bm::Counter(1.0 * iterations * n * (n + 1) * k / 2.0, bm::Counter::kIsRate);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
template <nk_dtype_t input_dtype_>
|
|
655
|
+
void run_hammings_packed(std::string name, //
|
|
656
|
+
typename nk::type_for<input_dtype_>::type::hammings_packed_size_kernel_t packed_size_fn,
|
|
657
|
+
typename nk::type_for<input_dtype_>::type::hammings_pack_kernel_t pack_fn,
|
|
658
|
+
typename nk::type_for<input_dtype_>::type::hammings_packed_kernel_t kernel) {
|
|
659
|
+
std::string bench_name = name + "<" + std::to_string(bench_config.matrix_height) + "x" +
|
|
660
|
+
std::to_string(bench_config.matrix_width) + "x" +
|
|
661
|
+
std::to_string(bench_config.matrix_depth) + ">";
|
|
662
|
+
bm::RegisterBenchmark(bench_name.c_str(), measure_hammings_packed<input_dtype_>, packed_size_fn, pack_fn, kernel,
|
|
663
|
+
bench_config.matrix_height, bench_config.matrix_width, bench_config.matrix_depth);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
template <nk_dtype_t input_dtype_>
|
|
667
|
+
void run_hammings_symmetric(std::string name, //
|
|
668
|
+
typename nk::type_for<input_dtype_>::type::hammings_symmetric_kernel_t kernel) {
|
|
669
|
+
std::string bench_name = name + "<" + std::to_string(bench_config.matrix_height) + "x" +
|
|
670
|
+
std::to_string(bench_config.matrix_depth) + ">";
|
|
671
|
+
bm::RegisterBenchmark(bench_name.c_str(), measure_hammings_symmetric<input_dtype_>, //
|
|
672
|
+
kernel, bench_config.matrix_height, bench_config.matrix_depth);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* @brief Measure packed Jaccard distance matrix computation.
|
|
677
|
+
*/
|
|
678
|
+
template <nk_dtype_t input_dtype_>
|
|
679
|
+
void measure_jaccards_packed( //
|
|
680
|
+
bm::State &state, //
|
|
681
|
+
typename nk::type_for<input_dtype_>::type::jaccards_packed_size_kernel_t packed_size_fn, //
|
|
682
|
+
typename nk::type_for<input_dtype_>::type::jaccards_pack_kernel_t pack_fn, //
|
|
683
|
+
typename nk::type_for<input_dtype_>::type::jaccards_packed_kernel_t kernel, //
|
|
684
|
+
std::size_t m, std::size_t n, std::size_t k) {
|
|
685
|
+
|
|
686
|
+
using input_t = typename nk::type_for<input_dtype_>::type;
|
|
687
|
+
using raw_input_t = typename input_t::raw_t;
|
|
688
|
+
|
|
689
|
+
nk_size_t values_per_row = nk::divide_round_up(k, 8);
|
|
690
|
+
nk_size_t a_stride_bytes = values_per_row * sizeof(typename input_t::raw_t);
|
|
691
|
+
nk_size_t b_stride_bytes = values_per_row * sizeof(typename input_t::raw_t);
|
|
692
|
+
nk_size_t packed_bytes = packed_size_fn(n, k);
|
|
693
|
+
|
|
694
|
+
std::size_t bytes_per_set = m * a_stride_bytes + n * b_stride_bytes + packed_bytes + m * n * sizeof(nk_f32_t);
|
|
695
|
+
std::size_t const sets_count = bench_input_count(bytes_per_set);
|
|
696
|
+
|
|
697
|
+
struct jaccards_set_t {
|
|
698
|
+
nk::vector<input_t> a, b;
|
|
699
|
+
std::vector<char> b_packed;
|
|
700
|
+
std::vector<nk_f32_t> c;
|
|
701
|
+
};
|
|
702
|
+
std::vector<jaccards_set_t> sets(sets_count);
|
|
703
|
+
auto generator = make_random_engine();
|
|
704
|
+
for (auto &s : sets) {
|
|
705
|
+
s.a = make_vector<input_t>(m * k);
|
|
706
|
+
s.b = make_vector<input_t>(n * k);
|
|
707
|
+
s.b_packed.resize(packed_bytes, 0);
|
|
708
|
+
s.c.resize(m * n, 0);
|
|
709
|
+
nk::fill_uniform(generator, s.a.values_data(), s.a.size_values());
|
|
710
|
+
nk::fill_uniform(generator, s.b.values_data(), s.b.size_values());
|
|
711
|
+
pack_fn(s.b.raw_values_data(), n, k, b_stride_bytes, s.b_packed.data());
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
std::size_t iterations = 0;
|
|
715
|
+
for (auto _ : state) {
|
|
716
|
+
auto &s = sets[iterations & (sets_count - 1)];
|
|
717
|
+
bm::DoNotOptimize(s.c.data());
|
|
718
|
+
kernel(s.a.raw_values_data(), s.b_packed.data(), s.c.data(), //
|
|
719
|
+
m, n, k, a_stride_bytes, n * sizeof(nk_f32_t));
|
|
720
|
+
++iterations;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
state.counters["scalar-ops"] = bm::Counter(1.0 * iterations * m * n * k, bm::Counter::kIsRate);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* @brief Measure symmetric Jaccard distance matrix computation.
|
|
728
|
+
*/
|
|
729
|
+
template <nk_dtype_t input_dtype_>
|
|
730
|
+
void measure_jaccards_symmetric( //
|
|
731
|
+
bm::State &state, //
|
|
732
|
+
typename nk::type_for<input_dtype_>::type::jaccards_symmetric_kernel_t kernel, //
|
|
733
|
+
std::size_t n, std::size_t k) {
|
|
734
|
+
|
|
735
|
+
using input_t = typename nk::type_for<input_dtype_>::type;
|
|
736
|
+
using raw_input_t = typename input_t::raw_t;
|
|
737
|
+
|
|
738
|
+
nk_size_t input_values_per_row = nk::divide_round_up(k, 8);
|
|
739
|
+
nk_size_t input_stride_bytes = input_values_per_row * sizeof(typename input_t::raw_t);
|
|
740
|
+
nk_size_t output_stride_bytes = n * sizeof(nk_f32_t);
|
|
741
|
+
|
|
742
|
+
std::size_t bytes_per_set = n * input_stride_bytes + n * n * sizeof(nk_f32_t);
|
|
743
|
+
std::size_t const sets_count = bench_input_count(bytes_per_set);
|
|
744
|
+
|
|
745
|
+
struct jaccards_sym_set_t {
|
|
746
|
+
nk::vector<input_t> a;
|
|
747
|
+
std::vector<nk_f32_t> c;
|
|
748
|
+
};
|
|
749
|
+
std::vector<jaccards_sym_set_t> sets(sets_count);
|
|
750
|
+
auto generator = make_random_engine();
|
|
751
|
+
for (auto &s : sets) {
|
|
752
|
+
s.a = make_vector<input_t>(n * k);
|
|
753
|
+
s.c.resize(n * n, 0);
|
|
754
|
+
nk::fill_uniform(generator, s.a.values_data(), s.a.size_values());
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
std::size_t iterations = 0;
|
|
758
|
+
for (auto _ : state) {
|
|
759
|
+
auto &s = sets[iterations & (sets_count - 1)];
|
|
760
|
+
bm::DoNotOptimize(s.c.data());
|
|
761
|
+
kernel(s.a.raw_values_data(), n, k, input_stride_bytes, //
|
|
762
|
+
s.c.data(), output_stride_bytes, 0, n);
|
|
763
|
+
++iterations;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
state.counters["scalar-ops"] = bm::Counter(1.0 * iterations * n * (n + 1) * k / 2.0, bm::Counter::kIsRate);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
template <nk_dtype_t input_dtype_>
|
|
770
|
+
void run_jaccards_packed(std::string name, //
|
|
771
|
+
typename nk::type_for<input_dtype_>::type::jaccards_packed_size_kernel_t packed_size_fn,
|
|
772
|
+
typename nk::type_for<input_dtype_>::type::jaccards_pack_kernel_t pack_fn,
|
|
773
|
+
typename nk::type_for<input_dtype_>::type::jaccards_packed_kernel_t kernel) {
|
|
774
|
+
std::string bench_name = name + "<" + std::to_string(bench_config.matrix_height) + "x" +
|
|
775
|
+
std::to_string(bench_config.matrix_width) + "x" +
|
|
776
|
+
std::to_string(bench_config.matrix_depth) + ">";
|
|
777
|
+
bm::RegisterBenchmark(bench_name.c_str(), measure_jaccards_packed<input_dtype_>, packed_size_fn, pack_fn, kernel,
|
|
778
|
+
bench_config.matrix_height, bench_config.matrix_width, bench_config.matrix_depth);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
template <nk_dtype_t input_dtype_>
|
|
782
|
+
void run_jaccards_symmetric(std::string name, //
|
|
783
|
+
typename nk::type_for<input_dtype_>::type::jaccards_symmetric_kernel_t kernel) {
|
|
784
|
+
std::string bench_name = name + "<" + std::to_string(bench_config.matrix_height) + "x" +
|
|
785
|
+
std::to_string(bench_config.matrix_depth) + ">";
|
|
786
|
+
bm::RegisterBenchmark(bench_name.c_str(), measure_jaccards_symmetric<input_dtype_>, //
|
|
787
|
+
kernel, bench_config.matrix_height, bench_config.matrix_depth);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// Forward declarations for benchmark registration functions (defined in separate files)
|
|
791
|
+
void bench_dot();
|
|
792
|
+
void bench_spatial();
|
|
793
|
+
void bench_set();
|
|
794
|
+
void bench_curved();
|
|
795
|
+
void bench_probability();
|
|
796
|
+
void bench_each();
|
|
797
|
+
void bench_trigonometry();
|
|
798
|
+
void bench_geospatial();
|
|
799
|
+
void bench_mesh();
|
|
800
|
+
void bench_sparse();
|
|
801
|
+
void bench_sparse_dot();
|
|
802
|
+
void bench_cast();
|
|
803
|
+
void bench_reduce();
|
|
804
|
+
void bench_maxsim();
|
|
805
|
+
|
|
806
|
+
// Forward declarations for cross/batch operations (ISA-family files)
|
|
807
|
+
void bench_cross_serial();
|
|
808
|
+
void bench_cross_x86();
|
|
809
|
+
void bench_cross_amx();
|
|
810
|
+
void bench_cross_arm();
|
|
811
|
+
void bench_cross_sme();
|
|
812
|
+
void bench_cross_blas();
|
|
813
|
+
void bench_cross_rvv();
|
|
814
|
+
void bench_cross_power();
|
|
815
|
+
void bench_cross_wasm();
|
|
816
|
+
void bench_cross_loongarch();
|