1 /* 2 * Copyright (c) 2018-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_CLELEMENTWISEOPERATIONKERNEL_H 25 #define ARM_COMPUTE_CLELEMENTWISEOPERATIONKERNEL_H 26 27 #include "arm_compute/core/Types.h" 28 #include "src/core/CL/ICLKernel.h" 29 #include "src/core/KernelTypes.h" 30 31 namespace arm_compute 32 { 33 class ICLTensor; 34 35 /** Interface for an element-wise operation kernel 36 * 37 * Element-wise operation is computed by: 38 * @f[ output(x,y) = OP(input1(x,y), input2(x,y))@f] 39 * 40 */ 41 class CLElementwiseOperationKernel : public ICLKernel 42 { 43 public: 44 /** Default constructor */ 45 CLElementwiseOperationKernel(); 46 /** Prevent instances of this class from being copied (As this class contains pointers) */ 47 CLElementwiseOperationKernel(const CLElementwiseOperationKernel &) = delete; 48 /** Prevent instances of this class from being copied (As this class contains pointers) */ 49 CLElementwiseOperationKernel &operator=(const CLElementwiseOperationKernel &) = delete; 50 /** Allow instances of this class to be moved */ 51 CLElementwiseOperationKernel(CLElementwiseOperationKernel &&) = default; 52 /** Allow instances of this class to be moved */ 53 CLElementwiseOperationKernel &operator=(CLElementwiseOperationKernel &&) = default; 54 /** Default destructor */ 55 ~CLElementwiseOperationKernel() = default; 56 57 // Inherited methods overridden: 58 void run_op(ITensorPack &tensors, const Window &window, cl::CommandQueue &queue) override; 59 60 protected: 61 /** The name of the operation */ 62 virtual std::string name() = 0; 63 64 /** Initialise the kernel's output. 65 * 66 * @param[in] input1 First tensor input info. Data types supported: U8/S8/QASYMM8/QASYMM8_SIGNED/U16/S16/F16/U32/S32/F32. 67 * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1. 68 * @param[in] output Output tensor info. Data types supported: Same as @p input1. 69 * 70 * @return a pair of Status and Window 71 */ 72 virtual std::pair<Status, Window> validate_and_configure_window(ITensorInfo &input1, ITensorInfo &input2, ITensorInfo &output) = 0; 73 74 /** Generate the build options for the specific kernel 75 * 76 * @reutrn a CLBuildOptions struct 77 */ 78 virtual CLBuildOptions generate_build_options(const ITensorInfo &input1, const ITensorInfo &input2, const ITensorInfo &output) = 0; 79 80 /** Generate the identifier for tuning 81 * 82 * @reutrn a string 83 */ 84 virtual std::string generate_id_for_tuning(const std::string &kernel_name, const ITensorInfo &input1, const ITensorInfo &output) = 0; 85 86 /** Commmon configure function for element-wise operators with no additional options (e.g., Div, Min, Max, SquaredDiff) 87 * 88 */ 89 void configure_common(ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output); 90 /** Commmon configure function for element-wise operators with no additional options (e.g., Div, Min, Max, SquaredDiff) 91 * 92 */ 93 void configure_common(const CLCompileContext &compile_context, ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output); 94 95 ActivationLayerInfo _act_info; 96 97 private: 98 const ITensorInfo *_input1; /**< Source tensor info 1 */ 99 const ITensorInfo *_input2; /**< Source tensor info 2 */ 100 ITensorInfo *_output; /**< Destination tensor info */ 101 }; 102 103 class CLLogicalBinaryKernel : public CLElementwiseOperationKernel 104 { 105 public: 106 /** Default constructor */ 107 CLLogicalBinaryKernel() = default; 108 /** Prevent instances of this class from being copied (As this class contains pointers) */ 109 CLLogicalBinaryKernel(const CLLogicalBinaryKernel &) = delete; 110 /** Prevent instances of this class from being copied (As this class contains pointers) */ 111 CLLogicalBinaryKernel &operator=(const CLLogicalBinaryKernel &) = delete; 112 /** Allow instances of this class to be moved */ 113 CLLogicalBinaryKernel(CLLogicalBinaryKernel &&) = default; 114 /** Allow instances of this class to be moved */ 115 CLLogicalBinaryKernel &operator=(CLLogicalBinaryKernel &&) = default; 116 /** Default destructor */ 117 ~CLLogicalBinaryKernel() = default; 118 /** Function to configure kernel 119 * 120 * @param[in] compile_context The compile context to be used. 121 * @param[in] op Logical binary operation to be executed. 122 * @param[in] input1 First tensor input info. Data types supported: U8. 123 * @param[in] input2 Second tensor input info. Data types supported: U8. 124 * @param[in] output Output tensor info. Data types supported: U8. 125 */ 126 void configure(const CLCompileContext &compile_context, kernels::LogicalOperation op, ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output); 127 /** Static function to check if the given configuration is valid for this kernel 128 * 129 * @param[in] op Logical binary operation to be executed. 130 * @param[in] input1 First tensor input info. Data types supported: U8. 131 * @param[in] input2 Second tensor input info. Data types supported: U8. 132 * @param[in] output Output tensor info. Data types supported: U8. 133 */ 134 static Status validate(kernels::LogicalOperation op, const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output); 135 136 private: 137 // Inherited methods overridden: 138 std::string name() override; 139 std::pair<Status, Window> validate_and_configure_window(ITensorInfo &input1, ITensorInfo &input2, ITensorInfo &output) override; 140 CLBuildOptions generate_build_options(const ITensorInfo &input1, const ITensorInfo &input2, const ITensorInfo &output) override; 141 std::string generate_id_for_tuning(const std::string &kernel_name, const ITensorInfo &input1, const ITensorInfo &output) override; 142 143 kernels::LogicalOperation _op{ kernels::LogicalOperation::Unknown }; 144 }; 145 146 /** Addition operation */ 147 class CLSaturatedArithmeticOperationKernel : public CLElementwiseOperationKernel 148 { 149 public: CLSaturatedArithmeticOperationKernel()150 CLSaturatedArithmeticOperationKernel() 151 : CLElementwiseOperationKernel(), _policy(), _op() 152 { 153 } 154 155 /** Static function to check if given info will lead to a valid configuration of @ref CLSaturatedArithmeticOperationKernel 156 * 157 * @param[in] op Arithmetic operation to be executed. 158 * @param[in] input1 First tensor input info. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/QSYMM16/F16/S32/F32. 159 * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1. 160 * @param[in] output Output tensor info. Data types supported: Same as @p input1. 161 * @param[in] policy Policy to use to handle overflow. 162 * @param[in] act_info (Optional) Activation layer information in case of a fused activation. 163 */ 164 void configure(ArithmeticOperation op, ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output, const ConvertPolicy &policy, const ActivationLayerInfo &act_info = ActivationLayerInfo()); 165 /** Static function to check if given info will lead to a valid configuration of @ref CLSaturatedArithmeticOperationKernel 166 * 167 * @param[in] compile_context The compile context to be used. 168 * @param[in] op Arithmetic operation to be executed. 169 * @param[in] input1 First tensor input info. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/QSYMM16/F16/S32/F32. 170 * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1. 171 * @param[in] output Output tensor info. Data types supported: Same as @p input1. 172 * @param[in] policy Policy to use to handle overflow. 173 * @param[in] act_info (Optional) Activation layer information in case of a fused activation. 174 */ 175 void configure(const CLCompileContext &compile_context, ArithmeticOperation op, ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output, const ConvertPolicy &policy, 176 const ActivationLayerInfo &act_info = ActivationLayerInfo()); 177 178 /** Static function to check if given info will lead to a valid configuration of @ref CLSaturatedArithmeticOperationKernel 179 * 180 * @param[in] op Arithmetic operation to be executed. 181 * @param[in] input1 First tensor input info info. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/QSYMM16/F16/S32/F32. 182 * @param[in] input2 Second tensor input info info. Data types supported: Same as @p input1. 183 * @param[in] output Output tensor info info. Data types supported: Same as @p input1. 184 * @param[in] policy Policy to use to handle overflow. 185 * @param[in] act_info (Optional) Activation layer information in case of a fused activation. 186 * 187 * @return a Status 188 */ 189 static Status validate(ArithmeticOperation op, const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ConvertPolicy &policy, 190 const ActivationLayerInfo &act_info = ActivationLayerInfo()); 191 192 protected: 193 // Inherited methods overridden: 194 std::string name() override; 195 std::pair<Status, Window> validate_and_configure_window(ITensorInfo &input1, ITensorInfo &input2, ITensorInfo &output) override; 196 CLBuildOptions generate_build_options(const ITensorInfo &input1, const ITensorInfo &input2, const ITensorInfo &output) override; 197 std::string generate_id_for_tuning(const std::string &kernel_name, const ITensorInfo &input1, const ITensorInfo &output) override; 198 199 private: 200 ConvertPolicy _policy; 201 ArithmeticOperation _op; 202 }; 203 204 class CLArithmeticOperationKernel : public CLElementwiseOperationKernel 205 { 206 public: CLArithmeticOperationKernel()207 CLArithmeticOperationKernel() 208 : CLElementwiseOperationKernel(), _op() 209 { 210 } 211 212 /** Static function to check if given info will lead to a valid configuration of @ref CLArithmeticOperationKernel 213 * 214 * @param[in] op Arithmetic operation to be executed. 215 * @param[in] input1 First tensor input info. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/QSYMM16/F16/S32/F32. 216 * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1. 217 * @param[in] output Output tensor info. Data types supported: Same as @p input1. 218 * @param[in] act_info (Optional) Activation layer information in case of a fused activation. 219 */ 220 void configure(ArithmeticOperation op, ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo()); 221 /** Static function to check if given info will lead to a valid configuration of @ref CLArithmeticOperationKernel 222 * 223 * @param[in] compile_context The compile context to be used. 224 * @param[in] op Arithmetic operation to be executed. 225 * @param[in] input1 First tensor input info. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/QSYMM16/F16/S32/F32. 226 * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1. 227 * @param[in] output Output tensor info. Data types supported: Same as @p input1. 228 * @param[in] act_info (Optional) Activation layer information in case of a fused activation. 229 */ 230 void configure(const CLCompileContext &compile_context, ArithmeticOperation op, ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output, 231 const ActivationLayerInfo &act_info = ActivationLayerInfo()); 232 233 /** Static function to check if given info will lead to a valid configuration of @ref CLArithmeticOperationKernel 234 * 235 * @param[in] op Arithmetic operation to be executed. 236 * @param[in] input1 First tensor input info. Data types supported: U8/QASYMM8/QASYMM8_SIGNED/S16/QSYMM16/F16/S32/F32. 237 * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1. 238 * @param[in] output Output tensor info. Data types supported: Same as @p input1. 239 * @param[in] act_info (Optional) Activation layer information in case of a fused activation. 240 * 241 * @return a Status 242 */ 243 static Status validate(ArithmeticOperation op, const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo()); 244 245 protected: 246 // Inherited methods overridden: 247 std::string name() override; 248 std::pair<Status, Window> validate_and_configure_window(ITensorInfo &input1, ITensorInfo &input2, ITensorInfo &output) override; 249 CLBuildOptions generate_build_options(const ITensorInfo &input1, const ITensorInfo &input2, const ITensorInfo &output) override; 250 std::string generate_id_for_tuning(const std::string &kernel_name, const ITensorInfo &input1, const ITensorInfo &output) override; 251 252 private: 253 ArithmeticOperation _op; 254 }; 255 } // namespace arm_compute 256 #endif /* ARM_COMPUTE_CLELEMENTWISEOPERATIONKERNEL_H */ 257