1 /* 2 * Copyright (c) 2021-2022 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_CPU_ELEMENTWISE_KERNEL_H 25 #define ARM_COMPUTE_CPU_ELEMENTWISE_KERNEL_H 26 27 #include "src/core/common/Macros.h" 28 #include "src/cpu/ICpuKernel.h" 29 30 namespace arm_compute 31 { 32 namespace cpu 33 { 34 namespace kernels 35 { 36 /** Interface for an element-wise operation kernel 37 * 38 * Element-wise operation is computed by: 39 * @f[ dst(x,y) = OP(src0(x,y), src1(x,y))@f] 40 * 41 */ 42 template <class Derived> 43 class CpuElementwiseKernel : public ICpuKernel<Derived> 44 { 45 private: 46 using ElementwiseKernelPtr = std::add_pointer<void(const ITensor *, const ITensor *, ITensor *, const Window &)>::type; 47 48 public: 49 CpuElementwiseKernel() = default; 50 ARM_COMPUTE_DISALLOW_COPY_ALLOW_MOVE(CpuElementwiseKernel); 51 52 using ElementwiseFunction = void(const ITensor *, const ITensor *, ITensor *, const Window &); 53 // Inherited methods overridden: 54 void run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info) override; 55 56 const char *name() const override; 57 58 struct ElementwiseKernel 59 { 60 const char *name; 61 const ElementwiseDataTypeISASelectorPtr is_selected; 62 ElementwiseKernelPtr ukernel; 63 }; 64 65 protected: 66 /** Validate the argument passed to the kernel 67 * 68 * @param[in] src0 First tensor input. Data types supported: QASYMM8/S16/F16/S32/F32. 69 * @param[in] src1 Second tensor input. Data types supported: Same as @p src0. 70 * @param[in] dst Output tensor. Data types supported: Dependent on subclass. 71 */ 72 static Status validate_arguments_common(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst); 73 74 protected: 75 ElementwiseKernelPtr _run_method{ nullptr }; 76 std::string _name{}; 77 }; 78 79 class CpuArithmeticKernel : public CpuElementwiseKernel<CpuArithmeticKernel> 80 { 81 public: 82 CpuArithmeticKernel() = default; 83 84 /** Configure kernel 85 * 86 * @param[in] op Arithmetic operation to be executed. 87 * @param[in] src0 First tensor input info. Data types supported: QASYMM8/S16/F16/S32/F32. 88 * @param[in] src1 Second tensor input info. Data types supported: Same as @p src0. 89 * @param[out] dst Output tensor info. Data types supported: Same as @p src0. 90 */ 91 void configure(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst); 92 93 /** Static function to check if given info will lead to a valid configuration 94 * 95 * Similar to CpuArithmeticKernel::configure() 96 * 97 * @return a status 98 */ 99 static Status validate(ArithmeticOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst); 100 101 static const std::vector<CpuElementwiseKernel<CpuArithmeticKernel>::ElementwiseKernel> &get_available_kernels(); 102 103 /** Return minimum workload size of the relevant kernel 104 * 105 * @param[in] platform The CPU platform used to create the context. 106 * @param[in] thread_count Number of threads in the execution. 107 * 108 * @return[out] mws Minimum workload size for requested configuration. 109 */ 110 size_t get_mws(const CPUInfo &platform, size_t thread_count) const override; 111 112 protected: 113 /** Commmon configure function for element-wise operators with no additional options (e.g. Min, Max, SquaredDiff) 114 */ 115 void configure_common(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst); 116 // Inherited methods overridden: 117 static Status validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst); 118 119 ArithmeticOperation _op{}; 120 }; 121 122 class CpuDivisionKernel : public CpuArithmeticKernel 123 { 124 public: 125 CpuDivisionKernel() = default; 126 127 /** Configure kernel 128 * 129 * @param[in] src0 First tensor input info. Data types supported: S32/F16/F32. 130 * @param[in] src1 Second tensor input info. Data types supported: Same as @p src0. 131 * @param[out] dst Output tensor info. Data types supported: Same as @p src0. 132 */ 133 void configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst); 134 135 /** Static function to check if given info will lead to a valid configuration 136 * 137 * Similar to CpuDivisionKernel::configure() 138 * 139 * @return a status 140 */ 141 static Status validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst); 142 143 /** Return minimum workload size of the relevant kernel 144 * 145 * @param[in] platform The CPU platform used to create the context. 146 * @param[in] thread_count Number of threads in the execution. 147 * 148 * @return[out] mws Minimum workload size for requested configuration. 149 */ 150 size_t get_mws(const CPUInfo &platform, size_t thread_count) const override; 151 152 protected: 153 // Inherited methods overridden: 154 static Status validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst); 155 }; 156 157 class CpuPowerKernel : public CpuArithmeticKernel 158 { 159 public: 160 CpuPowerKernel() = default; 161 162 /** Configure kernel 163 * 164 * @param[in] src0 First tensor input info. Data types supported: F16/F32. 165 * @param[in] src1 Second tensor input info. Data types supported: Same as @p src0. 166 * @param[out] dst Output tensor info. Data types supported: Same as @p src0. 167 */ 168 void configure(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst); 169 170 /** Static function to check if given info will lead to a valid configuration 171 * 172 * Similar to CpuPowerKernel::configure() 173 * 174 * @return a status 175 */ 176 static Status validate(const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst); 177 178 protected: 179 // Inherited methods overridden: 180 static Status validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst); 181 }; 182 183 class CpuComparisonKernel : public CpuElementwiseKernel<CpuComparisonKernel> 184 { 185 public: 186 CpuComparisonKernel() = default; 187 188 /** Configure kernel 189 * 190 * @param[in] op Comparison operation to be executed. 191 * @param[in] src0 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32. 192 * @param[in] src1 Second tensor input info. Data types supported: Same as @p src0. 193 * @param[out] dst Output tensor info. Data types supported: U8. 194 */ 195 void configure(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst); 196 197 /** Static function to check if given info will lead to a valid configuration 198 * 199 * Similar to CpuComparisonKernel::configure() 200 * 201 * @return a status 202 */ 203 static Status validate(ComparisonOperation op, const ITensorInfo *src0, const ITensorInfo *src1, const ITensorInfo *dst); 204 205 static const std::vector<CpuElementwiseKernel<CpuComparisonKernel>::ElementwiseKernel> &get_available_kernels(); 206 207 protected: 208 /** Commmon configure function for element-wise operators with no additional options (e.g. Min, Max, SquaredDiff) 209 */ 210 void configure_common(const ITensorInfo *src0, const ITensorInfo *src1, ITensorInfo *dst); 211 // Inherited methods overridden: 212 static Status validate_arguments(const ITensorInfo &src0, const ITensorInfo &src1, const ITensorInfo &dst); 213 214 private: 215 /** Function to get the micro kernel implementation 216 * 217 * @param[in] src0 First input tensor information 218 * @param[in] src1 Second input tensor information 219 * @param[in] dst Output tensor information 220 * 221 * @return the function instance for the micro kernel 222 */ 223 224 ComparisonOperation _op{}; 225 }; 226 } // namespace kernels 227 } // namespace cpu 228 } // namespace arm_compute 229 #endif /* ARM_COMPUTE_CPU_ELEMENTWISE_KERNEL_H */