blob: eef1be06ebbd04481cf72e08f41e751a5675fd3f [file] [log] [blame]
Georgios Pinitas57c033b2018-02-15 12:29:44 +00001/*
Michele Di Giorgiod9eaf612020-07-08 11:12:57 +01002 * Copyright (c) 2018-2020 Arm Limited.
Georgios Pinitas57c033b2018-02-15 12:29:44 +00003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
Michalis Spyrouf4643372019-11-29 16:17:13 +000024#ifndef ARM_COMPUTE_DETAIL_NEACTIVATION_FUNCTION_DETAIL_H
25#define ARM_COMPUTE_DETAIL_NEACTIVATION_FUNCTION_DETAIL_H
Georgios Pinitas57c033b2018-02-15 12:29:44 +000026
Georgios Pinitasddb93bb2020-10-02 16:38:59 +010027#include "src/core/NEON/wrapper/wrapper.h"
Georgios Pinitas57c033b2018-02-15 12:29:44 +000028
29namespace arm_compute
30{
31namespace detail
32{
Georgios Pinitas57c033b2018-02-15 12:29:44 +000033/** Dummy activation object */
34template <typename T, int S>
35struct dummy
36{
Alex Gildayc357c472018-03-21 13:54:09 +000037 /** NEON vector type. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +000038 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
39
Alex Gildayc357c472018-03-21 13:54:09 +000040 /** Construct a dummy activation object.
41 *
42 * @param[in] act_info Activation layer information.
43 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +000044 explicit dummy(ActivationLayerInfo act_info)
45 {
46 ARM_COMPUTE_UNUSED(act_info);
47 }
Georgios Pinitas980a9162020-06-03 20:16:46 +010048
Alex Gildayc357c472018-03-21 13:54:09 +000049 /** Run activation function.
50 *
51 * @param[in] vval Vector of values.
52 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +000053 void operator()(ExactType &vval)
54 {
55 ARM_COMPUTE_UNUSED(vval);
56 }
Georgios Pinitas980a9162020-06-03 20:16:46 +010057
58 /** Run activation function.
59 *
60 * @param[in] val Scalar value.
61 */
62 void operator()(T &val)
63 {
64 ARM_COMPUTE_UNUSED(val);
65 }
Georgios Pinitas57c033b2018-02-15 12:29:44 +000066};
Michalis Spyroua6825a42018-09-13 12:24:03 +010067/** Linear activation object */
68template <typename T, int S>
69struct linear
70{
71 /** NEON vector type. */
72 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
73 /** NEON vector tag type. */
74 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
75
76 /** Construct a Linear activation object.
77 *
78 * @param[in] act_info Activation layer information.
79 */
80 explicit linear(ActivationLayerInfo act_info)
Georgios Pinitas980a9162020-06-03 20:16:46 +010081 : alpha(act_info.a()),
82 beta(act_info.b()),
83 valpha(wrapper::vdup_n(static_cast<T>(alpha), ExactTagType{})),
84 vbeta(wrapper::vdup_n(static_cast<T>(beta), ExactTagType{}))
Michalis Spyroua6825a42018-09-13 12:24:03 +010085 {
86 }
87
88 /** Run activation function.
89 *
90 * @param[in] vval Vector of values.
91 */
92 void operator()(ExactType &vval)
93 {
Georgios Pinitas980a9162020-06-03 20:16:46 +010094 vval = wrapper::vmla(vbeta, vval, valpha);
Michalis Spyroua6825a42018-09-13 12:24:03 +010095 }
96
Georgios Pinitas980a9162020-06-03 20:16:46 +010097 /** Run activation function.
98 *
99 * @param[in] val Scalar value.
100 */
101 void operator()(T &val)
102 {
103 val = alpha * val + beta;
104 }
105
106 const T alpha; /**< Scalar alpha */
107 const T beta; /**< Scalar alpha */
108 const ExactType valpha; /**< Vector of alphas. */
109 const ExactType vbeta; /**< Vector of betas. */
Michalis Spyroua6825a42018-09-13 12:24:03 +0100110};
111/** Square activation object */
112template <typename T, int S>
113struct square
114{
115 /** NEON vector type. */
116 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
117 /** NEON vector tag type. */
118 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
119
120 /** Construct a Square activation object.
121 *
122 * @param[in] act_info Activation layer information.
123 */
124 explicit square(ActivationLayerInfo act_info)
125 {
126 ARM_COMPUTE_UNUSED(act_info);
127 }
128
129 /** Run activation function.
130 *
131 * @param[in] vval Vector of values.
132 */
133 void operator()(ExactType &vval)
134 {
135 vval = wrapper::vmul(vval, vval);
136 }
Georgios Pinitas980a9162020-06-03 20:16:46 +0100137
138 /** Run activation function.
139 *
140 * @param[in] val Scalar value.
141 */
142 void operator()(T &val)
143 {
144 val = val * val;
145 }
Michalis Spyroua6825a42018-09-13 12:24:03 +0100146};
147/** Logistic activation object */
148template <typename T, int S>
149struct logistic
150{
151 /** NEON vector type. */
152 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
153 /** NEON vector tag type. */
154 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
155
156 /** Construct a Logistic activation object.
157 *
158 * @param[in] act_info Activation layer information.
159 */
160 explicit logistic(ActivationLayerInfo act_info)
Georgios Pinitas980a9162020-06-03 20:16:46 +0100161 : vone(wrapper::vdup_n(static_cast<T>(1), ExactTagType{}))
Michalis Spyroua6825a42018-09-13 12:24:03 +0100162 {
163 ARM_COMPUTE_UNUSED(act_info);
164 }
165
166 /** Run activation function.
167 *
168 * @param[in] vval Vector of values.
169 */
170 void operator()(ExactType &vval)
171 {
Georgios Pinitas5a594532018-12-03 14:30:05 +0000172 vval = wrapper::vinv(wrapper::vadd(vone, wrapper::vexpq(wrapper::vneg(vval))));
Michalis Spyroua6825a42018-09-13 12:24:03 +0100173 }
174
Georgios Pinitas980a9162020-06-03 20:16:46 +0100175 /** Run activation function.
176 *
177 * @param[in] val Scalar value.
178 */
179 void operator()(T &val)
180 {
181 val = 1 / (1 + std::exp(-val));
182 }
183
Michalis Spyroua6825a42018-09-13 12:24:03 +0100184 /** Vector of ones. */
185 const ExactType vone;
186};
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000187/** RELU activation object */
188template <typename T, int S>
189struct relu
190{
Alex Gildayc357c472018-03-21 13:54:09 +0000191 /** NEON vector type. */
192 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
193 /** NEON vector tag type. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000194 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
195
Alex Gildayc357c472018-03-21 13:54:09 +0000196 /** Construct a RELU activation object.
197 *
198 * @param[in] act_info Activation layer information.
199 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000200 explicit relu(ActivationLayerInfo act_info)
Georgios Pinitas980a9162020-06-03 20:16:46 +0100201 : vzero(wrapper::vdup_n(static_cast<T>(0), ExactTagType{}))
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000202 {
203 ARM_COMPUTE_UNUSED(act_info);
204 }
205
Alex Gildayc357c472018-03-21 13:54:09 +0000206 /** Run activation function.
207 *
208 * @param[in] vval Vector of values.
209 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000210 void operator()(ExactType &vval)
211 {
212 vval = wrapper::vmax(vzero, vval);
213 }
214
Georgios Pinitas980a9162020-06-03 20:16:46 +0100215 /** Run activation function.
216 *
217 * @param[in] val Scalar value.
218 */
219 void operator()(T &val)
220 {
221 val = std::max(static_cast<T>(0), val);
222 }
223
Alex Gildayc357c472018-03-21 13:54:09 +0000224 /** Vector of zeroes. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000225 const ExactType vzero;
226};
227/** Bounded RELU activation object */
228template <typename T, int S>
229struct brelu
230{
Alex Gildayc357c472018-03-21 13:54:09 +0000231 /** NEON vector type. */
232 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
233 /** NEON vector tag type. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000234 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
235
Alex Gildayc357c472018-03-21 13:54:09 +0000236 /** Construct a bounded RELU activation object.
237 *
238 * @param[in] act_info Activation layer information.
239 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000240 explicit brelu(ActivationLayerInfo act_info)
Georgios Pinitas980a9162020-06-03 20:16:46 +0100241 : alpha(act_info.a()),
242 vzero(wrapper::vdup_n(static_cast<T>(0), ExactTagType{})),
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000243 valpha(wrapper::vdup_n(static_cast<T>(act_info.a()), ExactTagType{}))
244 {
245 }
246
Alex Gildayc357c472018-03-21 13:54:09 +0000247 /** Run activation function.
248 *
249 * @param[in] vval Vector of values.
250 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000251 void operator()(ExactType &vval)
252 {
253 vval = wrapper::vmin(valpha, wrapper::vmax(vzero, vval));
254 }
255
Georgios Pinitas980a9162020-06-03 20:16:46 +0100256 /** Run activation function.
257 *
258 * @param[in] val Scalar value.
259 */
260 void operator()(T &val)
261 {
262 val = std::min(alpha, std::max(static_cast<T>(0), val));
263 }
264
265 const T alpha; /** Scalar alpha */
266 const ExactType vzero; /** Vector of zeroes. */
267 const ExactType valpha; /** Vector of alphas. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000268};
269/** Lower-Upper Bounded RELU activation object */
270template <typename T, int S>
271struct lubrelu
272{
Alex Gildayc357c472018-03-21 13:54:09 +0000273 /** NEON vector type. */
274 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
275 /** NEON vector tag type. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000276 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
277
Alex Gildayc357c472018-03-21 13:54:09 +0000278 /** Construct a lower-upper bounded RELU activation object.
279 *
280 * @param[in] act_info Activation layer information.
281 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000282 explicit lubrelu(ActivationLayerInfo act_info)
Georgios Pinitas980a9162020-06-03 20:16:46 +0100283 : alpha(act_info.a()),
284 beta(act_info.b()),
285 valpha(wrapper::vdup_n(static_cast<T>(act_info.a()), ExactTagType{})),
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000286 vbeta(wrapper::vdup_n(static_cast<T>(act_info.b()), ExactTagType{}))
287 {
288 }
289
Alex Gildayc357c472018-03-21 13:54:09 +0000290 /** Run activation function.
291 *
292 * @param[in] vval Vector of values.
293 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000294 void operator()(ExactType &vval)
295 {
296 vval = wrapper::vmin(valpha, wrapper::vmax(vbeta, vval));
297 }
298
Georgios Pinitas980a9162020-06-03 20:16:46 +0100299 /** Run activation function.
300 *
301 * @param[in] val Scalar value.
302 */
303 void operator()(T &val)
304 {
305 val = std::min(alpha, std::max(beta, val));
306 }
307
308 const T alpha; /**< Scalar alpha */
309 const T beta; /**< Scalar alpha */
310 const ExactType valpha; /** Vector of alphas. */
311 const ExactType vbeta; /** Vector of betas. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000312};
313} // namespace detail
314} // namespace arm_compute
Michalis Spyrouf4643372019-11-29 16:17:13 +0000315#endif /* ARM_COMPUTE_DETAIL_NEACTIVATION_FUNCTION_DETAIL_H */