From 1524a0275dbe29005b7518dbe2991834b7e908d7 Mon Sep 17 00:00:00 2001 From: Viet-Hoa Do Date: Wed, 3 Aug 2022 16:39:23 +0100 Subject: Fix for AI benchmark ResNet regression * For 3x3 kernel, only choose the implementation with larger tile size if the input tensor is larger than the tile. Resolves: COMPMID-5467 Signed-off-by: Viet-Hoa Do Change-Id: I2cf95ddb25f477cb05da3b3501e0afe9548fc33a Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/8022 Tested-by: Arm Jenkins Reviewed-by: Gian Marco Iodice Comments-Addressed: Arm Jenkins Benchmark: Arm Jenkins --- .../kernels/convolution/winograd/output_transforms_fp32.cpp | 2 +- .../kernels/convolution/winograd/winograd_implementations.hpp | 11 ++++++++++- src/cpu/operators/CpuWinogradConv2d.cpp | 9 ++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/core/NEON/kernels/convolution/winograd/output_transforms_fp32.cpp b/src/core/NEON/kernels/convolution/winograd/output_transforms_fp32.cpp index 87ad4b2437..73abe8b945 100644 --- a/src/core/NEON/kernels/convolution/winograd/output_transforms_fp32.cpp +++ b/src/core/NEON/kernels/convolution/winograd/output_transforms_fp32.cpp @@ -45,7 +45,7 @@ void arm_fp32_1x2_1x7(unsigned int, const float *, size_t, const float *, float static const TransformImplementation transforms_fp32[] = { #if defined(__aarch64__) #endif // defined(__aarch64__) - { IMPL(4, 4, 3, 3, arm_fp32_4x4_3x3, Unpadded) }, + { IMPL(4, 4, 3, 3, arm_fp32_4x4_3x3, Unpadded), MethodConstraints::LargerShape }, { IMPL(2, 2, 3, 3, arm_fp32_2x2_3x3, Unpadded) }, { IMPL(2, 2, 5, 5, arm_fp32_2x2_5x5, Unpadded) }, { IMPL(1, 6, 1, 3, arm_fp32_1x6_1x3, Unpadded) }, diff --git a/src/core/NEON/kernels/convolution/winograd/winograd_implementations.hpp b/src/core/NEON/kernels/convolution/winograd/winograd_implementations.hpp index a23cb1d6b3..510f69baaa 100644 --- a/src/core/NEON/kernels/convolution/winograd/winograd_implementations.hpp +++ b/src/core/NEON/kernels/convolution/winograd/winograd_implementations.hpp @@ -38,6 +38,7 @@ enum class MethodConstraints RequiresSVE2 = 0x2, RequiresSME = 0x4, RequiresSME2 = 0x8, + LargerShape = 0x10, // Input tensor shape is larger than the output transform tile shape. }; constexpr inline bool operator!(const MethodConstraints &c) @@ -66,6 +67,14 @@ inline bool constraints_met(const MethodConstraints &c, const CPUInfo *ci, const ); } +inline bool output_transform_constraints_met(const output_transform::ITransform *transform, const MethodConstraints &c, const CPUInfo *ci, const ConvolutionArgs &conv_args, const WinogradConfig *cfg) +{ + return ( + constraints_met(c, ci, conv_args, cfg) && + (!(c & MethodConstraints::LargerShape) || (conv_args.input_shape.rows > transform->get_output_rows() && conv_args.input_shape.cols > transform->get_output_cols())) + ); +} + namespace weight_transform { template @@ -209,7 +218,7 @@ inline std::vector get_output_transforms( impl->transform.get() != nullptr; impl++) { if( - constraints_met(impl->constraints, ci, conv_args, cfg) && + output_transform_constraints_met(impl->transform.get(), impl->constraints, ci, conv_args, cfg) && impl->transform->get_kernel_rows() == conv_args.kernel_shape.rows && impl->transform->get_kernel_cols() == conv_args.kernel_shape.cols && (cfg->output_rows == 0 || cfg->output_rows == impl->transform->get_output_rows()) && diff --git a/src/cpu/operators/CpuWinogradConv2d.cpp b/src/cpu/operators/CpuWinogradConv2d.cpp index 7be2d6d230..81cf651b76 100644 --- a/src/cpu/operators/CpuWinogradConv2d.cpp +++ b/src/cpu/operators/CpuWinogradConv2d.cpp @@ -252,9 +252,15 @@ void CpuWinogradConv2d::configure(const ITensorInfo *src, const ITensorInfo *wei _permute_output->configure(&_output_nhwc, dst, PermutationVector(1U, 2U, 0U)); } + // Configure input transform kernel + _transform_input_kernel = std::make_unique(_winograd_impl, *_conv_args, nthreads); + // Configure GEMM function _gemm_function->configure(&_winograd_transformed_input, &_winograd_transformed_weights, nullptr, &_winograd_transformed_output, 1.0f, 0.f); + // Configure output transform kernel + _transform_output_kernel = std::make_unique(_winograd_impl, *_conv_args, nthreads); + //Configure Activation Layer _run_activation = act_info.enabled() && !fuse_function_supported(act_info); if(_run_activation) @@ -331,8 +337,6 @@ void CpuWinogradConv2d::run(ITensorPack &tensors) CpuAuxTensorHandler output_nhwc(offset_int_vec(PermutedOutput), _output_nhwc, tensors, true); ITensorPack transform_input_pack{ { ACL_SRC, is_nchw ? input_nhwc.get() : src }, { ACL_DST, winograd_input_transformed.get() }, { ACL_INT, input_workspace.get() } }; - _transform_input_kernel = std::make_unique(_winograd_impl, *_conv_args, nthreads); - NEScheduler::get().schedule_op(_transform_input_kernel.get(), Window::DimX, win, transform_input_pack); CpuAuxTensorHandler winograd_weights_transformed(offset_int_vec(TransformedWeights), _winograd_transformed_weights, tensors, true); @@ -346,7 +350,6 @@ void CpuWinogradConv2d::run(ITensorPack &tensors) _gemm_function->run(gemm_pack); // Output transform - _transform_output_kernel = std::make_unique(_winograd_impl, *_conv_args, nthreads); ITensorPack transform_output_pack{ { ACL_SRC_0, winograd_output_transformed.get() }, { ACL_DST, is_nchw ? output_nhwc.get() : output }, { ACL_SRC_1, biases }, { ACL_INT, output_workspace.get() } }; NEScheduler::get().schedule_op(_transform_output_kernel.get(), Window::DimX, win, transform_output_pack); if(is_nchw) -- cgit v1.2.1