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,638 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @brief SIMD-accelerated Trigonometric Functions for NEON.
|
|
3
|
+
* @file include/numkong/trigonometry/neon.h
|
|
4
|
+
* @author Ash Vardanian
|
|
5
|
+
* @date December 28, 2025
|
|
6
|
+
*
|
|
7
|
+
* @sa include/numkong/trigonometry.h
|
|
8
|
+
* @see https://sleef.org
|
|
9
|
+
*
|
|
10
|
+
* @section trigonometry_neon_instructions ARM NEON Instructions
|
|
11
|
+
*
|
|
12
|
+
* Intrinsic Instruction A76 M5
|
|
13
|
+
* vfmaq_f32 FMLA (V.4S, V.4S, V.4S) 4cy @ 2p 3cy @ 4p
|
|
14
|
+
* vfmsq_f32 FMLS (V.4S, V.4S, V.4S) 4cy @ 2p 3cy @ 4p
|
|
15
|
+
* vmulq_f32 FMUL (V.4S, V.4S, V.4S) 3cy @ 2p 3cy @ 4p
|
|
16
|
+
* vaddq_f32 FADD (V.4S, V.4S, V.4S) 2cy @ 2p 2cy @ 4p
|
|
17
|
+
* vsubq_f32 FSUB (V.4S, V.4S, V.4S) 2cy @ 2p 2cy @ 4p
|
|
18
|
+
* vcvtnq_s32_f32 FCVTNS (V.4S, V.4S) 3cy @ 2p 3cy @ 4p
|
|
19
|
+
* vcvtq_f32_s32 SCVTF (V.4S, V.4S) 3cy @ 2p 3cy @ 4p
|
|
20
|
+
* vbslq_f32 BSL (V.16B, V.16B, V.16B) 1cy @ 2p 2cy @ 4p
|
|
21
|
+
* vrecpeq_f32 FRECPE (V.4S, V.4S) 2cy @ 2p 3cy @ 1p
|
|
22
|
+
* vrecpsq_f32 FRECPS (V.4S, V.4S, V.4S) 4cy @ 2p 3cy @ 2p
|
|
23
|
+
* vfmaq_f64 FMLA (V.2D, V.2D, V.2D) 4cy @ 2p 3cy @ 4p
|
|
24
|
+
* vdivq_f64 FDIV (V.2D, V.2D, V.2D) 12cy @ 1p 7cy @ 1p
|
|
25
|
+
*
|
|
26
|
+
* Polynomial approximations for sin/cos/atan are FMA-dominated. On 4-pipe cores (Apple M4+,
|
|
27
|
+
* Graviton3+, Oryon), FMA throughput is 4/cy with 4cy latency.
|
|
28
|
+
*
|
|
29
|
+
* Division (vdivq_f64) remains slow at 0.5/cy on all cores. For f32, use fast reciprocal
|
|
30
|
+
* (vrecpeq_f32 + Newton-Raphson) instead when precision allows.
|
|
31
|
+
*/
|
|
32
|
+
#ifndef NK_TRIGONOMETRY_NEON_H
|
|
33
|
+
#define NK_TRIGONOMETRY_NEON_H
|
|
34
|
+
|
|
35
|
+
#if NK_TARGET_ARM64_
|
|
36
|
+
#if NK_TARGET_NEON
|
|
37
|
+
|
|
38
|
+
#include "numkong/types.h"
|
|
39
|
+
#include "numkong/reduce/neon.h"
|
|
40
|
+
|
|
41
|
+
#if defined(__cplusplus)
|
|
42
|
+
extern "C" {
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
#if defined(__clang__)
|
|
46
|
+
#pragma clang attribute push(__attribute__((target("arch=armv8-a+simd"))), apply_to = function)
|
|
47
|
+
#elif defined(__GNUC__)
|
|
48
|
+
#pragma GCC push_options
|
|
49
|
+
#pragma GCC target("arch=armv8-a+simd")
|
|
50
|
+
#endif
|
|
51
|
+
|
|
52
|
+
/* NEON trigonometry kernels (4-way f32, 2-way f64)
|
|
53
|
+
* These implement polynomial approximations using 128-bit NEON vectors.
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
NK_INTERNAL float32x4_t nk_sin_f32x4_neon_(float32x4_t const angles_radians) {
|
|
57
|
+
// Cody-Waite constants for argument reduction
|
|
58
|
+
float32x4_t const pi_high_f32x4 = vdupq_n_f32(3.1415927f);
|
|
59
|
+
float32x4_t const pi_low_f32x4 = vdupq_n_f32(-8.742278e-8f);
|
|
60
|
+
float32x4_t const pi_reciprocal_f32x4 = vdupq_n_f32(0.31830988618379067154f);
|
|
61
|
+
// Degree-9 minimax coefficients
|
|
62
|
+
float32x4_t const coeff_9_f32x4 = vdupq_n_f32(+2.7557319224e-6f);
|
|
63
|
+
float32x4_t const coeff_7_f32x4 = vdupq_n_f32(-1.9841269841e-4f);
|
|
64
|
+
float32x4_t const coeff_5_f32x4 = vdupq_n_f32(+8.3333293855e-3f);
|
|
65
|
+
float32x4_t const coeff_3_f32x4 = vdupq_n_f32(-1.6666666641e-1f);
|
|
66
|
+
|
|
67
|
+
// Compute (multiples_of_pi_i32x4) = round(angle / π) using vcvtnq which rounds to nearest
|
|
68
|
+
float32x4_t quotients_f32x4 = vmulq_f32(angles_radians, pi_reciprocal_f32x4);
|
|
69
|
+
int32x4_t multiples_of_pi_i32x4 = vcvtnq_s32_f32(quotients_f32x4);
|
|
70
|
+
float32x4_t rounded_quotients_f32x4 = vcvtq_f32_s32(multiples_of_pi_i32x4);
|
|
71
|
+
|
|
72
|
+
// Cody-Waite range reduction
|
|
73
|
+
float32x4_t angles_f32x4 = vfmsq_f32(angles_radians, rounded_quotients_f32x4, pi_high_f32x4);
|
|
74
|
+
angles_f32x4 = vfmsq_f32(angles_f32x4, rounded_quotients_f32x4, pi_low_f32x4);
|
|
75
|
+
float32x4_t const angles_squared_f32x4 = vmulq_f32(angles_f32x4, angles_f32x4);
|
|
76
|
+
float32x4_t const angles_cubed_f32x4 = vmulq_f32(angles_f32x4, angles_squared_f32x4);
|
|
77
|
+
|
|
78
|
+
// Degree-9 polynomial via Horner's method
|
|
79
|
+
float32x4_t polynomials_f32x4 = coeff_9_f32x4;
|
|
80
|
+
polynomials_f32x4 = vfmaq_f32(coeff_7_f32x4, polynomials_f32x4, angles_squared_f32x4);
|
|
81
|
+
polynomials_f32x4 = vfmaq_f32(coeff_5_f32x4, polynomials_f32x4, angles_squared_f32x4);
|
|
82
|
+
polynomials_f32x4 = vfmaq_f32(coeff_3_f32x4, polynomials_f32x4, angles_squared_f32x4);
|
|
83
|
+
float32x4_t results_f32x4 = vfmaq_f32(angles_f32x4, angles_cubed_f32x4, polynomials_f32x4);
|
|
84
|
+
|
|
85
|
+
// If multiples_of_pi_i32x4 is odd, flip the sign
|
|
86
|
+
int32x4_t parity_i32x4 = vandq_s32(multiples_of_pi_i32x4, vdupq_n_s32(1));
|
|
87
|
+
uint32x4_t odd_mask_u32x4 = vceqq_s32(parity_i32x4, vdupq_n_s32(1));
|
|
88
|
+
float32x4_t negated_f32x4 = vnegq_f32(results_f32x4);
|
|
89
|
+
results_f32x4 = vbslq_f32(odd_mask_u32x4, negated_f32x4, results_f32x4);
|
|
90
|
+
return results_f32x4;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
NK_INTERNAL float32x4_t nk_cos_f32x4_neon_(float32x4_t const angles_radians) {
|
|
94
|
+
// Cody-Waite constants for argument reduction
|
|
95
|
+
float32x4_t const pi_high_f32x4 = vdupq_n_f32(3.1415927f);
|
|
96
|
+
float32x4_t const pi_low_f32x4 = vdupq_n_f32(-8.742278e-8f);
|
|
97
|
+
float32x4_t const pi_half_f32x4 = vdupq_n_f32(1.57079632679489661923f);
|
|
98
|
+
float32x4_t const pi_reciprocal_f32x4 = vdupq_n_f32(0.31830988618379067154f);
|
|
99
|
+
// Degree-9 minimax coefficients
|
|
100
|
+
float32x4_t const coeff_9_f32x4 = vdupq_n_f32(+2.7557319224e-6f);
|
|
101
|
+
float32x4_t const coeff_7_f32x4 = vdupq_n_f32(-1.9841269841e-4f);
|
|
102
|
+
float32x4_t const coeff_5_f32x4 = vdupq_n_f32(+8.3333293855e-3f);
|
|
103
|
+
float32x4_t const coeff_3_f32x4 = vdupq_n_f32(-1.6666666641e-1f);
|
|
104
|
+
|
|
105
|
+
// Compute round((angle / π) - 0.5)
|
|
106
|
+
float32x4_t quotients_f32x4 = vsubq_f32(vmulq_f32(angles_radians, pi_reciprocal_f32x4), vdupq_n_f32(0.5f));
|
|
107
|
+
int32x4_t multiples_of_pi_i32x4 = vcvtnq_s32_f32(quotients_f32x4);
|
|
108
|
+
float32x4_t rounded_quotients_f32x4 = vcvtq_f32_s32(multiples_of_pi_i32x4);
|
|
109
|
+
|
|
110
|
+
// Cody-Waite range reduction: angle = (angle - pi/2) - rounded * (pi_high + pi_low)
|
|
111
|
+
float32x4_t shifted_f32x4 = vsubq_f32(angles_radians, pi_half_f32x4);
|
|
112
|
+
float32x4_t angles_f32x4 = vfmsq_f32(shifted_f32x4, rounded_quotients_f32x4, pi_high_f32x4);
|
|
113
|
+
angles_f32x4 = vfmsq_f32(angles_f32x4, rounded_quotients_f32x4, pi_low_f32x4);
|
|
114
|
+
float32x4_t const angles_squared_f32x4 = vmulq_f32(angles_f32x4, angles_f32x4);
|
|
115
|
+
float32x4_t const angles_cubed_f32x4 = vmulq_f32(angles_f32x4, angles_squared_f32x4);
|
|
116
|
+
|
|
117
|
+
// Degree-9 polynomial via Horner's method
|
|
118
|
+
float32x4_t polynomials_f32x4 = coeff_9_f32x4;
|
|
119
|
+
polynomials_f32x4 = vfmaq_f32(coeff_7_f32x4, polynomials_f32x4, angles_squared_f32x4);
|
|
120
|
+
polynomials_f32x4 = vfmaq_f32(coeff_5_f32x4, polynomials_f32x4, angles_squared_f32x4);
|
|
121
|
+
polynomials_f32x4 = vfmaq_f32(coeff_3_f32x4, polynomials_f32x4, angles_squared_f32x4);
|
|
122
|
+
float32x4_t results_f32x4 = vfmaq_f32(angles_f32x4, angles_cubed_f32x4, polynomials_f32x4);
|
|
123
|
+
|
|
124
|
+
// If multiples_of_pi_i32x4 is even, flip the sign
|
|
125
|
+
int32x4_t parity_i32x4 = vandq_s32(multiples_of_pi_i32x4, vdupq_n_s32(1));
|
|
126
|
+
uint32x4_t even_mask_u32x4 = vceqq_s32(parity_i32x4, vdupq_n_s32(0));
|
|
127
|
+
float32x4_t negated_f32x4 = vnegq_f32(results_f32x4);
|
|
128
|
+
results_f32x4 = vbslq_f32(even_mask_u32x4, negated_f32x4, results_f32x4);
|
|
129
|
+
return results_f32x4;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
NK_INTERNAL float32x4_t nk_atan_f32x4_neon_(float32x4_t const inputs) {
|
|
133
|
+
// Polynomial coefficients for atan approximation (8 terms)
|
|
134
|
+
float32x4_t const coeff_8_f32x4 = vdupq_n_f32(-0.333331018686294555664062f);
|
|
135
|
+
float32x4_t const coeff_7_f32x4 = vdupq_n_f32(+0.199926957488059997558594f);
|
|
136
|
+
float32x4_t const coeff_6_f32x4 = vdupq_n_f32(-0.142027363181114196777344f);
|
|
137
|
+
float32x4_t const coeff_5_f32x4 = vdupq_n_f32(+0.106347933411598205566406f);
|
|
138
|
+
float32x4_t const coeff_4_f32x4 = vdupq_n_f32(-0.0748900920152664184570312f);
|
|
139
|
+
float32x4_t const coeff_3_f32x4 = vdupq_n_f32(+0.0425049886107444763183594f);
|
|
140
|
+
float32x4_t const coeff_2_f32x4 = vdupq_n_f32(-0.0159569028764963150024414f);
|
|
141
|
+
float32x4_t const coeff_1_f32x4 = vdupq_n_f32(+0.00282363896258175373077393f);
|
|
142
|
+
float32x4_t const half_pi_f32x4 = vdupq_n_f32(1.5707963267948966f);
|
|
143
|
+
|
|
144
|
+
// Detect negative values_f32x4 and take absolute value
|
|
145
|
+
float32x4_t const zeros_f32x4 = vdupq_n_f32(0);
|
|
146
|
+
uint32x4_t negative_mask_u32x4 = vcltq_f32(inputs, zeros_f32x4);
|
|
147
|
+
float32x4_t values_f32x4 = vabsq_f32(inputs);
|
|
148
|
+
|
|
149
|
+
// Check if values_f32x4 > 1 (need reciprocal)
|
|
150
|
+
uint32x4_t reciprocal_mask_u32x4 = vcgtq_f32(values_f32x4, vdupq_n_f32(1.0f));
|
|
151
|
+
|
|
152
|
+
// Fast reciprocal using vrecpeq + Newton-Raphson (faster than vdivq on many Arm cores)
|
|
153
|
+
float32x4_t recip_f32x4 = vrecpeq_f32(values_f32x4);
|
|
154
|
+
recip_f32x4 = vmulq_f32(recip_f32x4, vrecpsq_f32(values_f32x4, recip_f32x4));
|
|
155
|
+
recip_f32x4 = vmulq_f32(recip_f32x4, vrecpsq_f32(values_f32x4, recip_f32x4));
|
|
156
|
+
values_f32x4 = vbslq_f32(reciprocal_mask_u32x4, recip_f32x4, values_f32x4);
|
|
157
|
+
|
|
158
|
+
// Compute powers
|
|
159
|
+
float32x4_t const values_squared_f32x4 = vmulq_f32(values_f32x4, values_f32x4);
|
|
160
|
+
float32x4_t const values_cubed_f32x4 = vmulq_f32(values_f32x4, values_squared_f32x4);
|
|
161
|
+
|
|
162
|
+
// Polynomial evaluation using Horner's method
|
|
163
|
+
float32x4_t polynomials_f32x4 = coeff_1_f32x4;
|
|
164
|
+
polynomials_f32x4 = vfmaq_f32(coeff_2_f32x4, polynomials_f32x4, values_squared_f32x4);
|
|
165
|
+
polynomials_f32x4 = vfmaq_f32(coeff_3_f32x4, polynomials_f32x4, values_squared_f32x4);
|
|
166
|
+
polynomials_f32x4 = vfmaq_f32(coeff_4_f32x4, polynomials_f32x4, values_squared_f32x4);
|
|
167
|
+
polynomials_f32x4 = vfmaq_f32(coeff_5_f32x4, polynomials_f32x4, values_squared_f32x4);
|
|
168
|
+
polynomials_f32x4 = vfmaq_f32(coeff_6_f32x4, polynomials_f32x4, values_squared_f32x4);
|
|
169
|
+
polynomials_f32x4 = vfmaq_f32(coeff_7_f32x4, polynomials_f32x4, values_squared_f32x4);
|
|
170
|
+
polynomials_f32x4 = vfmaq_f32(coeff_8_f32x4, polynomials_f32x4, values_squared_f32x4);
|
|
171
|
+
|
|
172
|
+
// Compute result_f32x4: atan(x) ≈ x + x³ * P(x²)
|
|
173
|
+
float32x4_t result_f32x4 = vfmaq_f32(values_f32x4, values_cubed_f32x4, polynomials_f32x4);
|
|
174
|
+
|
|
175
|
+
// Adjust for reciprocal: result_f32x4 = π/2 - result_f32x4
|
|
176
|
+
float32x4_t adjusted_f32x4 = vsubq_f32(half_pi_f32x4, result_f32x4);
|
|
177
|
+
result_f32x4 = vbslq_f32(reciprocal_mask_u32x4, adjusted_f32x4, result_f32x4);
|
|
178
|
+
|
|
179
|
+
// Adjust for negative: result_f32x4 = -result_f32x4
|
|
180
|
+
float32x4_t negated_f32x4 = vnegq_f32(result_f32x4);
|
|
181
|
+
result_f32x4 = vbslq_f32(negative_mask_u32x4, negated_f32x4, result_f32x4);
|
|
182
|
+
return result_f32x4;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
NK_INTERNAL float32x4_t nk_atan2_f32x4_neon_(float32x4_t const ys_inputs, float32x4_t const xs_inputs) {
|
|
186
|
+
// Polynomial coefficients (same as atan)
|
|
187
|
+
float32x4_t const coeff_8_f32x4 = vdupq_n_f32(-0.333331018686294555664062f);
|
|
188
|
+
float32x4_t const coeff_7_f32x4 = vdupq_n_f32(+0.199926957488059997558594f);
|
|
189
|
+
float32x4_t const coeff_6_f32x4 = vdupq_n_f32(-0.142027363181114196777344f);
|
|
190
|
+
float32x4_t const coeff_5_f32x4 = vdupq_n_f32(+0.106347933411598205566406f);
|
|
191
|
+
float32x4_t const coeff_4_f32x4 = vdupq_n_f32(-0.0748900920152664184570312f);
|
|
192
|
+
float32x4_t const coeff_3_f32x4 = vdupq_n_f32(+0.0425049886107444763183594f);
|
|
193
|
+
float32x4_t const coeff_2_f32x4 = vdupq_n_f32(-0.0159569028764963150024414f);
|
|
194
|
+
float32x4_t const coeff_1_f32x4 = vdupq_n_f32(+0.00282363896258175373077393f);
|
|
195
|
+
float32x4_t const half_pi_f32x4 = vdupq_n_f32(1.5707963267948966f);
|
|
196
|
+
float32x4_t const zeros_f32x4 = vdupq_n_f32(0);
|
|
197
|
+
|
|
198
|
+
// Quadrant adjustments - take absolute values
|
|
199
|
+
uint32x4_t xs_negative_mask_u32x4 = vcltq_f32(xs_inputs, zeros_f32x4);
|
|
200
|
+
float32x4_t xs_f32x4 = vabsq_f32(xs_inputs);
|
|
201
|
+
float32x4_t ys_f32x4 = vabsq_f32(ys_inputs);
|
|
202
|
+
|
|
203
|
+
// Ensure proper fraction where numerator < denominator
|
|
204
|
+
uint32x4_t swap_mask_u32x4 = vcgtq_f32(ys_f32x4, xs_f32x4);
|
|
205
|
+
float32x4_t temps_f32x4 = xs_f32x4;
|
|
206
|
+
xs_f32x4 = vbslq_f32(swap_mask_u32x4, ys_f32x4, xs_f32x4);
|
|
207
|
+
ys_f32x4 = vbslq_f32(swap_mask_u32x4, vnegq_f32(temps_f32x4), ys_f32x4);
|
|
208
|
+
|
|
209
|
+
// Fast reciprocal for division: ratio_f32x4 = ys_f32x4 / xs_f32x4 ≈ ys_f32x4 * recip_f32x4(xs_f32x4)
|
|
210
|
+
float32x4_t recip_f32x4 = vrecpeq_f32(xs_f32x4);
|
|
211
|
+
recip_f32x4 = vmulq_f32(recip_f32x4, vrecpsq_f32(xs_f32x4, recip_f32x4));
|
|
212
|
+
recip_f32x4 = vmulq_f32(recip_f32x4, vrecpsq_f32(xs_f32x4, recip_f32x4));
|
|
213
|
+
float32x4_t const ratio_f32x4 = vmulq_f32(ys_f32x4, recip_f32x4);
|
|
214
|
+
float32x4_t const ratio_squared_f32x4 = vmulq_f32(ratio_f32x4, ratio_f32x4);
|
|
215
|
+
float32x4_t const ratio_cubed_f32x4 = vmulq_f32(ratio_f32x4, ratio_squared_f32x4);
|
|
216
|
+
|
|
217
|
+
// Polynomial evaluation using Horner's method
|
|
218
|
+
float32x4_t polynomials_f32x4 = coeff_1_f32x4;
|
|
219
|
+
polynomials_f32x4 = vfmaq_f32(coeff_2_f32x4, polynomials_f32x4, ratio_squared_f32x4);
|
|
220
|
+
polynomials_f32x4 = vfmaq_f32(coeff_3_f32x4, polynomials_f32x4, ratio_squared_f32x4);
|
|
221
|
+
polynomials_f32x4 = vfmaq_f32(coeff_4_f32x4, polynomials_f32x4, ratio_squared_f32x4);
|
|
222
|
+
polynomials_f32x4 = vfmaq_f32(coeff_5_f32x4, polynomials_f32x4, ratio_squared_f32x4);
|
|
223
|
+
polynomials_f32x4 = vfmaq_f32(coeff_6_f32x4, polynomials_f32x4, ratio_squared_f32x4);
|
|
224
|
+
polynomials_f32x4 = vfmaq_f32(coeff_7_f32x4, polynomials_f32x4, ratio_squared_f32x4);
|
|
225
|
+
polynomials_f32x4 = vfmaq_f32(coeff_8_f32x4, polynomials_f32x4, ratio_squared_f32x4);
|
|
226
|
+
|
|
227
|
+
// Compute the result
|
|
228
|
+
float32x4_t results_f32x4 = vfmaq_f32(ratio_f32x4, ratio_cubed_f32x4, polynomials_f32x4);
|
|
229
|
+
|
|
230
|
+
// Compute quadrant_f32x4 value: 0 for x>=0 && !swap, 1 for x>=0 && swap,
|
|
231
|
+
// -2 for x<0 && !swap, -1 for x<0 && swap
|
|
232
|
+
float32x4_t quadrant_f32x4 = vdupq_n_f32(0.0f);
|
|
233
|
+
float32x4_t neg_two_f32x4 = vdupq_n_f32(-2.0f);
|
|
234
|
+
quadrant_f32x4 = vbslq_f32(xs_negative_mask_u32x4, neg_two_f32x4, quadrant_f32x4);
|
|
235
|
+
float32x4_t quadrant_incremented_f32x4 = vaddq_f32(quadrant_f32x4, vdupq_n_f32(1.0f));
|
|
236
|
+
quadrant_f32x4 = vbslq_f32(swap_mask_u32x4, quadrant_incremented_f32x4, quadrant_f32x4);
|
|
237
|
+
|
|
238
|
+
// Adjust for quadrant_f32x4: result += quadrant_f32x4 * π/2
|
|
239
|
+
results_f32x4 = vfmaq_f32(results_f32x4, quadrant_f32x4, half_pi_f32x4);
|
|
240
|
+
|
|
241
|
+
// Transfer sign from x and y by XOR with sign bits
|
|
242
|
+
uint32x4_t sign_mask_u32x4 = vreinterpretq_u32_f32(vdupq_n_f32(-0.0f));
|
|
243
|
+
uint32x4_t xs_sign_u32x4 = vandq_u32(vreinterpretq_u32_f32(xs_inputs), sign_mask_u32x4);
|
|
244
|
+
uint32x4_t ys_sign_u32x4 = vandq_u32(vreinterpretq_u32_f32(ys_inputs), sign_mask_u32x4);
|
|
245
|
+
uint32x4_t result_bits_u32x4 = vreinterpretq_u32_f32(results_f32x4);
|
|
246
|
+
result_bits_u32x4 = veorq_u32(result_bits_u32x4, xs_sign_u32x4);
|
|
247
|
+
result_bits_u32x4 = veorq_u32(result_bits_u32x4, ys_sign_u32x4);
|
|
248
|
+
results_f32x4 = vreinterpretq_f32_u32(result_bits_u32x4);
|
|
249
|
+
|
|
250
|
+
return results_f32x4;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
NK_INTERNAL float64x2_t nk_sin_f64x2_neon_(float64x2_t const angles_radians) {
|
|
254
|
+
// Constants for argument reduction
|
|
255
|
+
float64x2_t const pi_high_f64x2 = vdupq_n_f64(3.141592653589793116);
|
|
256
|
+
float64x2_t const pi_low_f64x2 = vdupq_n_f64(1.2246467991473532072e-16);
|
|
257
|
+
float64x2_t const pi_reciprocal_f64x2 = vdupq_n_f64(0.31830988618379067154);
|
|
258
|
+
|
|
259
|
+
// Polynomial coefficients for sine approximation
|
|
260
|
+
float64x2_t const coeff_0_f64x2 = vdupq_n_f64(+0.00833333333333332974823815);
|
|
261
|
+
float64x2_t const coeff_1_f64x2 = vdupq_n_f64(-0.000198412698412696162806809);
|
|
262
|
+
float64x2_t const coeff_2_f64x2 = vdupq_n_f64(+2.75573192239198747630416e-06);
|
|
263
|
+
float64x2_t const coeff_3_f64x2 = vdupq_n_f64(-2.50521083763502045810755e-08);
|
|
264
|
+
float64x2_t const coeff_4_f64x2 = vdupq_n_f64(+1.60590430605664501629054e-10);
|
|
265
|
+
float64x2_t const coeff_5_f64x2 = vdupq_n_f64(-7.64712219118158833288484e-13);
|
|
266
|
+
float64x2_t const coeff_6_f64x2 = vdupq_n_f64(+2.81009972710863200091251e-15);
|
|
267
|
+
float64x2_t const coeff_7_f64x2 = vdupq_n_f64(-7.97255955009037868891952e-18);
|
|
268
|
+
float64x2_t const coeff_8_f64x2 = vdupq_n_f64(-0.166666666666666657414808);
|
|
269
|
+
|
|
270
|
+
// Compute round(angle / π)
|
|
271
|
+
float64x2_t const quotients_f64x2 = vmulq_f64(angles_radians, pi_reciprocal_f64x2);
|
|
272
|
+
int64x2_t multiples_of_pi_i64x2 = vcvtnq_s64_f64(quotients_f64x2);
|
|
273
|
+
float64x2_t rounded_quotients_f64x2 = vcvtq_f64_s64(multiples_of_pi_i64x2);
|
|
274
|
+
|
|
275
|
+
// Two-step Cody-Waite reduction: angle - rounded * π_high - rounded * π_low
|
|
276
|
+
float64x2_t angles_f64x2 = angles_radians;
|
|
277
|
+
angles_f64x2 = vfmsq_f64(angles_f64x2, rounded_quotients_f64x2, pi_high_f64x2);
|
|
278
|
+
angles_f64x2 = vfmsq_f64(angles_f64x2, rounded_quotients_f64x2, pi_low_f64x2);
|
|
279
|
+
|
|
280
|
+
// If multiples_of_pi_i64x2 is odd, negate the angle
|
|
281
|
+
int64x2_t parity_i64x2 = vandq_s64(multiples_of_pi_i64x2, vdupq_n_s64(1));
|
|
282
|
+
uint64x2_t odd_mask_u64x2 = vceqq_s64(parity_i64x2, vdupq_n_s64(1));
|
|
283
|
+
float64x2_t negated_angles_f64x2 = vnegq_f64(angles_f64x2);
|
|
284
|
+
angles_f64x2 = vbslq_f64(odd_mask_u64x2, negated_angles_f64x2, angles_f64x2);
|
|
285
|
+
|
|
286
|
+
float64x2_t const angles_squared_f64x2 = vmulq_f64(angles_f64x2, angles_f64x2);
|
|
287
|
+
float64x2_t const angles_cubed_f64x2 = vmulq_f64(angles_f64x2, angles_squared_f64x2);
|
|
288
|
+
float64x2_t const angles_quadratic_f64x2 = vmulq_f64(angles_squared_f64x2, angles_squared_f64x2);
|
|
289
|
+
float64x2_t const angles_octic_f64x2 = vmulq_f64(angles_quadratic_f64x2, angles_quadratic_f64x2);
|
|
290
|
+
|
|
291
|
+
// Compute polynomial terms using Estrin's scheme for better ILP
|
|
292
|
+
float64x2_t const poly_67_f64x2 = vfmaq_f64(coeff_6_f64x2, angles_squared_f64x2, coeff_7_f64x2);
|
|
293
|
+
float64x2_t const poly_45_f64x2 = vfmaq_f64(coeff_4_f64x2, angles_squared_f64x2, coeff_5_f64x2);
|
|
294
|
+
float64x2_t const poly_4567_f64x2 = vfmaq_f64(poly_45_f64x2, angles_quadratic_f64x2, poly_67_f64x2);
|
|
295
|
+
|
|
296
|
+
float64x2_t const poly_23_f64x2 = vfmaq_f64(coeff_2_f64x2, angles_squared_f64x2, coeff_3_f64x2);
|
|
297
|
+
float64x2_t const poly_01_f64x2 = vfmaq_f64(coeff_0_f64x2, angles_squared_f64x2, coeff_1_f64x2);
|
|
298
|
+
float64x2_t const poly_0123_f64x2 = vfmaq_f64(poly_01_f64x2, angles_quadratic_f64x2, poly_23_f64x2);
|
|
299
|
+
|
|
300
|
+
// Combine polynomial terms
|
|
301
|
+
float64x2_t results_f64x2 = vfmaq_f64(poly_0123_f64x2, angles_octic_f64x2, poly_4567_f64x2);
|
|
302
|
+
results_f64x2 = vfmaq_f64(coeff_8_f64x2, results_f64x2, angles_squared_f64x2);
|
|
303
|
+
results_f64x2 = vfmaq_f64(angles_f64x2, results_f64x2, angles_cubed_f64x2);
|
|
304
|
+
|
|
305
|
+
// Handle zero input (preserve sign of zero)
|
|
306
|
+
uint64x2_t const non_zero_mask_u64x2 = vceqq_f64(angles_radians, vdupq_n_f64(0));
|
|
307
|
+
results_f64x2 = vbslq_f64(non_zero_mask_u64x2, angles_radians, results_f64x2);
|
|
308
|
+
return results_f64x2;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
NK_INTERNAL float64x2_t nk_cos_f64x2_neon_(float64x2_t const angles_radians) {
|
|
312
|
+
// Constants for argument reduction
|
|
313
|
+
float64x2_t const pi_high_half_f64x2 = vdupq_n_f64(3.141592653589793116 * 0.5);
|
|
314
|
+
float64x2_t const pi_low_half_f64x2 = vdupq_n_f64(1.2246467991473532072e-16 * 0.5);
|
|
315
|
+
float64x2_t const pi_reciprocal_f64x2 = vdupq_n_f64(0.31830988618379067154);
|
|
316
|
+
|
|
317
|
+
// Polynomial coefficients for cosine approximation
|
|
318
|
+
float64x2_t const coeff_0_f64x2 = vdupq_n_f64(+0.00833333333333332974823815);
|
|
319
|
+
float64x2_t const coeff_1_f64x2 = vdupq_n_f64(-0.000198412698412696162806809);
|
|
320
|
+
float64x2_t const coeff_2_f64x2 = vdupq_n_f64(+2.75573192239198747630416e-06);
|
|
321
|
+
float64x2_t const coeff_3_f64x2 = vdupq_n_f64(-2.50521083763502045810755e-08);
|
|
322
|
+
float64x2_t const coeff_4_f64x2 = vdupq_n_f64(+1.60590430605664501629054e-10);
|
|
323
|
+
float64x2_t const coeff_5_f64x2 = vdupq_n_f64(-7.64712219118158833288484e-13);
|
|
324
|
+
float64x2_t const coeff_6_f64x2 = vdupq_n_f64(+2.81009972710863200091251e-15);
|
|
325
|
+
float64x2_t const coeff_7_f64x2 = vdupq_n_f64(-7.97255955009037868891952e-18);
|
|
326
|
+
float64x2_t const coeff_8_f64x2 = vdupq_n_f64(-0.166666666666666657414808);
|
|
327
|
+
|
|
328
|
+
// Compute 2 * round(angle / π - 0.5) + 1
|
|
329
|
+
float64x2_t const quotients_f64x2 = vsubq_f64(vmulq_f64(angles_radians, pi_reciprocal_f64x2), vdupq_n_f64(0.5));
|
|
330
|
+
float64x2_t const rounded_f64x2 = vcvtq_f64_s64(vcvtnq_s64_f64(quotients_f64x2));
|
|
331
|
+
float64x2_t const rounded_quotients_f64x2 = vfmaq_f64(vdupq_n_f64(1.0), vdupq_n_f64(2.0), rounded_f64x2);
|
|
332
|
+
int64x2_t quotients_i64_i64x2 = vcvtnq_s64_f64(rounded_quotients_f64x2);
|
|
333
|
+
|
|
334
|
+
// Two-step Cody-Waite reduction
|
|
335
|
+
float64x2_t angles_f64x2 = angles_radians;
|
|
336
|
+
angles_f64x2 = vfmsq_f64(angles_f64x2, rounded_quotients_f64x2, pi_high_half_f64x2);
|
|
337
|
+
angles_f64x2 = vfmsq_f64(angles_f64x2, rounded_quotients_f64x2, pi_low_half_f64x2);
|
|
338
|
+
|
|
339
|
+
// If (rounded_quotients_f64x2 & 2) == 0, negate the angle
|
|
340
|
+
int64x2_t bit2_i64x2 = vandq_s64(quotients_i64_i64x2, vdupq_n_s64(2));
|
|
341
|
+
uint64x2_t flip_mask_u64x2 = vceqq_s64(bit2_i64x2, vdupq_n_s64(0));
|
|
342
|
+
float64x2_t negated_angles_f64x2 = vnegq_f64(angles_f64x2);
|
|
343
|
+
angles_f64x2 = vbslq_f64(flip_mask_u64x2, negated_angles_f64x2, angles_f64x2);
|
|
344
|
+
|
|
345
|
+
float64x2_t const angles_squared_f64x2 = vmulq_f64(angles_f64x2, angles_f64x2);
|
|
346
|
+
float64x2_t const angles_cubed_f64x2 = vmulq_f64(angles_f64x2, angles_squared_f64x2);
|
|
347
|
+
float64x2_t const angles_quadratic_f64x2 = vmulq_f64(angles_squared_f64x2, angles_squared_f64x2);
|
|
348
|
+
float64x2_t const angles_octic_f64x2 = vmulq_f64(angles_quadratic_f64x2, angles_quadratic_f64x2);
|
|
349
|
+
|
|
350
|
+
// Compute polynomial terms using Estrin's scheme
|
|
351
|
+
float64x2_t const poly_67_f64x2 = vfmaq_f64(coeff_6_f64x2, angles_squared_f64x2, coeff_7_f64x2);
|
|
352
|
+
float64x2_t const poly_45_f64x2 = vfmaq_f64(coeff_4_f64x2, angles_squared_f64x2, coeff_5_f64x2);
|
|
353
|
+
float64x2_t const poly_4567_f64x2 = vfmaq_f64(poly_45_f64x2, angles_quadratic_f64x2, poly_67_f64x2);
|
|
354
|
+
|
|
355
|
+
float64x2_t const poly_23_f64x2 = vfmaq_f64(coeff_2_f64x2, angles_squared_f64x2, coeff_3_f64x2);
|
|
356
|
+
float64x2_t const poly_01_f64x2 = vfmaq_f64(coeff_0_f64x2, angles_squared_f64x2, coeff_1_f64x2);
|
|
357
|
+
float64x2_t const poly_0123_f64x2 = vfmaq_f64(poly_01_f64x2, angles_quadratic_f64x2, poly_23_f64x2);
|
|
358
|
+
|
|
359
|
+
// Combine polynomial terms
|
|
360
|
+
float64x2_t results_f64x2 = vfmaq_f64(poly_0123_f64x2, angles_octic_f64x2, poly_4567_f64x2);
|
|
361
|
+
results_f64x2 = vfmaq_f64(coeff_8_f64x2, results_f64x2, angles_squared_f64x2);
|
|
362
|
+
results_f64x2 = vfmaq_f64(angles_f64x2, results_f64x2, angles_cubed_f64x2);
|
|
363
|
+
return results_f64x2;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
NK_INTERNAL float64x2_t nk_atan_f64x2_neon_(float64x2_t const inputs) {
|
|
367
|
+
// Polynomial coefficients for atan approximation (19 terms)
|
|
368
|
+
float64x2_t const coeff_19_f64x2 = vdupq_n_f64(-1.88796008463073496563746e-05);
|
|
369
|
+
float64x2_t const coeff_18_f64x2 = vdupq_n_f64(+0.000209850076645816976906797);
|
|
370
|
+
float64x2_t const coeff_17_f64x2 = vdupq_n_f64(-0.00110611831486672482563471);
|
|
371
|
+
float64x2_t const coeff_16_f64x2 = vdupq_n_f64(+0.00370026744188713119232403);
|
|
372
|
+
float64x2_t const coeff_15_f64x2 = vdupq_n_f64(-0.00889896195887655491740809);
|
|
373
|
+
float64x2_t const coeff_14_f64x2 = vdupq_n_f64(+0.016599329773529201970117);
|
|
374
|
+
float64x2_t const coeff_13_f64x2 = vdupq_n_f64(-0.0254517624932312641616861);
|
|
375
|
+
float64x2_t const coeff_12_f64x2 = vdupq_n_f64(+0.0337852580001353069993897);
|
|
376
|
+
float64x2_t const coeff_11_f64x2 = vdupq_n_f64(-0.0407629191276836500001934);
|
|
377
|
+
float64x2_t const coeff_10_f64x2 = vdupq_n_f64(+0.0466667150077840625632675);
|
|
378
|
+
float64x2_t const coeff_9_f64x2 = vdupq_n_f64(-0.0523674852303482457616113);
|
|
379
|
+
float64x2_t const coeff_8_f64x2 = vdupq_n_f64(+0.0587666392926673580854313);
|
|
380
|
+
float64x2_t const coeff_7_f64x2 = vdupq_n_f64(-0.0666573579361080525984562);
|
|
381
|
+
float64x2_t const coeff_6_f64x2 = vdupq_n_f64(+0.0769219538311769618355029);
|
|
382
|
+
float64x2_t const coeff_5_f64x2 = vdupq_n_f64(-0.090908995008245008229153);
|
|
383
|
+
float64x2_t const coeff_4_f64x2 = vdupq_n_f64(+0.111111105648261418443745);
|
|
384
|
+
float64x2_t const coeff_3_f64x2 = vdupq_n_f64(-0.14285714266771329383765);
|
|
385
|
+
float64x2_t const coeff_2_f64x2 = vdupq_n_f64(+0.199999999996591265594148);
|
|
386
|
+
float64x2_t const coeff_1_f64x2 = vdupq_n_f64(-0.333333333333311110369124);
|
|
387
|
+
float64x2_t const half_pi_f64x2 = vdupq_n_f64(1.5707963267948966);
|
|
388
|
+
float64x2_t const zeros_f64x2 = vdupq_n_f64(0);
|
|
389
|
+
|
|
390
|
+
// Detect negative and take absolute value
|
|
391
|
+
uint64x2_t negative_mask_u64x2 = vcltq_f64(inputs, zeros_f64x2);
|
|
392
|
+
float64x2_t values_f64x2 = vabsq_f64(inputs);
|
|
393
|
+
|
|
394
|
+
// Check if values_f64x2 > 1 (need reciprocal) - use division for f64 precision
|
|
395
|
+
uint64x2_t reciprocal_mask_u64x2 = vcgtq_f64(values_f64x2, vdupq_n_f64(1.0));
|
|
396
|
+
float64x2_t reciprocal_values_f64x2 = vdivq_f64(vdupq_n_f64(1.0), values_f64x2);
|
|
397
|
+
values_f64x2 = vbslq_f64(reciprocal_mask_u64x2, reciprocal_values_f64x2, values_f64x2);
|
|
398
|
+
|
|
399
|
+
// Compute powers
|
|
400
|
+
float64x2_t const values_squared_f64x2 = vmulq_f64(values_f64x2, values_f64x2);
|
|
401
|
+
float64x2_t const values_cubed_f64x2 = vmulq_f64(values_f64x2, values_squared_f64x2);
|
|
402
|
+
|
|
403
|
+
// Polynomial evaluation using Horner's method
|
|
404
|
+
float64x2_t polynomials_f64x2 = coeff_19_f64x2;
|
|
405
|
+
polynomials_f64x2 = vfmaq_f64(coeff_18_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
406
|
+
polynomials_f64x2 = vfmaq_f64(coeff_17_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
407
|
+
polynomials_f64x2 = vfmaq_f64(coeff_16_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
408
|
+
polynomials_f64x2 = vfmaq_f64(coeff_15_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
409
|
+
polynomials_f64x2 = vfmaq_f64(coeff_14_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
410
|
+
polynomials_f64x2 = vfmaq_f64(coeff_13_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
411
|
+
polynomials_f64x2 = vfmaq_f64(coeff_12_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
412
|
+
polynomials_f64x2 = vfmaq_f64(coeff_11_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
413
|
+
polynomials_f64x2 = vfmaq_f64(coeff_10_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
414
|
+
polynomials_f64x2 = vfmaq_f64(coeff_9_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
415
|
+
polynomials_f64x2 = vfmaq_f64(coeff_8_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
416
|
+
polynomials_f64x2 = vfmaq_f64(coeff_7_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
417
|
+
polynomials_f64x2 = vfmaq_f64(coeff_6_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
418
|
+
polynomials_f64x2 = vfmaq_f64(coeff_5_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
419
|
+
polynomials_f64x2 = vfmaq_f64(coeff_4_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
420
|
+
polynomials_f64x2 = vfmaq_f64(coeff_3_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
421
|
+
polynomials_f64x2 = vfmaq_f64(coeff_2_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
422
|
+
polynomials_f64x2 = vfmaq_f64(coeff_1_f64x2, polynomials_f64x2, values_squared_f64x2);
|
|
423
|
+
|
|
424
|
+
// Compute result_f64x2
|
|
425
|
+
float64x2_t result_f64x2 = vfmaq_f64(values_f64x2, values_cubed_f64x2, polynomials_f64x2);
|
|
426
|
+
|
|
427
|
+
// Adjust for reciprocal: result_f64x2 = π/2 - result_f64x2
|
|
428
|
+
float64x2_t adjusted_f64x2 = vsubq_f64(half_pi_f64x2, result_f64x2);
|
|
429
|
+
result_f64x2 = vbslq_f64(reciprocal_mask_u64x2, adjusted_f64x2, result_f64x2);
|
|
430
|
+
|
|
431
|
+
// Adjust for negative: result_f64x2 = -result_f64x2
|
|
432
|
+
float64x2_t negated_f64x2 = vnegq_f64(result_f64x2);
|
|
433
|
+
result_f64x2 = vbslq_f64(negative_mask_u64x2, negated_f64x2, result_f64x2);
|
|
434
|
+
return result_f64x2;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
NK_INTERNAL float64x2_t nk_atan2_f64x2_neon_(float64x2_t const ys_inputs, float64x2_t const xs_inputs) {
|
|
438
|
+
// Polynomial coefficients (same as atan)
|
|
439
|
+
float64x2_t const coeff_19_f64x2 = vdupq_n_f64(-1.88796008463073496563746e-05);
|
|
440
|
+
float64x2_t const coeff_18_f64x2 = vdupq_n_f64(+0.000209850076645816976906797);
|
|
441
|
+
float64x2_t const coeff_17_f64x2 = vdupq_n_f64(-0.00110611831486672482563471);
|
|
442
|
+
float64x2_t const coeff_16_f64x2 = vdupq_n_f64(+0.00370026744188713119232403);
|
|
443
|
+
float64x2_t const coeff_15_f64x2 = vdupq_n_f64(-0.00889896195887655491740809);
|
|
444
|
+
float64x2_t const coeff_14_f64x2 = vdupq_n_f64(+0.016599329773529201970117);
|
|
445
|
+
float64x2_t const coeff_13_f64x2 = vdupq_n_f64(-0.0254517624932312641616861);
|
|
446
|
+
float64x2_t const coeff_12_f64x2 = vdupq_n_f64(+0.0337852580001353069993897);
|
|
447
|
+
float64x2_t const coeff_11_f64x2 = vdupq_n_f64(-0.0407629191276836500001934);
|
|
448
|
+
float64x2_t const coeff_10_f64x2 = vdupq_n_f64(+0.0466667150077840625632675);
|
|
449
|
+
float64x2_t const coeff_9_f64x2 = vdupq_n_f64(-0.0523674852303482457616113);
|
|
450
|
+
float64x2_t const coeff_8_f64x2 = vdupq_n_f64(+0.0587666392926673580854313);
|
|
451
|
+
float64x2_t const coeff_7_f64x2 = vdupq_n_f64(-0.0666573579361080525984562);
|
|
452
|
+
float64x2_t const coeff_6_f64x2 = vdupq_n_f64(+0.0769219538311769618355029);
|
|
453
|
+
float64x2_t const coeff_5_f64x2 = vdupq_n_f64(-0.090908995008245008229153);
|
|
454
|
+
float64x2_t const coeff_4_f64x2 = vdupq_n_f64(+0.111111105648261418443745);
|
|
455
|
+
float64x2_t const coeff_3_f64x2 = vdupq_n_f64(-0.14285714266771329383765);
|
|
456
|
+
float64x2_t const coeff_2_f64x2 = vdupq_n_f64(+0.199999999996591265594148);
|
|
457
|
+
float64x2_t const coeff_1_f64x2 = vdupq_n_f64(-0.333333333333311110369124);
|
|
458
|
+
float64x2_t const half_pi_f64x2 = vdupq_n_f64(1.5707963267948966);
|
|
459
|
+
float64x2_t const zeros_f64x2 = vdupq_n_f64(0);
|
|
460
|
+
|
|
461
|
+
// Quadrant adjustments - take absolute values
|
|
462
|
+
uint64x2_t xs_negative_mask_u64x2 = vcltq_f64(xs_inputs, zeros_f64x2);
|
|
463
|
+
float64x2_t xs_f64x2 = vabsq_f64(xs_inputs);
|
|
464
|
+
float64x2_t ys_f64x2 = vabsq_f64(ys_inputs);
|
|
465
|
+
|
|
466
|
+
// Ensure proper fraction where numerator < denominator
|
|
467
|
+
uint64x2_t swap_mask_u64x2 = vcgtq_f64(ys_f64x2, xs_f64x2);
|
|
468
|
+
float64x2_t temps_f64x2 = xs_f64x2;
|
|
469
|
+
xs_f64x2 = vbslq_f64(swap_mask_u64x2, ys_f64x2, xs_f64x2);
|
|
470
|
+
ys_f64x2 = vbslq_f64(swap_mask_u64x2, vnegq_f64(temps_f64x2), ys_f64x2);
|
|
471
|
+
|
|
472
|
+
// Division for f64 precision
|
|
473
|
+
float64x2_t const ratio_f64x2 = vdivq_f64(ys_f64x2, xs_f64x2);
|
|
474
|
+
float64x2_t const ratio_squared_f64x2 = vmulq_f64(ratio_f64x2, ratio_f64x2);
|
|
475
|
+
float64x2_t const ratio_cubed_f64x2 = vmulq_f64(ratio_f64x2, ratio_squared_f64x2);
|
|
476
|
+
|
|
477
|
+
// Polynomial evaluation using Horner's method
|
|
478
|
+
float64x2_t polynomials_f64x2 = coeff_19_f64x2;
|
|
479
|
+
polynomials_f64x2 = vfmaq_f64(coeff_18_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
480
|
+
polynomials_f64x2 = vfmaq_f64(coeff_17_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
481
|
+
polynomials_f64x2 = vfmaq_f64(coeff_16_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
482
|
+
polynomials_f64x2 = vfmaq_f64(coeff_15_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
483
|
+
polynomials_f64x2 = vfmaq_f64(coeff_14_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
484
|
+
polynomials_f64x2 = vfmaq_f64(coeff_13_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
485
|
+
polynomials_f64x2 = vfmaq_f64(coeff_12_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
486
|
+
polynomials_f64x2 = vfmaq_f64(coeff_11_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
487
|
+
polynomials_f64x2 = vfmaq_f64(coeff_10_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
488
|
+
polynomials_f64x2 = vfmaq_f64(coeff_9_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
489
|
+
polynomials_f64x2 = vfmaq_f64(coeff_8_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
490
|
+
polynomials_f64x2 = vfmaq_f64(coeff_7_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
491
|
+
polynomials_f64x2 = vfmaq_f64(coeff_6_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
492
|
+
polynomials_f64x2 = vfmaq_f64(coeff_5_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
493
|
+
polynomials_f64x2 = vfmaq_f64(coeff_4_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
494
|
+
polynomials_f64x2 = vfmaq_f64(coeff_3_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
495
|
+
polynomials_f64x2 = vfmaq_f64(coeff_2_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
496
|
+
polynomials_f64x2 = vfmaq_f64(coeff_1_f64x2, polynomials_f64x2, ratio_squared_f64x2);
|
|
497
|
+
|
|
498
|
+
// Compute the result
|
|
499
|
+
float64x2_t results_f64x2 = vfmaq_f64(ratio_f64x2, ratio_cubed_f64x2, polynomials_f64x2);
|
|
500
|
+
|
|
501
|
+
// Compute quadrant_f64x2 value: 0 for x>=0 && !swap, 1 for x>=0 && swap,
|
|
502
|
+
// -2 for x<0 && !swap, -1 for x<0 && swap
|
|
503
|
+
float64x2_t quadrant_f64x2 = vdupq_n_f64(0.0);
|
|
504
|
+
float64x2_t neg_two_f64x2 = vdupq_n_f64(-2.0);
|
|
505
|
+
quadrant_f64x2 = vbslq_f64(xs_negative_mask_u64x2, neg_two_f64x2, quadrant_f64x2);
|
|
506
|
+
float64x2_t quadrant_incremented_f64x2 = vaddq_f64(quadrant_f64x2, vdupq_n_f64(1.0));
|
|
507
|
+
quadrant_f64x2 = vbslq_f64(swap_mask_u64x2, quadrant_incremented_f64x2, quadrant_f64x2);
|
|
508
|
+
|
|
509
|
+
// Adjust for quadrant_f64x2: result += quadrant_f64x2 * π/2
|
|
510
|
+
results_f64x2 = vfmaq_f64(results_f64x2, quadrant_f64x2, half_pi_f64x2);
|
|
511
|
+
|
|
512
|
+
// Transfer sign from x and y by XOR with sign bits
|
|
513
|
+
uint64x2_t sign_mask_u64x2 = vreinterpretq_u64_f64(vdupq_n_f64(-0.0));
|
|
514
|
+
uint64x2_t xs_sign_u64x2 = vandq_u64(vreinterpretq_u64_f64(xs_inputs), sign_mask_u64x2);
|
|
515
|
+
uint64x2_t ys_sign_u64x2 = vandq_u64(vreinterpretq_u64_f64(ys_inputs), sign_mask_u64x2);
|
|
516
|
+
uint64x2_t result_bits_u64x2 = vreinterpretq_u64_f64(results_f64x2);
|
|
517
|
+
result_bits_u64x2 = veorq_u64(result_bits_u64x2, xs_sign_u64x2);
|
|
518
|
+
result_bits_u64x2 = veorq_u64(result_bits_u64x2, ys_sign_u64x2);
|
|
519
|
+
results_f64x2 = vreinterpretq_f64_u64(result_bits_u64x2);
|
|
520
|
+
|
|
521
|
+
return results_f64x2;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
NK_PUBLIC void nk_each_sin_f32_neon(nk_f32_t const *ins, nk_size_t n, nk_f32_t *outs) {
|
|
525
|
+
nk_size_t i = 0;
|
|
526
|
+
for (; i + 4 <= n; i += 4) {
|
|
527
|
+
float32x4_t angles_f32x4 = vld1q_f32(ins + i);
|
|
528
|
+
float32x4_t results_f32x4 = nk_sin_f32x4_neon_(angles_f32x4);
|
|
529
|
+
vst1q_f32(outs + i, results_f32x4);
|
|
530
|
+
}
|
|
531
|
+
if (i < n) {
|
|
532
|
+
nk_size_t remaining = n - i;
|
|
533
|
+
nk_b128_vec_t angles_vec;
|
|
534
|
+
nk_partial_load_b32x4_serial_(ins + i, &angles_vec, remaining);
|
|
535
|
+
nk_b128_vec_t results_vec;
|
|
536
|
+
results_vec.f32x4 = nk_sin_f32x4_neon_(angles_vec.f32x4);
|
|
537
|
+
nk_partial_store_b32x4_serial_(&results_vec, outs + i, remaining);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
NK_PUBLIC void nk_each_cos_f32_neon(nk_f32_t const *ins, nk_size_t n, nk_f32_t *outs) {
|
|
542
|
+
nk_size_t i = 0;
|
|
543
|
+
for (; i + 4 <= n; i += 4) {
|
|
544
|
+
float32x4_t angles_f32x4 = vld1q_f32(ins + i);
|
|
545
|
+
float32x4_t results_f32x4 = nk_cos_f32x4_neon_(angles_f32x4);
|
|
546
|
+
vst1q_f32(outs + i, results_f32x4);
|
|
547
|
+
}
|
|
548
|
+
if (i < n) {
|
|
549
|
+
nk_size_t remaining = n - i;
|
|
550
|
+
nk_b128_vec_t angles_vec;
|
|
551
|
+
nk_partial_load_b32x4_serial_(ins + i, &angles_vec, remaining);
|
|
552
|
+
nk_b128_vec_t results_vec;
|
|
553
|
+
results_vec.f32x4 = nk_cos_f32x4_neon_(angles_vec.f32x4);
|
|
554
|
+
nk_partial_store_b32x4_serial_(&results_vec, outs + i, remaining);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
NK_PUBLIC void nk_each_atan_f32_neon(nk_f32_t const *ins, nk_size_t n, nk_f32_t *outs) {
|
|
559
|
+
nk_size_t i = 0;
|
|
560
|
+
for (; i + 4 <= n; i += 4) {
|
|
561
|
+
float32x4_t values_f32x4 = vld1q_f32(ins + i);
|
|
562
|
+
float32x4_t results_f32x4 = nk_atan_f32x4_neon_(values_f32x4);
|
|
563
|
+
vst1q_f32(outs + i, results_f32x4);
|
|
564
|
+
}
|
|
565
|
+
if (i < n) {
|
|
566
|
+
nk_size_t remaining = n - i;
|
|
567
|
+
nk_b128_vec_t values_vec;
|
|
568
|
+
nk_partial_load_b32x4_serial_(ins + i, &values_vec, remaining);
|
|
569
|
+
nk_b128_vec_t results_vec;
|
|
570
|
+
results_vec.f32x4 = nk_atan_f32x4_neon_(values_vec.f32x4);
|
|
571
|
+
nk_partial_store_b32x4_serial_(&results_vec, outs + i, remaining);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
NK_PUBLIC void nk_each_sin_f64_neon(nk_f64_t const *ins, nk_size_t n, nk_f64_t *outs) {
|
|
576
|
+
nk_size_t i = 0;
|
|
577
|
+
for (; i + 2 <= n; i += 2) {
|
|
578
|
+
float64x2_t angles_f64x2 = vld1q_f64(ins + i);
|
|
579
|
+
float64x2_t results_f64x2 = nk_sin_f64x2_neon_(angles_f64x2);
|
|
580
|
+
vst1q_f64(outs + i, results_f64x2);
|
|
581
|
+
}
|
|
582
|
+
if (i < n) {
|
|
583
|
+
nk_size_t remaining = n - i;
|
|
584
|
+
nk_b128_vec_t angles_vec;
|
|
585
|
+
nk_partial_load_b64x2_serial_(ins + i, &angles_vec, remaining);
|
|
586
|
+
nk_b128_vec_t results_vec;
|
|
587
|
+
results_vec.f64x2 = nk_sin_f64x2_neon_(angles_vec.f64x2);
|
|
588
|
+
nk_partial_store_b64x2_serial_(&results_vec, outs + i, remaining);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
NK_PUBLIC void nk_each_cos_f64_neon(nk_f64_t const *ins, nk_size_t n, nk_f64_t *outs) {
|
|
593
|
+
nk_size_t i = 0;
|
|
594
|
+
for (; i + 2 <= n; i += 2) {
|
|
595
|
+
float64x2_t angles_f64x2 = vld1q_f64(ins + i);
|
|
596
|
+
float64x2_t results_f64x2 = nk_cos_f64x2_neon_(angles_f64x2);
|
|
597
|
+
vst1q_f64(outs + i, results_f64x2);
|
|
598
|
+
}
|
|
599
|
+
if (i < n) {
|
|
600
|
+
nk_size_t remaining = n - i;
|
|
601
|
+
nk_b128_vec_t angles_vec;
|
|
602
|
+
nk_partial_load_b64x2_serial_(ins + i, &angles_vec, remaining);
|
|
603
|
+
nk_b128_vec_t results_vec;
|
|
604
|
+
results_vec.f64x2 = nk_cos_f64x2_neon_(angles_vec.f64x2);
|
|
605
|
+
nk_partial_store_b64x2_serial_(&results_vec, outs + i, remaining);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
NK_PUBLIC void nk_each_atan_f64_neon(nk_f64_t const *ins, nk_size_t n, nk_f64_t *outs) {
|
|
610
|
+
nk_size_t i = 0;
|
|
611
|
+
for (; i + 2 <= n; i += 2) {
|
|
612
|
+
float64x2_t values_f64x2 = vld1q_f64(ins + i);
|
|
613
|
+
float64x2_t results_f64x2 = nk_atan_f64x2_neon_(values_f64x2);
|
|
614
|
+
vst1q_f64(outs + i, results_f64x2);
|
|
615
|
+
}
|
|
616
|
+
if (i < n) {
|
|
617
|
+
nk_size_t remaining = n - i;
|
|
618
|
+
nk_b128_vec_t values_vec;
|
|
619
|
+
nk_partial_load_b64x2_serial_(ins + i, &values_vec, remaining);
|
|
620
|
+
nk_b128_vec_t results_vec;
|
|
621
|
+
results_vec.f64x2 = nk_atan_f64x2_neon_(values_vec.f64x2);
|
|
622
|
+
nk_partial_store_b64x2_serial_(&results_vec, outs + i, remaining);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
#if defined(__clang__)
|
|
627
|
+
#pragma clang attribute pop
|
|
628
|
+
#elif defined(__GNUC__)
|
|
629
|
+
#pragma GCC pop_options
|
|
630
|
+
#endif
|
|
631
|
+
|
|
632
|
+
#if defined(__cplusplus)
|
|
633
|
+
} // extern "C"
|
|
634
|
+
#endif
|
|
635
|
+
|
|
636
|
+
#endif // NK_TARGET_NEON
|
|
637
|
+
#endif // NK_TARGET_ARM64_
|
|
638
|
+
#endif // NK_TRIGONOMETRY_NEON_H
|