xref: /aosp_15_r20/external/ComputeLibrary/arm_compute/runtime/NEON/functions/NEElementwiseOperations.h (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1 /*
2  * Copyright (c) 2018-2021 Arm Limited.
3  *
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  */
24 #ifndef ARM_COMPUTE_NEELEMENTWISEOPERATIONS_H
25 #define ARM_COMPUTE_NEELEMENTWISEOPERATIONS_H
26 
27 #include "arm_compute/core/Types.h"
28 #include "arm_compute/runtime/IFunction.h"
29 #include "arm_compute/runtime/NEON/INEOperator.h"
30 
31 namespace arm_compute
32 {
33 class ITensor;
34 
35 /** Basic function to run @ref cpu::kernels::CpuArithmeticKernel for max
36  *
37  * @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
38  * @note The function performs a max operation between two tensors.
39  */
40 class NEElementwiseMax : public IFunction
41 {
42 public:
43     /** Default Constructor */
44     NEElementwiseMax();
45     /** Default Destructor */
46     ~NEElementwiseMax();
47     /** Prevent instances of this class from being copied (As this class contains pointers) */
48     NEElementwiseMax(const NEElementwiseMax &) = delete;
49     /** Default move constructor */
50     NEElementwiseMax(NEElementwiseMax &&);
51     /** Prevent instances of this class from being copied (As this class contains pointers) */
52     NEElementwiseMax &operator=(const NEElementwiseMax &) = delete;
53     /** Default move assignment operator */
54     NEElementwiseMax &operator=(NEElementwiseMax &&);
55     /** Initialise the kernel's inputs, output and conversion policy.
56      *
57      * Valid data layouts:
58      * - All
59      *
60      * Valid data type configurations:
61      * |src0           |src1           |dst            |
62      * |:--------------|:--------------|:--------------|
63      * |QASYMM8        |QASYMM8        |QASYMM8        |
64      * |QASYMM8_SIGNED |QASYMM8_SIGNED |QASYMM8_SIGNED |
65      * |S32            |S32            |S32            |
66      * |S16            |S16            |S16            |
67      * |F16            |F16            |F16            |
68      * |F32            |F32            |F32            |
69      *
70      * @param[in, out] input1   First tensor input. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
71      * @param[in, out] input2   Second tensor input. Data types supported: Same as @p input1.
72      * @param[out]     output   Output tensor. Data types supported: Same as @p input1.
73      * @param[in]      act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
74      */
75     void configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
76     /** Static function to check if given info will lead to a valid configuration of @ref cpu::kernels::CpuArithmeticKernel for max
77      *
78      * @param[in] input1   First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
79      * @param[in] input2   Second tensor input info. Data types supported: Same as @p input1.
80      * @param[in] output   Output tensor info. Data types supported: Same as @p input1.
81      * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
82      *
83      * @return a status
84      */
85     static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
86 
87     // Inherited methods overridden:
88     void run() override;
89 
90 private:
91     struct Impl;
92     std::unique_ptr<Impl> _impl;
93 };
94 
95 /** Basic function to run @ref cpu::kernels::CpuArithmeticKernel for min
96  *
97  * @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
98  * @note The function performs a min operation between two tensors.
99  */
100 class NEElementwiseMin : public IFunction
101 {
102 public:
103     /** Default Constructor */
104     NEElementwiseMin();
105     /** Default Destructor */
106     ~NEElementwiseMin();
107     /** Prevent instances of this class from being copied (As this class contains pointers) */
108     NEElementwiseMin(const NEElementwiseMin &) = delete;
109     /** Default move constructor */
110     NEElementwiseMin(NEElementwiseMin &&);
111     /** Prevent instances of this class from being copied (As this class contains pointers) */
112     NEElementwiseMin &operator=(const NEElementwiseMin &) = delete;
113     /** Default move assignment operator */
114     NEElementwiseMin &operator=(NEElementwiseMin &&);
115     /** Initialise the kernel's inputs, output and conversion policy.
116      *
117      * Valid data layouts:
118      * - All
119      *
120      * Valid data type configurations:
121      * |src0           |src1           |dst            |
122      * |:--------------|:--------------|:--------------|
123      * |QASYMM8        |QASYMM8        |QASYMM8        |
124      * |QASYMM8_SIGNED |QASYMM8_SIGNED |QASYMM8_SIGNED |
125      * |S32            |S32            |S32            |
126      * |S16            |S16            |S16            |
127      * |F16            |F16            |F16            |
128      * |F32            |F32            |F32            |
129      *
130      * @param[in, out] input1   First tensor input. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
131      * @param[in, out] input2   Second tensor input. Data types supported: Same as @p input1.
132      * @param[out]     output   Output tensor. Data types supported: Same as @p input1.
133      * @param[in]      act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
134      */
135     void configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
136     /** Static function to check if given info will lead to a valid configuration of @ref cpu::kernels::CpuArithmeticKernel for min
137      *
138      * @param[in] input1   First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
139      * @param[in] input2   Second tensor input info. Data types supported: Same as @p input1.
140      * @param[in] output   Output tensor info. Data types supported: Same as @p input1.
141      * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
142      *
143      * @return a status
144      */
145     static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
146 
147     // Inherited methods overridden:
148     void run() override;
149 
150 private:
151     struct Impl;
152     std::unique_ptr<Impl> _impl;
153 };
154 
155 /** Basic function to run @ref cpu::kernels::CpuArithmeticKernel for squared difference
156  *
157  * @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
158  * @note The function performs a squared different operation between two tensors (i.e., out[i] = (in1[i] - in2[i])^2
159  */
160 class NEElementwiseSquaredDiff : public IFunction
161 {
162 public:
163     /** Default Constructor */
164     NEElementwiseSquaredDiff();
165     /** Default Destructor */
166     ~NEElementwiseSquaredDiff();
167     /** Prevent instances of this class from being copied (As this class contains pointers) */
168     NEElementwiseSquaredDiff(const NEElementwiseSquaredDiff &) = delete;
169     /** Default move constructor */
170     NEElementwiseSquaredDiff(NEElementwiseSquaredDiff &&);
171     /** Prevent instances of this class from being copied (As this class contains pointers) */
172     NEElementwiseSquaredDiff &operator=(const NEElementwiseSquaredDiff &) = delete;
173     /** Default move assignment operator */
174     NEElementwiseSquaredDiff &operator=(NEElementwiseSquaredDiff &&);
175     /** Initialise the kernel's inputs, output and conversion policy.
176      *
177      * Valid data layouts:
178      * - All
179      *
180      * Valid data type configurations:
181      * |src0           |src1           |dst            |
182      * |:--------------|:--------------|:--------------|
183      * |QASYMM8        |QASYMM8        |QASYMM8        |
184      * |QASYMM8_SIGNED |QASYMM8_SIGNED |QASYMM8_SIGNED |
185      * |S32            |S32            |S32            |
186      * |S16            |S16            |S16            |
187      * |F16            |F16            |F16            |
188      * |F32            |F32            |F32            |
189      *
190      * @param[in, out] input1   First tensor input. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
191      * @param[in, out] input2   Second tensor input. Data types supported: Same as @p input1.
192      * @param[out]     output   Output tensor. Data types supported: Same as @p input1.
193      * @param[in]      act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
194      */
195     void configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
196     /** Static function to check if given info will lead to a valid configuration of @ref cpu::kernels::CpuArithmeticKernel for squared difference
197      *
198      * @param[in] input1   First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
199      * @param[in] input2   Second tensor input info. Data types supported: Same as @p input1.
200      * @param[in] output   Output tensor info. Data types supported: Same as @p input1.
201      * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
202      *
203      * @return a status
204      */
205     static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
206 
207     // Inherited methods overridden:
208     void run() override;
209 
210 private:
211     struct Impl;
212     std::unique_ptr<Impl> _impl;
213 };
214 
215 /** Basic function to run @ref cpu::kernels::CpuArithmeticKernel for division
216  *
217  * @note The tensor data type for the inputs must be F16/F32.
218  * @note The function performs a squared different operation between two tensors (i.e., out[i] = in1[i] / in2[i])
219  */
220 class NEElementwiseDivision : public IFunction
221 {
222 public:
223     /** Default Constructor */
224     NEElementwiseDivision();
225     /** Default Destructor */
226     ~NEElementwiseDivision();
227     /** Prevent instances of this class from being copied (As this class contains pointers) */
228     NEElementwiseDivision(const NEElementwiseDivision &) = delete;
229     /** Default move constructor */
230     NEElementwiseDivision(NEElementwiseDivision &&);
231     /** Prevent instances of this class from being copied (As this class contains pointers) */
232     NEElementwiseDivision &operator=(const NEElementwiseDivision &) = delete;
233     /** Default move assignment operator */
234     NEElementwiseDivision &operator=(NEElementwiseDivision &&);
235     /** Initialise the kernel's inputs, output and conversion policy.
236      *
237      * Valid data layouts:
238      * - All
239      *
240      * Valid data type configurations:
241      * |src0           |src1           |dst            |
242      * |:--------------|:--------------|:--------------|
243      * |F16            |F16            |F16            |
244      * |F32            |F32            |F32            |
245      *
246      * @param[in, out] input1   First tensor input. Data types supported: F16/F32.
247      * @param[in, out] input2   Second tensor input. Data types supported: Same as @p input1.
248      * @param[out]     output   Output tensor. Data types supported: Same as @p input1.
249      * @param[in]      act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
250      */
251     void configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
252     /** Static function to check if given info will lead to a valid configuration of @ref cpu::kernels::CpuArithmeticKernel for division
253      *
254      * @param[in] input1   First tensor input info. Data types supported: F16/F32.
255      * @param[in] input2   Second tensor input info. Data types supported: Same as @p input1.
256      * @param[in] output   Output tensor info. Data types supported: Same as @p input1.
257      * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
258      *
259      * @return a status
260      */
261     static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
262 
263     // Inherited methods overridden:
264     void run() override;
265 
266 private:
267     struct Impl;
268     std::unique_ptr<Impl> _impl;
269 };
270 
271 /** Basic function to run @ref cpu::kernels::CpuArithmeticKernel for power
272  *
273  * @note The tensor data type for the inputs must be F16/F32.
274  * @note The function performs a elementwise power of in1 to in2 (i.e., out[i] = in1[i] ^ in2[i])
275  * @note For an exponent that is a float, this function will only work with a positive base.
276  */
277 class NEElementwisePower : public IFunction
278 {
279 public:
280     /** Default Constructor */
281     NEElementwisePower();
282     /** Default Destructor */
283     ~NEElementwisePower();
284     /** Prevent instances of this class from being copied (As this class contains pointers) */
285     NEElementwisePower(const NEElementwisePower &) = delete;
286     /** Default move constructor */
287     NEElementwisePower(NEElementwisePower &&);
288     /** Prevent instances of this class from being copied (As this class contains pointers) */
289     NEElementwisePower &operator=(const NEElementwisePower &) = delete;
290     /** Default move assignment operator */
291     NEElementwisePower &operator=(NEElementwisePower &&);
292     /** Initialise the kernel's inputs, output and conversion policy.
293      *
294      * Valid data layouts:
295      * - All
296      *
297      * Valid data type configurations:
298      * |src0           |src1           |dst            |
299      * |:--------------|:--------------|:--------------|
300      * |F16            |F16            |F16            |
301      * |F32            |F32            |F32            |
302      *
303      * @param[in, out] input1   First tensor input. Data types supported: F16/F32.
304      * @param[in, out] input2   Second tensor input. Data types supported: Same as @p input1.
305      * @param[out]     output   Output tensor. Data types supported: Same as @p input1.
306      * @param[in]      act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
307      */
308     void configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
309     /** Static function to check if given info will lead to a valid configuration of @ref cpu::kernels::CpuArithmeticKernel for power
310      *
311      * @param[in] input1   First tensor input info. Data types supported: F16/F32.
312      * @param[in] input2   Second tensor input info. Data types supported: Same as @p input1.
313      * @param[in] output   Output tensor info. Data types supported: Same as @p input1.
314      * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
315      *
316      * @return a status
317      */
318     static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
319 
320     // Inherited methods overridden:
321     void run() override;
322 
323 private:
324     struct Impl;
325     std::unique_ptr<Impl> _impl;
326 };
327 
328 /** Basic function to run @ref cpu::kernels::CpuComparisonKernel.
329  *
330  * @note The tensor data type for the inputs must be U8/QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
331  * @note The function performs a comparison operation between two tensors.
332  */
333 class NEElementwiseComparison : public IFunction
334 {
335 public:
336     /** Default Constructor */
337     NEElementwiseComparison();
338     /** Default Destructor */
339     ~NEElementwiseComparison();
340     /** Prevent instances of this class from being copied (As this class contains pointers) */
341     NEElementwiseComparison(const NEElementwiseComparison &) = delete;
342     /** Default move constructor */
343     NEElementwiseComparison(NEElementwiseComparison &&);
344     /** Prevent instances of this class from being copied (As this class contains pointers) */
345     NEElementwiseComparison &operator=(const NEElementwiseComparison &) = delete;
346     /** Default move assignment operator */
347     NEElementwiseComparison &operator=(NEElementwiseComparison &&);
348     /** Initialise the kernel's inputs, output and conversion policy.
349      *
350      * Valid data layouts:
351      * - All
352      *
353      * Valid data type configurations:
354      * |src0           |src1           |dst   |
355      * |:--------------|:--------------|:-----|
356      * |QASYMM8        |QASYMM8        |U8    |
357      * |QASYMM8_SIGNED |QASYMM8_SIGNED |U8    |
358      * |S32            |S32            |U8    |
359      * |U8             |U8             |U8    |
360      * |S16            |S16            |U8    |
361      * |F16            |F16            |U8    |
362      * |F32            |F32            |U8    |
363      *
364      * @param[in, out] input1 First tensor input. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
365      * @param[in, out] input2 Second tensor input. Data types supported: Same as @p input1.
366      * @param[out]     output Output tensor. Data types supported: U8.
367      * @param[in]      op     Comparison Operation to be performed.
368      */
369     void configure(ITensor *input1, ITensor *input2, ITensor *output, ComparisonOperation op);
370     /** Static function to check if given info will lead to a valid configuration of @ref cpu::kernels::CpuComparisonKernel
371      *
372      * @param[in] input1 First tensor input info. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
373      * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
374      * @param[in] output Output tensor info. Data types supported: U8.
375      * @param[in] op     Comparison Operation to be performed.
376      *
377      * @return a status
378      */
379     static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, ComparisonOperation op);
380 
381     // Inherited methods overridden:
382     void run() override;
383 
384 private:
385     struct Impl;
386     std::unique_ptr<Impl> _impl;
387 };
388 
389 /** Basic function to run @ref cpu::kernels::CpuComparisonKernel
390  *
391  * @note The tensor data type for the inputs must be U8/QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
392  * @note The function performs a comparison operation between two tensors.
393  */
394 template <ComparisonOperation op>
395 class NEElementwiseComparisonStatic : public IFunction
396 {
397 public:
398     /** Default Constructor */
399     NEElementwiseComparisonStatic();
400     /** Default Destructor */
401     ~NEElementwiseComparisonStatic();
402     /** Prevent instances of this class from being copied (As this class contains pointers) */
403     NEElementwiseComparisonStatic(const NEElementwiseComparisonStatic &) = delete;
404     /** Default move constructor */
405     NEElementwiseComparisonStatic(NEElementwiseComparisonStatic &&);
406     /** Prevent instances of this class from being copied (As this class contains pointers) */
407     NEElementwiseComparisonStatic &operator=(const NEElementwiseComparisonStatic &) = delete;
408     /** Default move assignment operator */
409     NEElementwiseComparisonStatic &operator=(NEElementwiseComparisonStatic &&);
410     /** Initialise the kernel's inputs, output and conversion policy.
411      *
412      * @param[in, out] input1 First tensor input. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
413      * @param[in, out] input2 Second tensor input. Data types supported: Same as @p input1.
414      * @param[out]     output Output tensor. Data types supported: U16/U32.
415      */
416     void configure(ITensor *input1, ITensor *input2, ITensor *output);
417     /** Static function to check if given info will lead to a valid configuration of @ref cpu::kernels::CpuComparisonKernel
418      *
419      * @param[in] input1 First tensor input info. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
420      * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
421      * @param[in] output Output tensor info. Data types supported: U16/U32.
422      *
423      * @return a status
424      */
425     static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output);
426 
427     // Inherited methods overridden:
428     void run() override;
429 
430 private:
431     struct Impl;
432     std::unique_ptr<Impl> _impl;
433 };
434 
435 /** Basic function to run equal comparison. */
436 using NEEqual = NEElementwiseComparisonStatic<ComparisonOperation::Equal>;
437 /** Basic function to run not equal comparison. */
438 using NENotEqual = NEElementwiseComparisonStatic<ComparisonOperation::NotEqual>;
439 /** Basic function to run greater comparison. */
440 using NEGreater = NEElementwiseComparisonStatic<ComparisonOperation::Greater>;
441 /** Basic function to run greater-equal comparison. */
442 using NEGreaterEqual = NEElementwiseComparisonStatic<ComparisonOperation::GreaterEqual>;
443 /** Basic function to run less comparison. */
444 using NELess = NEElementwiseComparisonStatic<ComparisonOperation::Less>;
445 /** Basic function to run less-equal comparison. */
446 using NELessEqual = NEElementwiseComparisonStatic<ComparisonOperation::LessEqual>;
447 
448 } // namespace arm_compute
449 #endif /* ARM_COMPUTE_NEELEMENTWISEOPERATIONS_H */
450