aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkevmay01 <kevin.may@arm.com>2019-01-28 08:37:25 +0000
committerKevin May <kevin.may@arm.com>2019-01-29 08:28:32 +0000
commiteed85925f893256f8e813423de0f3c5fc79179ae (patch)
tree69d7421e542c13266e17985165760b9d831095be
parentcd7544e4ea0dc9fdee80447688bf4b8d64cc2ec8 (diff)
downloadarmnn-eed85925f893256f8e813423de0f3c5fc79179ae.tar.gz
IVGCVSW-2447 Add Greater Workload to Neon
Change-Id: Ic165061cc61534e7e391a398ea7c2918240e2d3b
-rw-r--r--src/backends/backendsCommon/WorkloadFactory.cpp5
-rw-r--r--src/backends/neon/NeonLayerSupport.cpp13
-rw-r--r--src/backends/neon/NeonLayerSupport.hpp5
-rw-r--r--src/backends/neon/NeonWorkloadFactory.cpp2
-rw-r--r--src/backends/neon/backend.mk1
-rw-r--r--src/backends/neon/test/NeonEndToEndTests.cpp41
-rw-r--r--src/backends/neon/test/NeonLayerTests.cpp8
-rw-r--r--src/backends/neon/workloads/CMakeLists.txt2
-rw-r--r--src/backends/neon/workloads/NeonGreaterWorkload.cpp49
-rw-r--r--src/backends/neon/workloads/NeonGreaterWorkload.hpp36
-rw-r--r--src/backends/neon/workloads/NeonWorkloads.hpp1
11 files changed, 158 insertions, 5 deletions
diff --git a/src/backends/backendsCommon/WorkloadFactory.cpp b/src/backends/backendsCommon/WorkloadFactory.cpp
index cffb54841b..6cca174141 100644
--- a/src/backends/backendsCommon/WorkloadFactory.cpp
+++ b/src/backends/backendsCommon/WorkloadFactory.cpp
@@ -729,10 +729,7 @@ bool IWorkloadFactory::IsLayerSupported(const BackendId& backendId,
const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = layerSupportObject->IsGreaterSupported(OverrideDataType(input0, dataType),
- OverrideDataType(input1, dataType),
- OverrideDataType(output, dataType),
- reason);
+ result = layerSupportObject->IsGreaterSupported(input0, input1, output, reason);
break;
}
default:
diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp
index 3b0967628d..e56d88b7c8 100644
--- a/src/backends/neon/NeonLayerSupport.cpp
+++ b/src/backends/neon/NeonLayerSupport.cpp
@@ -22,6 +22,7 @@
#include "workloads/NeonBatchNormalizationWorkload.hpp"
#include "workloads/NeonConvolution2dWorkload.hpp"
#include "workloads/NeonDepthwiseConvolutionWorkload.hpp"
+#include "workloads/NeonGreaterWorkload.hpp"
#include "workloads/NeonL2NormalizationFloatWorkload.hpp"
#include "workloads/NeonMaximumWorkload.hpp"
#include "workloads/NeonMeanWorkload.hpp"
@@ -236,6 +237,18 @@ bool NeonLayerSupport::IsFullyConnectedSupported(const TensorInfo& input,
descriptor);
}
+bool NeonLayerSupport::IsGreaterSupported(const armnn::TensorInfo& input0,
+ const armnn::TensorInfo& input1,
+ const armnn::TensorInfo& output,
+ armnn::Optional<std::string&> reasonIfUnsupported) const
+{
+ FORWARD_WORKLOAD_VALIDATE_FUNC(NeonGreaterWorkloadValidate,
+ reasonIfUnsupported,
+ input0,
+ input1,
+ output);
+}
+
bool NeonLayerSupport::IsInputSupported(const TensorInfo& input,
Optional<std::string&> reasonIfUnsupported) const
{
diff --git a/src/backends/neon/NeonLayerSupport.hpp b/src/backends/neon/NeonLayerSupport.hpp
index 6de5c784cc..27e825afa9 100644
--- a/src/backends/neon/NeonLayerSupport.hpp
+++ b/src/backends/neon/NeonLayerSupport.hpp
@@ -67,6 +67,11 @@ public:
const FullyConnectedDescriptor& descriptor,
Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
+ bool IsGreaterSupported(const TensorInfo& input0,
+ const TensorInfo& input1,
+ const TensorInfo& output,
+ Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
+
bool IsInputSupported(const TensorInfo& input,
Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
diff --git a/src/backends/neon/NeonWorkloadFactory.cpp b/src/backends/neon/NeonWorkloadFactory.cpp
index 5c7eeccb26..d9bd8b5223 100644
--- a/src/backends/neon/NeonWorkloadFactory.cpp
+++ b/src/backends/neon/NeonWorkloadFactory.cpp
@@ -316,7 +316,7 @@ std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateMinimum(const MinimumQueue
std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateGreater(const GreaterQueueDescriptor& descriptor,
const WorkloadInfo& info) const
{
- return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
+ return MakeWorkloadHelper<NeonGreaterFloat32Workload, NeonGreaterUint8Workload>(descriptor, info);
}
std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDebug(const DebugQueueDescriptor& descriptor,
diff --git a/src/backends/neon/backend.mk b/src/backends/neon/backend.mk
index 09dca63431..34f797ff46 100644
--- a/src/backends/neon/backend.mk
+++ b/src/backends/neon/backend.mk
@@ -23,6 +23,7 @@ BACKEND_SOURCES := \
workloads/NeonDepthwiseConvolutionWorkload.cpp \
workloads/NeonFloorFloatWorkload.cpp \
workloads/NeonFullyConnectedWorkload.cpp \
+ workloads/NeonGreaterWorkload.cpp \
workloads/NeonL2NormalizationFloatWorkload.cpp \
workloads/NeonLstmFloatWorkload.cpp \
workloads/NeonMaximumWorkload.cpp \
diff --git a/src/backends/neon/test/NeonEndToEndTests.cpp b/src/backends/neon/test/NeonEndToEndTests.cpp
index 665791a36a..deaa8eb81b 100644
--- a/src/backends/neon/test/NeonEndToEndTests.cpp
+++ b/src/backends/neon/test/NeonEndToEndTests.cpp
@@ -5,6 +5,7 @@
#include <backendsCommon/test/EndToEndTestImpl.hpp>
#include <backendsCommon/test/MergerTestImpl.hpp>
+#include <backendsCommon/test/ArithmeticTestImpl.hpp>
#include <boost/test/unit_test.hpp>
@@ -51,6 +52,46 @@ BOOST_AUTO_TEST_CASE(FallbackToCpuRef)
BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet)) == Status::Success);
}
+BOOST_AUTO_TEST_CASE(NeonGreaterSimpleEndToEndTest)
+{
+ const std::vector<uint8_t> expectedOutput({ 0, 0, 0, 0, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0 });
+
+ ArithmeticSimpleEndToEnd<armnn::DataType::Float32, armnn::DataType::Boolean>(defaultBackends,
+ LayerType::Greater,
+ expectedOutput);
+}
+
+BOOST_AUTO_TEST_CASE(NeonGreaterSimpleEndToEndUint8Test)
+{
+ const std::vector<uint8_t> expectedOutput({ 0, 0, 0, 0, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0 });
+
+ ArithmeticSimpleEndToEnd<armnn::DataType::QuantisedAsymm8, armnn::DataType::Boolean>(defaultBackends,
+ LayerType::Greater,
+ expectedOutput);
+}
+
+BOOST_AUTO_TEST_CASE(NeonGreaterBroadcastEndToEndTest)
+{
+ const std::vector<uint8_t> expectedOutput({ 0, 1, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1 });
+
+ ArithmeticBroadcastEndToEnd<armnn::DataType::Float32, armnn::DataType::Boolean>(defaultBackends,
+ LayerType::Greater,
+ expectedOutput);
+}
+
+BOOST_AUTO_TEST_CASE(NeonGreaterBroadcastEndToEndUint8Test)
+{
+ const std::vector<uint8_t> expectedOutput({ 0, 1, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1 });
+
+ ArithmeticBroadcastEndToEnd<armnn::DataType::QuantisedAsymm8, armnn::DataType::Boolean>(defaultBackends,
+ LayerType::Greater,
+ expectedOutput);
+}
+
BOOST_AUTO_TEST_CASE(NeonMergerEndToEndDim0Test)
{
MergerDim0EndToEnd<armnn::DataType::Float32>(defaultBackends);
diff --git a/src/backends/neon/test/NeonLayerTests.cpp b/src/backends/neon/test/NeonLayerTests.cpp
index b229cd020c..8b93c43327 100644
--- a/src/backends/neon/test/NeonLayerTests.cpp
+++ b/src/backends/neon/test/NeonLayerTests.cpp
@@ -382,6 +382,14 @@ ARMNN_AUTO_TEST_CASE(L2Normalization4dNhwc, L2Normalization4dTest, armnn::DataLa
// Floor
ARMNN_AUTO_TEST_CASE(SimpleFloor, SimpleFloorTest)
+// Greater
+ARMNN_AUTO_TEST_CASE(SimpleGreater, GreaterSimpleTest)
+ARMNN_AUTO_TEST_CASE(GreaterBroadcast1Element, GreaterBroadcast1ElementTest)
+ARMNN_AUTO_TEST_CASE(GreaterBroadcast1DVector, GreaterBroadcast1DVectorTest)
+ARMNN_AUTO_TEST_CASE(GreaterUint8, GreaterUint8Test)
+ARMNN_AUTO_TEST_CASE(GreaterBroadcast1ElementUint8, GreaterBroadcast1ElementUint8Test)
+ARMNN_AUTO_TEST_CASE(GreaterBroadcast1DVectorUint8, GreaterBroadcast1DVectorUint8Test)
+
// Reshape
ARMNN_AUTO_TEST_CASE(SimpleReshapeFloat32, SimpleReshapeFloat32Test)
ARMNN_AUTO_TEST_CASE(SimpleReshapeUint8, SimpleReshapeUint8Test)
diff --git a/src/backends/neon/workloads/CMakeLists.txt b/src/backends/neon/workloads/CMakeLists.txt
index 1a1ed74840..31b0866e23 100644
--- a/src/backends/neon/workloads/CMakeLists.txt
+++ b/src/backends/neon/workloads/CMakeLists.txt
@@ -24,6 +24,8 @@ list(APPEND armnnNeonBackendWorkloads_sources
NeonFloorFloatWorkload.hpp
NeonFullyConnectedWorkload.cpp
NeonFullyConnectedWorkload.hpp
+ NeonGreaterWorkload.cpp
+ NeonGreaterWorkload.hpp
NeonL2NormalizationFloatWorkload.cpp
NeonL2NormalizationFloatWorkload.hpp
NeonLstmFloatWorkload.cpp
diff --git a/src/backends/neon/workloads/NeonGreaterWorkload.cpp b/src/backends/neon/workloads/NeonGreaterWorkload.cpp
new file mode 100644
index 0000000000..ece52d6465
--- /dev/null
+++ b/src/backends/neon/workloads/NeonGreaterWorkload.cpp
@@ -0,0 +1,49 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "NeonGreaterWorkload.hpp"
+#include <aclCommon/ArmComputeTensorUtils.hpp>
+#include <backendsCommon/CpuTensorHandle.hpp>
+
+namespace armnn
+{
+
+arm_compute::Status NeonGreaterWorkloadValidate(const TensorInfo& input0,
+ const TensorInfo& input1,
+ const TensorInfo& output)
+{
+ const arm_compute::TensorInfo aclInput0 = armcomputetensorutils::BuildArmComputeTensorInfo(input0);
+ const arm_compute::TensorInfo aclInput1 = armcomputetensorutils::BuildArmComputeTensorInfo(input1);
+ const arm_compute::TensorInfo aclOutput = armcomputetensorutils::BuildArmComputeTensorInfo(output);
+
+ return arm_compute::NEGreater::validate(&aclInput0,
+ &aclInput1,
+ &aclOutput);
+}
+
+template <DataType T>
+NeonGreaterWorkload<T>::NeonGreaterWorkload(const GreaterQueueDescriptor& descriptor, const WorkloadInfo& info)
+ : MultiTypedWorkload<GreaterQueueDescriptor, T, DataType::Boolean>(descriptor, info)
+{
+ m_Data.ValidateInputsOutputs("NeonGreaterWorkload", 2, 1);
+
+ arm_compute::ITensor& input0 = boost::polymorphic_downcast<INeonTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
+ arm_compute::ITensor& input1 = boost::polymorphic_downcast<INeonTensorHandle*>(m_Data.m_Inputs[1])->GetTensor();
+ arm_compute::ITensor& output = boost::polymorphic_downcast<INeonTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
+
+ m_GreaterLayer.configure(&input0, &input1, &output);
+}
+
+template <DataType T>
+void NeonGreaterWorkload<T>::Execute() const
+{
+ ARMNN_SCOPED_PROFILING_EVENT_NEON("NeonGreaterWorkload_Execute");
+ m_GreaterLayer.run();
+}
+
+template class NeonGreaterWorkload<DataType::Float32>;
+template class NeonGreaterWorkload<DataType::QuantisedAsymm8>;
+
+} //namespace armnn \ No newline at end of file
diff --git a/src/backends/neon/workloads/NeonGreaterWorkload.hpp b/src/backends/neon/workloads/NeonGreaterWorkload.hpp
new file mode 100644
index 0000000000..df1e07e07b
--- /dev/null
+++ b/src/backends/neon/workloads/NeonGreaterWorkload.hpp
@@ -0,0 +1,36 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <neon/workloads/NeonWorkloadUtils.hpp>
+
+#include <arm_compute/runtime/NEON/functions/NEElementwiseOperations.h>
+
+namespace armnn
+{
+
+arm_compute::Status NeonGreaterWorkloadValidate(const TensorInfo& input0,
+ const TensorInfo& input1,
+ const TensorInfo& output);
+
+template <DataType T>
+class NeonGreaterWorkload : public MultiTypedWorkload<GreaterQueueDescriptor, T, DataType::Boolean>
+{
+public:
+ using MultiTypedWorkload<GreaterQueueDescriptor, T, DataType::Boolean>::m_Data;
+
+ NeonGreaterWorkload(const GreaterQueueDescriptor& descriptor, const WorkloadInfo& info);
+
+ virtual void Execute() const override;
+
+private:
+ mutable arm_compute::NEGreater m_GreaterLayer;
+};
+
+using NeonGreaterFloat32Workload = NeonGreaterWorkload<DataType::Float32>;
+using NeonGreaterUint8Workload = NeonGreaterWorkload<DataType::QuantisedAsymm8>;
+
+} //namespace armnn \ No newline at end of file
diff --git a/src/backends/neon/workloads/NeonWorkloads.hpp b/src/backends/neon/workloads/NeonWorkloads.hpp
index e4f4fcfc53..af85eb2f50 100644
--- a/src/backends/neon/workloads/NeonWorkloads.hpp
+++ b/src/backends/neon/workloads/NeonWorkloads.hpp
@@ -14,6 +14,7 @@
#include "NeonDepthwiseConvolutionWorkload.hpp"
#include "NeonFloorFloatWorkload.hpp"
#include "NeonFullyConnectedWorkload.hpp"
+#include "NeonGreaterWorkload.hpp"
#include "NeonL2NormalizationFloatWorkload.hpp"
#include "NeonLstmFloatWorkload.hpp"
#include "NeonMaximumWorkload.hpp"