arm/riscv: avoid fp16 GELU overflow (#7060)

This commit is contained in:
LI
2026-10-11 23:07:42 -07:00
committed by GitHub
parent 4a0e0dba89
commit bd38ca5b0c
3 changed files with 25 additions and 6 deletions
+4 -4
View File
@@ -844,7 +844,7 @@ static inline float16x4_t gelu_ps_f16(float16x4_t x)
float16x4_t _half = vdup_n_f16(0.5f);
float16x4_t _blob = vmul_f16(vdup_n_f16(-0.70710678f), x);
_blob = erfc_ps_f16(_blob);
return vmul_f16(_half, vmul_f16(_blob, x));
return vmul_f16(vmul_f16(_half, _blob), x);
}
static inline float16x8_t gelu_ps_f16(float16x8_t x)
@@ -852,7 +852,7 @@ static inline float16x8_t gelu_ps_f16(float16x8_t x)
float16x8_t _half = vdupq_n_f16(0.5f);
float16x8_t _blob = vmulq_f16(vdupq_n_f16(-0.70710678f), x);
_blob = erfc_ps_f16(_blob);
return vmulq_f16(_half, vmulq_f16(_blob, x));
return vmulq_f16(vmulq_f16(_half, _blob), x);
}
static inline float16x4_t fast_gelu_ps_f16(float16x4_t x)
@@ -865,7 +865,7 @@ static inline float16x4_t fast_gelu_ps_f16(float16x4_t x)
_blob = vfma_f16(_blob, vdup_n_f16(0.79788452f), x);
_blob = tanh_ps_f16(_blob);
_blob = vadd_f16(_one, _blob);
return vmul_f16(_half, vmul_f16(_blob, x));
return vmul_f16(vmul_f16(_half, _blob), x);
}
static inline float16x8_t fast_gelu_ps_f16(float16x8_t x)
@@ -878,7 +878,7 @@ static inline float16x8_t fast_gelu_ps_f16(float16x8_t x)
_blob = vfmaq_f16(_blob, vdupq_n_f16(0.79788452f), x);
_blob = tanh_ps_f16(_blob);
_blob = vaddq_f16(_one, _blob);
return vmulq_f16(_half, vmulq_f16(_blob, x));
return vmulq_f16(vmulq_f16(_half, _blob), x);
}
static inline float16x4_t selu_ps_f16(float16x4_t x, float16x4_t alphaxlambda, float16x4_t lambda)
+1 -1
View File
@@ -49,8 +49,8 @@ int GELU_riscv::forward_inplace_fp16s(Mat& bottom_top_blob, const Option& opt) c
vfloat16m4_t _one = __riscv_vfmv_v_f_f16m4((__fp16)1.f, vl);
_tanharg = __riscv_vfadd_vv_f16m4(_tanharg, _one, vl);
_tanharg = __riscv_vfmul_vf_f16m4(_tanharg, (__fp16)0.5f, vl);
_p = __riscv_vfmul_vv_f16m4(_p, _tanharg, vl);
_p = __riscv_vfmul_vf_f16m4(_p, (__fp16)0.5f, vl);
__riscv_vse16_v_f16m4(ptr, _p, vl);
n -= vl;
+20 -1
View File
@@ -89,6 +89,24 @@ static int test_gelu_4()
|| test_gelu(RandomMat(128, -2000.f, 2000.f), true);
}
static int test_gelu_5()
{
// finite fp16 inputs must not overflow when multiplying by 1 + tanh(...)
const float values[] = {-65504.f, -40000.f, -32768.f, -32752.f, -1.f, -0.f, 0.f, 1.f, 32752.f, 32768.f, 40000.f, 65504.f};
ncnn::Mat a(128);
ncnn::Mat b(127);
for (int i = 0; i < a.w; i++)
a[i] = values[i % 12];
for (int i = 0; i < b.w; i++)
b[i] = values[i % 12];
return 0
|| test_gelu(a, false)
|| test_gelu(a, true)
|| test_gelu(b, false)
|| test_gelu(b, true);
}
int main()
{
SRAND(7767517);
@@ -98,5 +116,6 @@ int main()
|| test_gelu_1()
|| test_gelu_2()
|| test_gelu_3()
|| test_gelu_4();
|| test_gelu_4()
|| test_gelu_5();
}