diff options
Diffstat (limited to 'src/backends/neon')
-rw-r--r-- | src/backends/neon/NeonLayerSupport.cpp | 32 | ||||
-rw-r--r-- | src/backends/neon/NeonLayerSupport.hpp | 7 | ||||
-rw-r--r-- | src/backends/neon/NeonWorkloadFactory.cpp | 37 | ||||
-rw-r--r-- | src/backends/neon/NeonWorkloadFactory.hpp | 5 | ||||
-rw-r--r-- | src/backends/neon/test/NeonCreateWorkloadTests.cpp | 30 | ||||
-rw-r--r-- | src/backends/neon/test/NeonEndToEndTests.cpp | 12 |
6 files changed, 84 insertions, 39 deletions
diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp index a73837b884..fe9bffbee9 100644 --- a/src/backends/neon/NeonLayerSupport.cpp +++ b/src/backends/neon/NeonLayerSupport.cpp @@ -129,10 +129,8 @@ bool NeonLayerSupport::IsAbsSupported(const TensorInfo& input, const TensorInfo& output, Optional<std::string&> reasonIfUnsupported) const { - FORWARD_WORKLOAD_VALIDATE_FUNC(NeonAbsWorkloadValidate, - reasonIfUnsupported, - input, - output); + ElementwiseUnaryDescriptor descriptor(UnaryOperation::Abs); + return IsElementwiseUnarySupported(input, output, descriptor, reasonIfUnsupported); } bool NeonLayerSupport::IsActivationSupported(const TensorInfo& input, @@ -386,6 +384,29 @@ bool NeonLayerSupport::IsDilatedDepthwiseConvolutionSupported(const TensorInfo& biases); } +bool NeonLayerSupport::IsElementwiseUnarySupported(const TensorInfo& input, + const TensorInfo& output, + const ElementwiseUnaryDescriptor& descriptor, + Optional<std::string&> reasonIfUnsupported) const +{ + if (descriptor.m_Operation == UnaryOperation::Abs) + { + FORWARD_WORKLOAD_VALIDATE_FUNC(NeonAbsWorkloadValidate, + reasonIfUnsupported, + input, + output); + } + else if (descriptor.m_Operation == UnaryOperation::Rsqrt) + { + FORWARD_WORKLOAD_VALIDATE_FUNC(NeonRsqrtWorkloadValidate, + reasonIfUnsupported, + input, + output); + } + + return false; +} + bool NeonLayerSupport::IsFloorSupported(const TensorInfo& input, const TensorInfo& output, Optional<std::string&> reasonIfUnsupported) const @@ -656,7 +677,8 @@ bool NeonLayerSupport::IsRsqrtSupported(const TensorInfo& input, const TensorInfo& output, Optional<std::string&> reasonIfUnsupported) const { - FORWARD_WORKLOAD_VALIDATE_FUNC(NeonRsqrtWorkloadValidate, reasonIfUnsupported, input, output); + ElementwiseUnaryDescriptor descriptor(UnaryOperation::Rsqrt); + return IsElementwiseUnarySupported(input, output, descriptor, reasonIfUnsupported); } bool NeonLayerSupport::IsSliceSupported(const TensorInfo& input, diff --git a/src/backends/neon/NeonLayerSupport.hpp b/src/backends/neon/NeonLayerSupport.hpp index 8e6cd6aded..d429aeceec 100644 --- a/src/backends/neon/NeonLayerSupport.hpp +++ b/src/backends/neon/NeonLayerSupport.hpp @@ -12,6 +12,7 @@ namespace armnn class NeonLayerSupport : public LayerSupportBase { public: + ARMNN_DEPRECATED_MSG("Use IsElementwiseUnarySupported instead") bool IsAbsSupported(const TensorInfo& input, const TensorInfo& output, Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; @@ -103,6 +104,11 @@ public: const Optional<TensorInfo>& biases, Optional<std::string&> reason = EmptyOptional()) const override; + bool IsElementwiseUnarySupported(const TensorInfo& input, + const TensorInfo& output, + const ElementwiseUnaryDescriptor& descriptor, + Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; + bool IsFloorSupported(const TensorInfo& input, const TensorInfo& output, Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; @@ -224,6 +230,7 @@ public: const TensorInfo& output, Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; + ARMNN_DEPRECATED_MSG("Use IsElementwiseUnarySupported instead") bool IsRsqrtSupported(const TensorInfo& input, const TensorInfo& output, Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; diff --git a/src/backends/neon/NeonWorkloadFactory.cpp b/src/backends/neon/NeonWorkloadFactory.cpp index 1cc9e50e0b..82f9bdb924 100644 --- a/src/backends/neon/NeonWorkloadFactory.cpp +++ b/src/backends/neon/NeonWorkloadFactory.cpp @@ -98,7 +98,12 @@ std::unique_ptr<ITensorHandle> NeonWorkloadFactory::CreateTensorHandle(const Ten std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateAbs(const AbsQueueDescriptor& descriptor, const WorkloadInfo& info) const { - return std::make_unique<NeonAbsWorkload>(descriptor, info); + boost::ignore_unused(descriptor); + + ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor; + elementwiseUnaryDescriptor.m_Parameters = ElementwiseUnaryDescriptor(UnaryOperation::Abs); + + return CreateElementwiseUnary(elementwiseUnaryDescriptor, info); } std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& descriptor, @@ -214,6 +219,29 @@ std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateDivision( return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info); } +std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateElementwiseUnary(const ElementwiseUnaryQueueDescriptor& + descriptor, + const WorkloadInfo& info) const +{ + if (descriptor.m_Parameters.m_Operation == UnaryOperation::Abs) + { + AbsQueueDescriptor absQueueDescriptor; + absQueueDescriptor.m_Inputs = descriptor.m_Inputs; + absQueueDescriptor.m_Outputs = descriptor.m_Outputs; + + return std::make_unique<NeonAbsWorkload>(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 std::make_unique<NeonRsqrtWorkload>(rsqrtQueueDescriptor, info); + } + return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info); +} + std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateEqual(const EqualQueueDescriptor& descriptor, const WorkloadInfo& info) const { @@ -418,7 +446,12 @@ std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateResizeBilinear( std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateRsqrt(const RsqrtQueueDescriptor &descriptor, const WorkloadInfo &info) const { - return std::make_unique<NeonRsqrtWorkload>(descriptor, info); + boost::ignore_unused(descriptor); + + ElementwiseUnaryQueueDescriptor elementwiseUnaryDescriptor; + elementwiseUnaryDescriptor.m_Parameters = ElementwiseUnaryDescriptor(UnaryOperation::Rsqrt); + + return CreateElementwiseUnary(elementwiseUnaryDescriptor, info); } std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateSlice(const SliceQueueDescriptor& descriptor, diff --git a/src/backends/neon/NeonWorkloadFactory.hpp b/src/backends/neon/NeonWorkloadFactory.hpp index b76a3a340a..44c0629ece 100644 --- a/src/backends/neon/NeonWorkloadFactory.hpp +++ b/src/backends/neon/NeonWorkloadFactory.hpp @@ -39,6 +39,7 @@ public: DataLayout dataLayout, const bool IsMemoryManaged = true) const override; + ARMNN_DEPRECATED_MSG("Use CreateElementwiseUnary instead") std::unique_ptr<IWorkload> CreateAbs(const AbsQueueDescriptor& descriptor, const WorkloadInfo& info) const override; @@ -92,6 +93,9 @@ public: std::unique_ptr<IWorkload> CreateDivision(const DivisionQueueDescriptor& descriptor, const WorkloadInfo& info) const override; + + std::unique_ptr<IWorkload> CreateElementwiseUnary(const ElementwiseUnaryQueueDescriptor& descriptor, + const WorkloadInfo& Info) const override; ARMNN_DEPRECATED_MSG("Use CreateComparison instead") std::unique_ptr<IWorkload> CreateEqual(const EqualQueueDescriptor& descriptor, @@ -181,6 +185,7 @@ public: std::unique_ptr<IWorkload> CreateResizeBilinear(const ResizeBilinearQueueDescriptor& descriptor, const WorkloadInfo& info) const override; + ARMNN_DEPRECATED_MSG("Use CreateElementwiseUnary instead") std::unique_ptr<IWorkload> CreateRsqrt(const RsqrtQueueDescriptor& descriptor, const WorkloadInfo& info) const override; diff --git a/src/backends/neon/test/NeonCreateWorkloadTests.cpp b/src/backends/neon/test/NeonCreateWorkloadTests.cpp index a08c8f7d2a..400a5a38e2 100644 --- a/src/backends/neon/test/NeonCreateWorkloadTests.cpp +++ b/src/backends/neon/test/NeonCreateWorkloadTests.cpp @@ -181,36 +181,6 @@ BOOST_AUTO_TEST_CASE(CreateMultiplicationUint8Workload) DataType::QAsymmU8>(); } -template <typename WorkloadType, - typename DescriptorType, - typename LayerType, - armnn::DataType DataType> -static void NeonCreateElementwiseUnaryWorkloadTest() -{ - Graph graph; - NeonWorkloadFactory factory = - NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager()); - - auto workload = CreateElementwiseUnaryWorkloadTest - <WorkloadType, DescriptorType, LayerType, DataType>(factory, graph); - - DescriptorType queueDescriptor = workload->GetData(); - - auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]); - auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]); - - BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({2, 3}, DataType))); - BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({2, 3}, DataType))); -} - -BOOST_AUTO_TEST_CASE(CreateRsqrtFloat32Workload) -{ - NeonCreateElementwiseUnaryWorkloadTest<NeonRsqrtWorkload, - RsqrtQueueDescriptor, - RsqrtLayer, - DataType::Float32>(); -} - template <typename BatchNormalizationWorkloadType, typename armnn::DataType DataType> static void NeonCreateBatchNormalizationWorkloadTest(DataLayout dataLayout) { diff --git a/src/backends/neon/test/NeonEndToEndTests.cpp b/src/backends/neon/test/NeonEndToEndTests.cpp index e1c929b17b..4e9fe0f3c3 100644 --- a/src/backends/neon/test/NeonEndToEndTests.cpp +++ b/src/backends/neon/test/NeonEndToEndTests.cpp @@ -5,13 +5,13 @@ #include <backendsCommon/test/EndToEndTestImpl.hpp> -#include <backendsCommon/test/AbsEndToEndTestImpl.hpp> #include <backendsCommon/test/ArgMinMaxEndToEndTestImpl.hpp> #include <backendsCommon/test/ComparisonEndToEndTestImpl.hpp> #include <backendsCommon/test/ConcatEndToEndTestImpl.hpp> #include <backendsCommon/test/DepthToSpaceEndToEndTestImpl.hpp> #include <backendsCommon/test/DequantizeEndToEndTestImpl.hpp> #include <backendsCommon/test/DetectionPostProcessEndToEndTestImpl.hpp> +#include <backendsCommon/test/ElementwiseUnaryEndToEndTestImpl.hpp> #include <backendsCommon/test/InstanceNormalizationEndToEndTestImpl.hpp> #include <backendsCommon/test/PreluEndToEndTestImpl.hpp> #include <backendsCommon/test/QuantizedLstmEndToEndTestImpl.hpp> @@ -28,7 +28,15 @@ std::vector<armnn::BackendId> defaultBackends = {armnn::Compute::CpuAcc}; // Abs BOOST_AUTO_TEST_CASE(NeonAbsEndToEndTestFloat32) { - AbsEndToEnd<armnn::DataType::Float32>(defaultBackends); + std::vector<float> expectedOutput = + { + 1.f, 1.f, 1.f, 1.f, 5.f, 5.f, 5.f, 5.f, + 3.f, 3.f, 3.f, 3.f, 4.f, 4.f, 4.f, 4.f + }; + + ElementwiseUnarySimpleEndToEnd<armnn::DataType::Float32>(defaultBackends, + UnaryOperation::Abs, + expectedOutput); } // Constant |