MCPcopy Create free account
hub / github.com/MegEngine/MegCC / GetKernelBody

Method GetKernelBody

compiler/lib/KernelGen/Arm/ArmCommon/ExpNeonKernel.cpp:16–103  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

14}
15
16std::string ExpNeonKernel::GetKernelBody(TContext*) const {
17 std::stringstream writer;
18
19 writer << R"(
20 #include<arm_neon.h>
21 #include<math.h>
22
23 typedef float32x4_t v4sf; // vector of 4 float
24 typedef uint32x4_t v4su; // vector of 4 uint32
25 typedef int32x4_t v4si; // vector of 4 int32
26
27 #define c_exp_hi 88.3762626647949f
28 #define c_exp_lo -88.3762626647949f
29
30 #define c_cephes_LOG2EF 1.44269504088896341
31 #define c_cephes_exp_C1 0.693359375
32 #define c_cephes_exp_C2 -2.12194440e-4
33
34 #define c_cephes_exp_p0 1.9875691500E-4
35 #define c_cephes_exp_p1 1.3981999507E-3
36 #define c_cephes_exp_p2 8.3334519073E-3
37 #define c_cephes_exp_p3 4.1665795894E-2
38 #define c_cephes_exp_p4 1.6666665459E-1
39 #define c_cephes_exp_p5 5.0000001201E-1
40
41 /* exp() computed for 4 float at once */
42 float32x4_t exp_ps_f32(float32x4_t x) {
43 v4sf tmp, fx;
44
45 v4sf one = vdupq_n_f32(1);
46 x = vminq_f32(x, vdupq_n_f32(c_exp_hi));
47 x = vmaxq_f32(x, vdupq_n_f32(c_exp_lo));
48
49 /* express exp(x) as exp(g + n*log(2)) */
50 fx = vmlaq_f32(vdupq_n_f32(0.5f), x, vdupq_n_f32(c_cephes_LOG2EF));
51
52 /* perform a floorf */
53 tmp = vcvtq_f32_s32(vcvtq_s32_f32(fx));
54
55 /* if greater, subtract 1 */
56 v4su mask = vcgtq_f32(tmp, fx);
57 mask = vandq_u32(mask, vreinterpretq_u32_f32(one));
58
59 fx = vsubq_f32(tmp, vreinterpretq_f32_u32(mask));
60
61 tmp = vmulq_f32(fx, vdupq_n_f32(c_cephes_exp_C1));
62 v4sf z = vmulq_f32(fx, vdupq_n_f32(c_cephes_exp_C2));
63 x = vsubq_f32(x, tmp);
64 x = vsubq_f32(x, z);
65
66 static const float cephes_exp_p[6] = {c_cephes_exp_p0, c_cephes_exp_p1,
67 c_cephes_exp_p2, c_cephes_exp_p3,
68 c_cephes_exp_p4, c_cephes_exp_p5};
69 v4sf y = vld1q_dup_f32(cephes_exp_p + 0);
70 v4sf c1 = vld1q_dup_f32(cephes_exp_p + 1);
71 v4sf c2 = vld1q_dup_f32(cephes_exp_p + 2);
72 v4sf c3 = vld1q_dup_f32(cephes_exp_p + 3);
73 v4sf c4 = vld1q_dup_f32(cephes_exp_p + 4);

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected