From d928735fee6baefdb74325c05d8152dd13044f32 Mon Sep 17 00:00:00 2001 From: SiCongLi Date: Wed, 3 Nov 2021 19:01:22 +0000 Subject: Add validate tests for CLConvolutionLayer and CLGEMMConvolutionLayer with post ops * Add validate tests * Restrict post ops support in ClGemmConv2d to only those that do not need im2col or col2im. In practice this means we only support post ops in conv1x1 with stride = 1, dilation = 1 and data layout = NHWC Resolves COMPMID-4435 Change-Id: I1fdf0c5d565a4624857250075ac76db35c2f383b Signed-off-by: SiCongLi Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/6573 Reviewed-by: Gunes Bayir Comments-Addressed: Arm Jenkins Tested-by: Arm Jenkins --- arm_compute/core/experimental/IPostOp.h | 9 ++++++++ arm_compute/core/utils/misc/ShapeCalculator.h | 31 ++++++++++++++++++--------- 2 files changed, 30 insertions(+), 10 deletions(-) (limited to 'arm_compute/core') diff --git a/arm_compute/core/experimental/IPostOp.h b/arm_compute/core/experimental/IPostOp.h index 178c83aa75..567a4023c0 100644 --- a/arm_compute/core/experimental/IPostOp.h +++ b/arm_compute/core/experimental/IPostOp.h @@ -71,6 +71,15 @@ using PostOpTypeSequence = std::vector; * * post_op_arg1 = [1, 1, 34] is allowed: broadcast in dims 0 and 1 * * post_op_arg1 = [14, 15, 34] is NOT allowed: broadcast widens the dst tensor * + * @note: On Data layout + * All post ops are data layout agnostic. This means post ops do not have an inherent idea of "width", "height" and so on. + * Should we want to perform a post op with 2 tensors of different data layouts (where data layouts are significant to both), + * then we need to perform necessary permutation op beforehand to unify their data layout before they can be fused with a post op + * + * Note although post ops themselves should be able to support any data layout, the main op they fuse to may impose + * additional restrictions in the presence of post ops. For example, the implementation of a gemm op may only allow + * NHWC data layout if post ops are provided. Such restrictions are main op implementation specific. + * * @note: PostOps do not own any resources pointed to by TensorRelatedT if it's a pointer type * @note: If TensorRelatedT points to a resource, IPostOp assumes that resource is valid throughout its lifetime * and the lifetime of its copies. This is almost guaranteed as IPostOp is only meant to be used at configure time diff --git a/arm_compute/core/utils/misc/ShapeCalculator.h b/arm_compute/core/utils/misc/ShapeCalculator.h index f18f5b7a42..3e8b024f82 100644 --- a/arm_compute/core/utils/misc/ShapeCalculator.h +++ b/arm_compute/core/utils/misc/ShapeCalculator.h @@ -703,20 +703,18 @@ inline TensorShape compute_winograd_output_transform_shape(const ITensorInfo &in /** Calculate the deep convolution shape output shape of a tensor * - * @param[in] input Input tensor info - * @param[in] weights Weights tensor info - * @param[in] conv_info Contains padding and stride information + * @param[in] input_shape Input tensor shape + * @param[in] input_data_layout Input data layout + * @param[in] weights_shape Weights tensor shape + * @param[in] conv_info Contains padding and stride information * * @return the calculated shape */ -inline TensorShape compute_deep_convolution_shape(const ITensorInfo &input, const ITensorInfo &weights, PadStrideInfo conv_info) +inline TensorShape compute_deep_convolution_shape(const TensorShape &input_shape, DataLayout input_data_layout, const TensorShape &weights_shape, const PadStrideInfo &conv_info) { - const TensorShape input_shape{ input.tensor_shape() }; - const TensorShape weights_shape{ weights.tensor_shape() }; - - const size_t idx_width = get_data_layout_dimension_index(input.data_layout(), DataLayoutDimension::WIDTH); - const size_t idx_height = get_data_layout_dimension_index(input.data_layout(), DataLayoutDimension::HEIGHT); - const size_t idx_channel = get_data_layout_dimension_index(input.data_layout(), DataLayoutDimension::CHANNEL); + const size_t idx_width = get_data_layout_dimension_index(input_data_layout, DataLayoutDimension::WIDTH); + const size_t idx_height = get_data_layout_dimension_index(input_data_layout, DataLayoutDimension::HEIGHT); + const size_t idx_channel = get_data_layout_dimension_index(input_data_layout, DataLayoutDimension::CHANNEL); const unsigned int input_width = input_shape[idx_width]; const unsigned int input_height = input_shape[idx_height]; @@ -735,6 +733,19 @@ inline TensorShape compute_deep_convolution_shape(const ITensorInfo &input, cons return output_shape; } +/** Calculate the deep convolution shape output shape of a tensor + * + * @param[in] input Input tensor info + * @param[in] weights Weights tensor info + * @param[in] conv_info Contains padding and stride information + * + * @return the calculated shape + */ +inline TensorShape compute_deep_convolution_shape(const ITensorInfo &input, const ITensorInfo &weights, const PadStrideInfo &conv_info) +{ + return compute_deep_convolution_shape(input.tensor_shape(), input.data_layout(), weights.tensor_shape(), conv_info); +} + /** Calculate the min/max shape output shape of a tensor * * @param[in] input Input tensor info -- cgit v1.2.1