blob: 2f541758f4e8885706d5f7cb47bdc3cbe17ac473 [file] [log] [blame]
Michalis Spyrou7362f0d2017-10-18 17:58:22 +01001/*
Sheri Zhangac6499a2021-02-10 15:32:38 +00002 * Copyright (c) 2017-2021 Arm Limited.
Michalis Spyrou7362f0d2017-10-18 17:58:22 +01003 *
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 */
Michalis Spyrouf4643372019-11-29 16:17:13 +000024#ifndef ARM_COMPUTE_NEDEPTHWISECONVOLUTION_H
25#define ARM_COMPUTE_NEDEPTHWISECONVOLUTION_H
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010026
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +010027#include "arm_compute/runtime/IMemoryManager.h"
28#include "arm_compute/runtime/MemoryGroup.h"
Georgios Pinitas60e98252018-10-22 16:17:20 +010029#include "arm_compute/runtime/NEON/functions/NEActivationLayer.h"
Georgios Pinitas284cfe22018-02-13 12:15:13 +000030#include "arm_compute/runtime/NEON/functions/NEPermute.h"
Michalis Spyrouebcebf12020-10-21 00:04:14 +010031#include <memory>
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010032
33namespace arm_compute
34{
Georgios Pinitas30271c72019-06-24 14:56:34 +010035// Forward declarations
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010036class ITensor;
Michalis Spyrouebcebf12020-10-21 00:04:14 +010037class NEDepthwiseConvolutionLayerNativeKernel;
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010038
Manuel Bottini05069f02019-09-26 17:18:26 +010039/** Function to execute a depthwise convolution.
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010040 */
Manuel Bottini05069f02019-09-26 17:18:26 +010041class NEDepthwiseConvolutionLayer : public IFunction
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010042{
43public:
44 /** Default constructor */
Manuel Bottini05069f02019-09-26 17:18:26 +010045 NEDepthwiseConvolutionLayer(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
Georgios Pinitas47d39dc2019-03-11 14:03:23 +000046 /** Prevent instances of this class from being copied (As this class contains pointers) */
Manuel Bottini05069f02019-09-26 17:18:26 +010047 NEDepthwiseConvolutionLayer(const NEDepthwiseConvolutionLayer &) = delete;
Georgios Pinitas47d39dc2019-03-11 14:03:23 +000048 /** Default move constructor */
Manuel Bottini05069f02019-09-26 17:18:26 +010049 NEDepthwiseConvolutionLayer(NEDepthwiseConvolutionLayer &&) = default;
Georgios Pinitas47d39dc2019-03-11 14:03:23 +000050 /** Prevent instances of this class from being copied (As this class contains pointers) */
Manuel Bottini05069f02019-09-26 17:18:26 +010051 NEDepthwiseConvolutionLayer &operator=(const NEDepthwiseConvolutionLayer &) = delete;
Georgios Pinitas47d39dc2019-03-11 14:03:23 +000052 /** Default move assignment operator */
Manuel Bottini05069f02019-09-26 17:18:26 +010053 NEDepthwiseConvolutionLayer &operator=(NEDepthwiseConvolutionLayer &&) = default;
Michalis Spyrouebcebf12020-10-21 00:04:14 +010054 /** Default destructor */
55 ~NEDepthwiseConvolutionLayer();
Manuel Bottini05069f02019-09-26 17:18:26 +010056 /** Initialize the function's source, destination, weights and convolution information.
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010057 *
Teresa Charlin62687422021-04-28 10:58:49 +010058 * Valid data layouts:
59 * - NHWC
60 * - NCHW
61 *
62 * Valid data type configurations:
63 * |src0 |src1 |src2 |dst |
64 * |:--------------|:------------------|:------|:--------------|
65 * |F16 |F16 |F16 |F16 |
66 * |F32 |F32 |F32 |F32 |
67 * |QASYMM8 |QASYMM8 |S32 |QASYMM8 |
68 * |QASYMM8 |QSYMM8_PER_CHANNEL |S32 |QASYMM8 |
69 * |QASYMM8_SIGNED |QASYMM8_SIGNED |S32 |QASYMM8_SIGNED |
70 * |QASYMM8_SIGNED |QSYMM8_PER_CHANNEL |S32 |QASYMM8_SIGNED |
71 *
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +000072 * @param[in, out] input Source tensor. Data type supported: QASYMM8/QASYMM8_SIGNED/F16/F32
Manuel Bottini05069f02019-09-26 17:18:26 +010073 * @param[out] output Destination tensor. Data type supported: same as @p input.
Michele Di Giorgiodf4cf572019-10-09 15:32:39 +010074 * @param[in] weights Weights tensor. These are 3D tensors with shape [kernel_x, kernel_y, IFM].
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +000075 * Data type supported: Same as @p input or QASYMM8/QASYMM8_SIGNED/QSYMM8_PER_CHANNEL when @p input is QASYMM8/QASYMM8_SIGNED.
Usama Arife73686a2019-04-08 17:30:48 +010076 * @param[in] biases Biases tensor. A 1D tensor with shape [IFM]. Must be nullptr if not needed.
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +000077 * Data type supported: Same as @p input, S32 when input is QASYMM8/QASYMM8_SIGNED.
Giorgio Arena76572242018-04-04 17:44:26 +010078 * @param[in] conv_info Padding and stride information to use for the convolution.
79 * @param[in] depth_multiplier (Optional) Multiplier to apply to the input's depth in order to retrieve the output's depth. Defaults to 1.
Georgios Pinitas60e98252018-10-22 16:17:20 +010080 * @param[in] act_info (Optional) Activation layer information in case of a fused activation.
Usama Arif881f2de2019-04-12 10:29:17 +010081 * @param[in] dilation (Optional) Dilation, in elements, across x and y. Defaults to (1, 1).
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010082 */
Georgios Pinitas60e98252018-10-22 16:17:20 +010083 void configure(ITensor *input, const ITensor *weights, const ITensor *biases, ITensor *output, const PadStrideInfo &conv_info,
Usama Arife73686a2019-04-08 17:30:48 +010084 unsigned int depth_multiplier = 1, const ActivationLayerInfo &act_info = ActivationLayerInfo(), const Size2D &dilation = Size2D(1U, 1U));
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010085
Manuel Bottini05069f02019-09-26 17:18:26 +010086 /** Static function to check if given info will lead to a valid configuration of @ref NEDepthwiseConvolutionLayer
Abe Mbise7784c832018-05-31 16:48:41 +010087 *
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +000088 * @param[in] input Source tensor. Data type supported: QASYMM8/QASYMM8_SIGNED/F16/F32
Manuel Bottini05069f02019-09-26 17:18:26 +010089 * @param[in] output Destination tensor. Data type supported: same as @p input.
Michele Di Giorgiodf4cf572019-10-09 15:32:39 +010090 * @param[in] weights Weights tensor. These are 3D tensors with shape [kernel_x, kernel_y, IFM].
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +000091 * Data type supported: Same as @p input or QASYMM8/QASYMM8_SIGNED/QSYMM8_PER_CHANNEL when @p input is QASYMM8/QASYMM8_SIGNED.
Usama Arife73686a2019-04-08 17:30:48 +010092 * @param[in] biases Biases tensor. A 1D tensor with shape [IFM]. Must be nullptr if not needed.
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +000093 * Data type supported: Same as @p input, S32 when input is QASYMM8/QASYMM8_SIGNED.
Abe Mbise7784c832018-05-31 16:48:41 +010094 * @param[in] conv_info Padding and stride information to use for the convolution.
95 * @param[in] depth_multiplier (Optional) Multiplier to apply to the input's depth in order to retrieve the output's depth. Defaults to 1.
Georgios Pinitas60e98252018-10-22 16:17:20 +010096 * @param[in] act_info (Optional) Activation layer information in case of a fused activation.
Usama Arif881f2de2019-04-12 10:29:17 +010097 * @param[in] dilation (Optional) Dilation, in elements, across x and y. Defaults to (1, 1).
Abe Mbise7784c832018-05-31 16:48:41 +010098 *
99 * @return a status
100 */
Georgios Pinitas60e98252018-10-22 16:17:20 +0100101 static Status validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *output, const PadStrideInfo &conv_info,
Usama Arife73686a2019-04-08 17:30:48 +0100102 unsigned int depth_multiplier = 1, const ActivationLayerInfo &act_info = ActivationLayerInfo(), const Size2D &dilation = Size2D(1U, 1U));
Abe Mbise7784c832018-05-31 16:48:41 +0100103
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100104 // Inherited methods overriden:
105 void run() override;
Georgios Pinitas47d39dc2019-03-11 14:03:23 +0000106 void prepare() override;
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100107
108private:
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000109 /** Basic function to execute optimized depthwise convolution routines. This function calls the following kernels:
Manuel Bottini05069f02019-09-26 17:18:26 +0100110 *
111 * @note At the moment 3x3 and 5x5 convolution of stride 1, 2 are supported
112 *
113 * -# @ref NEFillBorderKernel (if pad_x or pad_y > 0) and no assembly kernel implementation is present
114 * -# @ref NEDepthwiseConvolutionLayer3x3Kernel if 3x3 and no assembly kernel implementation is present
115 * -# @ref NEDepthwiseConvolutionAssemblyDispatch if assembly kernel implementation is present
116 * -# @ref NEDirectConvolutionLayerOutputStageKernel if re-quantization of output is required
117 * -# @ref NEActivationLayer if fused activation is required
118 *
119 */
120 class NEDepthwiseConvolutionLayerOptimizedInternal : public IFunction
121 {
122 public:
123 /** Default constructor */
124 NEDepthwiseConvolutionLayerOptimizedInternal(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
125 /** Prevent instances of this class from being copied (As this class contains pointers) */
126 NEDepthwiseConvolutionLayerOptimizedInternal(const NEDepthwiseConvolutionLayerOptimizedInternal &) = delete;
127 /** Default move constructor */
128 NEDepthwiseConvolutionLayerOptimizedInternal(NEDepthwiseConvolutionLayerOptimizedInternal &&) = default;
129 /** Prevent instances of this class from being copied (As this class contains pointers) */
130 NEDepthwiseConvolutionLayerOptimizedInternal &operator=(const NEDepthwiseConvolutionLayerOptimizedInternal &) = delete;
131 /** Default move assignment operator */
132 NEDepthwiseConvolutionLayerOptimizedInternal &operator=(NEDepthwiseConvolutionLayerOptimizedInternal &&) = default;
Michalis Spyrouebcebf12020-10-21 00:04:14 +0100133 /** Default destructor */
134 ~NEDepthwiseConvolutionLayerOptimizedInternal() = default;
Manuel Bottini05069f02019-09-26 17:18:26 +0100135 /** Initialize the function's source, destination, kernels and border_size.
136 *
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +0000137 * @param[in, out] input Source tensor. Data type supported: QASYMM8/QASYMM8_SIGNED/F16/F32. (Written to only for border filling).
Manuel Bottini05069f02019-09-26 17:18:26 +0100138 * @param[in] weights Weights tensor. These are 3D tensors with shape [kernel_x, kernel_y, IFM]. Data type supported: Same as @p input.
139 * @param[in] biases Biases tensor. A 1D tensor with shape [IFM]. Must be nullptr if not needed.
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +0000140 * Data type supported: Same as @p input, S32 when input is QASYMM8/QASYMM8_SIGNED.
Manuel Bottini05069f02019-09-26 17:18:26 +0100141 * @param[out] output Destination tensor. Data type supported: same as @p input.
142 * @param[in] conv_info Padding and stride information to use for the convolution.
143 * @param[in] depth_multiplier (Optional) Multiplier to apply to the input's depth in order to retrieve the output's depth. Defaults to 1.
144 * @param[in] act_info (Optional) Activation layer information in case of a fused activation.
145 * @param[in] dilation (Optional) Dilation, in elements, across x and y. Defaults to (1, 1).
146 */
147 void configure(ITensor *input, const ITensor *weights, const ITensor *biases, ITensor *output, const PadStrideInfo &conv_info,
148 unsigned int depth_multiplier = 1, const ActivationLayerInfo &act_info = ActivationLayerInfo(), const Size2D &dilation = Size2D(1U, 1U));
149
150 /** Static function to check if given info will lead to a valid configuration of @ref NEDepthwiseConvolutionLayer3x3
151 *
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +0000152 * @param[in] input Source tensor. Data type supported: QASYMM8/QASYMM8_SIGNED/F16/F32. (Written to only for border filling).
Manuel Bottini05069f02019-09-26 17:18:26 +0100153 * @param[in] weights Weights tensor. These are 3D tensors with shape [kernel_x, kernel_y, IFM]. Data type supported: Same as @p input.
154 * @param[in] biases Biases tensor. A 1D tensor with shape [IFM]. Must be nullptr if not needed.
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +0000155 * Data type supported: Same as @p input, S32 when input is QASYMM8/QASYMM8_SIGNED.
Manuel Bottini05069f02019-09-26 17:18:26 +0100156 * @param[in] output Destination tensor. Data type supported: same as @p input.
157 * @param[in] conv_info Padding and stride information to use for the convolution.
158 * @param[in] depth_multiplier (Optional) Multiplier to apply to the input's depth in order to retrieve the output's depth. Defaults to 1.
159 * @param[in] act_info (Optional) Activation layer information in case of a fused activation.
160 * @param[in] dilation (Optional) Dilation, in elements, across x and y. Defaults to (1, 1).
161 *
162 * @return a status
163 */
164 static Status validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *output, const PadStrideInfo &conv_info,
165 unsigned int depth_multiplier = 1, const ActivationLayerInfo &act_info = ActivationLayerInfo(), const Size2D &dilation = Size2D(1U, 1U));
166
167 // Inherited methods overriden:
168 void run() override;
169 void prepare() override;
170
171 private:
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +0100172 MemoryGroup _memory_group;
173 struct Impl;
174 std::unique_ptr<Impl> _impl;
Manuel Bottini05069f02019-09-26 17:18:26 +0100175 };
176
Michele Di Giorgio33f41fa2021-03-09 14:09:08 +0000177 /** Basic function to execute a generic depthwise convolution. This function calls the following kernel:
Manuel Bottini05069f02019-09-26 17:18:26 +0100178 *
179 * -# @ref NEDepthwiseConvolutionLayerNativeKernel
180 *
181 */
182 class NEDepthwiseConvolutionLayerGeneric : public IFunction
183 {
184 public:
185 /** Default constructor */
186 NEDepthwiseConvolutionLayerGeneric();
187 /** Prevent instances of this class from being copied (As this class contains pointers) */
188 NEDepthwiseConvolutionLayerGeneric(const NEDepthwiseConvolutionLayerGeneric &) = delete;
189 /** Default move constructor */
190 NEDepthwiseConvolutionLayerGeneric(NEDepthwiseConvolutionLayerGeneric &&) = default;
191 /** Prevent instances of this class from being copied (As this class contains pointers) */
192 NEDepthwiseConvolutionLayerGeneric &operator=(const NEDepthwiseConvolutionLayerGeneric &) = delete;
193 /** Default move assignment operator */
194 NEDepthwiseConvolutionLayerGeneric &operator=(NEDepthwiseConvolutionLayerGeneric &&) = default;
Michalis Spyrouebcebf12020-10-21 00:04:14 +0100195 /** Default destructor */
196 ~NEDepthwiseConvolutionLayerGeneric() = default;
Manuel Bottini05069f02019-09-26 17:18:26 +0100197 /** Initialize the function's source, destination, weights and convolution information.
198 *
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +0000199 * @param[in, out] input Source tensor. Data type supported: QASYMM8/QASYMM8_SIGNED/F16/F32. (Written to only for border filling).
Manuel Bottini05069f02019-09-26 17:18:26 +0100200 * @param[out] output Destination tensor. Data type supported: same as @p input.
Michele Di Giorgiodf4cf572019-10-09 15:32:39 +0100201 * @param[in] weights Weights tensor. These are 3D tensors with shape [kernel_x, kernel_y, IFM].
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +0000202 * Data type supported: Same as @p input or QASYMM8/QASYMM8_SIGNED/QSYMM8_PER_CHANNEL when @p input is QASYMM8/QASYMM8_SIGNED.
Manuel Bottini05069f02019-09-26 17:18:26 +0100203 * @param[in] biases Biases tensor. A 1D tensor with shape [IFM]. Must be nullptr if not needed.
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +0000204 * Data type supported: Same as @p input, S32 when input is QASYMM8/QASYMM8_SIGNED.
Manuel Bottini05069f02019-09-26 17:18:26 +0100205 * @param[in] conv_info Padding and stride information to use for the convolution.
206 * @param[in] depth_multiplier (Optional) Multiplier to apply to the input's depth in order to retrieve the output's depth. Defaults to 1.
207 * @param[in] act_info (Optional) Activation layer information in case of a fused activation.
208 * @param[in] dilation (Optional) Dilation, in elements, across x and y. Defaults to (1, 1).
209 */
210 void configure(ITensor *input, const ITensor *weights, const ITensor *biases, ITensor *output, const PadStrideInfo &conv_info,
211 unsigned int depth_multiplier = 1, const ActivationLayerInfo &act_info = ActivationLayerInfo(), const Size2D &dilation = Size2D(1U, 1U));
212
213 /** Static function to check if given info will lead to a valid configuration of @ref NEDepthwiseConvolutionLayerGeneric
214 *
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +0000215 * @param[in] input Source tensor. Data type supported: QASYMM8/QASYMM8_SIGNED/F16/F32. (Written to only for border filling).
Manuel Bottini05069f02019-09-26 17:18:26 +0100216 * @param[in] output Destination tensor. Data type supported: same as @p input.
Michele Di Giorgiodf4cf572019-10-09 15:32:39 +0100217 * @param[in] weights Weights tensor. These are 3D tensors with shape [kernel_x, kernel_y, IFM].
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +0000218 * Data type supported: Same as @p input or QASYMM8/QASYMM8_SIGNED/QSYMM8_PER_CHANNEL when @p input is QASYMM8/QASYMM8_SIGNED.
Manuel Bottini05069f02019-09-26 17:18:26 +0100219 * @param[in] biases Biases tensor. A 1D tensor with shape [IFM]. Must be nullptr if not needed.
Michele Di Giorgio8c837ca2020-01-07 15:06:41 +0000220 * Data type supported: Same as @p input, S32 when input is QASYMM8/QASYMM8_SIGNED.
Manuel Bottini05069f02019-09-26 17:18:26 +0100221 * @param[in] conv_info Padding and stride information to use for the convolution.
222 * @param[in] depth_multiplier (Optional) Multiplier to apply to the input's depth in order to retrieve the output's depth. Defaults to 1.
223 * @param[in] act_info (Optional) Activation layer information in case of a fused activation.
224 * @param[in] dilation (Optional) Dilation, in elements, across x and y. Defaults to (1, 1).
225 *
226 * @return a status
227 */
228 static Status validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *output, const PadStrideInfo &conv_info,
229 unsigned int depth_multiplier = 1, const ActivationLayerInfo &act_info = ActivationLayerInfo(), const Size2D &dilation = Size2D(1U, 1U));
230
231 // Inherited methods overriden:
232 void run() override;
Manuel Bottini05069f02019-09-26 17:18:26 +0100233
234 private:
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +0100235 struct Impl;
236 std::unique_ptr<Impl> _impl;
Manuel Bottini05069f02019-09-26 17:18:26 +0100237 };
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +0100238 MemoryGroup _memory_group;
239 struct Impl;
240 std::unique_ptr<Impl> _impl;
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100241};
Georgios Pinitas8cffcd62018-11-16 17:11:50 +0000242} // namespace arm_compute
Sheri Zhangac6499a2021-02-10 15:32:38 +0000243#endif /* ARM_COMPUTE_NEDEPTHWISECONVOLUTION_H */