diff options
Diffstat (limited to 'src/backends/cl')
-rw-r--r-- | src/backends/cl/ClLayerSupport.cpp | 45 | ||||
-rw-r--r-- | src/backends/cl/ClWorkloadFactory.cpp | 42 | ||||
-rw-r--r-- | src/backends/cl/backend.mk | 1 | ||||
-rw-r--r-- | src/backends/cl/test/ClLayerTests.cpp | 8 | ||||
-rw-r--r-- | src/backends/cl/workloads/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/backends/cl/workloads/ClExpWorkload.cpp | 45 | ||||
-rw-r--r-- | src/backends/cl/workloads/ClExpWorkload.hpp | 28 | ||||
-rw-r--r-- | src/backends/cl/workloads/ClWorkloads.hpp | 1 |
8 files changed, 132 insertions, 40 deletions
diff --git a/src/backends/cl/ClLayerSupport.cpp b/src/backends/cl/ClLayerSupport.cpp index 7418dbd9e4..c8d3816a4c 100644 --- a/src/backends/cl/ClLayerSupport.cpp +++ b/src/backends/cl/ClLayerSupport.cpp @@ -31,6 +31,7 @@ #include "workloads/ClDepthwiseConvolutionWorkload.hpp" #include "workloads/ClDequantizeWorkload.hpp" #include "workloads/ClDivisionFloatWorkload.hpp" +#include "workloads/ClExpWorkload.hpp" #include "workloads/ClFloorFloatWorkload.hpp" #include "workloads/ClFullyConnectedWorkload.hpp" #include "workloads/ClInstanceNormalizationWorkload.hpp" @@ -399,29 +400,31 @@ bool ClLayerSupport::IsElementwiseUnarySupported(const TensorInfo& input, const ElementwiseUnaryDescriptor& descriptor, Optional<std::string&> reasonIfUnsupported) const { - if (descriptor.m_Operation == UnaryOperation::Abs) + switch(descriptor.m_Operation) { - FORWARD_WORKLOAD_VALIDATE_FUNC(ClAbsWorkloadValidate, - reasonIfUnsupported, - input, - output); - } - else if (descriptor.m_Operation == UnaryOperation::Rsqrt) - { - FORWARD_WORKLOAD_VALIDATE_FUNC(ClRsqrtWorkloadValidate, - reasonIfUnsupported, - input, - output); - } - else if (descriptor.m_Operation == UnaryOperation::Neg) - { - FORWARD_WORKLOAD_VALIDATE_FUNC(ClNegWorkloadValidate, - reasonIfUnsupported, - input, - output); + case UnaryOperation::Abs: + FORWARD_WORKLOAD_VALIDATE_FUNC(ClAbsWorkloadValidate, + reasonIfUnsupported, + input, + output); + case UnaryOperation::Exp: + FORWARD_WORKLOAD_VALIDATE_FUNC(ClExpWorkloadValidate, + reasonIfUnsupported, + input, + output); + case UnaryOperation::Neg: + FORWARD_WORKLOAD_VALIDATE_FUNC(ClNegWorkloadValidate, + reasonIfUnsupported, + input, + output); + case UnaryOperation::Rsqrt: + FORWARD_WORKLOAD_VALIDATE_FUNC(ClRsqrtWorkloadValidate, + reasonIfUnsupported, + input, + output); + default: + return false; } - - return false; } bool ClLayerSupport::IsFloorSupported(const TensorInfo& input, diff --git a/src/backends/cl/ClWorkloadFactory.cpp b/src/backends/cl/ClWorkloadFactory.cpp index 50a867ca2c..cabc3466aa 100644 --- a/src/backends/cl/ClWorkloadFactory.cpp +++ b/src/backends/cl/ClWorkloadFactory.cpp @@ -249,27 +249,31 @@ std::unique_ptr<IWorkload> ClWorkloadFactory::CreateDivision(const DivisionQueue std::unique_ptr<IWorkload> ClWorkloadFactory::CreateElementwiseUnary(const ElementwiseUnaryQueueDescriptor& descriptor, const WorkloadInfo& info) const { - if (descriptor.m_Parameters.m_Operation == UnaryOperation::Abs) + switch(descriptor.m_Parameters.m_Operation) { - AbsQueueDescriptor absQueueDescriptor; - absQueueDescriptor.m_Inputs = descriptor.m_Inputs; - absQueueDescriptor.m_Outputs = descriptor.m_Outputs; - - return MakeWorkload<ClAbsWorkload>(absQueueDescriptor, info); - } - else if (descriptor.m_Parameters.m_Operation == UnaryOperation::Rsqrt) - { - RsqrtQueueDescriptor rsqrtQueueDescriptor; - rsqrtQueueDescriptor.m_Inputs = descriptor.m_Inputs; - rsqrtQueueDescriptor.m_Outputs = descriptor.m_Outputs; - - return MakeWorkload<ClRsqrtWorkload>(rsqrtQueueDescriptor, info); + case UnaryOperation::Abs: + { + AbsQueueDescriptor absQueueDescriptor; + absQueueDescriptor.m_Inputs = descriptor.m_Inputs; + absQueueDescriptor.m_Outputs = descriptor.m_Outputs; + + return std::make_unique<ClAbsWorkload>(absQueueDescriptor, info); + } + case UnaryOperation::Exp: + return std::make_unique<ClExpWorkload>(descriptor, info); + case UnaryOperation::Neg: + return std::make_unique<ClNegWorkload>(descriptor, info); + case UnaryOperation::Rsqrt: + { + RsqrtQueueDescriptor rsqrtQueueDescriptor; + rsqrtQueueDescriptor.m_Inputs = descriptor.m_Inputs; + rsqrtQueueDescriptor.m_Outputs = descriptor.m_Outputs; + + return std::make_unique<ClRsqrtWorkload>(rsqrtQueueDescriptor, info); + } + default: + return nullptr; } - else if (descriptor.m_Parameters.m_Operation == UnaryOperation::Neg) - { - return MakeWorkload<ClNegWorkload>(descriptor, info); - } - return MakeWorkload<NullWorkload, NullWorkload>(descriptor, info); } std::unique_ptr<IWorkload> ClWorkloadFactory::CreateEqual(const EqualQueueDescriptor& descriptor, diff --git a/src/backends/cl/backend.mk b/src/backends/cl/backend.mk index f18f8f03a2..740aee6d67 100644 --- a/src/backends/cl/backend.mk +++ b/src/backends/cl/backend.mk @@ -38,6 +38,7 @@ BACKEND_SOURCES := \ workloads/ClDepthwiseConvolutionWorkload.cpp \ workloads/ClDequantizeWorkload.cpp \ workloads/ClDivisionFloatWorkload.cpp \ + workloads/ClExpWorkload.cpp \ workloads/ClFloorFloatWorkload.cpp \ workloads/ClFullyConnectedWorkload.cpp \ workloads/ClInstanceNormalizationWorkload.cpp \ diff --git a/src/backends/cl/test/ClLayerTests.cpp b/src/backends/cl/test/ClLayerTests.cpp index 1c433a85c5..e6492f612a 100644 --- a/src/backends/cl/test/ClLayerTests.cpp +++ b/src/backends/cl/test/ClLayerTests.cpp @@ -1119,6 +1119,14 @@ ARMNN_AUTO_TEST_CASE(NegNegative, NegNegativeTest<DataType::Float32>) ARMNN_AUTO_TEST_CASE(Neg2dFloat16, Neg2dTest<DataType::Float16>) ARMNN_AUTO_TEST_CASE(Neg3dFloat16, Neg3dTest<DataType::Float16>) +// Exp +ARMNN_AUTO_TEST_CASE(Exp2d, Exp2dTest<DataType::Float32>) +ARMNN_AUTO_TEST_CASE(Exo3d, Exp3dTest<DataType::Float32>) +ARMNN_AUTO_TEST_CASE(ExpZero, ExpZeroTest<DataType::Float32>) +ARMNN_AUTO_TEST_CASE(ExpNegative, ExpNegativeTest<DataType::Float32>) +ARMNN_AUTO_TEST_CASE(Exp2dFloat16, Exp2dTest<DataType::Float16>) +ARMNN_AUTO_TEST_CASE(Exp3dFloat16, Exp3dTest<DataType::Float16>) + #if defined(ARMNNREF_ENABLED) // The ARMNN_COMPARE_REF_AUTO_TEST_CASE and the ARMNN_COMPARE_REF_FIXTURE_TEST_CASE test units are not available diff --git a/src/backends/cl/workloads/CMakeLists.txt b/src/backends/cl/workloads/CMakeLists.txt index 6d0aa792a1..7d9df07ed9 100644 --- a/src/backends/cl/workloads/CMakeLists.txt +++ b/src/backends/cl/workloads/CMakeLists.txt @@ -36,6 +36,8 @@ list(APPEND armnnClBackendWorkloads_sources ClDequantizeWorkload.hpp ClDivisionFloatWorkload.cpp ClDivisionFloatWorkload.hpp + ClExpWorkload.cpp + ClExpWorkload.hpp ClFloorFloatWorkload.cpp ClFloorFloatWorkload.hpp ClFullyConnectedWorkload.cpp diff --git a/src/backends/cl/workloads/ClExpWorkload.cpp b/src/backends/cl/workloads/ClExpWorkload.cpp new file mode 100644 index 0000000000..5b5e0a5f0c --- /dev/null +++ b/src/backends/cl/workloads/ClExpWorkload.cpp @@ -0,0 +1,45 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "ClExpWorkload.hpp" + +#include "ClWorkloadUtils.hpp" + +#include <aclCommon/ArmComputeTensorUtils.hpp> +#include <armnn/utility/PolymorphicDowncast.hpp> + +#include <cl/ClTensorHandle.hpp> + +#include <boost/cast.hpp> + +namespace armnn +{ + +arm_compute::Status ClExpWorkloadValidate(const TensorInfo& input, const TensorInfo& output) +{ + const arm_compute::TensorInfo aclInput = armcomputetensorutils::BuildArmComputeTensorInfo(input); + const arm_compute::TensorInfo aclOutput = armcomputetensorutils::BuildArmComputeTensorInfo(output); + + return arm_compute::CLExpLayer::validate(&aclInput, &aclOutput); +} + +ClExpWorkload::ClExpWorkload(const ElementwiseUnaryQueueDescriptor& descriptor, const WorkloadInfo& info) + : BaseWorkload<ElementwiseUnaryQueueDescriptor>(descriptor, info) +{ + m_Data.ValidateInputsOutputs("ClExpWorkload", 1, 1); + + arm_compute::ICLTensor& input = PolymorphicDowncast<ClTensorHandle*>(m_Data.m_Inputs[0])->GetTensor(); + arm_compute::ICLTensor& output = PolymorphicDowncast<ClTensorHandle*>(m_Data.m_Outputs[0])->GetTensor(); + + m_ExpLayer.configure(&input, &output); +} + +void ClExpWorkload::Execute() const +{ + ARMNN_SCOPED_PROFILING_EVENT_CL("ClExpWorkload_Execute"); + RunClFunction(m_ExpLayer, CHECK_LOCATION()); +} + +} // namespace armnn diff --git a/src/backends/cl/workloads/ClExpWorkload.hpp b/src/backends/cl/workloads/ClExpWorkload.hpp new file mode 100644 index 0000000000..c35aebbeb9 --- /dev/null +++ b/src/backends/cl/workloads/ClExpWorkload.hpp @@ -0,0 +1,28 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include <backendsCommon/Workload.hpp> + +#include <arm_compute/core/Error.h> +#include <arm_compute/runtime/CL/functions/CLElementWiseUnaryLayer.h> + +namespace armnn +{ + +arm_compute::Status ClExpWorkloadValidate(const TensorInfo& input, const TensorInfo& output); + +class ClExpWorkload : public BaseWorkload<ElementwiseUnaryQueueDescriptor> +{ +public: + ClExpWorkload(const ElementwiseUnaryQueueDescriptor& descriptor, const WorkloadInfo& info); + virtual void Execute() const override; + +private: + mutable arm_compute::CLExpLayer m_ExpLayer; +}; + +} // namespace armnn diff --git a/src/backends/cl/workloads/ClWorkloads.hpp b/src/backends/cl/workloads/ClWorkloads.hpp index 7b3ce439be..1ae9a91b88 100644 --- a/src/backends/cl/workloads/ClWorkloads.hpp +++ b/src/backends/cl/workloads/ClWorkloads.hpp @@ -17,6 +17,7 @@ #include "ClDepthwiseConvolutionWorkload.hpp" #include "ClDequantizeWorkload.hpp" #include "ClDivisionFloatWorkload.hpp" +#include "ClExpWorkload.hpp" #include "ClFloorFloatWorkload.hpp" #include "ClFullyConnectedWorkload.hpp" #include "ClInstanceNormalizationWorkload.hpp" |