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