aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Conroy <james.conroy@arm.com>2019-09-19 17:00:31 +0100
committerJames Conroy <james.conroy@arm.com>2019-11-13 12:17:48 +0000
commit2dc0572f4d9f28b2e0c38b8ff183b3f7bd9900da (patch)
tree206e34307dd62cfdfe8d1677f3e238658119b1e0
parent663c1849b2c359e6d898a763fff2ef013b55a459 (diff)
downloadarmnn-2dc0572f4d9f28b2e0c38b8ff183b3f7bd9900da.tar.gz
IVGCVSW-3695 Add CL ArgMinMax workload
* Also enabled copy to/from CL for Signed32. Signed-off-by: James Conroy <james.conroy@arm.com> Change-Id: I0113182891f9767de73f04dcd81252c84c996eda
-rw-r--r--src/backends/cl/ClLayerSupport.cpp13
-rw-r--r--src/backends/cl/ClLayerSupport.hpp5
-rw-r--r--src/backends/cl/ClTensorHandle.hpp16
-rw-r--r--src/backends/cl/ClWorkloadFactory.cpp6
-rw-r--r--src/backends/cl/ClWorkloadFactory.hpp3
-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/ClArgMinMaxWorkload.cpp82
-rw-r--r--src/backends/cl/workloads/ClArgMinMaxWorkload.hpp30
-rw-r--r--src/backends/cl/workloads/ClWorkloads.hpp1
-rw-r--r--src/backends/neon/test/NeonLayerTests.cpp2
12 files changed, 169 insertions, 0 deletions
diff --git a/src/backends/cl/ClLayerSupport.cpp b/src/backends/cl/ClLayerSupport.cpp
index 6dcda96100..ed570bc448 100644
--- a/src/backends/cl/ClLayerSupport.cpp
+++ b/src/backends/cl/ClLayerSupport.cpp
@@ -19,6 +19,7 @@
#include "workloads/ClAbsWorkload.hpp"
#include "workloads/ClAdditionWorkload.hpp"
#include "workloads/ClActivationWorkload.hpp"
+#include "workloads/ClArgMinMaxWorkload.hpp"
#include "workloads/ClBatchNormalizationFloatWorkload.hpp"
#include "workloads/ClBatchToSpaceNdWorkload.hpp"
#include "workloads/ClConvertFp16ToFp32Workload.hpp"
@@ -178,6 +179,18 @@ bool ClLayerSupport::IsAdditionSupported(const TensorInfo& input0,
output);
}
+bool ClLayerSupport::IsArgMinMaxSupported(const TensorInfo& input,
+ const TensorInfo& output,
+ const ArgMinMaxDescriptor& descriptor,
+ Optional<std::string&> reasonIfUnsupported) const
+{
+ FORWARD_WORKLOAD_VALIDATE_FUNC(ClArgMinMaxWorkloadValidate,
+ reasonIfUnsupported,
+ input,
+ output,
+ descriptor);
+}
+
bool ClLayerSupport::IsBatchNormalizationSupported(const TensorInfo& input,
const TensorInfo& output,
const TensorInfo& mean,
diff --git a/src/backends/cl/ClLayerSupport.hpp b/src/backends/cl/ClLayerSupport.hpp
index 26eb42e092..219ce3b49e 100644
--- a/src/backends/cl/ClLayerSupport.hpp
+++ b/src/backends/cl/ClLayerSupport.hpp
@@ -26,6 +26,11 @@ public:
const TensorInfo& output,
Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
+ bool IsArgMinMaxSupported(const TensorInfo& input,
+ const TensorInfo& output,
+ const ArgMinMaxDescriptor& descriptor,
+ Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
+
bool IsBatchNormalizationSupported(const TensorInfo& input,
const TensorInfo& output,
const TensorInfo& mean,
diff --git a/src/backends/cl/ClTensorHandle.hpp b/src/backends/cl/ClTensorHandle.hpp
index f5583c0b97..2423a8bbcb 100644
--- a/src/backends/cl/ClTensorHandle.hpp
+++ b/src/backends/cl/ClTensorHandle.hpp
@@ -110,6 +110,10 @@ private:
armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
static_cast<int16_t*>(memory));
break;
+ case arm_compute::DataType::S32:
+ armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
+ static_cast<int32_t*>(memory));
+ break;
default:
{
throw armnn::UnimplementedException();
@@ -142,6 +146,10 @@ private:
armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int16_t*>(memory),
this->GetTensor());
break;
+ case arm_compute::DataType::S32:
+ armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int32_t*>(memory),
+ this->GetTensor());
+ break;
default:
{
throw armnn::UnimplementedException();
@@ -222,6 +230,10 @@ private:
armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
static_cast<int16_t*>(memory));
break;
+ case arm_compute::DataType::S32:
+ armcomputetensorutils::CopyArmComputeITensorData(this->GetTensor(),
+ static_cast<int32_t*>(memory));
+ break;
default:
{
throw armnn::UnimplementedException();
@@ -254,6 +266,10 @@ private:
armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int16_t*>(memory),
this->GetTensor());
break;
+ case arm_compute::DataType::S32:
+ armcomputetensorutils::CopyArmComputeITensorData(static_cast<const int32_t*>(memory),
+ this->GetTensor());
+ break;
default:
{
throw armnn::UnimplementedException();
diff --git a/src/backends/cl/ClWorkloadFactory.cpp b/src/backends/cl/ClWorkloadFactory.cpp
index 04e09f4ff1..2a7c8fe4ef 100644
--- a/src/backends/cl/ClWorkloadFactory.cpp
+++ b/src/backends/cl/ClWorkloadFactory.cpp
@@ -144,6 +144,12 @@ std::unique_ptr<IWorkload> ClWorkloadFactory::CreateAddition(const AdditionQueue
return MakeWorkload<ClAdditionWorkload>(descriptor, info);
}
+std::unique_ptr<IWorkload> ClWorkloadFactory::CreateArgMinMax(const ArgMinMaxQueueDescriptor& descriptor,
+ const WorkloadInfo& info) const
+{
+ return std::make_unique<ClArgMinMaxWorkload>(descriptor, info);
+}
+
std::unique_ptr<IWorkload> ClWorkloadFactory::CreateBatchNormalization(
const BatchNormalizationQueueDescriptor& descriptor,
const WorkloadInfo& info) const
diff --git a/src/backends/cl/ClWorkloadFactory.hpp b/src/backends/cl/ClWorkloadFactory.hpp
index 1cae6e1faf..18d12bedf2 100644
--- a/src/backends/cl/ClWorkloadFactory.hpp
+++ b/src/backends/cl/ClWorkloadFactory.hpp
@@ -47,6 +47,9 @@ public:
std::unique_ptr<IWorkload> CreateAddition(const AdditionQueueDescriptor& descriptor,
const WorkloadInfo& info) const override;
+ std::unique_ptr<IWorkload> CreateArgMinMax(const ArgMinMaxQueueDescriptor& descriptor,
+ const WorkloadInfo& info) const override;
+
std::unique_ptr<IWorkload> CreateBatchNormalization(const BatchNormalizationQueueDescriptor& descriptor,
const WorkloadInfo& info) const override;
diff --git a/src/backends/cl/backend.mk b/src/backends/cl/backend.mk
index b78bae1582..c43918693c 100644
--- a/src/backends/cl/backend.mk
+++ b/src/backends/cl/backend.mk
@@ -25,6 +25,7 @@ BACKEND_SOURCES := \
workloads/ClAbsWorkload.cpp \
workloads/ClActivationWorkload.cpp \
workloads/ClAdditionWorkload.cpp \
+ workloads/ClArgMinMaxWorkload.cpp \
workloads/ClBatchNormalizationFloatWorkload.cpp \
workloads/ClBatchToSpaceNdWorkload.cpp \
workloads/ClConcatWorkload.cpp \
diff --git a/src/backends/cl/test/ClLayerTests.cpp b/src/backends/cl/test/ClLayerTests.cpp
index 0fc8ece498..7d1fb8b251 100644
--- a/src/backends/cl/test/ClLayerTests.cpp
+++ b/src/backends/cl/test/ClLayerTests.cpp
@@ -872,6 +872,14 @@ ARMNN_AUTO_TEST_CASE(Abs3dFloat16, Abs3dTest<DataType::Float16>)
ARMNN_AUTO_TEST_CASE(AbsZeroFloat16, AbsZeroTest<DataType::Float16>)
+// ArgMinMax
+ARMNN_AUTO_TEST_CASE(ArgMinFloat32, ArgMinSimpleTest<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE(ArgMaxFloat32, ArgMaxSimpleTest<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE(ArgMinChannel, ArgMinChannelTest<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE(ArgMaxChannel, ArgMaxChannelTest<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE(ArgMaxHeight, ArgMaxHeightTest<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE(ArgMinWidth, ArgMinWidthTest<DataType::Float32>)
+
#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 a9f320d51f..94c4a3e967 100644
--- a/src/backends/cl/workloads/CMakeLists.txt
+++ b/src/backends/cl/workloads/CMakeLists.txt
@@ -10,6 +10,8 @@ list(APPEND armnnClBackendWorkloads_sources
ClActivationWorkload.hpp
ClAdditionWorkload.cpp
ClAdditionWorkload.hpp
+ ClArgMinMaxWorkload.cpp
+ ClArgMinMaxWorkload.hpp
ClBatchNormalizationFloatWorkload.cpp
ClBatchNormalizationFloatWorkload.hpp
ClBatchToSpaceNdWorkload.cpp
diff --git a/src/backends/cl/workloads/ClArgMinMaxWorkload.cpp b/src/backends/cl/workloads/ClArgMinMaxWorkload.cpp
new file mode 100644
index 0000000000..3270b0a2f3
--- /dev/null
+++ b/src/backends/cl/workloads/ClArgMinMaxWorkload.cpp
@@ -0,0 +1,82 @@
+//
+// Copyright © 2019 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "ClArgMinMaxWorkload.hpp"
+#include "ClWorkloadUtils.hpp"
+
+#include <aclCommon/ArmComputeTensorUtils.hpp>
+
+#include <backendsCommon/CpuTensorHandle.hpp>
+
+#include <TensorUtils.hpp>
+
+#include <cl/ClTensorHandle.hpp>
+#include <cl/ClLayerSupport.hpp>
+
+namespace
+{
+unsigned int CalcAclAxis(unsigned int numDimensions, unsigned int axisIndex)
+{
+ return (numDimensions - axisIndex) - 1;
+}
+
+} //namespace
+
+namespace armnn
+{
+
+arm_compute::Status ClArgMinMaxWorkloadValidate(const TensorInfo& input,
+ const TensorInfo& output,
+ const ArgMinMaxDescriptor& descriptor)
+{
+ const arm_compute::TensorInfo aclInput = armcomputetensorutils::BuildArmComputeTensorInfo(input);
+ const arm_compute::TensorInfo aclOutput = armcomputetensorutils::BuildArmComputeTensorInfo(output);
+
+ auto numDims = input.GetNumDimensions();
+ auto unsignedAxis = armnnUtils::GetUnsignedAxis(numDims, descriptor.m_Axis);
+ int aclAxis = boost::numeric_cast<int>(CalcAclAxis(numDims, unsignedAxis));
+
+ if (descriptor.m_Function == ArgMinMaxFunction::Max)
+ {
+ return arm_compute::CLArgMinMaxLayer::validate(&aclInput, aclAxis, &aclOutput,
+ arm_compute::ReductionOperation::ARG_IDX_MAX);
+ }
+ else
+ {
+ return arm_compute::CLArgMinMaxLayer::validate(&aclInput, aclAxis, &aclOutput,
+ arm_compute::ReductionOperation::ARG_IDX_MIN);
+ }
+}
+
+
+ClArgMinMaxWorkload::ClArgMinMaxWorkload(const ArgMinMaxQueueDescriptor& descriptor,
+ const WorkloadInfo& info)
+ : BaseWorkload<ArgMinMaxQueueDescriptor>(descriptor, info)
+{
+ arm_compute::ICLTensor& input = static_cast<IClTensorHandle*>(this->m_Data.m_Inputs[0])->GetTensor();
+ arm_compute::ICLTensor& output = static_cast<IClTensorHandle*>(this->m_Data.m_Outputs[0])->GetTensor();
+
+ auto numDims = info.m_InputTensorInfos[0].GetNumDimensions();
+ auto unsignedAxis = armnnUtils::GetUnsignedAxis(numDims, m_Data.m_Parameters.m_Axis);
+ int aclAxis = boost::numeric_cast<int>(CalcAclAxis(numDims, unsignedAxis));
+
+ if (m_Data.m_Parameters.m_Function == ArgMinMaxFunction::Max)
+ {
+ m_ArgMinMaxLayer.configure(&input, aclAxis, &output, arm_compute::ReductionOperation::ARG_IDX_MAX);
+ }
+ else
+ {
+ m_ArgMinMaxLayer.configure(&input, aclAxis, &output, arm_compute::ReductionOperation::ARG_IDX_MIN);
+ }
+}
+
+void ClArgMinMaxWorkload::Execute() const
+{
+ ARMNN_SCOPED_PROFILING_EVENT_CL("ClArgMinMaxWorkload_Execute");
+ RunClFunction(m_ArgMinMaxLayer, CHECK_LOCATION());
+}
+
+} //namespace armnn
+
diff --git a/src/backends/cl/workloads/ClArgMinMaxWorkload.hpp b/src/backends/cl/workloads/ClArgMinMaxWorkload.hpp
new file mode 100644
index 0000000000..54f28e6175
--- /dev/null
+++ b/src/backends/cl/workloads/ClArgMinMaxWorkload.hpp
@@ -0,0 +1,30 @@
+//
+// Copyright © 2019 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/CLArgMinMaxLayer.h>
+
+namespace armnn
+{
+
+arm_compute::Status ClArgMinMaxWorkloadValidate(const TensorInfo& input,
+ const TensorInfo& output,
+ const ArgMinMaxDescriptor& descriptor);
+
+class ClArgMinMaxWorkload : public BaseWorkload<ArgMinMaxQueueDescriptor>
+{
+public:
+ ClArgMinMaxWorkload(const ArgMinMaxQueueDescriptor& descriptor, const WorkloadInfo& info);
+ virtual void Execute() const override;
+
+private:
+ mutable arm_compute::CLArgMinMaxLayer m_ArgMinMaxLayer;
+};
+
+} //namespace armnn
diff --git a/src/backends/cl/workloads/ClWorkloads.hpp b/src/backends/cl/workloads/ClWorkloads.hpp
index cd6ca5fe17..dd8c6996d4 100644
--- a/src/backends/cl/workloads/ClWorkloads.hpp
+++ b/src/backends/cl/workloads/ClWorkloads.hpp
@@ -7,6 +7,7 @@
#include "ClAbsWorkload.hpp"
#include "ClActivationWorkload.hpp"
#include "ClAdditionWorkload.hpp"
+#include "ClArgMinMaxWorkload.hpp"
#include "ClConstantWorkload.hpp"
#include "ClBatchNormalizationFloatWorkload.hpp"
#include "ClBatchToSpaceNdWorkload.hpp"
diff --git a/src/backends/neon/test/NeonLayerTests.cpp b/src/backends/neon/test/NeonLayerTests.cpp
index ef3c8379eb..ea9c813d34 100644
--- a/src/backends/neon/test/NeonLayerTests.cpp
+++ b/src/backends/neon/test/NeonLayerTests.cpp
@@ -955,6 +955,8 @@ ARMNN_AUTO_TEST_CASE(ArgMinFloat32, ArgMinSimpleTest<DataType::Float32>)
ARMNN_AUTO_TEST_CASE(ArgMaxFloat32, ArgMaxSimpleTest<DataType::Float32>)
ARMNN_AUTO_TEST_CASE(ArgMinChannel, ArgMinChannelTest<DataType::Float32>)
ARMNN_AUTO_TEST_CASE(ArgMaxChannel, ArgMaxChannelTest<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE(ArgMaxHeight, ArgMaxHeightTest<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE(ArgMinWidth, ArgMinWidthTest<DataType::Float32>)
#if defined(ARMNNREF_ENABLED)