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,884 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @brief C++ vector type instantiation tests.
|
|
3
|
+
* @file test/test_tensor.cpp
|
|
4
|
+
* @author Ash Vardanian
|
|
5
|
+
* @date February 6, 2026
|
|
6
|
+
*/
|
|
7
|
+
#include <array>
|
|
8
|
+
#include <cassert>
|
|
9
|
+
#include <complex>
|
|
10
|
+
|
|
11
|
+
#include "test.hpp"
|
|
12
|
+
|
|
13
|
+
#include "numkong/cast.hpp"
|
|
14
|
+
#include "numkong/dot.hpp"
|
|
15
|
+
#include "numkong/spatial.hpp"
|
|
16
|
+
#include "numkong/curved.hpp"
|
|
17
|
+
|
|
18
|
+
#if __has_include(<format>)
|
|
19
|
+
#include <format>
|
|
20
|
+
#if defined(__cpp_lib_format) && __cpp_lib_format >= 202110L
|
|
21
|
+
#define NK_TEST_FORMAT_ 1
|
|
22
|
+
#endif
|
|
23
|
+
#endif
|
|
24
|
+
#ifndef NK_TEST_FORMAT_
|
|
25
|
+
#define NK_TEST_FORMAT_ 0
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
#if NK_TEST_FORMAT_
|
|
29
|
+
void test_format_scalars();
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
// Explicit instantiations for tensor types — forces full compilation of all APIs
|
|
33
|
+
template class nk::tensor<nk::f32_t>;
|
|
34
|
+
template class nk::tensor<nk::f64_t>;
|
|
35
|
+
template class nk::tensor<nk::f16_t>;
|
|
36
|
+
template class nk::tensor<nk::bf16_t>;
|
|
37
|
+
template class nk::tensor<nk::i8_t>;
|
|
38
|
+
|
|
39
|
+
// Views and spans for rank-2 (matrix) and default rank
|
|
40
|
+
template class nk::tensor_view<nk::f32_t, 2>;
|
|
41
|
+
template class nk::tensor_view<nk::f32_t, 8>;
|
|
42
|
+
template class nk::tensor_span<nk::f32_t, 2>;
|
|
43
|
+
template class nk::tensor_span<nk::f32_t, 8>;
|
|
44
|
+
template class nk::tensor_view<nk::bf16_t, 2>;
|
|
45
|
+
template class nk::tensor_span<nk::bf16_t, 2>;
|
|
46
|
+
|
|
47
|
+
template <typename value_type_>
|
|
48
|
+
void test_vector_basics() {
|
|
49
|
+
constexpr std::size_t dims_per_value = nk::dimensions_per_value<value_type_>();
|
|
50
|
+
constexpr std::size_t test_dims = 64 * dims_per_value;
|
|
51
|
+
auto v = make_vector<value_type_>(test_dims);
|
|
52
|
+
assert(v.size() == test_dims);
|
|
53
|
+
assert(v.size_values() == test_dims / dims_per_value);
|
|
54
|
+
std::size_t count = 0;
|
|
55
|
+
for (auto it = v.begin(); it != v.end(); ++it) ++count;
|
|
56
|
+
assert(count == test_dims);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
void test_signed_indexing() {
|
|
60
|
+
auto v = make_vector<float>(100);
|
|
61
|
+
v[50] = 3.14f;
|
|
62
|
+
assert(v[50] == 3.14f && "float operator[] failed");
|
|
63
|
+
v[-1] = 42.0f;
|
|
64
|
+
assert(v[99] == 42.0f && "float signed indexing failed");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
void test_integral_indexing_api() {
|
|
68
|
+
auto v = make_vector<float>(5);
|
|
69
|
+
for (std::size_t i = 0; i < v.size(); ++i) v[i] = static_cast<float>(i + 1);
|
|
70
|
+
|
|
71
|
+
auto view = nk::vector_view<float>(v.values_data(), unsigned(v.size()));
|
|
72
|
+
auto span = nk::vector_span<float>(v.values_data(), unsigned(v.size()));
|
|
73
|
+
auto strided = nk::vector_view<float>(reinterpret_cast<char const *>(v.values_data()), 3u, sizeof(float));
|
|
74
|
+
|
|
75
|
+
assert(v[std::size_t {2}] == 3.0f && "vector unsigned indexing failed");
|
|
76
|
+
assert(view[2u] == 3.0f && "view unsigned indexing failed");
|
|
77
|
+
assert(view[std::ptrdiff_t {-1}] == 5.0f && "view signed indexing failed");
|
|
78
|
+
assert(span[unsigned {3}] == 4.0f && "span unsigned indexing failed");
|
|
79
|
+
assert(strided[2u] == 3.0f && "raw view unsigned stride ctor failed");
|
|
80
|
+
|
|
81
|
+
auto sub = view[nk::range(1u, 4u)];
|
|
82
|
+
assert(sub.size() == 3 && "unsigned range size mismatch");
|
|
83
|
+
assert(sub[0u] == 2.0f && "unsigned range first element mismatch");
|
|
84
|
+
|
|
85
|
+
auto tail = view[nk::range(-3, -1)];
|
|
86
|
+
assert(tail.size() == 2 && "signed range size mismatch");
|
|
87
|
+
assert(tail[0u] == 3.0f && "signed range first element mismatch");
|
|
88
|
+
assert(tail[1u] == 4.0f && "signed range last element mismatch");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
void test_tensor_operator_indexing() {
|
|
92
|
+
auto t = nk::tensor<float>::try_zeros({2, 3});
|
|
93
|
+
assert(!t.empty() && "tensor allocation failed");
|
|
94
|
+
|
|
95
|
+
for (int i = 0; i < 6; ++i) t[i] = static_cast<float>(i + 1);
|
|
96
|
+
|
|
97
|
+
assert(t[0] == 1.0f && "flat tensor lookup failed");
|
|
98
|
+
assert(t[-1] == 6.0f && "negative flat tensor lookup failed");
|
|
99
|
+
assert((t[0, 0] == 1.0f) && "exact tensor lookup failed");
|
|
100
|
+
assert((t[1, -1] == 6.0f) && "negative exact tensor lookup failed");
|
|
101
|
+
|
|
102
|
+
auto whole = t[nk::slice];
|
|
103
|
+
assert(whole.rank() == 2 && "slice identity rank mismatch");
|
|
104
|
+
assert(whole.extent(0) == 2 && whole.extent(1) == 3 && "slice identity extents mismatch");
|
|
105
|
+
|
|
106
|
+
auto row1 = t[1, nk::slice];
|
|
107
|
+
assert(row1.rank() == 1 && "row slice rank mismatch");
|
|
108
|
+
assert(row1.extent(0) == 3 && "row slice extent mismatch");
|
|
109
|
+
assert(row1[0] == 4.0f && row1[-1] == 6.0f && "row slice values mismatch");
|
|
110
|
+
row1[1] = 42.0f;
|
|
111
|
+
assert((t[1, 1] == 42.0f) && "row slice write-through failed");
|
|
112
|
+
|
|
113
|
+
auto cell = t[1, 1, nk::slice];
|
|
114
|
+
assert(cell.rank() == 0 && "scalar slice rank mismatch");
|
|
115
|
+
assert(cell.scalar() == 42.0f && "scalar slice value mismatch");
|
|
116
|
+
cell.scalar_ref() = 24.0f;
|
|
117
|
+
assert((t[1, 1] == 24.0f) && "scalar slice write-through failed");
|
|
118
|
+
|
|
119
|
+
auto const &ct = t;
|
|
120
|
+
auto const last_row = ct[-1, nk::slice];
|
|
121
|
+
assert(last_row.rank() == 1 && "const row slice rank mismatch");
|
|
122
|
+
assert(last_row[0] == 4.0f && "const row slice mismatch");
|
|
123
|
+
|
|
124
|
+
auto cube = nk::tensor<float>::try_zeros({2, 3, 4});
|
|
125
|
+
assert(!cube.empty() && "cube allocation failed");
|
|
126
|
+
for (int i = 0; i < 24; ++i) cube[i] = static_cast<float>(i);
|
|
127
|
+
|
|
128
|
+
auto plane = cube[1, nk::slice];
|
|
129
|
+
assert(plane.rank() == 2 && plane.extent(0) == 3 && plane.extent(1) == 4 && "plane slice mismatch");
|
|
130
|
+
auto line = cube[1, 2, nk::slice];
|
|
131
|
+
assert(line.rank() == 1 && line.extent(0) == 4 && "line slice mismatch");
|
|
132
|
+
assert((line[3] == cube[1, 2, 3]) && "line slice element mismatch");
|
|
133
|
+
auto point = cube[1, 2, 3, nk::slice];
|
|
134
|
+
assert((point.rank() == 0 && point.scalar() == cube[1, 2, 3]) && "point slice mismatch");
|
|
135
|
+
|
|
136
|
+
// all_t slicing: extract a column
|
|
137
|
+
auto second_column = t[nk::all, 1, nk::slice];
|
|
138
|
+
assert(second_column.rank() == 1 && "all_t column rank mismatch");
|
|
139
|
+
assert(second_column.numel() == 2 && "all_t column numel mismatch");
|
|
140
|
+
|
|
141
|
+
// range slicing: extract a sub-range of rows
|
|
142
|
+
auto first_two_planes = cube[nk::range(0, 2), nk::slice];
|
|
143
|
+
assert(first_two_planes.rank() == 3 && "range slice rank mismatch");
|
|
144
|
+
assert(first_two_planes.extent(0) == 2 && "range slice extent mismatch");
|
|
145
|
+
|
|
146
|
+
// combined: range + all_t + slice on a 3D tensor
|
|
147
|
+
auto sub = cube[nk::range(0, 2), nk::all, nk::slice];
|
|
148
|
+
assert(sub.rank() == 3 && sub.extent(0) == 2 && sub.extent(1) == 3 && "range+all slice mismatch");
|
|
149
|
+
|
|
150
|
+
// row() access
|
|
151
|
+
auto row0 = t.row(0);
|
|
152
|
+
assert(row0.rank() == 1 && row0.extent(0) == 3 && "row() rank/extent mismatch");
|
|
153
|
+
auto row0_via_slice = t[0, nk::slice];
|
|
154
|
+
assert(row0[0] == row0_via_slice[0] && "row() should match t[0, slice]");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
void test_packed_tensor_operator_indexing() {
|
|
158
|
+
auto t4 = nk::tensor<nk::u4x2_t>::try_zeros({2, 4});
|
|
159
|
+
assert(!t4.empty() && "packed u4 tensor allocation failed");
|
|
160
|
+
|
|
161
|
+
for (int i = 0; i < 8; ++i) t4[i] = i + 1;
|
|
162
|
+
|
|
163
|
+
assert(int(t4[0]) == 1 && "packed flat lookup failed");
|
|
164
|
+
assert(int(t4[-1]) == 8 && "packed negative flat lookup failed");
|
|
165
|
+
assert((int(t4[0, 3]) == 4) && "packed exact lookup failed");
|
|
166
|
+
assert((int(t4[1, -1]) == 8) && "packed negative exact lookup failed");
|
|
167
|
+
|
|
168
|
+
auto second_row = t4[1, nk::slice];
|
|
169
|
+
assert(second_row.rank() == 1 && second_row.extent(0) == 4 && "packed row slice rank mismatch");
|
|
170
|
+
assert(int(second_row[0]) == 5 && int(second_row[-1]) == 8 && "packed row slice values mismatch");
|
|
171
|
+
second_row[1] = 14;
|
|
172
|
+
assert((int(t4[1, 1]) == 14) && "packed row slice write-through failed");
|
|
173
|
+
|
|
174
|
+
auto t1 = nk::tensor<nk::u1x8_t>::try_zeros({2, 8});
|
|
175
|
+
assert(!t1.empty() && "packed u1 tensor allocation failed");
|
|
176
|
+
t1[0] = true;
|
|
177
|
+
t1[7] = true;
|
|
178
|
+
t1[11] = true;
|
|
179
|
+
t1[-1] = true;
|
|
180
|
+
|
|
181
|
+
assert(bool(t1[0]) && "packed bit flat lookup failed");
|
|
182
|
+
assert((bool(t1[0, 7])) && "packed bit exact lookup failed");
|
|
183
|
+
assert((bool(t1[1, 3])) && "packed bit second-row lookup failed");
|
|
184
|
+
assert(bool(t1[-1]) && "packed bit negative flat lookup failed");
|
|
185
|
+
|
|
186
|
+
auto bits = t1[1, nk::slice];
|
|
187
|
+
assert(bits.rank() == 1 && bits.extent(0) == 8 && "packed bit slice rank mismatch");
|
|
188
|
+
bits[4] = true;
|
|
189
|
+
assert((bool(t1[1, 4])) && "packed bit slice write-through failed");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
void test_move_semantics() {
|
|
193
|
+
auto v1 = make_vector<nk::f32_t>(100);
|
|
194
|
+
v1[50] = nk::f32_t(42.0f);
|
|
195
|
+
|
|
196
|
+
nk::vector<nk::f32_t> v2 = std::move(v1);
|
|
197
|
+
assert(v2.size() == 100 && "move ctor size mismatch");
|
|
198
|
+
assert(v2[50] == nk::f32_t(42.0f) && "move ctor value mismatch");
|
|
199
|
+
assert(v1.size() == 0 && "moved-from vector not empty"); // NOLINT(bugprone-use-after-move)
|
|
200
|
+
|
|
201
|
+
nk::vector<nk::f32_t> v3;
|
|
202
|
+
v3 = std::move(v2);
|
|
203
|
+
assert(v3.size() == 100 && "move assign size mismatch");
|
|
204
|
+
assert(v3[50] == nk::f32_t(42.0f) && "move assign value mismatch");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
void test_swap() {
|
|
208
|
+
auto v1 = make_vector<nk::i8_t>(10);
|
|
209
|
+
auto v2 = make_vector<nk::i8_t>(20);
|
|
210
|
+
v1[0] = nk::i8_t(1);
|
|
211
|
+
v2[0] = nk::i8_t(2);
|
|
212
|
+
|
|
213
|
+
swap(v1, v2);
|
|
214
|
+
assert(v1.size() == 20 && "swap v1 size mismatch");
|
|
215
|
+
assert(v2.size() == 10 && "swap v2 size mismatch");
|
|
216
|
+
assert(v1[0] == nk::i8_t(2) && "swap v1 value mismatch");
|
|
217
|
+
assert(v2[0] == nk::i8_t(1) && "swap v2 value mismatch");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
void test_view_span_rev() {
|
|
221
|
+
auto v = make_vector<float>(5);
|
|
222
|
+
v[0] = 1.0f;
|
|
223
|
+
v[1] = 2.0f;
|
|
224
|
+
v[2] = 3.0f;
|
|
225
|
+
v[3] = 4.0f;
|
|
226
|
+
v[4] = 5.0f;
|
|
227
|
+
|
|
228
|
+
auto view = v.view();
|
|
229
|
+
assert(view.size() == 5 && "view size mismatch");
|
|
230
|
+
assert(view[-1] == 5.0f && "view signed indexing failed");
|
|
231
|
+
|
|
232
|
+
auto span = v.span();
|
|
233
|
+
span[0] = 10.0f;
|
|
234
|
+
assert(v[0] == 10.0f && "span write-through failed");
|
|
235
|
+
|
|
236
|
+
auto rev = view.rev();
|
|
237
|
+
assert(rev[0] == 5.0f && "reversed view first element mismatch");
|
|
238
|
+
assert(rev[4] == 10.0f && "reversed view last element mismatch");
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
void test_range_slicing() {
|
|
242
|
+
auto v = make_vector<float>(5);
|
|
243
|
+
v[0] = 1.0f;
|
|
244
|
+
v[1] = 2.0f;
|
|
245
|
+
v[2] = 3.0f;
|
|
246
|
+
v[3] = 4.0f;
|
|
247
|
+
v[4] = 5.0f;
|
|
248
|
+
|
|
249
|
+
auto sub = v[nk::range(1, 4)];
|
|
250
|
+
assert(sub.size() == 3 && "range slice size mismatch");
|
|
251
|
+
assert(sub[0] == 2.0f && "range slice first element mismatch");
|
|
252
|
+
assert(sub[2] == 4.0f && "range slice last element mismatch");
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
void test_sub_byte_i4x2() {
|
|
256
|
+
auto v = make_vector<nk::i4x2_t>(100);
|
|
257
|
+
assert(v.size() == 100 && "i4x2_t size mismatch");
|
|
258
|
+
assert(v.size_values() == 50 && "i4x2_t size_values mismatch (should be dims/2)");
|
|
259
|
+
|
|
260
|
+
v[0] = 5, v[1] = -3;
|
|
261
|
+
assert(v[0] == 5 && "i4x2_t dim 0 mismatch");
|
|
262
|
+
assert(v[1] == -3 && "i4x2_t dim 1 mismatch");
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
void test_sub_byte_u1x8() {
|
|
266
|
+
auto v = make_vector<nk::u1x8_t>(64);
|
|
267
|
+
assert(v.size() == 64 && "u1x8_t size mismatch");
|
|
268
|
+
assert(v.size_values() == 8 && "u1x8_t size_values mismatch (should be dims/8)");
|
|
269
|
+
|
|
270
|
+
v[0] = true, v[1] = false, v[7] = true;
|
|
271
|
+
assert(v[0] == true && "u1x8_t dim 0 mismatch");
|
|
272
|
+
assert(v[1] == false && "u1x8_t dim 1 mismatch");
|
|
273
|
+
assert(v[7] == true && "u1x8_t dim 7 mismatch");
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
void test_custom_allocator() {
|
|
277
|
+
using custom_alloc_t = nk::aligned_allocator<nk::f32_t, 128>;
|
|
278
|
+
auto v = nk::vector<nk::f32_t, custom_alloc_t>::try_zeros(256);
|
|
279
|
+
assert(v.size() == 256 && "custom allocator size mismatch");
|
|
280
|
+
v[128] = nk::f32_t(99.0f);
|
|
281
|
+
assert(v[128] == nk::f32_t(99.0f) && "custom allocator value mismatch");
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
template <typename value_type_, std::size_t cols_>
|
|
285
|
+
void test_sub_byte_tensor_axis_reduction_case(std::array<int, cols_> const &first_row,
|
|
286
|
+
std::array<int, cols_> const &second_row,
|
|
287
|
+
std::array<int, cols_> const &expected_sums,
|
|
288
|
+
std::array<int, cols_> const &expected_mins,
|
|
289
|
+
std::array<int, cols_> const &expected_maxs) {
|
|
290
|
+
using tensor_t = nk::tensor<value_type_>;
|
|
291
|
+
using sum_t = typename value_type_::reduce_moments_sum_t;
|
|
292
|
+
using minmax_t = typename value_type_::reduce_minmax_value_t;
|
|
293
|
+
|
|
294
|
+
auto t = tensor_t::try_zeros({2, cols_});
|
|
295
|
+
assert(!t.empty() && "tensor allocation failed");
|
|
296
|
+
|
|
297
|
+
auto span = t.span();
|
|
298
|
+
auto row0 = span.slice_leading(0).as_vector();
|
|
299
|
+
auto row1 = span.slice_leading(1).as_vector();
|
|
300
|
+
for (std::size_t i = 0; i < cols_; ++i) {
|
|
301
|
+
row0[i] = first_row[i];
|
|
302
|
+
row1[i] = second_row[i];
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
auto sums = nk::try_sum<value_type_>(t.view(), 0);
|
|
306
|
+
assert(!sums.empty() && "axis-0 sum failed");
|
|
307
|
+
auto sum_view = sums.as_vector_view();
|
|
308
|
+
for (std::size_t i = 0; i < cols_; ++i) assert(sum_view[i] == sum_t(expected_sums[i]) && "axis-0 sum mismatch");
|
|
309
|
+
|
|
310
|
+
auto minmax = nk::try_minmax<value_type_>(t.view(), 0);
|
|
311
|
+
assert(!minmax.min_value.empty() && !minmax.max_value.empty() && "axis-0 minmax failed");
|
|
312
|
+
auto min_view = minmax.min_value.as_vector_view();
|
|
313
|
+
auto max_view = minmax.max_value.as_vector_view();
|
|
314
|
+
for (std::size_t i = 0; i < cols_; ++i) {
|
|
315
|
+
assert(min_view[i] == minmax_t(expected_mins[i]) && "axis-0 min mismatch");
|
|
316
|
+
assert(max_view[i] == minmax_t(expected_maxs[i]) && "axis-0 max mismatch");
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
template <typename tensor_type_, typename expected_type_, std::size_t dims_>
|
|
321
|
+
void assert_flat_tensor_equals(tensor_type_ const &tensor, std::array<expected_type_, dims_> const &expected) {
|
|
322
|
+
auto flat = tensor.view().flatten();
|
|
323
|
+
assert(!flat.empty() && "tensor flatten failed");
|
|
324
|
+
auto vec = flat.as_vector();
|
|
325
|
+
assert(vec.size() == dims_ && "flattened tensor size mismatch");
|
|
326
|
+
using actual_t = typename tensor_type_::value_type;
|
|
327
|
+
for (std::size_t i = 0; i < dims_; ++i)
|
|
328
|
+
assert(vec[i] == actual_t(expected[i]) && "flattened tensor value mismatch");
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
template <typename tensor_type_, typename expected_type_>
|
|
332
|
+
void assert_scalar_tensor_equals(tensor_type_ const &tensor, expected_type_ expected) {
|
|
333
|
+
auto flat = tensor.view().flatten();
|
|
334
|
+
assert(!flat.empty() && "tensor flatten failed");
|
|
335
|
+
auto vec = flat.as_vector();
|
|
336
|
+
assert(vec.size() == 1 && "scalar tensor should flatten to one value");
|
|
337
|
+
using actual_t = typename tensor_type_::value_type;
|
|
338
|
+
assert(vec[0u] == actual_t(expected) && "scalar tensor value mismatch");
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
template <typename value_type_, std::size_t cols_>
|
|
342
|
+
void test_sub_byte_tensor_rank3_axis_case(
|
|
343
|
+
std::array<int, cols_> const &a00, std::array<int, cols_> const &a01, std::array<int, cols_> const &a10,
|
|
344
|
+
std::array<int, cols_> const &a11, std::array<int, cols_ * 2> const &expected_sum_axis0,
|
|
345
|
+
std::array<int, cols_ * 2> const &expected_sum_axis1, std::array<int, 4> const &expected_sum_axis2,
|
|
346
|
+
std::array<int, cols_ * 2> const &expected_min_axis0, std::array<int, cols_ * 2> const &expected_max_axis0,
|
|
347
|
+
std::array<int, cols_ * 2> const &expected_min_axis1, std::array<int, cols_ * 2> const &expected_max_axis1,
|
|
348
|
+
std::array<int, 4> const &expected_min_axis2, std::array<int, 4> const &expected_max_axis2) {
|
|
349
|
+
using tensor_t = nk::tensor<value_type_>;
|
|
350
|
+
using sum_t = typename value_type_::reduce_moments_sum_t;
|
|
351
|
+
using minmax_t = typename value_type_::reduce_minmax_value_t;
|
|
352
|
+
|
|
353
|
+
auto t = tensor_t::try_zeros({2, 2, cols_});
|
|
354
|
+
assert(!t.empty() && "rank-3 tensor allocation failed");
|
|
355
|
+
|
|
356
|
+
auto span = t.span();
|
|
357
|
+
auto row00 = span.slice_leading(0).slice_leading(0).as_vector();
|
|
358
|
+
auto row01 = span.slice_leading(0).slice_leading(1).as_vector();
|
|
359
|
+
auto row10 = span.slice_leading(1).slice_leading(0).as_vector();
|
|
360
|
+
auto row11 = span.slice_leading(1).slice_leading(1).as_vector();
|
|
361
|
+
for (std::size_t i = 0; i < cols_; ++i) {
|
|
362
|
+
row00[i] = a00[i];
|
|
363
|
+
row01[i] = a01[i];
|
|
364
|
+
row10[i] = a10[i];
|
|
365
|
+
row11[i] = a11[i];
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
auto sums0 = nk::try_sum<value_type_>(t.view(), 0);
|
|
369
|
+
auto sums1 = nk::try_sum<value_type_>(t.view(), 1);
|
|
370
|
+
auto sums2 = nk::try_sum<value_type_>(t.view(), 2);
|
|
371
|
+
assert_flat_tensor_equals(sums0, expected_sum_axis0);
|
|
372
|
+
assert_flat_tensor_equals(sums1, expected_sum_axis1);
|
|
373
|
+
assert_flat_tensor_equals(sums2, expected_sum_axis2);
|
|
374
|
+
|
|
375
|
+
auto moments0 = nk::try_moments<value_type_>(t.view(), 0);
|
|
376
|
+
auto moments1 = nk::try_moments<value_type_>(t.view(), 1);
|
|
377
|
+
auto moments2 = nk::try_moments<value_type_>(t.view(), 2);
|
|
378
|
+
assert_flat_tensor_equals(moments0.sum, expected_sum_axis0);
|
|
379
|
+
assert_flat_tensor_equals(moments1.sum, expected_sum_axis1);
|
|
380
|
+
assert_flat_tensor_equals(moments2.sum, expected_sum_axis2);
|
|
381
|
+
|
|
382
|
+
auto minmax0 = nk::try_minmax<value_type_>(t.view(), 0);
|
|
383
|
+
auto minmax1 = nk::try_minmax<value_type_>(t.view(), 1);
|
|
384
|
+
auto minmax2 = nk::try_minmax<value_type_>(t.view(), 2);
|
|
385
|
+
assert_flat_tensor_equals(minmax0.min_value, expected_min_axis0);
|
|
386
|
+
assert_flat_tensor_equals(minmax0.max_value, expected_max_axis0);
|
|
387
|
+
assert_flat_tensor_equals(minmax1.min_value, expected_min_axis1);
|
|
388
|
+
assert_flat_tensor_equals(minmax1.max_value, expected_max_axis1);
|
|
389
|
+
assert_flat_tensor_equals(minmax2.min_value, expected_min_axis2);
|
|
390
|
+
assert_flat_tensor_equals(minmax2.max_value, expected_max_axis2);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
void test_sub_byte_tensor_axis_reductions() {
|
|
394
|
+
test_sub_byte_tensor_axis_reduction_case<nk::i4x2_t, 4>({1, -2, 7, -8}, {-3, 4, -5, 6}, {-2, 2, 2, -2},
|
|
395
|
+
{-3, -2, -5, -8}, {1, 4, 7, 6});
|
|
396
|
+
test_sub_byte_tensor_axis_reduction_case<nk::u4x2_t, 4>({1, 15, 3, 8}, {14, 2, 9, 7}, {15, 17, 12, 15},
|
|
397
|
+
{1, 2, 3, 7}, {14, 15, 9, 8});
|
|
398
|
+
test_sub_byte_tensor_axis_reduction_case<nk::u1x8_t, 8>({1, 0, 1, 1, 0, 0, 1, 0}, {0, 1, 1, 0, 1, 0, 0, 1},
|
|
399
|
+
{1, 1, 2, 1, 1, 0, 1, 1}, {0, 0, 1, 0, 0, 0, 0, 0},
|
|
400
|
+
{1, 1, 1, 1, 1, 0, 1, 1});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
void test_sub_byte_tensor_rank3_axis_reductions() {
|
|
404
|
+
test_sub_byte_tensor_rank3_axis_case<nk::i4x2_t, 4>(
|
|
405
|
+
{1, -2, 3, -4}, {5, -6, 7, -8}, {-1, 2, -3, 4}, {-5, 6, -7, 7}, {0, 0, 0, 0, 0, 0, 0, -1},
|
|
406
|
+
{6, -8, 10, -12, -6, 8, -10, 11}, {-2, -2, 2, 1}, {-1, -2, -3, -4, -5, -6, -7, -8}, {1, 2, 3, 4, 5, 6, 7, 7},
|
|
407
|
+
{1, -6, 3, -8, -5, 2, -7, 4}, {5, -2, 7, -4, -1, 6, -3, 7}, {-4, -8, -3, -7}, {3, 7, 4, 7});
|
|
408
|
+
|
|
409
|
+
test_sub_byte_tensor_rank3_axis_case<nk::u4x2_t, 4>(
|
|
410
|
+
{1, 2, 3, 4}, {5, 6, 7, 8}, {14, 13, 12, 11}, {10, 9, 8, 7}, {15, 15, 15, 15, 15, 15, 15, 15},
|
|
411
|
+
{6, 8, 10, 12, 24, 22, 20, 18}, {10, 26, 50, 34}, {1, 2, 3, 4, 5, 6, 7, 7}, {14, 13, 12, 11, 10, 9, 8, 8},
|
|
412
|
+
{1, 2, 3, 4, 10, 9, 8, 7}, {5, 6, 7, 8, 14, 13, 12, 11}, {1, 5, 11, 7}, {4, 8, 14, 10});
|
|
413
|
+
|
|
414
|
+
test_sub_byte_tensor_rank3_axis_case<nk::u1x8_t, 8>(
|
|
415
|
+
{1, 0, 1, 0, 1, 0, 1, 0}, {0, 1, 0, 1, 0, 1, 0, 1}, {1, 1, 0, 0, 1, 1, 0, 0}, {0, 0, 1, 1, 0, 0, 1, 1},
|
|
416
|
+
{2, 1, 1, 0, 2, 1, 1, 0, 0, 1, 1, 2, 0, 1, 1, 2}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
|
417
|
+
{4, 4, 4, 4}, {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1},
|
|
418
|
+
{1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
419
|
+
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 0, 0, 0}, {1, 1, 1, 1});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
void test_rank1_negative_stride_reductions() {
|
|
423
|
+
using value_t = nk::f32_t;
|
|
424
|
+
using sum_t = typename value_t::reduce_moments_sum_t;
|
|
425
|
+
using minmax_t = typename value_t::reduce_minmax_value_t;
|
|
426
|
+
|
|
427
|
+
value_t data[] = {1.0f, 2.0f, 3.0f, 4.0f};
|
|
428
|
+
nk::shape_storage_<8> shape {};
|
|
429
|
+
shape.rank = 1;
|
|
430
|
+
shape.extents[0] = 4;
|
|
431
|
+
shape.strides[0] = -static_cast<std::ptrdiff_t>(sizeof(value_t));
|
|
432
|
+
nk::tensor_view<value_t> reversed(reinterpret_cast<char const *>(data + 3), shape);
|
|
433
|
+
|
|
434
|
+
auto m = nk::moments(reversed);
|
|
435
|
+
auto mm = nk::minmax(reversed);
|
|
436
|
+
assert(m.sum == sum_t(10.0) && "negative-stride sum mismatch");
|
|
437
|
+
assert(m.sumsq == typename value_t::reduce_moments_sumsq_t(30.0) && "negative-stride sumsq mismatch");
|
|
438
|
+
assert(mm.min_value == minmax_t(1.0f) && "negative-stride min mismatch");
|
|
439
|
+
assert(mm.max_value == minmax_t(4.0f) && "negative-stride max mismatch");
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
void test_rank1_axis_reductions() {
|
|
443
|
+
auto v = nk::tensor<nk::i8_t>::try_zeros({4});
|
|
444
|
+
assert(!v.empty() && "rank-1 tensor allocation failed");
|
|
445
|
+
auto values = v.as_vector_span();
|
|
446
|
+
values[0u] = 4;
|
|
447
|
+
values[1u] = -2;
|
|
448
|
+
values[2u] = 7;
|
|
449
|
+
values[3u] = -5;
|
|
450
|
+
|
|
451
|
+
auto sums = nk::try_sum<nk::i8_t>(v.view(), 0);
|
|
452
|
+
auto moments = nk::try_moments<nk::i8_t>(v.view(), 0);
|
|
453
|
+
auto mins = nk::try_min<nk::i8_t>(v.view(), 0);
|
|
454
|
+
auto maxs = nk::try_max<nk::i8_t>(v.view(), 0);
|
|
455
|
+
auto argmins = nk::try_argmin<nk::i8_t>(v.view(), 0);
|
|
456
|
+
auto argmaxs = nk::try_argmax<nk::i8_t>(v.view(), 0);
|
|
457
|
+
|
|
458
|
+
assert(!sums.empty() && !moments.sum.empty() && "rank-1 axis moments failed");
|
|
459
|
+
assert(!mins.empty() && !maxs.empty() && !argmins.empty() && !argmaxs.empty() && "rank-1 axis minmax failed");
|
|
460
|
+
assert(sums.rank() == 0 && moments.sum.rank() == 0 && "collapsed rank-1 reductions should produce rank-0 tensors");
|
|
461
|
+
assert_scalar_tensor_equals(sums, 4);
|
|
462
|
+
assert_scalar_tensor_equals(moments.sum, 4);
|
|
463
|
+
assert_scalar_tensor_equals(mins, -5);
|
|
464
|
+
assert_scalar_tensor_equals(maxs, 7);
|
|
465
|
+
assert_scalar_tensor_equals(argmins, 3);
|
|
466
|
+
assert_scalar_tensor_equals(argmaxs, 2);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
void test_packed_tensor_fail_closed_views() {
|
|
470
|
+
auto packed = nk::tensor<nk::i4x2_t>::try_zeros({2, 4});
|
|
471
|
+
assert(!packed.empty() && "packed tensor allocation failed");
|
|
472
|
+
assert(packed.view().transpose().empty() && "packed transpose should fail closed");
|
|
473
|
+
assert((!packed[1, nk::slice].empty()) && "packed row slice should remain supported");
|
|
474
|
+
assert((packed[1, 2, nk::slice].empty()) && "packed scalar trailing slice should fail closed");
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
void test_vector_types() {
|
|
478
|
+
std::printf("Testing vector type instantiations...\n");
|
|
479
|
+
|
|
480
|
+
// Template-based type coverage
|
|
481
|
+
test_vector_basics<float>();
|
|
482
|
+
test_vector_basics<double>();
|
|
483
|
+
test_vector_basics<nk::f16_t>();
|
|
484
|
+
test_vector_basics<nk::bf16_t>();
|
|
485
|
+
test_vector_basics<nk::i8_t>();
|
|
486
|
+
test_vector_basics<nk::f32c_t>();
|
|
487
|
+
test_vector_basics<std::complex<double>>();
|
|
488
|
+
test_vector_basics<nk::i4x2_t>();
|
|
489
|
+
test_vector_basics<nk::u1x8_t>();
|
|
490
|
+
std::printf(" vector basics (9 types): OK\n");
|
|
491
|
+
|
|
492
|
+
// Feature tests (non-template, using specific types)
|
|
493
|
+
test_signed_indexing();
|
|
494
|
+
std::printf(" signed indexing: OK\n");
|
|
495
|
+
|
|
496
|
+
test_integral_indexing_api();
|
|
497
|
+
std::printf(" integral indexing api: OK\n");
|
|
498
|
+
|
|
499
|
+
test_move_semantics();
|
|
500
|
+
std::printf(" move semantics: OK\n");
|
|
501
|
+
|
|
502
|
+
test_swap();
|
|
503
|
+
std::printf(" swap: OK\n");
|
|
504
|
+
|
|
505
|
+
test_view_span_rev();
|
|
506
|
+
std::printf(" view/span/rev: OK\n");
|
|
507
|
+
|
|
508
|
+
test_range_slicing();
|
|
509
|
+
std::printf(" range slicing: OK\n");
|
|
510
|
+
|
|
511
|
+
test_sub_byte_i4x2();
|
|
512
|
+
test_sub_byte_u1x8();
|
|
513
|
+
std::printf(" sub-byte i4x2/u1x8: OK\n");
|
|
514
|
+
|
|
515
|
+
test_custom_allocator();
|
|
516
|
+
std::printf(" custom allocator: OK\n");
|
|
517
|
+
|
|
518
|
+
#if NK_TEST_FORMAT_
|
|
519
|
+
test_format_scalars();
|
|
520
|
+
std::printf(" std::format scalars+refs: OK\n");
|
|
521
|
+
#endif
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* @brief Explicit template instantiation test for all tensor-level operations.
|
|
526
|
+
*
|
|
527
|
+
* Forces the compiler to fully instantiate every type × operation combination,
|
|
528
|
+
* catching signature mismatches, missing type traits, and implicit conversion errors
|
|
529
|
+
* that syntax-only checks miss.
|
|
530
|
+
*/
|
|
531
|
+
template <typename value_type_>
|
|
532
|
+
void test_tensor_ops_for_type() {
|
|
533
|
+
using tensor_t = nk::tensor<value_type_>;
|
|
534
|
+
|
|
535
|
+
// Create small test tensors
|
|
536
|
+
auto a = tensor_t::try_zeros({4, 8});
|
|
537
|
+
auto b = tensor_t::try_zeros({4, 8});
|
|
538
|
+
assert(!a.empty() && !b.empty());
|
|
539
|
+
|
|
540
|
+
auto av = a.view();
|
|
541
|
+
auto bv = b.view();
|
|
542
|
+
|
|
543
|
+
// Scalar reductions
|
|
544
|
+
{ [[maybe_unused]] auto r = nk::sum<value_type_>(av); }
|
|
545
|
+
{ [[maybe_unused]] auto r = nk::moments<value_type_>(av); }
|
|
546
|
+
{ [[maybe_unused]] auto r = nk::min<value_type_>(av); }
|
|
547
|
+
{ [[maybe_unused]] auto r = nk::max<value_type_>(av); }
|
|
548
|
+
{ [[maybe_unused]] auto r = nk::argmin<value_type_>(av); }
|
|
549
|
+
{ [[maybe_unused]] auto r = nk::argmax<value_type_>(av); }
|
|
550
|
+
{ [[maybe_unused]] auto r = nk::minmax<value_type_>(av); }
|
|
551
|
+
|
|
552
|
+
// Axis reductions
|
|
553
|
+
{ [[maybe_unused]] auto r = nk::try_sum<value_type_>(av, 0); }
|
|
554
|
+
{ [[maybe_unused]] auto r = nk::try_sum<value_type_>(av, 1, nk::keep_dims_k); }
|
|
555
|
+
{ [[maybe_unused]] auto r = nk::try_moments<value_type_>(av, 1); }
|
|
556
|
+
{ [[maybe_unused]] auto r = nk::try_minmax<value_type_>(av, 0); }
|
|
557
|
+
{ [[maybe_unused]] auto r = nk::try_minmax<value_type_>(av, 1, nk::keep_dims_k); }
|
|
558
|
+
{ [[maybe_unused]] auto r = nk::try_min<value_type_>(av, 0); }
|
|
559
|
+
{ [[maybe_unused]] auto r = nk::try_min<value_type_>(av, 1, nk::keep_dims_k); }
|
|
560
|
+
{ [[maybe_unused]] auto r = nk::try_max<value_type_>(av, 0); }
|
|
561
|
+
{ [[maybe_unused]] auto r = nk::try_max<value_type_>(av, 1, nk::keep_dims_k); }
|
|
562
|
+
{ [[maybe_unused]] auto r = nk::try_argmin<value_type_>(av, 0); }
|
|
563
|
+
{ [[maybe_unused]] auto r = nk::try_argmax<value_type_>(av, 1, nk::keep_dims_k); }
|
|
564
|
+
|
|
565
|
+
// Elementwise binary
|
|
566
|
+
{ [[maybe_unused]] auto r = nk::try_add<value_type_>(av, bv); }
|
|
567
|
+
{ [[maybe_unused]] auto r = nk::try_sub<value_type_>(av, bv); }
|
|
568
|
+
{ [[maybe_unused]] auto r = nk::try_mul<value_type_>(av, bv); }
|
|
569
|
+
|
|
570
|
+
// Elementwise binary with scalar
|
|
571
|
+
using scale_t = typename value_type_::scale_t;
|
|
572
|
+
scale_t scalar {1};
|
|
573
|
+
{ [[maybe_unused]] auto r = nk::try_add<value_type_>(av, scalar); }
|
|
574
|
+
{ [[maybe_unused]] auto r = nk::try_sub<value_type_>(av, scalar); }
|
|
575
|
+
{ [[maybe_unused]] auto r = nk::try_mul<value_type_>(av, scalar); }
|
|
576
|
+
|
|
577
|
+
// Elementwise into
|
|
578
|
+
auto out = tensor_t::try_zeros({4, 8});
|
|
579
|
+
{ [[maybe_unused]] bool ok = nk::add<value_type_>(av, bv, out.span()); }
|
|
580
|
+
{ [[maybe_unused]] bool ok = nk::sub<value_type_>(av, bv, out.span()); }
|
|
581
|
+
{ [[maybe_unused]] bool ok = nk::mul<value_type_>(av, bv, out.span()); }
|
|
582
|
+
{ [[maybe_unused]] bool ok = nk::add<value_type_>(av, scalar, out.span()); }
|
|
583
|
+
{ [[maybe_unused]] bool ok = nk::sub<value_type_>(av, scalar, out.span()); }
|
|
584
|
+
{ [[maybe_unused]] bool ok = nk::mul<value_type_>(av, scalar, out.span()); }
|
|
585
|
+
|
|
586
|
+
// Affine
|
|
587
|
+
scale_t alpha {1}, beta {0};
|
|
588
|
+
{ [[maybe_unused]] auto r = nk::try_scale<value_type_>(av, alpha, beta); }
|
|
589
|
+
{ [[maybe_unused]] auto r = nk::try_blend<value_type_>(av, bv, alpha, beta); }
|
|
590
|
+
{ [[maybe_unused]] auto r = nk::try_fma<value_type_>(av, bv, av, alpha, beta); }
|
|
591
|
+
{ [[maybe_unused]] bool ok = nk::scale<value_type_>(av, alpha, beta, out.span()); }
|
|
592
|
+
{ [[maybe_unused]] bool ok = nk::blend<value_type_>(av, bv, alpha, beta, out.span()); }
|
|
593
|
+
{ [[maybe_unused]] bool ok = nk::fma<value_type_>(av, bv, av, alpha, beta, out.span()); }
|
|
594
|
+
|
|
595
|
+
// try_from 1D
|
|
596
|
+
{
|
|
597
|
+
auto from1d = tensor_t::try_from({value_type_ {}, value_type_ {}, value_type_ {}});
|
|
598
|
+
assert(!from1d.empty() && "try_from 1D failed");
|
|
599
|
+
assert(from1d.rank() == 1 && from1d.numel() == 3 && "try_from 1D shape mismatch");
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// try_from 2D
|
|
603
|
+
{
|
|
604
|
+
auto from2d = tensor_t::try_from({{value_type_ {}, value_type_ {}}, {value_type_ {}, value_type_ {}}});
|
|
605
|
+
assert(!from2d.empty() && "try_from 2D failed");
|
|
606
|
+
assert(from2d.rank() == 2 && from2d.extent(0) == 2 && from2d.extent(1) == 2 && "try_from 2D shape mismatch");
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// row() access
|
|
610
|
+
{
|
|
611
|
+
auto row0 = a.row(0);
|
|
612
|
+
assert(row0.rank() == 1 && row0.extent(0) == 8 && "row() shape mismatch");
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// Convenience view constructor (ptr, rows, cols)
|
|
616
|
+
{
|
|
617
|
+
nk::tensor_view<value_type_> view_from_ptr(a.data(), 4, 8);
|
|
618
|
+
assert(view_from_ptr.rank() == 2 && view_from_ptr.extent(0) == 4 && "convenience view ctor mismatch");
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
template <typename value_type_>
|
|
623
|
+
void test_tensor_trig_for_type() {
|
|
624
|
+
using tensor_t = nk::tensor<value_type_>;
|
|
625
|
+
auto a = tensor_t::try_zeros({4, 8});
|
|
626
|
+
auto out = tensor_t::try_zeros({4, 8});
|
|
627
|
+
auto av = a.view();
|
|
628
|
+
|
|
629
|
+
{ [[maybe_unused]] auto r = nk::try_sin<value_type_>(av); }
|
|
630
|
+
{ [[maybe_unused]] auto r = nk::try_cos<value_type_>(av); }
|
|
631
|
+
{ [[maybe_unused]] auto r = nk::try_atan<value_type_>(av); }
|
|
632
|
+
{ [[maybe_unused]] bool ok = nk::sin<value_type_>(av, out.span()); }
|
|
633
|
+
{ [[maybe_unused]] bool ok = nk::cos<value_type_>(av, out.span()); }
|
|
634
|
+
{ [[maybe_unused]] bool ok = nk::atan<value_type_>(av, out.span()); }
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
template <typename value_type_>
|
|
638
|
+
void test_tensor_symmetric_for_type() {
|
|
639
|
+
using tensor_t = nk::tensor<value_type_>;
|
|
640
|
+
auto a = tensor_t::try_zeros({4, 8});
|
|
641
|
+
auto am = a.as_matrix_view();
|
|
642
|
+
|
|
643
|
+
{ [[maybe_unused]] auto r = nk::try_dots_symmetric<value_type_>(am); }
|
|
644
|
+
{ [[maybe_unused]] auto r = nk::try_angulars_symmetric<value_type_>(am); }
|
|
645
|
+
{ [[maybe_unused]] auto r = nk::try_euclideans_symmetric<value_type_>(am); }
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
template <typename value_type_>
|
|
649
|
+
void test_tensor_packed_for_type() {
|
|
650
|
+
using tensor_t = nk::tensor<value_type_>;
|
|
651
|
+
auto a = tensor_t::try_zeros({4, 8});
|
|
652
|
+
auto b = tensor_t::try_zeros({6, 8});
|
|
653
|
+
|
|
654
|
+
// packed_matrix
|
|
655
|
+
auto bm = b.as_matrix_view();
|
|
656
|
+
auto packed = nk::packed_matrix<value_type_, nk::aligned_allocator<char>>::try_pack(bm);
|
|
657
|
+
auto am = a.as_matrix_view();
|
|
658
|
+
auto result = nk::matrix<typename value_type_::dot_result_t>::try_zeros({4, 6});
|
|
659
|
+
nk::dots_packed<value_type_>(am, packed, result.span());
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
template <typename value_type_>
|
|
663
|
+
void test_tensor_maxsim_for_type() {
|
|
664
|
+
using tensor_t = nk::tensor<value_type_>;
|
|
665
|
+
auto q = tensor_t::try_zeros({3, 16});
|
|
666
|
+
auto d = tensor_t::try_zeros({5, 16});
|
|
667
|
+
|
|
668
|
+
auto qm = q.as_matrix_view();
|
|
669
|
+
auto dm = d.as_matrix_view();
|
|
670
|
+
|
|
671
|
+
auto pq = nk::packed_maxsim<value_type_>::try_pack(qm);
|
|
672
|
+
auto pd = nk::packed_maxsim<value_type_>::try_pack(dm);
|
|
673
|
+
{ [[maybe_unused]] auto r = nk::maxsim(pq, pd); }
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
void test_view_overloads() {
|
|
677
|
+
nk::f32_t a_data[8] {}, b_data[8] {}, c_data[64] {};
|
|
678
|
+
nk::f32_t result {};
|
|
679
|
+
auto a_view = nk::vector_view<nk::f32_t>(a_data, 8u);
|
|
680
|
+
auto b_view = nk::vector_view<nk::f32_t>(b_data, 8u);
|
|
681
|
+
|
|
682
|
+
nk::dot(a_view, b_view, 8, &result);
|
|
683
|
+
nk::euclidean(a_view, b_view, 8, &result);
|
|
684
|
+
nk::sqeuclidean(a_view, b_view, 8, &result);
|
|
685
|
+
nk::angular(a_view, b_view, 8, &result);
|
|
686
|
+
|
|
687
|
+
auto c_view = nk::vector_view<nk::f32_t>(c_data, 64u);
|
|
688
|
+
nk::bilinear(a_view, b_view, c_view, 8, &result);
|
|
689
|
+
nk::mahalanobis(a_view, b_view, c_view, 8, &result);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
void test_custom_allocator_try_fns() {
|
|
693
|
+
using custom_alloc_t = nk::aligned_allocator<nk::f32_t, 128>;
|
|
694
|
+
auto a = nk::tensor<nk::f32_t>::try_zeros({4, 8});
|
|
695
|
+
auto av = a.view();
|
|
696
|
+
|
|
697
|
+
{ auto r = nk::try_scale<nk::f32_t, 8, custom_alloc_t>(av, 1.0, 0.0); }
|
|
698
|
+
{ auto r = nk::try_sin<nk::f32_t, 8, custom_alloc_t>(av); }
|
|
699
|
+
|
|
700
|
+
using sum_alloc_t = nk::aligned_allocator<nk::f64_t, 128>;
|
|
701
|
+
{ auto r = nk::try_sum<nk::f32_t, 8, sum_alloc_t>(av, 0); }
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
template <typename value_type_>
|
|
705
|
+
void test_vector_reductions_for_type() {
|
|
706
|
+
auto v = make_vector<value_type_>(32);
|
|
707
|
+
std::mt19937 generator(42);
|
|
708
|
+
fill_random(generator, v);
|
|
709
|
+
auto view = nk::vector_view<value_type_>(v.values_data(), static_cast<std::size_t>(v.size()));
|
|
710
|
+
|
|
711
|
+
{ [[maybe_unused]] auto r = nk::moments(view); }
|
|
712
|
+
{ [[maybe_unused]] auto r = nk::minmax(view); }
|
|
713
|
+
{ [[maybe_unused]] auto r = nk::sum(view); }
|
|
714
|
+
{ [[maybe_unused]] auto r = nk::min(view); }
|
|
715
|
+
{ [[maybe_unused]] auto r = nk::max(view); }
|
|
716
|
+
{ [[maybe_unused]] auto r = nk::argmin(view); }
|
|
717
|
+
{ [[maybe_unused]] auto r = nk::argmax(view); }
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
void test_vector_reductions_correctness() {
|
|
721
|
+
nk::f32_t data[] = {nk::f32_t(1), nk::f32_t(2), nk::f32_t(3), nk::f32_t(4), nk::f32_t(5)};
|
|
722
|
+
auto view = nk::vector_view<nk::f32_t>(data, std::size_t {5});
|
|
723
|
+
|
|
724
|
+
auto m = nk::moments(view);
|
|
725
|
+
assert(m.sum.raw_ == 15.0 && "vector moments sum");
|
|
726
|
+
assert(m.sumsq.raw_ == 55.0 && "vector moments sumsq");
|
|
727
|
+
|
|
728
|
+
auto mm = nk::minmax(view);
|
|
729
|
+
assert(mm.min_value.raw_ == 1.0f && "vector min");
|
|
730
|
+
assert(mm.max_value.raw_ == 5.0f && "vector max");
|
|
731
|
+
assert(mm.min_index == 0 && "vector argmin");
|
|
732
|
+
assert(mm.max_index == 4 && "vector argmax");
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
template <typename from_type_, typename to_type_>
|
|
736
|
+
void test_cast_for_types() {
|
|
737
|
+
auto src = make_vector<from_type_>(64);
|
|
738
|
+
auto dst = make_vector<to_type_>(64);
|
|
739
|
+
std::mt19937 generator(42);
|
|
740
|
+
fill_random(generator, src);
|
|
741
|
+
|
|
742
|
+
auto src_view = nk::vector_view<from_type_>(src.values_data(), static_cast<std::size_t>(src.size()));
|
|
743
|
+
auto dst_span = nk::vector_span<to_type_>(dst.values_data(), static_cast<std::size_t>(dst.size()));
|
|
744
|
+
|
|
745
|
+
// Pointer-level API
|
|
746
|
+
nk::cast<from_type_, to_type_>(src.values_data(), src.size(), dst.values_data());
|
|
747
|
+
// Vector view/span API
|
|
748
|
+
nk::cast<from_type_, to_type_>(src_view, dst_span);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
#if NK_TEST_FORMAT_
|
|
752
|
+
void test_format_scalars() {
|
|
753
|
+
// Float scalar formatters
|
|
754
|
+
{ [[maybe_unused]] auto s = std::format("{}", nk::f16_t(3.14f)); }
|
|
755
|
+
{ [[maybe_unused]] auto s = std::format("{:#}", nk::f16_t(3.14f)); }
|
|
756
|
+
{ [[maybe_unused]] auto s = std::format("{:.2f}", nk::f16_t(3.14f)); }
|
|
757
|
+
{ [[maybe_unused]] auto s = std::format("{:x}", nk::f16_t(3.14f)); }
|
|
758
|
+
{ [[maybe_unused]] auto s = std::format("{:b}", nk::f16_t(3.14f)); }
|
|
759
|
+
{ [[maybe_unused]] auto s = std::format("{}", nk::bf16_t(2.5f)); }
|
|
760
|
+
{ [[maybe_unused]] auto s = std::format("{}", nk::e4m3_t(1.0f)); }
|
|
761
|
+
{ [[maybe_unused]] auto s = std::format("{}", nk::e5m2_t(1.0f)); }
|
|
762
|
+
{ [[maybe_unused]] auto s = std::format("{}", nk::e2m3_t(1.0f)); }
|
|
763
|
+
{ [[maybe_unused]] auto s = std::format("{}", nk::e3m2_t(1.0f)); }
|
|
764
|
+
|
|
765
|
+
// Packed type formatters
|
|
766
|
+
{ [[maybe_unused]] auto s = std::format("{}", nk::i4x2_t {}); }
|
|
767
|
+
{ [[maybe_unused]] auto s = std::format("{:x}", nk::u4x2_t {}); }
|
|
768
|
+
{ [[maybe_unused]] auto s = std::format("{}", nk::u1x8_t {}); }
|
|
769
|
+
|
|
770
|
+
// Complex type formatters
|
|
771
|
+
{ [[maybe_unused]] auto s = std::format("{}", nk::f16c_t(nk::f16_t(1), nk::f16_t(2))); }
|
|
772
|
+
{ [[maybe_unused]] auto s = std::format("{:#}", nk::bf16c_t(nk::bf16_t(1), nk::bf16_t(2))); }
|
|
773
|
+
|
|
774
|
+
// Sub-byte ref formatters
|
|
775
|
+
nk_i4x2_t packed_i = 0x53;
|
|
776
|
+
nk::sub_byte_ref<nk::i4x2_t> iref(&packed_i, 0);
|
|
777
|
+
assert(std::format("{}", iref) == "3" && "i4 sub_byte_ref default format");
|
|
778
|
+
assert(std::format("{:x}", iref) == "3" && "i4 sub_byte_ref hex format");
|
|
779
|
+
assert(std::format("{:b}", iref) == "0011" && "i4 sub_byte_ref binary format");
|
|
780
|
+
assert(std::format("{:#}", iref) == "3 [0x3]" && "i4 sub_byte_ref annotated format");
|
|
781
|
+
|
|
782
|
+
nk_u4x2_t packed_u = 0xA7;
|
|
783
|
+
nk::sub_byte_ref<nk::u4x2_t> uref(&packed_u, 1);
|
|
784
|
+
assert(std::format("{}", uref) == "10" && "u4 sub_byte_ref default format");
|
|
785
|
+
assert(std::format("{:x}", uref) == "a" && "u4 sub_byte_ref hex format");
|
|
786
|
+
assert(std::format("{:b}", uref) == "1010" && "u4 sub_byte_ref binary format");
|
|
787
|
+
|
|
788
|
+
nk_u1x8_t packed_b = 0x05;
|
|
789
|
+
nk::sub_byte_ref<nk::u1x8_t> bref(&packed_b, 0);
|
|
790
|
+
assert(std::format("{}", bref) == "1" && "u1 sub_byte_ref format");
|
|
791
|
+
}
|
|
792
|
+
#endif // NK_TEST_FORMAT_
|
|
793
|
+
|
|
794
|
+
void test_tensor_ops() {
|
|
795
|
+
std::printf("Testing tensor op instantiations...\n");
|
|
796
|
+
|
|
797
|
+
// Core numeric types: all operations
|
|
798
|
+
test_tensor_ops_for_type<nk::f32_t>();
|
|
799
|
+
test_tensor_ops_for_type<nk::f64_t>();
|
|
800
|
+
test_tensor_ops_for_type<nk::f16_t>();
|
|
801
|
+
test_tensor_ops_for_type<nk::bf16_t>();
|
|
802
|
+
test_tensor_ops_for_type<nk::i8_t>();
|
|
803
|
+
test_tensor_ops_for_type<nk::u8_t>();
|
|
804
|
+
std::printf(" ops (6 types): OK\n");
|
|
805
|
+
|
|
806
|
+
test_sub_byte_tensor_axis_reductions();
|
|
807
|
+
std::printf(" tensor axis sub-byte: OK\n");
|
|
808
|
+
|
|
809
|
+
test_sub_byte_tensor_rank3_axis_reductions();
|
|
810
|
+
std::printf(" tensor axis rank-3 packed: OK\n");
|
|
811
|
+
|
|
812
|
+
test_rank1_negative_stride_reductions();
|
|
813
|
+
std::printf(" tensor negative stride: OK\n");
|
|
814
|
+
|
|
815
|
+
test_rank1_axis_reductions();
|
|
816
|
+
std::printf(" tensor rank-1 axis: OK\n");
|
|
817
|
+
|
|
818
|
+
test_tensor_operator_indexing();
|
|
819
|
+
std::printf(" tensor operator[]: OK\n");
|
|
820
|
+
|
|
821
|
+
test_packed_tensor_operator_indexing();
|
|
822
|
+
std::printf(" tensor packed operator[]: OK\n");
|
|
823
|
+
|
|
824
|
+
test_packed_tensor_fail_closed_views();
|
|
825
|
+
std::printf(" tensor fail-closed views: OK\n");
|
|
826
|
+
|
|
827
|
+
// Trig (float-capable types)
|
|
828
|
+
test_tensor_trig_for_type<nk::f32_t>();
|
|
829
|
+
test_tensor_trig_for_type<nk::f64_t>();
|
|
830
|
+
test_tensor_trig_for_type<nk::f16_t>();
|
|
831
|
+
test_tensor_trig_for_type<nk::bf16_t>();
|
|
832
|
+
std::printf(" trig (4 types): OK\n");
|
|
833
|
+
|
|
834
|
+
// Symmetric distances
|
|
835
|
+
test_tensor_symmetric_for_type<nk::f32_t>();
|
|
836
|
+
test_tensor_symmetric_for_type<nk::f64_t>();
|
|
837
|
+
test_tensor_symmetric_for_type<nk::f16_t>();
|
|
838
|
+
test_tensor_symmetric_for_type<nk::bf16_t>();
|
|
839
|
+
test_tensor_symmetric_for_type<nk::i8_t>();
|
|
840
|
+
std::printf(" symmetric dist (5 types): OK\n");
|
|
841
|
+
|
|
842
|
+
// Packed GEMM
|
|
843
|
+
test_tensor_packed_for_type<nk::f32_t>();
|
|
844
|
+
test_tensor_packed_for_type<nk::f64_t>();
|
|
845
|
+
test_tensor_packed_for_type<nk::f16_t>();
|
|
846
|
+
test_tensor_packed_for_type<nk::bf16_t>();
|
|
847
|
+
test_tensor_packed_for_type<nk::i8_t>();
|
|
848
|
+
std::printf(" packed GEMM (5 types): OK\n");
|
|
849
|
+
|
|
850
|
+
// MaxSim (bf16, f32, f16 only)
|
|
851
|
+
test_tensor_maxsim_for_type<nk::bf16_t>();
|
|
852
|
+
test_tensor_maxsim_for_type<nk::f32_t>();
|
|
853
|
+
test_tensor_maxsim_for_type<nk::f16_t>();
|
|
854
|
+
std::printf(" packed MaxSim (3 types): OK\n");
|
|
855
|
+
|
|
856
|
+
test_view_overloads();
|
|
857
|
+
std::printf(" view overloads: OK\n");
|
|
858
|
+
|
|
859
|
+
test_custom_allocator_try_fns();
|
|
860
|
+
std::printf(" custom allocator try_fns: OK\n");
|
|
861
|
+
|
|
862
|
+
// Vector-level reductions
|
|
863
|
+
test_vector_reductions_for_type<nk::f32_t>();
|
|
864
|
+
test_vector_reductions_for_type<nk::f64_t>();
|
|
865
|
+
test_vector_reductions_for_type<nk::f16_t>();
|
|
866
|
+
test_vector_reductions_for_type<nk::bf16_t>();
|
|
867
|
+
test_vector_reductions_for_type<nk::i8_t>();
|
|
868
|
+
test_vector_reductions_for_type<nk::u8_t>();
|
|
869
|
+
std::printf(" vector reductions (6 types): OK\n");
|
|
870
|
+
|
|
871
|
+
test_vector_reductions_correctness();
|
|
872
|
+
std::printf(" vector reductions correct: OK\n");
|
|
873
|
+
|
|
874
|
+
// Cast wrapper
|
|
875
|
+
test_cast_for_types<nk::f32_t, nk::f16_t>();
|
|
876
|
+
test_cast_for_types<nk::f16_t, nk::f32_t>();
|
|
877
|
+
test_cast_for_types<nk::f32_t, nk::bf16_t>();
|
|
878
|
+
test_cast_for_types<nk::bf16_t, nk::f32_t>();
|
|
879
|
+
test_cast_for_types<nk::f32_t, nk::e4m3_t>();
|
|
880
|
+
test_cast_for_types<nk::e4m3_t, nk::f32_t>();
|
|
881
|
+
test_cast_for_types<nk::i8_t, nk::i32_t>();
|
|
882
|
+
test_cast_for_types<nk::f64_t, nk::f32_t>();
|
|
883
|
+
std::printf(" cast wrapper (8 pairs): OK\n");
|
|
884
|
+
}
|