aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGian Marco Iodice <gianmarco.iodice@arm.com>2018-03-21 17:45:31 +0000
committerAnthony Barbier <anthony.barbier@arm.com>2018-11-02 16:49:16 +0000
commited99f411d52949720a4d64d91664cd71e46b79d5 (patch)
treed903b523dea830aeb48d59a66b8da59e4dcf707a
parent6528aa20e768f2d801328aa164d672b7fdfe266f (diff)
downloadComputeLibrary-ed99f411d52949720a4d64d91664cd71e46b79d5.tar.gz
COMPMID-1018 - Add Winograd support in VGG16 and Alexnet examples
Change-Id: I4a2deee9e4b2c54ea79d2895cfeca44190133b24 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/125453 Reviewed-by: Pablo Tello <pablo.tello@arm.com> Tested-by: Jenkins <bsgcomp@arm.com>
-rw-r--r--examples/graph_alexnet.cpp8
-rw-r--r--examples/graph_vgg16.cpp9
-rw-r--r--src/graph/nodes/ConvolutionLayer.cpp22
-rw-r--r--src/graph2/backends/CL/CLFunctionsFactory.cpp8
4 files changed, 31 insertions, 16 deletions
diff --git a/examples/graph_alexnet.cpp b/examples/graph_alexnet.cpp
index a396c7686c..f887f97a12 100644
--- a/examples/graph_alexnet.cpp
+++ b/examples/graph_alexnet.cpp
@@ -57,8 +57,10 @@ public:
const int int_target_hint = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0;
TargetHint target_hint = set_target_hint(int_target_hint);
- const bool is_gemm_convolution5x5 = Graph::gpu_target() == arm_compute::GPUTarget::MIDGARD || target_hint == TargetHint::NEON;
- ConvolutionMethodHint convolution_5x5_hint = is_gemm_convolution5x5 ? ConvolutionMethodHint::GEMM : ConvolutionMethodHint::DIRECT;
+ const bool is_gemm_convolution5x5 = Graph::gpu_target() == arm_compute::GPUTarget::MIDGARD || target_hint == TargetHint::NEON;
+ const bool is_winograd_convolution3x3 = target_hint == TargetHint::OPENCL;
+ ConvolutionMethodHint convolution_5x5_hint = is_gemm_convolution5x5 ? ConvolutionMethodHint::GEMM : ConvolutionMethodHint::DIRECT;
+ ConvolutionMethodHint convolution_3x3_hint = is_winograd_convolution3x3 ? ConvolutionMethodHint::WINOGRAD : ConvolutionMethodHint::GEMM;
// Parse arguments
if(argc < 2)
@@ -114,7 +116,7 @@ public:
<< ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
<< NormalizationLayer(NormalizationLayerInfo(NormType::CROSS_MAP, 5, 0.0001f, 0.75f))
<< PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0)))
- << ConvolutionMethodHint::GEMM
+ << convolution_3x3_hint
// Layer 3
<< ConvolutionLayer(
3U, 3U, 384U,
diff --git a/examples/graph_vgg16.cpp b/examples/graph_vgg16.cpp
index faaf579047..516b7b18f0 100644
--- a/examples/graph_vgg16.cpp
+++ b/examples/graph_vgg16.cpp
@@ -71,8 +71,10 @@ public:
bool enable_memory_management = true;
// Check if we can use GEMM-based convolutions evaluating if the platform has at least 1.8 GB of available memory
- const size_t memory_required = 1932735283L;
- ConvolutionMethod convolution_hint = convolution_hint_vgg16(memory_required);
+ const size_t memory_required = 1932735283L;
+ const bool is_opencl = target_hint == Target::CL;
+ ConvolutionMethod first_convolution3x3_hint = is_opencl ? ConvolutionMethod::DIRECT : ConvolutionMethod::GEMM;
+ ConvolutionMethod convolution3x3_hint = is_opencl ? ConvolutionMethod::WINOGRAD : convolution_hint_vgg16(memory_required);
// Parse arguments
if(argc < 2)
@@ -107,7 +109,7 @@ public:
}
graph << target_hint
- << convolution_hint
+ << first_convolution3x3_hint
<< InputLayer(TensorDescriptor(TensorShape(224U, 224U, 3U, 1U), DataType::F32),
get_input_accessor(image, std::move(preprocessor)))
// Layer 1
@@ -117,6 +119,7 @@ public:
get_weights_accessor(data_path, "/cnn_data/vgg16_model/conv1_1_b.npy"),
PadStrideInfo(1, 1, 1, 1))
<< ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ << convolution3x3_hint
// Layer 2
<< ConvolutionLayer(
3U, 3U, 64U,
diff --git a/src/graph/nodes/ConvolutionLayer.cpp b/src/graph/nodes/ConvolutionLayer.cpp
index d8089d804d..5b3a84a4ad 100644
--- a/src/graph/nodes/ConvolutionLayer.cpp
+++ b/src/graph/nodes/ConvolutionLayer.cpp
@@ -26,6 +26,7 @@
#include "arm_compute/graph/Error.h"
#include "arm_compute/runtime/CL/functions/CLConvolutionLayer.h"
#include "arm_compute/runtime/CL/functions/CLDirectConvolutionLayer.h"
+#include "arm_compute/runtime/CL/functions/CLWinogradConvolutionLayer.h"
#include "arm_compute/runtime/IFunction.h"
#include "arm_compute/runtime/NEON/functions/NEConvolutionLayer.h"
#include "arm_compute/runtime/NEON/functions/NEDirectConvolutionLayer.h"
@@ -107,8 +108,14 @@ std::unique_ptr<arm_compute::IFunction> instantiate<TargetHint::OPENCL>(arm_comp
const WeightsInfo &weights_info,
ConvolutionMethodHint conv_method)
{
- if((conv_method == ConvolutionMethodHint::DIRECT)
- && arm_compute::CLDirectConvolutionLayer::validate(input->info(), weights->info(), biases != nullptr ? biases->info() : nullptr, output->info(), conv_info)) // NOLINT
+ if((conv_method == ConvolutionMethodHint::WINOGRAD)
+ && arm_compute::CLWinogradConvolutionLayer::validate(input->info(), weights->info(), biases != nullptr ? biases->info() : nullptr, output->info(), conv_info)) // NOLINT
+ {
+ ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLWinogradConvolutionLayer");
+ return instantiate_direct_function<arm_compute::CLWinogradConvolutionLayer, arm_compute::ICLTensor, TargetHint::OPENCL>(input, weights, biases, output, conv_info);
+ }
+ else if((conv_method == ConvolutionMethodHint::DIRECT)
+ && arm_compute::CLDirectConvolutionLayer::validate(input->info(), weights->info(), biases != nullptr ? biases->info() : nullptr, output->info(), conv_info)) // NOLINT
{
ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLDirectConvolutionLayer");
return instantiate_direct_function<arm_compute::CLDirectConvolutionLayer, arm_compute::ICLTensor, TargetHint::OPENCL>(input, weights, biases, output, conv_info);
@@ -159,10 +166,7 @@ class GroupedConvolutionFunction final : public arm_compute::IFunction
{
public:
/** Default Constructor */
- GroupedConvolutionFunction()
- : _convolutions()
- {
- }
+ GroupedConvolutionFunction() = default;
/** Default Destructor */
~GroupedConvolutionFunction() final = default;
/** Prevent instances from being copy constructed */
@@ -177,12 +181,12 @@ public:
*
* @param convolution Convolution function to add
*/
- void add_convolution_function(std::unique_ptr<IFunction> convolution)
+ void add_convolution_function(std::unique_ptr<IFunction> convolution) // NOLINT
{
_convolutions.emplace_back(std::move(convolution));
}
- // Inherited methods overriden:
+ // Inherited methods overridden:
void run() override
{
for(auto &c : _convolutions)
@@ -192,7 +196,7 @@ public:
}
private:
- std::vector<std::unique_ptr<IFunction>> _convolutions;
+ std::vector<std::unique_ptr<IFunction>> _convolutions{};
};
std::unique_ptr<arm_compute::IFunction> ConvolutionLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output)
diff --git a/src/graph2/backends/CL/CLFunctionsFactory.cpp b/src/graph2/backends/CL/CLFunctionsFactory.cpp
index bba0cce025..5a51b19e18 100644
--- a/src/graph2/backends/CL/CLFunctionsFactory.cpp
+++ b/src/graph2/backends/CL/CLFunctionsFactory.cpp
@@ -165,7 +165,13 @@ std::unique_ptr<IFunction> create_convolution_layer(ConvolutionLayerNode &node,
std::shared_ptr<IMemoryManager> mm = get_memory_manager(ctx, Target::CL);
std::unique_ptr<IFunction> func;
std::string func_name;
- if(conv_algorithm == ConvolutionMethod::DIRECT)
+
+ if(conv_algorithm == ConvolutionMethod::WINOGRAD)
+ {
+ std::tie(func, func_name) = create_named_function<CLWinogradConvolutionLayer>(
+ std::string("CLWinogradConvolutionLayer"), input, weights, biases, output, conv_info);
+ }
+ else if(conv_algorithm == ConvolutionMethod::DIRECT)
{
std::tie(func, func_name) = create_named_function<CLDirectConvolutionLayer>(
std::string("CLDirectConvolutionLayer"), input, weights, biases, output, conv_info);