usearch 2.21.4 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -24
- package/binding.gyp +15 -37
- package/c/CMakeLists.txt +4 -5
- package/c/README.md +7 -7
- package/c/lib.cpp +32 -14
- package/c/test.c +83 -1
- package/c/usearch.h +24 -3
- package/cpp/CMakeLists.txt +4 -0
- package/cpp/README.md +5 -5
- package/cpp/bench.cpp +97 -116
- package/cpp/test.cpp +117 -20
- package/include/usearch/index.hpp +224 -48
- package/include/usearch/index_dense.hpp +105 -40
- package/include/usearch/index_plugins.hpp +1387 -204
- package/javascript/dist/cjs/usearch.d.ts +8 -3
- package/javascript/dist/cjs/usearch.js +12 -4
- package/javascript/dist/esm/usearch.d.ts +8 -3
- package/javascript/dist/esm/usearch.js +12 -4
- package/javascript/lib.cpp +17 -0
- package/javascript/usearch.ts +14 -6
- package/numkong/.clang-tidy +30 -0
- package/{simsimd → numkong}/.cmake-format.py +18 -0
- package/numkong/.editorconfig +12 -0
- package/numkong/.git-blame-ignore-revs +123 -0
- package/numkong/.mailmap +15 -0
- package/numkong/.spi.yml +11 -0
- package/numkong/.swift-format +14 -0
- package/numkong/CITATION.cff +81 -0
- package/numkong/CONTRIBUTING.md +500 -0
- package/numkong/Cargo.toml +54 -0
- package/numkong/MANIFEST.in +8 -0
- package/numkong/Package.swift +84 -0
- package/numkong/README.md +569 -0
- package/numkong/bench/README.md +217 -0
- package/numkong/bench/bench-browser.html +323 -0
- package/numkong/bench/bench.cpp +344 -0
- package/numkong/bench/bench.hpp +816 -0
- package/numkong/bench/bench.js +148 -0
- package/numkong/bench/bench.mjs +616 -0
- package/numkong/bench/bench_attention.cpp +113 -0
- package/numkong/bench/bench_cast.cpp +264 -0
- package/numkong/bench/bench_cross_amx.cpp +62 -0
- package/numkong/bench/bench_cross_arm.cpp +245 -0
- package/numkong/bench/bench_cross_blas.cpp +309 -0
- package/numkong/bench/bench_cross_loongarch.cpp +106 -0
- package/numkong/bench/bench_cross_power.cpp +84 -0
- package/numkong/bench/bench_cross_rvv.cpp +121 -0
- package/numkong/bench/bench_cross_serial.cpp +151 -0
- package/numkong/bench/bench_cross_sme.cpp +163 -0
- package/numkong/bench/bench_cross_wasm.cpp +142 -0
- package/numkong/bench/bench_cross_x86.cpp +455 -0
- package/numkong/bench/bench_curved.cpp +210 -0
- package/numkong/bench/bench_dot.cpp +315 -0
- package/numkong/bench/bench_each.cpp +503 -0
- package/numkong/bench/bench_geospatial.cpp +112 -0
- package/numkong/bench/bench_maxsim.cpp +154 -0
- package/numkong/bench/bench_mesh.cpp +148 -0
- package/numkong/bench/bench_probability.cpp +60 -0
- package/numkong/bench/bench_reduce.cpp +371 -0
- package/numkong/bench/bench_set.cpp +73 -0
- package/numkong/bench/bench_sparse.cpp +198 -0
- package/numkong/bench/bench_spatial.cpp +347 -0
- package/numkong/bench/bench_trigonometry.cpp +137 -0
- package/numkong/bench/swift/Bench.swift +506 -0
- package/numkong/binding.gyp +169 -0
- package/numkong/build.rs +484 -0
- package/numkong/c/dispatch.h +512 -0
- package/numkong/c/dispatch_bf16.c +447 -0
- package/numkong/c/dispatch_bf16c.c +52 -0
- package/numkong/c/dispatch_e2m3.c +296 -0
- package/numkong/c/dispatch_e3m2.c +284 -0
- package/numkong/c/dispatch_e4m3.c +318 -0
- package/numkong/c/dispatch_e5m2.c +316 -0
- package/numkong/c/dispatch_f16.c +452 -0
- package/numkong/c/dispatch_f16c.c +58 -0
- package/numkong/c/dispatch_f32.c +434 -0
- package/numkong/c/dispatch_f32c.c +99 -0
- package/numkong/c/dispatch_f64.c +348 -0
- package/numkong/c/dispatch_f64c.c +98 -0
- package/numkong/c/dispatch_i16.c +96 -0
- package/numkong/c/dispatch_i32.c +89 -0
- package/numkong/c/dispatch_i4.c +153 -0
- package/numkong/c/dispatch_i64.c +86 -0
- package/numkong/c/dispatch_i8.c +348 -0
- package/numkong/c/dispatch_other.c +348 -0
- package/numkong/c/dispatch_u1.c +193 -0
- package/numkong/c/dispatch_u16.c +124 -0
- package/numkong/c/dispatch_u32.c +118 -0
- package/numkong/c/dispatch_u4.c +153 -0
- package/numkong/c/dispatch_u64.c +102 -0
- package/numkong/c/dispatch_u8.c +364 -0
- package/numkong/c/numkong.c +940 -0
- package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
- package/numkong/cmake/nk_isa_probe.cmake +90 -0
- package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_math_lib.cmake +46 -0
- package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
- package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
- package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
- package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
- package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
- package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
- package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
- package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
- package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
- package/numkong/cmake/toolchain-wasi.cmake +77 -0
- package/numkong/cmake/toolchain-wasm.cmake +70 -0
- package/numkong/cmake/toolchain-wasm64.cmake +62 -0
- package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
- package/numkong/include/README.md +643 -0
- package/numkong/include/module.modulemap +129 -0
- package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
- package/numkong/include/numkong/attention/sme.h +2075 -0
- package/numkong/include/numkong/attention.h +49 -0
- package/numkong/include/numkong/capabilities.h +930 -0
- package/numkong/include/numkong/cast/README.md +262 -0
- package/numkong/include/numkong/cast/diamond.h +64 -0
- package/numkong/include/numkong/cast/haswell.h +823 -0
- package/numkong/include/numkong/cast/icelake.h +475 -0
- package/numkong/include/numkong/cast/loongsonasx.h +252 -0
- package/numkong/include/numkong/cast/neon.h +1174 -0
- package/numkong/include/numkong/cast/powervsx.h +449 -0
- package/numkong/include/numkong/cast/rvv.h +970 -0
- package/numkong/include/numkong/cast/sapphire.h +262 -0
- package/numkong/include/numkong/cast/serial.h +2336 -0
- package/numkong/include/numkong/cast/skylake.h +915 -0
- package/numkong/include/numkong/cast/v128relaxed.h +537 -0
- package/numkong/include/numkong/cast.h +254 -0
- package/numkong/include/numkong/cast.hpp +44 -0
- package/numkong/include/numkong/curved/README.md +223 -0
- package/numkong/include/numkong/curved/genoa.h +182 -0
- package/numkong/include/numkong/curved/haswell.h +276 -0
- package/numkong/include/numkong/curved/neon.h +329 -0
- package/numkong/include/numkong/curved/neonbfdot.h +211 -0
- package/numkong/include/numkong/curved/rvv.h +305 -0
- package/numkong/include/numkong/curved/serial.h +207 -0
- package/numkong/include/numkong/curved/skylake.h +457 -0
- package/numkong/include/numkong/curved/smef64.h +530 -0
- package/numkong/include/numkong/curved.h +513 -0
- package/numkong/include/numkong/curved.hpp +144 -0
- package/numkong/include/numkong/dot/README.md +442 -0
- package/numkong/include/numkong/dot/alder.h +563 -0
- package/numkong/include/numkong/dot/diamond.h +158 -0
- package/numkong/include/numkong/dot/genoa.h +289 -0
- package/numkong/include/numkong/dot/haswell.h +1723 -0
- package/numkong/include/numkong/dot/icelake.h +997 -0
- package/numkong/include/numkong/dot/loongsonasx.h +671 -0
- package/numkong/include/numkong/dot/neon.h +869 -0
- package/numkong/include/numkong/dot/neonbfdot.h +243 -0
- package/numkong/include/numkong/dot/neonfhm.h +358 -0
- package/numkong/include/numkong/dot/neonfp8.h +323 -0
- package/numkong/include/numkong/dot/neonsdot.h +622 -0
- package/numkong/include/numkong/dot/powervsx.h +752 -0
- package/numkong/include/numkong/dot/rvv.h +722 -0
- package/numkong/include/numkong/dot/rvvbb.h +72 -0
- package/numkong/include/numkong/dot/rvvbf16.h +123 -0
- package/numkong/include/numkong/dot/rvvhalf.h +129 -0
- package/numkong/include/numkong/dot/sapphire.h +141 -0
- package/numkong/include/numkong/dot/serial.h +874 -0
- package/numkong/include/numkong/dot/sierra.h +405 -0
- package/numkong/include/numkong/dot/skylake.h +1116 -0
- package/numkong/include/numkong/dot/sve.h +420 -0
- package/numkong/include/numkong/dot/svebfdot.h +75 -0
- package/numkong/include/numkong/dot/svehalf.h +168 -0
- package/numkong/include/numkong/dot/svesdot.h +90 -0
- package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
- package/numkong/include/numkong/dot.h +1136 -0
- package/numkong/include/numkong/dot.hpp +94 -0
- package/numkong/include/numkong/dots/README.md +496 -0
- package/numkong/include/numkong/dots/alder.h +117 -0
- package/numkong/include/numkong/dots/diamond.h +86 -0
- package/numkong/include/numkong/dots/genoa.h +100 -0
- package/numkong/include/numkong/dots/graniteamx.h +733 -0
- package/numkong/include/numkong/dots/haswell.h +310 -0
- package/numkong/include/numkong/dots/icelake.h +180 -0
- package/numkong/include/numkong/dots/loongsonasx.h +176 -0
- package/numkong/include/numkong/dots/neon.h +123 -0
- package/numkong/include/numkong/dots/neonbfdot.h +59 -0
- package/numkong/include/numkong/dots/neonfhm.h +96 -0
- package/numkong/include/numkong/dots/neonfp8.h +99 -0
- package/numkong/include/numkong/dots/neonsdot.h +144 -0
- package/numkong/include/numkong/dots/powervsx.h +194 -0
- package/numkong/include/numkong/dots/rvv.h +2593 -0
- package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
- package/numkong/include/numkong/dots/serial.h +2867 -0
- package/numkong/include/numkong/dots/sierra.h +100 -0
- package/numkong/include/numkong/dots/skylake.h +207 -0
- package/numkong/include/numkong/dots/sme.h +5041 -0
- package/numkong/include/numkong/dots/smebi32.h +477 -0
- package/numkong/include/numkong/dots/smef64.h +1328 -0
- package/numkong/include/numkong/dots/smehalf.h +47 -0
- package/numkong/include/numkong/dots/v128relaxed.h +317 -0
- package/numkong/include/numkong/dots.h +3110 -0
- package/numkong/include/numkong/dots.hpp +641 -0
- package/numkong/include/numkong/each/README.md +465 -0
- package/numkong/include/numkong/each/haswell.h +1658 -0
- package/numkong/include/numkong/each/icelake.h +272 -0
- package/numkong/include/numkong/each/neon.h +1138 -0
- package/numkong/include/numkong/each/neonbfdot.h +211 -0
- package/numkong/include/numkong/each/neonhalf.h +318 -0
- package/numkong/include/numkong/each/rvv.h +1121 -0
- package/numkong/include/numkong/each/sapphire.h +343 -0
- package/numkong/include/numkong/each/serial.h +282 -0
- package/numkong/include/numkong/each/skylake.h +1562 -0
- package/numkong/include/numkong/each/v128relaxed.h +562 -0
- package/numkong/include/numkong/each.h +2232 -0
- package/numkong/include/numkong/each.hpp +434 -0
- package/numkong/include/numkong/geospatial/README.md +147 -0
- package/numkong/include/numkong/geospatial/haswell.h +633 -0
- package/numkong/include/numkong/geospatial/neon.h +615 -0
- package/numkong/include/numkong/geospatial/rvv.h +701 -0
- package/numkong/include/numkong/geospatial/serial.h +309 -0
- package/numkong/include/numkong/geospatial/skylake.h +613 -0
- package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
- package/numkong/include/numkong/geospatial.h +453 -0
- package/numkong/include/numkong/geospatial.hpp +235 -0
- package/numkong/include/numkong/matrix.hpp +336 -0
- package/numkong/include/numkong/maxsim/README.md +187 -0
- package/numkong/include/numkong/maxsim/alder.h +511 -0
- package/numkong/include/numkong/maxsim/genoa.h +115 -0
- package/numkong/include/numkong/maxsim/haswell.h +553 -0
- package/numkong/include/numkong/maxsim/icelake.h +480 -0
- package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
- package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
- package/numkong/include/numkong/maxsim/serial.h +490 -0
- package/numkong/include/numkong/maxsim/sme.h +993 -0
- package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
- package/numkong/include/numkong/maxsim.h +571 -0
- package/numkong/include/numkong/maxsim.hpp +133 -0
- package/numkong/include/numkong/mesh/README.md +219 -0
- package/numkong/include/numkong/mesh/haswell.h +2013 -0
- package/numkong/include/numkong/mesh/neon.h +1821 -0
- package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
- package/numkong/include/numkong/mesh/rvv.h +936 -0
- package/numkong/include/numkong/mesh/serial.h +721 -0
- package/numkong/include/numkong/mesh/skylake.h +2344 -0
- package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
- package/numkong/include/numkong/mesh.h +666 -0
- package/numkong/include/numkong/mesh.hpp +701 -0
- package/numkong/include/numkong/numkong.h +78 -0
- package/numkong/include/numkong/numkong.hpp +58 -0
- package/numkong/include/numkong/probability/README.md +177 -0
- package/numkong/include/numkong/probability/haswell.h +267 -0
- package/numkong/include/numkong/probability/neon.h +255 -0
- package/numkong/include/numkong/probability/rvv.h +414 -0
- package/numkong/include/numkong/probability/serial.h +181 -0
- package/numkong/include/numkong/probability/skylake.h +324 -0
- package/numkong/include/numkong/probability.h +380 -0
- package/numkong/include/numkong/probability.hpp +120 -0
- package/numkong/include/numkong/random.h +50 -0
- package/numkong/include/numkong/random.hpp +285 -0
- package/numkong/include/numkong/reduce/README.md +552 -0
- package/numkong/include/numkong/reduce/alder.h +636 -0
- package/numkong/include/numkong/reduce/genoa.h +201 -0
- package/numkong/include/numkong/reduce/haswell.h +3785 -0
- package/numkong/include/numkong/reduce/icelake.h +549 -0
- package/numkong/include/numkong/reduce/neon.h +3980 -0
- package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
- package/numkong/include/numkong/reduce/neonfhm.h +293 -0
- package/numkong/include/numkong/reduce/neonsdot.h +357 -0
- package/numkong/include/numkong/reduce/rvv.h +3533 -0
- package/numkong/include/numkong/reduce/serial.h +753 -0
- package/numkong/include/numkong/reduce/sierra.h +338 -0
- package/numkong/include/numkong/reduce/skylake.h +3794 -0
- package/numkong/include/numkong/reduce/sve.h +52 -0
- package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
- package/numkong/include/numkong/reduce.h +1582 -0
- package/numkong/include/numkong/reduce.hpp +778 -0
- package/numkong/include/numkong/scalar/README.md +89 -0
- package/numkong/include/numkong/scalar/haswell.h +122 -0
- package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
- package/numkong/include/numkong/scalar/neon.h +122 -0
- package/numkong/include/numkong/scalar/neonhalf.h +70 -0
- package/numkong/include/numkong/scalar/powervsx.h +96 -0
- package/numkong/include/numkong/scalar/rvv.h +211 -0
- package/numkong/include/numkong/scalar/sapphire.h +74 -0
- package/numkong/include/numkong/scalar/serial.h +332 -0
- package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
- package/numkong/include/numkong/scalar.h +696 -0
- package/numkong/include/numkong/set/README.md +179 -0
- package/numkong/include/numkong/set/haswell.h +334 -0
- package/numkong/include/numkong/set/icelake.h +485 -0
- package/numkong/include/numkong/set/loongsonasx.h +181 -0
- package/numkong/include/numkong/set/neon.h +363 -0
- package/numkong/include/numkong/set/powervsx.h +326 -0
- package/numkong/include/numkong/set/rvv.h +226 -0
- package/numkong/include/numkong/set/rvvbb.h +117 -0
- package/numkong/include/numkong/set/serial.h +174 -0
- package/numkong/include/numkong/set/sve.h +187 -0
- package/numkong/include/numkong/set/v128relaxed.h +240 -0
- package/numkong/include/numkong/set.h +471 -0
- package/numkong/include/numkong/set.hpp +114 -0
- package/numkong/include/numkong/sets/README.md +149 -0
- package/numkong/include/numkong/sets/haswell.h +63 -0
- package/numkong/include/numkong/sets/icelake.h +66 -0
- package/numkong/include/numkong/sets/loongsonasx.h +52 -0
- package/numkong/include/numkong/sets/neon.h +61 -0
- package/numkong/include/numkong/sets/powervsx.h +65 -0
- package/numkong/include/numkong/sets/serial.h +43 -0
- package/numkong/include/numkong/sets/smebi32.h +1135 -0
- package/numkong/include/numkong/sets/v128relaxed.h +58 -0
- package/numkong/include/numkong/sets.h +382 -0
- package/numkong/include/numkong/sparse/README.md +156 -0
- package/numkong/include/numkong/sparse/icelake.h +463 -0
- package/numkong/include/numkong/sparse/neon.h +288 -0
- package/numkong/include/numkong/sparse/serial.h +117 -0
- package/numkong/include/numkong/sparse/sve2.h +504 -0
- package/numkong/include/numkong/sparse/turin.h +322 -0
- package/numkong/include/numkong/sparse.h +363 -0
- package/numkong/include/numkong/sparse.hpp +113 -0
- package/numkong/include/numkong/spatial/README.md +439 -0
- package/numkong/include/numkong/spatial/alder.h +604 -0
- package/numkong/include/numkong/spatial/diamond.h +240 -0
- package/numkong/include/numkong/spatial/genoa.h +222 -0
- package/numkong/include/numkong/spatial/haswell.h +979 -0
- package/numkong/include/numkong/spatial/icelake.h +1067 -0
- package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
- package/numkong/include/numkong/spatial/neon.h +846 -0
- package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
- package/numkong/include/numkong/spatial/neonfp8.h +258 -0
- package/numkong/include/numkong/spatial/neonsdot.h +429 -0
- package/numkong/include/numkong/spatial/powervsx.h +738 -0
- package/numkong/include/numkong/spatial/rvv.h +991 -0
- package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
- package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
- package/numkong/include/numkong/spatial/serial.h +347 -0
- package/numkong/include/numkong/spatial/sierra.h +516 -0
- package/numkong/include/numkong/spatial/skylake.h +605 -0
- package/numkong/include/numkong/spatial/sve.h +246 -0
- package/numkong/include/numkong/spatial/svebfdot.h +125 -0
- package/numkong/include/numkong/spatial/svehalf.h +136 -0
- package/numkong/include/numkong/spatial/svesdot.h +143 -0
- package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
- package/numkong/include/numkong/spatial.h +1681 -0
- package/numkong/include/numkong/spatial.hpp +183 -0
- package/numkong/include/numkong/spatials/README.md +580 -0
- package/numkong/include/numkong/spatials/alder.h +94 -0
- package/numkong/include/numkong/spatials/diamond.h +82 -0
- package/numkong/include/numkong/spatials/genoa.h +94 -0
- package/numkong/include/numkong/spatials/graniteamx.h +173 -0
- package/numkong/include/numkong/spatials/haswell.h +219 -0
- package/numkong/include/numkong/spatials/icelake.h +113 -0
- package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
- package/numkong/include/numkong/spatials/neon.h +109 -0
- package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
- package/numkong/include/numkong/spatials/neonfhm.h +92 -0
- package/numkong/include/numkong/spatials/neonfp8.h +111 -0
- package/numkong/include/numkong/spatials/neonsdot.h +143 -0
- package/numkong/include/numkong/spatials/powervsx.h +153 -0
- package/numkong/include/numkong/spatials/rvv.h +1976 -0
- package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
- package/numkong/include/numkong/spatials/serial.h +248 -0
- package/numkong/include/numkong/spatials/sierra.h +96 -0
- package/numkong/include/numkong/spatials/skylake.h +184 -0
- package/numkong/include/numkong/spatials/sme.h +1927 -0
- package/numkong/include/numkong/spatials/smef64.h +483 -0
- package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
- package/numkong/include/numkong/spatials.h +3374 -0
- package/numkong/include/numkong/spatials.hpp +509 -0
- package/numkong/include/numkong/tensor.hpp +1981 -0
- package/numkong/include/numkong/trigonometry/README.md +184 -0
- package/numkong/include/numkong/trigonometry/haswell.h +653 -0
- package/numkong/include/numkong/trigonometry/neon.h +638 -0
- package/numkong/include/numkong/trigonometry/rvv.h +700 -0
- package/numkong/include/numkong/trigonometry/serial.h +703 -0
- package/numkong/include/numkong/trigonometry/skylake.h +725 -0
- package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
- package/numkong/include/numkong/trigonometry.h +467 -0
- package/numkong/include/numkong/trigonometry.hpp +166 -0
- package/numkong/include/numkong/types.h +1695 -0
- package/numkong/include/numkong/types.hpp +6027 -0
- package/numkong/include/numkong/vector.hpp +766 -0
- package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
- package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
- package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
- package/numkong/javascript/README.md +254 -0
- package/numkong/javascript/node-gyp-build.d.ts +4 -0
- package/numkong/javascript/numkong-browser.ts +40 -0
- package/numkong/javascript/numkong-wasm.ts +750 -0
- package/numkong/javascript/numkong.c +712 -0
- package/numkong/javascript/numkong.ts +613 -0
- package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
- package/numkong/javascript/tsconfig-cjs.json +13 -0
- package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
- package/numkong/javascript/types.ts +784 -0
- package/numkong/numkong.gypi +104 -0
- package/numkong/package.json +108 -0
- package/numkong/probes/arm_neon.c +8 -0
- package/numkong/probes/arm_neon_bfdot.c +9 -0
- package/numkong/probes/arm_neon_fhm.c +9 -0
- package/numkong/probes/arm_neon_half.c +8 -0
- package/numkong/probes/arm_neon_sdot.c +9 -0
- package/numkong/probes/arm_neonfp8.c +9 -0
- package/numkong/probes/arm_sme.c +16 -0
- package/numkong/probes/arm_sme2.c +16 -0
- package/numkong/probes/arm_sme2p1.c +16 -0
- package/numkong/probes/arm_sme_bf16.c +16 -0
- package/numkong/probes/arm_sme_bi32.c +16 -0
- package/numkong/probes/arm_sme_f64.c +16 -0
- package/numkong/probes/arm_sme_fa64.c +14 -0
- package/numkong/probes/arm_sme_half.c +16 -0
- package/numkong/probes/arm_sme_lut2.c +15 -0
- package/numkong/probes/arm_sve.c +18 -0
- package/numkong/probes/arm_sve2.c +20 -0
- package/numkong/probes/arm_sve2p1.c +18 -0
- package/numkong/probes/arm_sve_bfdot.c +20 -0
- package/numkong/probes/arm_sve_half.c +18 -0
- package/numkong/probes/arm_sve_sdot.c +21 -0
- package/numkong/probes/loongarch_lasx.c +12 -0
- package/numkong/probes/power_vsx.c +12 -0
- package/numkong/probes/probe.js +127 -0
- package/numkong/probes/riscv_rvv.c +14 -0
- package/numkong/probes/riscv_rvv_bb.c +15 -0
- package/numkong/probes/riscv_rvv_bf16.c +17 -0
- package/numkong/probes/riscv_rvv_half.c +14 -0
- package/numkong/probes/wasm_v128relaxed.c +11 -0
- package/numkong/probes/x86_alder.c +17 -0
- package/numkong/probes/x86_diamond.c +17 -0
- package/numkong/probes/x86_genoa.c +17 -0
- package/numkong/probes/x86_graniteamx.c +19 -0
- package/numkong/probes/x86_haswell.c +11 -0
- package/numkong/probes/x86_icelake.c +17 -0
- package/numkong/probes/x86_sapphire.c +16 -0
- package/numkong/probes/x86_sapphireamx.c +18 -0
- package/numkong/probes/x86_sierra.c +17 -0
- package/numkong/probes/x86_skylake.c +15 -0
- package/numkong/probes/x86_turin.c +17 -0
- package/numkong/rust/README.md +698 -0
- package/numkong/rust/capabilities.rs +96 -0
- package/numkong/rust/cast.rs +314 -0
- package/numkong/rust/curved.rs +391 -0
- package/numkong/rust/each.rs +2721 -0
- package/numkong/rust/geospatial.rs +343 -0
- package/numkong/rust/matrix.rs +5424 -0
- package/numkong/rust/maxsim.rs +540 -0
- package/numkong/rust/mesh.rs +837 -0
- package/numkong/rust/numkong.rs +409 -0
- package/numkong/rust/probability.rs +272 -0
- package/numkong/rust/reduce.rs +1249 -0
- package/numkong/rust/set.rs +194 -0
- package/numkong/rust/sparse.rs +513 -0
- package/numkong/rust/spatial.rs +1815 -0
- package/numkong/rust/tensor.rs +7565 -0
- package/numkong/rust/types.rs +3666 -0
- package/numkong/rust/vector.rs +1899 -0
- package/numkong/rustfmt.toml +2 -0
- package/numkong/swift/Matrix.swift +1388 -0
- package/numkong/swift/MaxSim.swift +151 -0
- package/numkong/swift/NumKong.swift +283 -0
- package/numkong/swift/Numerics.swift +329 -0
- package/numkong/swift/README.md +433 -0
- package/numkong/swift/Scalar.swift +741 -0
- package/numkong/swift/Tensor.swift +209 -0
- package/numkong/test/README.md +315 -0
- package/numkong/test/playwright.config.ts +16 -0
- package/numkong/test/swift/Test.swift +534 -0
- package/numkong/test/test-browser-bundle-runner.mjs +36 -0
- package/numkong/test/test-browser-bundle.html +188 -0
- package/numkong/test/test-browser-runner.mjs +43 -0
- package/numkong/test/test-browser.html +305 -0
- package/numkong/test/test-dtypes.mjs +453 -0
- package/numkong/test/test-wasm.mjs +267 -0
- package/numkong/test/test.cpp +442 -0
- package/numkong/test/test.hpp +580 -0
- package/numkong/test/test.mjs +363 -0
- package/numkong/test/test_base.py +1041 -0
- package/numkong/test/test_cast.cpp +242 -0
- package/numkong/test/test_cross.hpp +551 -0
- package/numkong/test/test_cross.py +467 -0
- package/numkong/test/test_cross_amx.cpp +50 -0
- package/numkong/test/test_cross_arm.cpp +225 -0
- package/numkong/test/test_cross_blas.cpp +354 -0
- package/numkong/test/test_cross_loongarch.cpp +90 -0
- package/numkong/test/test_cross_power.cpp +73 -0
- package/numkong/test/test_cross_rvv.cpp +109 -0
- package/numkong/test/test_cross_serial.cpp +181 -0
- package/numkong/test/test_cross_sme.cpp +148 -0
- package/numkong/test/test_cross_wasm.cpp +141 -0
- package/numkong/test/test_cross_x86.cpp +442 -0
- package/numkong/test/test_curved.cpp +182 -0
- package/numkong/test/test_curved.py +207 -0
- package/numkong/test/test_dot.cpp +353 -0
- package/numkong/test/test_dot.py +296 -0
- package/numkong/test/test_each.cpp +437 -0
- package/numkong/test/test_each.py +756 -0
- package/numkong/test/test_geospatial.cpp +155 -0
- package/numkong/test/test_geospatial.py +241 -0
- package/numkong/test/test_maxsim.cpp +138 -0
- package/numkong/test/test_maxsim.py +209 -0
- package/numkong/test/test_mesh.cpp +203 -0
- package/numkong/test/test_mesh.py +394 -0
- package/numkong/test/test_probability.cpp +136 -0
- package/numkong/test/test_probability.py +166 -0
- package/numkong/test/test_reduce.cpp +563 -0
- package/numkong/test/test_reduce.py +781 -0
- package/numkong/test/test_set.cpp +151 -0
- package/numkong/test/test_set.py +120 -0
- package/numkong/test/test_similarities.py +579 -0
- package/numkong/test/test_sparse.cpp +121 -0
- package/numkong/test/test_sparse.py +118 -0
- package/numkong/test/test_spatial.cpp +518 -0
- package/numkong/test/test_spatial.py +269 -0
- package/numkong/test/test_tensor.cpp +884 -0
- package/numkong/test/test_tensor.py +1417 -0
- package/numkong/test/test_trigonometry.cpp +156 -0
- package/numkong/test/test_trigonometry.py +180 -0
- package/package.json +7 -8
- package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
- package/prebuilds/linux-arm64/usearch.node +0 -0
- package/prebuilds/linux-x64/usearch.node +0 -0
- package/fp16/CMakeLists.txt +0 -176
- package/fp16/LICENSE +0 -11
- package/fp16/README.md +0 -20
- package/fp16/bench/alt-element.cc +0 -89
- package/fp16/bench/from-alt-array.cc +0 -175
- package/fp16/bench/from-ieee-array.cc +0 -399
- package/fp16/bench/ieee-element.cc +0 -272
- package/fp16/bench/to-alt-array.cc +0 -91
- package/fp16/bench/to-ieee-array.cc +0 -303
- package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
- package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
- package/fp16/cmake/DownloadPSimd.cmake +0 -15
- package/fp16/configure.py +0 -65
- package/fp16/confu.yaml +0 -8
- package/fp16/include/fp16/__init__.py +0 -0
- package/fp16/include/fp16/avx.py +0 -50
- package/fp16/include/fp16/avx2.py +0 -53
- package/fp16/include/fp16/bitcasts.h +0 -92
- package/fp16/include/fp16/fp16.h +0 -451
- package/fp16/include/fp16/psimd.h +0 -131
- package/fp16/include/fp16.h +0 -11
- package/fp16/jni/Android.mk +0 -6
- package/fp16/jni/Application.mk +0 -4
- package/fp16/test/alt-from-fp32-value.cc +0 -498
- package/fp16/test/alt-to-fp32-bits.cc +0 -263
- package/fp16/test/alt-to-fp32-psimd.cc +0 -145
- package/fp16/test/alt-to-fp32-value.cc +0 -348
- package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
- package/fp16/test/bitcasts.cc +0 -56
- package/fp16/test/ieee-from-fp32-value.cc +0 -523
- package/fp16/test/ieee-to-fp32-bits.cc +0 -333
- package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
- package/fp16/test/ieee-to-fp32-value.cc +0 -420
- package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
- package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
- package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
- package/fp16/test/peachpy/stubs.py +0 -38
- package/fp16/test/tables.cc +0 -530
- package/fp16/test/tables.h +0 -13
- package/fp16/third-party/THHalf.h +0 -92
- package/fp16/third-party/eigen-half.h +0 -170
- package/fp16/third-party/float16-compressor.h +0 -80
- package/fp16/third-party/half.hpp +0 -2916
- package/fp16/third-party/npy-halffloat.h +0 -328
- package/simsimd/.git-blame-ignore-revs +0 -2
- package/simsimd/CONTRIBUTING.md +0 -321
- package/simsimd/Cargo.toml +0 -49
- package/simsimd/MANIFEST.in +0 -4
- package/simsimd/Package.swift +0 -28
- package/simsimd/README.md +0 -1493
- package/simsimd/binding.gyp +0 -35
- package/simsimd/build.rs +0 -70
- package/simsimd/c/lib.c +0 -374
- package/simsimd/include/module.modulemap +0 -4
- package/simsimd/include/simsimd/binary.h +0 -486
- package/simsimd/include/simsimd/curved.h +0 -1541
- package/simsimd/include/simsimd/dot.h +0 -1853
- package/simsimd/include/simsimd/elementwise.h +0 -2465
- package/simsimd/include/simsimd/geospatial.h +0 -43
- package/simsimd/include/simsimd/mesh.h +0 -69
- package/simsimd/include/simsimd/probability.h +0 -606
- package/simsimd/include/simsimd/simsimd.h +0 -2567
- package/simsimd/include/simsimd/sparse.h +0 -1384
- package/simsimd/include/simsimd/spatial.h +0 -2335
- package/simsimd/include/simsimd/types.h +0 -666
- package/simsimd/javascript/fallback.ts +0 -233
- package/simsimd/javascript/lib.c +0 -125
- package/simsimd/javascript/node-gyp-build.d.ts +0 -1
- package/simsimd/javascript/simsimd.ts +0 -179
- package/simsimd/javascript/tsconfig-cjs.json +0 -8
- package/simsimd/package-lock.json +0 -1761
- package/simsimd/package.json +0 -61
- package/simsimd/rust/lib.rs +0 -1821
- package/simsimd/scripts/bench.cxx +0 -1170
- package/simsimd/scripts/bench.ipynb +0 -187
- package/simsimd/scripts/bench.js +0 -127
- package/simsimd/scripts/bench.rs +0 -876
- package/simsimd/scripts/bench_vectors.py +0 -734
- package/simsimd/scripts/bench_vectors_live.py +0 -213
- package/simsimd/scripts/test.c +0 -187
- package/simsimd/scripts/test.mjs +0 -220
- package/simsimd/scripts/test.py +0 -1505
- package/simsimd/swift/SimSIMD.swift +0 -149
- package/simsimd/swift/Test.swift +0 -128
- /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
- /package/{simsimd → numkong}/LICENSE +0 -0
- /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
- /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @brief Comprehensive dtype tests for NumKong JavaScript API
|
|
4
|
+
* @file test/test-dtypes.mjs
|
|
5
|
+
* @author Claude & Ash Vardanian
|
|
6
|
+
* @date February 3, 2026
|
|
7
|
+
*
|
|
8
|
+
* Tests all functions with all compatible data types across multiple dimensions.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { test } from "node:test";
|
|
12
|
+
import assert from "node:assert";
|
|
13
|
+
import build from "node-gyp-build";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
18
|
+
const __dirname = path.dirname(__filename);
|
|
19
|
+
const builddir = path.join(__dirname, ".."); // Root directory where binding.gyp is
|
|
20
|
+
|
|
21
|
+
// Load NumKong native addon
|
|
22
|
+
const numkong = build(builddir);
|
|
23
|
+
|
|
24
|
+
// Dtypes that require explicit dtype argument (not auto-detected from TypedArray type)
|
|
25
|
+
const CUSTOM_DTYPES = new Set(["f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2"]);
|
|
26
|
+
|
|
27
|
+
// Configuration from environment variables
|
|
28
|
+
const CONFIG = {
|
|
29
|
+
seed: parseInt(process.env.NK_SEED || "42"),
|
|
30
|
+
dimensions: process.env.NK_DENSE_DIMENSIONS
|
|
31
|
+
? process.env.NK_DENSE_DIMENSIONS.split(",").map(Number)
|
|
32
|
+
: [3, 16, 128, 1536],
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Test matrix configuration
|
|
36
|
+
const TEST_MATRIX = {
|
|
37
|
+
functions: {
|
|
38
|
+
dot: ["f64", "f32", "f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2", "i8", "u8"],
|
|
39
|
+
inner: ["f64", "f32", "f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2", "i8", "u8"],
|
|
40
|
+
angular: ["f64", "f32", "f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2", "i8"],
|
|
41
|
+
sqeuclidean: ["f64", "f32", "f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2", "i8", "u8"],
|
|
42
|
+
euclidean: ["f64", "f32", "f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2", "i8", "u8"],
|
|
43
|
+
hamming: ["u1"],
|
|
44
|
+
jaccard: ["u1"],
|
|
45
|
+
kullbackleibler: ["f64", "f32", "f16", "bf16"],
|
|
46
|
+
jensenshannon: ["f64", "f32", "f16", "bf16"],
|
|
47
|
+
},
|
|
48
|
+
dimensions: CONFIG.dimensions,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Sub-byte packing ratio — mirrors nk_dimensions_per_value in types.h.
|
|
52
|
+
// A single storage byte holds this many logical elements for the given dtype.
|
|
53
|
+
function dimensionsPerValue(dtype) {
|
|
54
|
+
switch (dtype) {
|
|
55
|
+
case "u1":
|
|
56
|
+
return 8;
|
|
57
|
+
case "i4":
|
|
58
|
+
case "u4":
|
|
59
|
+
return 2;
|
|
60
|
+
default:
|
|
61
|
+
return 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Round a logical dimension up to the nearest packed-value boundary.
|
|
66
|
+
function alignDimension(dimension, dtype) {
|
|
67
|
+
const dpv = dimensionsPerValue(dtype);
|
|
68
|
+
return Math.ceil(dimension / dpv) * dpv;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Simple PRNG for reproducible tests
|
|
72
|
+
class Random {
|
|
73
|
+
constructor(seed) {
|
|
74
|
+
this.seed = seed;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
next() {
|
|
78
|
+
this.seed = (this.seed * 1103515245 + 12345) & 0x7fffffff;
|
|
79
|
+
return this.seed / 0x7fffffff;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @brief Generate test data for a specific dtype.
|
|
85
|
+
* For custom dtypes (f16, bf16, e4m3, e5m2, e2m3, e3m2), generates f32 source data
|
|
86
|
+
* and uses numkong.cast() to convert to the proper backing array type.
|
|
87
|
+
*/
|
|
88
|
+
function generateTestData(dtype, length, seed = CONFIG.seed) {
|
|
89
|
+
const rng = new Random(seed);
|
|
90
|
+
|
|
91
|
+
switch (dtype) {
|
|
92
|
+
case "f64":
|
|
93
|
+
return Float64Array.from({ length }, () => rng.next() * 2 - 1);
|
|
94
|
+
|
|
95
|
+
case "f32":
|
|
96
|
+
return Float32Array.from({ length }, () => rng.next() * 2 - 1);
|
|
97
|
+
|
|
98
|
+
case "f16":
|
|
99
|
+
case "bf16": {
|
|
100
|
+
// 16-bit types: backing array is Uint16Array, convert from f32 via cast()
|
|
101
|
+
const src = Float32Array.from({ length }, () => rng.next() * 2 - 1);
|
|
102
|
+
const dst = new Uint16Array(length);
|
|
103
|
+
numkong.cast(src, "f32", dst, dtype);
|
|
104
|
+
return dst;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
case "e4m3":
|
|
108
|
+
case "e5m2":
|
|
109
|
+
case "e2m3":
|
|
110
|
+
case "e3m2": {
|
|
111
|
+
// 8-bit types: backing array is Uint8Array, convert from f32 via cast()
|
|
112
|
+
const src = Float32Array.from({ length }, () => rng.next() * 2 - 1);
|
|
113
|
+
const dst = new Uint8Array(length);
|
|
114
|
+
numkong.cast(src, "f32", dst, dtype);
|
|
115
|
+
return dst;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
case "i8":
|
|
119
|
+
return Int8Array.from({ length }, () => Math.floor(rng.next() * 256) - 128);
|
|
120
|
+
|
|
121
|
+
case "u8":
|
|
122
|
+
return Uint8Array.from({ length }, () => Math.floor(rng.next() * 256));
|
|
123
|
+
|
|
124
|
+
case "u1": {
|
|
125
|
+
const byteLength = Math.ceil(length / 8);
|
|
126
|
+
return Uint8Array.from({ length: byteLength }, () => Math.floor(rng.next() * 256));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
default:
|
|
130
|
+
throw new Error(`Unknown dtype: ${dtype}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @brief Generate positive probability-like data suitable for KLD/JSD.
|
|
136
|
+
* Values are in [0.1, 1.0] range to avoid precision issues with narrow types.
|
|
137
|
+
*/
|
|
138
|
+
function generateProbabilityData(dtype, length, seed = CONFIG.seed) {
|
|
139
|
+
const rng = new Random(seed);
|
|
140
|
+
|
|
141
|
+
switch (dtype) {
|
|
142
|
+
case "f64":
|
|
143
|
+
return Float64Array.from({ length }, () => rng.next() * 0.9 + 0.1);
|
|
144
|
+
|
|
145
|
+
case "f32":
|
|
146
|
+
return Float32Array.from({ length }, () => rng.next() * 0.9 + 0.1);
|
|
147
|
+
|
|
148
|
+
case "f16":
|
|
149
|
+
case "bf16": {
|
|
150
|
+
const src = Float32Array.from({ length }, () => rng.next() * 0.9 + 0.1);
|
|
151
|
+
const dst = new Uint16Array(length);
|
|
152
|
+
numkong.cast(src, "f32", dst, dtype);
|
|
153
|
+
return dst;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
default:
|
|
157
|
+
throw new Error(`Unsupported dtype for probability data: ${dtype}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @brief Validate result is a valid number
|
|
163
|
+
*/
|
|
164
|
+
function validateResult(result, funcName, dtype) {
|
|
165
|
+
assert.strictEqual(typeof result, "number", `${funcName}(${dtype}) should return a number`);
|
|
166
|
+
assert.ok(!isNaN(result), `${funcName}(${dtype}) should not return NaN`);
|
|
167
|
+
assert.ok(isFinite(result), `${funcName}(${dtype}) should return finite value`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* @brief Expected result ranges for different functions
|
|
172
|
+
*/
|
|
173
|
+
function validateResultRange(result, funcName, dtype, dimension) {
|
|
174
|
+
switch (funcName) {
|
|
175
|
+
case "dot":
|
|
176
|
+
case "inner":
|
|
177
|
+
// Dot product range depends on dtype: i8 values go up to 127, u8 up to 255
|
|
178
|
+
const maxElement = dtype === "i8" ? 128 : dtype === "u8" ? 255 : 10;
|
|
179
|
+
assert.ok(
|
|
180
|
+
Math.abs(result) < dimension * maxElement * maxElement,
|
|
181
|
+
`${funcName}(${dtype}) result ${result} out of expected range`,
|
|
182
|
+
);
|
|
183
|
+
break;
|
|
184
|
+
|
|
185
|
+
case "angular":
|
|
186
|
+
// Cosine distance is in [0, π]
|
|
187
|
+
assert.ok(result >= 0 && result <= Math.PI, `${funcName}(${dtype}) should be in [0, π], got ${result}`);
|
|
188
|
+
break;
|
|
189
|
+
|
|
190
|
+
case "sqeuclidean":
|
|
191
|
+
// Squared Euclidean distance is non-negative
|
|
192
|
+
assert.ok(result >= 0, `${funcName}(${dtype}) should be non-negative, got ${result}`);
|
|
193
|
+
break;
|
|
194
|
+
|
|
195
|
+
case "euclidean":
|
|
196
|
+
// Euclidean distance is non-negative
|
|
197
|
+
assert.ok(result >= 0, `${funcName}(${dtype}) should be non-negative, got ${result}`);
|
|
198
|
+
break;
|
|
199
|
+
|
|
200
|
+
case "hamming":
|
|
201
|
+
// Hamming distance for binary vectors (in bits)
|
|
202
|
+
assert.ok(
|
|
203
|
+
result >= 0 && result <= dimension,
|
|
204
|
+
`${funcName}(${dtype}) should be in [0, ${dimension}], got ${result}`,
|
|
205
|
+
);
|
|
206
|
+
break;
|
|
207
|
+
|
|
208
|
+
case "jaccard":
|
|
209
|
+
// Jaccard distance is in [0, 1]
|
|
210
|
+
assert.ok(result >= 0 && result <= 1, `${funcName}(${dtype}) should be in [0, 1], got ${result}`);
|
|
211
|
+
break;
|
|
212
|
+
|
|
213
|
+
case "kullbackleibler":
|
|
214
|
+
// KL divergence is non-negative
|
|
215
|
+
assert.ok(result >= 0, `${funcName}(${dtype}) should be non-negative, got ${result}`);
|
|
216
|
+
break;
|
|
217
|
+
|
|
218
|
+
case "jensenshannon":
|
|
219
|
+
// JS divergence is in [0, 1] for probability distributions
|
|
220
|
+
// For arbitrary vectors, just check non-negative and finite
|
|
221
|
+
assert.ok(result >= 0, `${funcName}(${dtype}) should be non-negative, got ${result}`);
|
|
222
|
+
assert.ok(isFinite(result), `${funcName}(${dtype}) should be finite, got ${result}`);
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @brief Call a distance function, passing dtype as 3rd arg for custom types.
|
|
229
|
+
*/
|
|
230
|
+
function callFunc(funcName, a, b, dtype) {
|
|
231
|
+
return CUSTOM_DTYPES.has(dtype) ? numkong[funcName](a, b, dtype) : numkong[funcName](a, b);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* @brief Test determinism - same inputs should produce same output
|
|
236
|
+
*/
|
|
237
|
+
function testDeterminism(funcName, dtype, dimension) {
|
|
238
|
+
const a = genData(funcName, dtype, dimension, 123);
|
|
239
|
+
const b = genData(funcName, dtype, dimension, 456);
|
|
240
|
+
|
|
241
|
+
const result1 = callFunc(funcName, a, b, dtype);
|
|
242
|
+
const result2 = callFunc(funcName, a, b, dtype);
|
|
243
|
+
|
|
244
|
+
assert.strictEqual(result1, result2, `${funcName}(${dtype}, dim=${dimension}) should be deterministic`);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* @brief Test commutativity for symmetric functions
|
|
249
|
+
*/
|
|
250
|
+
function testCommutativity(funcName, dtype, dimension) {
|
|
251
|
+
// Only symmetric functions
|
|
252
|
+
const symmetric = ["dot", "inner", "sqeuclidean", "euclidean", "hamming", "jaccard"];
|
|
253
|
+
if (!symmetric.includes(funcName)) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const a = genData(funcName, dtype, dimension, 789);
|
|
258
|
+
const b = genData(funcName, dtype, dimension, 101);
|
|
259
|
+
|
|
260
|
+
const result1 = callFunc(funcName, a, b, dtype);
|
|
261
|
+
const result2 = callFunc(funcName, b, a, dtype);
|
|
262
|
+
|
|
263
|
+
// For floating point, allow small tolerance
|
|
264
|
+
const tolerance = dtype.startsWith("f") ? 1e-6 : 0;
|
|
265
|
+
assert.ok(
|
|
266
|
+
Math.abs(result1 - result2) <= tolerance,
|
|
267
|
+
`${funcName}(${dtype}) should be commutative: ${result1} vs ${result2}`,
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* @brief Test self-distance properties
|
|
273
|
+
*/
|
|
274
|
+
function testSelfDistance(funcName, dtype, dimension) {
|
|
275
|
+
const a = genData(funcName, dtype, dimension, 111);
|
|
276
|
+
|
|
277
|
+
const result = callFunc(funcName, a, a, dtype);
|
|
278
|
+
|
|
279
|
+
switch (funcName) {
|
|
280
|
+
case "dot":
|
|
281
|
+
case "inner":
|
|
282
|
+
// dot(a, a) should be positive (sum of squares)
|
|
283
|
+
assert.ok(result >= 0, `${funcName}(${dtype}) with same vector should be non-negative`);
|
|
284
|
+
break;
|
|
285
|
+
|
|
286
|
+
case "angular":
|
|
287
|
+
// angular(a, a) should be ~0 (same direction)
|
|
288
|
+
assert.ok(result < 0.01, `${funcName}(${dtype}) with same vector should be near 0, got ${result}`);
|
|
289
|
+
break;
|
|
290
|
+
|
|
291
|
+
case "sqeuclidean":
|
|
292
|
+
case "euclidean":
|
|
293
|
+
// distance(a, a) should be 0
|
|
294
|
+
assert.ok(result < 0.01, `${funcName}(${dtype}) with same vector should be near 0, got ${result}`);
|
|
295
|
+
break;
|
|
296
|
+
|
|
297
|
+
case "hamming":
|
|
298
|
+
// hamming(a, a) should be ~0 (allow floating point tolerance)
|
|
299
|
+
assert.ok(result < 1e-9, `${funcName}(${dtype}) with same vector should be near 0, got ${result}`);
|
|
300
|
+
break;
|
|
301
|
+
|
|
302
|
+
case "jaccard":
|
|
303
|
+
// jaccard(a, a) should be 0
|
|
304
|
+
assert.ok(result < 0.01, `${funcName}(${dtype}) with same vector should be near 0, got ${result}`);
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// #region Main test suite
|
|
310
|
+
|
|
311
|
+
console.log("╔════════════════════════════════════════════════════════════════╗");
|
|
312
|
+
console.log("║ NumKong Comprehensive DType Test Suite ║");
|
|
313
|
+
console.log("╚════════════════════════════════════════════════════════════════╝\n");
|
|
314
|
+
|
|
315
|
+
let totalTests = 0;
|
|
316
|
+
for (const [funcName, dtypes] of Object.entries(TEST_MATRIX.functions)) {
|
|
317
|
+
totalTests += dtypes.length * TEST_MATRIX.dimensions.length * 4; // 4 tests per combo
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
console.log(`Seed: ${CONFIG.seed}, Dimensions: ${CONFIG.dimensions.join(", ")}`);
|
|
321
|
+
console.log(`Running ${totalTests} tests across:`);
|
|
322
|
+
console.log(` - ${Object.keys(TEST_MATRIX.functions).length} functions`);
|
|
323
|
+
console.log(` - ${new Set(Object.values(TEST_MATRIX.functions).flat()).size} data types`);
|
|
324
|
+
console.log(` - ${TEST_MATRIX.dimensions.length} dimension sizes\n`);
|
|
325
|
+
|
|
326
|
+
// Known issues to skip:
|
|
327
|
+
// - sqeuclidean/euclidean e4m3 < 16 dims: SIMD overread crash in kernel
|
|
328
|
+
// - kld/jsd f16: precision loss causes NaN/Infinity with test data
|
|
329
|
+
function isKnownBroken(funcName, dtype, dimension) {
|
|
330
|
+
if ((funcName === "sqeuclidean" || funcName === "euclidean") && dtype === "e4m3" && dimension < 16) return true;
|
|
331
|
+
if ((funcName === "kullbackleibler" || funcName === "jensenshannon") && dtype === "f16") return true;
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Divergence functions need probability-like (positive) test data
|
|
336
|
+
const DIVERGENCE_FUNCS = new Set(["kullbackleibler", "jensenshannon"]);
|
|
337
|
+
function genData(funcName, dtype, length, seed) {
|
|
338
|
+
return DIVERGENCE_FUNCS.has(funcName)
|
|
339
|
+
? generateProbabilityData(dtype, length, seed)
|
|
340
|
+
: generateTestData(dtype, length, seed);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Generate tests for each function, dtype, and dimension
|
|
344
|
+
for (const [funcName, supportedDtypes] of Object.entries(TEST_MATRIX.functions)) {
|
|
345
|
+
for (const dtype of supportedDtypes) {
|
|
346
|
+
for (const rawDimension of TEST_MATRIX.dimensions) {
|
|
347
|
+
const dimension = alignDimension(rawDimension, dtype);
|
|
348
|
+
if (isKnownBroken(funcName, dtype, dimension)) continue;
|
|
349
|
+
|
|
350
|
+
// Test 1: Basic functionality
|
|
351
|
+
test(`${funcName}(${dtype}, dim=${dimension}): basic`, () => {
|
|
352
|
+
const a = genData(funcName, dtype, dimension, CONFIG.seed);
|
|
353
|
+
const b = genData(funcName, dtype, dimension, CONFIG.seed + 1);
|
|
354
|
+
|
|
355
|
+
const result = callFunc(funcName, a, b, dtype);
|
|
356
|
+
|
|
357
|
+
validateResult(result, funcName, dtype);
|
|
358
|
+
validateResultRange(result, funcName, dtype, dimension);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
// Test 2: Determinism
|
|
362
|
+
test(`${funcName}(${dtype}, dim=${dimension}): determinism`, () => {
|
|
363
|
+
testDeterminism(funcName, dtype, dimension);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// Test 3: Commutativity (for symmetric functions)
|
|
367
|
+
test(`${funcName}(${dtype}, dim=${dimension}): commutativity`, () => {
|
|
368
|
+
testCommutativity(funcName, dtype, dimension);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// Test 4: Self-distance properties
|
|
372
|
+
test(`${funcName}(${dtype}, dim=${dimension}): self-distance`, () => {
|
|
373
|
+
testSelfDistance(funcName, dtype, dimension);
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Additional edge case tests
|
|
380
|
+
test("Edge case: empty vectors", () => {
|
|
381
|
+
const a = new Float32Array(0);
|
|
382
|
+
const b = new Float32Array(0);
|
|
383
|
+
|
|
384
|
+
// Should handle gracefully (may throw or return 0)
|
|
385
|
+
try {
|
|
386
|
+
const result = numkong.dot(a, b);
|
|
387
|
+
assert.ok(typeof result === "number");
|
|
388
|
+
} catch (e) {
|
|
389
|
+
// Acceptable to throw on empty vectors
|
|
390
|
+
assert.ok(e.message.includes("length") || e.message.includes("empty"));
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
test("Edge case: mismatched lengths", () => {
|
|
395
|
+
const a = new Float32Array([1, 2, 3]);
|
|
396
|
+
const b = new Float32Array([4, 5]);
|
|
397
|
+
|
|
398
|
+
// Should throw error mentioning length or dimensionality
|
|
399
|
+
assert.throws(() => {
|
|
400
|
+
numkong.dot(a, b);
|
|
401
|
+
}, /(length|dimensionality)/i);
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
test("Edge case: zero vectors", () => {
|
|
405
|
+
const a = new Float32Array(100).fill(0);
|
|
406
|
+
const b = new Float32Array(100).fill(0);
|
|
407
|
+
|
|
408
|
+
const dot_result = numkong.dot(a, b);
|
|
409
|
+
assert.strictEqual(dot_result, 0);
|
|
410
|
+
|
|
411
|
+
const sqeuc_result = numkong.sqeuclidean(a, b);
|
|
412
|
+
assert.strictEqual(sqeuc_result, 0);
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
test("Conversion functions: f16 round-trip", () => {
|
|
416
|
+
const original = 3.14159;
|
|
417
|
+
const f16_bits = numkong.castF32ToF16(original);
|
|
418
|
+
const decoded = numkong.castF16ToF32(f16_bits);
|
|
419
|
+
|
|
420
|
+
// f16 has limited precision, allow some error
|
|
421
|
+
assert.ok(Math.abs(original - decoded) < 0.01);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
test("Conversion functions: bf16 round-trip", () => {
|
|
425
|
+
const original = 2.71828;
|
|
426
|
+
const bf16_bits = numkong.castF32ToBF16(original);
|
|
427
|
+
const decoded = numkong.castBF16ToF32(bf16_bits);
|
|
428
|
+
|
|
429
|
+
// bf16 has limited precision
|
|
430
|
+
assert.ok(Math.abs(original - decoded) < 0.01);
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
test("Conversion functions: e4m3 round-trip", () => {
|
|
434
|
+
const original = 1.5;
|
|
435
|
+
const e4m3_bits = numkong.castF32ToE4M3(original);
|
|
436
|
+
const decoded = numkong.castE4M3ToF32(e4m3_bits);
|
|
437
|
+
|
|
438
|
+
// FP8 E4M3 has very limited precision
|
|
439
|
+
assert.ok(Math.abs(original - decoded) < 0.1);
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
test("Conversion functions: e5m2 round-trip", () => {
|
|
443
|
+
const original = 1.5;
|
|
444
|
+
const e5m2_bits = numkong.castF32ToE5M2(original);
|
|
445
|
+
const decoded = numkong.castE5M2ToF32(e5m2_bits);
|
|
446
|
+
|
|
447
|
+
// FP8 E5M2 has very limited precision
|
|
448
|
+
assert.ok(Math.abs(original - decoded) < 0.1);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// #endregion Main test suite
|
|
452
|
+
|
|
453
|
+
console.log("\n✅ All tests defined. Running with Node.js test runner...\n");
|