27 #if defined(__ARM_FEATURE_SVE) && defined(ARM_COMPUTE_ENABLE_SVE) 30 #define M_PI (3.14159265358979323846) 35 inline svfloat32_t svtaylor_poly_f32_z(svbool_t pg, svfloat32_t x, svfloat32_t coeff_1, svfloat32_t coeff_2, svfloat32_t coeff_3,
36 svfloat32_t coeff_4, svfloat32_t coeff_5, svfloat32_t coeff_6, svfloat32_t coeff_7, svfloat32_t coeff_8)
38 const auto A = svmla_f32_z(pg, coeff_1, coeff_5, x);
39 const auto B = svmla_f32_z(pg, coeff_3, coeff_7, x);
40 const auto C = svmla_f32_z(pg, coeff_2, coeff_6, x);
41 const auto D = svmla_f32_z(pg, coeff_4, coeff_8, x);
42 const auto x2 = svmul_f32_z(pg, x, x);
43 const auto x4 = svmul_f32_z(pg, x2, x2);
44 const auto res = svmla_f32_z(pg, svmla_f32_z(pg, A, B, x2), svmla_f32_z(pg, C, D, x2), x4);
48 inline svfloat16_t svtaylor_poly_f16_z(svbool_t pg, svfloat16_t x, svfloat16_t coeff_1, svfloat16_t coeff_2, svfloat16_t coeff_3,
49 svfloat16_t coeff_4, svfloat16_t coeff_5, svfloat16_t coeff_6, svfloat16_t coeff_7, svfloat16_t coeff_8)
51 const auto A = svmla_f16_z(pg, coeff_1, coeff_5, x);
52 const auto B = svmla_f16_z(pg, coeff_3, coeff_7, x);
53 const auto C = svmla_f16_z(pg, coeff_2, coeff_6, x);
54 const auto D = svmla_f16_z(pg, coeff_4, coeff_8, x);
55 const auto x2 = svmul_f16_z(pg, x, x);
56 const auto x4 = svmul_f16_z(pg, x2, x2);
57 const auto res = svmla_f16_z(pg, svmla_f16_z(pg, A, B, x2), svmla_f16_z(pg, C, D, x2), x4);
61 inline svfloat16_t svinv_f16_z(svbool_t pg, svfloat16_t x)
63 auto recip = svrecpe_f16(x);
64 recip = svmul_f16_z(pg, svrecps_f16(x, recip), recip);
65 recip = svmul_f16_z(pg, svrecps_f16(x, recip), recip);
69 inline svfloat32_t svinv_f32_z(svbool_t pg, svfloat32_t x)
71 auto recip = svrecpe_f32(x);
72 recip = svmul_f32_z(pg, svrecps_f32(x, recip), recip);
73 recip = svmul_f32_z(pg, svrecps_f32(x, recip), recip);
77 inline svfloat32_t svexp_f32_z(svbool_t pg, svfloat32_t x)
79 const auto CONST_LN2 = svdup_n_f32(0.6931471805f);
80 const auto CONST_INV_LN2 = svdup_n_f32(1.4426950408f);
81 const auto CONST_INF = svdup_n_f32(std::numeric_limits<float>::infinity());
82 const auto CONST_MAX_INPUT = svdup_n_f32(88.7f);
83 const auto CONST_0 = svdup_n_f32(0.f);
84 const auto CONST_NEGATIVE_126 = svdup_n_s32(-126);
87 const svfloat32_t exp_tab_1 = svdup_n_f32(1.f);
88 const svfloat32_t exp_tab_2 = svdup_n_f32(0.0416598916054f);
89 const svfloat32_t exp_tab_3 = svdup_n_f32(0.500000596046f);
90 const svfloat32_t exp_tab_4 = svdup_n_f32(0.0014122662833f);
91 const svfloat32_t exp_tab_5 = svdup_n_f32(1.00000011921f);
92 const svfloat32_t exp_tab_6 = svdup_n_f32(0.00833693705499f);
93 const svfloat32_t exp_tab_7 = svdup_n_f32(0.166665703058f);
94 const svfloat32_t exp_tab_8 = svdup_n_f32(0.000195780929062f);
97 auto m = svcvt_s32_f32_z(pg, svmul_f32_z(pg, x, CONST_INV_LN2));
98 auto val = svmls_f32_z(pg, x, svcvt_f32_s32_z(pg, m), CONST_LN2);
101 auto poly = svtaylor_poly_f32_z(pg, val, exp_tab_1, exp_tab_2, exp_tab_3, exp_tab_4, exp_tab_5, exp_tab_6, exp_tab_7, exp_tab_8);
104 poly = svreinterpret_f32_s32(svqadd_s32(svreinterpret_s32_f32(poly), svlsl_n_s32_z(pg, m, 23)));
107 svbool_t ltpg = svcmplt_s32(pg, m, CONST_NEGATIVE_126);
108 poly = svsel_f32(ltpg, CONST_0, poly);
111 svbool_t gtpg = svcmpgt_f32(pg, x, CONST_MAX_INPUT);
112 poly = svsel_f32(gtpg, CONST_INF, poly);
117 inline svfloat16_t svexp_f16_z(svbool_t pg, svfloat16_t x)
119 auto bottom = svcvt_f32_z(pg, x);
120 #if defined(ARM_COMPUTE_ENABLE_SVE2) 121 auto top = svcvtlt_f32_x(pg, x);
124 auto pg_top = svptrue_b16();
125 auto top = svcvt_f32_z(pg_top, svreinterpret_f16(svrevh_z(svptrue_b16(), svreinterpret_u32(x))));
128 bottom = svexp_f32_z(pg, bottom);
129 top = svexp_f32_z(pg_top, top);
131 #if defined(ARM_COMPUTE_ENABLE_SVE2) 132 return svcvtnt_f16_m(svcvt_f16_z(pg, bottom), pg_top, top);
134 return svtrn1(svcvt_f16_z(pg, bottom), svcvt_f16_z(pg_top, top));
138 inline svfloat32_t svtanh_f32_z(svbool_t pg, svfloat32_t val)
140 const svfloat32_t CONST_1 = svdup_n_f32(1.f);
141 const svfloat32_t CONST_2 = svdup_n_f32(2.f);
142 const svfloat32_t CONST_MIN_TANH = svdup_n_f32(-10.f);
143 const svfloat32_t CONST_MAX_TANH = svdup_n_f32(10.f);
145 svfloat32_t x = svmin_f32_z(pg, svmax_f32_z(pg, val, CONST_MIN_TANH), CONST_MAX_TANH);
146 svfloat32_t exp2x = svexp_f32_z(pg, svmul_f32_z(pg, CONST_2, x));
147 svfloat32_t num = svsub_f32_z(pg, exp2x, CONST_1);
148 svfloat32_t den = svadd_f32_z(pg, exp2x, CONST_1);
149 svfloat32_t tanh = svdiv_f32_z(pg, num, den);
153 inline svfloat16_t svtanh_f16_z(svbool_t pg, svfloat16_t val)
155 const svfloat16_t CONST_1 = svdup_n_f16(1.f);
156 const svfloat16_t CONST_2 = svdup_n_f16(2.f);
157 const svfloat16_t CONST_MIN_TANH = svdup_n_f16(-10.f);
158 const svfloat16_t CONST_MAX_TANH = svdup_n_f16(10.f);
160 const svfloat16_t x = svmin_f16_z(pg, svmax_f16_z(pg, val, CONST_MIN_TANH), CONST_MAX_TANH);
161 const svfloat16_t exp2x = svexp_f16_z(pg, svmul_f16_z(pg, CONST_2, x));
162 const svfloat16_t num = svsub_f16_z(pg, exp2x, CONST_1);
163 const svfloat16_t den = svadd_f16_z(pg, exp2x, CONST_1);
164 const svfloat16_t tanh = svdiv_f16_z(pg, num, den);
168 inline svfloat32_t svlog_f32_z(svbool_t pg, svfloat32_t x)
171 const svfloat32_t log_tab_1 = svdup_n_f32(-2.29561495781f);
172 const svfloat32_t log_tab_2 = svdup_n_f32(-2.47071170807f);
173 const svfloat32_t log_tab_3 = svdup_n_f32(-5.68692588806f);
174 const svfloat32_t log_tab_4 = svdup_n_f32(-0.165253549814f);
175 const svfloat32_t log_tab_5 = svdup_n_f32(5.17591238022f);
176 const svfloat32_t log_tab_6 = svdup_n_f32(0.844007015228f);
177 const svfloat32_t log_tab_7 = svdup_n_f32(4.58445882797f);
178 const svfloat32_t log_tab_8 = svdup_n_f32(0.0141278216615f);
180 const auto CONST_127 = svdup_n_s32(127);
181 const auto CONST_LN2 = svdup_n_f32(0.6931471805f);
184 auto m = svsub_s32_z(pg, svasr_n_s32_z(pg, svreinterpret_s32_f32(x), 23), CONST_127);
185 auto val = svreinterpret_f32_s32(svsub_s32_z(pg, svreinterpret_s32_f32(x), svlsl_n_s32_z(pg, m, 23)));
188 auto poly = svtaylor_poly_f32_z(pg, val, log_tab_1, log_tab_2, log_tab_3, log_tab_4, log_tab_5, log_tab_6, log_tab_7, log_tab_8);
191 poly = svmla_f32_z(pg, poly, svcvt_f32_s32_z(pg, m), CONST_LN2);
196 inline svfloat16_t svlog_f16_z(svbool_t pg, svfloat16_t x)
198 auto bottom = svcvt_f32_z(pg, x);
199 #if defined(ARM_COMPUTE_ENABLE_SVE2) 200 auto top = svcvtlt_f32_x(pg, x);
203 auto pg_top = svptrue_b16();
204 auto top = svcvt_f32_z(pg_top, svreinterpret_f16(svrevh_z(svptrue_b16(), svreinterpret_u32(x))));
207 bottom = svlog_f32_z(pg, bottom);
208 top = svlog_f32_z(pg_top, top);
210 #if defined(ARM_COMPUTE_ENABLE_SVE2) 211 return svcvtnt_f16_m(svcvt_f16_z(pg, bottom), pg_top, top);
213 return svtrn1(svcvt_f16_z(pg, bottom), svcvt_f16_z(pg_top, top));
217 inline svfloat32_t svsin_f32_z(svbool_t pg, svfloat32_t val)
219 using ScalarType = float;
220 using IntType = uint32_t;
227 const auto pi_v = wrapper::svdup_n(ScalarType(
M_PI));
228 const auto pio2_v = wrapper::svdup_n(ScalarType(
M_PI / 2));
229 const auto ipi_v = wrapper::svdup_n(ScalarType(1 /
M_PI));
232 const auto c_v = svabs_z(pg, wrapper::svcvt_z<int32_t>(pg, svmul_z(pg, val, ipi_v)));
233 const auto sign_v = svcmple(pg, val, wrapper::svdup_n(ScalarType(0)));
234 const auto odd_v = svcmpne(pg, svand_z(pg, wrapper::svreinterpret<IntType>(c_v), wrapper::svdup_n(IntType(1))), wrapper::svdup_n(IntType(0)));
236 auto neg_v = sveor_z(pg, odd_v, sign_v);
239 auto ma = svsub_z(pg, svabs_z(pg, val), svmul_z(pg, pi_v, wrapper::svcvt_z<ScalarType>(pg, c_v)));
240 const auto reb_v = svcmpge(pg, ma, pio2_v);
243 ma = svsel(reb_v, svsub_z(pg, pi_v, ma), ma);
246 const auto ma2 = svmul_z(pg, ma, ma);
249 auto elem = svmul_z(pg, svmul_z(pg, ma, ma2), wrapper::svdup_n(ScalarType(te_sin_coeff2)));
250 auto res = svsub_z(pg, ma, elem);
253 elem = svmul_z(pg, svmul_z(pg, elem, ma2), wrapper::svdup_n(ScalarType(te_sin_coeff3)));
254 res = svadd_z(pg, res, elem);
257 elem = svmul_z(pg, svmul_z(pg, elem, ma2), wrapper::svdup_n(ScalarType(te_sin_coeff4)));
258 res = svsub_z(pg, res, elem);
261 elem = svmul_z(pg, svmul_z(pg, elem, ma2), wrapper::svdup_n(ScalarType(te_sin_coeff5)));
262 res = svadd_z(pg, res, elem);
265 res = svneg_m(res, neg_v, res);
269 inline svfloat16_t svsin_f16_z(svbool_t pg, svfloat16_t val)
271 auto bottom = svcvt_f32_z(pg, val);
272 #if defined(ARM_COMPUTE_ENABLE_SVE2) 273 auto top = svcvtlt_f32_x(pg, val);
276 auto pg_top = svptrue_b16();
277 auto top = svcvt_f32_z(pg_top, svreinterpret_f16(svrevh_z(svptrue_b16(), svreinterpret_u32(val))));
280 bottom = svsin_f32_z(pg, bottom);
281 top = svsin_f32_z(pg_top, top);
283 #if defined(ARM_COMPUTE_ENABLE_SVE2) 284 return svcvtnt_f16_m(svcvt_f16_z(pg, bottom), pg_top, top);
286 return svtrn1(svcvt_f16_z(pg, bottom), svcvt_f16_z(pg_top, top));
290 inline svfloat32_t svpow_f32_z(svbool_t pg, svfloat32_t a, svfloat32_t
b)
292 return svexp_f32_z(pg, svmul_z(pg, b, svlog_f32_z(pg, a)));
295 inline svfloat16_t svpow_f16_z(svbool_t pg, svfloat16_t a, svfloat16_t b)
297 auto a_bottom = svcvt_f32_z(pg, a);
298 auto b_bottom = svcvt_f32_z(pg, b);
300 #if defined(ARM_COMPUTE_ENABLE_SVE2) 302 auto a_top = svcvtlt_f32_x(pg, a);
303 auto b_top = svcvtlt_f32_x(pg, b);
305 auto pg_top = svptrue_b16();
306 auto a_top = svcvt_f32_z(pg_top, svreinterpret_f16(svrevh_z(svptrue_b16(), svreinterpret_u32(a))));
307 auto b_top = svcvt_f32_z(pg_top, svreinterpret_f16(svrevh_z(svptrue_b16(), svreinterpret_u32(b))));
310 auto res_bottom = svpow_f32_z(pg, a_bottom, b_bottom);
311 auto res_top = svpow_f32_z(pg_top, a_top, b_top);
313 #if defined(ARM_COMPUTE_ENABLE_SVE2) 314 return svcvtnt_f16_m(svcvt_f16_z(pg, res_bottom), pg_top, res_top);
316 return svtrn1(svcvt_f16_z(pg, res_bottom), svcvt_f16_z(pg_top, res_top));
320 #if defined(ARM_COMPUTE_ENABLE_SVE2) 322 inline svuint8_t convert_float_to_int<svuint8_t>(
const svfloat32_t &in_0,
const svfloat32_t &in_1,
const svfloat32_t &in_2,
const svfloat32_t &in_3)
325 const auto all_true_pg = svptrue_b32();
326 auto tmp_0 = svcvt_u32_f32_z(all_true_pg, in_0);
327 auto tmp_1 = svcvt_u32_f32_z(all_true_pg, in_1);
328 auto tmp_2 = svcvt_u32_f32_z(all_true_pg, in_2);
329 auto tmp_3 = svcvt_u32_f32_z(all_true_pg, in_3);
331 auto tmp_16_0 = svqxtnt_u32(svqxtnb_u32(tmp_0), tmp_1);
332 auto tmp_16_1 = svqxtnt_u32(svqxtnb_u32(tmp_2), tmp_3);
334 auto tmp_16_uzp_0 = svuzp1(tmp_16_0, tmp_16_0);
335 auto tmp_16_uzp_1 = svuzp2(tmp_16_0, tmp_16_0);
336 auto tmp_16_uzp_2 = svuzp1(tmp_16_1, tmp_16_1);
337 auto tmp_16_uzp_3 = svuzp2(tmp_16_1, tmp_16_1);
339 auto pg = svwhilelt_b16_s32(0, svcnth() / 2);
341 tmp_16_0 = svsplice(pg, tmp_16_uzp_0, tmp_16_uzp_1);
342 tmp_16_1 = svsplice(pg, tmp_16_uzp_2, tmp_16_uzp_3);
344 out = svqxtnt_u16(svqxtnb_u16(tmp_16_0), tmp_16_1);
346 auto out_uzp_0 = svuzp1(out, out);
347 auto out_uzp_1 = svuzp2(out, out);
349 pg = svwhilelt_b8_s32(0, svcntb() / 2);
350 out = svsplice(pg, out_uzp_0, out_uzp_1);
356 inline svint8_t convert_float_to_int<svint8_t>(
const svfloat32_t &in_0,
const svfloat32_t &in_1,
const svfloat32_t &in_2,
const svfloat32_t &in_3)
359 const auto all_true_pg = svptrue_b32();
360 auto tmp_0 = svcvt_s32_f32_z(all_true_pg, in_0);
361 auto tmp_1 = svcvt_s32_f32_z(all_true_pg, in_1);
362 auto tmp_2 = svcvt_s32_f32_z(all_true_pg, in_2);
363 auto tmp_3 = svcvt_s32_f32_z(all_true_pg, in_3);
365 auto tmp_16_0 = svqxtnt_s32(svqxtnb_s32(tmp_0), tmp_1);
366 auto tmp_16_1 = svqxtnt_s32(svqxtnb_s32(tmp_2), tmp_3);
368 auto tmp_16_uzp_0 = svuzp1(tmp_16_0, tmp_16_0);
369 auto tmp_16_uzp_1 = svuzp2(tmp_16_0, tmp_16_0);
370 auto tmp_16_uzp_2 = svuzp1(tmp_16_1, tmp_16_1);
371 auto tmp_16_uzp_3 = svuzp2(tmp_16_1, tmp_16_1);
373 auto pg = svwhilelt_b16_s32(0, svcnth() / 2);
375 tmp_16_0 = svsplice(pg, tmp_16_uzp_0, tmp_16_uzp_1);
376 tmp_16_1 = svsplice(pg, tmp_16_uzp_2, tmp_16_uzp_3);
378 out = svqxtnt_s16(svqxtnb_s16(tmp_16_0), tmp_16_1);
380 auto out_uzp_0 = svuzp1(out, out);
381 auto out_uzp_1 = svuzp2(out, out);
383 pg = svwhilelt_b8_s32(0, svcntb() / 2);
384 out = svsplice(pg, out_uzp_0, out_uzp_1);
constexpr float te_sin_coeff5
Copyright (c) 2017-2021 Arm Limited.
constexpr float te_sin_coeff3
constexpr float te_sin_coeff4
constexpr float te_sin_coeff2
Sin polynomial coefficients.