blob: 95cdc8f2f9e73bbdc0c2ce556563ef016c1c103c [file] [log] [blame]
Georgios Pinitas57c033b2018-02-15 12:29:44 +00001/*
Matthew Benthamf1aeab92023-05-30 13:35:34 +00002 * Copyright (c) 2018-2021, 2023 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
SiCong Li91295492023-07-21 18:16:13 +010027#include "arm_compute/function_info/ActivationLayerInfo.h"
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010028
Georgios Pinitasddb93bb2020-10-02 16:38:59 +010029#include "src/core/NEON/wrapper/wrapper.h"
Georgios Pinitas57c033b2018-02-15 12:29:44 +000030
31namespace arm_compute
32{
33namespace detail
34{
Georgios Pinitas57c033b2018-02-15 12:29:44 +000035/** Dummy activation object */
36template <typename T, int S>
37struct dummy
38{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +000039 /** SIMD vector type. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +000040 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
41
Alex Gildayc357c472018-03-21 13:54:09 +000042 /** Construct a dummy activation object.
43 *
44 * @param[in] act_info Activation layer information.
45 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +000046 explicit dummy(ActivationLayerInfo act_info)
47 {
48 ARM_COMPUTE_UNUSED(act_info);
49 }
Georgios Pinitas980a9162020-06-03 20:16:46 +010050
Alex Gildayc357c472018-03-21 13:54:09 +000051 /** Run activation function.
52 *
53 * @param[in] vval Vector of values.
54 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +000055 void operator()(ExactType &vval)
56 {
57 ARM_COMPUTE_UNUSED(vval);
58 }
Georgios Pinitas980a9162020-06-03 20:16:46 +010059
60 /** Run activation function.
61 *
62 * @param[in] val Scalar value.
63 */
64 void operator()(T &val)
65 {
66 ARM_COMPUTE_UNUSED(val);
67 }
Georgios Pinitas57c033b2018-02-15 12:29:44 +000068};
Michalis Spyroua6825a42018-09-13 12:24:03 +010069/** Linear activation object */
70template <typename T, int S>
71struct linear
72{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +000073 /** SIMD vector type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +010074 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +000075 /** SIMD vector tag type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +010076 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
77
78 /** Construct a Linear activation object.
79 *
80 * @param[in] act_info Activation layer information.
81 */
82 explicit linear(ActivationLayerInfo act_info)
Georgios Pinitas980a9162020-06-03 20:16:46 +010083 : alpha(act_info.a()),
84 beta(act_info.b()),
85 valpha(wrapper::vdup_n(static_cast<T>(alpha), ExactTagType{})),
86 vbeta(wrapper::vdup_n(static_cast<T>(beta), ExactTagType{}))
Michalis Spyroua6825a42018-09-13 12:24:03 +010087 {
88 }
89
90 /** Run activation function.
91 *
92 * @param[in] vval Vector of values.
93 */
94 void operator()(ExactType &vval)
95 {
Georgios Pinitas980a9162020-06-03 20:16:46 +010096 vval = wrapper::vmla(vbeta, vval, valpha);
Michalis Spyroua6825a42018-09-13 12:24:03 +010097 }
98
Georgios Pinitas980a9162020-06-03 20:16:46 +010099 /** Run activation function.
100 *
101 * @param[in] val Scalar value.
102 */
103 void operator()(T &val)
104 {
105 val = alpha * val + beta;
106 }
107
108 const T alpha; /**< Scalar alpha */
109 const T beta; /**< Scalar alpha */
110 const ExactType valpha; /**< Vector of alphas. */
111 const ExactType vbeta; /**< Vector of betas. */
Michalis Spyroua6825a42018-09-13 12:24:03 +0100112};
113/** Square activation object */
114template <typename T, int S>
115struct square
116{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000117 /** SIMD vector type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +0100118 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000119 /** SIMD vector tag type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +0100120 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
121
122 /** Construct a Square activation object.
123 *
124 * @param[in] act_info Activation layer information.
125 */
126 explicit square(ActivationLayerInfo act_info)
127 {
128 ARM_COMPUTE_UNUSED(act_info);
129 }
130
131 /** Run activation function.
132 *
133 * @param[in] vval Vector of values.
134 */
135 void operator()(ExactType &vval)
136 {
137 vval = wrapper::vmul(vval, vval);
138 }
Georgios Pinitas980a9162020-06-03 20:16:46 +0100139
140 /** Run activation function.
141 *
142 * @param[in] val Scalar value.
143 */
144 void operator()(T &val)
145 {
146 val = val * val;
147 }
Michalis Spyroua6825a42018-09-13 12:24:03 +0100148};
149/** Logistic activation object */
150template <typename T, int S>
151struct logistic
152{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000153 /** SIMD vector type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +0100154 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000155 /** SIMD vector tag type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +0100156 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
157
158 /** Construct a Logistic activation object.
159 *
160 * @param[in] act_info Activation layer information.
161 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100162 explicit logistic(ActivationLayerInfo act_info) : vone(wrapper::vdup_n(static_cast<T>(1), ExactTagType{}))
Michalis Spyroua6825a42018-09-13 12:24:03 +0100163 {
164 ARM_COMPUTE_UNUSED(act_info);
165 }
166
167 /** Run activation function.
168 *
169 * @param[in] vval Vector of values.
170 */
171 void operator()(ExactType &vval)
172 {
Georgios Pinitas5a594532018-12-03 14:30:05 +0000173 vval = wrapper::vinv(wrapper::vadd(vone, wrapper::vexpq(wrapper::vneg(vval))));
Michalis Spyroua6825a42018-09-13 12:24:03 +0100174 }
175
Georgios Pinitas980a9162020-06-03 20:16:46 +0100176 /** Run activation function.
177 *
178 * @param[in] val Scalar value.
179 */
180 void operator()(T &val)
181 {
182 val = 1 / (1 + std::exp(-val));
183 }
184
Michalis Spyroua6825a42018-09-13 12:24:03 +0100185 /** Vector of ones. */
186 const ExactType vone;
187};
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000188/** RELU activation object */
189template <typename T, int S>
190struct relu
191{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000192 /** SIMD vector type. */
Alex Gildayc357c472018-03-21 13:54:09 +0000193 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000194 /** SIMD vector tag type. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000195 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
196
Alex Gildayc357c472018-03-21 13:54:09 +0000197 /** Construct a RELU activation object.
198 *
199 * @param[in] act_info Activation layer information.
200 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100201 explicit relu(ActivationLayerInfo act_info) : 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{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000231 /** SIMD vector type. */
Alex Gildayc357c472018-03-21 13:54:09 +0000232 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000233 /** SIMD 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{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000273 /** SIMD vector type. */
Alex Gildayc357c472018-03-21 13:54:09 +0000274 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000275 /** SIMD 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 */