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