1 // Tencent is pleased to support the open source community by making ncnn available.
2 //
3 // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 //
5 // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // https://opensource.org/licenses/BSD-3-Clause
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14
15 #include "unaryop.h"
16
17 #include <math.h>
18
19 namespace ncnn {
20
UnaryOp()21 UnaryOp::UnaryOp()
22 {
23 one_blob_only = true;
24 support_inplace = true;
25 }
26
load_param(const ParamDict & pd)27 int UnaryOp::load_param(const ParamDict& pd)
28 {
29 op_type = pd.get(0, 0);
30
31 return 0;
32 }
33
34 template<typename Op>
unary_op_inplace(Mat & a,const Option & opt)35 static int unary_op_inplace(Mat& a, const Option& opt)
36 {
37 Op op;
38
39 int size = static_cast<int>(a.total());
40
41 #pragma omp parallel for num_threads(opt.num_threads)
42 for (int i = 0; i < size; i++)
43 {
44 a[i] = op(a[i]);
45 }
46
47 return 0;
48 }
49
50 struct unary_op_abs
51 {
operator ()ncnn::unary_op_abs52 float operator()(const float& x) const
53 {
54 return (float)fabs(x);
55 }
56 };
57
58 struct unary_op_neg
59 {
operator ()ncnn::unary_op_neg60 float operator()(const float& x) const
61 {
62 return -x;
63 }
64 };
65
66 struct unary_op_floor
67 {
operator ()ncnn::unary_op_floor68 float operator()(const float& x) const
69 {
70 return (float)floor(x);
71 }
72 };
73
74 struct unary_op_ceil
75 {
operator ()ncnn::unary_op_ceil76 float operator()(const float& x) const
77 {
78 return (float)ceil(x);
79 }
80 };
81
82 struct unary_op_square
83 {
operator ()ncnn::unary_op_square84 float operator()(const float& x) const
85 {
86 return x * x;
87 }
88 };
89
90 struct unary_op_sqrt
91 {
operator ()ncnn::unary_op_sqrt92 float operator()(const float& x) const
93 {
94 return (float)sqrt(x);
95 }
96 };
97
98 struct unary_op_rsqrt
99 {
operator ()ncnn::unary_op_rsqrt100 float operator()(const float& x) const
101 {
102 return (float)(1.f / sqrt(x));
103 }
104 };
105
106 struct unary_op_exp
107 {
operator ()ncnn::unary_op_exp108 float operator()(const float& x) const
109 {
110 return (float)exp(x);
111 }
112 };
113
114 struct unary_op_log
115 {
operator ()ncnn::unary_op_log116 float operator()(const float& x) const
117 {
118 return (float)log(x);
119 }
120 };
121
122 struct unary_op_sin
123 {
operator ()ncnn::unary_op_sin124 float operator()(const float& x) const
125 {
126 return (float)sin(x);
127 }
128 };
129
130 struct unary_op_cos
131 {
operator ()ncnn::unary_op_cos132 float operator()(const float& x) const
133 {
134 return (float)cos(x);
135 }
136 };
137
138 struct unary_op_tan
139 {
operator ()ncnn::unary_op_tan140 float operator()(const float& x) const
141 {
142 return (float)tan(x);
143 }
144 };
145
146 struct unary_op_asin
147 {
operator ()ncnn::unary_op_asin148 float operator()(const float& x) const
149 {
150 return (float)asin(x);
151 }
152 };
153
154 struct unary_op_acos
155 {
operator ()ncnn::unary_op_acos156 float operator()(const float& x) const
157 {
158 return (float)acos(x);
159 }
160 };
161
162 struct unary_op_atan
163 {
operator ()ncnn::unary_op_atan164 float operator()(const float& x) const
165 {
166 return (float)atan(x);
167 }
168 };
169
170 struct unary_op_reciprocal
171 {
operator ()ncnn::unary_op_reciprocal172 float operator()(const float& x) const
173 {
174 return 1.f / x;
175 }
176 };
177
178 struct unary_op_tanh
179 {
operator ()ncnn::unary_op_tanh180 float operator()(const float& x) const
181 {
182 return (float)tanh(x);
183 }
184 };
185
forward_inplace(Mat & bottom_top_blob,const Option & opt) const186 int UnaryOp::forward_inplace(Mat& bottom_top_blob, const Option& opt) const
187 {
188 if (op_type == Operation_ABS)
189 return unary_op_inplace<unary_op_abs>(bottom_top_blob, opt);
190
191 if (op_type == Operation_NEG)
192 return unary_op_inplace<unary_op_neg>(bottom_top_blob, opt);
193
194 if (op_type == Operation_FLOOR)
195 return unary_op_inplace<unary_op_floor>(bottom_top_blob, opt);
196
197 if (op_type == Operation_CEIL)
198 return unary_op_inplace<unary_op_ceil>(bottom_top_blob, opt);
199
200 if (op_type == Operation_SQUARE)
201 return unary_op_inplace<unary_op_square>(bottom_top_blob, opt);
202
203 if (op_type == Operation_SQRT)
204 return unary_op_inplace<unary_op_sqrt>(bottom_top_blob, opt);
205
206 if (op_type == Operation_RSQRT)
207 return unary_op_inplace<unary_op_rsqrt>(bottom_top_blob, opt);
208
209 if (op_type == Operation_EXP)
210 return unary_op_inplace<unary_op_exp>(bottom_top_blob, opt);
211
212 if (op_type == Operation_LOG)
213 return unary_op_inplace<unary_op_log>(bottom_top_blob, opt);
214
215 if (op_type == Operation_SIN)
216 return unary_op_inplace<unary_op_sin>(bottom_top_blob, opt);
217
218 if (op_type == Operation_COS)
219 return unary_op_inplace<unary_op_cos>(bottom_top_blob, opt);
220
221 if (op_type == Operation_TAN)
222 return unary_op_inplace<unary_op_tan>(bottom_top_blob, opt);
223
224 if (op_type == Operation_ASIN)
225 return unary_op_inplace<unary_op_asin>(bottom_top_blob, opt);
226
227 if (op_type == Operation_ACOS)
228 return unary_op_inplace<unary_op_acos>(bottom_top_blob, opt);
229
230 if (op_type == Operation_ATAN)
231 return unary_op_inplace<unary_op_atan>(bottom_top_blob, opt);
232
233 if (op_type == Operation_RECIPROCAL)
234 return unary_op_inplace<unary_op_reciprocal>(bottom_top_blob, opt);
235
236 if (op_type == Operation_TANH)
237 return unary_op_inplace<unary_op_tanh>(bottom_top_blob, opt);
238
239 return 0;
240 }
241
242 } // namespace ncnn
243