blob: 3900ea62cdddbf5e5dca98f4a70fb4fb19389dd0 [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"
Georgios Pinitasddb93bb2020-10-02 16:38:59 +010028#include "src/core/NEON/wrapper/wrapper.h"
Georgios Pinitas57c033b2018-02-15 12:29:44 +000029
30namespace arm_compute
31{
32namespace detail
33{
Georgios Pinitas57c033b2018-02-15 12:29:44 +000034/** Dummy activation object */
35template <typename T, int S>
36struct dummy
37{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +000038 /** SIMD vector type. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +000039 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
40
Alex Gildayc357c472018-03-21 13:54:09 +000041 /** Construct a dummy activation object.
42 *
43 * @param[in] act_info Activation layer information.
44 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +000045 explicit dummy(ActivationLayerInfo act_info)
46 {
47 ARM_COMPUTE_UNUSED(act_info);
48 }
Georgios Pinitas980a9162020-06-03 20:16:46 +010049
Alex Gildayc357c472018-03-21 13:54:09 +000050 /** Run activation function.
51 *
52 * @param[in] vval Vector of values.
53 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +000054 void operator()(ExactType &vval)
55 {
56 ARM_COMPUTE_UNUSED(vval);
57 }
Georgios Pinitas980a9162020-06-03 20:16:46 +010058
59 /** Run activation function.
60 *
61 * @param[in] val Scalar value.
62 */
63 void operator()(T &val)
64 {
65 ARM_COMPUTE_UNUSED(val);
66 }
Georgios Pinitas57c033b2018-02-15 12:29:44 +000067};
Michalis Spyroua6825a42018-09-13 12:24:03 +010068/** Linear activation object */
69template <typename T, int S>
70struct linear
71{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +000072 /** SIMD vector type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +010073 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +000074 /** SIMD vector tag type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +010075 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
76
77 /** Construct a Linear activation object.
78 *
79 * @param[in] act_info Activation layer information.
80 */
81 explicit linear(ActivationLayerInfo act_info)
Georgios Pinitas980a9162020-06-03 20:16:46 +010082 : alpha(act_info.a()),
83 beta(act_info.b()),
84 valpha(wrapper::vdup_n(static_cast<T>(alpha), ExactTagType{})),
85 vbeta(wrapper::vdup_n(static_cast<T>(beta), ExactTagType{}))
Michalis Spyroua6825a42018-09-13 12:24:03 +010086 {
87 }
88
89 /** Run activation function.
90 *
91 * @param[in] vval Vector of values.
92 */
93 void operator()(ExactType &vval)
94 {
Georgios Pinitas980a9162020-06-03 20:16:46 +010095 vval = wrapper::vmla(vbeta, vval, valpha);
Michalis Spyroua6825a42018-09-13 12:24:03 +010096 }
97
Georgios Pinitas980a9162020-06-03 20:16:46 +010098 /** Run activation function.
99 *
100 * @param[in] val Scalar value.
101 */
102 void operator()(T &val)
103 {
104 val = alpha * val + beta;
105 }
106
107 const T alpha; /**< Scalar alpha */
108 const T beta; /**< Scalar alpha */
109 const ExactType valpha; /**< Vector of alphas. */
110 const ExactType vbeta; /**< Vector of betas. */
Michalis Spyroua6825a42018-09-13 12:24:03 +0100111};
112/** Square activation object */
113template <typename T, int S>
114struct square
115{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000116 /** SIMD vector type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +0100117 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000118 /** SIMD vector tag type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +0100119 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
120
121 /** Construct a Square activation object.
122 *
123 * @param[in] act_info Activation layer information.
124 */
125 explicit square(ActivationLayerInfo act_info)
126 {
127 ARM_COMPUTE_UNUSED(act_info);
128 }
129
130 /** Run activation function.
131 *
132 * @param[in] vval Vector of values.
133 */
134 void operator()(ExactType &vval)
135 {
136 vval = wrapper::vmul(vval, vval);
137 }
Georgios Pinitas980a9162020-06-03 20:16:46 +0100138
139 /** Run activation function.
140 *
141 * @param[in] val Scalar value.
142 */
143 void operator()(T &val)
144 {
145 val = val * val;
146 }
Michalis Spyroua6825a42018-09-13 12:24:03 +0100147};
148/** Logistic activation object */
149template <typename T, int S>
150struct logistic
151{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000152 /** SIMD vector type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +0100153 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000154 /** SIMD vector tag type. */
Michalis Spyroua6825a42018-09-13 12:24:03 +0100155 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
156
157 /** Construct a Logistic activation object.
158 *
159 * @param[in] act_info Activation layer information.
160 */
161 explicit logistic(ActivationLayerInfo act_info)
Georgios Pinitas980a9162020-06-03 20:16:46 +0100162 : 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 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000201 explicit relu(ActivationLayerInfo act_info)
Georgios Pinitas980a9162020-06-03 20:16:46 +0100202 : vzero(wrapper::vdup_n(static_cast<T>(0), ExactTagType{}))
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000203 {
204 ARM_COMPUTE_UNUSED(act_info);
205 }
206
Alex Gildayc357c472018-03-21 13:54:09 +0000207 /** Run activation function.
208 *
209 * @param[in] vval Vector of values.
210 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000211 void operator()(ExactType &vval)
212 {
213 vval = wrapper::vmax(vzero, vval);
214 }
215
Georgios Pinitas980a9162020-06-03 20:16:46 +0100216 /** Run activation function.
217 *
218 * @param[in] val Scalar value.
219 */
220 void operator()(T &val)
221 {
222 val = std::max(static_cast<T>(0), val);
223 }
224
Alex Gildayc357c472018-03-21 13:54:09 +0000225 /** Vector of zeroes. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000226 const ExactType vzero;
227};
228/** Bounded RELU activation object */
229template <typename T, int S>
230struct brelu
231{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000232 /** SIMD vector type. */
Alex Gildayc357c472018-03-21 13:54:09 +0000233 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000234 /** SIMD vector tag type. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000235 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
236
Alex Gildayc357c472018-03-21 13:54:09 +0000237 /** Construct a bounded RELU activation object.
238 *
239 * @param[in] act_info Activation layer information.
240 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000241 explicit brelu(ActivationLayerInfo act_info)
Georgios Pinitas980a9162020-06-03 20:16:46 +0100242 : alpha(act_info.a()),
243 vzero(wrapper::vdup_n(static_cast<T>(0), ExactTagType{})),
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000244 valpha(wrapper::vdup_n(static_cast<T>(act_info.a()), ExactTagType{}))
245 {
246 }
247
Alex Gildayc357c472018-03-21 13:54:09 +0000248 /** Run activation function.
249 *
250 * @param[in] vval Vector of values.
251 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000252 void operator()(ExactType &vval)
253 {
254 vval = wrapper::vmin(valpha, wrapper::vmax(vzero, vval));
255 }
256
Georgios Pinitas980a9162020-06-03 20:16:46 +0100257 /** Run activation function.
258 *
259 * @param[in] val Scalar value.
260 */
261 void operator()(T &val)
262 {
263 val = std::min(alpha, std::max(static_cast<T>(0), val));
264 }
265
266 const T alpha; /** Scalar alpha */
267 const ExactType vzero; /** Vector of zeroes. */
268 const ExactType valpha; /** Vector of alphas. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000269};
270/** Lower-Upper Bounded RELU activation object */
271template <typename T, int S>
272struct lubrelu
273{
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000274 /** SIMD vector type. */
Alex Gildayc357c472018-03-21 13:54:09 +0000275 using ExactType = typename wrapper::traits::neon_vector<T, S>::type;
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000276 /** SIMD vector tag type. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000277 using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;
278
Alex Gildayc357c472018-03-21 13:54:09 +0000279 /** Construct a lower-upper bounded RELU activation object.
280 *
281 * @param[in] act_info Activation layer information.
282 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000283 explicit lubrelu(ActivationLayerInfo act_info)
Georgios Pinitas980a9162020-06-03 20:16:46 +0100284 : alpha(act_info.a()),
285 beta(act_info.b()),
286 valpha(wrapper::vdup_n(static_cast<T>(act_info.a()), ExactTagType{})),
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000287 vbeta(wrapper::vdup_n(static_cast<T>(act_info.b()), ExactTagType{}))
288 {
289 }
290
Alex Gildayc357c472018-03-21 13:54:09 +0000291 /** Run activation function.
292 *
293 * @param[in] vval Vector of values.
294 */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000295 void operator()(ExactType &vval)
296 {
297 vval = wrapper::vmin(valpha, wrapper::vmax(vbeta, vval));
298 }
299
Georgios Pinitas980a9162020-06-03 20:16:46 +0100300 /** Run activation function.
301 *
302 * @param[in] val Scalar value.
303 */
304 void operator()(T &val)
305 {
306 val = std::min(alpha, std::max(beta, val));
307 }
308
309 const T alpha; /**< Scalar alpha */
310 const T beta; /**< Scalar alpha */
311 const ExactType valpha; /** Vector of alphas. */
312 const ExactType vbeta; /** Vector of betas. */
Georgios Pinitas57c033b2018-02-15 12:29:44 +0000313};
314} // namespace detail
315} // namespace arm_compute
Michalis Spyrouf4643372019-11-29 16:17:13 +0000316#endif /* ARM_COMPUTE_DETAIL_NEACTIVATION_FUNCTION_DETAIL_H */