aboutsummaryrefslogtreecommitdiff
path: root/src/backends/cl
diff options
context:
space:
mode:
Diffstat (limited to 'src/backends/cl')
-rw-r--r--src/backends/cl/ClLayerSupport.cpp45
-rw-r--r--src/backends/cl/ClWorkloadFactory.cpp42
-rw-r--r--src/backends/cl/backend.mk1
-rw-r--r--src/backends/cl/test/ClLayerTests.cpp8
-rw-r--r--src/backends/cl/workloads/CMakeLists.txt2
-rw-r--r--src/backends/cl/workloads/ClExpWorkload.cpp45
-rw-r--r--src/backends/cl/workloads/ClExpWorkload.hpp28
-rw-r--r--src/backends/cl/workloads/ClWorkloads.hpp1
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"