usearch 2.21.3 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -24
- package/binding.gyp +15 -37
- package/c/CMakeLists.txt +4 -5
- package/c/README.md +7 -7
- package/c/lib.cpp +32 -14
- package/c/test.c +83 -1
- package/c/usearch.h +24 -3
- package/cpp/CMakeLists.txt +4 -0
- package/cpp/README.md +5 -5
- package/cpp/bench.cpp +97 -116
- package/cpp/test.cpp +117 -20
- package/include/usearch/index.hpp +235 -52
- package/include/usearch/index_dense.hpp +105 -40
- package/include/usearch/index_plugins.hpp +1387 -204
- package/javascript/dist/cjs/usearch.d.ts +8 -3
- package/javascript/dist/cjs/usearch.js +12 -4
- package/javascript/dist/esm/usearch.d.ts +8 -3
- package/javascript/dist/esm/usearch.js +12 -4
- package/javascript/lib.cpp +17 -0
- package/javascript/usearch.ts +14 -6
- package/numkong/.clang-tidy +30 -0
- package/{simsimd → numkong}/.cmake-format.py +18 -0
- package/numkong/.editorconfig +12 -0
- package/numkong/.git-blame-ignore-revs +123 -0
- package/numkong/.mailmap +15 -0
- package/numkong/.spi.yml +11 -0
- package/numkong/.swift-format +14 -0
- package/numkong/CITATION.cff +81 -0
- package/numkong/CONTRIBUTING.md +500 -0
- package/numkong/Cargo.toml +54 -0
- package/numkong/MANIFEST.in +8 -0
- package/numkong/Package.swift +84 -0
- package/numkong/README.md +569 -0
- package/numkong/bench/README.md +217 -0
- package/numkong/bench/bench-browser.html +323 -0
- package/numkong/bench/bench.cpp +344 -0
- package/numkong/bench/bench.hpp +816 -0
- package/numkong/bench/bench.js +148 -0
- package/numkong/bench/bench.mjs +616 -0
- package/numkong/bench/bench_attention.cpp +113 -0
- package/numkong/bench/bench_cast.cpp +264 -0
- package/numkong/bench/bench_cross_amx.cpp +62 -0
- package/numkong/bench/bench_cross_arm.cpp +245 -0
- package/numkong/bench/bench_cross_blas.cpp +309 -0
- package/numkong/bench/bench_cross_loongarch.cpp +106 -0
- package/numkong/bench/bench_cross_power.cpp +84 -0
- package/numkong/bench/bench_cross_rvv.cpp +121 -0
- package/numkong/bench/bench_cross_serial.cpp +151 -0
- package/numkong/bench/bench_cross_sme.cpp +163 -0
- package/numkong/bench/bench_cross_wasm.cpp +142 -0
- package/numkong/bench/bench_cross_x86.cpp +455 -0
- package/numkong/bench/bench_curved.cpp +210 -0
- package/numkong/bench/bench_dot.cpp +315 -0
- package/numkong/bench/bench_each.cpp +503 -0
- package/numkong/bench/bench_geospatial.cpp +112 -0
- package/numkong/bench/bench_maxsim.cpp +154 -0
- package/numkong/bench/bench_mesh.cpp +148 -0
- package/numkong/bench/bench_probability.cpp +60 -0
- package/numkong/bench/bench_reduce.cpp +371 -0
- package/numkong/bench/bench_set.cpp +73 -0
- package/numkong/bench/bench_sparse.cpp +198 -0
- package/numkong/bench/bench_spatial.cpp +347 -0
- package/numkong/bench/bench_trigonometry.cpp +137 -0
- package/numkong/bench/swift/Bench.swift +506 -0
- package/numkong/binding.gyp +169 -0
- package/numkong/build.rs +484 -0
- package/numkong/c/dispatch.h +512 -0
- package/numkong/c/dispatch_bf16.c +447 -0
- package/numkong/c/dispatch_bf16c.c +52 -0
- package/numkong/c/dispatch_e2m3.c +296 -0
- package/numkong/c/dispatch_e3m2.c +284 -0
- package/numkong/c/dispatch_e4m3.c +318 -0
- package/numkong/c/dispatch_e5m2.c +316 -0
- package/numkong/c/dispatch_f16.c +452 -0
- package/numkong/c/dispatch_f16c.c +58 -0
- package/numkong/c/dispatch_f32.c +434 -0
- package/numkong/c/dispatch_f32c.c +99 -0
- package/numkong/c/dispatch_f64.c +348 -0
- package/numkong/c/dispatch_f64c.c +98 -0
- package/numkong/c/dispatch_i16.c +96 -0
- package/numkong/c/dispatch_i32.c +89 -0
- package/numkong/c/dispatch_i4.c +153 -0
- package/numkong/c/dispatch_i64.c +86 -0
- package/numkong/c/dispatch_i8.c +348 -0
- package/numkong/c/dispatch_other.c +348 -0
- package/numkong/c/dispatch_u1.c +193 -0
- package/numkong/c/dispatch_u16.c +124 -0
- package/numkong/c/dispatch_u32.c +118 -0
- package/numkong/c/dispatch_u4.c +153 -0
- package/numkong/c/dispatch_u64.c +102 -0
- package/numkong/c/dispatch_u8.c +364 -0
- package/numkong/c/numkong.c +940 -0
- package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
- package/numkong/cmake/nk_isa_probe.cmake +90 -0
- package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_math_lib.cmake +46 -0
- package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
- package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
- package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
- package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
- package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
- package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
- package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
- package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
- package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
- package/numkong/cmake/toolchain-wasi.cmake +77 -0
- package/numkong/cmake/toolchain-wasm.cmake +70 -0
- package/numkong/cmake/toolchain-wasm64.cmake +62 -0
- package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
- package/numkong/include/README.md +643 -0
- package/numkong/include/module.modulemap +129 -0
- package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
- package/numkong/include/numkong/attention/sme.h +2075 -0
- package/numkong/include/numkong/attention.h +49 -0
- package/numkong/include/numkong/capabilities.h +930 -0
- package/numkong/include/numkong/cast/README.md +262 -0
- package/numkong/include/numkong/cast/diamond.h +64 -0
- package/numkong/include/numkong/cast/haswell.h +823 -0
- package/numkong/include/numkong/cast/icelake.h +475 -0
- package/numkong/include/numkong/cast/loongsonasx.h +252 -0
- package/numkong/include/numkong/cast/neon.h +1174 -0
- package/numkong/include/numkong/cast/powervsx.h +449 -0
- package/numkong/include/numkong/cast/rvv.h +970 -0
- package/numkong/include/numkong/cast/sapphire.h +262 -0
- package/numkong/include/numkong/cast/serial.h +2336 -0
- package/numkong/include/numkong/cast/skylake.h +915 -0
- package/numkong/include/numkong/cast/v128relaxed.h +537 -0
- package/numkong/include/numkong/cast.h +254 -0
- package/numkong/include/numkong/cast.hpp +44 -0
- package/numkong/include/numkong/curved/README.md +223 -0
- package/numkong/include/numkong/curved/genoa.h +182 -0
- package/numkong/include/numkong/curved/haswell.h +276 -0
- package/numkong/include/numkong/curved/neon.h +329 -0
- package/numkong/include/numkong/curved/neonbfdot.h +211 -0
- package/numkong/include/numkong/curved/rvv.h +305 -0
- package/numkong/include/numkong/curved/serial.h +207 -0
- package/numkong/include/numkong/curved/skylake.h +457 -0
- package/numkong/include/numkong/curved/smef64.h +530 -0
- package/numkong/include/numkong/curved.h +513 -0
- package/numkong/include/numkong/curved.hpp +144 -0
- package/numkong/include/numkong/dot/README.md +442 -0
- package/numkong/include/numkong/dot/alder.h +563 -0
- package/numkong/include/numkong/dot/diamond.h +158 -0
- package/numkong/include/numkong/dot/genoa.h +289 -0
- package/numkong/include/numkong/dot/haswell.h +1723 -0
- package/numkong/include/numkong/dot/icelake.h +997 -0
- package/numkong/include/numkong/dot/loongsonasx.h +671 -0
- package/numkong/include/numkong/dot/neon.h +869 -0
- package/numkong/include/numkong/dot/neonbfdot.h +243 -0
- package/numkong/include/numkong/dot/neonfhm.h +358 -0
- package/numkong/include/numkong/dot/neonfp8.h +323 -0
- package/numkong/include/numkong/dot/neonsdot.h +622 -0
- package/numkong/include/numkong/dot/powervsx.h +752 -0
- package/numkong/include/numkong/dot/rvv.h +722 -0
- package/numkong/include/numkong/dot/rvvbb.h +72 -0
- package/numkong/include/numkong/dot/rvvbf16.h +123 -0
- package/numkong/include/numkong/dot/rvvhalf.h +129 -0
- package/numkong/include/numkong/dot/sapphire.h +141 -0
- package/numkong/include/numkong/dot/serial.h +874 -0
- package/numkong/include/numkong/dot/sierra.h +405 -0
- package/numkong/include/numkong/dot/skylake.h +1116 -0
- package/numkong/include/numkong/dot/sve.h +420 -0
- package/numkong/include/numkong/dot/svebfdot.h +75 -0
- package/numkong/include/numkong/dot/svehalf.h +168 -0
- package/numkong/include/numkong/dot/svesdot.h +90 -0
- package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
- package/numkong/include/numkong/dot.h +1136 -0
- package/numkong/include/numkong/dot.hpp +94 -0
- package/numkong/include/numkong/dots/README.md +496 -0
- package/numkong/include/numkong/dots/alder.h +117 -0
- package/numkong/include/numkong/dots/diamond.h +86 -0
- package/numkong/include/numkong/dots/genoa.h +100 -0
- package/numkong/include/numkong/dots/graniteamx.h +733 -0
- package/numkong/include/numkong/dots/haswell.h +310 -0
- package/numkong/include/numkong/dots/icelake.h +180 -0
- package/numkong/include/numkong/dots/loongsonasx.h +176 -0
- package/numkong/include/numkong/dots/neon.h +123 -0
- package/numkong/include/numkong/dots/neonbfdot.h +59 -0
- package/numkong/include/numkong/dots/neonfhm.h +96 -0
- package/numkong/include/numkong/dots/neonfp8.h +99 -0
- package/numkong/include/numkong/dots/neonsdot.h +144 -0
- package/numkong/include/numkong/dots/powervsx.h +194 -0
- package/numkong/include/numkong/dots/rvv.h +2593 -0
- package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
- package/numkong/include/numkong/dots/serial.h +2867 -0
- package/numkong/include/numkong/dots/sierra.h +100 -0
- package/numkong/include/numkong/dots/skylake.h +207 -0
- package/numkong/include/numkong/dots/sme.h +5041 -0
- package/numkong/include/numkong/dots/smebi32.h +477 -0
- package/numkong/include/numkong/dots/smef64.h +1328 -0
- package/numkong/include/numkong/dots/smehalf.h +47 -0
- package/numkong/include/numkong/dots/v128relaxed.h +317 -0
- package/numkong/include/numkong/dots.h +3110 -0
- package/numkong/include/numkong/dots.hpp +641 -0
- package/numkong/include/numkong/each/README.md +465 -0
- package/numkong/include/numkong/each/haswell.h +1658 -0
- package/numkong/include/numkong/each/icelake.h +272 -0
- package/numkong/include/numkong/each/neon.h +1138 -0
- package/numkong/include/numkong/each/neonbfdot.h +211 -0
- package/numkong/include/numkong/each/neonhalf.h +318 -0
- package/numkong/include/numkong/each/rvv.h +1121 -0
- package/numkong/include/numkong/each/sapphire.h +343 -0
- package/numkong/include/numkong/each/serial.h +282 -0
- package/numkong/include/numkong/each/skylake.h +1562 -0
- package/numkong/include/numkong/each/v128relaxed.h +562 -0
- package/numkong/include/numkong/each.h +2232 -0
- package/numkong/include/numkong/each.hpp +434 -0
- package/numkong/include/numkong/geospatial/README.md +147 -0
- package/numkong/include/numkong/geospatial/haswell.h +633 -0
- package/numkong/include/numkong/geospatial/neon.h +615 -0
- package/numkong/include/numkong/geospatial/rvv.h +701 -0
- package/numkong/include/numkong/geospatial/serial.h +309 -0
- package/numkong/include/numkong/geospatial/skylake.h +613 -0
- package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
- package/numkong/include/numkong/geospatial.h +453 -0
- package/numkong/include/numkong/geospatial.hpp +235 -0
- package/numkong/include/numkong/matrix.hpp +336 -0
- package/numkong/include/numkong/maxsim/README.md +187 -0
- package/numkong/include/numkong/maxsim/alder.h +511 -0
- package/numkong/include/numkong/maxsim/genoa.h +115 -0
- package/numkong/include/numkong/maxsim/haswell.h +553 -0
- package/numkong/include/numkong/maxsim/icelake.h +480 -0
- package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
- package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
- package/numkong/include/numkong/maxsim/serial.h +490 -0
- package/numkong/include/numkong/maxsim/sme.h +993 -0
- package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
- package/numkong/include/numkong/maxsim.h +571 -0
- package/numkong/include/numkong/maxsim.hpp +133 -0
- package/numkong/include/numkong/mesh/README.md +219 -0
- package/numkong/include/numkong/mesh/haswell.h +2013 -0
- package/numkong/include/numkong/mesh/neon.h +1821 -0
- package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
- package/numkong/include/numkong/mesh/rvv.h +936 -0
- package/numkong/include/numkong/mesh/serial.h +721 -0
- package/numkong/include/numkong/mesh/skylake.h +2344 -0
- package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
- package/numkong/include/numkong/mesh.h +666 -0
- package/numkong/include/numkong/mesh.hpp +701 -0
- package/numkong/include/numkong/numkong.h +78 -0
- package/numkong/include/numkong/numkong.hpp +58 -0
- package/numkong/include/numkong/probability/README.md +177 -0
- package/numkong/include/numkong/probability/haswell.h +267 -0
- package/numkong/include/numkong/probability/neon.h +255 -0
- package/numkong/include/numkong/probability/rvv.h +414 -0
- package/numkong/include/numkong/probability/serial.h +181 -0
- package/numkong/include/numkong/probability/skylake.h +324 -0
- package/numkong/include/numkong/probability.h +380 -0
- package/numkong/include/numkong/probability.hpp +120 -0
- package/numkong/include/numkong/random.h +50 -0
- package/numkong/include/numkong/random.hpp +285 -0
- package/numkong/include/numkong/reduce/README.md +552 -0
- package/numkong/include/numkong/reduce/alder.h +636 -0
- package/numkong/include/numkong/reduce/genoa.h +201 -0
- package/numkong/include/numkong/reduce/haswell.h +3785 -0
- package/numkong/include/numkong/reduce/icelake.h +549 -0
- package/numkong/include/numkong/reduce/neon.h +3980 -0
- package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
- package/numkong/include/numkong/reduce/neonfhm.h +293 -0
- package/numkong/include/numkong/reduce/neonsdot.h +357 -0
- package/numkong/include/numkong/reduce/rvv.h +3533 -0
- package/numkong/include/numkong/reduce/serial.h +753 -0
- package/numkong/include/numkong/reduce/sierra.h +338 -0
- package/numkong/include/numkong/reduce/skylake.h +3794 -0
- package/numkong/include/numkong/reduce/sve.h +52 -0
- package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
- package/numkong/include/numkong/reduce.h +1582 -0
- package/numkong/include/numkong/reduce.hpp +778 -0
- package/numkong/include/numkong/scalar/README.md +89 -0
- package/numkong/include/numkong/scalar/haswell.h +122 -0
- package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
- package/numkong/include/numkong/scalar/neon.h +122 -0
- package/numkong/include/numkong/scalar/neonhalf.h +70 -0
- package/numkong/include/numkong/scalar/powervsx.h +96 -0
- package/numkong/include/numkong/scalar/rvv.h +211 -0
- package/numkong/include/numkong/scalar/sapphire.h +74 -0
- package/numkong/include/numkong/scalar/serial.h +332 -0
- package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
- package/numkong/include/numkong/scalar.h +696 -0
- package/numkong/include/numkong/set/README.md +179 -0
- package/numkong/include/numkong/set/haswell.h +334 -0
- package/numkong/include/numkong/set/icelake.h +485 -0
- package/numkong/include/numkong/set/loongsonasx.h +181 -0
- package/numkong/include/numkong/set/neon.h +363 -0
- package/numkong/include/numkong/set/powervsx.h +326 -0
- package/numkong/include/numkong/set/rvv.h +226 -0
- package/numkong/include/numkong/set/rvvbb.h +117 -0
- package/numkong/include/numkong/set/serial.h +174 -0
- package/numkong/include/numkong/set/sve.h +187 -0
- package/numkong/include/numkong/set/v128relaxed.h +240 -0
- package/numkong/include/numkong/set.h +471 -0
- package/numkong/include/numkong/set.hpp +114 -0
- package/numkong/include/numkong/sets/README.md +149 -0
- package/numkong/include/numkong/sets/haswell.h +63 -0
- package/numkong/include/numkong/sets/icelake.h +66 -0
- package/numkong/include/numkong/sets/loongsonasx.h +52 -0
- package/numkong/include/numkong/sets/neon.h +61 -0
- package/numkong/include/numkong/sets/powervsx.h +65 -0
- package/numkong/include/numkong/sets/serial.h +43 -0
- package/numkong/include/numkong/sets/smebi32.h +1135 -0
- package/numkong/include/numkong/sets/v128relaxed.h +58 -0
- package/numkong/include/numkong/sets.h +382 -0
- package/numkong/include/numkong/sparse/README.md +156 -0
- package/numkong/include/numkong/sparse/icelake.h +463 -0
- package/numkong/include/numkong/sparse/neon.h +288 -0
- package/numkong/include/numkong/sparse/serial.h +117 -0
- package/numkong/include/numkong/sparse/sve2.h +504 -0
- package/numkong/include/numkong/sparse/turin.h +322 -0
- package/numkong/include/numkong/sparse.h +363 -0
- package/numkong/include/numkong/sparse.hpp +113 -0
- package/numkong/include/numkong/spatial/README.md +439 -0
- package/numkong/include/numkong/spatial/alder.h +604 -0
- package/numkong/include/numkong/spatial/diamond.h +240 -0
- package/numkong/include/numkong/spatial/genoa.h +222 -0
- package/numkong/include/numkong/spatial/haswell.h +979 -0
- package/numkong/include/numkong/spatial/icelake.h +1067 -0
- package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
- package/numkong/include/numkong/spatial/neon.h +846 -0
- package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
- package/numkong/include/numkong/spatial/neonfp8.h +258 -0
- package/numkong/include/numkong/spatial/neonsdot.h +429 -0
- package/numkong/include/numkong/spatial/powervsx.h +738 -0
- package/numkong/include/numkong/spatial/rvv.h +991 -0
- package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
- package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
- package/numkong/include/numkong/spatial/serial.h +347 -0
- package/numkong/include/numkong/spatial/sierra.h +516 -0
- package/numkong/include/numkong/spatial/skylake.h +605 -0
- package/numkong/include/numkong/spatial/sve.h +246 -0
- package/numkong/include/numkong/spatial/svebfdot.h +125 -0
- package/numkong/include/numkong/spatial/svehalf.h +136 -0
- package/numkong/include/numkong/spatial/svesdot.h +143 -0
- package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
- package/numkong/include/numkong/spatial.h +1681 -0
- package/numkong/include/numkong/spatial.hpp +183 -0
- package/numkong/include/numkong/spatials/README.md +580 -0
- package/numkong/include/numkong/spatials/alder.h +94 -0
- package/numkong/include/numkong/spatials/diamond.h +82 -0
- package/numkong/include/numkong/spatials/genoa.h +94 -0
- package/numkong/include/numkong/spatials/graniteamx.h +173 -0
- package/numkong/include/numkong/spatials/haswell.h +219 -0
- package/numkong/include/numkong/spatials/icelake.h +113 -0
- package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
- package/numkong/include/numkong/spatials/neon.h +109 -0
- package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
- package/numkong/include/numkong/spatials/neonfhm.h +92 -0
- package/numkong/include/numkong/spatials/neonfp8.h +111 -0
- package/numkong/include/numkong/spatials/neonsdot.h +143 -0
- package/numkong/include/numkong/spatials/powervsx.h +153 -0
- package/numkong/include/numkong/spatials/rvv.h +1976 -0
- package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
- package/numkong/include/numkong/spatials/serial.h +248 -0
- package/numkong/include/numkong/spatials/sierra.h +96 -0
- package/numkong/include/numkong/spatials/skylake.h +184 -0
- package/numkong/include/numkong/spatials/sme.h +1927 -0
- package/numkong/include/numkong/spatials/smef64.h +483 -0
- package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
- package/numkong/include/numkong/spatials.h +3374 -0
- package/numkong/include/numkong/spatials.hpp +509 -0
- package/numkong/include/numkong/tensor.hpp +1981 -0
- package/numkong/include/numkong/trigonometry/README.md +184 -0
- package/numkong/include/numkong/trigonometry/haswell.h +653 -0
- package/numkong/include/numkong/trigonometry/neon.h +638 -0
- package/numkong/include/numkong/trigonometry/rvv.h +700 -0
- package/numkong/include/numkong/trigonometry/serial.h +703 -0
- package/numkong/include/numkong/trigonometry/skylake.h +725 -0
- package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
- package/numkong/include/numkong/trigonometry.h +467 -0
- package/numkong/include/numkong/trigonometry.hpp +166 -0
- package/numkong/include/numkong/types.h +1695 -0
- package/numkong/include/numkong/types.hpp +6027 -0
- package/numkong/include/numkong/vector.hpp +766 -0
- package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
- package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
- package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
- package/numkong/javascript/README.md +254 -0
- package/numkong/javascript/node-gyp-build.d.ts +4 -0
- package/numkong/javascript/numkong-browser.ts +40 -0
- package/numkong/javascript/numkong-wasm.ts +750 -0
- package/numkong/javascript/numkong.c +712 -0
- package/numkong/javascript/numkong.ts +613 -0
- package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
- package/numkong/javascript/tsconfig-cjs.json +13 -0
- package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
- package/numkong/javascript/types.ts +784 -0
- package/numkong/numkong.gypi +104 -0
- package/numkong/package.json +108 -0
- package/numkong/probes/arm_neon.c +8 -0
- package/numkong/probes/arm_neon_bfdot.c +9 -0
- package/numkong/probes/arm_neon_fhm.c +9 -0
- package/numkong/probes/arm_neon_half.c +8 -0
- package/numkong/probes/arm_neon_sdot.c +9 -0
- package/numkong/probes/arm_neonfp8.c +9 -0
- package/numkong/probes/arm_sme.c +16 -0
- package/numkong/probes/arm_sme2.c +16 -0
- package/numkong/probes/arm_sme2p1.c +16 -0
- package/numkong/probes/arm_sme_bf16.c +16 -0
- package/numkong/probes/arm_sme_bi32.c +16 -0
- package/numkong/probes/arm_sme_f64.c +16 -0
- package/numkong/probes/arm_sme_fa64.c +14 -0
- package/numkong/probes/arm_sme_half.c +16 -0
- package/numkong/probes/arm_sme_lut2.c +15 -0
- package/numkong/probes/arm_sve.c +18 -0
- package/numkong/probes/arm_sve2.c +20 -0
- package/numkong/probes/arm_sve2p1.c +18 -0
- package/numkong/probes/arm_sve_bfdot.c +20 -0
- package/numkong/probes/arm_sve_half.c +18 -0
- package/numkong/probes/arm_sve_sdot.c +21 -0
- package/numkong/probes/loongarch_lasx.c +12 -0
- package/numkong/probes/power_vsx.c +12 -0
- package/numkong/probes/probe.js +127 -0
- package/numkong/probes/riscv_rvv.c +14 -0
- package/numkong/probes/riscv_rvv_bb.c +15 -0
- package/numkong/probes/riscv_rvv_bf16.c +17 -0
- package/numkong/probes/riscv_rvv_half.c +14 -0
- package/numkong/probes/wasm_v128relaxed.c +11 -0
- package/numkong/probes/x86_alder.c +17 -0
- package/numkong/probes/x86_diamond.c +17 -0
- package/numkong/probes/x86_genoa.c +17 -0
- package/numkong/probes/x86_graniteamx.c +19 -0
- package/numkong/probes/x86_haswell.c +11 -0
- package/numkong/probes/x86_icelake.c +17 -0
- package/numkong/probes/x86_sapphire.c +16 -0
- package/numkong/probes/x86_sapphireamx.c +18 -0
- package/numkong/probes/x86_sierra.c +17 -0
- package/numkong/probes/x86_skylake.c +15 -0
- package/numkong/probes/x86_turin.c +17 -0
- package/numkong/rust/README.md +698 -0
- package/numkong/rust/capabilities.rs +96 -0
- package/numkong/rust/cast.rs +314 -0
- package/numkong/rust/curved.rs +391 -0
- package/numkong/rust/each.rs +2721 -0
- package/numkong/rust/geospatial.rs +343 -0
- package/numkong/rust/matrix.rs +5424 -0
- package/numkong/rust/maxsim.rs +540 -0
- package/numkong/rust/mesh.rs +837 -0
- package/numkong/rust/numkong.rs +409 -0
- package/numkong/rust/probability.rs +272 -0
- package/numkong/rust/reduce.rs +1249 -0
- package/numkong/rust/set.rs +194 -0
- package/numkong/rust/sparse.rs +513 -0
- package/numkong/rust/spatial.rs +1815 -0
- package/numkong/rust/tensor.rs +7565 -0
- package/numkong/rust/types.rs +3666 -0
- package/numkong/rust/vector.rs +1899 -0
- package/numkong/rustfmt.toml +2 -0
- package/numkong/swift/Matrix.swift +1388 -0
- package/numkong/swift/MaxSim.swift +151 -0
- package/numkong/swift/NumKong.swift +283 -0
- package/numkong/swift/Numerics.swift +329 -0
- package/numkong/swift/README.md +433 -0
- package/numkong/swift/Scalar.swift +741 -0
- package/numkong/swift/Tensor.swift +209 -0
- package/numkong/test/README.md +315 -0
- package/numkong/test/playwright.config.ts +16 -0
- package/numkong/test/swift/Test.swift +534 -0
- package/numkong/test/test-browser-bundle-runner.mjs +36 -0
- package/numkong/test/test-browser-bundle.html +188 -0
- package/numkong/test/test-browser-runner.mjs +43 -0
- package/numkong/test/test-browser.html +305 -0
- package/numkong/test/test-dtypes.mjs +453 -0
- package/numkong/test/test-wasm.mjs +267 -0
- package/numkong/test/test.cpp +442 -0
- package/numkong/test/test.hpp +580 -0
- package/numkong/test/test.mjs +363 -0
- package/numkong/test/test_base.py +1041 -0
- package/numkong/test/test_cast.cpp +242 -0
- package/numkong/test/test_cross.hpp +551 -0
- package/numkong/test/test_cross.py +467 -0
- package/numkong/test/test_cross_amx.cpp +50 -0
- package/numkong/test/test_cross_arm.cpp +225 -0
- package/numkong/test/test_cross_blas.cpp +354 -0
- package/numkong/test/test_cross_loongarch.cpp +90 -0
- package/numkong/test/test_cross_power.cpp +73 -0
- package/numkong/test/test_cross_rvv.cpp +109 -0
- package/numkong/test/test_cross_serial.cpp +181 -0
- package/numkong/test/test_cross_sme.cpp +148 -0
- package/numkong/test/test_cross_wasm.cpp +141 -0
- package/numkong/test/test_cross_x86.cpp +442 -0
- package/numkong/test/test_curved.cpp +182 -0
- package/numkong/test/test_curved.py +207 -0
- package/numkong/test/test_dot.cpp +353 -0
- package/numkong/test/test_dot.py +296 -0
- package/numkong/test/test_each.cpp +437 -0
- package/numkong/test/test_each.py +756 -0
- package/numkong/test/test_geospatial.cpp +155 -0
- package/numkong/test/test_geospatial.py +241 -0
- package/numkong/test/test_maxsim.cpp +138 -0
- package/numkong/test/test_maxsim.py +209 -0
- package/numkong/test/test_mesh.cpp +203 -0
- package/numkong/test/test_mesh.py +394 -0
- package/numkong/test/test_probability.cpp +136 -0
- package/numkong/test/test_probability.py +166 -0
- package/numkong/test/test_reduce.cpp +563 -0
- package/numkong/test/test_reduce.py +781 -0
- package/numkong/test/test_set.cpp +151 -0
- package/numkong/test/test_set.py +120 -0
- package/numkong/test/test_similarities.py +579 -0
- package/numkong/test/test_sparse.cpp +121 -0
- package/numkong/test/test_sparse.py +118 -0
- package/numkong/test/test_spatial.cpp +518 -0
- package/numkong/test/test_spatial.py +269 -0
- package/numkong/test/test_tensor.cpp +884 -0
- package/numkong/test/test_tensor.py +1417 -0
- package/numkong/test/test_trigonometry.cpp +156 -0
- package/numkong/test/test_trigonometry.py +180 -0
- package/package.json +7 -8
- package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
- package/prebuilds/linux-arm64/usearch.node +0 -0
- package/prebuilds/linux-x64/usearch.node +0 -0
- package/fp16/CMakeLists.txt +0 -176
- package/fp16/LICENSE +0 -11
- package/fp16/README.md +0 -20
- package/fp16/bench/alt-element.cc +0 -89
- package/fp16/bench/from-alt-array.cc +0 -175
- package/fp16/bench/from-ieee-array.cc +0 -399
- package/fp16/bench/ieee-element.cc +0 -272
- package/fp16/bench/to-alt-array.cc +0 -91
- package/fp16/bench/to-ieee-array.cc +0 -303
- package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
- package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
- package/fp16/cmake/DownloadPSimd.cmake +0 -15
- package/fp16/configure.py +0 -65
- package/fp16/confu.yaml +0 -8
- package/fp16/include/fp16/__init__.py +0 -0
- package/fp16/include/fp16/avx.py +0 -50
- package/fp16/include/fp16/avx2.py +0 -53
- package/fp16/include/fp16/bitcasts.h +0 -92
- package/fp16/include/fp16/fp16.h +0 -451
- package/fp16/include/fp16/psimd.h +0 -131
- package/fp16/include/fp16.h +0 -11
- package/fp16/jni/Android.mk +0 -6
- package/fp16/jni/Application.mk +0 -4
- package/fp16/test/alt-from-fp32-value.cc +0 -498
- package/fp16/test/alt-to-fp32-bits.cc +0 -263
- package/fp16/test/alt-to-fp32-psimd.cc +0 -145
- package/fp16/test/alt-to-fp32-value.cc +0 -348
- package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
- package/fp16/test/bitcasts.cc +0 -56
- package/fp16/test/ieee-from-fp32-value.cc +0 -523
- package/fp16/test/ieee-to-fp32-bits.cc +0 -333
- package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
- package/fp16/test/ieee-to-fp32-value.cc +0 -420
- package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
- package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
- package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
- package/fp16/test/peachpy/stubs.py +0 -38
- package/fp16/test/tables.cc +0 -530
- package/fp16/test/tables.h +0 -13
- package/fp16/third-party/THHalf.h +0 -92
- package/fp16/third-party/eigen-half.h +0 -170
- package/fp16/third-party/float16-compressor.h +0 -80
- package/fp16/third-party/half.hpp +0 -2916
- package/fp16/third-party/npy-halffloat.h +0 -328
- package/simsimd/.git-blame-ignore-revs +0 -2
- package/simsimd/CONTRIBUTING.md +0 -321
- package/simsimd/Cargo.toml +0 -49
- package/simsimd/MANIFEST.in +0 -4
- package/simsimd/Package.swift +0 -28
- package/simsimd/README.md +0 -1493
- package/simsimd/binding.gyp +0 -35
- package/simsimd/build.rs +0 -70
- package/simsimd/c/lib.c +0 -374
- package/simsimd/include/module.modulemap +0 -4
- package/simsimd/include/simsimd/binary.h +0 -486
- package/simsimd/include/simsimd/curved.h +0 -1541
- package/simsimd/include/simsimd/dot.h +0 -1853
- package/simsimd/include/simsimd/elementwise.h +0 -2465
- package/simsimd/include/simsimd/geospatial.h +0 -43
- package/simsimd/include/simsimd/mesh.h +0 -69
- package/simsimd/include/simsimd/probability.h +0 -606
- package/simsimd/include/simsimd/simsimd.h +0 -2567
- package/simsimd/include/simsimd/sparse.h +0 -1384
- package/simsimd/include/simsimd/spatial.h +0 -2335
- package/simsimd/include/simsimd/types.h +0 -666
- package/simsimd/javascript/fallback.ts +0 -233
- package/simsimd/javascript/lib.c +0 -125
- package/simsimd/javascript/node-gyp-build.d.ts +0 -1
- package/simsimd/javascript/simsimd.ts +0 -179
- package/simsimd/javascript/tsconfig-cjs.json +0 -8
- package/simsimd/package-lock.json +0 -1761
- package/simsimd/package.json +0 -61
- package/simsimd/rust/lib.rs +0 -1821
- package/simsimd/scripts/bench.cxx +0 -1170
- package/simsimd/scripts/bench.ipynb +0 -187
- package/simsimd/scripts/bench.js +0 -127
- package/simsimd/scripts/bench.rs +0 -876
- package/simsimd/scripts/bench_vectors.py +0 -734
- package/simsimd/scripts/bench_vectors_live.py +0 -213
- package/simsimd/scripts/test.c +0 -187
- package/simsimd/scripts/test.mjs +0 -220
- package/simsimd/scripts/test.py +0 -1505
- package/simsimd/swift/SimSIMD.swift +0 -149
- package/simsimd/swift/Test.swift +0 -128
- /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
- /package/{simsimd → numkong}/LICENSE +0 -0
- /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
- /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @brief SIMD-accelerated Set Similarity Measures.
|
|
3
|
+
* @file include/numkong/set.h
|
|
4
|
+
* @author Ash Vardanian
|
|
5
|
+
* @date July 1, 2023
|
|
6
|
+
*
|
|
7
|
+
* Contains following similarity measures:
|
|
8
|
+
*
|
|
9
|
+
* - Bit-level Hamming distance → `u32` counter
|
|
10
|
+
* - Byte-level Hamming distance → `u32` counter
|
|
11
|
+
* - Bit-level Jaccard distance (Tanimoto coefficient) → `f32` ratio
|
|
12
|
+
* - Word-level Jaccard distance for `u16` and `u32` MinHash vectors from StringZilla → `f32` ratio
|
|
13
|
+
*
|
|
14
|
+
* For hardware architectures:
|
|
15
|
+
*
|
|
16
|
+
* - Arm: NEON, SVE
|
|
17
|
+
* - x86: Haswell, Ice Lake
|
|
18
|
+
* - RISC-V: RVV, RVV+BB
|
|
19
|
+
* - WASM: V128Relaxed
|
|
20
|
+
*
|
|
21
|
+
* @section numerical_stability Numerical Stability
|
|
22
|
+
*
|
|
23
|
+
* Hamming u1: u32 popcount accumulator. Overflows at n_bits > 2^32 (~4.3 billion).
|
|
24
|
+
* The streaming u1x512 variant uses u64, safe for any practical dimension.
|
|
25
|
+
* Jaccard u1: u32 intersection/union counts, f32 division at finalization.
|
|
26
|
+
* Popcount values above 2^24 lose precision in f32 cast (24-bit mantissa).
|
|
27
|
+
* Byte-level Hamming/Jaccard u8: u32 mismatch counter. Overflows at n > 2^32.
|
|
28
|
+
*
|
|
29
|
+
* @section popcount_strategies Population Count Strategies
|
|
30
|
+
*
|
|
31
|
+
* Jaccard distances are extremely common and also fairly cheap to compute on binary vectors.
|
|
32
|
+
* The hardest part of optimizing binary similarity measures is the population count operation.
|
|
33
|
+
* It's natively supported by almost every instruction set, but the throughput and latency can
|
|
34
|
+
* be suboptimal. There are several ways to optimize this operation:
|
|
35
|
+
*
|
|
36
|
+
* - Lookup tables, mostly using nibbles (4-bit lookups)
|
|
37
|
+
* - Harley-Seal population counts using Carry-Save Adders (CSA)
|
|
38
|
+
*
|
|
39
|
+
* @section x86_instructions Relevant x86 Instructions
|
|
40
|
+
*
|
|
41
|
+
* On binary vectors, when computing Jaccard distance, the CPU often struggles to compute the
|
|
42
|
+
* large number of required population counts. There are several instructions we should keep in mind:
|
|
43
|
+
*
|
|
44
|
+
* Intrinsic Instruction Icelake Genoa
|
|
45
|
+
* _mm512_popcnt_epi64 VPOPCNTQ (ZMM, K, ZMM) 3cy @ p5 2cy @ p01
|
|
46
|
+
* _mm512_shuffle_epi8 VPSHUFB (ZMM, ZMM, ZMM) 1cy @ p5 2cy @ p12
|
|
47
|
+
* _mm512_sad_epu8 VPSADBW (ZMM, ZMM, ZMM) 3cy @ p5 3cy @ p01
|
|
48
|
+
* _mm512_ternarylogic_epi64 VPTERNLOGQ (ZMM, ZMM, ZMM, I8) 1cy @ p05 1cy @ p0123
|
|
49
|
+
* _mm512_gf2p8mul_epi8 VGF2P8MULB (ZMM, ZMM, ZMM) 5cy @ p0 3cy @ p01
|
|
50
|
+
*
|
|
51
|
+
* On Ice Lake, VPOPCNTQ bottlenecks on port 5. On AMD Genoa/Turin, it dual-issues
|
|
52
|
+
* on ports 0-1, making native popcount significantly faster without CSA tricks.
|
|
53
|
+
*
|
|
54
|
+
* @section harley_seal Harley-Seal Carry-Save Adders
|
|
55
|
+
*
|
|
56
|
+
* The Harley-Seal algorithm uses Carry-Save Adders (CSA) to accumulate population counts
|
|
57
|
+
* with fewer VPOPCNTQ instructions. A CSA computes (a + b + c) as (sum, carry) using only
|
|
58
|
+
* bitwise operations, deferring expensive popcounts to the final reduction.
|
|
59
|
+
*
|
|
60
|
+
* Performance varies significantly by architecture and buffer size (cycles/byte):
|
|
61
|
+
*
|
|
62
|
+
* Method Buffer Ice Lake Sapphire Genoa
|
|
63
|
+
* Native VPOPCNTQ any ~0.12 ~0.10 ~0.06
|
|
64
|
+
* Harley-Seal CSA 1 KB 0.107 0.095 0.08
|
|
65
|
+
* Harley-Seal CSA 4 KB 0.056 0.052 0.05
|
|
66
|
+
* VPSHUFB lookup 4 KB 0.063 0.058 0.07
|
|
67
|
+
*
|
|
68
|
+
* For small buffers (<1KB), loop overhead dominates and unrolled native VPOPCNTQ wins.
|
|
69
|
+
* Harley-Seal shines on large buffers where CSA chains amortize the setup cost.
|
|
70
|
+
* On AMD Genoa, native VPOPCNTQ is competitive even for large buffers.
|
|
71
|
+
*
|
|
72
|
+
* @section jaccard_norms Jaccard Optimization via Norms
|
|
73
|
+
*
|
|
74
|
+
* There is a trivial optimization to halve the number of population counts needed for
|
|
75
|
+
* binary Jaccard distance, if one knows the set magnitudes ahead of time:
|
|
76
|
+
*
|
|
77
|
+
* J = |A ∩ B| / |A ∪ B| = |A ∩ B| / (|A| + |B| - |A ∩ B|)
|
|
78
|
+
*
|
|
79
|
+
* At that point the problem reduces to optimizing memory accesses and register usage.
|
|
80
|
+
* For such cases, we provide additional function variants designed exclusively for compile-time
|
|
81
|
+
* dispatch in heavily inlined code, operating on wider vectors with known sizes:
|
|
82
|
+
*
|
|
83
|
+
* - nk_jaccard_u1x512_state_<isa>_t - Smallest optimal running state
|
|
84
|
+
* - nk_jaccard_u1x512_init_<isa> - Initializes the running state
|
|
85
|
+
* - nk_jaccard_u1x512_update_<isa> - Updates the running state with 2 new 512-bit vectors
|
|
86
|
+
* - nk_jaccard_u1x512_finalize_<isa> - Finalizes the running state and produces the distance
|
|
87
|
+
*
|
|
88
|
+
* @section streaming_api Streaming API
|
|
89
|
+
*
|
|
90
|
+
* The streaming variants aren't always strictly equivalent to their counterparts above
|
|
91
|
+
* and their usage also differs quite drastically. For large-scale batch processing where
|
|
92
|
+
* vectors won't be reused, consider non-temporal loads (`_mm512_stream_load_si512`) to
|
|
93
|
+
* bypass the cache and avoid pollution. This is especially beneficial when computing
|
|
94
|
+
* distances across millions of vectors in a single pass.
|
|
95
|
+
*
|
|
96
|
+
* @code{.c}
|
|
97
|
+
* // 1024-dimensional binary vectors, one query and four targets
|
|
98
|
+
* nk_u1x8_t query[128], target_first[128], target_second[128], target_third[128], target_fourth[128];
|
|
99
|
+
* // Precomputed popcount of 'a' as f32
|
|
100
|
+
* nk_f32_t query_popcount = ...;
|
|
101
|
+
* nk_f32_t target_popcount_first = ..., target_popcount_second = ...;
|
|
102
|
+
*
|
|
103
|
+
* nk_jaccard_u1x512_state_icelake_t state_first, state_second, state_third, state_fourth;
|
|
104
|
+
* nk_jaccard_u1x512_init_icelake(&state_first);
|
|
105
|
+
* nk_jaccard_u1x512_init_icelake(&state_second);
|
|
106
|
+
* nk_jaccard_u1x512_init_icelake(&state_third);
|
|
107
|
+
* nk_jaccard_u1x512_init_icelake(&state_fourth);
|
|
108
|
+
* nk_jaccard_u1x512_update_icelake(&state_first, &query[0], &target_first[0], 0, 512); // First 512 bits
|
|
109
|
+
* nk_jaccard_u1x512_update_icelake(&state_first, &query[64], &target_first[64], 512, 512); // Second 512 bits
|
|
110
|
+
* // ... update state_second, state_third, state_fourth similarly ...
|
|
111
|
+
*
|
|
112
|
+
* nk_f32_t results[4];
|
|
113
|
+
* nk_jaccard_u1x512_finalize_icelake(&state_first, &state_second, &state_third, &state_fourth,
|
|
114
|
+
* query_popcount, target_popcount_first, target_popcount_second,
|
|
115
|
+
* target_popcount_third, target_popcount_fourth, total_dimensions, results);
|
|
116
|
+
* @endcode
|
|
117
|
+
*
|
|
118
|
+
* @section tail_handling Tail Handling
|
|
119
|
+
*
|
|
120
|
+
* The trickiest part is handling the tails of the vectors when their size isn't divisible
|
|
121
|
+
* by our step size. In such cases, it's recommended to use masked loads when supported by
|
|
122
|
+
* the ISA, or fall back to scalar code and a local on-stack buffer.
|
|
123
|
+
*
|
|
124
|
+
* @section references References
|
|
125
|
+
*
|
|
126
|
+
* - Intel Intrinsics Guide: https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html
|
|
127
|
+
* - Arm Intrinsics Reference: https://developer.arm.com/architectures/instruction-sets/intrinsics/
|
|
128
|
+
* - Muła et al. "Faster Population Counts": https://arxiv.org/pdf/1611.07612
|
|
129
|
+
* - Muła SSE POPCOUNT experiments: https://github.com/WojciechMula/sse-popcount
|
|
130
|
+
* - NumKong binary R&D tracker: https://github.com/ashvardanian/NumKong/pull/138
|
|
131
|
+
*
|
|
132
|
+
* @section Finalize Output Types
|
|
133
|
+
*
|
|
134
|
+
* Jaccard similarity finalize outputs to f32:
|
|
135
|
+
* - Jaccard = intersection / union, always ∈ [0.0, 1.0]
|
|
136
|
+
* - f32 provides ~7 decimal digits, far exceeding practical needs
|
|
137
|
+
* - Matches spatial.h convention for non-f64 distance outputs
|
|
138
|
+
* - Reduces memory footprint in large-scale binary similarity search
|
|
139
|
+
*
|
|
140
|
+
* The intersection and union counts are u64 internally for correctness,
|
|
141
|
+
* but the final ratio fits comfortably in f32.
|
|
142
|
+
*
|
|
143
|
+
*/
|
|
144
|
+
#ifndef NK_SET_H
|
|
145
|
+
#define NK_SET_H
|
|
146
|
+
|
|
147
|
+
#include "numkong/types.h"
|
|
148
|
+
|
|
149
|
+
#if defined(__cplusplus)
|
|
150
|
+
extern "C" {
|
|
151
|
+
#endif
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @brief Binary Hamming distance computing the number of differing bits between two binary vectors.
|
|
155
|
+
*
|
|
156
|
+
* @param[in] a The first binary vector.
|
|
157
|
+
* @param[in] b The second binary vector.
|
|
158
|
+
* @param[in] n The number of bits in the vectors.
|
|
159
|
+
* @param[out] result The output distance value.
|
|
160
|
+
*
|
|
161
|
+
* @note The output distance value is non-negative.
|
|
162
|
+
* @note The output distance value is zero if and only if the two vectors are identical.
|
|
163
|
+
*/
|
|
164
|
+
NK_DYNAMIC void nk_hamming_u1(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @brief Binary Jaccard distance computing the ratio of differing bits to the union of bits.
|
|
168
|
+
*
|
|
169
|
+
* @param[in] a The first binary vector.
|
|
170
|
+
* @param[in] b The second binary vector.
|
|
171
|
+
* @param[in] n The number of bits in the vectors.
|
|
172
|
+
* @param[out] result The output distance value.
|
|
173
|
+
*
|
|
174
|
+
* @note The output distance value is non-negative.
|
|
175
|
+
* @note The output distance value is zero if and only if the two vectors are identical.
|
|
176
|
+
*/
|
|
177
|
+
NK_DYNAMIC void nk_jaccard_u1(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result);
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* @brief Integral Jaccard distance computing the ratio of differing bits to the union of bits.
|
|
181
|
+
*
|
|
182
|
+
* @param[in] a The first binary vector.
|
|
183
|
+
* @param[in] b The second binary vector.
|
|
184
|
+
* @param[in] n The number of 32-bit scalars in the vectors.
|
|
185
|
+
* @param[out] result The output distance value.
|
|
186
|
+
*
|
|
187
|
+
* @note The output distance value is non-negative.
|
|
188
|
+
* @note The output distance value is zero if and only if the two vectors are identical.
|
|
189
|
+
*/
|
|
190
|
+
NK_DYNAMIC void nk_jaccard_u32(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result);
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* @brief Byte-level Hamming distance computing the number of differing bytes between two vectors.
|
|
194
|
+
*
|
|
195
|
+
* @param[in] a The first byte vector.
|
|
196
|
+
* @param[in] b The second byte vector.
|
|
197
|
+
* @param[in] n The number of bytes in the vectors.
|
|
198
|
+
* @param[out] result The output distance value.
|
|
199
|
+
*
|
|
200
|
+
* @note The output distance value is non-negative.
|
|
201
|
+
* @note The output distance value is zero if and only if the two vectors are identical.
|
|
202
|
+
*/
|
|
203
|
+
NK_DYNAMIC void nk_hamming_u8(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @brief Integral Jaccard distance for 16-bit unsigned integer vectors.
|
|
207
|
+
*
|
|
208
|
+
* @param[in] a The first vector.
|
|
209
|
+
* @param[in] b The second vector.
|
|
210
|
+
* @param[in] n The number of 16-bit scalars in the vectors.
|
|
211
|
+
* @param[out] result The output distance value.
|
|
212
|
+
*
|
|
213
|
+
* @note The output distance value is non-negative.
|
|
214
|
+
* @note The output distance value is zero if and only if the two vectors are identical.
|
|
215
|
+
*/
|
|
216
|
+
NK_DYNAMIC void nk_jaccard_u16(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result);
|
|
217
|
+
|
|
218
|
+
/** @copydoc nk_hamming_u1 */
|
|
219
|
+
NK_PUBLIC void nk_hamming_u1_serial(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
220
|
+
/** @copydoc nk_hamming_u8 */
|
|
221
|
+
NK_PUBLIC void nk_hamming_u8_serial(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
222
|
+
/** @copydoc nk_jaccard_u1 */
|
|
223
|
+
NK_PUBLIC void nk_jaccard_u1_serial(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result);
|
|
224
|
+
/** @copydoc nk_jaccard_u32 */
|
|
225
|
+
NK_PUBLIC void nk_jaccard_u32_serial(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result);
|
|
226
|
+
/** @copydoc nk_jaccard_u16 */
|
|
227
|
+
NK_PUBLIC void nk_jaccard_u16_serial(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result);
|
|
228
|
+
|
|
229
|
+
#if NK_TARGET_NEON
|
|
230
|
+
/** @copydoc nk_hamming_u1 */
|
|
231
|
+
NK_PUBLIC void nk_hamming_u1_neon(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
232
|
+
/** @copydoc nk_hamming_u8 */
|
|
233
|
+
NK_PUBLIC void nk_hamming_u8_neon(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
234
|
+
/** @copydoc nk_jaccard_u1 */
|
|
235
|
+
NK_PUBLIC void nk_jaccard_u1_neon(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result);
|
|
236
|
+
/** @copydoc nk_jaccard_u32 */
|
|
237
|
+
NK_PUBLIC void nk_jaccard_u32_neon(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result);
|
|
238
|
+
/** @copydoc nk_jaccard_u16 */
|
|
239
|
+
NK_PUBLIC void nk_jaccard_u16_neon(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result);
|
|
240
|
+
|
|
241
|
+
#endif // NK_TARGET_NEON
|
|
242
|
+
|
|
243
|
+
#if NK_TARGET_SVE
|
|
244
|
+
/** @copydoc nk_hamming_u1 */
|
|
245
|
+
NK_PUBLIC void nk_hamming_u1_sve(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
246
|
+
/** @copydoc nk_hamming_u8 */
|
|
247
|
+
NK_PUBLIC void nk_hamming_u8_sve(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
248
|
+
/** @copydoc nk_jaccard_u1 */
|
|
249
|
+
NK_PUBLIC void nk_jaccard_u1_sve(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result);
|
|
250
|
+
/** @copydoc nk_jaccard_u32 */
|
|
251
|
+
NK_PUBLIC void nk_jaccard_u32_sve(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result);
|
|
252
|
+
/** @copydoc nk_jaccard_u16 */
|
|
253
|
+
NK_PUBLIC void nk_jaccard_u16_sve(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result);
|
|
254
|
+
#endif // NK_TARGET_SVE
|
|
255
|
+
|
|
256
|
+
#if NK_TARGET_HASWELL
|
|
257
|
+
/** @copydoc nk_hamming_u1 */
|
|
258
|
+
NK_PUBLIC void nk_hamming_u1_haswell(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
259
|
+
/** @copydoc nk_hamming_u8 */
|
|
260
|
+
NK_PUBLIC void nk_hamming_u8_haswell(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
261
|
+
/** @copydoc nk_jaccard_u1 */
|
|
262
|
+
NK_PUBLIC void nk_jaccard_u1_haswell(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result);
|
|
263
|
+
/** @copydoc nk_jaccard_u16 */
|
|
264
|
+
NK_PUBLIC void nk_jaccard_u16_haswell(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result);
|
|
265
|
+
/** @copydoc nk_jaccard_u32 */
|
|
266
|
+
NK_PUBLIC void nk_jaccard_u32_haswell(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result);
|
|
267
|
+
#endif // NK_TARGET_HASWELL
|
|
268
|
+
|
|
269
|
+
#if NK_TARGET_ICELAKE
|
|
270
|
+
/** @copydoc nk_hamming_u1 */
|
|
271
|
+
NK_PUBLIC void nk_hamming_u1_icelake(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
272
|
+
/** @copydoc nk_hamming_u8 */
|
|
273
|
+
NK_PUBLIC void nk_hamming_u8_icelake(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
274
|
+
/** @copydoc nk_jaccard_u1 */
|
|
275
|
+
NK_PUBLIC void nk_jaccard_u1_icelake(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result);
|
|
276
|
+
/** @copydoc nk_jaccard_u32 */
|
|
277
|
+
NK_PUBLIC void nk_jaccard_u32_icelake(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result);
|
|
278
|
+
/** @copydoc nk_jaccard_u16 */
|
|
279
|
+
NK_PUBLIC void nk_jaccard_u16_icelake(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result);
|
|
280
|
+
#endif // NK_TARGET_ICELAKE
|
|
281
|
+
|
|
282
|
+
#if NK_TARGET_RVVBB
|
|
283
|
+
/** @copydoc nk_hamming_u1 */
|
|
284
|
+
NK_PUBLIC void nk_hamming_u1_rvvbb(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
285
|
+
/** @copydoc nk_jaccard_u1 */
|
|
286
|
+
NK_PUBLIC void nk_jaccard_u1_rvvbb(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result);
|
|
287
|
+
#endif // NK_TARGET_RVVBB
|
|
288
|
+
|
|
289
|
+
#if NK_TARGET_RVV
|
|
290
|
+
/** @copydoc nk_hamming_u1 */
|
|
291
|
+
NK_PUBLIC void nk_hamming_u1_rvv(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
292
|
+
/** @copydoc nk_hamming_u8 */
|
|
293
|
+
NK_PUBLIC void nk_hamming_u8_rvv(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
294
|
+
/** @copydoc nk_jaccard_u1 */
|
|
295
|
+
NK_PUBLIC void nk_jaccard_u1_rvv(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result);
|
|
296
|
+
/** @copydoc nk_jaccard_u16 */
|
|
297
|
+
NK_PUBLIC void nk_jaccard_u16_rvv(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result);
|
|
298
|
+
/** @copydoc nk_jaccard_u32 */
|
|
299
|
+
NK_PUBLIC void nk_jaccard_u32_rvv(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result);
|
|
300
|
+
#endif // NK_TARGET_RVV
|
|
301
|
+
|
|
302
|
+
#if NK_TARGET_V128RELAXED
|
|
303
|
+
/** @copydoc nk_hamming_u1 */
|
|
304
|
+
NK_PUBLIC void nk_hamming_u1_v128relaxed(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
305
|
+
/** @copydoc nk_hamming_u8 */
|
|
306
|
+
NK_PUBLIC void nk_hamming_u8_v128relaxed(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result);
|
|
307
|
+
/** @copydoc nk_jaccard_u1 */
|
|
308
|
+
NK_PUBLIC void nk_jaccard_u1_v128relaxed(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result);
|
|
309
|
+
/** @copydoc nk_jaccard_u16 */
|
|
310
|
+
NK_PUBLIC void nk_jaccard_u16_v128relaxed(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result);
|
|
311
|
+
/** @copydoc nk_jaccard_u32 */
|
|
312
|
+
NK_PUBLIC void nk_jaccard_u32_v128relaxed(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result);
|
|
313
|
+
#endif // NK_TARGET_V128RELAXED
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* @brief Returns the output dtype for Hamming distance.
|
|
317
|
+
*/
|
|
318
|
+
NK_INTERNAL nk_dtype_t nk_hamming_output_dtype(nk_dtype_t dtype) {
|
|
319
|
+
switch (dtype) {
|
|
320
|
+
case nk_u1_k: return nk_u32_k;
|
|
321
|
+
case nk_u8_k: return nk_u32_k;
|
|
322
|
+
default: return nk_dtype_unknown_k;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* @brief Returns the output dtype for Jaccard distance.
|
|
328
|
+
*/
|
|
329
|
+
NK_INTERNAL nk_dtype_t nk_jaccard_output_dtype(nk_dtype_t dtype) {
|
|
330
|
+
switch (dtype) {
|
|
331
|
+
case nk_u1_k: return nk_f32_k;
|
|
332
|
+
case nk_u16_k: return nk_f32_k;
|
|
333
|
+
case nk_u32_k: return nk_f32_k;
|
|
334
|
+
default: return nk_dtype_unknown_k;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
#if defined(__cplusplus)
|
|
339
|
+
} // extern "C"
|
|
340
|
+
#endif
|
|
341
|
+
|
|
342
|
+
#include "numkong/set/serial.h"
|
|
343
|
+
#include "numkong/set/neon.h"
|
|
344
|
+
#include "numkong/set/sve.h"
|
|
345
|
+
#include "numkong/set/icelake.h"
|
|
346
|
+
#include "numkong/set/haswell.h"
|
|
347
|
+
#include "numkong/set/powervsx.h"
|
|
348
|
+
#include "numkong/set/v128relaxed.h"
|
|
349
|
+
#include "numkong/set/rvv.h"
|
|
350
|
+
#include "numkong/set/rvvbb.h"
|
|
351
|
+
#include "numkong/set/loongsonasx.h"
|
|
352
|
+
|
|
353
|
+
#if defined(__cplusplus)
|
|
354
|
+
extern "C" {
|
|
355
|
+
#endif
|
|
356
|
+
|
|
357
|
+
#if !NK_DYNAMIC_DISPATCH
|
|
358
|
+
|
|
359
|
+
NK_PUBLIC void nk_hamming_u1(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result) {
|
|
360
|
+
#if NK_TARGET_V128RELAXED
|
|
361
|
+
nk_hamming_u1_v128relaxed(a, b, n, result);
|
|
362
|
+
#elif NK_TARGET_SVE
|
|
363
|
+
nk_hamming_u1_sve(a, b, n, result);
|
|
364
|
+
#elif NK_TARGET_NEON
|
|
365
|
+
nk_hamming_u1_neon(a, b, n, result);
|
|
366
|
+
#elif NK_TARGET_ICELAKE
|
|
367
|
+
nk_hamming_u1_icelake(a, b, n, result);
|
|
368
|
+
#elif NK_TARGET_HASWELL
|
|
369
|
+
nk_hamming_u1_haswell(a, b, n, result);
|
|
370
|
+
#elif NK_TARGET_POWERVSX
|
|
371
|
+
nk_hamming_u1_powervsx(a, b, n, result);
|
|
372
|
+
#elif NK_TARGET_LOONGSONASX
|
|
373
|
+
nk_hamming_u1_loongsonasx(a, b, n, result);
|
|
374
|
+
#elif NK_TARGET_RVVBB
|
|
375
|
+
nk_hamming_u1_rvvbb(a, b, n, result);
|
|
376
|
+
#elif NK_TARGET_RVV
|
|
377
|
+
nk_hamming_u1_rvv(a, b, n, result);
|
|
378
|
+
#else
|
|
379
|
+
nk_hamming_u1_serial(a, b, n, result);
|
|
380
|
+
#endif
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
NK_PUBLIC void nk_jaccard_u1(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result) {
|
|
384
|
+
#if NK_TARGET_V128RELAXED
|
|
385
|
+
nk_jaccard_u1_v128relaxed(a, b, n, result);
|
|
386
|
+
#elif NK_TARGET_SVE
|
|
387
|
+
nk_jaccard_u1_sve(a, b, n, result);
|
|
388
|
+
#elif NK_TARGET_NEON
|
|
389
|
+
nk_jaccard_u1_neon(a, b, n, result);
|
|
390
|
+
#elif NK_TARGET_ICELAKE
|
|
391
|
+
nk_jaccard_u1_icelake(a, b, n, result);
|
|
392
|
+
#elif NK_TARGET_HASWELL
|
|
393
|
+
nk_jaccard_u1_haswell(a, b, n, result);
|
|
394
|
+
#elif NK_TARGET_POWERVSX
|
|
395
|
+
nk_jaccard_u1_powervsx(a, b, n, result);
|
|
396
|
+
#elif NK_TARGET_LOONGSONASX
|
|
397
|
+
nk_jaccard_u1_loongsonasx(a, b, n, result);
|
|
398
|
+
#elif NK_TARGET_RVVBB
|
|
399
|
+
nk_jaccard_u1_rvvbb(a, b, n, result);
|
|
400
|
+
#elif NK_TARGET_RVV
|
|
401
|
+
nk_jaccard_u1_rvv(a, b, n, result);
|
|
402
|
+
#else
|
|
403
|
+
nk_jaccard_u1_serial(a, b, n, result);
|
|
404
|
+
#endif
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
NK_PUBLIC void nk_jaccard_u32(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result) {
|
|
408
|
+
#if NK_TARGET_V128RELAXED
|
|
409
|
+
nk_jaccard_u32_v128relaxed(a, b, n, result);
|
|
410
|
+
#elif NK_TARGET_SVE
|
|
411
|
+
nk_jaccard_u32_sve(a, b, n, result);
|
|
412
|
+
#elif NK_TARGET_NEON
|
|
413
|
+
nk_jaccard_u32_neon(a, b, n, result);
|
|
414
|
+
#elif NK_TARGET_ICELAKE
|
|
415
|
+
nk_jaccard_u32_icelake(a, b, n, result);
|
|
416
|
+
#elif NK_TARGET_HASWELL
|
|
417
|
+
nk_jaccard_u32_haswell(a, b, n, result);
|
|
418
|
+
#elif NK_TARGET_RVV
|
|
419
|
+
nk_jaccard_u32_rvv(a, b, n, result);
|
|
420
|
+
#else
|
|
421
|
+
nk_jaccard_u32_serial(a, b, n, result);
|
|
422
|
+
#endif
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
NK_PUBLIC void nk_hamming_u8(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result) {
|
|
426
|
+
#if NK_TARGET_V128RELAXED
|
|
427
|
+
nk_hamming_u8_v128relaxed(a, b, n, result);
|
|
428
|
+
#elif NK_TARGET_SVE
|
|
429
|
+
nk_hamming_u8_sve(a, b, n, result);
|
|
430
|
+
#elif NK_TARGET_NEON
|
|
431
|
+
nk_hamming_u8_neon(a, b, n, result);
|
|
432
|
+
#elif NK_TARGET_ICELAKE
|
|
433
|
+
nk_hamming_u8_icelake(a, b, n, result);
|
|
434
|
+
#elif NK_TARGET_HASWELL
|
|
435
|
+
nk_hamming_u8_haswell(a, b, n, result);
|
|
436
|
+
#elif NK_TARGET_POWERVSX
|
|
437
|
+
nk_hamming_u8_powervsx(a, b, n, result);
|
|
438
|
+
#elif NK_TARGET_LOONGSONASX
|
|
439
|
+
nk_hamming_u8_loongsonasx(a, b, n, result);
|
|
440
|
+
#elif NK_TARGET_RVV
|
|
441
|
+
nk_hamming_u8_rvv(a, b, n, result);
|
|
442
|
+
#else
|
|
443
|
+
nk_hamming_u8_serial(a, b, n, result);
|
|
444
|
+
#endif
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
NK_PUBLIC void nk_jaccard_u16(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result) {
|
|
448
|
+
#if NK_TARGET_V128RELAXED
|
|
449
|
+
nk_jaccard_u16_v128relaxed(a, b, n, result);
|
|
450
|
+
#elif NK_TARGET_SVE
|
|
451
|
+
nk_jaccard_u16_sve(a, b, n, result);
|
|
452
|
+
#elif NK_TARGET_NEON
|
|
453
|
+
nk_jaccard_u16_neon(a, b, n, result);
|
|
454
|
+
#elif NK_TARGET_ICELAKE
|
|
455
|
+
nk_jaccard_u16_icelake(a, b, n, result);
|
|
456
|
+
#elif NK_TARGET_HASWELL
|
|
457
|
+
nk_jaccard_u16_haswell(a, b, n, result);
|
|
458
|
+
#elif NK_TARGET_RVV
|
|
459
|
+
nk_jaccard_u16_rvv(a, b, n, result);
|
|
460
|
+
#else
|
|
461
|
+
nk_jaccard_u16_serial(a, b, n, result);
|
|
462
|
+
#endif
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
#endif // !NK_DYNAMIC_DISPATCH
|
|
466
|
+
|
|
467
|
+
#if defined(__cplusplus)
|
|
468
|
+
} // extern "C"
|
|
469
|
+
#endif
|
|
470
|
+
|
|
471
|
+
#endif
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @brief C++ bindings for set-intersection kernels.
|
|
3
|
+
* @file include/numkong/set.hpp
|
|
4
|
+
* @author Ash Vardanian
|
|
5
|
+
* @date February 5, 2026
|
|
6
|
+
*/
|
|
7
|
+
#ifndef NK_SET_HPP
|
|
8
|
+
#define NK_SET_HPP
|
|
9
|
+
|
|
10
|
+
#include <cstdint>
|
|
11
|
+
#include <type_traits>
|
|
12
|
+
|
|
13
|
+
#include "numkong/set.h"
|
|
14
|
+
#include "numkong/sets.h"
|
|
15
|
+
|
|
16
|
+
#include "numkong/types.hpp"
|
|
17
|
+
|
|
18
|
+
namespace ashvardanian::numkong {
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @brief Hamming distance: Σ(aᵢ ⊕ bᵢ)
|
|
22
|
+
* @param[in] a,b Input vectors
|
|
23
|
+
* @param[in] d Number of dimensions
|
|
24
|
+
* @param[out] r Pointer to output count
|
|
25
|
+
*
|
|
26
|
+
* @tparam in_type_ Input vector element type (u1x8_t or u8_t)
|
|
27
|
+
* @tparam result_type_ Accumulator type, defaults to `in_type_::hamming_result_t`
|
|
28
|
+
* @tparam allow_simd_ Enable SIMD kernel dispatch when `prefer_simd_k`
|
|
29
|
+
*/
|
|
30
|
+
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::hamming_result_t,
|
|
31
|
+
allow_simd_t allow_simd_ = prefer_simd_k>
|
|
32
|
+
void hamming(in_type_ const *a, in_type_ const *b, std::size_t d, result_type_ *r) noexcept {
|
|
33
|
+
constexpr bool simd = allow_simd_ == prefer_simd_k &&
|
|
34
|
+
std::is_same_v<result_type_, typename in_type_::hamming_result_t>;
|
|
35
|
+
|
|
36
|
+
if constexpr (std::is_same_v<in_type_, u1x8_t> && simd) nk_hamming_u1(&a->raw_, &b->raw_, d, &r->raw_);
|
|
37
|
+
else if constexpr (std::is_same_v<in_type_, u8_t> && simd) nk_hamming_u8(&a->raw_, &b->raw_, d, &r->raw_);
|
|
38
|
+
else {
|
|
39
|
+
constexpr std::size_t dims_per_value = dimensions_per_value<in_type_>();
|
|
40
|
+
std::size_t n = divide_round_up(d, dims_per_value);
|
|
41
|
+
typename result_type_::raw_t count = 0;
|
|
42
|
+
for (std::size_t i = 0; i < n; i++) count += count_differences(a[i], b[i]);
|
|
43
|
+
*r = result_type_::from_raw(count);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @brief Jaccard distance: 1 − |A ∩ B| / |A ∪ B|
|
|
49
|
+
* @param[in] a,b Input vectors
|
|
50
|
+
* @param[in] d Number of dimensions
|
|
51
|
+
* @param[out] r Pointer to output distance
|
|
52
|
+
*
|
|
53
|
+
* For u1x8_t (bit vectors): uses popcount(AND) / popcount(OR)
|
|
54
|
+
* For u16_t/u32_t (element vectors): uses count of matching elements / total
|
|
55
|
+
*
|
|
56
|
+
* @tparam in_type_ Input vector element type (u1x8_t, u16_t, or u32_t)
|
|
57
|
+
* @tparam result_type_ Accumulator type, defaults to `in_type_::jaccard_result_t`
|
|
58
|
+
* @tparam allow_simd_ Enable SIMD kernel dispatch when `prefer_simd_k`
|
|
59
|
+
*/
|
|
60
|
+
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::jaccard_result_t,
|
|
61
|
+
allow_simd_t allow_simd_ = prefer_simd_k>
|
|
62
|
+
void jaccard(in_type_ const *a, in_type_ const *b, std::size_t d, result_type_ *r) noexcept {
|
|
63
|
+
constexpr bool simd = allow_simd_ == prefer_simd_k &&
|
|
64
|
+
std::is_same_v<result_type_, typename in_type_::jaccard_result_t>;
|
|
65
|
+
|
|
66
|
+
if constexpr (std::is_same_v<in_type_, u1x8_t> && simd) nk_jaccard_u1(&a->raw_, &b->raw_, d, &r->raw_);
|
|
67
|
+
else if constexpr (std::is_same_v<in_type_, u16_t> && simd) nk_jaccard_u16(&a->raw_, &b->raw_, d, &r->raw_);
|
|
68
|
+
else if constexpr (std::is_same_v<in_type_, u32_t> && simd) nk_jaccard_u32(&a->raw_, &b->raw_, d, &r->raw_);
|
|
69
|
+
else {
|
|
70
|
+
constexpr std::size_t dims_per_value = dimensions_per_value<in_type_>();
|
|
71
|
+
std::size_t n = divide_round_up(d, dims_per_value);
|
|
72
|
+
std::uint32_t intersection_count = 0, union_count = 0;
|
|
73
|
+
for (std::size_t i = 0; i < n; i++)
|
|
74
|
+
intersection_count += count_intersection(a[i], b[i]), union_count += count_union(a[i], b[i]);
|
|
75
|
+
if (union_count == 0) *r = result_type_();
|
|
76
|
+
else *r = result_type_(1) - result_type_(intersection_count) / result_type_(union_count);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
} // namespace ashvardanian::numkong
|
|
81
|
+
|
|
82
|
+
#include "numkong/tensor.hpp"
|
|
83
|
+
|
|
84
|
+
namespace ashvardanian::numkong {
|
|
85
|
+
|
|
86
|
+
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::hamming_result_t,
|
|
87
|
+
allow_simd_t allow_simd_ = prefer_simd_k, std::size_t max_rank_a_, std::size_t max_rank_b_>
|
|
88
|
+
void hamming(tensor_view<in_type_, max_rank_a_> a, tensor_view<in_type_, max_rank_b_> b, std::size_t d,
|
|
89
|
+
result_type_ *r) noexcept {
|
|
90
|
+
hamming<in_type_, result_type_, allow_simd_>(a.data(), b.data(), d, r);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::hamming_result_t,
|
|
94
|
+
allow_simd_t allow_simd_ = prefer_simd_k>
|
|
95
|
+
void hamming(vector_view<in_type_> a, vector_view<in_type_> b, std::size_t d, result_type_ *r) noexcept {
|
|
96
|
+
hamming<in_type_, result_type_, allow_simd_>(a.data(), b.data(), d, r);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::jaccard_result_t,
|
|
100
|
+
allow_simd_t allow_simd_ = prefer_simd_k, std::size_t max_rank_a_, std::size_t max_rank_b_>
|
|
101
|
+
void jaccard(tensor_view<in_type_, max_rank_a_> a, tensor_view<in_type_, max_rank_b_> b, std::size_t d,
|
|
102
|
+
result_type_ *r) noexcept {
|
|
103
|
+
jaccard<in_type_, result_type_, allow_simd_>(a.data(), b.data(), d, r);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::jaccard_result_t,
|
|
107
|
+
allow_simd_t allow_simd_ = prefer_simd_k>
|
|
108
|
+
void jaccard(vector_view<in_type_> a, vector_view<in_type_> b, std::size_t d, result_type_ *r) noexcept {
|
|
109
|
+
jaccard<in_type_, result_type_, allow_simd_>(a.data(), b.data(), d, r);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
} // namespace ashvardanian::numkong
|
|
113
|
+
|
|
114
|
+
#endif // NK_SET_HPP
|