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,217 @@
|
|
|
1
|
+
# NumKong Built-in Benchmarks
|
|
2
|
+
|
|
3
|
+
Internal profiling suite comparing NumKong's SIMD backends against each other and optionally against BLAS libraries.
|
|
4
|
+
For broader comparisons — Rust, Python, etc. — see [NumWars](https://github.com/ashvardanian/NumWars).
|
|
5
|
+
|
|
6
|
+
- On x86 it compares serial code to manually-vectorized Haswell, Skylake, Ice Lake, Genoa, Sapphire Rapids and newer-generation SIMD kernels.
|
|
7
|
+
- On Arm it compares serial code to manually-vectorized NEON, SVE, SVE2, SME, SME2 with various extensions for BF16 and mixed-precision dot-products.
|
|
8
|
+
- On RISC-V it compares serial code to manually-vectorized RVV 1.0 kernels with and without BB, BF16, and F16 extensions.
|
|
9
|
+
- In WASM environments it compares serial code to manually-vectorized V128 kernels with Relaxed SIMD extensions.
|
|
10
|
+
|
|
11
|
+
## C++
|
|
12
|
+
|
|
13
|
+
### Building
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
cmake -B build_release -D CMAKE_BUILD_TYPE=Release -D NK_BUILD_BENCH=1
|
|
17
|
+
cmake --build build_release --config Release --parallel
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
With BLAS or MKL cross-validation:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
cmake -B build_release -D CMAKE_BUILD_TYPE=Release \
|
|
24
|
+
-D NK_BUILD_BENCH=1 \
|
|
25
|
+
-D NK_COMPARE_TO_BLAS=1 \
|
|
26
|
+
-D NK_COMPARE_TO_MKL=1
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
On macOS with Homebrew Clang and OpenBLAS — see [CONTRIBUTING.md](../CONTRIBUTING.md#macos) for the full recipe, adding `-DNK_BUILD_BENCH=1` to the cmake flags.
|
|
30
|
+
|
|
31
|
+
Compiler requirements vary by ISA target — see [CONTRIBUTING.md](../CONTRIBUTING.md#compiler-requirements) for the full table.
|
|
32
|
+
|
|
33
|
+
### Running
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
build_release/nk_bench # run all benchmarks
|
|
37
|
+
build_release/nk_bench --benchmark_filter=dot # filter by name
|
|
38
|
+
build_release/nk_bench --benchmark_min_time=10s # longer runs for stable results
|
|
39
|
+
build_release/nk_bench --filter=dot # shorthand for --benchmark_filter
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Environment Variables
|
|
43
|
+
|
|
44
|
+
| Variable | Default | Description |
|
|
45
|
+
| ------------------------- | ------- | ------------------------------------------------------ |
|
|
46
|
+
| `NK_FILTER` | `.*` | Regex to filter benchmarks by name |
|
|
47
|
+
| `NK_SEED` | `42` | RNG seed for reproducible inputs |
|
|
48
|
+
| `NK_BUDGET_SECS` | `10` | Minimum time per benchmark in seconds |
|
|
49
|
+
| `NK_BUDGET_MB` | `1024` | Memory budget for pre-allocated inputs |
|
|
50
|
+
| `NK_DENSE_DIMENSIONS` | `1536` | Vector dimension for dot/spatial benchmarks |
|
|
51
|
+
| `NK_CURVED_DIMENSIONS` | `64` | Vector dimension for curved / bilinear form benchmarks |
|
|
52
|
+
| `NK_MESH_POINTS` | `1000` | Point count for mesh / RMSD / Kabsch benchmarks |
|
|
53
|
+
| `NK_MATRIX_HEIGHT` | `1024` | GEMM M dimension, dataset size in kNN |
|
|
54
|
+
| `NK_MATRIX_WIDTH` | `128` | GEMM N dimension, query count in kNN |
|
|
55
|
+
| `NK_MATRIX_DEPTH` | `1536` | GEMM K dimension, vector dimension in kNN |
|
|
56
|
+
| `NK_SPARSE_FIRST_LENGTH` | `1024` | First set size for sparse benchmarks |
|
|
57
|
+
| `NK_SPARSE_SECOND_LENGTH` | `8192` | Second set size for sparse benchmarks |
|
|
58
|
+
| `NK_SPARSE_INTERSECTION` | `0.5` | Intersection share [0.0, 1.0] for sparse benchmarks |
|
|
59
|
+
| `NK_MAX_COORD_ANGLE` | `180` | Maximum angle in degrees for geospatial benchmarks |
|
|
60
|
+
|
|
61
|
+
Disable multi-threading in BLAS libraries to avoid interference:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
export OPENBLAS_NUM_THREADS=1 # for OpenBLAS
|
|
65
|
+
export MKL_NUM_THREADS=1 # for Intel MKL
|
|
66
|
+
export VECLIB_MAXIMUM_THREADS=1 # for Apple Accelerate
|
|
67
|
+
export BLIS_NUM_THREADS=1 # for BLIS
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Reported Units
|
|
71
|
+
|
|
72
|
+
| Benchmark Type | Counter | Meaning |
|
|
73
|
+
| --------------------------------------- | -------------- | --------------------------------------------------------------- |
|
|
74
|
+
| Vector kernels — dot, spatial, set, ... | `bytes/s` | Bytes of input consumed per second, both input vectors combined |
|
|
75
|
+
| GEMM, symmetric, batch | `scalar-ops/s` | Scalar multiply-accumulate operations per second / FLOPS |
|
|
76
|
+
| Reductions, casts, trigonometry | `bytes/s` | Bytes of input consumed per second, single input vector |
|
|
77
|
+
|
|
78
|
+
__bytes__: total bytes across all input vectors read per call.
|
|
79
|
+
For a pair of 1536-dimensional `f32` vectors: `2 * 1536 * 4 = 12288` bytes per call.
|
|
80
|
+
|
|
81
|
+
__scalar-ops__: number of scalar arithmetic operations.
|
|
82
|
+
For dense GEMM: `2 * M * N * K` per call.
|
|
83
|
+
For symmetric GEMM: `N * (N + 1) * K` per call.
|
|
84
|
+
|
|
85
|
+
## JavaScript
|
|
86
|
+
|
|
87
|
+
### Running
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
npm run bench:native # Node.js native addon
|
|
91
|
+
npm run bench:emscripten # Emscripten WASM with SIMD
|
|
92
|
+
npm run bench:wasi # WASI portable execution
|
|
93
|
+
npm run bench:browser # Chromium via Playwright
|
|
94
|
+
npm run bench:all # all runtimes
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
NK_DIMENSIONS=768 NK_FILTER="dot" npm run bench:native # custom config
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
| Variable | Default | Description |
|
|
102
|
+
| --------------- | -------- | --------------------------------------- |
|
|
103
|
+
| `NK_DIMENSIONS` | `1536` | Vector dimensionality |
|
|
104
|
+
| `NK_ITERATIONS` | `1000` | Number of benchmark iterations |
|
|
105
|
+
| `NK_FILTER` | `.*` | Regex to filter benchmarks |
|
|
106
|
+
| `NK_RUNTIME` | `native` | Runtime: `native`, `emscripten`, `wasi` |
|
|
107
|
+
| `NK_SEED` | `42` | Random seed for reproducible data |
|
|
108
|
+
|
|
109
|
+
### Output
|
|
110
|
+
|
|
111
|
+
JSON results are written to `bench/results/`.
|
|
112
|
+
Generate a Markdown comparison report:
|
|
113
|
+
|
|
114
|
+
```sh
|
|
115
|
+
npm run bench:report
|
|
116
|
+
cat bench/results/report.md
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## WASM
|
|
120
|
+
|
|
121
|
+
__Emscripten — wasm32 and wasm64__
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
source ~/emsdk/emsdk_env.sh
|
|
125
|
+
cmake -B build-wasm -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-wasm.cmake -DNK_BUILD_BENCH=1
|
|
126
|
+
cmake --build build-wasm --parallel
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
For wasm64:
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
cmake -B build-wasm64 -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-wasm64.cmake -DNK_BUILD_BENCH=1
|
|
133
|
+
cmake --build build-wasm64 --parallel
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The toolchain files enable `-msimd128` and `-mrelaxed-simd` automatically.
|
|
137
|
+
|
|
138
|
+
__WASI__
|
|
139
|
+
|
|
140
|
+
```sh
|
|
141
|
+
export WASI_SDK_PATH=~/wasi-sdk-24.0-x86_64-linux
|
|
142
|
+
cmake -B build-wasi -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-wasi.cmake -DNK_BUILD_BENCH=1
|
|
143
|
+
cmake --build build-wasi --parallel
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
__Running__
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
wasmtime run -W simd=y,relaxed-simd=y,threads=y,shared-memory=y -S threads=y,inherit-env=y ./build-wasi/nk_bench.wasm
|
|
150
|
+
wasmer run --enable-simd --enable-relaxed-simd ./build-wasi/nk_bench.wasm
|
|
151
|
+
node ./build-wasm/nk_bench.js
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Browser benchmarks via Playwright:
|
|
155
|
+
|
|
156
|
+
```sh
|
|
157
|
+
npm run bench:browser
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
__Interpreting WASM Results__
|
|
161
|
+
|
|
162
|
+
WASM benchmarks run slower than native due to JIT compilation overhead and memory indirection.
|
|
163
|
+
Expected performance relative to native:
|
|
164
|
+
|
|
165
|
+
| Runtime | Typical Throughput vs Native |
|
|
166
|
+
| -------------------- | ---------------------------- |
|
|
167
|
+
| Emscripten / Node.js | 60–80% |
|
|
168
|
+
| WASI / Wasmtime | 50–70% |
|
|
169
|
+
| Browser / Chromium | 40–60% |
|
|
170
|
+
|
|
171
|
+
wasm64 / Memory64 adds ~5–10% overhead vs wasm32 due to 64-bit pointer arithmetic.
|
|
172
|
+
Relaxed SIMD provides measurable gains for fused multiply-add patterns — compare with and without `--wasm-features relaxed-simd` to quantify.
|
|
173
|
+
|
|
174
|
+
## Frequency Scaling on AMX and SME
|
|
175
|
+
|
|
176
|
+
Intel AMX tiles on Sapphire Rapids and later cause P-state throttling: the CPU reduces its frequency when AMX instructions execute, similar to heavy AVX-512 workloads.
|
|
177
|
+
Arm SME streaming mode on Graviton4 and Apple M4 has analogous frequency effects when entering and exiting streaming SVE mode.
|
|
178
|
+
|
|
179
|
+
This means AMX/SME benchmarks that interleave with non-AMX/SME work will show misleading throughput numbers as the CPU oscillates between frequency states.
|
|
180
|
+
|
|
181
|
+
Mitigations:
|
|
182
|
+
|
|
183
|
+
- Use `--benchmark_min_time=10s` or higher to amortize warm-up over a longer measurement window.
|
|
184
|
+
- Disable turbo boost with `echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo` on Linux.
|
|
185
|
+
- Run AMX/SME benchmarks in isolation — do not mix them with non-AMX/SME benchmarks in the same invocation.
|
|
186
|
+
- Filter with `--benchmark_filter=amx` or `--benchmark_filter=sme` for dedicated runs.
|
|
187
|
+
|
|
188
|
+
## Pinning to Performance Cores
|
|
189
|
+
|
|
190
|
+
### Linux
|
|
191
|
+
|
|
192
|
+
```sh
|
|
193
|
+
taskset -c 0-3 ./build_release/nk_bench
|
|
194
|
+
numactl --physcpubind=0-3 ./build_release/nk_bench
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
For dedicated benchmarking machines, add `isolcpus=4-7` to the kernel command line and pin benchmarks to isolated cores.
|
|
198
|
+
|
|
199
|
+
### macOS
|
|
200
|
+
|
|
201
|
+
No direct core-pinning API exists on macOS.
|
|
202
|
+
Use QoS to avoid efficiency cores:
|
|
203
|
+
|
|
204
|
+
```sh
|
|
205
|
+
taskpolicy -b ./build_release/nk_bench
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
On Apple Silicon there is no public API for P/E core pinning.
|
|
209
|
+
Run with minimal background load for reproducible results.
|
|
210
|
+
|
|
211
|
+
### Windows
|
|
212
|
+
|
|
213
|
+
```sh
|
|
214
|
+
start /affinity 0xF nk_bench.exe
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The hex mask `0xF` pins to cores 0-3.
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>NumKong Browser Benchmarks</title>
|
|
8
|
+
<style>
|
|
9
|
+
body {
|
|
10
|
+
font-family: 'Courier New', monospace;
|
|
11
|
+
max-width: 1200px;
|
|
12
|
+
margin: 40px auto;
|
|
13
|
+
padding: 20px;
|
|
14
|
+
background: #1e1e1e;
|
|
15
|
+
color: #d4d4d4;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
h1 {
|
|
19
|
+
color: #4ec9b0;
|
|
20
|
+
border-bottom: 2px solid #4ec9b0;
|
|
21
|
+
padding-bottom: 10px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
h2 {
|
|
25
|
+
color: #569cd6;
|
|
26
|
+
margin-top: 30px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#progress {
|
|
30
|
+
background: #264f78;
|
|
31
|
+
padding: 15px;
|
|
32
|
+
border-radius: 5px;
|
|
33
|
+
margin: 20px 0;
|
|
34
|
+
font-weight: bold;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
#results {
|
|
38
|
+
background: #252526;
|
|
39
|
+
padding: 20px;
|
|
40
|
+
border-radius: 5px;
|
|
41
|
+
margin-top: 20px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.result-row {
|
|
45
|
+
padding: 8px 0;
|
|
46
|
+
border-bottom: 1px solid #3e3e42;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.result-row:last-child {
|
|
50
|
+
border-bottom: none;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.test-name {
|
|
54
|
+
color: #ce9178;
|
|
55
|
+
display: inline-block;
|
|
56
|
+
width: 250px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.ops-sec {
|
|
60
|
+
color: #b5cea8;
|
|
61
|
+
display: inline-block;
|
|
62
|
+
width: 150px;
|
|
63
|
+
text-align: right;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.time {
|
|
67
|
+
color: #9cdcfe;
|
|
68
|
+
display: inline-block;
|
|
69
|
+
margin-left: 20px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.error {
|
|
73
|
+
color: #f48771;
|
|
74
|
+
background: #5a1d1d;
|
|
75
|
+
padding: 10px;
|
|
76
|
+
border-radius: 5px;
|
|
77
|
+
margin: 10px 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.complete {
|
|
81
|
+
color: #4ec9b0;
|
|
82
|
+
font-weight: bold;
|
|
83
|
+
}
|
|
84
|
+
</style>
|
|
85
|
+
</head>
|
|
86
|
+
|
|
87
|
+
<body>
|
|
88
|
+
<h1>NumKong Browser Benchmarks</h1>
|
|
89
|
+
|
|
90
|
+
<div id="config">
|
|
91
|
+
<h2>Configuration</h2>
|
|
92
|
+
<div id="config-info">Loading...</div>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<div id="progress">Initializing NumKong WASM module...</div>
|
|
96
|
+
|
|
97
|
+
<div id="results"></div>
|
|
98
|
+
|
|
99
|
+
<script src="https://cdn.jsdelivr.net/npm/benchmark@2.1.4/benchmark.min.js"></script>
|
|
100
|
+
<script type="module">
|
|
101
|
+
// Configuration from URL parameters or defaults
|
|
102
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
103
|
+
const CONFIG = {
|
|
104
|
+
dimensions: parseInt(urlParams.get('dimensions') || '1536'),
|
|
105
|
+
iterations: parseInt(urlParams.get('iterations') || '1000'),
|
|
106
|
+
filter: new RegExp(urlParams.get('filter') || '.*'),
|
|
107
|
+
seed: parseInt(urlParams.get('seed') || '42')
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// Benchmark matrix (same as bench-multi-runtime.mjs)
|
|
111
|
+
const BENCHMARK_MATRIX = {
|
|
112
|
+
functions: ['dot', 'inner', 'angular', 'sqeuclidean', 'euclidean', 'hamming', 'jaccard', 'kullbackleibler', 'jensenshannon'],
|
|
113
|
+
dtypes: ['f64', 'f32', 'f16', 'bf16', 'e4m3', 'e5m2', 'e2m3', 'e3m2', 'i8', 'u8', 'u1'],
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const FUNCTION_DTYPE_SUPPORT = {
|
|
117
|
+
'dot': ['f64', 'f32', 'f16', 'bf16', 'e4m3', 'e5m2', 'e2m3', 'e3m2', 'i8', 'u8'],
|
|
118
|
+
'inner': ['f64', 'f32', 'f16', 'bf16', 'e4m3', 'e5m2', 'e2m3', 'e3m2', 'i8', 'u8'],
|
|
119
|
+
'angular': ['f64', 'f32', 'f16', 'bf16', 'e4m3', 'e5m2', 'e2m3', 'e3m2', 'i8'],
|
|
120
|
+
'sqeuclidean': ['f64', 'f32', 'f16', 'bf16', 'e4m3', 'e5m2', 'e2m3', 'e3m2', 'i8', 'u8'],
|
|
121
|
+
'euclidean': ['f64', 'f32', 'f16', 'bf16', 'e4m3', 'e5m2', 'e2m3', 'e3m2', 'i8', 'u8'],
|
|
122
|
+
'hamming': ['u1'],
|
|
123
|
+
'jaccard': ['u1'],
|
|
124
|
+
'kullbackleibler': ['f64', 'f32'],
|
|
125
|
+
'jensenshannon': ['f64', 'f32']
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// Simple PRNG for reproducible benchmarks
|
|
129
|
+
class Random {
|
|
130
|
+
constructor(seed) {
|
|
131
|
+
this.seed = seed;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
next() {
|
|
135
|
+
this.seed = (this.seed * 1103515245 + 12345) & 0x7fffffff;
|
|
136
|
+
return this.seed / 0x7fffffff;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Generate test data
|
|
141
|
+
function generateTestData(dtype, length, seed) {
|
|
142
|
+
const rng = new Random(seed);
|
|
143
|
+
|
|
144
|
+
switch (dtype) {
|
|
145
|
+
case 'f64':
|
|
146
|
+
return Float64Array.from({ length }, () => rng.next() * 2 - 1);
|
|
147
|
+
case 'f32':
|
|
148
|
+
return Float32Array.from({ length }, () => rng.next() * 2 - 1);
|
|
149
|
+
case 'f16':
|
|
150
|
+
case 'bf16':
|
|
151
|
+
case 'e4m3':
|
|
152
|
+
case 'e5m2':
|
|
153
|
+
case 'e2m3':
|
|
154
|
+
case 'e3m2':
|
|
155
|
+
return Float32Array.from({ length }, () => rng.next() * 2 - 1);
|
|
156
|
+
case 'i8':
|
|
157
|
+
return Int8Array.from({ length }, () => Math.floor(rng.next() * 256) - 128);
|
|
158
|
+
case 'u8':
|
|
159
|
+
return Uint8Array.from({ length }, () => Math.floor(rng.next() * 256));
|
|
160
|
+
case 'u1':
|
|
161
|
+
const byteLength = Math.ceil(length / 8);
|
|
162
|
+
return Uint8Array.from({ length: byteLength }, () => Math.floor(rng.next() * 256));
|
|
163
|
+
default:
|
|
164
|
+
throw new Error(`Unknown dtype: ${dtype}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Update UI
|
|
169
|
+
function updateProgress(message) {
|
|
170
|
+
document.getElementById('progress').textContent = message;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
function benchmarkOperation(fn, iterations) {
|
|
175
|
+
const warmupIterations = Math.max(16, Math.min(256, iterations));
|
|
176
|
+
const samples = 5;
|
|
177
|
+
const sampleTimesMs = [];
|
|
178
|
+
|
|
179
|
+
for (let i = 0; i < warmupIterations; i++) {
|
|
180
|
+
fn();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
for (let sample = 0; sample < samples; sample++) {
|
|
184
|
+
const start = performance.now();
|
|
185
|
+
for (let i = 0; i < iterations; i++) {
|
|
186
|
+
fn();
|
|
187
|
+
}
|
|
188
|
+
const elapsedMs = performance.now() - start;
|
|
189
|
+
sampleTimesMs.push(elapsedMs / iterations);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const meanTime = sampleTimesMs.reduce((sum, value) => sum + value, 0) / sampleTimesMs.length;
|
|
193
|
+
const variance = sampleTimesMs.reduce((sum, value) => {
|
|
194
|
+
const delta = value - meanTime;
|
|
195
|
+
return sum + delta * delta;
|
|
196
|
+
}, 0) / sampleTimesMs.length;
|
|
197
|
+
const stdDev = Math.sqrt(variance);
|
|
198
|
+
const opsPerSec = meanTime > 0 ? 1000 / meanTime : 0;
|
|
199
|
+
|
|
200
|
+
return { opsPerSec, meanTime, stdDev };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function addResult(testName, opsPerSec, meanTime, stdDev) {
|
|
204
|
+
const resultsDiv = document.getElementById('results');
|
|
205
|
+
const row = document.createElement('div');
|
|
206
|
+
row.className = 'result-row';
|
|
207
|
+
row.innerHTML = `
|
|
208
|
+
<span class="test-name">${testName}</span>
|
|
209
|
+
<span class="ops-sec">${opsPerSec.toFixed(0).padStart(10)} ops/sec</span>
|
|
210
|
+
<span class="time">(${meanTime.toFixed(3)}ms ± ${stdDev.toFixed(3)}ms)</span>
|
|
211
|
+
`;
|
|
212
|
+
resultsDiv.appendChild(row);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function showError(message) {
|
|
216
|
+
const resultsDiv = document.getElementById('results');
|
|
217
|
+
const errorDiv = document.createElement('div');
|
|
218
|
+
errorDiv.className = 'error';
|
|
219
|
+
errorDiv.textContent = `❌ Error: ${message}`;
|
|
220
|
+
resultsDiv.appendChild(errorDiv);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Main benchmark execution
|
|
224
|
+
async function runBenchmarks() {
|
|
225
|
+
try {
|
|
226
|
+
// Display configuration
|
|
227
|
+
document.getElementById('config-info').innerHTML = `
|
|
228
|
+
<div>Dimensions: ${CONFIG.dimensions}</div>
|
|
229
|
+
<div>Filter: ${CONFIG.filter.source}</div>
|
|
230
|
+
<div>Seed: ${CONFIG.seed}</div>
|
|
231
|
+
<div>Runtime: Browser (Chromium)</div>
|
|
232
|
+
`;
|
|
233
|
+
|
|
234
|
+
// Load NumKong WASM module
|
|
235
|
+
updateProgress('Loading NumKong WASM module...');
|
|
236
|
+
|
|
237
|
+
const wasmPath = '../build-wasm/numkong.js';
|
|
238
|
+
const wasmWrapperPath = '../javascript/dist/esm/numkong-wasm.js';
|
|
239
|
+
const numkongWrapper = await import(wasmWrapperPath);
|
|
240
|
+
const NumKongModule = await import(wasmPath);
|
|
241
|
+
const wasmInstance = await NumKongModule.default();
|
|
242
|
+
numkongWrapper.initWasm(wasmInstance);
|
|
243
|
+
const numkong = numkongWrapper;
|
|
244
|
+
|
|
245
|
+
updateProgress('NumKong WASM loaded successfully. Running benchmarks...');
|
|
246
|
+
|
|
247
|
+
const results = [];
|
|
248
|
+
let testCount = 0;
|
|
249
|
+
let totalTests = 0;
|
|
250
|
+
|
|
251
|
+
// Count total tests
|
|
252
|
+
for (const func of BENCHMARK_MATRIX.functions) {
|
|
253
|
+
const supportedDtypes = FUNCTION_DTYPE_SUPPORT[func] || [];
|
|
254
|
+
for (const dtype of supportedDtypes) {
|
|
255
|
+
const testName = `${func}-${dtype}`;
|
|
256
|
+
if (CONFIG.filter.test(testName)) {
|
|
257
|
+
totalTests++;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Run benchmarks
|
|
263
|
+
for (const func of BENCHMARK_MATRIX.functions) {
|
|
264
|
+
const supportedDtypes = FUNCTION_DTYPE_SUPPORT[func] || [];
|
|
265
|
+
|
|
266
|
+
for (const dtype of supportedDtypes) {
|
|
267
|
+
const testName = `${func}-${dtype}`;
|
|
268
|
+
|
|
269
|
+
// Apply filter
|
|
270
|
+
if (!CONFIG.filter.test(testName)) {
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
testCount++;
|
|
275
|
+
updateProgress(`Running ${testCount}/${totalTests}: ${testName}...`);
|
|
276
|
+
|
|
277
|
+
// Generate test data
|
|
278
|
+
const a = generateTestData(dtype, CONFIG.dimensions, CONFIG.seed);
|
|
279
|
+
const b = generateTestData(dtype, CONFIG.dimensions, CONFIG.seed + 1);
|
|
280
|
+
|
|
281
|
+
const metrics = benchmarkOperation(() => numkong[func](a, b), CONFIG.iterations);
|
|
282
|
+
|
|
283
|
+
addResult(testName, metrics.opsPerSec, metrics.meanTime, metrics.stdDev);
|
|
284
|
+
|
|
285
|
+
results.push({
|
|
286
|
+
function: func,
|
|
287
|
+
dtype: dtype,
|
|
288
|
+
runtime: 'browser',
|
|
289
|
+
dimensions: CONFIG.dimensions,
|
|
290
|
+
opsPerSec: metrics.opsPerSec,
|
|
291
|
+
meanTime: metrics.meanTime,
|
|
292
|
+
stdDev: metrics.stdDev,
|
|
293
|
+
timestamp: new Date().toISOString()
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Make results available to Playwright
|
|
299
|
+
window.benchmarkResults = results;
|
|
300
|
+
window.benchmarkComplete = true;
|
|
301
|
+
|
|
302
|
+
updateProgress(`✅ Benchmark complete! Total tests run: ${results.length}`);
|
|
303
|
+
|
|
304
|
+
const completeDiv = document.createElement('div');
|
|
305
|
+
completeDiv.className = 'complete';
|
|
306
|
+
completeDiv.style.marginTop = '20px';
|
|
307
|
+
completeDiv.textContent = `All ${results.length} benchmarks completed successfully.`;
|
|
308
|
+
document.getElementById('results').appendChild(completeDiv);
|
|
309
|
+
|
|
310
|
+
} catch (error) {
|
|
311
|
+
showError(error.message);
|
|
312
|
+
updateProgress(`❌ Benchmark failed: ${error.message}`);
|
|
313
|
+
window.benchmarkError = error.message;
|
|
314
|
+
window.benchmarkComplete = true;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Start benchmarks when page loads
|
|
319
|
+
runBenchmarks();
|
|
320
|
+
</script>
|
|
321
|
+
</body>
|
|
322
|
+
|
|
323
|
+
</html>
|