ggml-cpu: fix fallback for RVV kernels without zvfh (#21157)
* ggml-cpu: refactor sgemm; fix rvv checks * ggml-cpu: refactor rvv kernels; set zvfbfwma default to off
This commit is contained in:
+2
-1
@@ -172,7 +172,8 @@ option(GGML_RVV "ggml: enable rvv" ON)
|
|||||||
option(GGML_RV_ZFH "ggml: enable riscv zfh" ON)
|
option(GGML_RV_ZFH "ggml: enable riscv zfh" ON)
|
||||||
option(GGML_RV_ZVFH "ggml: enable riscv zvfh" ON)
|
option(GGML_RV_ZVFH "ggml: enable riscv zvfh" ON)
|
||||||
option(GGML_RV_ZICBOP "ggml: enable riscv zicbop" ON)
|
option(GGML_RV_ZICBOP "ggml: enable riscv zicbop" ON)
|
||||||
option(GGML_RV_ZIHINTPAUSE "ggml: enable riscv zihintpause " ON)
|
option(GGML_RV_ZIHINTPAUSE "ggml: enable riscv zihintpause" ON)
|
||||||
|
option(GGML_RV_ZVFBFWMA "ggml: enable riscv zvfbfwma" OFF)
|
||||||
option(GGML_XTHEADVECTOR "ggml: enable xtheadvector" OFF)
|
option(GGML_XTHEADVECTOR "ggml: enable xtheadvector" OFF)
|
||||||
option(GGML_VXE "ggml: enable vxe" ${GGML_NATIVE})
|
option(GGML_VXE "ggml: enable vxe" ${GGML_NATIVE})
|
||||||
|
|
||||||
|
|||||||
@@ -180,44 +180,49 @@ inline float32x4_t madd(float32x4_t a, float32x4_t b, float32x4_t c) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__riscv_zvfh)
|
#if defined(__riscv_v_intrinsic)
|
||||||
template <>
|
template <> inline vfloat32m1_t madd(vfloat32m1_t a, vfloat32m1_t b, vfloat32m1_t c) {
|
||||||
inline vfloat32m1_t madd(vfloat16mf2_t a, vfloat16mf2_t b, vfloat32m1_t c) {
|
|
||||||
return __riscv_vfwmacc_vv_f32m1(c, a, b, __riscv_vsetvlmax_e32m1());
|
|
||||||
}
|
|
||||||
inline vfloat32m2_t madd(vfloat16m1_t a, vfloat16m1_t b, vfloat32m2_t c) {
|
|
||||||
return __riscv_vfwmacc_vv_f32m2(c, a, b, __riscv_vsetvlmax_e32m2());
|
|
||||||
}
|
|
||||||
inline vfloat32m4_t madd(vfloat16m2_t a, vfloat16m2_t b, vfloat32m4_t c) {
|
|
||||||
return __riscv_vfwmacc_vv_f32m4(c, a, b, __riscv_vsetvlmax_e32m4());
|
|
||||||
}
|
|
||||||
inline vfloat32m8_t madd(vfloat16m4_t a, vfloat16m4_t b, vfloat32m8_t c) {
|
|
||||||
return __riscv_vfwmacc_vv_f32m8(c, a, b, __riscv_vsetvlmax_e32m8());
|
|
||||||
}
|
|
||||||
inline vfloat32m1_t madd(vfloat32m1_t a, vfloat32m1_t b, vfloat32m1_t c) {
|
|
||||||
return __riscv_vfmacc_vv_f32m1(c, a, b, __riscv_vsetvlmax_e32m1());
|
return __riscv_vfmacc_vv_f32m1(c, a, b, __riscv_vsetvlmax_e32m1());
|
||||||
}
|
}
|
||||||
inline vfloat32m2_t madd(vfloat32m2_t a, vfloat32m2_t b, vfloat32m2_t c) {
|
template <> inline vfloat32m2_t madd(vfloat32m2_t a, vfloat32m2_t b, vfloat32m2_t c) {
|
||||||
return __riscv_vfmacc_vv_f32m2(c, a, b, __riscv_vsetvlmax_e32m2());
|
return __riscv_vfmacc_vv_f32m2(c, a, b, __riscv_vsetvlmax_e32m2());
|
||||||
}
|
}
|
||||||
inline vfloat32m4_t madd(vfloat32m4_t a, vfloat32m4_t b, vfloat32m4_t c) {
|
template <> inline vfloat32m4_t madd(vfloat32m4_t a, vfloat32m4_t b, vfloat32m4_t c) {
|
||||||
return __riscv_vfmacc_vv_f32m4(c, a, b, __riscv_vsetvlmax_e32m4());
|
return __riscv_vfmacc_vv_f32m4(c, a, b, __riscv_vsetvlmax_e32m4());
|
||||||
}
|
}
|
||||||
inline vfloat32m8_t madd(vfloat32m8_t a, vfloat32m8_t b, vfloat32m8_t c) {
|
template <> inline vfloat32m8_t madd(vfloat32m8_t a, vfloat32m8_t b, vfloat32m8_t c) {
|
||||||
return __riscv_vfmacc_vv_f32m8(c, a, b, __riscv_vsetvlmax_e32m8());
|
return __riscv_vfmacc_vv_f32m8(c, a, b, __riscv_vsetvlmax_e32m8());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__riscv_zvfh)
|
||||||
|
template <> inline vfloat32m1_t madd(vfloat16mf2_t a, vfloat16mf2_t b, vfloat32m1_t c) {
|
||||||
|
return __riscv_vfwmacc_vv_f32m1(c, a, b, __riscv_vsetvlmax_e32m1());
|
||||||
|
}
|
||||||
|
template <> inline vfloat32m2_t madd(vfloat16m1_t a, vfloat16m1_t b, vfloat32m2_t c) {
|
||||||
|
return __riscv_vfwmacc_vv_f32m2(c, a, b, __riscv_vsetvlmax_e32m2());
|
||||||
|
}
|
||||||
|
template <> inline vfloat32m4_t madd(vfloat16m2_t a, vfloat16m2_t b, vfloat32m4_t c) {
|
||||||
|
return __riscv_vfwmacc_vv_f32m4(c, a, b, __riscv_vsetvlmax_e32m4());
|
||||||
|
}
|
||||||
|
template <> inline vfloat32m8_t madd(vfloat16m4_t a, vfloat16m4_t b, vfloat32m8_t c) {
|
||||||
|
return __riscv_vfwmacc_vv_f32m8(c, a, b, __riscv_vsetvlmax_e32m8());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__riscv_zvfbfwma)
|
#if defined(__riscv_zvfbfwma)
|
||||||
inline vfloat32m1_t madd(vbfloat16mf2_t a, vbfloat16mf2_t b, vfloat32m1_t c) {
|
template <> inline vfloat32m1_t madd(vbfloat16mf2_t a, vbfloat16mf2_t b, vfloat32m1_t c) {
|
||||||
return __riscv_vfwmaccbf16_vv_f32m1(c, a, b, __riscv_vsetvlmax_e32m1());
|
return __riscv_vfwmaccbf16_vv_f32m1(c, a, b, __riscv_vsetvlmax_e32m1());
|
||||||
}
|
}
|
||||||
inline vfloat32m2_t madd(vbfloat16m1_t a, vbfloat16m1_t b, vfloat32m2_t c) {
|
template <> inline vfloat32m2_t madd(vbfloat16m1_t a, vbfloat16m1_t b, vfloat32m2_t c) {
|
||||||
return __riscv_vfwmaccbf16_vv_f32m2(c, a, b, __riscv_vsetvlmax_e32m2());
|
return __riscv_vfwmaccbf16_vv_f32m2(c, a, b, __riscv_vsetvlmax_e32m2());
|
||||||
}
|
}
|
||||||
inline vfloat32m4_t madd(vbfloat16m2_t a, vbfloat16m2_t b, vfloat32m4_t c) {
|
template <> inline vfloat32m4_t madd(vbfloat16m2_t a, vbfloat16m2_t b, vfloat32m4_t c) {
|
||||||
return __riscv_vfwmaccbf16_vv_f32m4(c, a, b, __riscv_vsetvlmax_e32m4());
|
return __riscv_vfwmaccbf16_vv_f32m4(c, a, b, __riscv_vsetvlmax_e32m4());
|
||||||
}
|
}
|
||||||
|
template <> inline vfloat32m8_t madd(vbfloat16m4_t a, vbfloat16m4_t b, vfloat32m8_t c) {
|
||||||
|
return __riscv_vfwmaccbf16_vv_f32m8(c, a, b, __riscv_vsetvlmax_e32m8());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -272,7 +277,7 @@ inline float hsum(__m512 x) {
|
|||||||
}
|
}
|
||||||
#endif // __AVX512F__
|
#endif // __AVX512F__
|
||||||
|
|
||||||
#if defined(__riscv_zvfh)
|
#if defined(__riscv_v_intrinsic)
|
||||||
inline float hsum(vfloat32m1_t x) {
|
inline float hsum(vfloat32m1_t x) {
|
||||||
return __riscv_vfmv_f_s_f32m1_f32(
|
return __riscv_vfmv_f_s_f32m1_f32(
|
||||||
__riscv_vfredusum_vs_f32m1_f32m1(x, __riscv_vfmv_v_f_f32m1(0, 1), __riscv_vsetvlmax_e32m1()));
|
__riscv_vfredusum_vs_f32m1_f32m1(x, __riscv_vfmv_v_f_f32m1(0, 1), __riscv_vsetvlmax_e32m1()));
|
||||||
@@ -379,19 +384,7 @@ template <> inline __m256bh load(const float *p) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__riscv_zvfh)
|
#if defined(__riscv_v_intrinsic)
|
||||||
template <> inline vfloat16mf2_t load(const ggml_fp16_t *p) {
|
|
||||||
return __riscv_vle16_v_f16mf2(reinterpret_cast<const _Float16 *>(p), __riscv_vsetvlmax_e16mf2());
|
|
||||||
}
|
|
||||||
template <> inline vfloat16m1_t load(const ggml_fp16_t *p) {
|
|
||||||
return __riscv_vle16_v_f16m1(reinterpret_cast<const _Float16 *>(p), __riscv_vsetvlmax_e16m1());
|
|
||||||
}
|
|
||||||
template <> inline vfloat16m2_t load(const ggml_fp16_t *p) {
|
|
||||||
return __riscv_vle16_v_f16m2(reinterpret_cast<const _Float16 *>(p), __riscv_vsetvlmax_e16m2());
|
|
||||||
}
|
|
||||||
template <> inline vfloat16m4_t load(const ggml_fp16_t *p) {
|
|
||||||
return __riscv_vle16_v_f16m4(reinterpret_cast<const _Float16 *>(p), __riscv_vsetvlmax_e16m4());
|
|
||||||
}
|
|
||||||
template <> inline vfloat32m1_t load(const float *p) {
|
template <> inline vfloat32m1_t load(const float *p) {
|
||||||
return __riscv_vle32_v_f32m1(p, __riscv_vsetvlmax_e32m1());
|
return __riscv_vle32_v_f32m1(p, __riscv_vsetvlmax_e32m1());
|
||||||
}
|
}
|
||||||
@@ -406,6 +399,21 @@ template <> inline vfloat32m8_t load(const float *p) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__riscv_zvfh)
|
||||||
|
template <> inline vfloat16mf2_t load(const ggml_fp16_t *p) {
|
||||||
|
return __riscv_vle16_v_f16mf2(reinterpret_cast<const _Float16 *>(p), __riscv_vsetvlmax_e16mf2());
|
||||||
|
}
|
||||||
|
template <> inline vfloat16m1_t load(const ggml_fp16_t *p) {
|
||||||
|
return __riscv_vle16_v_f16m1(reinterpret_cast<const _Float16 *>(p), __riscv_vsetvlmax_e16m1());
|
||||||
|
}
|
||||||
|
template <> inline vfloat16m2_t load(const ggml_fp16_t *p) {
|
||||||
|
return __riscv_vle16_v_f16m2(reinterpret_cast<const _Float16 *>(p), __riscv_vsetvlmax_e16m2());
|
||||||
|
}
|
||||||
|
template <> inline vfloat16m4_t load(const ggml_fp16_t *p) {
|
||||||
|
return __riscv_vle16_v_f16m4(reinterpret_cast<const _Float16 *>(p), __riscv_vsetvlmax_e16m4());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__riscv_zvfbfwma)
|
#if defined(__riscv_zvfbfwma)
|
||||||
template <> inline vbfloat16mf2_t load(const ggml_bf16_t *p) {
|
template <> inline vbfloat16mf2_t load(const ggml_bf16_t *p) {
|
||||||
return __riscv_vle16_v_bf16mf2(reinterpret_cast<const __bf16*>(p), __riscv_vsetvlmax_e16mf2());
|
return __riscv_vle16_v_bf16mf2(reinterpret_cast<const __bf16*>(p), __riscv_vsetvlmax_e16mf2());
|
||||||
@@ -416,23 +424,14 @@ template <> inline vbfloat16m1_t load(const ggml_bf16_t *p) {
|
|||||||
template <> inline vbfloat16m2_t load(const ggml_bf16_t *p) {
|
template <> inline vbfloat16m2_t load(const ggml_bf16_t *p) {
|
||||||
return __riscv_vle16_v_bf16m2(reinterpret_cast<const __bf16*>(p), __riscv_vsetvlmax_e16m2());
|
return __riscv_vle16_v_bf16m2(reinterpret_cast<const __bf16*>(p), __riscv_vsetvlmax_e16m2());
|
||||||
}
|
}
|
||||||
|
template <> inline vbfloat16m4_t load(const ggml_bf16_t *p) {
|
||||||
|
return __riscv_vle16_v_bf16m4(reinterpret_cast<const __bf16*>(p), __riscv_vsetvlmax_e16m4());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__riscv_zvfh)
|
#if defined(__riscv_v_intrinsic)
|
||||||
template <typename T> T set_zero();
|
template <typename T> T set_zero();
|
||||||
|
|
||||||
template <> inline vfloat16mf2_t set_zero() {
|
|
||||||
return __riscv_vfmv_v_f_f16mf2(0, __riscv_vsetvlmax_e16mf2());
|
|
||||||
}
|
|
||||||
template <> inline vfloat16m1_t set_zero() {
|
|
||||||
return __riscv_vfmv_v_f_f16m1(0, __riscv_vsetvlmax_e16m1());
|
|
||||||
}
|
|
||||||
template <> inline vfloat16m2_t set_zero() {
|
|
||||||
return __riscv_vfmv_v_f_f16m2(0, __riscv_vsetvlmax_e16m2());
|
|
||||||
}
|
|
||||||
template <> inline vfloat16m4_t set_zero() {
|
|
||||||
return __riscv_vfmv_v_f_f16m4(0, __riscv_vsetvlmax_e16m4());
|
|
||||||
}
|
|
||||||
template <> inline vfloat32m1_t set_zero() {
|
template <> inline vfloat32m1_t set_zero() {
|
||||||
return __riscv_vfmv_v_f_f32m1(0.0f, __riscv_vsetvlmax_e32m1());
|
return __riscv_vfmv_v_f_f32m1(0.0f, __riscv_vsetvlmax_e32m1());
|
||||||
}
|
}
|
||||||
@@ -449,14 +448,22 @@ template <> inline vfloat32m8_t set_zero() {
|
|||||||
|
|
||||||
#if defined(__riscv_v_intrinsic)
|
#if defined(__riscv_v_intrinsic)
|
||||||
template <typename T> size_t vlmax() {
|
template <typename T> size_t vlmax() {
|
||||||
if constexpr (std::is_same_v<T, vfloat16mf2_t>) { return __riscv_vsetvlmax_e16mf2(); }
|
if constexpr (std::is_same_v<T, vfloat32m1_t>) { return __riscv_vsetvlmax_e32m1(); }
|
||||||
else if constexpr (std::is_same_v<T, vfloat16m1_t>) { return __riscv_vsetvlmax_e16m1(); }
|
|
||||||
else if constexpr (std::is_same_v<T, vfloat16m2_t>) { return __riscv_vsetvlmax_e16m2(); }
|
|
||||||
else if constexpr (std::is_same_v<T, vfloat16m4_t>) { return __riscv_vsetvlmax_e16m4(); }
|
|
||||||
else if constexpr (std::is_same_v<T, vfloat32m1_t>) { return __riscv_vsetvlmax_e32m1(); }
|
|
||||||
else if constexpr (std::is_same_v<T, vfloat32m2_t>) { return __riscv_vsetvlmax_e32m2(); }
|
else if constexpr (std::is_same_v<T, vfloat32m2_t>) { return __riscv_vsetvlmax_e32m2(); }
|
||||||
else if constexpr (std::is_same_v<T, vfloat32m4_t>) { return __riscv_vsetvlmax_e32m4(); }
|
else if constexpr (std::is_same_v<T, vfloat32m4_t>) { return __riscv_vsetvlmax_e32m4(); }
|
||||||
else if constexpr (std::is_same_v<T, vfloat32m8_t>) { return __riscv_vsetvlmax_e32m8(); }
|
else if constexpr (std::is_same_v<T, vfloat32m8_t>) { return __riscv_vsetvlmax_e32m8(); }
|
||||||
|
#if defined (__riscv_zvfh)
|
||||||
|
else if constexpr (std::is_same_v<T, vfloat16mf2_t>) { return __riscv_vsetvlmax_e16mf2(); }
|
||||||
|
else if constexpr (std::is_same_v<T, vfloat16m1_t>) { return __riscv_vsetvlmax_e16m1(); }
|
||||||
|
else if constexpr (std::is_same_v<T, vfloat16m2_t>) { return __riscv_vsetvlmax_e16m2(); }
|
||||||
|
else if constexpr (std::is_same_v<T, vfloat16m4_t>) { return __riscv_vsetvlmax_e16m4(); }
|
||||||
|
#endif
|
||||||
|
#if defined (__riscv_zvfbfwma)
|
||||||
|
else if constexpr (std::is_same_v<T, vbfloat16mf2_t>) { return __riscv_vsetvlmax_e16mf2(); }
|
||||||
|
else if constexpr (std::is_same_v<T, vbfloat16m1_t>) { return __riscv_vsetvlmax_e16m1(); }
|
||||||
|
else if constexpr (std::is_same_v<T, vbfloat16m2_t>) { return __riscv_vsetvlmax_e16m2(); }
|
||||||
|
else if constexpr (std::is_same_v<T, vbfloat16m4_t>) { return __riscv_vsetvlmax_e16m4(); }
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -3740,7 +3747,7 @@ bool llamafile_sgemm(const struct ggml_compute_params * params, int64_t m, int64
|
|||||||
params->ith, params->nth};
|
params->ith, params->nth};
|
||||||
tb.matmul(m, n);
|
tb.matmul(m, n);
|
||||||
return true;
|
return true;
|
||||||
#elif defined(__riscv_zvfh)
|
#elif defined(__riscv_v_intrinsic)
|
||||||
#if LMUL == 1
|
#if LMUL == 1
|
||||||
tinyBLAS_RVV<vfloat32m1_t, vfloat32m1_t, float, float, float> tb{ params,
|
tinyBLAS_RVV<vfloat32m1_t, vfloat32m1_t, float, float, float> tb{ params,
|
||||||
k, (const float *)A, lda,
|
k, (const float *)A, lda,
|
||||||
@@ -3804,6 +3811,7 @@ bool llamafile_sgemm(const struct ggml_compute_params * params, int64_t m, int64
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#elif defined(__riscv_zvfbfwma)
|
#elif defined(__riscv_zvfbfwma)
|
||||||
|
if (Btype == GGML_TYPE_BF16) {
|
||||||
#if LMUL == 1
|
#if LMUL == 1
|
||||||
tinyBLAS_RVV<vfloat32m1_t, vbfloat16mf2_t, ggml_bf16_t, ggml_bf16_t, float> tb{ params,
|
tinyBLAS_RVV<vfloat32m1_t, vbfloat16mf2_t, ggml_bf16_t, ggml_bf16_t, float> tb{ params,
|
||||||
k, (const ggml_bf16_t *)A, lda,
|
k, (const ggml_bf16_t *)A, lda,
|
||||||
@@ -3821,6 +3829,7 @@ bool llamafile_sgemm(const struct ggml_compute_params * params, int64_t m, int64
|
|||||||
(float *)C, ldc};
|
(float *)C, ldc};
|
||||||
#endif
|
#endif
|
||||||
return tb.matmul(m, n);
|
return tb.matmul(m, n);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-28
@@ -126,7 +126,7 @@ inline static void ggml_vec_dot_f16_unroll(const int n, const int xs, float * GG
|
|||||||
const int ggml_f16_epr = sve_register_length / 16; // running when 16
|
const int ggml_f16_epr = sve_register_length / 16; // running when 16
|
||||||
const int ggml_f16_step = 8 * ggml_f16_epr; // choose 8 SVE registers
|
const int ggml_f16_step = 8 * ggml_f16_epr; // choose 8 SVE registers
|
||||||
|
|
||||||
const int np = (n & ~(ggml_f16_step - 1));
|
int np = (n & ~(ggml_f16_step - 1));
|
||||||
|
|
||||||
svfloat16_t sum_00 = svdup_n_f16(0.0f);
|
svfloat16_t sum_00 = svdup_n_f16(0.0f);
|
||||||
svfloat16_t sum_01 = svdup_n_f16(0.0f);
|
svfloat16_t sum_01 = svdup_n_f16(0.0f);
|
||||||
@@ -224,8 +224,9 @@ inline static void ggml_vec_dot_f16_unroll(const int n, const int xs, float * GG
|
|||||||
}
|
}
|
||||||
GGML_F16x_VEC_REDUCE(sumf[0], sum_00, sum_01, sum_02, sum_03);
|
GGML_F16x_VEC_REDUCE(sumf[0], sum_00, sum_01, sum_02, sum_03);
|
||||||
GGML_F16x_VEC_REDUCE(sumf[1], sum_10, sum_11, sum_12, sum_13);
|
GGML_F16x_VEC_REDUCE(sumf[1], sum_10, sum_11, sum_12, sum_13);
|
||||||
|
np = n;
|
||||||
#elif defined(__riscv_v_intrinsic) && defined(__riscv_zvfh)
|
#elif defined(__riscv_v_intrinsic)
|
||||||
|
#if defined(__riscv_zvfh)
|
||||||
size_t vl = __riscv_vsetvlmax_e32m4();
|
size_t vl = __riscv_vsetvlmax_e32m4();
|
||||||
|
|
||||||
// initialize accumulators to all zeroes
|
// initialize accumulators to all zeroes
|
||||||
@@ -237,7 +238,7 @@ inline static void ggml_vec_dot_f16_unroll(const int n, const int xs, float * GG
|
|||||||
// calculate step size
|
// calculate step size
|
||||||
const size_t epr = __riscv_vsetvlmax_e16m2();
|
const size_t epr = __riscv_vsetvlmax_e16m2();
|
||||||
const size_t step = epr * 2;
|
const size_t step = epr * 2;
|
||||||
const int np = (n & ~(step - 1));
|
int np = (n & ~(step - 1));
|
||||||
|
|
||||||
// unroll by 2 along the row dimension
|
// unroll by 2 along the row dimension
|
||||||
for (int i = 0; i < np; i += step) {
|
for (int i = 0; i < np; i += step) {
|
||||||
@@ -288,7 +289,10 @@ inline static void ggml_vec_dot_f16_unroll(const int n, const int xs, float * GG
|
|||||||
acc1_1, __riscv_vfmv_v_f_f32m1(0.0f, 1), vl);
|
acc1_1, __riscv_vfmv_v_f_f32m1(0.0f, 1), vl);
|
||||||
sumf[0] = __riscv_vfmv_f_s_f32m1_f32(redsum0);
|
sumf[0] = __riscv_vfmv_f_s_f32m1_f32(redsum0);
|
||||||
sumf[1] = __riscv_vfmv_f_s_f32m1_f32(redsum1);
|
sumf[1] = __riscv_vfmv_f_s_f32m1_f32(redsum1);
|
||||||
|
np = n;
|
||||||
|
#else
|
||||||
|
const int np = 0;
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
const int np = (n & ~(GGML_F16_STEP - 1));
|
const int np = (n & ~(GGML_F16_STEP - 1));
|
||||||
|
|
||||||
@@ -313,21 +317,17 @@ inline static void ggml_vec_dot_f16_unroll(const int n, const int xs, float * GG
|
|||||||
for (int k = 0; k < GGML_VEC_DOT_UNROLL; ++k) {
|
for (int k = 0; k < GGML_VEC_DOT_UNROLL; ++k) {
|
||||||
GGML_F16_VEC_REDUCE(sumf[k], sum[k]);
|
GGML_F16_VEC_REDUCE(sumf[k], sum[k]);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// leftovers
|
#else
|
||||||
|
// scalar path
|
||||||
|
const int np = 0;
|
||||||
|
#endif
|
||||||
|
// scalar and leftovers
|
||||||
for (int i = np; i < n; ++i) {
|
for (int i = np; i < n; ++i) {
|
||||||
for (int j = 0; j < GGML_VEC_DOT_UNROLL; ++j) {
|
for (int j = 0; j < GGML_VEC_DOT_UNROLL; ++j) {
|
||||||
sumf[j] += (ggml_float)(GGML_CPU_FP16_TO_FP32(x[j][i])*GGML_CPU_FP16_TO_FP32(y[i]));
|
sumf[j] += (ggml_float)(GGML_CPU_FP16_TO_FP32(x[j][i])*GGML_CPU_FP16_TO_FP32(y[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
for (int j = 0; j < GGML_VEC_DOT_UNROLL; ++j) {
|
|
||||||
sumf[j] += (ggml_float)(GGML_CPU_FP16_TO_FP32(x[j][i])*GGML_CPU_FP16_TO_FP32(y[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int i = 0; i < GGML_VEC_DOT_UNROLL; ++i) {
|
for (int i = 0; i < GGML_VEC_DOT_UNROLL; ++i) {
|
||||||
s[i] = (float)sumf[i];
|
s[i] = (float)sumf[i];
|
||||||
@@ -532,7 +532,8 @@ inline static void ggml_vec_mad_f16(const int n, ggml_fp16_t * GGML_RESTRICT y,
|
|||||||
svst1_f16(pg, (__fp16 *)(y + np2), hy);
|
svst1_f16(pg, (__fp16 *)(y + np2), hy);
|
||||||
}
|
}
|
||||||
np = n;
|
np = n;
|
||||||
#elif defined(__riscv_zvfh) // implies __riscv_v_intrinsic
|
#elif defined(__riscv_v_intrinsic) // implies __riscv_v_intrinsic
|
||||||
|
#if defined (__riscv_zvfh)
|
||||||
const ggml_fp16_t s = GGML_CPU_FP32_TO_FP16(v);
|
const ggml_fp16_t s = GGML_CPU_FP32_TO_FP16(v);
|
||||||
const _Float16 scale = *(const _Float16*)(&s);
|
const _Float16 scale = *(const _Float16*)(&s);
|
||||||
|
|
||||||
@@ -566,6 +567,10 @@ inline static void ggml_vec_mad_f16(const int n, ggml_fp16_t * GGML_RESTRICT y,
|
|||||||
__riscv_vse16_v_f16m4((_Float16*)y + i, ay0, vl);
|
__riscv_vse16_v_f16m4((_Float16*)y + i, ay0, vl);
|
||||||
}
|
}
|
||||||
np = n;
|
np = n;
|
||||||
|
#else
|
||||||
|
// fall to scalar path
|
||||||
|
const int np = 0;
|
||||||
|
#endif
|
||||||
#elif defined(GGML_SIMD)
|
#elif defined(GGML_SIMD)
|
||||||
const int np = (n & ~(GGML_F16_STEP - 1));
|
const int np = (n & ~(GGML_F16_STEP - 1));
|
||||||
|
|
||||||
@@ -584,10 +589,11 @@ inline static void ggml_vec_mad_f16(const int n, ggml_fp16_t * GGML_RESTRICT y,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
// scalar path
|
||||||
const int np = 0;
|
const int np = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// leftovers
|
// scalar and leftovers
|
||||||
for (int i = np; i < n; ++i) {
|
for (int i = np; i < n; ++i) {
|
||||||
y[i] = GGML_CPU_FP32_TO_FP16(GGML_CPU_FP16_TO_FP32(y[i]) + GGML_CPU_FP16_TO_FP32(x[i])*v);
|
y[i] = GGML_CPU_FP32_TO_FP16(GGML_CPU_FP16_TO_FP32(y[i]) + GGML_CPU_FP16_TO_FP32(x[i])*v);
|
||||||
}
|
}
|
||||||
@@ -785,7 +791,7 @@ inline static void ggml_vec_scale_f16(const int n, ggml_fp16_t * y, const float
|
|||||||
const int ggml_f16_step = 2 * ggml_f16_epr;
|
const int ggml_f16_step = 2 * ggml_f16_epr;
|
||||||
|
|
||||||
GGML_F16x_VEC vx = GGML_F16x_VEC_SET1(v);
|
GGML_F16x_VEC vx = GGML_F16x_VEC_SET1(v);
|
||||||
const int np = (n & ~(ggml_f16_step - 1));
|
int np = (n & ~(ggml_f16_step - 1));
|
||||||
svfloat16_t ay1, ay2;
|
svfloat16_t ay1, ay2;
|
||||||
|
|
||||||
for (int i = 0; i < np; i += ggml_f16_step) {
|
for (int i = 0; i < np; i += ggml_f16_step) {
|
||||||
@@ -805,14 +811,16 @@ inline static void ggml_vec_scale_f16(const int n, ggml_fp16_t * y, const float
|
|||||||
svfloat16_t out = svmul_f16_m(pg, hy, vx);
|
svfloat16_t out = svmul_f16_m(pg, hy, vx);
|
||||||
svst1_f16(pg, (__fp16 *)(y + np), out);
|
svst1_f16(pg, (__fp16 *)(y + np), out);
|
||||||
}
|
}
|
||||||
#elif defined(__riscv_v_intrinsic) && defined(__riscv_zvfh)
|
np = n;
|
||||||
|
#elif defined(__riscv_v_intrinsic)
|
||||||
|
#if defined(__riscv_zvfh)
|
||||||
const ggml_fp16_t s = GGML_CPU_FP32_TO_FP16(v);
|
const ggml_fp16_t s = GGML_CPU_FP32_TO_FP16(v);
|
||||||
const _Float16 scale = *(const _Float16*)(&s);
|
const _Float16 scale = *(const _Float16*)(&s);
|
||||||
|
|
||||||
// calculate step size
|
// calculate step size
|
||||||
const int epr = __riscv_vsetvlmax_e16m4();
|
const int epr = __riscv_vsetvlmax_e16m4();
|
||||||
const int step = epr * 2;
|
const int step = epr * 2;
|
||||||
const int np = (n & ~(step - 1));
|
int np = (n & ~(step - 1));
|
||||||
|
|
||||||
// unroll by 2
|
// unroll by 2
|
||||||
for (int i = 0; i < np; i += step) {
|
for (int i = 0; i < np; i += step) {
|
||||||
@@ -835,6 +843,11 @@ inline static void ggml_vec_scale_f16(const int n, ggml_fp16_t * y, const float
|
|||||||
ay0 = __riscv_vfmul_vf_f16m4(ay0, scale, vl);
|
ay0 = __riscv_vfmul_vf_f16m4(ay0, scale, vl);
|
||||||
__riscv_vse16_v_f16m4((_Float16*)y + i, ay0, vl);
|
__riscv_vse16_v_f16m4((_Float16*)y + i, ay0, vl);
|
||||||
}
|
}
|
||||||
|
np = n;
|
||||||
|
#else
|
||||||
|
// fall to scalar path
|
||||||
|
const int np = 0;
|
||||||
|
#endif
|
||||||
#elif defined(GGML_SIMD)
|
#elif defined(GGML_SIMD)
|
||||||
const int np = (n & ~(GGML_F16_STEP - 1));
|
const int np = (n & ~(GGML_F16_STEP - 1));
|
||||||
|
|
||||||
@@ -850,17 +863,14 @@ inline static void ggml_vec_scale_f16(const int n, ggml_fp16_t * y, const float
|
|||||||
GGML_F16_VEC_STORE(y + i + j*GGML_F16_EPR, ay, j);
|
GGML_F16_VEC_STORE(y + i + j*GGML_F16_EPR, ay, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
// leftovers
|
// scalar path
|
||||||
|
const int np = 0;
|
||||||
|
#endif
|
||||||
|
// scalar and leftovers
|
||||||
for (int i = np; i < n; ++i) {
|
for (int i = np; i < n; ++i) {
|
||||||
y[i] = GGML_CPU_FP32_TO_FP16(GGML_CPU_FP16_TO_FP32(y[i])*v);
|
y[i] = GGML_CPU_FP32_TO_FP16(GGML_CPU_FP16_TO_FP32(y[i])*v);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
// scalar
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
y[i] = GGML_CPU_FP32_TO_FP16(GGML_CPU_FP16_TO_FP32(y[i])*v);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void ggml_vec_norm_f32 (const int n, float * s, const float * x) { ggml_vec_dot_f32(n, s, 0, x, 0, x, 0, 1); *s = sqrtf(*s); }
|
inline static void ggml_vec_norm_f32 (const int n, float * s, const float * x) { ggml_vec_dot_f32(n, s, 0, x, 0, x, 0, 1); *s = sqrtf(*s); }
|
||||||
|
|||||||
Reference in New Issue
Block a user