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