1212namespace ncnn {
1313
1414#if __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
15+ static inline float16x4_t fmod_f16 (const float16x4_t & x, const float16x4_t & y)
16+ {
17+ float32x4_t fx = vcvt_f32_f16 (x);
18+ float32x4_t fy = vcvt_f32_f16 (y);
19+ return vcvt_f16_f32 (fmod_ps (fx, fy));
20+ }
21+
22+ static inline float16x8_t fmodq_f16 (const float16x8_t & x, const float16x8_t & y)
23+ {
24+ float16x4_t xl = vget_low_f16 (x);
25+ float16x4_t xh = vget_high_f16 (x);
26+ float16x4_t yl = vget_low_f16 (y);
27+ float16x4_t yh = vget_high_f16 (y);
28+
29+ float16x4_t rl = fmod_f16 (xl, yl);
30+ float16x4_t rh = fmod_f16 (xh, yh);
31+ return vcombine_f16 (rl, rh);
32+ }
33+
34+ static inline float16x4_t round_f16 (const float16x4_t & x)
35+ {
36+ return vcvt_f16_f32 (round_ps (vcvt_f32_f16 (x)));
37+ }
38+
39+ static inline float16x8_t roundq_f16 (const float16x8_t & x)
40+ {
41+ float16x4_t xl = vget_low_f16 (x);
42+ float16x4_t xh = vget_high_f16 (x);
43+ float16x4_t rl = round_f16 (xl);
44+ float16x4_t rh = round_f16 (xh);
45+ return vcombine_f16 (rl, rh);
46+ }
47+
48+ static inline float16x4_t logaddexp_f16 (const float16x4_t & x, const float16x4_t & y)
49+ {
50+ return vcvt_f16_f32 (logaddexp_ps (vcvt_f32_f16 (x), vcvt_f32_f16 (y)));
51+ }
52+
53+ static inline float16x8_t logaddexpq_f16 (const float16x8_t & x, const float16x8_t & y)
54+ {
55+ float16x4_t xl = vget_low_f16 (x);
56+ float16x4_t xh = vget_high_f16 (x);
57+ float16x4_t yl = vget_low_f16 (y);
58+ float16x4_t yh = vget_high_f16 (y);
59+ float16x4_t rl = logaddexp_f16 (xl, yl);
60+ float16x4_t rh = logaddexp_f16 (xh, yh);
61+ return vcombine_f16 (rl, rh);
62+ }
63+
64+ static inline float16x4_t floor_divide_f16 (const float16x4_t & x, const float16x4_t & y)
65+ {
66+ return vcvt_f16_f32 (floor_divide_ps (vcvt_f32_f16 (x), vcvt_f32_f16 (y)));
67+ }
68+
69+ static inline float16x8_t floor_divideq_f16 (const float16x8_t & x, const float16x8_t & y)
70+ {
71+ float16x4_t xl = vget_low_f16 (x);
72+ float16x4_t xh = vget_high_f16 (x);
73+ float16x4_t yl = vget_low_f16 (y);
74+ float16x4_t yh = vget_high_f16 (y);
75+ float16x4_t rl = floor_divide_f16 (xl, yl);
76+ float16x4_t rh = floor_divide_f16 (xh, yh);
77+ return vcombine_f16 (rl, rh);
78+ }
79+
80+ static inline float16x4_t remainder_f16 (const float16x4_t & x, const float16x4_t & y)
81+ {
82+ return vcvt_f16_f32 (remainder_ps (vcvt_f32_f16 (x), vcvt_f32_f16 (y)));
83+ }
84+
85+ static inline float16x8_t remainderq_f16 (const float16x8_t & x, const float16x8_t & y)
86+ {
87+ float16x4_t xl = vget_low_f16 (x);
88+ float16x4_t xh = vget_high_f16 (x);
89+ float16x4_t yl = vget_low_f16 (y);
90+ float16x4_t yh = vget_high_f16 (y);
91+ float16x4_t rl = remainder_f16 (xl, yl);
92+ float16x4_t rh = remainder_f16 (xh, yh);
93+ return vcombine_f16 (rl, rh);
94+ }
95+
1596template <typename Op>
1697static void binary_op_vector_no_broadcast_fp16s (const __fp16* ptr, const __fp16* ptr1, __fp16* outptr, int size)
1798{
@@ -318,6 +399,13 @@ MAKE_FUNCTION(binary_op_rdiv_fp16s, y / x, vdiv_f16(y, x), vdivq_f16(y, x))
318399MAKE_FUNCTION (binary_op_rpow_fp16s, (__fp16)powf(y, x), vcvt_f16_f32(pow_ps(vcvt_f32_f16(y), vcvt_f32_f16(x))), vcombine_f16(vcvt_f16_f32(pow_ps(vcvt_f32_f16(vget_low_f16(y)), vcvt_f32_f16(vget_low_f16(x)))), vcvt_f16_f32(pow_ps(vcvt_f32_f16(vget_high_f16(y)), vcvt_f32_f16(vget_high_f16(x))))))
319400MAKE_FUNCTION (binary_op_atan2_fp16s, (__fp16)atan2f(x, y), vcvt_f16_f32(atan2_ps(vcvt_f32_f16(x), vcvt_f32_f16(y))), vcombine_f16(vcvt_f16_f32(atan2_ps(vcvt_f32_f16(vget_low_f16(x)), vcvt_f32_f16(vget_low_f16(y)))), vcvt_f16_f32(atan2_ps(vcvt_f32_f16(vget_high_f16(x)), vcvt_f32_f16(vget_high_f16(y))))))
320401MAKE_FUNCTION (binary_op_ratan2_fp16s, (__fp16)atan2f(y, x), vcvt_f16_f32(atan2_ps(vcvt_f32_f16(y), vcvt_f32_f16(x))), vcombine_f16(vcvt_f16_f32(atan2_ps(vcvt_f32_f16(vget_low_f16(y)), vcvt_f32_f16(vget_low_f16(x)))), vcvt_f16_f32(atan2_ps(vcvt_f32_f16(vget_high_f16(y)), vcvt_f32_f16(vget_high_f16(x))))))
402+ MAKE_FUNCTION (binary_op_fmod_fp16s, (__fp16)fmodf((float )x, (float )y), fmod_f16(x, y), fmodq_f16(x, y))
403+ MAKE_FUNCTION (binary_op_rfmod_fp16s, (__fp16)fmodf((float )y, (float )x), fmod_f16(y, x), fmodq_f16(y, x))
404+ MAKE_FUNCTION (binary_op_logaddexp_fp16s, (__fp16)(std::max((float )x, (float )y) + log1pf(expf(std::min((float )x, (float )y) - std::max((float )x, (float )y)))), logaddexp_f16(x, y), logaddexpq_f16(x, y))
405+ MAKE_FUNCTION (binary_op_floor_divide_fp16s, (__fp16)floorf((float )x / (float )y), floor_divide_f16(x, y), floor_divideq_f16(x, y))
406+ MAKE_FUNCTION (binary_op_rfloor_divide_fp16s, (__fp16)floorf((float )y / (float )x), floor_divide_f16(y, x), floor_divideq_f16(y, x))
407+ MAKE_FUNCTION (binary_op_remainder_fp16s, (__fp16)remainderf((float )x, (float )y), remainder_f16(x, y), remainderq_f16(x, y))
408+ MAKE_FUNCTION (binary_op_rremainder_fp16s, (__fp16)remainderf((float )y, (float )x), remainder_f16(y, x), remainderq_f16(y, x))
321409// *INDENT-ON*
322410// clang-format on
323411
@@ -341,6 +429,13 @@ static void binary_op_vector_fp16s(const __fp16* ptr, const __fp16* ptr1, __fp16
341429 if (op_type == BinaryOp::Operation_RPOW) return binary_op_vector_fp16s<binary_op_rpow_fp16s>(ptr, ptr1, outptr, aw, bw, ap, bp);
342430 if (op_type == BinaryOp::Operation_ATAN2) return binary_op_vector_fp16s<binary_op_atan2_fp16s>(ptr, ptr1, outptr, aw, bw, ap, bp);
343431 if (op_type == BinaryOp::Operation_RATAN2) return binary_op_vector_fp16s<binary_op_ratan2_fp16s>(ptr, ptr1, outptr, aw, bw, ap, bp);
432+ if (op_type == BinaryOp::Operation_FMOD) return binary_op_vector_fp16s<binary_op_fmod_fp16s>(ptr, ptr1, outptr, aw, bw, ap, bp);
433+ if (op_type == BinaryOp::Operation_RFMOD) return binary_op_vector_fp16s<binary_op_rfmod_fp16s>(ptr, ptr1, outptr, aw, bw, ap, bp);
434+ if (op_type == BinaryOp::Operation_LOGADDEXP) return binary_op_vector_fp16s<binary_op_logaddexp_fp16s>(ptr, ptr1, outptr, aw, bw, ap, bp);
435+ if (op_type == BinaryOp::Operation_FLOOR_DIVIDE) return binary_op_vector_fp16s<binary_op_floor_divide_fp16s>(ptr, ptr1, outptr, aw, bw, ap, bp);
436+ if (op_type == BinaryOp::Operation_RFLOOR_DIVIDE) return binary_op_vector_fp16s<binary_op_rfloor_divide_fp16s>(ptr, ptr1, outptr, aw, bw, ap, bp);
437+ if (op_type == BinaryOp::Operation_REMAINDER) return binary_op_vector_fp16s<binary_op_remainder_fp16s>(ptr, ptr1, outptr, aw, bw, ap, bp);
438+ if (op_type == BinaryOp::Operation_RREMAINDER) return binary_op_vector_fp16s<binary_op_rremainder_fp16s>(ptr, ptr1, outptr, aw, bw, ap, bp);
344439
345440 // should never reach here
346441}
@@ -485,10 +580,18 @@ static int get_reverse_op_type(int op_type)
485580 if (op_type == BinaryOp::Operation_DIV) return BinaryOp::Operation_RDIV;
486581 if (op_type == BinaryOp::Operation_POW) return BinaryOp::Operation_RPOW;
487582 if (op_type == BinaryOp::Operation_ATAN2) return BinaryOp::Operation_RATAN2;
583+ if (op_type == BinaryOp::Operation_FMOD) return BinaryOp::Operation_RFMOD;
584+ if (op_type == BinaryOp::Operation_FLOOR_DIVIDE) return BinaryOp::Operation_RFLOOR_DIVIDE;
585+ if (op_type == BinaryOp::Operation_REMAINDER) return BinaryOp::Operation_RREMAINDER;
586+
488587 if (op_type == BinaryOp::Operation_RSUB) return BinaryOp::Operation_SUB;
489588 if (op_type == BinaryOp::Operation_RDIV) return BinaryOp::Operation_DIV;
490589 if (op_type == BinaryOp::Operation_RPOW) return BinaryOp::Operation_POW;
491590 if (op_type == BinaryOp::Operation_RATAN2) return BinaryOp::Operation_ATAN2;
591+ if (op_type == BinaryOp::Operation_RFMOD) return BinaryOp::Operation_FMOD;
592+ if (op_type == BinaryOp::Operation_RFLOOR_DIVIDE) return BinaryOp::Operation_FLOOR_DIVIDE;
593+ if (op_type == BinaryOp::Operation_RREMAINDER) return BinaryOp::Operation_REMAINDER;
594+
492595 return op_type;
493596}
494597
0 commit comments