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_DEPTHWISE_CONV2D_H 25 #define ARM_COMPUTE_CPU_DEPTHWISE_CONV2D_H 26 27 #include "arm_compute/core/ITensorInfo.h" 28 #include "arm_compute/core/experimental/Types.h" 29 #include "src/cpu/ICpuKernel.h" 30 #include "src/cpu/ICpuOperator.h" 31 #include "src/cpu/kernels/CpuDepthwiseConv2dNativeKernel.h" 32 #include "src/cpu/operators/CpuActivation.h" 33 #include "src/cpu/operators/CpuDepthwiseConv2dAssemblyDispatch.h" 34 #include "src/cpu/operators/CpuPermute.h" 35 36 #include <memory> 37 38 namespace arm_compute 39 { 40 namespace cpu 41 { 42 /** Function to execute a depthwise convolution. 43 */ 44 class CpuDepthwiseConv2d : public ICpuOperator 45 { 46 public: 47 /** Default constructor */ 48 CpuDepthwiseConv2d() = default; 49 /** Initialize the function's source, destination, weights and convolution information. 50 * 51 * @param[in, out] src Source tensor info. Data type supported: QASYMM8/QASYMM8_SIGNED/F16/F32 52 * @param[out] dst Destination tensor info. Data type supported: same as @p src. 53 * @param[in] weights Weights tensor info. These are 3D tensor infos with shape [kernel_x, kernel_y, IFM]. 54 * Data type supported: Same as @p src or QASYMM8/QASYMM8_SIGNED/QSYMM8_PER_CHANNEL when @p src is QASYMM8/QASYMM8_SIGNED. 55 * @param[in] biases Biases tensor info. A 1D tensor with shape [IFM]. Must be nullptr if not needed. 56 * Data type supported: Same as @p src, S32 when src is QASYMM8/QASYMM8_SIGNED. 57 * @param[in] info Depthwise convolution meta-data. 58 */ 59 void configure(ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *biases, ITensorInfo *dst, const ConvolutionInfo &info); 60 /** Static function to check if given info will lead to a valid configuration 61 * 62 * Similar to CpuDepthwiseConv2d::configure() 63 * 64 * @return a status 65 */ 66 static Status validate(const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *dst, const ConvolutionInfo &info); 67 /** Static function to choose the best depthwise convolution function for @ref CpuDepthwiseConv2d 68 * 69 * @param[in] src Source tensor info. Data type supported: QASYMM8/QASYMM8_SIGNED/F16/F32 70 * @param[in] weights Weights tensor info. These are 3D tensors with shape [kernel_x, kernel_y, IFM]. 71 * Data type supported: Same as @p src or QASYMM8/QASYMM8_SIGNED/QSYMM8_PER_CHANNEL when @p src is QASYMM8/QASYMM8_SIGNED. 72 * @param[in] biases Biases tensor info. A 1D tensor with shape [IFM]. Must be nullptr if not needed. 73 * Data type supported: Same as @p src, S32 when src is QASYMM8/QASYMM8_SIGNED. 74 * @param[in] dst Destination tensor. Data type supported: same as @p src. 75 * @param[in] info Depthwise convolution meta-data. 76 * 77 * @return a Depthwise Convolution Function 78 */ 79 static DepthwiseConvolutionFunction get_depthwiseconvolution_function(const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *dst, 80 const ConvolutionInfo &info); 81 82 // Inherited methods overriden: 83 void run(ITensorPack &tensors) override; 84 void prepare(ITensorPack &tensors) override; 85 86 private: 87 /** Basic function to execute optimized depthwise convolution routines. This function calls the following kernels: 88 * 89 * @note At the moment 3x3 and 5x5 convolution of stride 1, 2 are supported 90 * 91 * -# @ref NEFillBorderKernel (if pad_x or pad_y > 0) and no assembly kernel implementation is present 92 * -# @ref CpuDepthwiseConv2d3x3Kernel if 3x3 and no assembly kernel implementation is present 93 * -# @ref CpuDepthwiseConv2dAssemblyDispatch if assembly kernel implementation is present 94 * -# @ref CpuActivation if fused activation is required 95 * 96 */ 97 class CpuDepthwiseConv2dOptimizedInternal : public ICpuOperator 98 { 99 public: 100 /** Default constructor */ 101 CpuDepthwiseConv2dOptimizedInternal() = default; 102 /** Prevent instances of this class from being copied (As this class contains pointers) */ 103 CpuDepthwiseConv2dOptimizedInternal(const CpuDepthwiseConv2dOptimizedInternal &) = delete; 104 /** Default move constructor */ 105 CpuDepthwiseConv2dOptimizedInternal(CpuDepthwiseConv2dOptimizedInternal &&) = default; 106 /** Prevent instances of this class from being copied (As this class contains pointers) */ 107 CpuDepthwiseConv2dOptimizedInternal &operator=(const CpuDepthwiseConv2dOptimizedInternal &) = delete; 108 /** Default move assignment operator */ 109 CpuDepthwiseConv2dOptimizedInternal &operator=(CpuDepthwiseConv2dOptimizedInternal &&) = default; 110 /** Default destructor */ 111 ~CpuDepthwiseConv2dOptimizedInternal() = default; 112 /** Initialize the function's source, destination, kernels and border_size. 113 * 114 * @param[in, out] src Source tensor info. Data type supported: QASYMM8/QASYMM8_SIGNED/F16/F32. (Written to only for border filling). 115 * @param[in] weights Weights tensor info. These are 3D tensors with shape [kernel_x, kernel_y, IFM]. Data type supported: Same as @p src. 116 * @param[in] biases Biases tensor info. A 1D tensor with shape [IFM]. Must be nullptr if not needed. 117 * Data type supported: Same as @p src, S32 when src is QASYMM8/QASYMM8_SIGNED. 118 * @param[out] dst Destination tensor info. Data type supported: same as @p src. 119 * @param[in] info Depthwise convolution meta-data. 120 */ 121 void configure(ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *biases, ITensorInfo *dst, const ConvolutionInfo &info); 122 /** Static function to check if given info will lead to a valid configuration 123 * 124 * Similar to CpuDepthwiseConv2dOptimizedInternal::configure() 125 * 126 * @return a status 127 */ 128 static Status validate(const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *dst, const ConvolutionInfo &info); 129 130 // Inherited methods overriden: 131 void run(ITensorPack &tensors) override; 132 void prepare(ITensorPack &tensors) override; 133 134 private: 135 std::unique_ptr<CpuDepthwiseConv2dAssemblyDispatch> _dwc_optimized_func{ nullptr }; 136 std::unique_ptr<CpuPermute> _permute_input{ nullptr }; 137 std::unique_ptr<CpuPermute> _permute_weights{ nullptr }; 138 std::unique_ptr<CpuPermute> _permute_output{ nullptr }; 139 std::unique_ptr<CpuActivation> _activationlayer_function{ nullptr }; 140 bool _has_bias{ false }; 141 bool _is_quantized{ false }; 142 bool _is_nchw{ true }; 143 bool _permute{ false }; 144 bool _is_activationlayer_enabled{ false }; 145 bool _is_prepared{ false }; 146 bool _are_weights_const{ true }; 147 }; 148 149 /** Basic function to execute a generic depthwise convolution. This function calls the following kernel: 150 * 151 * -# @ref CpuDepthwiseConv2dNativeKernel 152 * 153 */ 154 class CpuDepthwiseConv2dGeneric : public ICpuOperator 155 { 156 public: 157 /** Default constructor */ 158 CpuDepthwiseConv2dGeneric() = default; 159 /** Prevent instances of this class from being copied (As this class contains pointers) */ 160 CpuDepthwiseConv2dGeneric(const CpuDepthwiseConv2dGeneric &) = delete; 161 /** Default move constructor */ 162 CpuDepthwiseConv2dGeneric(CpuDepthwiseConv2dGeneric &&) = default; 163 /** Prevent instances of this class from being copied (As this class contains pointers) */ 164 CpuDepthwiseConv2dGeneric &operator=(const CpuDepthwiseConv2dGeneric &) = delete; 165 /** Default move assignment operator */ 166 CpuDepthwiseConv2dGeneric &operator=(CpuDepthwiseConv2dGeneric &&) = default; 167 /** Default destructor */ 168 ~CpuDepthwiseConv2dGeneric() = default; 169 /** Initialize the function's source, destination, weights and convolution information. 170 * 171 * @param[in, out] src Source tensor info. Data type supported: QASYMM8/QASYMM8_SIGNED/F16/F32. (Written to only for border filling). 172 * @param[out] dst Destination tensor info. Data type supported: same as @p src. 173 * @param[in] weights Weights tensor info. These are 3D tensors with shape [kernel_x, kernel_y, IFM]. 174 * Data type supported: Same as @p src or QASYMM8/QASYMM8_SIGNED/QSYMM8_PER_CHANNEL when @p src is QASYMM8/QASYMM8_SIGNED. 175 * @param[in] biases Biases tensor info. A 1D tensor with shape [IFM]. Must be nullptr if not needed. 176 * Data type supported: Same as @p src, S32 when src is QASYMM8/QASYMM8_SIGNED. 177 * @param[in] info Depthwise convolution meta-data. 178 */ 179 void configure(ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *biases, ITensorInfo *dst, const ConvolutionInfo &info); 180 181 /** Static function to check if given info will lead to a valid configuration 182 * 183 * Similar to CpuDepthwiseConv2dGeneric::configure() 184 * 185 * @return a status 186 */ 187 static Status validate(const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *dst, const ConvolutionInfo &info); 188 189 // Inherited methods overridden: 190 void run(ITensorPack &tensors) override; 191 void prepare(ITensorPack &tensors) override; 192 193 private: 194 std::unique_ptr<kernels::CpuDepthwiseConv2dNativeKernel> _depthwise_conv_kernel{ nullptr }; 195 std::unique_ptr<CpuPermute> _permute_input{ nullptr }; 196 std::unique_ptr<CpuPermute> _permute_weights{ nullptr }; 197 std::unique_ptr<CpuPermute> _permute_output{ nullptr }; 198 std::unique_ptr<CpuActivation> _activationlayer_function{ nullptr }; 199 bool _is_nchw{ true }; 200 bool _is_prepared{ false }; 201 bool _is_activationlayer_enabled{ false }; 202 }; 203 204 DepthwiseConvolutionFunction _depth_conv_func{ DepthwiseConvolutionFunction::GENERIC }; 205 CpuDepthwiseConv2dOptimizedInternal _func_optimized{}; 206 CpuDepthwiseConv2dGeneric _func_generic{}; 207 }; 208 } // namespace cpu 209 } // namespace arm_compute 210 #endif /* ARM_COMPUTE_CPU_DEPTHWISE_CONV2D_H */ 211