usearch 2.26.1 → 2.26.2
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 +1 -1
- package/include/usearch/index.hpp +5 -1
- package/numkong/CITATION.cff +13 -9
- package/numkong/CONTRIBUTING.md +29 -24
- package/numkong/Cargo.toml +1 -1
- package/numkong/README.md +21 -7
- package/numkong/binding.gyp +47 -31
- package/numkong/build.rs +15 -5
- package/numkong/c/dispatch.h +0 -1
- package/numkong/c/parallel.c +139 -0
- package/numkong/c/parallel.h +47 -0
- package/numkong/cmake/toolchain-wasi.cmake +39 -5
- package/numkong/include/README.md +24 -17
- package/numkong/include/numkong/attention/sapphireamx.h +6 -6
- package/numkong/include/numkong/attention/sme.h +2 -2
- package/numkong/include/numkong/capabilities.h +2 -2
- package/numkong/include/numkong/cast/README.md +9 -7
- package/numkong/include/numkong/cast/loongsonasx.h +48 -40
- package/numkong/include/numkong/cast/serial.h +89 -11
- package/numkong/include/numkong/cast.h +3 -3
- package/numkong/include/numkong/curved/README.md +10 -10
- package/numkong/include/numkong/curved/neon.h +1 -0
- package/numkong/include/numkong/curved/neonbfdot.h +1 -0
- package/numkong/include/numkong/curved/smef64.h +1 -0
- package/numkong/include/numkong/dot/README.md +18 -18
- package/numkong/include/numkong/dot/alder.h +8 -8
- package/numkong/include/numkong/dot/haswell.h +8 -8
- package/numkong/include/numkong/dot/icelake.h +12 -12
- package/numkong/include/numkong/dot/loongsonasx.h +6 -6
- package/numkong/include/numkong/dot/neon.h +2 -1
- package/numkong/include/numkong/dot/neonbfdot.h +1 -0
- package/numkong/include/numkong/dot/neonfhm.h +1 -0
- package/numkong/include/numkong/dot/neonsdot.h +1 -0
- package/numkong/include/numkong/dot/powervsx.h +3 -3
- package/numkong/include/numkong/dot/serial.h +19 -6
- package/numkong/include/numkong/dot/skylake.h +4 -4
- package/numkong/include/numkong/dot/svehalf.h +1 -1
- package/numkong/include/numkong/dot/v128relaxed.h +24 -23
- package/numkong/include/numkong/dots/README.md +26 -26
- package/numkong/include/numkong/dots/genoa.h +3 -1
- package/numkong/include/numkong/dots/icelake.h +1 -0
- package/numkong/include/numkong/dots/powervsx.h +1 -1
- package/numkong/include/numkong/dots/serial.h +32 -33
- package/numkong/include/numkong/dots/sierra.h +4 -3
- package/numkong/include/numkong/each/README.md +5 -3
- package/numkong/include/numkong/each/sapphire.h +2 -0
- package/numkong/include/numkong/each/skylake.h +1 -0
- package/numkong/include/numkong/geospatial/README.md +6 -6
- package/numkong/include/numkong/geospatial/v128relaxed.h +1 -0
- package/numkong/include/numkong/maxsim/README.md +5 -5
- package/numkong/include/numkong/maxsim/genoa.h +4 -0
- package/numkong/include/numkong/maxsim/icelake.h +1 -0
- package/numkong/include/numkong/maxsim/serial.h +22 -9
- package/numkong/include/numkong/maxsim/sme.h +3 -2
- package/numkong/include/numkong/mesh/README.md +7 -4
- package/numkong/include/numkong/mesh/genoa.h +2 -2
- package/numkong/include/numkong/mesh/haswell.h +8 -8
- package/numkong/include/numkong/mesh/neon.h +6 -6
- package/numkong/include/numkong/mesh/neonbfdot.h +3 -2
- package/numkong/include/numkong/mesh/neonfhm.h +3 -2
- package/numkong/include/numkong/mesh/rvv.h +4 -4
- package/numkong/include/numkong/mesh/serial.h +17 -17
- package/numkong/include/numkong/mesh/skylake.h +4 -4
- package/numkong/include/numkong/mesh/v128relaxed.h +4 -4
- package/numkong/include/numkong/mesh.hpp +2 -2
- package/numkong/include/numkong/numkong.h +1 -1
- package/numkong/include/numkong/numkong.hpp +1 -1
- package/numkong/include/numkong/probability/README.md +17 -15
- package/numkong/include/numkong/probability/skylake.h +1 -1
- package/numkong/include/numkong/reduce/README.md +27 -21
- package/numkong/include/numkong/reduce/genoa.h +2 -1
- package/numkong/include/numkong/reduce/icelake.h +1 -0
- package/numkong/include/numkong/reduce/neon.h +1 -1
- package/numkong/include/numkong/reduce/serial.h +9 -9
- package/numkong/include/numkong/reduce/skylake.h +4 -4
- package/numkong/include/numkong/reduce.hpp +38 -0
- package/numkong/include/numkong/scalar/README.md +29 -28
- package/numkong/include/numkong/set/README.md +17 -14
- package/numkong/include/numkong/set/haswell.h +15 -16
- package/numkong/include/numkong/set/icelake.h +15 -16
- package/numkong/include/numkong/set/loongsonasx.h +12 -10
- package/numkong/include/numkong/set/neon.h +15 -19
- package/numkong/include/numkong/set/powervsx.h +15 -21
- package/numkong/include/numkong/set/serial.h +19 -20
- package/numkong/include/numkong/set/v128relaxed.h +10 -8
- package/numkong/include/numkong/sets/icelake.h +1 -0
- package/numkong/include/numkong/sparse/README.md +4 -4
- package/numkong/include/numkong/sparse/icelake.h +1 -0
- package/numkong/include/numkong/sparse/neon.h +1 -0
- package/numkong/include/numkong/sparse/serial.h +10 -3
- package/numkong/include/numkong/sparse/turin.h +1 -0
- package/numkong/include/numkong/spatial/README.md +25 -24
- package/numkong/include/numkong/spatial/alder.h +2 -1
- package/numkong/include/numkong/spatial/haswell.h +48 -40
- package/numkong/include/numkong/spatial/icelake.h +2 -1
- package/numkong/include/numkong/spatial/neon.h +54 -46
- package/numkong/include/numkong/spatial/neonbfdot.h +1 -1
- package/numkong/include/numkong/spatial/powervsx.h +54 -46
- package/numkong/include/numkong/spatial/serial.h +56 -46
- package/numkong/include/numkong/spatial/sierra.h +4 -3
- package/numkong/include/numkong/spatial/skylake.h +27 -22
- package/numkong/include/numkong/spatial/sve.h +6 -6
- package/numkong/include/numkong/spatial/svebfdot.h +1 -1
- package/numkong/include/numkong/spatial/svehalf.h +1 -1
- package/numkong/include/numkong/spatial/v128relaxed.h +36 -30
- package/numkong/include/numkong/spatials/README.md +15 -15
- package/numkong/include/numkong/spatials/genoa.h +3 -0
- package/numkong/include/numkong/spatials/graniteamx.h +2 -0
- package/numkong/include/numkong/spatials/icelake.h +1 -0
- package/numkong/include/numkong/spatials/sierra.h +1 -0
- package/numkong/include/numkong/tensor.hpp +236 -123
- package/numkong/include/numkong/trigonometry/README.md +4 -4
- package/numkong/include/numkong/trigonometry/serial.h +6 -6
- package/numkong/include/numkong/trigonometry/v128relaxed.h +1 -0
- package/numkong/include/numkong/types.hpp +46 -16
- package/numkong/include/numkong/vector.hpp +116 -23
- package/numkong/javascript/@numkong-darwin-arm64/package.json +1 -1
- package/numkong/javascript/@numkong-darwin-x64/package.json +1 -1
- package/numkong/javascript/@numkong-linux-arm64/package.json +1 -1
- package/numkong/javascript/@numkong-linux-x64/package.json +1 -1
- package/numkong/javascript/@numkong-win32-arm64/package.json +1 -1
- package/numkong/javascript/@numkong-win32-x64/package.json +1 -1
- package/numkong/javascript/README.md +18 -16
- package/numkong/javascript/numkong.c +70 -40
- package/numkong/package.json +8 -8
- package/numkong/rust/README.md +19 -9
- package/numkong/rust/cast.rs +52 -1
- package/numkong/rust/each.rs +480 -7
- package/numkong/rust/matrix.rs +877 -216
- package/numkong/rust/numkong.rs +12 -8
- package/numkong/rust/reduce.rs +433 -5
- package/numkong/rust/tensor.rs +450 -842
- package/numkong/rust/vector.rs +520 -101
- package/numkong/swift/README.md +5 -3
- package/numkong/test/README.md +4 -4
- package/numkong/test/test-wasi.mjs +17 -0
- package/numkong/test/test_each.cpp +30 -1
- package/numkong/test/test_each.py +74 -1
- package/numkong/test/test_reduce.cpp +51 -0
- package/numkong/test/test_tensor.cpp +2 -63
- package/numkong/test/test_tensor.py +93 -0
- package/package.json +1 -1
- 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/prebuilds/win32-x64/usearch.node +0 -0
|
@@ -670,13 +670,14 @@ nk_angular_e5m2_neon_cycle:
|
|
|
670
670
|
}
|
|
671
671
|
|
|
672
672
|
/** @brief Angular from_dot: computes 1 − dot × rsqrt(query_sumsq × target_sumsq) for 4 pairs in f64. */
|
|
673
|
-
NK_INTERNAL void nk_angular_through_f64_from_dot_neon_(nk_b256_vec_t
|
|
674
|
-
nk_b256_vec_t
|
|
675
|
-
|
|
676
|
-
float64x2_t
|
|
673
|
+
NK_INTERNAL void nk_angular_through_f64_from_dot_neon_(nk_b256_vec_t const *dots_vec, nk_f64_t query_sumsq,
|
|
674
|
+
nk_b256_vec_t const *target_sumsqs_vec,
|
|
675
|
+
nk_b256_vec_t *result_vec) {
|
|
676
|
+
float64x2_t dots_ab_f64x2 = dots_vec->f64x2s[0];
|
|
677
|
+
float64x2_t dots_cd_f64x2 = dots_vec->f64x2s[1];
|
|
677
678
|
float64x2_t query_sumsq_f64x2 = vdupq_n_f64(query_sumsq);
|
|
678
|
-
float64x2_t target_sumsqs_ab_f64x2 =
|
|
679
|
-
float64x2_t target_sumsqs_cd_f64x2 =
|
|
679
|
+
float64x2_t target_sumsqs_ab_f64x2 = target_sumsqs_vec->f64x2s[0];
|
|
680
|
+
float64x2_t target_sumsqs_cd_f64x2 = target_sumsqs_vec->f64x2s[1];
|
|
680
681
|
|
|
681
682
|
// products = query_sumsq * target_sumsq
|
|
682
683
|
float64x2_t products_ab_f64x2 = vmulq_f64(query_sumsq_f64x2, target_sumsqs_ab_f64x2);
|
|
@@ -723,18 +724,19 @@ NK_INTERNAL void nk_angular_through_f64_from_dot_neon_(nk_b256_vec_t dots, nk_f6
|
|
|
723
724
|
result_ab_f64x2 = vbslq_f64(prod_zero_dot_nonzero_ab_u64x2, ones_f64x2, result_ab_f64x2);
|
|
724
725
|
result_cd_f64x2 = vbslq_f64(prod_zero_dot_nonzero_cd_u64x2, ones_f64x2, result_cd_f64x2);
|
|
725
726
|
|
|
726
|
-
|
|
727
|
-
|
|
727
|
+
result_vec->f64x2s[0] = result_ab_f64x2;
|
|
728
|
+
result_vec->f64x2s[1] = result_cd_f64x2;
|
|
728
729
|
}
|
|
729
730
|
|
|
730
731
|
/** @brief Euclidean from_dot: computes √(query_sumsq + target_sumsq − 2 × dot) for 4 pairs in f64. */
|
|
731
|
-
NK_INTERNAL void nk_euclidean_through_f64_from_dot_neon_(nk_b256_vec_t
|
|
732
|
-
nk_b256_vec_t
|
|
733
|
-
|
|
734
|
-
float64x2_t
|
|
732
|
+
NK_INTERNAL void nk_euclidean_through_f64_from_dot_neon_(nk_b256_vec_t const *dots_vec, nk_f64_t query_sumsq,
|
|
733
|
+
nk_b256_vec_t const *target_sumsqs_vec,
|
|
734
|
+
nk_b256_vec_t *result_vec) {
|
|
735
|
+
float64x2_t dots_ab_f64x2 = dots_vec->f64x2s[0];
|
|
736
|
+
float64x2_t dots_cd_f64x2 = dots_vec->f64x2s[1];
|
|
735
737
|
float64x2_t query_sumsq_f64x2 = vdupq_n_f64(query_sumsq);
|
|
736
|
-
float64x2_t target_sumsqs_ab_f64x2 =
|
|
737
|
-
float64x2_t target_sumsqs_cd_f64x2 =
|
|
738
|
+
float64x2_t target_sumsqs_ab_f64x2 = target_sumsqs_vec->f64x2s[0];
|
|
739
|
+
float64x2_t target_sumsqs_cd_f64x2 = target_sumsqs_vec->f64x2s[1];
|
|
738
740
|
|
|
739
741
|
// dist_sq = query_sumsq + target_sumsq − 2 × dot
|
|
740
742
|
float64x2_t neg_two_f64x2 = vdupq_n_f64(-2.0);
|
|
@@ -750,16 +752,17 @@ NK_INTERNAL void nk_euclidean_through_f64_from_dot_neon_(nk_b256_vec_t dots, nk_
|
|
|
750
752
|
float64x2_t dist_ab_f64x2 = vsqrtq_f64(dist_sq_ab_f64x2);
|
|
751
753
|
float64x2_t dist_cd_f64x2 = vsqrtq_f64(dist_sq_cd_f64x2);
|
|
752
754
|
|
|
753
|
-
|
|
754
|
-
|
|
755
|
+
result_vec->f64x2s[0] = dist_ab_f64x2;
|
|
756
|
+
result_vec->f64x2s[1] = dist_cd_f64x2;
|
|
755
757
|
}
|
|
756
758
|
|
|
757
759
|
/** @brief Angular from_dot: computes 1 − dot × rsqrt(query_sumsq × target_sumsq) for 4 pairs in f32. */
|
|
758
|
-
NK_INTERNAL void nk_angular_through_f32_from_dot_neon_(nk_b128_vec_t
|
|
759
|
-
nk_b128_vec_t
|
|
760
|
-
|
|
760
|
+
NK_INTERNAL void nk_angular_through_f32_from_dot_neon_(nk_b128_vec_t const *dots_vec, nk_f32_t query_sumsq,
|
|
761
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
762
|
+
nk_b128_vec_t *result_vec) {
|
|
763
|
+
float32x4_t dots_f32x4 = dots_vec->f32x4;
|
|
761
764
|
float32x4_t query_sumsq_f32x4 = vdupq_n_f32(query_sumsq);
|
|
762
|
-
float32x4_t products_f32x4 = vmulq_f32(query_sumsq_f32x4,
|
|
765
|
+
float32x4_t products_f32x4 = vmulq_f32(query_sumsq_f32x4, target_sumsqs_vec->f32x4);
|
|
763
766
|
|
|
764
767
|
// rsqrt with Newton-Raphson refinement (2 iterations)
|
|
765
768
|
float32x4_t rsqrt_f32x4 = vrsqrteq_f32(products_f32x4);
|
|
@@ -768,66 +771,71 @@ NK_INTERNAL void nk_angular_through_f32_from_dot_neon_(nk_b128_vec_t dots, nk_f3
|
|
|
768
771
|
|
|
769
772
|
float32x4_t normalized_f32x4 = vmulq_f32(dots_f32x4, rsqrt_f32x4);
|
|
770
773
|
float32x4_t angular_f32x4 = vsubq_f32(vdupq_n_f32(1.0f), normalized_f32x4);
|
|
771
|
-
|
|
774
|
+
result_vec->f32x4 = vmaxq_f32(angular_f32x4, vdupq_n_f32(0.0f));
|
|
772
775
|
}
|
|
773
776
|
|
|
774
777
|
/** @brief Euclidean from_dot: computes √(query_sumsq + target_sumsq − 2 × dot) for 4 pairs in f32. */
|
|
775
|
-
NK_INTERNAL void nk_euclidean_through_f32_from_dot_neon_(nk_b128_vec_t
|
|
776
|
-
nk_b128_vec_t
|
|
777
|
-
|
|
778
|
+
NK_INTERNAL void nk_euclidean_through_f32_from_dot_neon_(nk_b128_vec_t const *dots_vec, nk_f32_t query_sumsq,
|
|
779
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
780
|
+
nk_b128_vec_t *result_vec) {
|
|
781
|
+
float32x4_t dots_f32x4 = dots_vec->f32x4;
|
|
778
782
|
float32x4_t query_sumsq_f32x4 = vdupq_n_f32(query_sumsq);
|
|
779
|
-
float32x4_t sum_sq_f32x4 = vaddq_f32(query_sumsq_f32x4,
|
|
783
|
+
float32x4_t sum_sq_f32x4 = vaddq_f32(query_sumsq_f32x4, target_sumsqs_vec->f32x4);
|
|
780
784
|
// dist_sq = sum_sq − 2 × dot
|
|
781
785
|
float32x4_t dist_sq_f32x4 = vfmsq_f32(sum_sq_f32x4, vdupq_n_f32(2.0f), dots_f32x4);
|
|
782
786
|
// Clamp and sqrt
|
|
783
787
|
dist_sq_f32x4 = vmaxq_f32(dist_sq_f32x4, vdupq_n_f32(0.0f));
|
|
784
|
-
|
|
788
|
+
result_vec->f32x4 = vsqrtq_f32(dist_sq_f32x4);
|
|
785
789
|
}
|
|
786
790
|
|
|
787
791
|
/** @brief Angular from_dot for i32 accumulators: cast to f32, rsqrt+NR, clamp. 4 pairs. */
|
|
788
|
-
NK_INTERNAL void nk_angular_through_i32_from_dot_neon_(nk_b128_vec_t
|
|
789
|
-
nk_b128_vec_t
|
|
790
|
-
|
|
792
|
+
NK_INTERNAL void nk_angular_through_i32_from_dot_neon_(nk_b128_vec_t const *dots_vec, nk_i32_t query_sumsq,
|
|
793
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
794
|
+
nk_b128_vec_t *result_vec) {
|
|
795
|
+
float32x4_t dots_f32x4 = vcvtq_f32_s32(dots_vec->i32x4);
|
|
791
796
|
float32x4_t query_sumsq_f32x4 = vdupq_n_f32((nk_f32_t)query_sumsq);
|
|
792
|
-
float32x4_t products_f32x4 = vmulq_f32(query_sumsq_f32x4, vcvtq_f32_s32(
|
|
797
|
+
float32x4_t products_f32x4 = vmulq_f32(query_sumsq_f32x4, vcvtq_f32_s32(target_sumsqs_vec->i32x4));
|
|
793
798
|
float32x4_t rsqrt_f32x4 = nk_rsqrt_f32x4_neon_(products_f32x4);
|
|
794
799
|
float32x4_t normalized_f32x4 = vmulq_f32(dots_f32x4, rsqrt_f32x4);
|
|
795
800
|
float32x4_t angular_f32x4 = vsubq_f32(vdupq_n_f32(1.0f), normalized_f32x4);
|
|
796
|
-
|
|
801
|
+
result_vec->f32x4 = vmaxq_f32(angular_f32x4, vdupq_n_f32(0.0f));
|
|
797
802
|
}
|
|
798
803
|
|
|
799
804
|
/** @brief Euclidean from_dot for i32 accumulators: cast to f32, then √(a² + b² − 2ab). 4 pairs. */
|
|
800
|
-
NK_INTERNAL void nk_euclidean_through_i32_from_dot_neon_(nk_b128_vec_t
|
|
801
|
-
nk_b128_vec_t
|
|
802
|
-
|
|
805
|
+
NK_INTERNAL void nk_euclidean_through_i32_from_dot_neon_(nk_b128_vec_t const *dots_vec, nk_i32_t query_sumsq,
|
|
806
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
807
|
+
nk_b128_vec_t *result_vec) {
|
|
808
|
+
float32x4_t dots_f32x4 = vcvtq_f32_s32(dots_vec->i32x4);
|
|
803
809
|
float32x4_t query_sumsq_f32x4 = vdupq_n_f32((nk_f32_t)query_sumsq);
|
|
804
|
-
float32x4_t sum_sq_f32x4 = vaddq_f32(query_sumsq_f32x4, vcvtq_f32_s32(
|
|
810
|
+
float32x4_t sum_sq_f32x4 = vaddq_f32(query_sumsq_f32x4, vcvtq_f32_s32(target_sumsqs_vec->i32x4));
|
|
805
811
|
float32x4_t dist_sq_f32x4 = vfmsq_f32(sum_sq_f32x4, vdupq_n_f32(2.0f), dots_f32x4);
|
|
806
812
|
dist_sq_f32x4 = vmaxq_f32(dist_sq_f32x4, vdupq_n_f32(0.0f));
|
|
807
|
-
|
|
813
|
+
result_vec->f32x4 = vsqrtq_f32(dist_sq_f32x4);
|
|
808
814
|
}
|
|
809
815
|
|
|
810
816
|
/** @brief Angular from_dot for u32 accumulators: cast to f32, rsqrt+NR, clamp. 4 pairs. */
|
|
811
|
-
NK_INTERNAL void nk_angular_through_u32_from_dot_neon_(nk_b128_vec_t
|
|
812
|
-
nk_b128_vec_t
|
|
813
|
-
|
|
817
|
+
NK_INTERNAL void nk_angular_through_u32_from_dot_neon_(nk_b128_vec_t const *dots_vec, nk_u32_t query_sumsq,
|
|
818
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
819
|
+
nk_b128_vec_t *result_vec) {
|
|
820
|
+
float32x4_t dots_f32x4 = vcvtq_f32_u32(dots_vec->u32x4);
|
|
814
821
|
float32x4_t query_sumsq_f32x4 = vdupq_n_f32((nk_f32_t)query_sumsq);
|
|
815
|
-
float32x4_t products_f32x4 = vmulq_f32(query_sumsq_f32x4, vcvtq_f32_u32(
|
|
822
|
+
float32x4_t products_f32x4 = vmulq_f32(query_sumsq_f32x4, vcvtq_f32_u32(target_sumsqs_vec->u32x4));
|
|
816
823
|
float32x4_t rsqrt_f32x4 = nk_rsqrt_f32x4_neon_(products_f32x4);
|
|
817
824
|
float32x4_t normalized_f32x4 = vmulq_f32(dots_f32x4, rsqrt_f32x4);
|
|
818
825
|
float32x4_t angular_f32x4 = vsubq_f32(vdupq_n_f32(1.0f), normalized_f32x4);
|
|
819
|
-
|
|
826
|
+
result_vec->f32x4 = vmaxq_f32(angular_f32x4, vdupq_n_f32(0.0f));
|
|
820
827
|
}
|
|
821
828
|
|
|
822
829
|
/** @brief Euclidean from_dot for u32 accumulators: cast to f32, then √(a² + b² − 2ab). 4 pairs. */
|
|
823
|
-
NK_INTERNAL void nk_euclidean_through_u32_from_dot_neon_(nk_b128_vec_t
|
|
824
|
-
nk_b128_vec_t
|
|
825
|
-
|
|
830
|
+
NK_INTERNAL void nk_euclidean_through_u32_from_dot_neon_(nk_b128_vec_t const *dots_vec, nk_u32_t query_sumsq,
|
|
831
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
832
|
+
nk_b128_vec_t *result_vec) {
|
|
833
|
+
float32x4_t dots_f32x4 = vcvtq_f32_u32(dots_vec->u32x4);
|
|
826
834
|
float32x4_t query_sumsq_f32x4 = vdupq_n_f32((nk_f32_t)query_sumsq);
|
|
827
|
-
float32x4_t sum_sq_f32x4 = vaddq_f32(query_sumsq_f32x4, vcvtq_f32_u32(
|
|
835
|
+
float32x4_t sum_sq_f32x4 = vaddq_f32(query_sumsq_f32x4, vcvtq_f32_u32(target_sumsqs_vec->u32x4));
|
|
828
836
|
float32x4_t dist_sq_f32x4 = vfmsq_f32(sum_sq_f32x4, vdupq_n_f32(2.0f), dots_f32x4);
|
|
829
837
|
dist_sq_f32x4 = vmaxq_f32(dist_sq_f32x4, vdupq_n_f32(0.0f));
|
|
830
|
-
|
|
838
|
+
result_vec->f32x4 = vsqrtq_f32(dist_sq_f32x4);
|
|
831
839
|
}
|
|
832
840
|
|
|
833
841
|
#if defined(__clang__)
|
|
@@ -49,7 +49,7 @@ extern "C" {
|
|
|
49
49
|
|
|
50
50
|
NK_PUBLIC void nk_angular_bf16_neonbfdot(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result) {
|
|
51
51
|
|
|
52
|
-
// Similar to `
|
|
52
|
+
// Similar to `nk_angular_i8_neonsdot`, we can use the `BFMMLA` instruction through
|
|
53
53
|
// the `vbfmmlaq_f32` intrinsic to compute matrix products and later drop 1/4 of values.
|
|
54
54
|
// The only difference is that `zip` isn't provided for `bf16` and we need to reinterpret back
|
|
55
55
|
// and forth before zipping. Same as with integers, on modern Arm CPUs, this "smart"
|
|
@@ -587,13 +587,14 @@ nk_angular_u8_powervsx_cycle:
|
|
|
587
587
|
}
|
|
588
588
|
|
|
589
589
|
/** @brief Angular from_dot: computes 1 − dot × rsqrt(query_sumsq × target_sumsq) for 4 pairs in f64. */
|
|
590
|
-
NK_INTERNAL void nk_angular_through_f64_from_dot_powervsx_(nk_b256_vec_t
|
|
591
|
-
nk_b256_vec_t
|
|
592
|
-
|
|
593
|
-
nk_vf64x2_t
|
|
590
|
+
NK_INTERNAL void nk_angular_through_f64_from_dot_powervsx_(nk_b256_vec_t const *dots_vec, nk_f64_t query_sumsq,
|
|
591
|
+
nk_b256_vec_t const *target_sumsqs_vec,
|
|
592
|
+
nk_b256_vec_t *result_vec) {
|
|
593
|
+
nk_vf64x2_t dots_ab_f64x2 = dots_vec->vf64x2s[0];
|
|
594
|
+
nk_vf64x2_t dots_cd_f64x2 = dots_vec->vf64x2s[1];
|
|
594
595
|
nk_vf64x2_t query_f64x2 = vec_splats(query_sumsq);
|
|
595
|
-
nk_vf64x2_t targets_ab_f64x2 =
|
|
596
|
-
nk_vf64x2_t targets_cd_f64x2 =
|
|
596
|
+
nk_vf64x2_t targets_ab_f64x2 = target_sumsqs_vec->vf64x2s[0];
|
|
597
|
+
nk_vf64x2_t targets_cd_f64x2 = target_sumsqs_vec->vf64x2s[1];
|
|
597
598
|
|
|
598
599
|
nk_vf64x2_t products_ab_f64x2 = vec_mul(query_f64x2, targets_ab_f64x2);
|
|
599
600
|
nk_vf64x2_t products_cd_f64x2 = vec_mul(query_f64x2, targets_cd_f64x2);
|
|
@@ -616,109 +617,116 @@ NK_INTERNAL void nk_angular_through_f64_from_dot_powervsx_(nk_b256_vec_t dots, n
|
|
|
616
617
|
result_cd_f64x2 = vec_sel(result_cd_f64x2, zeros_f64x2, vec_and(prodzero_cd_u64x2, dotzero_cd_u64x2));
|
|
617
618
|
result_cd_f64x2 = vec_sel(result_cd_f64x2, ones_f64x2, vec_andc(prodzero_cd_u64x2, dotzero_cd_u64x2));
|
|
618
619
|
|
|
619
|
-
|
|
620
|
-
|
|
620
|
+
result_vec->vf64x2s[0] = result_ab_f64x2;
|
|
621
|
+
result_vec->vf64x2s[1] = result_cd_f64x2;
|
|
621
622
|
}
|
|
622
623
|
|
|
623
624
|
/** @brief Euclidean from_dot: computes √(query_sumsq + target_sumsq − 2×dot) for 4 pairs in f64. */
|
|
624
|
-
NK_INTERNAL void nk_euclidean_through_f64_from_dot_powervsx_(nk_b256_vec_t
|
|
625
|
-
nk_b256_vec_t
|
|
625
|
+
NK_INTERNAL void nk_euclidean_through_f64_from_dot_powervsx_(nk_b256_vec_t const *dots_vec, nk_f64_t query_sumsq,
|
|
626
|
+
nk_b256_vec_t const *target_sumsqs_vec,
|
|
627
|
+
nk_b256_vec_t *result_vec) {
|
|
626
628
|
nk_vf64x2_t query_f64x2 = vec_splats(query_sumsq);
|
|
627
629
|
nk_vf64x2_t neg_two_f64x2 = vec_splats(-2.0);
|
|
628
630
|
nk_vf64x2_t zeros_f64x2 = vec_splats(0.0);
|
|
629
631
|
|
|
630
|
-
nk_vf64x2_t sum_sq_ab_f64x2 = vec_add(query_f64x2,
|
|
631
|
-
nk_vf64x2_t sum_sq_cd_f64x2 = vec_add(query_f64x2,
|
|
632
|
-
nk_vf64x2_t dist_sq_ab_f64x2 = vec_max(vec_madd(neg_two_f64x2,
|
|
633
|
-
nk_vf64x2_t dist_sq_cd_f64x2 = vec_max(vec_madd(neg_two_f64x2,
|
|
632
|
+
nk_vf64x2_t sum_sq_ab_f64x2 = vec_add(query_f64x2, target_sumsqs_vec->vf64x2s[0]);
|
|
633
|
+
nk_vf64x2_t sum_sq_cd_f64x2 = vec_add(query_f64x2, target_sumsqs_vec->vf64x2s[1]);
|
|
634
|
+
nk_vf64x2_t dist_sq_ab_f64x2 = vec_max(vec_madd(neg_two_f64x2, dots_vec->vf64x2s[0], sum_sq_ab_f64x2), zeros_f64x2);
|
|
635
|
+
nk_vf64x2_t dist_sq_cd_f64x2 = vec_max(vec_madd(neg_two_f64x2, dots_vec->vf64x2s[1], sum_sq_cd_f64x2), zeros_f64x2);
|
|
634
636
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
+
result_vec->vf64x2s[0] = vec_sqrt(dist_sq_ab_f64x2);
|
|
638
|
+
result_vec->vf64x2s[1] = vec_sqrt(dist_sq_cd_f64x2);
|
|
637
639
|
}
|
|
638
640
|
|
|
639
641
|
/** @brief Angular from_dot: computes 1 − dot × rsqrt(query_sumsq × target_sumsq) for 4 pairs in f32. */
|
|
640
|
-
NK_INTERNAL void nk_angular_through_f32_from_dot_powervsx_(nk_b128_vec_t
|
|
641
|
-
nk_b128_vec_t
|
|
642
|
-
|
|
642
|
+
NK_INTERNAL void nk_angular_through_f32_from_dot_powervsx_(nk_b128_vec_t const *dots_vec, nk_f32_t query_sumsq,
|
|
643
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
644
|
+
nk_b128_vec_t *result_vec) {
|
|
645
|
+
nk_vf32x4_t dots_f32x4 = dots_vec->vf32x4;
|
|
643
646
|
nk_vf32x4_t query_f32x4 = vec_splats(query_sumsq);
|
|
644
|
-
nk_vf32x4_t products_f32x4 = vec_mul(query_f32x4,
|
|
647
|
+
nk_vf32x4_t products_f32x4 = vec_mul(query_f32x4, target_sumsqs_vec->vf32x4);
|
|
645
648
|
nk_vf32x4_t rsqrt_f32x4 = nk_rsqrt_f32x4_powervsx_(products_f32x4);
|
|
646
649
|
nk_vf32x4_t normalized_f32x4 = vec_mul(dots_f32x4, rsqrt_f32x4);
|
|
647
650
|
nk_vf32x4_t angular_f32x4 = vec_sub(vec_splats(1.0f), normalized_f32x4);
|
|
648
651
|
nk_vf32x4_t result_f32x4 = vec_max(angular_f32x4, vec_splats(0.0f));
|
|
649
|
-
|
|
652
|
+
result_vec->vf32x4 = result_f32x4;
|
|
650
653
|
}
|
|
651
654
|
|
|
652
655
|
/** @brief Euclidean from_dot: computes √(query_sumsq + target_sumsq − 2×dot) for 4 pairs in f32. */
|
|
653
|
-
NK_INTERNAL void nk_euclidean_through_f32_from_dot_powervsx_(nk_b128_vec_t
|
|
654
|
-
nk_b128_vec_t
|
|
655
|
-
|
|
656
|
+
NK_INTERNAL void nk_euclidean_through_f32_from_dot_powervsx_(nk_b128_vec_t const *dots_vec, nk_f32_t query_sumsq,
|
|
657
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
658
|
+
nk_b128_vec_t *result_vec) {
|
|
659
|
+
nk_vf32x4_t dots_f32x4 = dots_vec->vf32x4;
|
|
656
660
|
nk_vf32x4_t query_f32x4 = vec_splats(query_sumsq);
|
|
657
|
-
nk_vf32x4_t sum_sq_f32x4 = vec_add(query_f32x4,
|
|
661
|
+
nk_vf32x4_t sum_sq_f32x4 = vec_add(query_f32x4, target_sumsqs_vec->vf32x4);
|
|
658
662
|
// dist_sq = sum_sq − 2 × dot
|
|
659
663
|
nk_vf32x4_t dist_sq_f32x4 = vec_madd(vec_splats(-2.0f), dots_f32x4, sum_sq_f32x4);
|
|
660
664
|
// Clamp and sqrt
|
|
661
665
|
dist_sq_f32x4 = vec_max(dist_sq_f32x4, vec_splats(0.0f));
|
|
662
666
|
nk_vf32x4_t dist_f32x4 = vec_sqrt(dist_sq_f32x4);
|
|
663
|
-
|
|
667
|
+
result_vec->vf32x4 = dist_f32x4;
|
|
664
668
|
}
|
|
665
669
|
|
|
666
670
|
/** @brief Angular from_dot for i32 accumulators: cast to f32, rsqrt+NR, clamp. 4 pairs. */
|
|
667
|
-
NK_INTERNAL void nk_angular_through_i32_from_dot_powervsx_(nk_b128_vec_t
|
|
668
|
-
nk_b128_vec_t
|
|
669
|
-
|
|
671
|
+
NK_INTERNAL void nk_angular_through_i32_from_dot_powervsx_(nk_b128_vec_t const *dots_vec, nk_i32_t query_sumsq,
|
|
672
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
673
|
+
nk_b128_vec_t *result_vec) {
|
|
674
|
+
nk_vi32x4_t dots_i32x4 = dots_vec->vi32x4;
|
|
670
675
|
nk_vf32x4_t dots_f32x4 = vec_ctf(dots_i32x4, 0);
|
|
671
676
|
nk_vf32x4_t query_f32x4 = vec_splats((nk_f32_t)query_sumsq);
|
|
672
|
-
nk_vi32x4_t targets_i32x4 =
|
|
677
|
+
nk_vi32x4_t targets_i32x4 = target_sumsqs_vec->vi32x4;
|
|
673
678
|
nk_vf32x4_t products_f32x4 = vec_mul(query_f32x4, vec_ctf(targets_i32x4, 0));
|
|
674
679
|
nk_vf32x4_t rsqrt_f32x4 = nk_rsqrt_f32x4_powervsx_(products_f32x4);
|
|
675
680
|
nk_vf32x4_t normalized_f32x4 = vec_mul(dots_f32x4, rsqrt_f32x4);
|
|
676
681
|
nk_vf32x4_t angular_f32x4 = vec_sub(vec_splats(1.0f), normalized_f32x4);
|
|
677
682
|
nk_vf32x4_t result_f32x4 = vec_max(angular_f32x4, vec_splats(0.0f));
|
|
678
|
-
|
|
683
|
+
result_vec->vf32x4 = result_f32x4;
|
|
679
684
|
}
|
|
680
685
|
|
|
681
686
|
/** @brief Euclidean from_dot for i32 accumulators: cast to f32, then √(a² + b² − 2ab). 4 pairs. */
|
|
682
|
-
NK_INTERNAL void nk_euclidean_through_i32_from_dot_powervsx_(nk_b128_vec_t
|
|
683
|
-
nk_b128_vec_t
|
|
684
|
-
|
|
687
|
+
NK_INTERNAL void nk_euclidean_through_i32_from_dot_powervsx_(nk_b128_vec_t const *dots_vec, nk_i32_t query_sumsq,
|
|
688
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
689
|
+
nk_b128_vec_t *result_vec) {
|
|
690
|
+
nk_vi32x4_t dots_i32x4 = dots_vec->vi32x4;
|
|
685
691
|
nk_vf32x4_t dots_f32x4 = vec_ctf(dots_i32x4, 0);
|
|
686
692
|
nk_vf32x4_t query_f32x4 = vec_splats((nk_f32_t)query_sumsq);
|
|
687
|
-
nk_vi32x4_t targets_i32x4 =
|
|
693
|
+
nk_vi32x4_t targets_i32x4 = target_sumsqs_vec->vi32x4;
|
|
688
694
|
nk_vf32x4_t sum_sq_f32x4 = vec_add(query_f32x4, vec_ctf(targets_i32x4, 0));
|
|
689
695
|
nk_vf32x4_t dist_sq_f32x4 = vec_madd(vec_splats(-2.0f), dots_f32x4, sum_sq_f32x4);
|
|
690
696
|
dist_sq_f32x4 = vec_max(dist_sq_f32x4, vec_splats(0.0f));
|
|
691
697
|
nk_vf32x4_t dist_f32x4 = vec_sqrt(dist_sq_f32x4);
|
|
692
|
-
|
|
698
|
+
result_vec->vf32x4 = dist_f32x4;
|
|
693
699
|
}
|
|
694
700
|
|
|
695
701
|
/** @brief Angular from_dot for u32 accumulators: cast to f32, rsqrt+NR, clamp. 4 pairs. */
|
|
696
|
-
NK_INTERNAL void nk_angular_through_u32_from_dot_powervsx_(nk_b128_vec_t
|
|
697
|
-
nk_b128_vec_t
|
|
698
|
-
|
|
702
|
+
NK_INTERNAL void nk_angular_through_u32_from_dot_powervsx_(nk_b128_vec_t const *dots_vec, nk_u32_t query_sumsq,
|
|
703
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
704
|
+
nk_b128_vec_t *result_vec) {
|
|
705
|
+
nk_vu32x4_t dots_u32x4 = dots_vec->vu32x4;
|
|
699
706
|
nk_vf32x4_t dots_f32x4 = vec_ctf(dots_u32x4, 0);
|
|
700
707
|
nk_vf32x4_t query_f32x4 = vec_splats((nk_f32_t)query_sumsq);
|
|
701
|
-
nk_vu32x4_t targets_u32x4 =
|
|
708
|
+
nk_vu32x4_t targets_u32x4 = target_sumsqs_vec->vu32x4;
|
|
702
709
|
nk_vf32x4_t products_f32x4 = vec_mul(query_f32x4, vec_ctf(targets_u32x4, 0));
|
|
703
710
|
nk_vf32x4_t rsqrt_f32x4 = nk_rsqrt_f32x4_powervsx_(products_f32x4);
|
|
704
711
|
nk_vf32x4_t normalized_f32x4 = vec_mul(dots_f32x4, rsqrt_f32x4);
|
|
705
712
|
nk_vf32x4_t angular_f32x4 = vec_sub(vec_splats(1.0f), normalized_f32x4);
|
|
706
713
|
nk_vf32x4_t result_f32x4 = vec_max(angular_f32x4, vec_splats(0.0f));
|
|
707
|
-
|
|
714
|
+
result_vec->vf32x4 = result_f32x4;
|
|
708
715
|
}
|
|
709
716
|
|
|
710
717
|
/** @brief Euclidean from_dot for u32 accumulators: cast to f32, then √(a² + b² − 2ab). 4 pairs. */
|
|
711
|
-
NK_INTERNAL void nk_euclidean_through_u32_from_dot_powervsx_(nk_b128_vec_t
|
|
712
|
-
nk_b128_vec_t
|
|
713
|
-
|
|
718
|
+
NK_INTERNAL void nk_euclidean_through_u32_from_dot_powervsx_(nk_b128_vec_t const *dots_vec, nk_u32_t query_sumsq,
|
|
719
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
720
|
+
nk_b128_vec_t *result_vec) {
|
|
721
|
+
nk_vu32x4_t dots_u32x4 = dots_vec->vu32x4;
|
|
714
722
|
nk_vf32x4_t dots_f32x4 = vec_ctf(dots_u32x4, 0);
|
|
715
723
|
nk_vf32x4_t query_f32x4 = vec_splats((nk_f32_t)query_sumsq);
|
|
716
|
-
nk_vu32x4_t targets_u32x4 =
|
|
724
|
+
nk_vu32x4_t targets_u32x4 = target_sumsqs_vec->vu32x4;
|
|
717
725
|
nk_vf32x4_t sum_sq_f32x4 = vec_add(query_f32x4, vec_ctf(targets_u32x4, 0));
|
|
718
726
|
nk_vf32x4_t dist_sq_f32x4 = vec_madd(vec_splats(-2.0f), dots_f32x4, sum_sq_f32x4);
|
|
719
727
|
dist_sq_f32x4 = vec_max(dist_sq_f32x4, vec_splats(0.0f));
|
|
720
728
|
nk_vf32x4_t dist_f32x4 = vec_sqrt(dist_sq_f32x4);
|
|
721
|
-
|
|
729
|
+
result_vec->vf32x4 = dist_f32x4;
|
|
722
730
|
}
|
|
723
731
|
|
|
724
732
|
#pragma endregion I8 and U8 Integers
|
|
@@ -253,108 +253,118 @@ NK_PUBLIC void nk_angular_u4_serial(nk_u4x2_t const *a, nk_u4x2_t const *b, nk_s
|
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
+
#if defined(__clang__)
|
|
257
|
+
#pragma clang attribute pop
|
|
258
|
+
#elif defined(__GNUC__)
|
|
259
|
+
#pragma GCC pop_options
|
|
260
|
+
#endif
|
|
261
|
+
|
|
256
262
|
/** @brief Angular from_dot: computes 1 − dot × rsqrt(query_sumsq × target_sumsq) for 4 pairs (serial). */
|
|
257
|
-
NK_INTERNAL void nk_angular_through_f32_from_dot_serial_(nk_b128_vec_t
|
|
258
|
-
nk_b128_vec_t
|
|
263
|
+
NK_INTERNAL void nk_angular_through_f32_from_dot_serial_(nk_b128_vec_t const *dots_vec, nk_f32_t query_sumsq,
|
|
264
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
265
|
+
nk_b128_vec_t *result_vec) {
|
|
259
266
|
for (int i = 0; i < 4; ++i) {
|
|
260
|
-
nk_f32_t product = query_sumsq *
|
|
267
|
+
nk_f32_t product = query_sumsq * target_sumsqs_vec->f32s[i];
|
|
261
268
|
if (product > 0) {
|
|
262
269
|
nk_f32_t rsqrt_val = nk_f32_rsqrt_serial(product);
|
|
263
|
-
nk_f32_t normalized =
|
|
270
|
+
nk_f32_t normalized = dots_vec->f32s[i] * rsqrt_val;
|
|
264
271
|
nk_f32_t result = 1.0f - normalized;
|
|
265
|
-
|
|
272
|
+
result_vec->f32s[i] = result > 0 ? result : 0;
|
|
266
273
|
}
|
|
267
|
-
else {
|
|
274
|
+
else { result_vec->f32s[i] = (dots_vec->f32s[i] == 0) ? 0.0f : 1.0f; }
|
|
268
275
|
}
|
|
269
276
|
}
|
|
270
277
|
|
|
271
278
|
/** @brief Euclidean from_dot: computes √(query_sumsq + target_sumsq − 2 × dot) for 4 pairs (serial). */
|
|
272
|
-
NK_INTERNAL void nk_euclidean_through_f32_from_dot_serial_(nk_b128_vec_t
|
|
273
|
-
nk_b128_vec_t
|
|
279
|
+
NK_INTERNAL void nk_euclidean_through_f32_from_dot_serial_(nk_b128_vec_t const *dots_vec, nk_f32_t query_sumsq,
|
|
280
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
281
|
+
nk_b128_vec_t *result_vec) {
|
|
274
282
|
for (int i = 0; i < 4; ++i) {
|
|
275
|
-
nk_f32_t dist_sq = query_sumsq +
|
|
276
|
-
|
|
283
|
+
nk_f32_t dist_sq = query_sumsq + target_sumsqs_vec->f32s[i] - 2.0f * dots_vec->f32s[i];
|
|
284
|
+
result_vec->f32s[i] = dist_sq > 0 ? nk_f32_sqrt_serial(dist_sq) : 0.0f;
|
|
277
285
|
}
|
|
278
286
|
}
|
|
279
287
|
|
|
280
288
|
/** @brief Angular from_dot for f64 precision. */
|
|
281
|
-
NK_INTERNAL void nk_angular_through_f64_from_dot_serial_(nk_b256_vec_t
|
|
282
|
-
nk_b256_vec_t
|
|
289
|
+
NK_INTERNAL void nk_angular_through_f64_from_dot_serial_(nk_b256_vec_t const *dots_vec, nk_f64_t query_sumsq,
|
|
290
|
+
nk_b256_vec_t const *target_sumsqs_vec,
|
|
291
|
+
nk_b256_vec_t *result_vec) {
|
|
283
292
|
for (int i = 0; i < 4; ++i) {
|
|
284
|
-
nk_f64_t product = query_sumsq *
|
|
293
|
+
nk_f64_t product = query_sumsq * target_sumsqs_vec->f64s[i];
|
|
285
294
|
if (product > 0) {
|
|
286
295
|
nk_f64_t rsqrt_val = nk_f64_rsqrt_serial(product);
|
|
287
|
-
nk_f64_t normalized =
|
|
296
|
+
nk_f64_t normalized = dots_vec->f64s[i] * rsqrt_val;
|
|
288
297
|
nk_f64_t result = 1.0 - normalized;
|
|
289
|
-
|
|
298
|
+
result_vec->f64s[i] = result > 0 ? result : 0;
|
|
290
299
|
}
|
|
291
|
-
else {
|
|
300
|
+
else { result_vec->f64s[i] = (dots_vec->f64s[i] == 0) ? 0.0 : 1.0; }
|
|
292
301
|
}
|
|
293
302
|
}
|
|
294
303
|
|
|
295
304
|
/** @brief Euclidean from_dot for f64 precision. */
|
|
296
|
-
NK_INTERNAL void nk_euclidean_through_f64_from_dot_serial_(nk_b256_vec_t
|
|
297
|
-
nk_b256_vec_t
|
|
305
|
+
NK_INTERNAL void nk_euclidean_through_f64_from_dot_serial_(nk_b256_vec_t const *dots_vec, nk_f64_t query_sumsq,
|
|
306
|
+
nk_b256_vec_t const *target_sumsqs_vec,
|
|
307
|
+
nk_b256_vec_t *result_vec) {
|
|
298
308
|
for (int i = 0; i < 4; ++i) {
|
|
299
|
-
nk_f64_t dist_sq = query_sumsq +
|
|
300
|
-
|
|
309
|
+
nk_f64_t dist_sq = query_sumsq + target_sumsqs_vec->f64s[i] - 2.0 * dots_vec->f64s[i];
|
|
310
|
+
result_vec->f64s[i] = dist_sq > 0 ? nk_f64_sqrt_serial(dist_sq) : 0.0;
|
|
301
311
|
}
|
|
302
312
|
}
|
|
303
313
|
|
|
304
314
|
/** @brief Angular from_dot for i32 accumulators: cast to f32, then same math as f32 variant. */
|
|
305
|
-
NK_INTERNAL void nk_angular_through_i32_from_dot_serial_(nk_b128_vec_t
|
|
306
|
-
nk_b128_vec_t
|
|
315
|
+
NK_INTERNAL void nk_angular_through_i32_from_dot_serial_(nk_b128_vec_t const *dots_vec, nk_i32_t query_sumsq,
|
|
316
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
317
|
+
nk_b128_vec_t *result_vec) {
|
|
307
318
|
for (int i = 0; i < 4; ++i) {
|
|
308
|
-
nk_f32_t product = (nk_f32_t)query_sumsq * (nk_f32_t)
|
|
319
|
+
nk_f32_t product = (nk_f32_t)query_sumsq * (nk_f32_t)target_sumsqs_vec->i32s[i];
|
|
309
320
|
if (product > 0) {
|
|
310
321
|
nk_f32_t rsqrt_val = nk_f32_rsqrt_serial(product);
|
|
311
|
-
nk_f32_t normalized = (nk_f32_t)
|
|
322
|
+
nk_f32_t normalized = (nk_f32_t)dots_vec->i32s[i] * rsqrt_val;
|
|
312
323
|
nk_f32_t result = 1.0f - normalized;
|
|
313
|
-
|
|
324
|
+
result_vec->f32s[i] = result > 0 ? result : 0;
|
|
314
325
|
}
|
|
315
|
-
else {
|
|
326
|
+
else { result_vec->f32s[i] = (dots_vec->i32s[i] == 0) ? 0.0f : 1.0f; }
|
|
316
327
|
}
|
|
317
328
|
}
|
|
318
329
|
|
|
319
330
|
/** @brief Euclidean from_dot for i32 accumulators: cast to f32, then same math as f32 variant. */
|
|
320
|
-
NK_INTERNAL void nk_euclidean_through_i32_from_dot_serial_(nk_b128_vec_t
|
|
321
|
-
nk_b128_vec_t
|
|
331
|
+
NK_INTERNAL void nk_euclidean_through_i32_from_dot_serial_(nk_b128_vec_t const *dots_vec, nk_i32_t query_sumsq,
|
|
332
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
333
|
+
nk_b128_vec_t *result_vec) {
|
|
322
334
|
for (int i = 0; i < 4; ++i) {
|
|
323
|
-
nk_f32_t dist_sq = (nk_f32_t)query_sumsq + (nk_f32_t)
|
|
324
|
-
|
|
335
|
+
nk_f32_t dist_sq = (nk_f32_t)query_sumsq + (nk_f32_t)target_sumsqs_vec->i32s[i] -
|
|
336
|
+
2.0f * (nk_f32_t)dots_vec->i32s[i];
|
|
337
|
+
result_vec->f32s[i] = dist_sq > 0 ? nk_f32_sqrt_serial(dist_sq) : 0.0f;
|
|
325
338
|
}
|
|
326
339
|
}
|
|
327
340
|
|
|
328
341
|
/** @brief Angular from_dot for u32 accumulators: cast to f32, then same math as f32 variant. */
|
|
329
|
-
NK_INTERNAL void nk_angular_through_u32_from_dot_serial_(nk_b128_vec_t
|
|
330
|
-
nk_b128_vec_t
|
|
342
|
+
NK_INTERNAL void nk_angular_through_u32_from_dot_serial_(nk_b128_vec_t const *dots_vec, nk_u32_t query_sumsq,
|
|
343
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
344
|
+
nk_b128_vec_t *result_vec) {
|
|
331
345
|
for (int i = 0; i < 4; ++i) {
|
|
332
|
-
nk_f32_t product = (nk_f32_t)query_sumsq * (nk_f32_t)
|
|
346
|
+
nk_f32_t product = (nk_f32_t)query_sumsq * (nk_f32_t)target_sumsqs_vec->u32s[i];
|
|
333
347
|
if (product > 0) {
|
|
334
348
|
nk_f32_t rsqrt_val = nk_f32_rsqrt_serial(product);
|
|
335
|
-
nk_f32_t normalized = (nk_f32_t)
|
|
349
|
+
nk_f32_t normalized = (nk_f32_t)dots_vec->u32s[i] * rsqrt_val;
|
|
336
350
|
nk_f32_t result = 1.0f - normalized;
|
|
337
|
-
|
|
351
|
+
result_vec->f32s[i] = result > 0 ? result : 0;
|
|
338
352
|
}
|
|
339
|
-
else {
|
|
353
|
+
else { result_vec->f32s[i] = (dots_vec->u32s[i] == 0) ? 0.0f : 1.0f; }
|
|
340
354
|
}
|
|
341
355
|
}
|
|
342
356
|
|
|
343
357
|
/** @brief Euclidean from_dot for u32 accumulators: cast to f32, then same math as f32 variant. */
|
|
344
|
-
NK_INTERNAL void nk_euclidean_through_u32_from_dot_serial_(nk_b128_vec_t
|
|
345
|
-
nk_b128_vec_t
|
|
358
|
+
NK_INTERNAL void nk_euclidean_through_u32_from_dot_serial_(nk_b128_vec_t const *dots_vec, nk_u32_t query_sumsq,
|
|
359
|
+
nk_b128_vec_t const *target_sumsqs_vec,
|
|
360
|
+
nk_b128_vec_t *result_vec) {
|
|
346
361
|
for (int i = 0; i < 4; ++i) {
|
|
347
|
-
nk_f32_t dist_sq = (nk_f32_t)query_sumsq + (nk_f32_t)
|
|
348
|
-
|
|
362
|
+
nk_f32_t dist_sq = (nk_f32_t)query_sumsq + (nk_f32_t)target_sumsqs_vec->u32s[i] -
|
|
363
|
+
2.0f * (nk_f32_t)dots_vec->u32s[i];
|
|
364
|
+
result_vec->f32s[i] = dist_sq > 0 ? nk_f32_sqrt_serial(dist_sq) : 0.0f;
|
|
349
365
|
}
|
|
350
366
|
}
|
|
351
367
|
|
|
352
|
-
#if defined(__clang__)
|
|
353
|
-
#pragma clang attribute pop
|
|
354
|
-
#elif defined(__GNUC__)
|
|
355
|
-
#pragma GCC pop_options
|
|
356
|
-
#endif
|
|
357
|
-
|
|
358
368
|
#if defined(__cplusplus)
|
|
359
369
|
} // extern "C"
|
|
360
370
|
#endif
|
|
@@ -26,9 +26,10 @@
|
|
|
26
26
|
#if NK_TARGET_SIERRA
|
|
27
27
|
|
|
28
28
|
#include "numkong/types.h"
|
|
29
|
-
#include "numkong/scalar/haswell.h"
|
|
30
|
-
#include "numkong/reduce/haswell.h"
|
|
31
|
-
#include "numkong/
|
|
29
|
+
#include "numkong/scalar/haswell.h" // `nk_f32_sqrt_haswell`
|
|
30
|
+
#include "numkong/reduce/haswell.h" // `nk_reduce_add_i32x8_haswell_`
|
|
31
|
+
#include "numkong/spatial/haswell.h" // `nk_angular_normalize_f32_haswell_`
|
|
32
|
+
#include "numkong/cast/serial.h" // `nk_partial_load_b8x32_serial_`
|
|
32
33
|
|
|
33
34
|
#if defined(__cplusplus)
|
|
34
35
|
extern "C" {
|