From 6d109965f3641056bb8164dc8450a7327e76e939 Mon Sep 17 00:00:00 2001 From: giuros01 Date: Mon, 7 Jan 2019 17:47:19 +0000 Subject: COMPMID-1691: Optimize CLDepthwiseConvolutionKernel (QASYMM8/NHWC) for 3x3 kernels (stride=1 and stride=2) Change-Id: I7d0d2dc350feeb40d253d17f9ffd5051a8fb42ef Reviewed-on: https://review.mlplatform.org/511 Reviewed-by: Gian Marco Iodice Tested-by: Arm Jenkins --- arm_compute/core/utils/misc/ShapeCalculator.h | 56 +++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'arm_compute/core/utils') diff --git a/arm_compute/core/utils/misc/ShapeCalculator.h b/arm_compute/core/utils/misc/ShapeCalculator.h index 35e21679d2..b256e73146 100644 --- a/arm_compute/core/utils/misc/ShapeCalculator.h +++ b/arm_compute/core/utils/misc/ShapeCalculator.h @@ -250,6 +250,30 @@ inline TensorShape compute_interleaved_shape(const ITensorInfo &a, int mult_inte return shape_interleaved_a; } +/** Calculate the reshaped shape of the weights to use in depthwise convolution + * + * @param[in] input Input tensor info + * @param[in] info Depthwise convolution information to be used for reshaping. + * + * @return the calculated shape + */ +inline TensorShape compute_reshaped_depthwise_weights_shape(const ITensorInfo &input, const DepthwiseConvolutionReshapeInfo &info) +{ + const auto data_layout = input.data_layout(); + TensorShape weights_shape{}; + + const int width_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH); + const int height_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT); + const int channel_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::CHANNEL); + const size_t num_channels = input.dimension(channel_idx); + const size_t num_rows = input.dimension(height_idx); + const size_t num_cols = input.dimension(width_idx); + + weights_shape.set(0, num_rows * num_cols * info.c0); + weights_shape.set(1, DIV_CEIL(num_channels, info.c0)); + return weights_shape; +} + /** Calculate the transposed 1xW shape * * @param[in] b Input tensor info @@ -405,6 +429,38 @@ inline TensorShape compute_depthwise_convolution_shape(const ITensorInfo &input, return output_shape; } +/** Calculate the depthwise convolution output shape of a tensor + * + * @param[in] input Input tensor info + * @param[in] weights_width Weights width + * @param[in] weights_height Weights height + * @param[in] conv_info Padding and stride information to use for the convolution. + * @param[in] depth_multiplier Multiplier to apply to the input's depth in order to retrieve the output's depth. + * + * @return the calculated shape + */ +inline TensorShape compute_depthwise_convolution_shape(const ITensorInfo &input, int weights_width, int weights_height, PadStrideInfo conv_info, unsigned int depth_multiplier) +{ + const TensorShape input_shape{ input.tensor_shape() }; + + const DataLayout data_layout = input.data_layout(); + const int width_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH); + const int height_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT); + const int channel_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::CHANNEL); + + unsigned int output_width = 0; + unsigned int output_height = 0; + std::tie(output_width, output_height) = scaled_dimensions(input_shape[width_idx], input_shape[height_idx], + weights_width, weights_width, conv_info); + + TensorShape output_shape{ input_shape }; + output_shape.set(width_idx, output_width); + output_shape.set(height_idx, output_height); + output_shape.set(channel_idx, input_shape[channel_idx] * depth_multiplier); + + return output_shape; +} + /** Calculate the upsampled output shape used for deconvolution * * @param[in] input Input tensor info -- cgit v1.2.1