From cedd34fa77a42fce6b832f6424eed45543fe71d4 Mon Sep 17 00:00:00 2001 From: Teresa Charlin Date: Mon, 30 Mar 2020 11:17:30 +0100 Subject: IVGCVSW-4603 Support comparison operators in Neon * Deprecate NeonGreaterWorkload * Add NeonComparisonWorkload to encompass all comparison operators Signed-off-by: Teresa Charlin Change-Id: I5e828088d17e994fc5cb0b908719b53ee01fa959 --- src/backends/backendsCommon/WorkloadData.hpp | 2 +- src/backends/neon/NeonLayerSupport.cpp | 17 +++---- src/backends/neon/NeonWorkloadFactory.cpp | 9 +--- src/backends/neon/backend.mk | 2 +- src/backends/neon/test/NeonLayerTests.cpp | 45 ++++++++++++++++++ src/backends/neon/workloads/CMakeLists.txt | 4 +- .../neon/workloads/NeonComparisonWorkload.cpp | 53 ++++++++++++++++++++++ .../neon/workloads/NeonComparisonWorkload.hpp | 31 +++++++++++++ .../neon/workloads/NeonGreaterWorkload.cpp | 44 ------------------ .../neon/workloads/NeonGreaterWorkload.hpp | 30 ------------ src/backends/neon/workloads/NeonWorkloads.hpp | 2 +- 11 files changed, 142 insertions(+), 97 deletions(-) create mode 100644 src/backends/neon/workloads/NeonComparisonWorkload.cpp create mode 100644 src/backends/neon/workloads/NeonComparisonWorkload.hpp delete mode 100644 src/backends/neon/workloads/NeonGreaterWorkload.cpp delete mode 100644 src/backends/neon/workloads/NeonGreaterWorkload.hpp (limited to 'src/backends') diff --git a/src/backends/backendsCommon/WorkloadData.hpp b/src/backends/backendsCommon/WorkloadData.hpp index ad71e3c0a9..9239f4a525 100644 --- a/src/backends/backendsCommon/WorkloadData.hpp +++ b/src/backends/backendsCommon/WorkloadData.hpp @@ -259,7 +259,7 @@ struct QuantizeQueueDescriptor : QueueDescriptor void Validate(const WorkloadInfo& workloadInfo) const; }; -// Equal layer workload data +// Deprecated use ComparisonQueueDescriptor instead struct EqualQueueDescriptor : QueueDescriptor { void Validate(const WorkloadInfo& workloadInfo) const; diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp index 999b158f74..c01a178f18 100644 --- a/src/backends/neon/NeonLayerSupport.cpp +++ b/src/backends/neon/NeonLayerSupport.cpp @@ -24,11 +24,11 @@ #include "workloads/NeonArgMinMaxWorkload.hpp" #include "workloads/NeonBatchNormalizationWorkload.hpp" #include "workloads/NeonBatchToSpaceNdWorkload.hpp" +#include "workloads/NeonComparisonWorkload.hpp" #include "workloads/NeonConvolution2dWorkload.hpp" #include "workloads/NeonDepthToSpaceWorkload.hpp" #include "workloads/NeonDepthwiseConvolutionWorkload.hpp" #include "workloads/NeonDequantizeWorkload.hpp" -#include "workloads/NeonGreaterWorkload.hpp" #include "workloads/NeonInstanceNormalizationWorkload.hpp" #include "workloads/NeonL2NormalizationFloatWorkload.hpp" #include "workloads/NeonLstmFloatWorkload.hpp" @@ -202,16 +202,13 @@ bool NeonLayerSupport::IsComparisonSupported(const TensorInfo& input0, const ComparisonDescriptor& descriptor, Optional reasonIfUnsupported) const { - if (descriptor.m_Operation == ComparisonOperation::Greater) - { - FORWARD_WORKLOAD_VALIDATE_FUNC(NeonGreaterWorkloadValidate, - reasonIfUnsupported, - input0, - input1, - output); - } - return false; + FORWARD_WORKLOAD_VALIDATE_FUNC(NeonComparisonWorkloadValidate, + reasonIfUnsupported, + input0, + input1, + output, + descriptor); } bool NeonLayerSupport::IsConcatSupported(const std::vector inputs, diff --git a/src/backends/neon/NeonWorkloadFactory.cpp b/src/backends/neon/NeonWorkloadFactory.cpp index bf26d82a76..982104e38e 100644 --- a/src/backends/neon/NeonWorkloadFactory.cpp +++ b/src/backends/neon/NeonWorkloadFactory.cpp @@ -139,14 +139,7 @@ std::unique_ptr NeonWorkloadFactory::CreateBatchToSpaceNd(const Batch std::unique_ptr NeonWorkloadFactory::CreateComparison(const ComparisonQueueDescriptor& descriptor, const WorkloadInfo& info) const { - if (descriptor.m_Parameters.m_Operation == ComparisonOperation::Greater) - { - GreaterQueueDescriptor greaterQueueDescriptor; - greaterQueueDescriptor.m_Inputs = descriptor.m_Inputs; - greaterQueueDescriptor.m_Outputs = descriptor.m_Outputs; - return std::make_unique(greaterQueueDescriptor, info); - } - return MakeWorkloadHelper(descriptor, info); + return std::make_unique(descriptor, info); } std::unique_ptr NeonWorkloadFactory::CreateConcat(const ConcatQueueDescriptor& descriptor, diff --git a/src/backends/neon/backend.mk b/src/backends/neon/backend.mk index 3cb8bd582a..3b3333a0c3 100644 --- a/src/backends/neon/backend.mk +++ b/src/backends/neon/backend.mk @@ -27,6 +27,7 @@ BACKEND_SOURCES := \ workloads/NeonArgMinMaxWorkload.cpp \ workloads/NeonBatchNormalizationWorkload.cpp \ workloads/NeonBatchToSpaceNdWorkload.cpp \ + workloads/NeonComparisonWorkload.cpp \ workloads/NeonConcatWorkload.cpp \ workloads/NeonConstantWorkload.cpp \ workloads/NeonConvertFp16ToFp32Workload.cpp \ @@ -38,7 +39,6 @@ BACKEND_SOURCES := \ workloads/NeonDetectionPostProcessWorkload.cpp \ workloads/NeonFloorFloatWorkload.cpp \ workloads/NeonFullyConnectedWorkload.cpp \ - workloads/NeonGreaterWorkload.cpp \ workloads/NeonInstanceNormalizationWorkload.cpp \ workloads/NeonL2NormalizationFloatWorkload.cpp \ workloads/NeonLstmFloatWorkload.cpp \ diff --git a/src/backends/neon/test/NeonLayerTests.cpp b/src/backends/neon/test/NeonLayerTests.cpp index 06b5597fcf..19a89160c4 100644 --- a/src/backends/neon/test/NeonLayerTests.cpp +++ b/src/backends/neon/test/NeonLayerTests.cpp @@ -623,6 +623,15 @@ ARMNN_AUTO_TEST_CASE(L2NormalizationNonDefaultEpsilon, L2NormalizationNonDefault // Floor ARMNN_AUTO_TEST_CASE(SimpleFloor, SimpleFloorTest) +// Equal +ARMNN_AUTO_TEST_CASE(EqualSimple, EqualSimpleTest) +ARMNN_AUTO_TEST_CASE(EqualBroadcast1Element, EqualBroadcast1ElementTest) +ARMNN_AUTO_TEST_CASE(EqualBroadcast1dVector, EqualBroadcast1dVectorTest) + +ARMNN_AUTO_TEST_CASE(EqualSimpleUint8, EqualSimpleUint8Test) +ARMNN_AUTO_TEST_CASE(EqualBroadcast1ElementUint8, EqualBroadcast1ElementUint8Test) +ARMNN_AUTO_TEST_CASE(EqualBroadcast1dVectorUint8, EqualBroadcast1dVectorUint8Test) + // Greater ARMNN_AUTO_TEST_CASE(GreaterSimple, GreaterSimpleTest) ARMNN_AUTO_TEST_CASE(GreaterBroadcast1Element, GreaterBroadcast1ElementTest) @@ -632,6 +641,42 @@ ARMNN_AUTO_TEST_CASE(GreaterSimpleUint8, GreaterSimpleUint8Test) ARMNN_AUTO_TEST_CASE(GreaterBroadcast1ElementUint8, GreaterBroadcast1ElementUint8Test) ARMNN_AUTO_TEST_CASE(GreaterBroadcast1dVectorUint8, GreaterBroadcast1dVectorUint8Test) +// GreaterOrEqual +ARMNN_AUTO_TEST_CASE(GreaterOrEqualSimple, GreaterOrEqualSimpleTest) +ARMNN_AUTO_TEST_CASE(GreaterOrEqualBroadcast1Element, GreaterOrEqualBroadcast1ElementTest) +ARMNN_AUTO_TEST_CASE(GreaterOrEqualBroadcast1dVector, GreaterOrEqualBroadcast1dVectorTest) + +ARMNN_AUTO_TEST_CASE(GreaterOrEqualSimpleUint8, GreaterOrEqualSimpleUint8Test) +ARMNN_AUTO_TEST_CASE(GreaterOrEqualBroadcast1ElementUint8, GreaterOrEqualBroadcast1ElementUint8Test) +ARMNN_AUTO_TEST_CASE(GreaterOrEqualBroadcast1dVectorUint8, GreaterOrEqualBroadcast1dVectorUint8Test) + +// Less +ARMNN_AUTO_TEST_CASE(LessSimple, LessSimpleTest) +ARMNN_AUTO_TEST_CASE(LessBroadcast1Element, LessBroadcast1ElementTest) +ARMNN_AUTO_TEST_CASE(LessBroadcast1dVector, LessBroadcast1dVectorTest) + +ARMNN_AUTO_TEST_CASE(LessSimpleUint8, LessSimpleUint8Test) +ARMNN_AUTO_TEST_CASE(LessBroadcast1ElementUint8, LessBroadcast1ElementUint8Test) +ARMNN_AUTO_TEST_CASE(LessBroadcast1dVectorUint8, LessBroadcast1dVectorUint8Test) + +// LessOrEqual +ARMNN_AUTO_TEST_CASE(LessOrEqualSimple, LessOrEqualSimpleTest) +ARMNN_AUTO_TEST_CASE(LessOrEqualBroadcast1Element, LessOrEqualBroadcast1ElementTest) +ARMNN_AUTO_TEST_CASE(LessOrEqualBroadcast1dVector, LessOrEqualBroadcast1dVectorTest) + +ARMNN_AUTO_TEST_CASE(LessOrEqualSimpleUint8, LessOrEqualSimpleUint8Test) +ARMNN_AUTO_TEST_CASE(LessOrEqualBroadcast1ElementUint8, LessOrEqualBroadcast1ElementUint8Test) +ARMNN_AUTO_TEST_CASE(LessOrEqualBroadcast1dVectorUint8, LessOrEqualBroadcast1dVectorUint8Test) + +// NotEqual +ARMNN_AUTO_TEST_CASE(NotEqualSimple, NotEqualSimpleTest) +ARMNN_AUTO_TEST_CASE(NotEqualBroadcast1Element, NotEqualBroadcast1ElementTest) +ARMNN_AUTO_TEST_CASE(NotEqualBroadcast1dVector, NotEqualBroadcast1dVectorTest) + +ARMNN_AUTO_TEST_CASE(NotEqualSimpleUint8, NotEqualSimpleUint8Test) +ARMNN_AUTO_TEST_CASE(NotEqualBroadcast1ElementUint8, NotEqualBroadcast1ElementUint8Test) +ARMNN_AUTO_TEST_CASE(NotEqualBroadcast1dVectorUint8, NotEqualBroadcast1dVectorUint8Test) + // Reshape ARMNN_AUTO_TEST_CASE(SimpleReshapeFloat32, SimpleReshapeTest) ARMNN_AUTO_TEST_CASE(SimpleReshapeUint8, SimpleReshapeTest) diff --git a/src/backends/neon/workloads/CMakeLists.txt b/src/backends/neon/workloads/CMakeLists.txt index 8160710f65..cbe1e3b945 100644 --- a/src/backends/neon/workloads/CMakeLists.txt +++ b/src/backends/neon/workloads/CMakeLists.txt @@ -16,6 +16,8 @@ list(APPEND armnnNeonBackendWorkloads_sources NeonBatchNormalizationWorkload.hpp NeonBatchToSpaceNdWorkload.cpp NeonBatchToSpaceNdWorkload.hpp + NeonComparisonWorkload.cpp + NeonComparisonWorkload.hpp NeonConcatWorkload.cpp NeonConcatWorkload.hpp NeonConstantWorkload.cpp @@ -38,8 +40,6 @@ list(APPEND armnnNeonBackendWorkloads_sources NeonFloorFloatWorkload.hpp NeonFullyConnectedWorkload.cpp NeonFullyConnectedWorkload.hpp - NeonGreaterWorkload.cpp - NeonGreaterWorkload.hpp NeonInstanceNormalizationWorkload.cpp NeonInstanceNormalizationWorkload.hpp NeonL2NormalizationFloatWorkload.cpp diff --git a/src/backends/neon/workloads/NeonComparisonWorkload.cpp b/src/backends/neon/workloads/NeonComparisonWorkload.cpp new file mode 100644 index 0000000000..0edb3328b9 --- /dev/null +++ b/src/backends/neon/workloads/NeonComparisonWorkload.cpp @@ -0,0 +1,53 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "NeonComparisonWorkload.hpp" +#include +#include +#include + +namespace armnn +{ +using namespace armcomputetensorutils; + +arm_compute::Status NeonComparisonWorkloadValidate(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + const ComparisonDescriptor& descriptor) +{ + const arm_compute::TensorInfo aclInput0 = BuildArmComputeTensorInfo(input0); + const arm_compute::TensorInfo aclInput1 = BuildArmComputeTensorInfo(input1); + const arm_compute::TensorInfo aclOutput = BuildArmComputeTensorInfo(output); + + const arm_compute::ComparisonOperation comparisonOperation = ConvertComparisonOperationToAcl(descriptor); + + const arm_compute::Status aclStatus = arm_compute::NEElementwiseComparison::validate(&aclInput0, + &aclInput1, + &aclOutput, + comparisonOperation); + return aclStatus; +} + +NeonComparisonWorkload::NeonComparisonWorkload(const ComparisonQueueDescriptor& descriptor, const WorkloadInfo& info) + : BaseWorkload(descriptor, info) +{ + m_Data.ValidateInputsOutputs("NeonComparisonWorkload", 2, 1); + + arm_compute::ITensor& input0 = boost::polymorphic_downcast(m_Data.m_Inputs[0])->GetTensor(); + arm_compute::ITensor& input1 = boost::polymorphic_downcast(m_Data.m_Inputs[1])->GetTensor(); + arm_compute::ITensor& output = boost::polymorphic_downcast(m_Data.m_Outputs[0])->GetTensor(); + + const arm_compute::ComparisonOperation comparisonOperation = ConvertComparisonOperationToAcl(m_Data.m_Parameters); + + m_ComparisonLayer.configure(&input0, &input1, &output, comparisonOperation); +} + +void NeonComparisonWorkload::Execute() const +{ + ARMNN_SCOPED_PROFILING_EVENT_NEON("NeonComparisonWorkload_Execute"); + m_ComparisonLayer.run(); +} + +} //namespace armnn \ No newline at end of file diff --git a/src/backends/neon/workloads/NeonComparisonWorkload.hpp b/src/backends/neon/workloads/NeonComparisonWorkload.hpp new file mode 100644 index 0000000000..1b01053d00 --- /dev/null +++ b/src/backends/neon/workloads/NeonComparisonWorkload.hpp @@ -0,0 +1,31 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include + +#include + +namespace armnn +{ + +arm_compute::Status NeonComparisonWorkloadValidate(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + const ComparisonDescriptor& descriptor); + +class NeonComparisonWorkload : public BaseWorkload +{ +public: + NeonComparisonWorkload(const ComparisonQueueDescriptor& descriptor, const WorkloadInfo& info); + + virtual void Execute() const override; + +private: + mutable arm_compute::NEElementwiseComparison m_ComparisonLayer; +}; + +} //namespace armnn \ No newline at end of file diff --git a/src/backends/neon/workloads/NeonGreaterWorkload.cpp b/src/backends/neon/workloads/NeonGreaterWorkload.cpp deleted file mode 100644 index 1ec5ac4be0..0000000000 --- a/src/backends/neon/workloads/NeonGreaterWorkload.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#include "NeonGreaterWorkload.hpp" -#include -#include - -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); -} - -NeonGreaterWorkload::NeonGreaterWorkload(const GreaterQueueDescriptor& descriptor, const WorkloadInfo& info) - : BaseWorkload(descriptor, info) -{ - m_Data.ValidateInputsOutputs("NeonGreaterWorkload", 2, 1); - - arm_compute::ITensor& input0 = boost::polymorphic_downcast(m_Data.m_Inputs[0])->GetTensor(); - arm_compute::ITensor& input1 = boost::polymorphic_downcast(m_Data.m_Inputs[1])->GetTensor(); - arm_compute::ITensor& output = boost::polymorphic_downcast(m_Data.m_Outputs[0])->GetTensor(); - - m_GreaterLayer.configure(&input0, &input1, &output); -} - -void NeonGreaterWorkload::Execute() const -{ - ARMNN_SCOPED_PROFILING_EVENT_NEON("NeonGreaterWorkload_Execute"); - m_GreaterLayer.run(); -} - -} //namespace armnn \ No newline at end of file diff --git a/src/backends/neon/workloads/NeonGreaterWorkload.hpp b/src/backends/neon/workloads/NeonGreaterWorkload.hpp deleted file mode 100644 index 503e60e784..0000000000 --- a/src/backends/neon/workloads/NeonGreaterWorkload.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include - -#include - -namespace armnn -{ - -arm_compute::Status NeonGreaterWorkloadValidate(const TensorInfo& input0, - const TensorInfo& input1, - const TensorInfo& output); - -class NeonGreaterWorkload : public BaseWorkload -{ -public: - NeonGreaterWorkload(const GreaterQueueDescriptor& descriptor, const WorkloadInfo& info); - - virtual void Execute() const override; - -private: - mutable arm_compute::NEGreater m_GreaterLayer; -}; - -} //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 e28d120de7..2b7eabeb0d 100644 --- a/src/backends/neon/workloads/NeonWorkloads.hpp +++ b/src/backends/neon/workloads/NeonWorkloads.hpp @@ -11,6 +11,7 @@ #include "NeonArgMinMaxWorkload.hpp" #include "NeonBatchNormalizationWorkload.hpp" #include "NeonBatchToSpaceNdWorkload.hpp" +#include "NeonComparisonWorkload.hpp" #include "NeonConstantWorkload.hpp" #include "NeonConvertFp16ToFp32Workload.hpp" #include "NeonConvertFp32ToFp16Workload.hpp" @@ -21,7 +22,6 @@ #include "NeonDetectionPostProcessWorkload.hpp" #include "NeonFloorFloatWorkload.hpp" #include "NeonFullyConnectedWorkload.hpp" -#include "NeonGreaterWorkload.hpp" #include "NeonInstanceNormalizationWorkload.hpp" #include "NeonL2NormalizationFloatWorkload.hpp" #include "NeonLstmFloatWorkload.hpp" -- cgit v1.2.1