diff options
author | Nikhil Raj <nikhil.raj@arm.com> | 2019-07-05 12:22:58 +0100 |
---|---|---|
committer | Matteo Martincigh <matteo.martincigh@arm.com> | 2019-07-05 12:55:51 +0000 |
commit | 91e4c6d43921b735e6aee78d8611bc0372eda4df (patch) | |
tree | 0a1cf9d18ba23984c6a66a79cf8105834b00ef55 /src/backends/cl | |
parent | 328d92b84e6bd29906bf1fc496b1103af7f7e115 (diff) | |
download | armnn-91e4c6d43921b735e6aee78d8611bc0372eda4df.tar.gz |
IVGCVSW-3293 Add CL backend support for PReLU
Change-Id: I1bb187db89bb3eb883b8f0aca4c3439d82b56583
Signed-off-by: Nikhil Raj <nikhil.raj@arm.com>
Diffstat (limited to 'src/backends/cl')
-rw-r--r-- | src/backends/cl/ClLayerSupport.cpp | 9 | ||||
-rw-r--r-- | src/backends/cl/ClLayerSupport.hpp | 5 | ||||
-rw-r--r-- | src/backends/cl/ClWorkloadFactory.cpp | 6 | ||||
-rw-r--r-- | src/backends/cl/ClWorkloadFactory.hpp | 3 | ||||
-rw-r--r-- | src/backends/cl/backend.mk | 1 | ||||
-rw-r--r-- | src/backends/cl/test/ClCreateWorkloadTests.cpp | 42 | ||||
-rw-r--r-- | src/backends/cl/test/ClLayerTests.cpp | 4 | ||||
-rw-r--r-- | src/backends/cl/workloads/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/backends/cl/workloads/ClPreluWorkload.cpp | 48 | ||||
-rw-r--r-- | src/backends/cl/workloads/ClPreluWorkload.hpp | 28 | ||||
-rw-r--r-- | src/backends/cl/workloads/ClWorkloads.hpp | 1 |
11 files changed, 149 insertions, 0 deletions
diff --git a/src/backends/cl/ClLayerSupport.cpp b/src/backends/cl/ClLayerSupport.cpp index d79f6126a7..a6baa3c38f 100644 --- a/src/backends/cl/ClLayerSupport.cpp +++ b/src/backends/cl/ClLayerSupport.cpp @@ -39,6 +39,7 @@ #include "workloads/ClPadWorkload.hpp" #include "workloads/ClPermuteWorkload.hpp" #include "workloads/ClPooling2dWorkload.hpp" +#include "workloads/ClPreluWorkload.hpp" #include "workloads/ClQuantizeWorkload.hpp" #include "workloads/ClSoftmaxBaseWorkload.hpp" #include "workloads/ClSpaceToBatchNdWorkload.hpp" @@ -571,6 +572,14 @@ bool ClLayerSupport::IsPooling2dSupported(const TensorInfo& input, FORWARD_WORKLOAD_VALIDATE_FUNC(ClPooling2dWorkloadValidate, reasonIfUnsupported, input, output, descriptor); } +bool ClLayerSupport::IsPreluSupported(const armnn::TensorInfo &input, + const armnn::TensorInfo &alpha, + const armnn::TensorInfo &output, + armnn::Optional<std::string &> reasonIfUnsupported) const +{ + FORWARD_WORKLOAD_VALIDATE_FUNC(ClPreluWorkloadValidate, reasonIfUnsupported, input, alpha, output); +} + bool ClLayerSupport::IsQuantizeSupported(const TensorInfo& input, const TensorInfo& output, Optional<std::string&> reasonIfUnsupported) const diff --git a/src/backends/cl/ClLayerSupport.hpp b/src/backends/cl/ClLayerSupport.hpp index 1461f41691..f77889bef6 100644 --- a/src/backends/cl/ClLayerSupport.hpp +++ b/src/backends/cl/ClLayerSupport.hpp @@ -190,6 +190,11 @@ public: const Pooling2dDescriptor& descriptor, Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; + bool IsPreluSupported(const TensorInfo& input, + const TensorInfo& alpha, + const TensorInfo& output, + Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; + bool IsQuantizeSupported(const TensorInfo& input, const TensorInfo& output, Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; diff --git a/src/backends/cl/ClWorkloadFactory.cpp b/src/backends/cl/ClWorkloadFactory.cpp index c662a9db29..307f954bae 100644 --- a/src/backends/cl/ClWorkloadFactory.cpp +++ b/src/backends/cl/ClWorkloadFactory.cpp @@ -180,6 +180,12 @@ std::unique_ptr<armnn::IWorkload> ClWorkloadFactory::CreatePooling2d(const Pooli return MakeWorkload<ClPooling2dWorkload>(descriptor, info); } +std::unique_ptr<armnn::IWorkload> ClWorkloadFactory::CreatePrelu(const armnn::PreluQueueDescriptor &descriptor, + const armnn::WorkloadInfo &info) const +{ + return MakeWorkload<ClPreluWorkload>(descriptor, info); +} + std::unique_ptr<armnn::IWorkload> ClWorkloadFactory::CreateConvolution2d(const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const { diff --git a/src/backends/cl/ClWorkloadFactory.hpp b/src/backends/cl/ClWorkloadFactory.hpp index 32925f7f95..5448504737 100644 --- a/src/backends/cl/ClWorkloadFactory.hpp +++ b/src/backends/cl/ClWorkloadFactory.hpp @@ -64,6 +64,9 @@ public: std::unique_ptr<IWorkload> CreatePooling2d(const Pooling2dQueueDescriptor& descriptor, const WorkloadInfo& info) const override; + std::unique_ptr<IWorkload> CreatePrelu(const PreluQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + std::unique_ptr<IWorkload> CreateConvolution2d(const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const override; diff --git a/src/backends/cl/backend.mk b/src/backends/cl/backend.mk index 137cf7654b..87964cdc7a 100644 --- a/src/backends/cl/backend.mk +++ b/src/backends/cl/backend.mk @@ -45,6 +45,7 @@ BACKEND_SOURCES := \ workloads/ClPadWorkload.cpp \ workloads/ClPermuteWorkload.cpp \ workloads/ClPooling2dWorkload.cpp \ + workloads/ClPreluWorkload.cpp \ workloads/ClQuantizeWorkload.cpp \ workloads/ClReshapeWorkload.cpp \ workloads/ClResizeBilinearFloatWorkload.cpp \ diff --git a/src/backends/cl/test/ClCreateWorkloadTests.cpp b/src/backends/cl/test/ClCreateWorkloadTests.cpp index aa1393f407..9e4f85b46c 100644 --- a/src/backends/cl/test/ClCreateWorkloadTests.cpp +++ b/src/backends/cl/test/ClCreateWorkloadTests.cpp @@ -452,6 +452,48 @@ BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16NhwcWorkload) ClPooling2dWorkloadTest<armnn::DataType::Float16>(DataLayout::NHWC); } +static void ClCreatePreluWorkloadTest(const armnn::TensorShape& inputShape, + const armnn::TensorShape& alphaShape, + const armnn::TensorShape& outputShape, + armnn::DataType dataType) +{ + Graph graph; + ClWorkloadFactory factory = + ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager()); + + auto workload = CreatePreluWorkloadTest<ClPreluWorkload>(factory, + graph, + inputShape, + alphaShape, + outputShape, + dataType); + + // Checks that outputs and inputs are as we expect them (see definition of CreatePreluWorkloadTest). + PreluQueueDescriptor queueDescriptor = workload->GetData(); + auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]); + auto alphaHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[1]); + auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]); + + BOOST_TEST((inputHandle->GetShape() == inputShape)); + BOOST_TEST((alphaHandle->GetShape() == alphaShape)); + BOOST_TEST((outputHandle->GetShape() == outputShape)); +} + +BOOST_AUTO_TEST_CASE(CreatePreluFloat16Workload) +{ + ClCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float16); +} + +BOOST_AUTO_TEST_CASE(CreatePreluFloatWorkload) +{ + ClCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float32); +} + +BOOST_AUTO_TEST_CASE(CreatePreluUint8Workload) +{ + ClCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::QuantisedAsymm8); +} + template <typename armnn::DataType DataType> static void ClCreateReshapeWorkloadTest() { diff --git a/src/backends/cl/test/ClLayerTests.cpp b/src/backends/cl/test/ClLayerTests.cpp index 3618adc70d..9ac244e505 100644 --- a/src/backends/cl/test/ClLayerTests.cpp +++ b/src/backends/cl/test/ClLayerTests.cpp @@ -331,6 +331,10 @@ ARMNN_AUTO_TEST_CASE(PadFloat322d, PadFloat322dTest) ARMNN_AUTO_TEST_CASE(PadFloat323d, PadFloat323dTest) ARMNN_AUTO_TEST_CASE(PadFloat324d, PadFloat324dTest) +// PReLU +ARMNN_AUTO_TEST_CASE(PreluFloat32, PreluTest<armnn::DataType::Float32>) +ARMNN_AUTO_TEST_CASE(PreluUint8, PreluTest<armnn::DataType::QuantisedAsymm8>) + // Permute ARMNN_AUTO_TEST_CASE(SimplePermuteFloat32, SimplePermuteFloat32Test) ARMNN_AUTO_TEST_CASE(SimplePermuteUint8, SimplePermuteUint8Test) diff --git a/src/backends/cl/workloads/CMakeLists.txt b/src/backends/cl/workloads/CMakeLists.txt index 1b4c85b947..40c5f766e4 100644 --- a/src/backends/cl/workloads/CMakeLists.txt +++ b/src/backends/cl/workloads/CMakeLists.txt @@ -54,6 +54,8 @@ list(APPEND armnnClBackendWorkloads_sources ClPermuteWorkload.hpp ClPooling2dWorkload.cpp ClPooling2dWorkload.hpp + ClPreluWorkload.cpp + ClPreluWorkload.hpp ClQuantizeWorkload.cpp ClQuantizeWorkload.hpp ClReshapeWorkload.cpp diff --git a/src/backends/cl/workloads/ClPreluWorkload.cpp b/src/backends/cl/workloads/ClPreluWorkload.cpp new file mode 100644 index 0000000000..1813105c21 --- /dev/null +++ b/src/backends/cl/workloads/ClPreluWorkload.cpp @@ -0,0 +1,48 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "ClPreluWorkload.hpp" +#include "ClWorkloadUtils.hpp" +#include <backendsCommon/CpuTensorHandle.hpp> +#include <aclCommon/ArmComputeUtils.hpp> +#include <cl/ClLayerSupport.hpp> +#include <cl/ClTensorHandle.hpp> + +namespace armnn +{ + +arm_compute::Status ClPreluWorkloadValidate(const TensorInfo& input, + const TensorInfo& alpha, + const TensorInfo& output) +{ + const arm_compute::TensorInfo aclInput = armcomputetensorutils::BuildArmComputeTensorInfo(input); + const arm_compute::TensorInfo aclAlpha = armcomputetensorutils::BuildArmComputeTensorInfo(alpha); + const arm_compute::TensorInfo aclOutput = armcomputetensorutils::BuildArmComputeTensorInfo(output); + + return arm_compute::CLPReluLayer::validate(&aclInput, + &aclAlpha, + &aclOutput); +} + +ClPreluWorkload::ClPreluWorkload(const PreluQueueDescriptor& descriptor, + const WorkloadInfo& info) + : BaseWorkload<PreluQueueDescriptor>(descriptor, info) +{ + m_Data.ValidateInputsOutputs("ClPreluWorkload", 1, 1); + + arm_compute::ICLTensor& input = static_cast<IClTensorHandle*>(m_Data.m_Inputs[0])->GetTensor(); + arm_compute::ICLTensor& alpha = static_cast<IClTensorHandle*>(m_Data.m_Inputs[1])->GetTensor(); + arm_compute::ICLTensor& output = static_cast<IClTensorHandle*>(m_Data.m_Outputs[0])->GetTensor(); + + m_PreluLayer.configure(&input, &alpha, &output); +} + +void ClPreluWorkload::Execute() const +{ + ARMNN_SCOPED_PROFILING_EVENT_CL("ClPreluWorkload_Execute"); + RunClFunction(m_PreluLayer, CHECK_LOCATION()); +} + +} //namespace armnn diff --git a/src/backends/cl/workloads/ClPreluWorkload.hpp b/src/backends/cl/workloads/ClPreluWorkload.hpp new file mode 100644 index 0000000000..6ffe4ca7c0 --- /dev/null +++ b/src/backends/cl/workloads/ClPreluWorkload.hpp @@ -0,0 +1,28 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include <backendsCommon/Workload.hpp> + +#include <arm_compute/runtime/CL/CLFunctions.h> + +namespace armnn +{ +arm_compute::Status ClPreluWorkloadValidate(const TensorInfo& input, + const TensorInfo& alpha, + const TensorInfo& output); + +class ClPreluWorkload : public BaseWorkload<PreluQueueDescriptor> +{ +public: + ClPreluWorkload(const PreluQueueDescriptor& descriptor, const WorkloadInfo& info); + void Execute() const override; + +private: + mutable arm_compute::CLPReluLayer m_PreluLayer; +}; + +} //namespace armnn diff --git a/src/backends/cl/workloads/ClWorkloads.hpp b/src/backends/cl/workloads/ClWorkloads.hpp index e82afc54c3..6ba8138780 100644 --- a/src/backends/cl/workloads/ClWorkloads.hpp +++ b/src/backends/cl/workloads/ClWorkloads.hpp @@ -27,6 +27,7 @@ #include "ClPermuteWorkload.hpp" #include "ClPadWorkload.hpp" #include "ClPooling2dWorkload.hpp" +#include "ClPreluWorkload.hpp" #include "ClQuantizeWorkload.hpp" #include "ClReshapeWorkload.hpp" #include "ClResizeBilinearFloatWorkload.hpp" |