COMPMID-765: Add Winograd Convolution Hint for NEON Convolution
Change-Id: I6ca59689df2b196de4960a62216c37780a04684e
Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/118959
Reviewed-by: Pablo Tello <pablo.tello@arm.com>
Reviewed-by: Gian Marco Iodice <gianmarco.iodice@arm.com>
Tested-by: Jenkins <bsgcomp@arm.com>
diff --git a/arm_compute/graph/Types.h b/arm_compute/graph/Types.h
index a5d6ae8..db5bbb8 100644
--- a/arm_compute/graph/Types.h
+++ b/arm_compute/graph/Types.h
@@ -83,8 +83,9 @@
/** Convolution method hint to the graph executor */
enum class ConvolutionMethodHint
{
- GEMM, /**< Convolution using GEMM */
- DIRECT /**< Direct convolution */
+ GEMM, /**< Convolution using GEMM */
+ DIRECT, /**< Direct convolution */
+ WINOGRAD /**< Winograd convolution */
};
/** Supported layer operations */
diff --git a/src/graph/nodes/ConvolutionLayer.cpp b/src/graph/nodes/ConvolutionLayer.cpp
index f292b89..d8089d8 100644
--- a/src/graph/nodes/ConvolutionLayer.cpp
+++ b/src/graph/nodes/ConvolutionLayer.cpp
@@ -29,6 +29,7 @@
#include "arm_compute/runtime/IFunction.h"
#include "arm_compute/runtime/NEON/functions/NEConvolutionLayer.h"
#include "arm_compute/runtime/NEON/functions/NEDirectConvolutionLayer.h"
+#include "arm_compute/runtime/NEON/functions/NEWinogradLayer.h"
#include "support/ToolchainSupport.h"
#include "utils/GraphTypePrinter.h"
#include "utils/TypePrinter.h"
@@ -125,8 +126,22 @@
const WeightsInfo &weights_info,
ConvolutionMethodHint conv_method)
{
- if((conv_method == ConvolutionMethodHint::DIRECT)
- && arm_compute::NEDirectConvolutionLayer::validate(input->info(), weights->info(), biases != nullptr ? biases->info() : nullptr, output->info(), conv_info)) // NOLINT
+ const unsigned int kernel_size_x = weights->info()->tensor_shape().x();
+ const unsigned int kernel_size_y = weights->info()->tensor_shape().y();
+ const unsigned int conv_stride_x = conv_info.stride().first;
+ const unsigned int conv_stride_y = conv_info.stride().second;
+
+ bool is_square_kernel = (kernel_size_x == kernel_size_y);
+ bool has_same_stride = (conv_stride_x == conv_stride_y);
+
+ // TODO (COMPID-765) : Winograd should have a validate function
+ if(conv_method == ConvolutionMethodHint::WINOGRAD && is_square_kernel && ((kernel_size_x == 3) || (kernel_size_x == 5)) && has_same_stride && (conv_info.stride().first == 1))
+ {
+ ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEWinogradConvolutionLayer");
+ return instantiate_direct_function<arm_compute::NEWinogradLayer, arm_compute::ITensor, TargetHint::NEON>(input, weights, biases, output, conv_info);
+ }
+ else if((conv_method == ConvolutionMethodHint::DIRECT)
+ && arm_compute::NEDirectConvolutionLayer::validate(input->info(), weights->info(), biases != nullptr ? biases->info() : nullptr, output->info(), conv_info)) // NOLINT
{
ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEDirectConvolutionLayer");
return instantiate_direct_function<arm_compute::NEDirectConvolutionLayer, arm_compute::ITensor, TargetHint::NEON>(input, weights, biases, output, conv_info);