• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2020-2022 Huawei Technologies Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <math.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include "nnacl/fp32/arithmetic_self_fp32.h"
20 #include "nnacl/arithmetic_self_fp32_simd.h"
21 
ElementAbs(const float * input,float * output,const int element_size)22 int ElementAbs(const float *input, float *output, const int element_size) {
23   int i = 0;
24 
25   // only avx512 support abs fp32 instruction
26   SIMD_RUN_AVX512(ElementAbs, i, input, output, element_size);
27   for (; i < element_size; i++) {
28     output[i] = fabsf(input[i]);
29   }
30   return NNACL_OK;
31 }
32 
ElementAbsInt(const int32_t * input,int32_t * output,const int element_size)33 int ElementAbsInt(const int32_t *input, int32_t *output, const int element_size) {
34   int i = 0;
35 
36   // only avx512 support abs fp32 instruction
37   SIMD_RUN_AVX512(ElementAbsInt, i, input, output, element_size);
38   for (; i < element_size; i++) {
39     output[i] = abs(input[i]);
40   }
41   return NNACL_OK;
42 }
43 
44 // cos
ElementCos(const float * input,float * output,const int element_size)45 int ElementCos(const float *input, float *output, const int element_size) {
46   int i = 0;
47   SIMD_RUN_X86_NO_SCALAR(ElementCos, i, input, output, element_size);
48   for (; i < element_size; i++) {
49     output[i] = cosf(input[i]);
50   }
51   return NNACL_OK;
52 }
53 
54 // log:
ElementLog(const float * input,float * output,const int element_size)55 int ElementLog(const float *input, float *output, const int element_size) {
56   int i = 0;
57 
58   SIMD_RUN_X86_NO_SCALAR(ElementLog, i, input, output, element_size);
59   for (; i < element_size; i++) {
60     if (MS_UNLIKELY(input[i] < 0)) {
61       return NNACL_ERRCODE_LOG_NEGATIVE_OR_ZERO;
62     }
63     output[i] = logf(input[i]);
64   }
65   return NNACL_OK;
66 }
67 
68 // log1p:
ElementLog1p(const float * input,float * output,const int element_size)69 int ElementLog1p(const float *input, float *output, const int element_size) {
70   for (int i = 0; i < element_size; i++) {
71     if (MS_UNLIKELY(input[i] < -1.0f)) {
72       return NNACL_ERRCODE_LOG_NEGATIVE_OR_ZERO;
73     }
74     output[i] = log1p(input[i]);
75   }
76   return NNACL_OK;
77 }
78 
ElementSquare(const float * input,float * output,const int element_size)79 int ElementSquare(const float *input, float *output, const int element_size) {
80   int i = 0;
81 
82   SIMD_RUN_NO_SCALAR(ElementSquare, i, input, output, element_size);
83   for (; i < element_size; i++) {
84     output[i] = input[i] * input[i];
85   }
86   return NNACL_OK;
87 }
88 
ElementSqrt(const float * input,float * output,const int element_size)89 int ElementSqrt(const float *input, float *output, const int element_size) {
90   int i = 0;
91 
92   SIMD_RUN_NO_SCALAR(ElementSqrt, i, input, output, element_size);
93   for (; i < element_size; i++) {
94     if (MS_UNLIKELY(input[i] < 0)) {
95       return NNACL_ERRCODE_SQRT_NEGATIVE;
96     }
97     output[i] = sqrtf(input[i]);
98   }
99   return NNACL_OK;
100 }
101 
ElementRsqrt(const float * input,float * output,const int element_size)102 int ElementRsqrt(const float *input, float *output, const int element_size) {
103   int i = 0;
104 
105   SIMD_RUN_NO_SCALAR(ElementRsqrt, i, input, output, element_size);
106   for (; i < element_size; i++) {
107     if (MS_UNLIKELY(input[i] < 0)) {
108       return NNACL_ERRCODE_RSQRT_NEGATIVE;
109     }
110     output[i] = 1.f / sqrtf(input[i]);
111   }
112   return NNACL_OK;
113 }
114 
ElementSin(const float * input,float * output,const int element_size)115 int ElementSin(const float *input, float *output, const int element_size) {
116   for (int i = 0; i < element_size; i++) {
117     output[i] = sinf(input[i]);
118   }
119   return NNACL_OK;
120 }
121 
122 // logical_not:
ElementLogicalNot(const float * input,float * output,const int element_size)123 int ElementLogicalNot(const float *input, float *output, const int element_size) {
124   for (int i = 0; i < element_size; i++) {
125     output[i] = (float)(!((bool)(input[i])));
126   }
127   return NNACL_OK;
128 }
129 
130 // logical_not:
ElementLogicalNotBool(const bool * input,bool * output,const int element_size)131 int ElementLogicalNotBool(const bool *input, bool *output, const int element_size) {
132   for (int i = 0; i < element_size; i++) {
133     output[i] = !input[i];
134   }
135   return NNACL_OK;
136 }
137 
ElementRound(const float * input,float * output,const int element_size)138 int ElementRound(const float *input, float *output, const int element_size) {
139   int i = 0;
140 
141   SIMD_RUN_AVX(ElementRound, i, input, output, element_size);
142   SIMD_RUN_SSE(ElementRound, i, input, output, element_size);
143   for (; i < element_size; i++) {
144     output[i] = roundf(input[i]);
145   }
146   return NNACL_OK;
147 }
148 
ElementFloor(const float * input,float * output,const int element_size)149 int ElementFloor(const float *input, float *output, const int element_size) {
150   int i = 0;
151 
152   SIMD_RUN_X86_NO_SCALAR(ElementFloor, i, input, output, element_size);
153   for (; i < element_size; i++) {
154     output[i] = floorf(input[i]);
155   }
156   return NNACL_OK;
157 }
158 
ElementCeil(const float * input,float * output,const int element_size)159 int ElementCeil(const float *input, float *output, const int element_size) {
160   int i = 0;
161 
162   SIMD_RUN_X86_NO_SCALAR(ElementCeil, i, input, output, element_size);
163   for (; i < element_size; ++i) {
164     output[i] = ceilf(input[i]);
165   }
166   return NNACL_OK;
167 }
168 
ElementNegative(const float * input,float * output,const int element_size)169 int ElementNegative(const float *input, float *output, const int element_size) {
170   int i = 0;
171 
172   SIMD_RUN_NO_SCALAR(ElementNegative, i, input, output, element_size);
173   for (; i < element_size; ++i) {
174     output[i] = -input[i];
175   }
176   return NNACL_OK;
177 }
178 
ElementNegativeInt(const int32_t * input,int32_t * output,const int element_size)179 int ElementNegativeInt(const int32_t *input, int32_t *output, const int element_size) {
180   int i = 0;
181 
182   SIMD_RUN_NO_SCALAR(ElementNegativeInt, i, input, output, element_size);
183   for (; i < element_size; ++i) {
184     output[i] = -input[i];
185   }
186   return NNACL_OK;
187 }
188 
ElementReciprocal(const float * input,float * output,const int element_size)189 int ElementReciprocal(const float *input, float *output, const int element_size) {
190   int i = 0;
191 
192   SIMD_RUN_NO_SCALAR(ElementReciprocal, i, input, output, element_size);
193   for (; i < element_size; ++i) {
194     if (input[i] == 0.0f) {
195       return NNACL_ERR;
196     }
197     output[i] = 1.f / input[i];
198   }
199   return NNACL_OK;
200 }
201 
202 // Erf
ElementErf(const float * input,float * output,const int element_size)203 int ElementErf(const float *input, float *output, const int element_size) {
204   for (int i = 0; i < element_size; i++) {
205     output[i] = erff(input[i]);
206   }
207   return NNACL_OK;
208 }
209 
ElementIsFinite(const float * input,bool * output,const int element_size)210 int ElementIsFinite(const float *input, bool *output, const int element_size) {
211   for (int i = 0; i < element_size; i++) {
212     output[i] = true;
213     if (isnan(input[i]) || isinf(input[i])) {
214       output[i] = false;
215     }
216   }
217   return NNACL_OK;
218 }
219 
ElementMish(const float * input,float * output,const int element_size)220 int ElementMish(const float *input, float *output, const int element_size) {
221   int i = 0;
222   SIMD_RUN_NO_SCALAR(ElementMish, i, input, output, element_size);
223 
224   for (; i < element_size; ++i) {
225     simd_exp32(input[i], output + i);
226     float exp_pow = (output[i] + 1) * (output[i] + 1);
227     output[i] = input[i] * (exp_pow - 1) / (exp_pow + 1);
228   }
229   return NNACL_OK;
230 }
231