usearch 2.21.3 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -24
- package/binding.gyp +15 -37
- package/c/CMakeLists.txt +4 -5
- package/c/README.md +7 -7
- package/c/lib.cpp +32 -14
- package/c/test.c +83 -1
- package/c/usearch.h +24 -3
- package/cpp/CMakeLists.txt +4 -0
- package/cpp/README.md +5 -5
- package/cpp/bench.cpp +97 -116
- package/cpp/test.cpp +117 -20
- package/include/usearch/index.hpp +235 -52
- package/include/usearch/index_dense.hpp +105 -40
- package/include/usearch/index_plugins.hpp +1387 -204
- package/javascript/dist/cjs/usearch.d.ts +8 -3
- package/javascript/dist/cjs/usearch.js +12 -4
- package/javascript/dist/esm/usearch.d.ts +8 -3
- package/javascript/dist/esm/usearch.js +12 -4
- package/javascript/lib.cpp +17 -0
- package/javascript/usearch.ts +14 -6
- package/numkong/.clang-tidy +30 -0
- package/{simsimd → numkong}/.cmake-format.py +18 -0
- package/numkong/.editorconfig +12 -0
- package/numkong/.git-blame-ignore-revs +123 -0
- package/numkong/.mailmap +15 -0
- package/numkong/.spi.yml +11 -0
- package/numkong/.swift-format +14 -0
- package/numkong/CITATION.cff +81 -0
- package/numkong/CONTRIBUTING.md +500 -0
- package/numkong/Cargo.toml +54 -0
- package/numkong/MANIFEST.in +8 -0
- package/numkong/Package.swift +84 -0
- package/numkong/README.md +569 -0
- package/numkong/bench/README.md +217 -0
- package/numkong/bench/bench-browser.html +323 -0
- package/numkong/bench/bench.cpp +344 -0
- package/numkong/bench/bench.hpp +816 -0
- package/numkong/bench/bench.js +148 -0
- package/numkong/bench/bench.mjs +616 -0
- package/numkong/bench/bench_attention.cpp +113 -0
- package/numkong/bench/bench_cast.cpp +264 -0
- package/numkong/bench/bench_cross_amx.cpp +62 -0
- package/numkong/bench/bench_cross_arm.cpp +245 -0
- package/numkong/bench/bench_cross_blas.cpp +309 -0
- package/numkong/bench/bench_cross_loongarch.cpp +106 -0
- package/numkong/bench/bench_cross_power.cpp +84 -0
- package/numkong/bench/bench_cross_rvv.cpp +121 -0
- package/numkong/bench/bench_cross_serial.cpp +151 -0
- package/numkong/bench/bench_cross_sme.cpp +163 -0
- package/numkong/bench/bench_cross_wasm.cpp +142 -0
- package/numkong/bench/bench_cross_x86.cpp +455 -0
- package/numkong/bench/bench_curved.cpp +210 -0
- package/numkong/bench/bench_dot.cpp +315 -0
- package/numkong/bench/bench_each.cpp +503 -0
- package/numkong/bench/bench_geospatial.cpp +112 -0
- package/numkong/bench/bench_maxsim.cpp +154 -0
- package/numkong/bench/bench_mesh.cpp +148 -0
- package/numkong/bench/bench_probability.cpp +60 -0
- package/numkong/bench/bench_reduce.cpp +371 -0
- package/numkong/bench/bench_set.cpp +73 -0
- package/numkong/bench/bench_sparse.cpp +198 -0
- package/numkong/bench/bench_spatial.cpp +347 -0
- package/numkong/bench/bench_trigonometry.cpp +137 -0
- package/numkong/bench/swift/Bench.swift +506 -0
- package/numkong/binding.gyp +169 -0
- package/numkong/build.rs +484 -0
- package/numkong/c/dispatch.h +512 -0
- package/numkong/c/dispatch_bf16.c +447 -0
- package/numkong/c/dispatch_bf16c.c +52 -0
- package/numkong/c/dispatch_e2m3.c +296 -0
- package/numkong/c/dispatch_e3m2.c +284 -0
- package/numkong/c/dispatch_e4m3.c +318 -0
- package/numkong/c/dispatch_e5m2.c +316 -0
- package/numkong/c/dispatch_f16.c +452 -0
- package/numkong/c/dispatch_f16c.c +58 -0
- package/numkong/c/dispatch_f32.c +434 -0
- package/numkong/c/dispatch_f32c.c +99 -0
- package/numkong/c/dispatch_f64.c +348 -0
- package/numkong/c/dispatch_f64c.c +98 -0
- package/numkong/c/dispatch_i16.c +96 -0
- package/numkong/c/dispatch_i32.c +89 -0
- package/numkong/c/dispatch_i4.c +153 -0
- package/numkong/c/dispatch_i64.c +86 -0
- package/numkong/c/dispatch_i8.c +348 -0
- package/numkong/c/dispatch_other.c +348 -0
- package/numkong/c/dispatch_u1.c +193 -0
- package/numkong/c/dispatch_u16.c +124 -0
- package/numkong/c/dispatch_u32.c +118 -0
- package/numkong/c/dispatch_u4.c +153 -0
- package/numkong/c/dispatch_u64.c +102 -0
- package/numkong/c/dispatch_u8.c +364 -0
- package/numkong/c/numkong.c +940 -0
- package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
- package/numkong/cmake/nk_isa_probe.cmake +90 -0
- package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_math_lib.cmake +46 -0
- package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
- package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
- package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
- package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
- package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
- package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
- package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
- package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
- package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
- package/numkong/cmake/toolchain-wasi.cmake +77 -0
- package/numkong/cmake/toolchain-wasm.cmake +70 -0
- package/numkong/cmake/toolchain-wasm64.cmake +62 -0
- package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
- package/numkong/include/README.md +643 -0
- package/numkong/include/module.modulemap +129 -0
- package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
- package/numkong/include/numkong/attention/sme.h +2075 -0
- package/numkong/include/numkong/attention.h +49 -0
- package/numkong/include/numkong/capabilities.h +930 -0
- package/numkong/include/numkong/cast/README.md +262 -0
- package/numkong/include/numkong/cast/diamond.h +64 -0
- package/numkong/include/numkong/cast/haswell.h +823 -0
- package/numkong/include/numkong/cast/icelake.h +475 -0
- package/numkong/include/numkong/cast/loongsonasx.h +252 -0
- package/numkong/include/numkong/cast/neon.h +1174 -0
- package/numkong/include/numkong/cast/powervsx.h +449 -0
- package/numkong/include/numkong/cast/rvv.h +970 -0
- package/numkong/include/numkong/cast/sapphire.h +262 -0
- package/numkong/include/numkong/cast/serial.h +2336 -0
- package/numkong/include/numkong/cast/skylake.h +915 -0
- package/numkong/include/numkong/cast/v128relaxed.h +537 -0
- package/numkong/include/numkong/cast.h +254 -0
- package/numkong/include/numkong/cast.hpp +44 -0
- package/numkong/include/numkong/curved/README.md +223 -0
- package/numkong/include/numkong/curved/genoa.h +182 -0
- package/numkong/include/numkong/curved/haswell.h +276 -0
- package/numkong/include/numkong/curved/neon.h +329 -0
- package/numkong/include/numkong/curved/neonbfdot.h +211 -0
- package/numkong/include/numkong/curved/rvv.h +305 -0
- package/numkong/include/numkong/curved/serial.h +207 -0
- package/numkong/include/numkong/curved/skylake.h +457 -0
- package/numkong/include/numkong/curved/smef64.h +530 -0
- package/numkong/include/numkong/curved.h +513 -0
- package/numkong/include/numkong/curved.hpp +144 -0
- package/numkong/include/numkong/dot/README.md +442 -0
- package/numkong/include/numkong/dot/alder.h +563 -0
- package/numkong/include/numkong/dot/diamond.h +158 -0
- package/numkong/include/numkong/dot/genoa.h +289 -0
- package/numkong/include/numkong/dot/haswell.h +1723 -0
- package/numkong/include/numkong/dot/icelake.h +997 -0
- package/numkong/include/numkong/dot/loongsonasx.h +671 -0
- package/numkong/include/numkong/dot/neon.h +869 -0
- package/numkong/include/numkong/dot/neonbfdot.h +243 -0
- package/numkong/include/numkong/dot/neonfhm.h +358 -0
- package/numkong/include/numkong/dot/neonfp8.h +323 -0
- package/numkong/include/numkong/dot/neonsdot.h +622 -0
- package/numkong/include/numkong/dot/powervsx.h +752 -0
- package/numkong/include/numkong/dot/rvv.h +722 -0
- package/numkong/include/numkong/dot/rvvbb.h +72 -0
- package/numkong/include/numkong/dot/rvvbf16.h +123 -0
- package/numkong/include/numkong/dot/rvvhalf.h +129 -0
- package/numkong/include/numkong/dot/sapphire.h +141 -0
- package/numkong/include/numkong/dot/serial.h +874 -0
- package/numkong/include/numkong/dot/sierra.h +405 -0
- package/numkong/include/numkong/dot/skylake.h +1116 -0
- package/numkong/include/numkong/dot/sve.h +420 -0
- package/numkong/include/numkong/dot/svebfdot.h +75 -0
- package/numkong/include/numkong/dot/svehalf.h +168 -0
- package/numkong/include/numkong/dot/svesdot.h +90 -0
- package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
- package/numkong/include/numkong/dot.h +1136 -0
- package/numkong/include/numkong/dot.hpp +94 -0
- package/numkong/include/numkong/dots/README.md +496 -0
- package/numkong/include/numkong/dots/alder.h +117 -0
- package/numkong/include/numkong/dots/diamond.h +86 -0
- package/numkong/include/numkong/dots/genoa.h +100 -0
- package/numkong/include/numkong/dots/graniteamx.h +733 -0
- package/numkong/include/numkong/dots/haswell.h +310 -0
- package/numkong/include/numkong/dots/icelake.h +180 -0
- package/numkong/include/numkong/dots/loongsonasx.h +176 -0
- package/numkong/include/numkong/dots/neon.h +123 -0
- package/numkong/include/numkong/dots/neonbfdot.h +59 -0
- package/numkong/include/numkong/dots/neonfhm.h +96 -0
- package/numkong/include/numkong/dots/neonfp8.h +99 -0
- package/numkong/include/numkong/dots/neonsdot.h +144 -0
- package/numkong/include/numkong/dots/powervsx.h +194 -0
- package/numkong/include/numkong/dots/rvv.h +2593 -0
- package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
- package/numkong/include/numkong/dots/serial.h +2867 -0
- package/numkong/include/numkong/dots/sierra.h +100 -0
- package/numkong/include/numkong/dots/skylake.h +207 -0
- package/numkong/include/numkong/dots/sme.h +5041 -0
- package/numkong/include/numkong/dots/smebi32.h +477 -0
- package/numkong/include/numkong/dots/smef64.h +1328 -0
- package/numkong/include/numkong/dots/smehalf.h +47 -0
- package/numkong/include/numkong/dots/v128relaxed.h +317 -0
- package/numkong/include/numkong/dots.h +3110 -0
- package/numkong/include/numkong/dots.hpp +641 -0
- package/numkong/include/numkong/each/README.md +465 -0
- package/numkong/include/numkong/each/haswell.h +1658 -0
- package/numkong/include/numkong/each/icelake.h +272 -0
- package/numkong/include/numkong/each/neon.h +1138 -0
- package/numkong/include/numkong/each/neonbfdot.h +211 -0
- package/numkong/include/numkong/each/neonhalf.h +318 -0
- package/numkong/include/numkong/each/rvv.h +1121 -0
- package/numkong/include/numkong/each/sapphire.h +343 -0
- package/numkong/include/numkong/each/serial.h +282 -0
- package/numkong/include/numkong/each/skylake.h +1562 -0
- package/numkong/include/numkong/each/v128relaxed.h +562 -0
- package/numkong/include/numkong/each.h +2232 -0
- package/numkong/include/numkong/each.hpp +434 -0
- package/numkong/include/numkong/geospatial/README.md +147 -0
- package/numkong/include/numkong/geospatial/haswell.h +633 -0
- package/numkong/include/numkong/geospatial/neon.h +615 -0
- package/numkong/include/numkong/geospatial/rvv.h +701 -0
- package/numkong/include/numkong/geospatial/serial.h +309 -0
- package/numkong/include/numkong/geospatial/skylake.h +613 -0
- package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
- package/numkong/include/numkong/geospatial.h +453 -0
- package/numkong/include/numkong/geospatial.hpp +235 -0
- package/numkong/include/numkong/matrix.hpp +336 -0
- package/numkong/include/numkong/maxsim/README.md +187 -0
- package/numkong/include/numkong/maxsim/alder.h +511 -0
- package/numkong/include/numkong/maxsim/genoa.h +115 -0
- package/numkong/include/numkong/maxsim/haswell.h +553 -0
- package/numkong/include/numkong/maxsim/icelake.h +480 -0
- package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
- package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
- package/numkong/include/numkong/maxsim/serial.h +490 -0
- package/numkong/include/numkong/maxsim/sme.h +993 -0
- package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
- package/numkong/include/numkong/maxsim.h +571 -0
- package/numkong/include/numkong/maxsim.hpp +133 -0
- package/numkong/include/numkong/mesh/README.md +219 -0
- package/numkong/include/numkong/mesh/haswell.h +2013 -0
- package/numkong/include/numkong/mesh/neon.h +1821 -0
- package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
- package/numkong/include/numkong/mesh/rvv.h +936 -0
- package/numkong/include/numkong/mesh/serial.h +721 -0
- package/numkong/include/numkong/mesh/skylake.h +2344 -0
- package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
- package/numkong/include/numkong/mesh.h +666 -0
- package/numkong/include/numkong/mesh.hpp +701 -0
- package/numkong/include/numkong/numkong.h +78 -0
- package/numkong/include/numkong/numkong.hpp +58 -0
- package/numkong/include/numkong/probability/README.md +177 -0
- package/numkong/include/numkong/probability/haswell.h +267 -0
- package/numkong/include/numkong/probability/neon.h +255 -0
- package/numkong/include/numkong/probability/rvv.h +414 -0
- package/numkong/include/numkong/probability/serial.h +181 -0
- package/numkong/include/numkong/probability/skylake.h +324 -0
- package/numkong/include/numkong/probability.h +380 -0
- package/numkong/include/numkong/probability.hpp +120 -0
- package/numkong/include/numkong/random.h +50 -0
- package/numkong/include/numkong/random.hpp +285 -0
- package/numkong/include/numkong/reduce/README.md +552 -0
- package/numkong/include/numkong/reduce/alder.h +636 -0
- package/numkong/include/numkong/reduce/genoa.h +201 -0
- package/numkong/include/numkong/reduce/haswell.h +3785 -0
- package/numkong/include/numkong/reduce/icelake.h +549 -0
- package/numkong/include/numkong/reduce/neon.h +3980 -0
- package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
- package/numkong/include/numkong/reduce/neonfhm.h +293 -0
- package/numkong/include/numkong/reduce/neonsdot.h +357 -0
- package/numkong/include/numkong/reduce/rvv.h +3533 -0
- package/numkong/include/numkong/reduce/serial.h +753 -0
- package/numkong/include/numkong/reduce/sierra.h +338 -0
- package/numkong/include/numkong/reduce/skylake.h +3794 -0
- package/numkong/include/numkong/reduce/sve.h +52 -0
- package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
- package/numkong/include/numkong/reduce.h +1582 -0
- package/numkong/include/numkong/reduce.hpp +778 -0
- package/numkong/include/numkong/scalar/README.md +89 -0
- package/numkong/include/numkong/scalar/haswell.h +122 -0
- package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
- package/numkong/include/numkong/scalar/neon.h +122 -0
- package/numkong/include/numkong/scalar/neonhalf.h +70 -0
- package/numkong/include/numkong/scalar/powervsx.h +96 -0
- package/numkong/include/numkong/scalar/rvv.h +211 -0
- package/numkong/include/numkong/scalar/sapphire.h +74 -0
- package/numkong/include/numkong/scalar/serial.h +332 -0
- package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
- package/numkong/include/numkong/scalar.h +696 -0
- package/numkong/include/numkong/set/README.md +179 -0
- package/numkong/include/numkong/set/haswell.h +334 -0
- package/numkong/include/numkong/set/icelake.h +485 -0
- package/numkong/include/numkong/set/loongsonasx.h +181 -0
- package/numkong/include/numkong/set/neon.h +363 -0
- package/numkong/include/numkong/set/powervsx.h +326 -0
- package/numkong/include/numkong/set/rvv.h +226 -0
- package/numkong/include/numkong/set/rvvbb.h +117 -0
- package/numkong/include/numkong/set/serial.h +174 -0
- package/numkong/include/numkong/set/sve.h +187 -0
- package/numkong/include/numkong/set/v128relaxed.h +240 -0
- package/numkong/include/numkong/set.h +471 -0
- package/numkong/include/numkong/set.hpp +114 -0
- package/numkong/include/numkong/sets/README.md +149 -0
- package/numkong/include/numkong/sets/haswell.h +63 -0
- package/numkong/include/numkong/sets/icelake.h +66 -0
- package/numkong/include/numkong/sets/loongsonasx.h +52 -0
- package/numkong/include/numkong/sets/neon.h +61 -0
- package/numkong/include/numkong/sets/powervsx.h +65 -0
- package/numkong/include/numkong/sets/serial.h +43 -0
- package/numkong/include/numkong/sets/smebi32.h +1135 -0
- package/numkong/include/numkong/sets/v128relaxed.h +58 -0
- package/numkong/include/numkong/sets.h +382 -0
- package/numkong/include/numkong/sparse/README.md +156 -0
- package/numkong/include/numkong/sparse/icelake.h +463 -0
- package/numkong/include/numkong/sparse/neon.h +288 -0
- package/numkong/include/numkong/sparse/serial.h +117 -0
- package/numkong/include/numkong/sparse/sve2.h +504 -0
- package/numkong/include/numkong/sparse/turin.h +322 -0
- package/numkong/include/numkong/sparse.h +363 -0
- package/numkong/include/numkong/sparse.hpp +113 -0
- package/numkong/include/numkong/spatial/README.md +439 -0
- package/numkong/include/numkong/spatial/alder.h +604 -0
- package/numkong/include/numkong/spatial/diamond.h +240 -0
- package/numkong/include/numkong/spatial/genoa.h +222 -0
- package/numkong/include/numkong/spatial/haswell.h +979 -0
- package/numkong/include/numkong/spatial/icelake.h +1067 -0
- package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
- package/numkong/include/numkong/spatial/neon.h +846 -0
- package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
- package/numkong/include/numkong/spatial/neonfp8.h +258 -0
- package/numkong/include/numkong/spatial/neonsdot.h +429 -0
- package/numkong/include/numkong/spatial/powervsx.h +738 -0
- package/numkong/include/numkong/spatial/rvv.h +991 -0
- package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
- package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
- package/numkong/include/numkong/spatial/serial.h +347 -0
- package/numkong/include/numkong/spatial/sierra.h +516 -0
- package/numkong/include/numkong/spatial/skylake.h +605 -0
- package/numkong/include/numkong/spatial/sve.h +246 -0
- package/numkong/include/numkong/spatial/svebfdot.h +125 -0
- package/numkong/include/numkong/spatial/svehalf.h +136 -0
- package/numkong/include/numkong/spatial/svesdot.h +143 -0
- package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
- package/numkong/include/numkong/spatial.h +1681 -0
- package/numkong/include/numkong/spatial.hpp +183 -0
- package/numkong/include/numkong/spatials/README.md +580 -0
- package/numkong/include/numkong/spatials/alder.h +94 -0
- package/numkong/include/numkong/spatials/diamond.h +82 -0
- package/numkong/include/numkong/spatials/genoa.h +94 -0
- package/numkong/include/numkong/spatials/graniteamx.h +173 -0
- package/numkong/include/numkong/spatials/haswell.h +219 -0
- package/numkong/include/numkong/spatials/icelake.h +113 -0
- package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
- package/numkong/include/numkong/spatials/neon.h +109 -0
- package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
- package/numkong/include/numkong/spatials/neonfhm.h +92 -0
- package/numkong/include/numkong/spatials/neonfp8.h +111 -0
- package/numkong/include/numkong/spatials/neonsdot.h +143 -0
- package/numkong/include/numkong/spatials/powervsx.h +153 -0
- package/numkong/include/numkong/spatials/rvv.h +1976 -0
- package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
- package/numkong/include/numkong/spatials/serial.h +248 -0
- package/numkong/include/numkong/spatials/sierra.h +96 -0
- package/numkong/include/numkong/spatials/skylake.h +184 -0
- package/numkong/include/numkong/spatials/sme.h +1927 -0
- package/numkong/include/numkong/spatials/smef64.h +483 -0
- package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
- package/numkong/include/numkong/spatials.h +3374 -0
- package/numkong/include/numkong/spatials.hpp +509 -0
- package/numkong/include/numkong/tensor.hpp +1981 -0
- package/numkong/include/numkong/trigonometry/README.md +184 -0
- package/numkong/include/numkong/trigonometry/haswell.h +653 -0
- package/numkong/include/numkong/trigonometry/neon.h +638 -0
- package/numkong/include/numkong/trigonometry/rvv.h +700 -0
- package/numkong/include/numkong/trigonometry/serial.h +703 -0
- package/numkong/include/numkong/trigonometry/skylake.h +725 -0
- package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
- package/numkong/include/numkong/trigonometry.h +467 -0
- package/numkong/include/numkong/trigonometry.hpp +166 -0
- package/numkong/include/numkong/types.h +1695 -0
- package/numkong/include/numkong/types.hpp +6027 -0
- package/numkong/include/numkong/vector.hpp +766 -0
- package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
- package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
- package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
- package/numkong/javascript/README.md +254 -0
- package/numkong/javascript/node-gyp-build.d.ts +4 -0
- package/numkong/javascript/numkong-browser.ts +40 -0
- package/numkong/javascript/numkong-wasm.ts +750 -0
- package/numkong/javascript/numkong.c +712 -0
- package/numkong/javascript/numkong.ts +613 -0
- package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
- package/numkong/javascript/tsconfig-cjs.json +13 -0
- package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
- package/numkong/javascript/types.ts +784 -0
- package/numkong/numkong.gypi +104 -0
- package/numkong/package.json +108 -0
- package/numkong/probes/arm_neon.c +8 -0
- package/numkong/probes/arm_neon_bfdot.c +9 -0
- package/numkong/probes/arm_neon_fhm.c +9 -0
- package/numkong/probes/arm_neon_half.c +8 -0
- package/numkong/probes/arm_neon_sdot.c +9 -0
- package/numkong/probes/arm_neonfp8.c +9 -0
- package/numkong/probes/arm_sme.c +16 -0
- package/numkong/probes/arm_sme2.c +16 -0
- package/numkong/probes/arm_sme2p1.c +16 -0
- package/numkong/probes/arm_sme_bf16.c +16 -0
- package/numkong/probes/arm_sme_bi32.c +16 -0
- package/numkong/probes/arm_sme_f64.c +16 -0
- package/numkong/probes/arm_sme_fa64.c +14 -0
- package/numkong/probes/arm_sme_half.c +16 -0
- package/numkong/probes/arm_sme_lut2.c +15 -0
- package/numkong/probes/arm_sve.c +18 -0
- package/numkong/probes/arm_sve2.c +20 -0
- package/numkong/probes/arm_sve2p1.c +18 -0
- package/numkong/probes/arm_sve_bfdot.c +20 -0
- package/numkong/probes/arm_sve_half.c +18 -0
- package/numkong/probes/arm_sve_sdot.c +21 -0
- package/numkong/probes/loongarch_lasx.c +12 -0
- package/numkong/probes/power_vsx.c +12 -0
- package/numkong/probes/probe.js +127 -0
- package/numkong/probes/riscv_rvv.c +14 -0
- package/numkong/probes/riscv_rvv_bb.c +15 -0
- package/numkong/probes/riscv_rvv_bf16.c +17 -0
- package/numkong/probes/riscv_rvv_half.c +14 -0
- package/numkong/probes/wasm_v128relaxed.c +11 -0
- package/numkong/probes/x86_alder.c +17 -0
- package/numkong/probes/x86_diamond.c +17 -0
- package/numkong/probes/x86_genoa.c +17 -0
- package/numkong/probes/x86_graniteamx.c +19 -0
- package/numkong/probes/x86_haswell.c +11 -0
- package/numkong/probes/x86_icelake.c +17 -0
- package/numkong/probes/x86_sapphire.c +16 -0
- package/numkong/probes/x86_sapphireamx.c +18 -0
- package/numkong/probes/x86_sierra.c +17 -0
- package/numkong/probes/x86_skylake.c +15 -0
- package/numkong/probes/x86_turin.c +17 -0
- package/numkong/rust/README.md +698 -0
- package/numkong/rust/capabilities.rs +96 -0
- package/numkong/rust/cast.rs +314 -0
- package/numkong/rust/curved.rs +391 -0
- package/numkong/rust/each.rs +2721 -0
- package/numkong/rust/geospatial.rs +343 -0
- package/numkong/rust/matrix.rs +5424 -0
- package/numkong/rust/maxsim.rs +540 -0
- package/numkong/rust/mesh.rs +837 -0
- package/numkong/rust/numkong.rs +409 -0
- package/numkong/rust/probability.rs +272 -0
- package/numkong/rust/reduce.rs +1249 -0
- package/numkong/rust/set.rs +194 -0
- package/numkong/rust/sparse.rs +513 -0
- package/numkong/rust/spatial.rs +1815 -0
- package/numkong/rust/tensor.rs +7565 -0
- package/numkong/rust/types.rs +3666 -0
- package/numkong/rust/vector.rs +1899 -0
- package/numkong/rustfmt.toml +2 -0
- package/numkong/swift/Matrix.swift +1388 -0
- package/numkong/swift/MaxSim.swift +151 -0
- package/numkong/swift/NumKong.swift +283 -0
- package/numkong/swift/Numerics.swift +329 -0
- package/numkong/swift/README.md +433 -0
- package/numkong/swift/Scalar.swift +741 -0
- package/numkong/swift/Tensor.swift +209 -0
- package/numkong/test/README.md +315 -0
- package/numkong/test/playwright.config.ts +16 -0
- package/numkong/test/swift/Test.swift +534 -0
- package/numkong/test/test-browser-bundle-runner.mjs +36 -0
- package/numkong/test/test-browser-bundle.html +188 -0
- package/numkong/test/test-browser-runner.mjs +43 -0
- package/numkong/test/test-browser.html +305 -0
- package/numkong/test/test-dtypes.mjs +453 -0
- package/numkong/test/test-wasm.mjs +267 -0
- package/numkong/test/test.cpp +442 -0
- package/numkong/test/test.hpp +580 -0
- package/numkong/test/test.mjs +363 -0
- package/numkong/test/test_base.py +1041 -0
- package/numkong/test/test_cast.cpp +242 -0
- package/numkong/test/test_cross.hpp +551 -0
- package/numkong/test/test_cross.py +467 -0
- package/numkong/test/test_cross_amx.cpp +50 -0
- package/numkong/test/test_cross_arm.cpp +225 -0
- package/numkong/test/test_cross_blas.cpp +354 -0
- package/numkong/test/test_cross_loongarch.cpp +90 -0
- package/numkong/test/test_cross_power.cpp +73 -0
- package/numkong/test/test_cross_rvv.cpp +109 -0
- package/numkong/test/test_cross_serial.cpp +181 -0
- package/numkong/test/test_cross_sme.cpp +148 -0
- package/numkong/test/test_cross_wasm.cpp +141 -0
- package/numkong/test/test_cross_x86.cpp +442 -0
- package/numkong/test/test_curved.cpp +182 -0
- package/numkong/test/test_curved.py +207 -0
- package/numkong/test/test_dot.cpp +353 -0
- package/numkong/test/test_dot.py +296 -0
- package/numkong/test/test_each.cpp +437 -0
- package/numkong/test/test_each.py +756 -0
- package/numkong/test/test_geospatial.cpp +155 -0
- package/numkong/test/test_geospatial.py +241 -0
- package/numkong/test/test_maxsim.cpp +138 -0
- package/numkong/test/test_maxsim.py +209 -0
- package/numkong/test/test_mesh.cpp +203 -0
- package/numkong/test/test_mesh.py +394 -0
- package/numkong/test/test_probability.cpp +136 -0
- package/numkong/test/test_probability.py +166 -0
- package/numkong/test/test_reduce.cpp +563 -0
- package/numkong/test/test_reduce.py +781 -0
- package/numkong/test/test_set.cpp +151 -0
- package/numkong/test/test_set.py +120 -0
- package/numkong/test/test_similarities.py +579 -0
- package/numkong/test/test_sparse.cpp +121 -0
- package/numkong/test/test_sparse.py +118 -0
- package/numkong/test/test_spatial.cpp +518 -0
- package/numkong/test/test_spatial.py +269 -0
- package/numkong/test/test_tensor.cpp +884 -0
- package/numkong/test/test_tensor.py +1417 -0
- package/numkong/test/test_trigonometry.cpp +156 -0
- package/numkong/test/test_trigonometry.py +180 -0
- package/package.json +7 -8
- package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
- package/prebuilds/linux-arm64/usearch.node +0 -0
- package/prebuilds/linux-x64/usearch.node +0 -0
- package/fp16/CMakeLists.txt +0 -176
- package/fp16/LICENSE +0 -11
- package/fp16/README.md +0 -20
- package/fp16/bench/alt-element.cc +0 -89
- package/fp16/bench/from-alt-array.cc +0 -175
- package/fp16/bench/from-ieee-array.cc +0 -399
- package/fp16/bench/ieee-element.cc +0 -272
- package/fp16/bench/to-alt-array.cc +0 -91
- package/fp16/bench/to-ieee-array.cc +0 -303
- package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
- package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
- package/fp16/cmake/DownloadPSimd.cmake +0 -15
- package/fp16/configure.py +0 -65
- package/fp16/confu.yaml +0 -8
- package/fp16/include/fp16/__init__.py +0 -0
- package/fp16/include/fp16/avx.py +0 -50
- package/fp16/include/fp16/avx2.py +0 -53
- package/fp16/include/fp16/bitcasts.h +0 -92
- package/fp16/include/fp16/fp16.h +0 -451
- package/fp16/include/fp16/psimd.h +0 -131
- package/fp16/include/fp16.h +0 -11
- package/fp16/jni/Android.mk +0 -6
- package/fp16/jni/Application.mk +0 -4
- package/fp16/test/alt-from-fp32-value.cc +0 -498
- package/fp16/test/alt-to-fp32-bits.cc +0 -263
- package/fp16/test/alt-to-fp32-psimd.cc +0 -145
- package/fp16/test/alt-to-fp32-value.cc +0 -348
- package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
- package/fp16/test/bitcasts.cc +0 -56
- package/fp16/test/ieee-from-fp32-value.cc +0 -523
- package/fp16/test/ieee-to-fp32-bits.cc +0 -333
- package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
- package/fp16/test/ieee-to-fp32-value.cc +0 -420
- package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
- package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
- package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
- package/fp16/test/peachpy/stubs.py +0 -38
- package/fp16/test/tables.cc +0 -530
- package/fp16/test/tables.h +0 -13
- package/fp16/third-party/THHalf.h +0 -92
- package/fp16/third-party/eigen-half.h +0 -170
- package/fp16/third-party/float16-compressor.h +0 -80
- package/fp16/third-party/half.hpp +0 -2916
- package/fp16/third-party/npy-halffloat.h +0 -328
- package/simsimd/.git-blame-ignore-revs +0 -2
- package/simsimd/CONTRIBUTING.md +0 -321
- package/simsimd/Cargo.toml +0 -49
- package/simsimd/MANIFEST.in +0 -4
- package/simsimd/Package.swift +0 -28
- package/simsimd/README.md +0 -1493
- package/simsimd/binding.gyp +0 -35
- package/simsimd/build.rs +0 -70
- package/simsimd/c/lib.c +0 -374
- package/simsimd/include/module.modulemap +0 -4
- package/simsimd/include/simsimd/binary.h +0 -486
- package/simsimd/include/simsimd/curved.h +0 -1541
- package/simsimd/include/simsimd/dot.h +0 -1853
- package/simsimd/include/simsimd/elementwise.h +0 -2465
- package/simsimd/include/simsimd/geospatial.h +0 -43
- package/simsimd/include/simsimd/mesh.h +0 -69
- package/simsimd/include/simsimd/probability.h +0 -606
- package/simsimd/include/simsimd/simsimd.h +0 -2567
- package/simsimd/include/simsimd/sparse.h +0 -1384
- package/simsimd/include/simsimd/spatial.h +0 -2335
- package/simsimd/include/simsimd/types.h +0 -666
- package/simsimd/javascript/fallback.ts +0 -233
- package/simsimd/javascript/lib.c +0 -125
- package/simsimd/javascript/node-gyp-build.d.ts +0 -1
- package/simsimd/javascript/simsimd.ts +0 -179
- package/simsimd/javascript/tsconfig-cjs.json +0 -8
- package/simsimd/package-lock.json +0 -1761
- package/simsimd/package.json +0 -61
- package/simsimd/rust/lib.rs +0 -1821
- package/simsimd/scripts/bench.cxx +0 -1170
- package/simsimd/scripts/bench.ipynb +0 -187
- package/simsimd/scripts/bench.js +0 -127
- package/simsimd/scripts/bench.rs +0 -876
- package/simsimd/scripts/bench_vectors.py +0 -734
- package/simsimd/scripts/bench_vectors_live.py +0 -213
- package/simsimd/scripts/test.c +0 -187
- package/simsimd/scripts/test.mjs +0 -220
- package/simsimd/scripts/test.py +0 -1505
- package/simsimd/swift/SimSIMD.swift +0 -149
- package/simsimd/swift/Test.swift +0 -128
- /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
- /package/{simsimd → numkong}/LICENSE +0 -0
- /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
- /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
|
@@ -1,1170 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SimSIMD C++ Benchmark Suite
|
|
3
|
-
*
|
|
4
|
-
* Comprehensive benchmarks comparing SimSIMD SIMD-optimized functions against
|
|
5
|
-
* baseline implementations using Google Benchmark framework. Run with:
|
|
6
|
-
*
|
|
7
|
-
* ```bash
|
|
8
|
-
* cmake -B build_release -D SIMSIMD_BUILD_BENCHMARKS=1
|
|
9
|
-
* cmake --build build_release
|
|
10
|
-
* build_release/simsimd_bench
|
|
11
|
-
* ```
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
#include <array> // `std::array`
|
|
15
|
-
#include <cmath> // `std::sqrt`
|
|
16
|
-
#include <cstdlib> // `std::aligned_alloc`
|
|
17
|
-
#include <cstring> // `std::memcpy`
|
|
18
|
-
#include <numeric> // `std::accumulate`
|
|
19
|
-
#include <random> // `std::uniform_int_distribution`
|
|
20
|
-
#include <thread> // `std::thread`
|
|
21
|
-
#include <tuple> // `std::tuple` for callable introspection
|
|
22
|
-
#include <type_traits> // `std::numeric_limits`
|
|
23
|
-
#include <unordered_set> // `std::unordered_set`
|
|
24
|
-
#include <vector> // `std::vector`
|
|
25
|
-
|
|
26
|
-
#include <benchmark/benchmark.h>
|
|
27
|
-
|
|
28
|
-
#if !defined(SIMSIMD_BUILD_BENCHMARKS_WITH_CBLAS)
|
|
29
|
-
#define SIMSIMD_BUILD_BENCHMARKS_WITH_CBLAS 0
|
|
30
|
-
#endif
|
|
31
|
-
#if SIMSIMD_BUILD_BENCHMARKS_WITH_CBLAS
|
|
32
|
-
#include <cblas.h>
|
|
33
|
-
#endif
|
|
34
|
-
|
|
35
|
-
// It's important to note, that out compression/decompression routines
|
|
36
|
-
// are quite inaccurate. They are not meant to be used in production code.
|
|
37
|
-
// So when benchmarking, if possible, please use the native types, if those
|
|
38
|
-
// are implemented.
|
|
39
|
-
#define SIMSIMD_NATIVE_F16 1
|
|
40
|
-
#define SIMSIMD_NATIVE_BF16 1
|
|
41
|
-
#include <simsimd/simsimd.h>
|
|
42
|
-
|
|
43
|
-
constexpr std::size_t default_seconds = 10;
|
|
44
|
-
constexpr std::size_t default_threads = 1;
|
|
45
|
-
constexpr simsimd_distance_t signaling_distance = std::numeric_limits<simsimd_distance_t>::signaling_NaN();
|
|
46
|
-
|
|
47
|
-
/// For sub-byte data types
|
|
48
|
-
/// Can be overridden at runtime via `SIMSIMD_BENCH_DENSE_DIMENSIONS` environment variable
|
|
49
|
-
std::size_t dense_dimensions = 1536;
|
|
50
|
-
/// Has quadratic impact on the number of operations
|
|
51
|
-
/// Can be overridden at runtime via `SIMSIMD_BENCH_CURVED_DIMENSIONS` environment variable
|
|
52
|
-
std::size_t curved_dimensions = 8;
|
|
53
|
-
|
|
54
|
-
namespace bm = benchmark;
|
|
55
|
-
|
|
56
|
-
// clang-format off
|
|
57
|
-
template <simsimd_datatype_t> struct datatype_enum_to_type_gt { using value_t = void; using scalar_t = void; static constexpr std::size_t components_k = 1; };
|
|
58
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_f64_k> { using value_t = simsimd_f64_t; using scalar_t = simsimd_f64_t; static constexpr std::size_t components_k = 1; };
|
|
59
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_f32_k> { using value_t = simsimd_f32_t; using scalar_t = simsimd_f32_t; static constexpr std::size_t components_k = 1; };
|
|
60
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_f16_k> { using value_t = simsimd_f16_t; using scalar_t = simsimd_f16_t; static constexpr std::size_t components_k = 1; };
|
|
61
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_bf16_k> { using value_t = simsimd_bf16_t; using scalar_t = simsimd_bf16_t; static constexpr std::size_t components_k = 1; };
|
|
62
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_f64c_k> { using value_t = simsimd_f64c_t; using scalar_t = simsimd_f64_t; static constexpr std::size_t components_k = 2; };
|
|
63
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_f32c_k> { using value_t = simsimd_f32c_t; using scalar_t = simsimd_f32_t; static constexpr std::size_t components_k = 2; };
|
|
64
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_f16c_k> { using value_t = simsimd_f16c_t; using scalar_t = simsimd_f16_t; static constexpr std::size_t components_k = 2; };
|
|
65
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_bf16c_k> { using value_t = simsimd_bf16c_t; using scalar_t = simsimd_bf16_t; static constexpr std::size_t components_k = 2; };
|
|
66
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_b8_k> { using value_t = simsimd_b8_t; using scalar_t = simsimd_b8_t; static constexpr std::size_t components_k = 1; };
|
|
67
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_i8_k> { using value_t = simsimd_i8_t; using scalar_t = simsimd_i8_t; static constexpr std::size_t components_k = 1; };
|
|
68
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_u8_k> { using value_t = simsimd_u8_t; using scalar_t = simsimd_u8_t; static constexpr std::size_t components_k = 1; };
|
|
69
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_i16_k> { using value_t = simsimd_i16_t; using scalar_t = simsimd_i16_t; static constexpr std::size_t components_k = 1; };
|
|
70
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_u16_k> { using value_t = simsimd_u16_t; using scalar_t = simsimd_u16_t; static constexpr std::size_t components_k = 1; };
|
|
71
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_i32_k> { using value_t = simsimd_i32_t; using scalar_t = simsimd_i32_t; static constexpr std::size_t components_k = 1; };
|
|
72
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_u32_k> { using value_t = simsimd_u32_t; using scalar_t = simsimd_u32_t; static constexpr std::size_t components_k = 1; };
|
|
73
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_i64_k> { using value_t = simsimd_i64_t; using scalar_t = simsimd_i64_t; static constexpr std::size_t components_k = 1; };
|
|
74
|
-
template <> struct datatype_enum_to_type_gt<simsimd_datatype_u64_k> { using value_t = simsimd_u64_t; using scalar_t = simsimd_u64_t; static constexpr std::size_t components_k = 1; };
|
|
75
|
-
// clang-format on
|
|
76
|
-
|
|
77
|
-
template <std::size_t multiple>
|
|
78
|
-
constexpr std::size_t divide_round_up(std::size_t n) {
|
|
79
|
-
return ((n + multiple - 1) / multiple) * multiple;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* @brief Vector-like fixed capacity buffer, ensuring cache-line alignment.
|
|
84
|
-
* @tparam datatype_ak The data type of the vector elements, represented as a `simsimd_datatype_t`.
|
|
85
|
-
*/
|
|
86
|
-
template <simsimd_datatype_t datatype_ak>
|
|
87
|
-
struct vector_gt {
|
|
88
|
-
using datatype_reflection_t = datatype_enum_to_type_gt<datatype_ak>;
|
|
89
|
-
using scalar_t = typename datatype_reflection_t::scalar_t;
|
|
90
|
-
using value_t = typename datatype_reflection_t::value_t;
|
|
91
|
-
static constexpr std::size_t components_k = datatype_reflection_t::components_k;
|
|
92
|
-
|
|
93
|
-
static constexpr bool is_integral =
|
|
94
|
-
datatype_ak == datatype_ak == simsimd_datatype_b8_k || //
|
|
95
|
-
datatype_ak == simsimd_datatype_i8_k || datatype_ak == simsimd_datatype_u8_k || //
|
|
96
|
-
datatype_ak == simsimd_datatype_i16_k || datatype_ak == simsimd_datatype_u16_k || //
|
|
97
|
-
datatype_ak == simsimd_datatype_i32_k || datatype_ak == simsimd_datatype_u32_k ||
|
|
98
|
-
datatype_ak == simsimd_datatype_i64_k || datatype_ak == simsimd_datatype_u64_k;
|
|
99
|
-
static constexpr std::size_t cacheline_length = 64;
|
|
100
|
-
|
|
101
|
-
value_t *values_ptr_ = nullptr;
|
|
102
|
-
std::size_t values_count_ = 0;
|
|
103
|
-
|
|
104
|
-
vector_gt() = default;
|
|
105
|
-
vector_gt(std::size_t values_count) noexcept(false)
|
|
106
|
-
: values_count_(values_count),
|
|
107
|
-
values_ptr_(static_cast<value_t *>(std::aligned_alloc(
|
|
108
|
-
cacheline_length, divide_round_up<cacheline_length>(values_count * sizeof(value_t))))) {
|
|
109
|
-
if (!values_ptr_) throw std::bad_alloc();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
~vector_gt() noexcept { std::free(values_ptr_); }
|
|
113
|
-
|
|
114
|
-
vector_gt(vector_gt const &other) : vector_gt(other.size()) {
|
|
115
|
-
std::memcpy(values_ptr_, other.values_ptr_, divide_round_up<cacheline_length>(values_count_ * sizeof(value_t)));
|
|
116
|
-
}
|
|
117
|
-
vector_gt &operator=(vector_gt const &other) {
|
|
118
|
-
if (this != &other) {
|
|
119
|
-
if (values_count_ != other.size()) {
|
|
120
|
-
std::free(values_ptr_);
|
|
121
|
-
values_count_ = other.size();
|
|
122
|
-
values_ptr_ = static_cast<value_t *>(std::aligned_alloc(
|
|
123
|
-
cacheline_length, divide_round_up<cacheline_length>(values_count_ * sizeof(value_t))));
|
|
124
|
-
if (!values_ptr_) throw std::bad_alloc();
|
|
125
|
-
}
|
|
126
|
-
std::memcpy(values_ptr_, other.values_ptr_,
|
|
127
|
-
divide_round_up<cacheline_length>(values_count_ * sizeof(value_t)));
|
|
128
|
-
}
|
|
129
|
-
return *this;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
value_t *data() noexcept { return values_ptr_; }
|
|
133
|
-
value_t const *data() const noexcept { return values_ptr_; }
|
|
134
|
-
std::size_t size() const noexcept { return values_count_; }
|
|
135
|
-
std::size_t size_bytes() const noexcept {
|
|
136
|
-
return divide_round_up<cacheline_length>(values_count_ * sizeof(value_t));
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
scalar_t *data_scalars() noexcept { return reinterpret_cast<scalar_t *>(data()); }
|
|
140
|
-
scalar_t const *data_scalars() const noexcept { return reinterpret_cast<scalar_t *>(data()); }
|
|
141
|
-
std::size_t size_scalars() const noexcept { return size() * components_k; }
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* @brief Broadcast a scalar value to all elements of the vector.
|
|
145
|
-
* @param v The scalar value to broadcast.
|
|
146
|
-
*/
|
|
147
|
-
void set(scalar_t v) noexcept {
|
|
148
|
-
for (std::size_t i = 0; i != size_scalars(); ++i) data_scalars()[i] = v;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* @brief Compresses a double value into the vector's scalar type.
|
|
153
|
-
* @param from The double value to compress.
|
|
154
|
-
* @param to The scalar type where the compressed value will be stored.
|
|
155
|
-
*/
|
|
156
|
-
static void compress(double const &from, scalar_t &to) noexcept {
|
|
157
|
-
// In a NaN, the sign bit is irrelevant, mantissa describes the kind of NaN,
|
|
158
|
-
// and the exponent is all ones - we can only check the the exponent bits.
|
|
159
|
-
// Brain float is similar: https://en.wikipedia.org/wiki/Bfloat16_floating-point_format
|
|
160
|
-
constexpr unsigned short exponent_mask_f16 = 0b0111110000000000; // 1 sign, 5 exp, 10 mantissa
|
|
161
|
-
constexpr unsigned short exponent_mask_bf16 = 0b0111111110000000; // 1 sign, 8 exp, 7 mantissa
|
|
162
|
-
constexpr unsigned int exponent_mask_f32 = 0b01111111100000000000000000000000; // 1 sign, 8 exp, 23 mantissa
|
|
163
|
-
constexpr unsigned long long exponent_mask_f64 = // 1 sign, 11 exp, 52 mantissa
|
|
164
|
-
0b011111111110000000000000000000000000000000000000000000000000000;
|
|
165
|
-
|
|
166
|
-
#if !SIMSIMD_NATIVE_BF16
|
|
167
|
-
if constexpr (datatype_ak == simsimd_datatype_bf16_k || datatype_ak == simsimd_datatype_bf16c_k) {
|
|
168
|
-
simsimd_f32_to_bf16(from, &to);
|
|
169
|
-
if ((to & exponent_mask_bf16) == exponent_mask_bf16) to = 0;
|
|
170
|
-
static_assert(sizeof(scalar_t) == sizeof(simsimd_bf16_t));
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
#endif
|
|
174
|
-
#if !SIMSIMD_NATIVE_F16
|
|
175
|
-
if constexpr (datatype_ak == simsimd_datatype_f16_k || datatype_ak == simsimd_datatype_f16c_k) {
|
|
176
|
-
simsimd_f32_to_f16(from, &to);
|
|
177
|
-
if ((to & exponent_mask_f16) == exponent_mask_f16) to = 0;
|
|
178
|
-
static_assert(sizeof(scalar_t) == sizeof(simsimd_f16_t));
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
#endif
|
|
182
|
-
to = static_cast<scalar_t>(from);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* @brief Decompresses the vector's scalar type into a double value.
|
|
187
|
-
* @param from The compressed scalar value to decompress.
|
|
188
|
-
* @return The decompressed double value.
|
|
189
|
-
*/
|
|
190
|
-
static double uncompress(scalar_t const &from) noexcept {
|
|
191
|
-
#if !SIMSIMD_NATIVE_BF16
|
|
192
|
-
if constexpr (datatype_ak == simsimd_datatype_bf16_k || datatype_ak == simsimd_datatype_bf16c_k) {
|
|
193
|
-
return simsimd_bf16_to_f32((simsimd_bf16_t const *)&from);
|
|
194
|
-
}
|
|
195
|
-
#endif
|
|
196
|
-
#if !SIMSIMD_NATIVE_F16
|
|
197
|
-
if constexpr (datatype_ak == simsimd_datatype_f16_k || datatype_ak == simsimd_datatype_f16c_k) {
|
|
198
|
-
return simsimd_f16_to_f32((simsimd_f16_t const *)&from);
|
|
199
|
-
}
|
|
200
|
-
#endif
|
|
201
|
-
return from;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* @brief Randomizes the vector elements with normalized values.
|
|
206
|
-
*
|
|
207
|
-
* This method fills the vector with random values. For floating-point types, the vector is normalized
|
|
208
|
-
* so that the sum of the squares of its elements equals 1. For integral types, the values are generated
|
|
209
|
-
* within the range of the scalar type.
|
|
210
|
-
*/
|
|
211
|
-
void randomize(std::uint32_t seed) noexcept {
|
|
212
|
-
|
|
213
|
-
static std::mt19937 generator;
|
|
214
|
-
generator.seed(seed);
|
|
215
|
-
|
|
216
|
-
if constexpr (is_integral) {
|
|
217
|
-
std::uniform_int_distribution<scalar_t> distribution(std::numeric_limits<scalar_t>::min(),
|
|
218
|
-
std::numeric_limits<scalar_t>::max());
|
|
219
|
-
for (std::size_t i = 0; i != size_scalars(); ++i) { data_scalars()[i] = distribution(generator); }
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
// Using non-uniform distribution helps detect tail errors
|
|
223
|
-
std::normal_distribution<double> distribution(0.1, 1.0);
|
|
224
|
-
double squared_sum = 0.0;
|
|
225
|
-
for (std::size_t i = 0; i != size_scalars(); ++i) {
|
|
226
|
-
double a_i = distribution(generator);
|
|
227
|
-
squared_sum += a_i * a_i;
|
|
228
|
-
compress(a_i, data_scalars()[i]);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Normalize the vectors:
|
|
232
|
-
squared_sum = std::sqrt(squared_sum);
|
|
233
|
-
for (std::size_t i = 0; i != size_scalars(); ++i) {
|
|
234
|
-
compress(uncompress(data_scalars()[i]) / squared_sum, data_scalars()[i]);
|
|
235
|
-
// Zero out NaNs
|
|
236
|
-
if (std::isnan(uncompress(data_scalars()[i]))) data_scalars()[i] = 0;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
template <simsimd_datatype_t datatype_ak>
|
|
243
|
-
struct vectors_pair_gt {
|
|
244
|
-
using vector_t = vector_gt<datatype_ak>;
|
|
245
|
-
using scalar_t = typename vector_t::scalar_t;
|
|
246
|
-
static constexpr bool is_integral = vector_t::is_integral;
|
|
247
|
-
|
|
248
|
-
vector_t a;
|
|
249
|
-
vector_t b;
|
|
250
|
-
|
|
251
|
-
vectors_pair_gt() noexcept = default;
|
|
252
|
-
vectors_pair_gt(std::size_t dimensions) noexcept : a(dimensions), b(dimensions) {}
|
|
253
|
-
vectors_pair_gt(std::size_t size_a, std::size_t size_b) noexcept : a(size_a), b(size_b) {}
|
|
254
|
-
vectors_pair_gt(vectors_pair_gt const &other) noexcept(false) : a(other.a), b(other.b) {}
|
|
255
|
-
vectors_pair_gt &operator=(vectors_pair_gt const &other) noexcept(false) {
|
|
256
|
-
if (this != &other) a = other.a, b = other.b;
|
|
257
|
-
return *this;
|
|
258
|
-
}
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* @brief Measures the performance of a @b dense metric function against a baseline using Google Benchmark.
|
|
263
|
-
* @tparam pair_at The type representing the vector pair used in the measurement.
|
|
264
|
-
* @tparam metric_at The type of the metric function (default is void).
|
|
265
|
-
* @param state The benchmark state object provided by Google Benchmark.
|
|
266
|
-
* @param metric The metric function to benchmark.
|
|
267
|
-
* @param baseline The baseline function to compare against.
|
|
268
|
-
* @param dimensions The number of dimensions in the vectors.
|
|
269
|
-
*/
|
|
270
|
-
template <typename pair_at, typename metric_at = void>
|
|
271
|
-
void measure_dense(bm::State &state, metric_at metric, metric_at baseline, std::size_t dimensions) {
|
|
272
|
-
|
|
273
|
-
using pair_t = pair_at;
|
|
274
|
-
using vector_t = typename pair_at::vector_t;
|
|
275
|
-
|
|
276
|
-
auto call_baseline = [&](pair_t &pair) -> double {
|
|
277
|
-
// Output for real vectors have a single dimensions.
|
|
278
|
-
// Output for complex vectors have two dimensions.
|
|
279
|
-
simsimd_distance_t results[2] = {signaling_distance, signaling_distance};
|
|
280
|
-
baseline(pair.a.data(), pair.b.data(), pair.a.size(), &results[0]);
|
|
281
|
-
return results[0];
|
|
282
|
-
};
|
|
283
|
-
auto call_contender = [&](pair_t &pair) -> double {
|
|
284
|
-
// Output for real vectors have a single dimensions.
|
|
285
|
-
// Output for complex vectors have two dimensions.
|
|
286
|
-
simsimd_distance_t results[2] = {signaling_distance, signaling_distance};
|
|
287
|
-
metric(pair.a.data(), pair.b.data(), pair.a.size(), &results[0]);
|
|
288
|
-
return results[0];
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
// Let's average the distance results over many pairs.
|
|
292
|
-
constexpr std::size_t pairs_count = 128;
|
|
293
|
-
std::vector<pair_t> pairs(pairs_count);
|
|
294
|
-
for (std::size_t i = 0; i != pairs.size(); ++i) {
|
|
295
|
-
auto &pair = pairs[i];
|
|
296
|
-
pair.a = pair.b = vector_t(dimensions);
|
|
297
|
-
pair.a.randomize(static_cast<std::uint32_t>(i)), pair.b.randomize(static_cast<std::uint32_t>(i) + 54321u);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// Initialize the output buffers for distance calculations.
|
|
301
|
-
std::vector<double> results_baseline(pairs.size());
|
|
302
|
-
std::vector<double> results_contender(pairs.size());
|
|
303
|
-
for (std::size_t i = 0; i != pairs.size(); ++i)
|
|
304
|
-
results_baseline[i] = call_baseline(pairs[i]), results_contender[i] = call_contender(pairs[i]);
|
|
305
|
-
|
|
306
|
-
// The actual benchmarking loop.
|
|
307
|
-
std::size_t iterations = 0;
|
|
308
|
-
for (auto _ : state)
|
|
309
|
-
bm::DoNotOptimize((results_contender[iterations & (pairs_count - 1)] =
|
|
310
|
-
call_contender(pairs[iterations & (pairs_count - 1)]))),
|
|
311
|
-
iterations++;
|
|
312
|
-
|
|
313
|
-
// Measure the mean absolute delta and relative error.
|
|
314
|
-
double mean_delta = 0, mean_relative_error = 0;
|
|
315
|
-
for (std::size_t i = 0; i != pairs.size(); ++i) {
|
|
316
|
-
auto abs_delta = std::abs(results_contender[i] - results_baseline[i]);
|
|
317
|
-
mean_delta += abs_delta;
|
|
318
|
-
double error = abs_delta != 0 && results_baseline[i] != 0 ? abs_delta / std::abs(results_baseline[i]) : 0;
|
|
319
|
-
mean_relative_error += error;
|
|
320
|
-
}
|
|
321
|
-
mean_delta /= pairs.size();
|
|
322
|
-
mean_relative_error /= pairs.size();
|
|
323
|
-
state.counters["abs_delta"] = mean_delta;
|
|
324
|
-
state.counters["relative_error"] = mean_relative_error;
|
|
325
|
-
state.counters["bytes"] = bm::Counter(iterations * pairs[0].a.size_bytes() * 2, bm::Counter::kIsRate);
|
|
326
|
-
state.counters["pairs"] = bm::Counter(iterations, bm::Counter::kIsRate);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* @brief Measures the performance of a @b curved metric function against a baseline using Google Benchmark.
|
|
331
|
-
* @tparam pair_at The type representing the vector pair used in the measurement.
|
|
332
|
-
* @tparam metric_at The type of the metric function (default is void).
|
|
333
|
-
* @param state The benchmark state object provided by Google Benchmark.
|
|
334
|
-
* @param metric The metric function to benchmark.
|
|
335
|
-
* @param baseline The baseline function to compare against.
|
|
336
|
-
* @param dimensions The number of dimensions in the vectors.
|
|
337
|
-
*/
|
|
338
|
-
template <typename pair_at, typename metric_at = void>
|
|
339
|
-
void measure_curved(bm::State &state, metric_at metric, metric_at baseline, std::size_t dimensions) {
|
|
340
|
-
|
|
341
|
-
using pair_t = pair_at;
|
|
342
|
-
using vector_t = typename pair_at::vector_t;
|
|
343
|
-
|
|
344
|
-
auto call_baseline = [&](pair_t const &pair, vector_t const &tensor) -> double {
|
|
345
|
-
simsimd_distance_t results[2] = {signaling_distance, 0};
|
|
346
|
-
baseline(pair.a.data(), pair.b.data(), tensor.data(), pair.a.size(), &results[0]);
|
|
347
|
-
return results[0] + results[1];
|
|
348
|
-
};
|
|
349
|
-
auto call_contender = [&](pair_t const &pair, vector_t const &tensor) -> double {
|
|
350
|
-
simsimd_distance_t results[2] = {signaling_distance, 0};
|
|
351
|
-
metric(pair.a.data(), pair.b.data(), tensor.data(), pair.a.size(), &results[0]);
|
|
352
|
-
return results[0] + results[1];
|
|
353
|
-
};
|
|
354
|
-
|
|
355
|
-
// Let's average the distance results over many pairs.
|
|
356
|
-
constexpr std::size_t pairs_count = 128;
|
|
357
|
-
std::vector<pair_t> pairs(pairs_count);
|
|
358
|
-
std::vector<vector_t> tensors(pairs_count);
|
|
359
|
-
for (std::size_t i = 0; i != pairs.size(); ++i) {
|
|
360
|
-
pair_t &pair = pairs[i];
|
|
361
|
-
pair.a = pair.b = vector_t(dimensions);
|
|
362
|
-
pair.a.randomize(static_cast<std::uint32_t>(i)), pair.b.randomize(static_cast<std::uint32_t>(i) + 54321u);
|
|
363
|
-
vector_t &tensor = tensors[i];
|
|
364
|
-
tensor = vector_t(dimensions * dimensions);
|
|
365
|
-
tensor.randomize(static_cast<std::uint32_t>(i) + 123456u);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// Initialize the output buffers for distance calculations.
|
|
369
|
-
std::vector<double> results_baseline(pairs.size());
|
|
370
|
-
std::vector<double> results_contender(pairs.size());
|
|
371
|
-
for (std::size_t i = 0; i != pairs.size(); ++i)
|
|
372
|
-
results_baseline[i] = call_baseline(pairs[i], tensors[i]),
|
|
373
|
-
results_contender[i] = call_contender(pairs[i], tensors[i]);
|
|
374
|
-
|
|
375
|
-
// The actual benchmarking loop.
|
|
376
|
-
std::size_t iterations = 0;
|
|
377
|
-
for (auto _ : state)
|
|
378
|
-
bm::DoNotOptimize((results_contender[iterations & (pairs_count - 1)] = call_contender(
|
|
379
|
-
pairs[iterations & (pairs_count - 1)], tensors[iterations & (pairs_count - 1)]))),
|
|
380
|
-
iterations++;
|
|
381
|
-
|
|
382
|
-
// Measure the mean absolute delta and relative error.
|
|
383
|
-
double mean_delta = 0, mean_relative_error = 0;
|
|
384
|
-
for (std::size_t i = 0; i != pairs.size(); ++i) {
|
|
385
|
-
auto abs_delta = std::abs(results_contender[i] - results_baseline[i]);
|
|
386
|
-
mean_delta += abs_delta;
|
|
387
|
-
double error = abs_delta != 0 && results_baseline[i] != 0 ? abs_delta / std::abs(results_baseline[i]) : 0;
|
|
388
|
-
mean_relative_error += error;
|
|
389
|
-
}
|
|
390
|
-
mean_delta /= pairs.size();
|
|
391
|
-
mean_relative_error /= pairs.size();
|
|
392
|
-
state.counters["abs_delta"] = mean_delta;
|
|
393
|
-
state.counters["relative_error"] = mean_relative_error;
|
|
394
|
-
state.counters["bytes"] = bm::Counter(iterations * pairs[0].a.size_bytes() * 2, bm::Counter::kIsRate);
|
|
395
|
-
state.counters["pairs"] = bm::Counter(iterations, bm::Counter::kIsRate);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
/**
|
|
399
|
-
* @brief Measures the performance of a @b sparse metric function against a baseline using Google Benchmark.
|
|
400
|
-
* @tparam pair_at The type representing the vector pair used in the measurement.
|
|
401
|
-
* @tparam metric_at The type of the metric function (default is void).
|
|
402
|
-
* @param state The benchmark state object provided by Google Benchmark.
|
|
403
|
-
* @param metric The metric function to benchmark.
|
|
404
|
-
* @param baseline The baseline function to compare against.
|
|
405
|
-
* @param size_a The number of elements in the smaller vector.
|
|
406
|
-
* @param size_b The number of elements in the larger vector.
|
|
407
|
-
* @param intersection_size The expected number of common scalars between the vectors.
|
|
408
|
-
*/
|
|
409
|
-
template <typename pair_at, typename metric_at = void>
|
|
410
|
-
void measure_sparse(bm::State &state, metric_at metric, metric_at baseline, std::size_t size_a, std::size_t size_b,
|
|
411
|
-
std::size_t intersection_size) {
|
|
412
|
-
|
|
413
|
-
using pair_t = pair_at;
|
|
414
|
-
using vector_t = typename pair_at::vector_t;
|
|
415
|
-
using scalar_t = typename vector_t::scalar_t;
|
|
416
|
-
|
|
417
|
-
auto call_baseline = [&](pair_t &pair) -> double {
|
|
418
|
-
simsimd_distance_t result = std::numeric_limits<simsimd_distance_t>::signaling_NaN();
|
|
419
|
-
baseline(pair.a.data(), pair.b.data(), pair.a.size(), pair.b.size(), &result);
|
|
420
|
-
return result;
|
|
421
|
-
};
|
|
422
|
-
auto call_contender = [&](pair_t &pair) -> double {
|
|
423
|
-
simsimd_distance_t result = std::numeric_limits<simsimd_distance_t>::signaling_NaN();
|
|
424
|
-
metric(pair.a.data(), pair.b.data(), pair.a.size(), pair.b.size(), &result);
|
|
425
|
-
return result;
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
// Let's average the distance results over many pairs.
|
|
429
|
-
constexpr std::size_t pairs_count = 128;
|
|
430
|
-
std::vector<pair_t> pairs(pairs_count);
|
|
431
|
-
std::random_device seed_source;
|
|
432
|
-
std::mt19937 generator(seed_source());
|
|
433
|
-
std::uniform_int_distribution<scalar_t> distribution(0, std::numeric_limits<scalar_t>::max());
|
|
434
|
-
|
|
435
|
-
// Randomizing the vectors for sparse distances is a bit more complex then:
|
|
436
|
-
//
|
|
437
|
-
// pair.a.randomize(), pair.b.randomize();
|
|
438
|
-
//
|
|
439
|
-
// We need to ensure that the intersection is of the expected size.
|
|
440
|
-
std::unordered_set<scalar_t> intersection_set, unique_a, unique_b;
|
|
441
|
-
intersection_set.reserve(intersection_size);
|
|
442
|
-
unique_a.reserve(size_a - intersection_size);
|
|
443
|
-
unique_b.reserve(size_b - intersection_size);
|
|
444
|
-
|
|
445
|
-
for (auto &pair : pairs) {
|
|
446
|
-
pair.a = vector_t(size_a);
|
|
447
|
-
pair.b = vector_t(size_b);
|
|
448
|
-
|
|
449
|
-
// Step 1: Generate intersection set
|
|
450
|
-
intersection_set.clear();
|
|
451
|
-
while (intersection_set.size() < intersection_size) intersection_set.insert(distribution(generator));
|
|
452
|
-
|
|
453
|
-
unique_a.clear();
|
|
454
|
-
while (unique_a.size() < size_a - intersection_size) {
|
|
455
|
-
scalar_t element = distribution(generator);
|
|
456
|
-
if (intersection_set.find(element) == intersection_set.end()) unique_a.insert(element);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
unique_b.clear();
|
|
460
|
-
while (unique_b.size() < size_b - intersection_size) {
|
|
461
|
-
scalar_t element = distribution(generator);
|
|
462
|
-
if (intersection_set.find(element) == intersection_set.end() && unique_a.find(element) == unique_a.end())
|
|
463
|
-
unique_b.insert(element);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// Step 2: Merge and sort
|
|
467
|
-
std::copy(intersection_set.begin(), intersection_set.end(), pair.a.values_ptr_);
|
|
468
|
-
std::copy(intersection_set.begin(), intersection_set.end(), pair.b.values_ptr_);
|
|
469
|
-
std::copy(unique_a.begin(), unique_a.end(), pair.a.values_ptr_ + intersection_size);
|
|
470
|
-
std::copy(unique_b.begin(), unique_b.end(), pair.b.values_ptr_ + intersection_size);
|
|
471
|
-
std::sort(pair.a.values_ptr_, pair.a.values_ptr_ + size_a);
|
|
472
|
-
std::sort(pair.b.values_ptr_, pair.b.values_ptr_ + size_b);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// Initialize the output buffers for distance calculations.
|
|
476
|
-
std::vector<double> results_baseline(pairs.size());
|
|
477
|
-
std::vector<double> results_contender(pairs.size());
|
|
478
|
-
for (std::size_t i = 0; i != pairs.size(); ++i)
|
|
479
|
-
results_baseline[i] = call_baseline(pairs[i]), results_contender[i] = call_contender(pairs[i]);
|
|
480
|
-
|
|
481
|
-
// The actual benchmarking loop.
|
|
482
|
-
std::size_t iterations = 0;
|
|
483
|
-
for (auto _ : state)
|
|
484
|
-
bm::DoNotOptimize((results_contender[iterations & (pairs_count - 1)] =
|
|
485
|
-
call_contender(pairs[iterations & (pairs_count - 1)]))),
|
|
486
|
-
iterations++;
|
|
487
|
-
|
|
488
|
-
// Measure the mean absolute delta and relative error.
|
|
489
|
-
double mean_error = 0;
|
|
490
|
-
for (std::size_t i = 0; i != pairs.size(); ++i) {
|
|
491
|
-
auto abs_error = std::abs(results_contender[i] - results_baseline[i]);
|
|
492
|
-
mean_error += abs_error;
|
|
493
|
-
}
|
|
494
|
-
mean_error /= pairs.size();
|
|
495
|
-
state.counters["error"] = mean_error;
|
|
496
|
-
state.counters["bytes"] =
|
|
497
|
-
bm::Counter(iterations * (pairs[0].a.size_bytes() + pairs[0].b.size_bytes()), bm::Counter::kIsRate);
|
|
498
|
-
state.counters["pairs"] = bm::Counter(iterations, bm::Counter::kIsRate);
|
|
499
|
-
state.counters["matches"] =
|
|
500
|
-
std::accumulate(results_contender.begin(), results_contender.end(), 0.0) / results_contender.size();
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
template <typename... function_args_at>
|
|
504
|
-
constexpr std::size_t function_args_count(void (*function)(function_args_at...)) {
|
|
505
|
-
return sizeof...(function_args_at);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
/**
|
|
509
|
-
* @brief Measures the performance of a vector-vector @b FMA function against a baseline using Google Benchmark.
|
|
510
|
-
* @tparam pair_at The type representing the vector pair used in the measurement.
|
|
511
|
-
* @tparam kernel_at The type of the kernel function (default is void).
|
|
512
|
-
* @param state The benchmark state object provided by Google Benchmark.
|
|
513
|
-
* @param kernel The kernel function to benchmark.
|
|
514
|
-
* @param baseline The baseline function to compare against.
|
|
515
|
-
* @param dimensions The number of dimensions in the vectors.
|
|
516
|
-
*/
|
|
517
|
-
template <typename pair_at, typename kernel_at = void, typename l2_metric_at = void>
|
|
518
|
-
void measure_fma(bm::State &state, kernel_at kernel, kernel_at baseline, l2_metric_at l2_metric,
|
|
519
|
-
std::size_t dimensions) {
|
|
520
|
-
|
|
521
|
-
using pair_t = pair_at;
|
|
522
|
-
using vector_t = typename pair_at::vector_t;
|
|
523
|
-
|
|
524
|
-
constexpr simsimd_distance_t alpha = 0.2;
|
|
525
|
-
constexpr simsimd_distance_t beta = 0.3;
|
|
526
|
-
static_assert(function_args_count(kernel_at {}) >= 6 && function_args_count(kernel_at {}) <= 7,
|
|
527
|
-
"Kernel must take two or three vectors.");
|
|
528
|
-
|
|
529
|
-
auto call_baseline = [&](vector_t const &a, vector_t const &b, vector_t const &c, vector_t &d) {
|
|
530
|
-
if constexpr (function_args_count(kernel_at {}) == 6) {
|
|
531
|
-
baseline(a.data(), c.data(), a.size(), alpha, beta, d.data());
|
|
532
|
-
}
|
|
533
|
-
else { baseline(a.data(), b.data(), c.data(), a.size(), alpha, beta, d.data()); }
|
|
534
|
-
};
|
|
535
|
-
auto call_contender = [&](vector_t const &a, vector_t const &b, vector_t const &c, vector_t &d) {
|
|
536
|
-
if constexpr (function_args_count(kernel_at {}) == 6) {
|
|
537
|
-
kernel(a.data(), c.data(), a.size(), alpha, beta, d.data());
|
|
538
|
-
}
|
|
539
|
-
else { kernel(a.data(), b.data(), c.data(), a.size(), alpha, beta, d.data()); }
|
|
540
|
-
};
|
|
541
|
-
|
|
542
|
-
// Let's average the distance results over many quads.
|
|
543
|
-
struct quad_t {
|
|
544
|
-
vector_t a, b, c, d;
|
|
545
|
-
};
|
|
546
|
-
constexpr std::size_t quads_count = 128;
|
|
547
|
-
std::vector<quad_t> quads(quads_count);
|
|
548
|
-
for (std::size_t i = 0; i != quads.size(); ++i) {
|
|
549
|
-
auto &quad = quads[i];
|
|
550
|
-
quad.a = quad.b = quad.c = quad.d = vector_t(dimensions);
|
|
551
|
-
quad.a.randomize(static_cast<std::uint32_t>(i));
|
|
552
|
-
quad.b.set(2); // Having a small constant here will help avoid overflows
|
|
553
|
-
quad.c.randomize(static_cast<std::uint32_t>(i) + 54321u);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// Initialize the output buffers for distance calculations.
|
|
557
|
-
vector_t baseline_d(dimensions), contender_d(dimensions), zeros(dimensions);
|
|
558
|
-
std::vector<simsimd_distance_t> l2_metric_from_baseline(quads.size());
|
|
559
|
-
std::vector<simsimd_distance_t> l2_baseline_result_norm(quads.size());
|
|
560
|
-
std::vector<simsimd_distance_t> l2_contender_result_norm(quads.size());
|
|
561
|
-
zeros.set(0);
|
|
562
|
-
double mean_delta = 0, mean_relative_error = 0;
|
|
563
|
-
for (std::size_t i = 0; i != quads.size(); ++i) {
|
|
564
|
-
quad_t &quad = quads[i];
|
|
565
|
-
call_baseline(quad.a, quad.b, quad.c, baseline_d);
|
|
566
|
-
call_contender(quad.a, quad.b, quad.c, contender_d);
|
|
567
|
-
l2_metric(baseline_d.data(), contender_d.data(), dimensions, &l2_metric_from_baseline[i]);
|
|
568
|
-
l2_metric(baseline_d.data(), zeros.data(), dimensions, &l2_baseline_result_norm[i]);
|
|
569
|
-
l2_metric(contender_d.data(), zeros.data(), dimensions, &l2_contender_result_norm[i]);
|
|
570
|
-
|
|
571
|
-
mean_delta += std::abs(l2_metric_from_baseline[i]);
|
|
572
|
-
mean_relative_error +=
|
|
573
|
-
std::abs(l2_metric_from_baseline[i]) / (std::max)(l2_baseline_result_norm[i], l2_contender_result_norm[i]);
|
|
574
|
-
}
|
|
575
|
-
mean_delta /= quads_count;
|
|
576
|
-
mean_relative_error /= quads_count;
|
|
577
|
-
|
|
578
|
-
// The actual benchmarking loop.
|
|
579
|
-
std::size_t iterations = 0;
|
|
580
|
-
for (auto _ : state) {
|
|
581
|
-
quad_t &quad = quads[iterations & (quads_count - 1)];
|
|
582
|
-
call_contender(quad.a, quad.b, quad.c, quad.d);
|
|
583
|
-
iterations++;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
// Measure the mean absolute delta and relative error.
|
|
587
|
-
state.counters["abs_delta"] = mean_delta;
|
|
588
|
-
state.counters["relative_error"] = mean_relative_error;
|
|
589
|
-
state.counters["bytes"] = bm::Counter(
|
|
590
|
-
iterations * quads[0].a.size_bytes() * (function_args_count(kernel_at {}) > 6 ? 3 : 2), bm::Counter::kIsRate);
|
|
591
|
-
state.counters["pairs"] = bm::Counter(iterations, bm::Counter::kIsRate);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
template <simsimd_datatype_t datatype_ak, typename metric_at = void>
|
|
595
|
-
void dense_(std::string name, metric_at *distance_func, metric_at *baseline_func) {
|
|
596
|
-
using pair_t = vectors_pair_gt<datatype_ak>;
|
|
597
|
-
std::string bench_name = name + "<" + std::to_string(dense_dimensions) + "d>";
|
|
598
|
-
bm::RegisterBenchmark(bench_name.c_str(), measure_dense<pair_t, metric_at *>, distance_func, baseline_func,
|
|
599
|
-
dense_dimensions)
|
|
600
|
-
->MinTime(default_seconds)
|
|
601
|
-
->Threads(default_threads);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
template <simsimd_datatype_t datatype_ak, typename kernel_at = void, typename l2_metric_at = void>
|
|
605
|
-
void fma_(std::string name, kernel_at *kernel_func, kernel_at *baseline_func, l2_metric_at *l2_metric_func) {
|
|
606
|
-
using pair_t = vectors_pair_gt<datatype_ak>;
|
|
607
|
-
std::string bench_name = name + "<" + std::to_string(dense_dimensions) + "d>";
|
|
608
|
-
bm::RegisterBenchmark(bench_name.c_str(), measure_fma<pair_t, kernel_at *, l2_metric_at *>, kernel_func,
|
|
609
|
-
baseline_func, l2_metric_func, dense_dimensions)
|
|
610
|
-
->MinTime(default_seconds)
|
|
611
|
-
->Threads(default_threads);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
template <simsimd_datatype_t datatype_ak, typename metric_at = void>
|
|
615
|
-
void sparse_(std::string name, metric_at *distance_func, metric_at *baseline_func) {
|
|
616
|
-
|
|
617
|
-
using pair_t = vectors_pair_gt<datatype_ak>;
|
|
618
|
-
|
|
619
|
-
// Register different lengths, intersection sizes, and distributions
|
|
620
|
-
// 2 first lengths * 3 second length multipliers * 4 intersection grades = 24 benchmarks for each metric.
|
|
621
|
-
for (std::size_t first_len : {128, 1024}) { //< 2 lengths
|
|
622
|
-
for (std::size_t second_len_multiplier : {1, 8, 64}) { //< 3 length multipliers
|
|
623
|
-
for (double intersection_share : {0.01, 0.05, 0.5, 0.95}) { //< 4 intersection grades
|
|
624
|
-
std::size_t intersection_size = static_cast<std::size_t>(first_len * intersection_share);
|
|
625
|
-
std::size_t second_len = first_len * second_len_multiplier;
|
|
626
|
-
std::string bench_name = name + "<|A|=" + std::to_string(first_len) +
|
|
627
|
-
",|B|=" + std::to_string(second_len) +
|
|
628
|
-
",|A∩B|=" + std::to_string(intersection_size) + ">";
|
|
629
|
-
if (second_len > 8192) continue;
|
|
630
|
-
bm::RegisterBenchmark(bench_name.c_str(), measure_sparse<pair_t, metric_at *>, distance_func,
|
|
631
|
-
baseline_func, first_len, second_len, intersection_size)
|
|
632
|
-
->MinTime(default_seconds)
|
|
633
|
-
->Threads(default_threads);
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
template <simsimd_datatype_t datatype_ak, typename metric_at = void>
|
|
640
|
-
void curved_(std::string name, metric_at *distance_func, metric_at *baseline_func) {
|
|
641
|
-
|
|
642
|
-
using pair_t = vectors_pair_gt<datatype_ak>;
|
|
643
|
-
std::string bench_name = name + "<" + std::to_string(curved_dimensions) + "d>";
|
|
644
|
-
bm::RegisterBenchmark(bench_name.c_str(), measure_curved<pair_t, metric_at *>, distance_func, baseline_func,
|
|
645
|
-
curved_dimensions)
|
|
646
|
-
->MinTime(default_seconds)
|
|
647
|
-
->Threads(default_threads);
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
#if SIMSIMD_BUILD_BENCHMARKS_WITH_CBLAS
|
|
651
|
-
|
|
652
|
-
void dot_f32_blas(simsimd_f32_t const *a, simsimd_f32_t const *b, simsimd_size_t n, simsimd_distance_t *result) {
|
|
653
|
-
*result = cblas_sdot((int)n, a, 1, b, 1);
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
void dot_f64_blas(simsimd_f64_t const *a, simsimd_f64_t const *b, simsimd_size_t n, simsimd_distance_t *result) {
|
|
657
|
-
*result = cblas_ddot((int)n, a, 1, b, 1);
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
void dot_f32c_blas(simsimd_f32c_t const *a, simsimd_f32c_t const *b, simsimd_size_t n, simsimd_distance_t *result) {
|
|
661
|
-
simsimd_f32_t f32_result[2] = {0, 0};
|
|
662
|
-
cblas_cdotu_sub((int)n, (simsimd_f32_t const *)a, 1, (simsimd_f32_t const *)b, 1, f32_result);
|
|
663
|
-
result[0] = f32_result[0];
|
|
664
|
-
result[1] = f32_result[1];
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
void dot_f64c_blas(simsimd_f64c_t const *a, simsimd_f64c_t const *b, simsimd_size_t n, simsimd_distance_t *result) {
|
|
668
|
-
cblas_zdotu_sub((int)n, (simsimd_f64_t const *)a, 1, (simsimd_f64_t const *)b, 1, result);
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
void vdot_f32c_blas(simsimd_f32c_t const *a, simsimd_f32c_t const *b, simsimd_size_t n, simsimd_distance_t *result) {
|
|
672
|
-
simsimd_f32_t f32_result[2] = {0, 0};
|
|
673
|
-
cblas_cdotc_sub((int)n, (simsimd_f32_t const *)a, 1, (simsimd_f32_t const *)b, 1, f32_result);
|
|
674
|
-
result[0] = f32_result[0];
|
|
675
|
-
result[1] = f32_result[1];
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
void vdot_f64c_blas(simsimd_f64c_t const *a, simsimd_f64c_t const *b, simsimd_size_t n, simsimd_distance_t *result) {
|
|
679
|
-
cblas_zdotc_sub((int)n, (simsimd_f64_t const *)a, 1, (simsimd_f64_t const *)b, 1, result);
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
void bilinear_f32_blas(simsimd_f32_t const *a, simsimd_f32_t const *b, simsimd_f32_t const *c, simsimd_size_t n,
|
|
683
|
-
simsimd_distance_t *result) {
|
|
684
|
-
// Thread-local buffer to avoid allocation in hot path
|
|
685
|
-
static thread_local std::vector<simsimd_f32_t> intermediate;
|
|
686
|
-
if (intermediate.size() < n) intermediate.resize(n);
|
|
687
|
-
|
|
688
|
-
simsimd_f32_t alpha = 1.0f, beta = 0.0f;
|
|
689
|
-
cblas_sgemv(CblasRowMajor, CblasNoTrans, (int)n, (int)n, alpha, c, (int)n, b, 1, beta, intermediate.data(), 1);
|
|
690
|
-
*result = cblas_sdot((int)n, a, 1, intermediate.data(), 1);
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
void bilinear_f64_blas(simsimd_f64_t const *a, simsimd_f64_t const *b, simsimd_f64_t const *c, simsimd_size_t n,
|
|
694
|
-
simsimd_distance_t *result) {
|
|
695
|
-
// Thread-local buffer to avoid allocation in hot path
|
|
696
|
-
static thread_local std::vector<simsimd_f64_t> intermediate;
|
|
697
|
-
if (intermediate.size() < n) intermediate.resize(n);
|
|
698
|
-
|
|
699
|
-
simsimd_f64_t alpha = 1.0, beta = 0.0;
|
|
700
|
-
cblas_dgemv(CblasRowMajor, CblasNoTrans, (int)n, (int)n, alpha, c, n, b, 1, beta, intermediate.data(), 1);
|
|
701
|
-
*result = cblas_ddot((int)n, a, 1, intermediate.data(), 1);
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
void bilinear_f32c_blas(simsimd_f32c_t const *a, simsimd_f32c_t const *b, simsimd_f32c_t const *c, simsimd_size_t n,
|
|
705
|
-
simsimd_distance_t *results) {
|
|
706
|
-
// Thread-local buffer to avoid allocation in hot path
|
|
707
|
-
static thread_local std::vector<simsimd_f32c_t> intermediate;
|
|
708
|
-
if (intermediate.size() < n) intermediate.resize(n);
|
|
709
|
-
|
|
710
|
-
simsimd_f32c_t alpha = {1.0f, 0.0f}, beta = {0.0f, 0.0f};
|
|
711
|
-
cblas_cgemv(CblasRowMajor, CblasNoTrans, (int)n, (int)n, &alpha, c, n, b, 1, &beta, intermediate.data(), 1);
|
|
712
|
-
simsimd_f32_t f32_result[2] = {0, 0};
|
|
713
|
-
cblas_cdotu_sub((int)n, (simsimd_f32_t const *)a, 1, (simsimd_f32_t const *)intermediate.data(), 1, f32_result);
|
|
714
|
-
results[0] = f32_result[0];
|
|
715
|
-
results[1] = f32_result[1];
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
void bilinear_f64c_blas(simsimd_f64c_t const *a, simsimd_f64c_t const *b, simsimd_f64c_t const *c, simsimd_size_t n,
|
|
719
|
-
simsimd_distance_t *results) {
|
|
720
|
-
// Thread-local buffer to avoid allocation in hot path
|
|
721
|
-
static thread_local std::vector<simsimd_f64c_t> intermediate;
|
|
722
|
-
if (intermediate.size() < n) intermediate.resize(n);
|
|
723
|
-
|
|
724
|
-
simsimd_f64c_t alpha = {1.0, 0.0}, beta = {0.0, 0.0};
|
|
725
|
-
cblas_zgemv(CblasRowMajor, CblasNoTrans, (int)n, (int)n, &alpha, c, n, b, 1, &beta, intermediate.data(), 1);
|
|
726
|
-
cblas_zdotu_sub((int)n, (simsimd_f64_t const *)a, 1, (simsimd_f64_t const *)intermediate.data(), 1, results);
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
#endif
|
|
730
|
-
|
|
731
|
-
int main(int argc, char **argv) {
|
|
732
|
-
simsimd_capability_t runtime_caps = simsimd_capabilities();
|
|
733
|
-
|
|
734
|
-
// Log supported functionality
|
|
735
|
-
char const *flags[2] = {"false", "true"};
|
|
736
|
-
std::printf("Benchmarking Similarity Measures\n");
|
|
737
|
-
std::printf("- Compiler used native F16: %s\n", flags[SIMSIMD_NATIVE_F16]);
|
|
738
|
-
std::printf("- Compiler used native BF16: %s\n", flags[SIMSIMD_NATIVE_BF16]);
|
|
739
|
-
std::printf("- Benchmark against CBLAS: %s\n", flags[SIMSIMD_BUILD_BENCHMARKS_WITH_CBLAS]);
|
|
740
|
-
std::printf("\n");
|
|
741
|
-
std::printf("Compile-time settings:\n");
|
|
742
|
-
std::printf("- Arm NEON support enabled: %s\n", flags[SIMSIMD_TARGET_NEON]);
|
|
743
|
-
std::printf("- Arm SVE support enabled: %s\n", flags[SIMSIMD_TARGET_SVE]);
|
|
744
|
-
std::printf("- Arm SVE2 support enabled: %s\n", flags[SIMSIMD_TARGET_SVE2]);
|
|
745
|
-
std::printf("- x86 Haswell support enabled: %s\n", flags[SIMSIMD_TARGET_HASWELL]);
|
|
746
|
-
std::printf("- x86 Skylake support enabled: %s\n", flags[SIMSIMD_TARGET_SKYLAKE]);
|
|
747
|
-
std::printf("- x86 Ice Lake support enabled: %s\n", flags[SIMSIMD_TARGET_ICE]);
|
|
748
|
-
std::printf("- x86 Genoa support enabled: %s\n", flags[SIMSIMD_TARGET_GENOA]);
|
|
749
|
-
std::printf("- x86 Sapphire Rapids support enabled: %s\n", flags[SIMSIMD_TARGET_SAPPHIRE]);
|
|
750
|
-
std::printf("- x86 Turin support enabled: %s\n", flags[SIMSIMD_TARGET_TURIN]);
|
|
751
|
-
std::printf("\n");
|
|
752
|
-
std::printf("Run-time settings:\n");
|
|
753
|
-
std::printf("- Arm NEON support enabled: %s\n", flags[(runtime_caps & simsimd_cap_neon_k) != 0]);
|
|
754
|
-
std::printf("- Arm NEON F16 support enabled: %s\n", flags[(runtime_caps & simsimd_cap_neon_f16_k) != 0]);
|
|
755
|
-
std::printf("- Arm NEON BF16 support enabled: %s\n", flags[(runtime_caps & simsimd_cap_neon_bf16_k) != 0]);
|
|
756
|
-
std::printf("- Arm NEON I8 support enabled: %s\n", flags[(runtime_caps & simsimd_cap_neon_i8_k) != 0]);
|
|
757
|
-
std::printf("- Arm SVE support enabled: %s\n", flags[(runtime_caps & simsimd_cap_sve_k) != 0]);
|
|
758
|
-
std::printf("- Arm SVE F16 support enabled: %s\n", flags[(runtime_caps & simsimd_cap_sve_f16_k) != 0]);
|
|
759
|
-
std::printf("- Arm SVE BF16 support enabled: %s\n", flags[(runtime_caps & simsimd_cap_sve_bf16_k) != 0]);
|
|
760
|
-
std::printf("- Arm SVE I8 support enabled: %s\n", flags[(runtime_caps & simsimd_cap_sve_i8_k) != 0]);
|
|
761
|
-
std::printf("- Arm SVE2 support enabled: %s\n", flags[(runtime_caps & simsimd_cap_sve2_k) != 0]);
|
|
762
|
-
std::printf("- x86 Haswell support enabled: %s\n", flags[(runtime_caps & simsimd_cap_haswell_k) != 0]);
|
|
763
|
-
std::printf("- x86 Skylake support enabled: %s\n", flags[(runtime_caps & simsimd_cap_skylake_k) != 0]);
|
|
764
|
-
std::printf("- x86 Ice Lake support enabled: %s\n", flags[(runtime_caps & simsimd_cap_ice_k) != 0]);
|
|
765
|
-
std::printf("- x86 Genoa support enabled: %s\n", flags[(runtime_caps & simsimd_cap_genoa_k) != 0]);
|
|
766
|
-
std::printf("- x86 Sapphire Rapids support enabled: %s\n", flags[(runtime_caps & simsimd_cap_sapphire_k) != 0]);
|
|
767
|
-
std::printf("- x86 Turin support enabled: %s\n", flags[(runtime_caps & simsimd_cap_turin_k) != 0]);
|
|
768
|
-
std::printf("- x86 Sierra Forest support enabled: %s\n", flags[(runtime_caps & simsimd_cap_sierra_k) != 0]);
|
|
769
|
-
std::printf("\n");
|
|
770
|
-
|
|
771
|
-
// Override dimensions from environment variables if provided
|
|
772
|
-
if (char const *env_dense = std::getenv("SIMSIMD_BENCH_DENSE_DIMENSIONS")) {
|
|
773
|
-
std::size_t parsed_dense = std::atoi(env_dense);
|
|
774
|
-
if (parsed_dense > 0) {
|
|
775
|
-
dense_dimensions = parsed_dense;
|
|
776
|
-
std::printf("Overriding `dense_dimensions` to %zu from SIMSIMD_BENCH_DENSE_DIMENSIONS\n", dense_dimensions);
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
if (char const *env_curved = std::getenv("SIMSIMD_BENCH_CURVED_DIMENSIONS")) {
|
|
780
|
-
std::size_t parsed_curved = std::atoi(env_curved);
|
|
781
|
-
if (parsed_curved > 0) {
|
|
782
|
-
curved_dimensions = parsed_curved;
|
|
783
|
-
std::printf("Overriding `curved_dimensions` to %zu from SIMSIMD_BENCH_CURVED_DIMENSIONS\n",
|
|
784
|
-
curved_dimensions);
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
std::printf("\n");
|
|
788
|
-
|
|
789
|
-
// Run the benchmarks
|
|
790
|
-
bm::Initialize(&argc, argv);
|
|
791
|
-
if (bm::ReportUnrecognizedArguments(argc, argv)) return 1;
|
|
792
|
-
|
|
793
|
-
constexpr simsimd_datatype_t b8_k = simsimd_datatype_b8_k;
|
|
794
|
-
constexpr simsimd_datatype_t i4x2_k = simsimd_datatype_i4x2_k;
|
|
795
|
-
constexpr simsimd_datatype_t i8_k = simsimd_datatype_i8_k;
|
|
796
|
-
constexpr simsimd_datatype_t i16_k = simsimd_datatype_i16_k;
|
|
797
|
-
constexpr simsimd_datatype_t i32_k = simsimd_datatype_i32_k;
|
|
798
|
-
constexpr simsimd_datatype_t i64_k = simsimd_datatype_i64_k;
|
|
799
|
-
constexpr simsimd_datatype_t u8_k = simsimd_datatype_u8_k;
|
|
800
|
-
constexpr simsimd_datatype_t u16_k = simsimd_datatype_u16_k;
|
|
801
|
-
constexpr simsimd_datatype_t u32_k = simsimd_datatype_u32_k;
|
|
802
|
-
constexpr simsimd_datatype_t u64_k = simsimd_datatype_u64_k;
|
|
803
|
-
constexpr simsimd_datatype_t f64_k = simsimd_datatype_f64_k;
|
|
804
|
-
constexpr simsimd_datatype_t f32_k = simsimd_datatype_f32_k;
|
|
805
|
-
constexpr simsimd_datatype_t f16_k = simsimd_datatype_f16_k;
|
|
806
|
-
constexpr simsimd_datatype_t bf16_k = simsimd_datatype_bf16_k;
|
|
807
|
-
constexpr simsimd_datatype_t f64c_k = simsimd_datatype_f64c_k;
|
|
808
|
-
constexpr simsimd_datatype_t f32c_k = simsimd_datatype_f32c_k;
|
|
809
|
-
constexpr simsimd_datatype_t f16c_k = simsimd_datatype_f16c_k;
|
|
810
|
-
constexpr simsimd_datatype_t bf16c_k = simsimd_datatype_bf16c_k;
|
|
811
|
-
|
|
812
|
-
#if SIMSIMD_BUILD_BENCHMARKS_WITH_CBLAS
|
|
813
|
-
|
|
814
|
-
dense_<f32_k>("dot_f32_blas", dot_f32_blas, simsimd_dot_f32_accurate);
|
|
815
|
-
dense_<f64_k>("dot_f64_blas", dot_f64_blas, simsimd_dot_f64_serial);
|
|
816
|
-
dense_<f32c_k>("dot_f32c_blas", dot_f32c_blas, simsimd_dot_f32c_accurate);
|
|
817
|
-
dense_<f64c_k>("dot_f64c_blas", dot_f64c_blas, simsimd_dot_f64c_serial);
|
|
818
|
-
dense_<f32c_k>("vdot_f32c_blas", vdot_f32c_blas, simsimd_vdot_f32c_accurate);
|
|
819
|
-
dense_<f64c_k>("vdot_f64c_blas", vdot_f64c_blas, simsimd_vdot_f64c_serial);
|
|
820
|
-
|
|
821
|
-
curved_<f64_k>("bilinear_f64_blas", bilinear_f64_blas, simsimd_bilinear_f64_serial);
|
|
822
|
-
curved_<f64c_k>("bilinear_f64c_blas", bilinear_f64c_blas, simsimd_bilinear_f64c_serial);
|
|
823
|
-
curved_<f32_k>("bilinear_f32_blas", bilinear_f32_blas, simsimd_bilinear_f32_accurate);
|
|
824
|
-
curved_<f32c_k>("bilinear_f32c_blas", bilinear_f32c_blas, simsimd_bilinear_f32c_accurate);
|
|
825
|
-
|
|
826
|
-
#endif
|
|
827
|
-
|
|
828
|
-
#if SIMSIMD_TARGET_NEON
|
|
829
|
-
dense_<f32_k>("dot_f32_neon", simsimd_dot_f32_neon, simsimd_dot_f32_accurate);
|
|
830
|
-
dense_<f32_k>("cos_f32_neon", simsimd_cos_f32_neon, simsimd_cos_f32_accurate);
|
|
831
|
-
dense_<f32_k>("l2sq_f32_neon", simsimd_l2sq_f32_neon, simsimd_l2sq_f32_accurate);
|
|
832
|
-
dense_<f32_k>("l2_f32_neon", simsimd_l2_f32_neon, simsimd_l2_f32_accurate);
|
|
833
|
-
dense_<f32_k>("kl_f32_neon", simsimd_kl_f32_neon, simsimd_kl_f32_accurate);
|
|
834
|
-
dense_<f32_k>("js_f32_neon", simsimd_js_f32_neon, simsimd_js_f32_accurate);
|
|
835
|
-
|
|
836
|
-
dense_<f64_k>("cos_f64_neon", simsimd_cos_f64_neon, simsimd_cos_f64_serial);
|
|
837
|
-
dense_<f64_k>("l2sq_f64_neon", simsimd_l2sq_f64_neon, simsimd_l2sq_f64_serial);
|
|
838
|
-
dense_<f64_k>("l2_f64_neon", simsimd_l2_f64_neon, simsimd_l2_f64_serial);
|
|
839
|
-
|
|
840
|
-
dense_<i8_k>("cos_i8_neon", simsimd_cos_i8_neon, simsimd_cos_i8_serial);
|
|
841
|
-
dense_<i8_k>("l2sq_i8_neon", simsimd_l2sq_i8_neon, simsimd_l2sq_i8_serial);
|
|
842
|
-
dense_<i8_k>("l2_i8_neon", simsimd_l2_i8_neon, simsimd_l2_i8_serial);
|
|
843
|
-
dense_<i8_k>("dot_i8_neon", simsimd_dot_i8_neon, simsimd_dot_i8_serial);
|
|
844
|
-
|
|
845
|
-
dense_<u8_k>("cos_u8_neon", simsimd_cos_u8_neon, simsimd_cos_u8_serial);
|
|
846
|
-
dense_<u8_k>("l2sq_u8_neon", simsimd_l2sq_u8_neon, simsimd_l2sq_u8_serial);
|
|
847
|
-
dense_<u8_k>("l2_u8_neon", simsimd_l2_u8_neon, simsimd_l2_u8_serial);
|
|
848
|
-
dense_<u8_k>("dot_u8_neon", simsimd_dot_u8_neon, simsimd_dot_u8_serial);
|
|
849
|
-
|
|
850
|
-
dense_<b8_k>("hamming_b8_neon", simsimd_hamming_b8_neon, simsimd_hamming_b8_serial);
|
|
851
|
-
dense_<b8_k>("jaccard_b8_neon", simsimd_jaccard_b8_neon, simsimd_jaccard_b8_serial);
|
|
852
|
-
|
|
853
|
-
dense_<f32c_k>("dot_f32c_neon", simsimd_dot_f32c_neon, simsimd_dot_f32c_accurate);
|
|
854
|
-
dense_<f32c_k>("vdot_f32c_neon", simsimd_vdot_f32c_neon, simsimd_vdot_f32c_accurate);
|
|
855
|
-
|
|
856
|
-
curved_<f32_k>("bilinear_f32_neon", simsimd_bilinear_f32_neon, simsimd_bilinear_f32_accurate);
|
|
857
|
-
curved_<f32_k>("mahalanobis_f32_neon", simsimd_mahalanobis_f32_neon, simsimd_mahalanobis_f32_accurate);
|
|
858
|
-
curved_<f32c_k>("bilinear_f32c_neon", simsimd_bilinear_f32c_neon, simsimd_bilinear_f32c_accurate);
|
|
859
|
-
|
|
860
|
-
sparse_<u16_k>("intersect_u16_neon", simsimd_intersect_u16_neon, simsimd_intersect_u16_accurate);
|
|
861
|
-
sparse_<u32_k>("intersect_u32_neon", simsimd_intersect_u32_neon, simsimd_intersect_u32_accurate);
|
|
862
|
-
|
|
863
|
-
fma_<f32_k>("fma_f32_neon", simsimd_fma_f32_neon, simsimd_fma_f32_accurate, simsimd_l2_f32_accurate);
|
|
864
|
-
fma_<f32_k>("wsum_f32_neon", simsimd_wsum_f32_neon, simsimd_wsum_f32_accurate, simsimd_l2_f32_accurate);
|
|
865
|
-
fma_<f32_k>("fma_f32_serial", simsimd_fma_f32_serial, simsimd_fma_f32_accurate, simsimd_l2_f32_accurate);
|
|
866
|
-
fma_<f32_k>("wsum_f32_serial", simsimd_wsum_f32_serial, simsimd_wsum_f32_accurate, simsimd_l2_f32_accurate);
|
|
867
|
-
|
|
868
|
-
#endif
|
|
869
|
-
|
|
870
|
-
#if SIMSIMD_TARGET_NEON_F16
|
|
871
|
-
dense_<f16c_k>("dot_f16c_neon", simsimd_dot_f16c_neon, simsimd_dot_f16c_accurate);
|
|
872
|
-
dense_<f16c_k>("vdot_f16c_neon", simsimd_vdot_f16c_neon, simsimd_vdot_f16c_accurate);
|
|
873
|
-
|
|
874
|
-
dense_<f16_k>("dot_f16_neon", simsimd_dot_f16_neon, simsimd_dot_f16_accurate);
|
|
875
|
-
dense_<f16_k>("cos_f16_neon", simsimd_cos_f16_neon, simsimd_cos_f16_accurate);
|
|
876
|
-
dense_<f16_k>("l2sq_f16_neon", simsimd_l2sq_f16_neon, simsimd_l2sq_f16_accurate);
|
|
877
|
-
dense_<f16_k>("l2_f16_neon", simsimd_l2_f16_neon, simsimd_l2sq_f16_accurate);
|
|
878
|
-
dense_<f16_k>("kl_f16_neon", simsimd_kl_f16_neon, simsimd_kl_f16_accurate);
|
|
879
|
-
dense_<f16_k>("js_f16_neon", simsimd_js_f16_neon, simsimd_js_f16_accurate);
|
|
880
|
-
|
|
881
|
-
curved_<f16_k>("bilinear_f16_neon", simsimd_bilinear_f16_neon, simsimd_bilinear_f16_accurate);
|
|
882
|
-
curved_<f16_k>("mahalanobis_f16_neon", simsimd_mahalanobis_f16_neon, simsimd_mahalanobis_f16_accurate);
|
|
883
|
-
curved_<f16c_k>("bilinear_f16c_neon", simsimd_bilinear_f16c_neon, simsimd_bilinear_f16c_accurate);
|
|
884
|
-
|
|
885
|
-
fma_<f16_k>("fma_f16_neon", simsimd_fma_f16_neon, simsimd_fma_f16_accurate, simsimd_l2_f16_accurate);
|
|
886
|
-
fma_<f16_k>("wsum_f16_neon", simsimd_wsum_f16_neon, simsimd_wsum_f16_accurate, simsimd_l2_f16_accurate);
|
|
887
|
-
|
|
888
|
-
// FMA kernels for `u8` on NEON use `f16` arithmetic
|
|
889
|
-
fma_<u8_k>("fma_u8_neon", simsimd_fma_u8_neon, simsimd_fma_u8_accurate, simsimd_l2_u8_serial);
|
|
890
|
-
fma_<u8_k>("wsum_u8_neon", simsimd_wsum_u8_neon, simsimd_wsum_u8_accurate, simsimd_l2_u8_serial);
|
|
891
|
-
fma_<i8_k>("fma_i8_neon", simsimd_fma_i8_neon, simsimd_fma_i8_accurate, simsimd_l2_i8_serial);
|
|
892
|
-
fma_<i8_k>("wsum_i8_neon", simsimd_wsum_i8_neon, simsimd_wsum_i8_accurate, simsimd_l2_i8_serial);
|
|
893
|
-
#endif
|
|
894
|
-
|
|
895
|
-
#if SIMSIMD_TARGET_NEON_BF16
|
|
896
|
-
dense_<bf16c_k>("dot_bf16c_neon", simsimd_dot_bf16c_neon, simsimd_dot_bf16c_accurate);
|
|
897
|
-
dense_<bf16c_k>("vdot_bf16c_neon", simsimd_vdot_bf16c_neon, simsimd_vdot_bf16c_accurate);
|
|
898
|
-
|
|
899
|
-
dense_<bf16_k>("dot_bf16_neon", simsimd_dot_bf16_neon, simsimd_dot_bf16_accurate);
|
|
900
|
-
dense_<bf16_k>("cos_bf16_neon", simsimd_cos_bf16_neon, simsimd_cos_bf16_accurate);
|
|
901
|
-
dense_<bf16_k>("l2sq_bf16_neon", simsimd_l2sq_bf16_neon, simsimd_l2sq_bf16_accurate);
|
|
902
|
-
dense_<bf16_k>("l2_bf16_neon", simsimd_l2_bf16_neon, simsimd_l2_bf16_accurate);
|
|
903
|
-
|
|
904
|
-
curved_<bf16_k>("bilinear_bf16_neon", simsimd_bilinear_bf16_neon, simsimd_bilinear_bf16_accurate);
|
|
905
|
-
curved_<bf16_k>("mahalanobis_bf16_neon", simsimd_mahalanobis_bf16_neon, simsimd_mahalanobis_bf16_accurate);
|
|
906
|
-
curved_<bf16c_k>("bilinear_bf16c_neon", simsimd_bilinear_bf16c_neon, simsimd_bilinear_bf16c_accurate);
|
|
907
|
-
|
|
908
|
-
fma_<bf16_k>("fma_bf16_neon", simsimd_fma_bf16_neon, simsimd_fma_bf16_accurate, simsimd_l2_bf16_accurate);
|
|
909
|
-
fma_<bf16_k>("wsum_bf16_neon", simsimd_wsum_bf16_neon, simsimd_wsum_bf16_accurate, simsimd_l2_bf16_accurate);
|
|
910
|
-
#endif
|
|
911
|
-
|
|
912
|
-
#if SIMSIMD_TARGET_SVE
|
|
913
|
-
dense_<f32_k>("dot_f32_sve", simsimd_dot_f32_sve, simsimd_dot_f32_accurate);
|
|
914
|
-
dense_<f32_k>("cos_f32_sve", simsimd_cos_f32_sve, simsimd_cos_f32_accurate);
|
|
915
|
-
dense_<f32_k>("l2sq_f32_sve", simsimd_l2sq_f32_sve, simsimd_l2sq_f32_accurate);
|
|
916
|
-
dense_<f32_k>("l2_f32_sve", simsimd_l2_f32_sve, simsimd_l2_f32_accurate);
|
|
917
|
-
|
|
918
|
-
dense_<f64_k>("dot_f64_sve", simsimd_dot_f64_sve, simsimd_dot_f64_serial);
|
|
919
|
-
dense_<f64_k>("cos_f64_sve", simsimd_cos_f64_sve, simsimd_cos_f64_serial);
|
|
920
|
-
dense_<f64_k>("l2sq_f64_sve", simsimd_l2sq_f64_sve, simsimd_l2sq_f64_serial);
|
|
921
|
-
dense_<f64_k>("l2_f64_sve", simsimd_l2_f64_sve, simsimd_l2_f64_serial);
|
|
922
|
-
|
|
923
|
-
dense_<b8_k>("hamming_b8_sve", simsimd_hamming_b8_sve, simsimd_hamming_b8_serial);
|
|
924
|
-
dense_<b8_k>("jaccard_b8_sve", simsimd_jaccard_b8_sve, simsimd_jaccard_b8_serial);
|
|
925
|
-
|
|
926
|
-
dense_<f32c_k>("dot_f32c_sve", simsimd_dot_f32c_sve, simsimd_dot_f32c_accurate);
|
|
927
|
-
dense_<f32c_k>("vdot_f32c_sve", simsimd_vdot_f32c_sve, simsimd_vdot_f32c_accurate);
|
|
928
|
-
dense_<f64c_k>("dot_f64c_sve", simsimd_dot_f64c_sve, simsimd_dot_f64c_serial);
|
|
929
|
-
dense_<f64c_k>("vdot_f64c_sve", simsimd_vdot_f64c_sve, simsimd_vdot_f64c_serial);
|
|
930
|
-
#endif
|
|
931
|
-
|
|
932
|
-
#if SIMSIMD_TARGET_SVE_F16
|
|
933
|
-
dense_<f16_k>("dot_f16_sve", simsimd_dot_f16_sve, simsimd_dot_f16_accurate);
|
|
934
|
-
dense_<f16_k>("cos_f16_sve", simsimd_cos_f16_sve, simsimd_cos_f16_accurate);
|
|
935
|
-
dense_<f16_k>("l2sq_f16_sve", simsimd_l2sq_f16_sve, simsimd_l2sq_f16_accurate);
|
|
936
|
-
dense_<f16_k>("l2_f16_sve", simsimd_l2_f16_sve, simsimd_l2sq_f16_accurate);
|
|
937
|
-
dense_<f16c_k>("dot_f16c_sve", simsimd_dot_f16c_sve, simsimd_dot_f16c_accurate);
|
|
938
|
-
dense_<f16c_k>("vdot_f16c_sve", simsimd_vdot_f16c_sve, simsimd_vdot_f16c_accurate);
|
|
939
|
-
#endif
|
|
940
|
-
|
|
941
|
-
#if SIMSIMD_TARGET_SVE_BF16
|
|
942
|
-
dense_<bf16_k>("cos_bf16_sve", simsimd_cos_bf16_sve, simsimd_cos_bf16_accurate);
|
|
943
|
-
dense_<bf16_k>("l2sq_bf16_sve", simsimd_l2sq_bf16_sve, simsimd_l2sq_bf16_accurate);
|
|
944
|
-
dense_<bf16_k>("l2_bf16_sve", simsimd_l2_bf16_sve, simsimd_l2_bf16_accurate);
|
|
945
|
-
#endif
|
|
946
|
-
|
|
947
|
-
#if SIMSIMD_TARGET_SVE2
|
|
948
|
-
sparse_<u16_k>("intersect_u16_sve2", simsimd_intersect_u16_sve2, simsimd_intersect_u16_accurate);
|
|
949
|
-
sparse_<u32_k>("intersect_u32_sve2", simsimd_intersect_u32_sve2, simsimd_intersect_u32_accurate);
|
|
950
|
-
#endif
|
|
951
|
-
|
|
952
|
-
#if SIMSIMD_TARGET_HASWELL
|
|
953
|
-
dense_<f16_k>("dot_f16_haswell", simsimd_dot_f16_haswell, simsimd_dot_f16_accurate);
|
|
954
|
-
dense_<f16_k>("cos_f16_haswell", simsimd_cos_f16_haswell, simsimd_cos_f16_accurate);
|
|
955
|
-
dense_<f16_k>("l2sq_f16_haswell", simsimd_l2sq_f16_haswell, simsimd_l2sq_f16_accurate);
|
|
956
|
-
dense_<f16_k>("l2_f16_haswell", simsimd_l2_f16_haswell, simsimd_l2_f16_accurate);
|
|
957
|
-
dense_<f16_k>("kl_f16_haswell", simsimd_kl_f16_haswell, simsimd_kl_f16_accurate);
|
|
958
|
-
dense_<f16_k>("js_f16_haswell", simsimd_js_f16_haswell, simsimd_js_f16_accurate);
|
|
959
|
-
|
|
960
|
-
dense_<bf16_k>("dot_bf16_haswell", simsimd_dot_bf16_haswell, simsimd_dot_bf16_accurate);
|
|
961
|
-
dense_<bf16_k>("cos_bf16_haswell", simsimd_cos_bf16_haswell, simsimd_cos_bf16_accurate);
|
|
962
|
-
dense_<bf16_k>("l2sq_bf16_haswell", simsimd_l2sq_bf16_haswell, simsimd_l2sq_bf16_accurate);
|
|
963
|
-
dense_<bf16_k>("l2_bf16_haswell", simsimd_l2_bf16_haswell, simsimd_l2_bf16_accurate);
|
|
964
|
-
|
|
965
|
-
dense_<i8_k>("cos_i8_haswell", simsimd_cos_i8_haswell, simsimd_cos_i8_serial);
|
|
966
|
-
dense_<i8_k>("l2sq_i8_haswell", simsimd_l2sq_i8_haswell, simsimd_l2sq_i8_serial);
|
|
967
|
-
dense_<i8_k>("l2_i8_haswell", simsimd_l2_i8_haswell, simsimd_l2_i8_serial);
|
|
968
|
-
dense_<i8_k>("dot_i8_haswell", simsimd_dot_i8_haswell, simsimd_dot_i8_serial);
|
|
969
|
-
|
|
970
|
-
dense_<u8_k>("cos_u8_haswell", simsimd_cos_u8_haswell, simsimd_cos_u8_serial);
|
|
971
|
-
dense_<u8_k>("l2sq_u8_haswell", simsimd_l2sq_u8_haswell, simsimd_l2sq_u8_serial);
|
|
972
|
-
dense_<u8_k>("l2_u8_haswell", simsimd_l2_u8_haswell, simsimd_l2_u8_serial);
|
|
973
|
-
dense_<u8_k>("dot_u8_haswell", simsimd_dot_u8_haswell, simsimd_dot_u8_serial);
|
|
974
|
-
|
|
975
|
-
dense_<b8_k>("hamming_b8_haswell", simsimd_hamming_b8_haswell, simsimd_hamming_b8_serial);
|
|
976
|
-
dense_<b8_k>("jaccard_b8_haswell", simsimd_jaccard_b8_haswell, simsimd_jaccard_b8_serial);
|
|
977
|
-
|
|
978
|
-
dense_<f16c_k>("dot_f16c_haswell", simsimd_dot_f16c_haswell, simsimd_dot_f16c_accurate);
|
|
979
|
-
dense_<f16c_k>("vdot_f16c_haswell", simsimd_vdot_f16c_haswell, simsimd_vdot_f16c_accurate);
|
|
980
|
-
dense_<f32c_k>("dot_f32c_haswell", simsimd_dot_f32c_haswell, simsimd_dot_f32c_accurate);
|
|
981
|
-
dense_<f32c_k>("vdot_f32c_haswell", simsimd_vdot_f32c_haswell, simsimd_vdot_f32c_accurate);
|
|
982
|
-
|
|
983
|
-
curved_<f16_k>("bilinear_f16_haswell", simsimd_bilinear_f16_haswell, simsimd_bilinear_f16_accurate);
|
|
984
|
-
curved_<f16_k>("mahalanobis_f16_haswell", simsimd_mahalanobis_f16_haswell, simsimd_mahalanobis_f16_accurate);
|
|
985
|
-
curved_<bf16_k>("bilinear_bf16_haswell", simsimd_bilinear_bf16_haswell, simsimd_bilinear_bf16_accurate);
|
|
986
|
-
curved_<bf16_k>("mahalanobis_bf16_haswell", simsimd_mahalanobis_bf16_haswell, simsimd_mahalanobis_bf16_accurate);
|
|
987
|
-
|
|
988
|
-
fma_<f64_k>("fma_f64_haswell", simsimd_fma_f64_haswell, simsimd_fma_f64_serial, simsimd_l2_f64_serial);
|
|
989
|
-
fma_<f64_k>("wsum_f64_haswell", simsimd_wsum_f64_haswell, simsimd_wsum_f64_serial, simsimd_l2_f64_serial);
|
|
990
|
-
fma_<f32_k>("fma_f32_haswell", simsimd_fma_f32_haswell, simsimd_fma_f32_accurate, simsimd_l2_f32_accurate);
|
|
991
|
-
fma_<f32_k>("wsum_f32_haswell", simsimd_wsum_f32_haswell, simsimd_wsum_f32_accurate, simsimd_l2_f32_accurate);
|
|
992
|
-
fma_<f16_k>("fma_f16_haswell", simsimd_fma_f16_haswell, simsimd_fma_f16_accurate, simsimd_l2_f16_accurate);
|
|
993
|
-
fma_<f16_k>("wsum_f16_haswell", simsimd_wsum_f16_haswell, simsimd_wsum_f16_accurate, simsimd_l2_f16_accurate);
|
|
994
|
-
fma_<bf16_k>("fma_bf16_haswell", simsimd_fma_bf16_haswell, simsimd_fma_bf16_accurate, simsimd_l2_bf16_accurate);
|
|
995
|
-
fma_<bf16_k>("wsum_bf16_haswell", simsimd_wsum_bf16_haswell, simsimd_wsum_bf16_accurate, simsimd_l2_bf16_accurate);
|
|
996
|
-
fma_<i8_k>("fma_i8_haswell", simsimd_fma_i8_haswell, simsimd_fma_i8_accurate, simsimd_l2_i8_serial);
|
|
997
|
-
fma_<i8_k>("wsum_i8_haswell", simsimd_wsum_i8_haswell, simsimd_wsum_i8_accurate, simsimd_l2_i8_serial);
|
|
998
|
-
fma_<u8_k>("fma_u8_haswell", simsimd_fma_u8_haswell, simsimd_fma_u8_accurate, simsimd_l2_u8_serial);
|
|
999
|
-
fma_<u8_k>("wsum_u8_haswell", simsimd_wsum_u8_haswell, simsimd_wsum_u8_accurate, simsimd_l2_u8_serial);
|
|
1000
|
-
|
|
1001
|
-
#endif
|
|
1002
|
-
|
|
1003
|
-
#if SIMSIMD_TARGET_GENOA
|
|
1004
|
-
dense_<bf16_k>("dot_bf16_genoa", simsimd_dot_bf16_genoa, simsimd_dot_bf16_accurate);
|
|
1005
|
-
dense_<bf16_k>("cos_bf16_genoa", simsimd_cos_bf16_genoa, simsimd_cos_bf16_accurate);
|
|
1006
|
-
dense_<bf16_k>("l2sq_bf16_genoa", simsimd_l2sq_bf16_genoa, simsimd_l2sq_bf16_accurate);
|
|
1007
|
-
dense_<bf16_k>("l2_bf16_genoa", simsimd_l2_bf16_genoa, simsimd_l2_bf16_accurate);
|
|
1008
|
-
dense_<bf16c_k>("dot_bf16c_genoa", simsimd_dot_bf16c_genoa, simsimd_dot_bf16c_accurate);
|
|
1009
|
-
dense_<bf16c_k>("vdot_bf16c_genoa", simsimd_vdot_bf16c_genoa, simsimd_vdot_bf16c_accurate);
|
|
1010
|
-
|
|
1011
|
-
curved_<bf16_k>("bilinear_bf16_genoa", simsimd_bilinear_bf16_genoa, simsimd_bilinear_bf16_accurate);
|
|
1012
|
-
curved_<bf16_k>("mahalanobis_bf16_genoa", simsimd_mahalanobis_bf16_genoa, simsimd_mahalanobis_bf16_accurate);
|
|
1013
|
-
curved_<bf16c_k>("bilinear_bf16c_genoa", simsimd_bilinear_bf16c_genoa, simsimd_bilinear_bf16c_accurate);
|
|
1014
|
-
#endif
|
|
1015
|
-
|
|
1016
|
-
#if SIMSIMD_TARGET_SAPPHIRE
|
|
1017
|
-
dense_<f16_k>("dot_f16_sapphire", simsimd_dot_f16_sapphire, simsimd_dot_f16_accurate);
|
|
1018
|
-
dense_<f16_k>("cos_f16_sapphire", simsimd_cos_f16_sapphire, simsimd_cos_f16_accurate);
|
|
1019
|
-
dense_<f16_k>("l2sq_f16_sapphire", simsimd_l2sq_f16_sapphire, simsimd_l2sq_f16_accurate);
|
|
1020
|
-
dense_<f16_k>("l2_f16_sapphire", simsimd_l2_f16_sapphire, simsimd_l2_f16_accurate);
|
|
1021
|
-
dense_<f16_k>("kl_f16_sapphire", simsimd_kl_f16_sapphire, simsimd_kl_f16_accurate);
|
|
1022
|
-
dense_<f16_k>("js_f16_sapphire", simsimd_js_f16_sapphire, simsimd_js_f16_accurate);
|
|
1023
|
-
|
|
1024
|
-
dense_<f16c_k>("dot_f16c_sapphire", simsimd_dot_f16c_sapphire, simsimd_dot_f16c_accurate);
|
|
1025
|
-
dense_<f16c_k>("vdot_f16c_sapphire", simsimd_vdot_f16c_sapphire, simsimd_vdot_f16c_accurate);
|
|
1026
|
-
|
|
1027
|
-
fma_<u8_k>("fma_u8_sapphire", simsimd_fma_u8_sapphire, simsimd_fma_u8_accurate, simsimd_l2_u8_serial);
|
|
1028
|
-
fma_<u8_k>("wsum_u8_sapphire", simsimd_wsum_u8_sapphire, simsimd_wsum_u8_accurate, simsimd_l2_u8_serial);
|
|
1029
|
-
fma_<i8_k>("fma_i8_sapphire", simsimd_fma_i8_sapphire, simsimd_fma_i8_accurate, simsimd_l2_i8_serial);
|
|
1030
|
-
fma_<i8_k>("wsum_i8_sapphire", simsimd_wsum_i8_sapphire, simsimd_wsum_i8_accurate, simsimd_l2_i8_serial);
|
|
1031
|
-
|
|
1032
|
-
curved_<f16_k>("bilinear_f16_sapphire", simsimd_bilinear_f16_sapphire, simsimd_bilinear_f16_accurate);
|
|
1033
|
-
curved_<f16_k>("mahalanobis_f16_sapphire", simsimd_mahalanobis_f16_sapphire, simsimd_mahalanobis_f16_accurate);
|
|
1034
|
-
curved_<f16c_k>("bilinear_f16c_sapphire", simsimd_bilinear_f16c_sapphire, simsimd_bilinear_f16c_accurate);
|
|
1035
|
-
#endif
|
|
1036
|
-
|
|
1037
|
-
#if SIMSIMD_TARGET_ICE
|
|
1038
|
-
dense_<i8_k>("cos_i8_ice", simsimd_cos_i8_ice, simsimd_cos_i8_serial);
|
|
1039
|
-
dense_<i8_k>("l2sq_i8_ice", simsimd_l2sq_i8_ice, simsimd_l2sq_i8_serial);
|
|
1040
|
-
dense_<i8_k>("l2_i8_ice", simsimd_l2_i8_ice, simsimd_l2_i8_serial);
|
|
1041
|
-
dense_<i8_k>("dot_i8_ice", simsimd_dot_i8_ice, simsimd_dot_i8_serial);
|
|
1042
|
-
|
|
1043
|
-
dense_<u8_k>("cos_u8_ice", simsimd_cos_u8_ice, simsimd_cos_u8_serial);
|
|
1044
|
-
dense_<u8_k>("l2sq_u8_ice", simsimd_l2sq_u8_ice, simsimd_l2sq_u8_serial);
|
|
1045
|
-
dense_<u8_k>("l2_u8_ice", simsimd_l2_u8_ice, simsimd_l2_u8_serial);
|
|
1046
|
-
dense_<u8_k>("dot_u8_ice", simsimd_dot_u8_ice, simsimd_dot_u8_serial);
|
|
1047
|
-
|
|
1048
|
-
dense_<f64_k>("dot_f64_skylake", simsimd_dot_f64_skylake, simsimd_dot_f64_serial);
|
|
1049
|
-
dense_<f64_k>("cos_f64_skylake", simsimd_cos_f64_skylake, simsimd_cos_f64_serial);
|
|
1050
|
-
dense_<f64_k>("l2sq_f64_skylake", simsimd_l2sq_f64_skylake, simsimd_l2sq_f64_serial);
|
|
1051
|
-
dense_<f64_k>("l2_f64_skylake", simsimd_l2_f64_skylake, simsimd_l2_f64_serial);
|
|
1052
|
-
|
|
1053
|
-
dense_<b8_k>("hamming_b8_ice", simsimd_hamming_b8_ice, simsimd_hamming_b8_serial);
|
|
1054
|
-
dense_<b8_k>("jaccard_b8_ice", simsimd_jaccard_b8_ice, simsimd_jaccard_b8_serial);
|
|
1055
|
-
|
|
1056
|
-
sparse_<u16_k>("intersect_u16_ice", simsimd_intersect_u16_ice, simsimd_intersect_u16_accurate);
|
|
1057
|
-
sparse_<u32_k>("intersect_u32_ice", simsimd_intersect_u32_ice, simsimd_intersect_u32_accurate);
|
|
1058
|
-
#endif
|
|
1059
|
-
|
|
1060
|
-
#if SIMSIMD_TARGET_TURIN
|
|
1061
|
-
sparse_<u16_k>("intersect_u16_turin", simsimd_intersect_u16_turin, simsimd_intersect_u16_accurate);
|
|
1062
|
-
sparse_<u32_k>("intersect_u32_turin", simsimd_intersect_u32_turin, simsimd_intersect_u32_accurate);
|
|
1063
|
-
#endif
|
|
1064
|
-
|
|
1065
|
-
#if SIMSIMD_TARGET_SKYLAKE
|
|
1066
|
-
dense_<f32_k>("dot_f32_skylake", simsimd_dot_f32_skylake, simsimd_dot_f32_accurate);
|
|
1067
|
-
dense_<f32_k>("cos_f32_skylake", simsimd_cos_f32_skylake, simsimd_cos_f32_accurate);
|
|
1068
|
-
dense_<f32_k>("l2sq_f32_skylake", simsimd_l2sq_f32_skylake, simsimd_l2sq_f32_accurate);
|
|
1069
|
-
dense_<f32_k>("l2_f32_skylake", simsimd_l2_f32_skylake, simsimd_l2_f32_accurate);
|
|
1070
|
-
dense_<f32_k>("kl_f32_skylake", simsimd_kl_f32_skylake, simsimd_kl_f32_accurate);
|
|
1071
|
-
dense_<f32_k>("js_f32_skylake", simsimd_js_f32_skylake, simsimd_js_f32_accurate);
|
|
1072
|
-
|
|
1073
|
-
dense_<f32c_k>("dot_f32c_skylake", simsimd_dot_f32c_skylake, simsimd_dot_f32c_accurate);
|
|
1074
|
-
dense_<f32c_k>("vdot_f32c_skylake", simsimd_vdot_f32c_skylake, simsimd_vdot_f32c_accurate);
|
|
1075
|
-
dense_<f64c_k>("dot_f64c_skylake", simsimd_dot_f64c_skylake, simsimd_dot_f64c_serial);
|
|
1076
|
-
dense_<f64c_k>("vdot_f64c_skylake", simsimd_vdot_f64c_skylake, simsimd_vdot_f64c_serial);
|
|
1077
|
-
|
|
1078
|
-
fma_<f64_k>("fma_f64_skylake", simsimd_fma_f64_skylake, simsimd_fma_f64_serial, simsimd_l2_f64_serial);
|
|
1079
|
-
fma_<f64_k>("wsum_f64_skylake", simsimd_wsum_f64_skylake, simsimd_wsum_f64_serial, simsimd_l2_f64_serial);
|
|
1080
|
-
fma_<f32_k>("fma_f32_skylake", simsimd_fma_f32_skylake, simsimd_fma_f32_accurate, simsimd_l2_f32_accurate);
|
|
1081
|
-
fma_<f32_k>("wsum_f32_skylake", simsimd_wsum_f32_skylake, simsimd_wsum_f32_accurate, simsimd_l2_f32_accurate);
|
|
1082
|
-
fma_<bf16_k>("fma_bf16_skylake", simsimd_fma_bf16_skylake, simsimd_fma_bf16_accurate, simsimd_l2_bf16_accurate);
|
|
1083
|
-
fma_<bf16_k>("wsum_bf16_skylake", simsimd_wsum_bf16_skylake, simsimd_wsum_bf16_accurate, simsimd_l2_bf16_accurate);
|
|
1084
|
-
|
|
1085
|
-
curved_<f32_k>("bilinear_f32_skylake", simsimd_bilinear_f32_skylake, simsimd_bilinear_f32_serial);
|
|
1086
|
-
curved_<f32c_k>("bilinear_f32c_skylake", simsimd_bilinear_f32c_skylake, simsimd_bilinear_f32c_serial);
|
|
1087
|
-
curved_<f64_k>("bilinear_f64_skylake", simsimd_bilinear_f64_skylake, simsimd_bilinear_f64_serial);
|
|
1088
|
-
curved_<f64c_k>("bilinear_f64c_skylake", simsimd_bilinear_f64c_skylake, simsimd_bilinear_f64c_serial);
|
|
1089
|
-
#endif
|
|
1090
|
-
|
|
1091
|
-
sparse_<u16_k>("intersect_u16_serial", simsimd_intersect_u16_serial, simsimd_intersect_u16_accurate);
|
|
1092
|
-
sparse_<u16_k>("intersect_u16_accurate", simsimd_intersect_u16_accurate, simsimd_intersect_u16_accurate);
|
|
1093
|
-
sparse_<u32_k>("intersect_u32_serial", simsimd_intersect_u32_serial, simsimd_intersect_u32_accurate);
|
|
1094
|
-
sparse_<u32_k>("intersect_u32_accurate", simsimd_intersect_u32_accurate, simsimd_intersect_u32_accurate);
|
|
1095
|
-
|
|
1096
|
-
curved_<f64_k>("bilinear_f64_serial", simsimd_bilinear_f64_serial, simsimd_bilinear_f64_serial);
|
|
1097
|
-
curved_<f64c_k>("bilinear_f64c_serial", simsimd_bilinear_f64c_serial, simsimd_bilinear_f64c_serial);
|
|
1098
|
-
curved_<f64_k>("mahalanobis_f64_serial", simsimd_mahalanobis_f64_serial, simsimd_mahalanobis_f64_serial);
|
|
1099
|
-
curved_<f32_k>("bilinear_f32_serial", simsimd_bilinear_f32_serial, simsimd_bilinear_f32_accurate);
|
|
1100
|
-
curved_<f32c_k>("bilinear_f32c_serial", simsimd_bilinear_f32c_serial, simsimd_bilinear_f32c_accurate);
|
|
1101
|
-
curved_<f32_k>("mahalanobis_f32_serial", simsimd_mahalanobis_f32_serial, simsimd_mahalanobis_f32_accurate);
|
|
1102
|
-
curved_<f16_k>("bilinear_f16_serial", simsimd_bilinear_f16_serial, simsimd_bilinear_f16_accurate);
|
|
1103
|
-
curved_<f16c_k>("bilinear_f16c_serial", simsimd_bilinear_f16c_serial, simsimd_bilinear_f16c_accurate);
|
|
1104
|
-
curved_<f16_k>("mahalanobis_f16_serial", simsimd_mahalanobis_f16_serial, simsimd_mahalanobis_f16_accurate);
|
|
1105
|
-
curved_<bf16_k>("bilinear_bf16_serial", simsimd_bilinear_bf16_serial, simsimd_bilinear_bf16_accurate);
|
|
1106
|
-
curved_<bf16c_k>("bilinear_bf16c_serial", simsimd_bilinear_bf16c_serial, simsimd_bilinear_bf16c_accurate);
|
|
1107
|
-
curved_<bf16_k>("mahalanobis_bf16_serial", simsimd_mahalanobis_bf16_serial, simsimd_mahalanobis_bf16_accurate);
|
|
1108
|
-
|
|
1109
|
-
dense_<bf16_k>("dot_bf16_serial", simsimd_dot_bf16_serial, simsimd_dot_bf16_accurate);
|
|
1110
|
-
dense_<bf16_k>("cos_bf16_serial", simsimd_cos_bf16_serial, simsimd_cos_bf16_accurate);
|
|
1111
|
-
dense_<bf16_k>("l2sq_bf16_serial", simsimd_l2sq_bf16_serial, simsimd_l2sq_bf16_accurate);
|
|
1112
|
-
dense_<bf16_k>("l2_bf16_serial", simsimd_l2_bf16_serial, simsimd_l2_bf16_accurate);
|
|
1113
|
-
dense_<bf16_k>("kl_bf16_serial", simsimd_kl_bf16_serial, simsimd_kl_bf16_accurate);
|
|
1114
|
-
dense_<bf16_k>("js_bf16_serial", simsimd_js_bf16_serial, simsimd_js_bf16_accurate);
|
|
1115
|
-
|
|
1116
|
-
dense_<f16_k>("dot_f16_serial", simsimd_dot_f16_serial, simsimd_dot_f16_accurate);
|
|
1117
|
-
dense_<f16_k>("cos_f16_serial", simsimd_cos_f16_serial, simsimd_cos_f16_accurate);
|
|
1118
|
-
dense_<f16_k>("l2sq_f16_serial", simsimd_l2sq_f16_serial, simsimd_l2sq_f16_accurate);
|
|
1119
|
-
dense_<f16_k>("l2_f16_serial", simsimd_l2_f16_serial, simsimd_l2_f16_accurate);
|
|
1120
|
-
dense_<f16_k>("kl_f16_serial", simsimd_kl_f16_serial, simsimd_kl_f16_accurate);
|
|
1121
|
-
dense_<f16_k>("js_f16_serial", simsimd_js_f16_serial, simsimd_js_f16_accurate);
|
|
1122
|
-
|
|
1123
|
-
dense_<f32_k>("dot_f32_serial", simsimd_dot_f32_serial, simsimd_dot_f32_accurate);
|
|
1124
|
-
dense_<f32_k>("cos_f32_serial", simsimd_cos_f32_serial, simsimd_cos_f32_accurate);
|
|
1125
|
-
dense_<f32_k>("l2sq_f32_serial", simsimd_l2sq_f32_serial, simsimd_l2sq_f32_accurate);
|
|
1126
|
-
dense_<f32_k>("l2_f32_serial", simsimd_l2_f32_serial, simsimd_l2_f32_accurate);
|
|
1127
|
-
dense_<f32_k>("kl_f32_serial", simsimd_kl_f32_serial, simsimd_kl_f32_accurate);
|
|
1128
|
-
dense_<f32_k>("js_f32_serial", simsimd_js_f32_serial, simsimd_js_f32_accurate);
|
|
1129
|
-
|
|
1130
|
-
dense_<f64_k>("dot_f64_serial", simsimd_dot_f64_serial, simsimd_dot_f64_serial);
|
|
1131
|
-
dense_<f64_k>("cos_f64_serial", simsimd_cos_f64_serial, simsimd_cos_f64_serial);
|
|
1132
|
-
dense_<f64_k>("l2sq_f64_serial", simsimd_l2sq_f64_serial, simsimd_l2sq_f64_serial);
|
|
1133
|
-
dense_<f64_k>("l2_f64_serial", simsimd_l2_f64_serial, simsimd_l2_f64_serial);
|
|
1134
|
-
|
|
1135
|
-
dense_<i8_k>("cos_i8_serial", simsimd_cos_i8_serial, simsimd_cos_i8_serial);
|
|
1136
|
-
dense_<i8_k>("l2sq_i8_serial", simsimd_l2sq_i8_serial, simsimd_l2sq_i8_serial);
|
|
1137
|
-
dense_<i8_k>("l2_i8_serial", simsimd_l2_i8_serial, simsimd_l2_i8_serial);
|
|
1138
|
-
dense_<i8_k>("dot_i8_serial", simsimd_dot_i8_serial, simsimd_dot_i8_serial);
|
|
1139
|
-
|
|
1140
|
-
dense_<u8_k>("cos_u8_serial", simsimd_cos_u8_serial, simsimd_cos_u8_serial);
|
|
1141
|
-
dense_<u8_k>("l2sq_u8_serial", simsimd_l2sq_u8_serial, simsimd_l2sq_u8_serial);
|
|
1142
|
-
dense_<u8_k>("l2_u8_serial", simsimd_l2_u8_serial, simsimd_l2_u8_serial);
|
|
1143
|
-
dense_<u8_k>("dot_u8_serial", simsimd_dot_u8_serial, simsimd_dot_u8_serial);
|
|
1144
|
-
|
|
1145
|
-
dense_<f64c_k>("dot_f64c_serial", simsimd_dot_f64c_serial, simsimd_dot_f64c_serial);
|
|
1146
|
-
dense_<f32c_k>("dot_f32c_serial", simsimd_dot_f32c_serial, simsimd_dot_f32c_accurate);
|
|
1147
|
-
dense_<f16c_k>("dot_f16c_serial", simsimd_dot_f16c_serial, simsimd_dot_f16c_accurate);
|
|
1148
|
-
dense_<bf16c_k>("dot_bf16c_serial", simsimd_dot_bf16c_serial, simsimd_dot_bf16c_accurate);
|
|
1149
|
-
dense_<f64c_k>("vdot_f64c_serial", simsimd_vdot_f64c_serial, simsimd_vdot_f64c_serial);
|
|
1150
|
-
dense_<f32c_k>("vdot_f32c_serial", simsimd_vdot_f32c_serial, simsimd_vdot_f32c_accurate);
|
|
1151
|
-
dense_<f16c_k>("vdot_f16c_serial", simsimd_vdot_f16c_serial, simsimd_vdot_f16c_accurate);
|
|
1152
|
-
dense_<bf16c_k>("vdot_bf16c_serial", simsimd_vdot_bf16c_serial, simsimd_vdot_bf16c_accurate);
|
|
1153
|
-
|
|
1154
|
-
dense_<f16c_k>("vdot_f16c_serial", simsimd_vdot_f16c_serial, simsimd_vdot_f16c_accurate);
|
|
1155
|
-
dense_<bf16c_k>("vdot_bf16c_serial", simsimd_vdot_bf16c_serial, simsimd_vdot_bf16c_accurate);
|
|
1156
|
-
|
|
1157
|
-
dense_<b8_k>("hamming_b8_serial", simsimd_hamming_b8_serial, simsimd_hamming_b8_serial);
|
|
1158
|
-
dense_<b8_k>("jaccard_b8_serial", simsimd_jaccard_b8_serial, simsimd_jaccard_b8_serial);
|
|
1159
|
-
|
|
1160
|
-
fma_<f16_k>("fma_f16_serial", simsimd_fma_f16_serial, simsimd_fma_f16_accurate, simsimd_l2_f16_accurate);
|
|
1161
|
-
fma_<f16_k>("wsum_f16_serial", simsimd_wsum_f16_serial, simsimd_wsum_f16_accurate, simsimd_l2_f16_accurate);
|
|
1162
|
-
fma_<u8_k>("fma_u8_serial", simsimd_fma_u8_serial, simsimd_fma_u8_accurate, simsimd_l2_u8_serial);
|
|
1163
|
-
fma_<u8_k>("wsum_u8_serial", simsimd_wsum_u8_serial, simsimd_wsum_u8_accurate, simsimd_l2_u8_serial);
|
|
1164
|
-
fma_<i8_k>("fma_i8_serial", simsimd_fma_i8_serial, simsimd_fma_i8_accurate, simsimd_l2_i8_serial);
|
|
1165
|
-
fma_<i8_k>("wsum_i8_serial", simsimd_wsum_i8_serial, simsimd_wsum_i8_accurate, simsimd_l2_i8_serial);
|
|
1166
|
-
|
|
1167
|
-
bm::RunSpecifiedBenchmarks();
|
|
1168
|
-
bm::Shutdown();
|
|
1169
|
-
return 0;
|
|
1170
|
-
}
|