1 /* 2 * Copyright (c) 2016-2020 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_NEPIXELWISEMULTIPLICATIONKERNEL_H 25 #define ARM_COMPUTE_NEPIXELWISEMULTIPLICATIONKERNEL_H 26 27 #include "arm_compute/core/Types.h" 28 #include "src/core/NEON/INEKernel.h" 29 30 namespace arm_compute 31 { 32 class ITensor; 33 34 /** Interface for the kernel to perform addition between two tensors */ 35 class NEPixelWiseMultiplicationKernel : public INEKernel 36 { 37 public: name()38 const char *name() const override 39 { 40 return "NEPixelWiseMultiplicationKernel"; 41 } 42 /** Default constructor */ 43 NEPixelWiseMultiplicationKernel(); 44 /** Prevent instances of this class from being copied (As this class contains pointers) */ 45 NEPixelWiseMultiplicationKernel(const NEPixelWiseMultiplicationKernel &) = delete; 46 /** Prevent instances of this class from being copied (As this class contains pointers) */ 47 NEPixelWiseMultiplicationKernel &operator=(const NEPixelWiseMultiplicationKernel &) = delete; 48 /** Allow instances of this class to be moved */ 49 NEPixelWiseMultiplicationKernel(NEPixelWiseMultiplicationKernel &&) = default; 50 /** Allow instances of this class to be moved */ 51 NEPixelWiseMultiplicationKernel &operator=(NEPixelWiseMultiplicationKernel &&) = default; 52 /** Default destructor */ 53 ~NEPixelWiseMultiplicationKernel() = default; 54 /** Initialise the kernel's input, output and border mode. 55 * 56 * Valid configurations (Input1,Input2) -> Output : 57 * 58 * Support: Broadcast? Scale=1/255? 59 * - (U8,U8) -> U8, S16 N Y 60 * - (U8,S16) -> S16 N Y 61 * - (S16,U8) -> S16 N Y 62 * - (S16,S16) -> S16 N Y 63 * - (S32,S32) -> S32 Y N 64 * - (F16,F16) -> F16 N Y 65 * - (F32,F32) -> F32 Y Y 66 * - (QASYMM8,QASYMM8) -> QASYMM8 Y Y 67 * - (QASYMM8_SIGNED,QASYMM8_SIGNED) -> QASYMM8_SIGNED Y Y 68 * - (QSYMM16,QSYMM16) -> QSYMM16, S32 N Y 69 * 70 * @note For @p scale equal to 1/255 only round to nearest even (implemented as round half up) is supported. 71 * For all other scale values only round to zero (implemented as round towards minus infinity) is supported. 72 * 73 * @param[in] input1 First input tensor. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/S32/QSYMM16/F16/F32 74 * @param[in] input2 Second input tensor. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/S32/QSYMM16/F16/F32 75 * @param[out] output Output tensor. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/S32/QSYMM16/F16/F32 76 * @param[in] scale Scale to apply after multiplication. 77 * Scale must be positive and its value must be either 1/255 or 1/2^n where n is between 0 and 15. 78 * If both @p input1, @p input2 and @p output are of datatype S32, scale cannot be 1/255 79 * @param[in] overflow_policy Overflow policy. ConvertPolicy cannot be WRAP if any of the inputs is of quantized datatype 80 * @param[in] rounding_policy Rounding policy. 81 */ 82 void configure(ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output, float scale, ConvertPolicy overflow_policy, RoundingPolicy rounding_policy); 83 /** Static function to check if given info will lead to a valid configuration of @ref NEPixelWiseMultiplicationKernel 84 * 85 * Valid configurations (Input1,Input2) -> Output : 86 * Support: Broadcast? Scale=1/255? 87 * - (U8,U8) -> U8, S16 N Y 88 * - (U8,S16) -> S16 N Y 89 * - (S16,U8) -> S16 N Y 90 * - (S16,S16) -> S16 N Y 91 * - (S32,S32) -> S32 Y N 92 * - (F16,F16) -> F16 N Y 93 * - (F32,F32) -> F32 Y Y 94 * - (QASYMM8,QASYMM8) -> QASYMM8 Y Y 95 * - (QASYMM8_SIGNED,QASYMM8_SIGNED) -> QASYMM8_SIGNED Y Y 96 * - (QSYMM16,QSYMM16) -> QSYMM16, S32 N Y 97 * 98 * @note For @p scale equal to 1/255 only round to nearest even (implemented as round half up) is supported. 99 * For all other scale values only round to zero (implemented as round towards minus infinity) is supported. 100 * 101 * @param[in] input1 First input tensor info. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/S32/QSYMM16/F16/F32 102 * @param[in] input2 Second input tensor info. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/S32/QSYMM16/F16/F32 103 * @param[in] output Output tensor info. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/S32/QSYMM16/F16/F32 104 * @param[in] scale Scale to apply after multiplication. 105 * Scale must be positive and its value must be either 1/255 or 1/2^n where n is between 0 and 15. 106 * If both @p input1, @p input2 and @p output are of datatype S32, scale cannot be 1/255 107 * @param[in] overflow_policy Overflow policy. ConvertPolicy cannot be WRAP if any of the inputs is of quantized datatype 108 * @param[in] rounding_policy Rounding policy. 109 * 110 * @return a status 111 */ 112 static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, float scale, ConvertPolicy overflow_policy, RoundingPolicy rounding_policy); 113 114 // Inherited methods overridden 115 void run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info) override; 116 117 private: 118 /** Common signature for all the specialised multiplication functions with integer scaling factor 119 * 120 * @param[in] in1 Input1 tensor object. 121 * @param[in] in2 Input2 tensor object. 122 * @param[out] out Output tensor object. 123 * @param[in] window Region on which to execute the kernel 124 * @param[in] scale Integer scale factor. 125 */ 126 using MulFunctionInt = void(const ITensor *in1, const ITensor *in2, ITensor *out, const Window &window, int scale); 127 /** Common signature for all the specialised multiplication functions with float scaling factor 128 * 129 * @param[in] in1 Input1 tensor object. 130 * @param[in] in2 Input2 tensor object. 131 * @param[out] out Output tensor object. 132 * @param[in] window Region on which to execute the kernel 133 * @param[in] scale Float scale factor. 134 */ 135 using MulFunctionFloat = void(const ITensor *in1, const ITensor *in2, ITensor *out, const Window &window, float scale); 136 /** Common signature for all the specialised QASYMM8 multiplication functions with float scaling factor 137 * 138 * @param[in] in1 Input1 tensor object. 139 * @param[in] in2 Input2 tensor object. 140 * @param[out] out Output tensor object. 141 * @param[in] window Region on which to execute the kernel 142 * @param[in] scale Float scale factor. 143 * 144 */ 145 using MulFunctionQuantized = void(const ITensor *in1, const ITensor *in2, ITensor *out, const Window &window, float scale); 146 147 MulFunctionFloat *_func_float; 148 MulFunctionInt *_func_int; 149 MulFunctionQuantized *_func_quantized; 150 151 private: 152 float _scale; 153 int _scale_exponent; 154 }; 155 156 /** Interface for the complex pixelwise multiplication kernel. */ 157 class NEComplexPixelWiseMultiplicationKernel : public INEKernel 158 { 159 public: name()160 const char *name() const override 161 { 162 return "NEComplexPixelWiseMultiplicationKernel"; 163 } 164 /** Initialise the kernel's input, output and border mode. 165 * 166 * @param[in] input1 An input tensor. Data types supported: F32. Number of channels supported: 2 (complex tensor). 167 * @param[in] input2 An input tensor. Data types supported: same as @p input1. Number of channels supported: same as @p input1. 168 * @param[out] output The output tensor, Data types supported: same as @p input1. Number of channels supported: same as @p input1. 169 */ 170 void configure(ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output); 171 /** Static function to check if given info will lead to a valid configuration of @ref NEComplexPixelWiseMultiplicationKernel 172 * 173 * @param[in] input1 An input tensor info. Data types supported: F32. Number of channels supported: 2 (complex tensor). 174 * @param[in] input2 An input tensor info. Data types supported: same as @p input1. Number of channels supported: same as @p input1. 175 * @param[in] output The output tensor info. Data types supported: same as @p input1. Number of channels supported: same as @p input1. 176 * 177 * @return a status 178 */ 179 static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output); 180 181 // Inherited methods overridden: 182 void run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info) override; 183 }; 184 185 } // namespace arm_compute 186 #endif /*ARM_COMPUTE_NEPIXELWISEMULTIPLICATIONKERNEL_H */ 187