diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/armnn/test/CreateWorkload.hpp | 37 | ||||
-rw-r--r-- | src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.cpp | 4 | ||||
-rw-r--r-- | src/backends/neon/NeonLayerSupport.cpp | 9 | ||||
-rw-r--r-- | src/backends/neon/NeonLayerSupport.hpp | 7 | ||||
-rw-r--r-- | src/backends/neon/NeonWorkloadFactory.cpp | 14 | ||||
-rw-r--r-- | src/backends/neon/NeonWorkloadFactory.hpp | 5 | ||||
-rw-r--r-- | src/backends/neon/backend.mk | 3 | ||||
-rw-r--r-- | src/backends/neon/test/NeonCreateWorkloadTests.cpp | 33 | ||||
-rw-r--r-- | src/backends/neon/test/NeonLayerTests.cpp | 3 | ||||
-rw-r--r-- | src/backends/neon/workloads/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/backends/neon/workloads/NeonLogSoftmaxWorkload.cpp | 53 | ||||
-rw-r--r-- | src/backends/neon/workloads/NeonLogSoftmaxWorkload.hpp | 36 | ||||
-rw-r--r-- | src/backends/neon/workloads/NeonWorkloads.hpp | 3 |
13 files changed, 198 insertions, 13 deletions
diff --git a/src/armnn/test/CreateWorkload.hpp b/src/armnn/test/CreateWorkload.hpp index f484a21f48..aad6244c4b 100644 --- a/src/armnn/test/CreateWorkload.hpp +++ b/src/armnn/test/CreateWorkload.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd. All rights reserved. +// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once @@ -1262,6 +1262,41 @@ std::unique_ptr<BatchToSpaceNdWorkload> CreateBatchToSpaceNdWorkloadTest(armnn:: return workload; } +template <typename LogSoftmaxWorkload, armnn::DataType DataType> +std::unique_ptr<LogSoftmaxWorkload> CreateLogSoftmaxWorkloadTest(armnn::IWorkloadFactory& factory, + armnn::Graph& graph) +{ + // Create the layer we're testing. + LogSoftmaxDescriptor logSoftmaxDescriptor; + // Set Axis to 1 if CL or Neon until further Axes are supported. + if (factory.GetBackendId() == armnn::Compute::CpuAcc || factory.GetBackendId() == armnn::Compute::GpuAcc) + { + logSoftmaxDescriptor.m_Axis = 0; + } + + Layer* const layer = graph.AddLayer<LogSoftmaxLayer>(logSoftmaxDescriptor, "layer"); + // Create extra layers. + Layer* const input = graph.AddLayer<InputLayer>(0, "input"); + Layer* const output = graph.AddLayer<OutputLayer>(0, "output"); + + // Connect up + armnn::TensorInfo tensorInfo({4, 1}, DataType); + + Connect(input, layer, tensorInfo); + Connect(layer, output, tensorInfo); + CreateTensorHandles(graph, factory); + + // Make the workload and checks it. + auto workload = MakeAndCheckWorkload<LogSoftmaxWorkload>(*layer, factory); + + LogSoftmaxQueueDescriptor queueDescriptor = workload->GetData(); + BOOST_TEST(queueDescriptor.m_Inputs.size() == 1); + BOOST_TEST(queueDescriptor.m_Outputs.size() == 1); + + // Return so we can do extra, backend-specific tests. + return workload; +} + template <typename L2NormalizationWorkload, armnn::DataType DataType> std::unique_ptr<L2NormalizationWorkload> CreateL2NormalizationWorkloadTest(armnn::IWorkloadFactory& factory, armnn::Graph& graph, DataLayout dataLayout = DataLayout::NCHW) diff --git a/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.cpp index 208bed24a5..9ccca84bfc 100644 --- a/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.cpp +++ b/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.cpp @@ -1,5 +1,5 @@ // -// Copyright © 2019 Arm Ltd. All rights reserved. +// Copyright © 2019 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -57,7 +57,7 @@ LayerTestResult<T, NumDims> LogSoftmaxTestImpl( auto inputTensor = MakeTensor<T, NumDims>(inputInfo, armnnUtils::QuantizedVector<T>(inputValues, qScale, qOffset)); CopyDataToITensorHandle(inputHandle.get(), inputTensor.origin()); - workload->Execute(); + ExecuteWorkload(*workload, memoryManager); CopyDataFromITensorHandle(result.output.origin(), outputHandle.get()); diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp index f6b3b7627a..b848f0c10f 100644 --- a/src/backends/neon/NeonLayerSupport.cpp +++ b/src/backends/neon/NeonLayerSupport.cpp @@ -34,6 +34,7 @@ #include "workloads/NeonDequantizeWorkload.hpp" #include "workloads/NeonInstanceNormalizationWorkload.hpp" #include "workloads/NeonL2NormalizationFloatWorkload.hpp" +#include "workloads/NeonLogSoftmaxWorkload.hpp" #include "workloads/NeonLstmFloatWorkload.hpp" #include "workloads/NeonMaximumWorkload.hpp" #include "workloads/NeonMeanWorkload.hpp" @@ -493,6 +494,14 @@ bool NeonLayerSupport::IsL2NormalizationSupported(const TensorInfo& input, FORWARD_WORKLOAD_VALIDATE_FUNC(NeonL2NormalizationWorkloadValidate, reasonIfUnsupported, input, output, descriptor); } +bool NeonLayerSupport::IsLogSoftmaxSupported(const TensorInfo& input, + const TensorInfo& output, + const LogSoftmaxDescriptor& descriptor, + Optional<std::string&> reasonIfUnsupported) const +{ + FORWARD_WORKLOAD_VALIDATE_FUNC(NeonLogSoftmaxWorkloadValidate, reasonIfUnsupported, input, output, descriptor); +} + bool NeonLayerSupport::IsLstmSupported(const TensorInfo& input, const TensorInfo& outputStateIn, const TensorInfo& cellStateIn, diff --git a/src/backends/neon/NeonLayerSupport.hpp b/src/backends/neon/NeonLayerSupport.hpp index aff62d18d7..bdc905d17e 100644 --- a/src/backends/neon/NeonLayerSupport.hpp +++ b/src/backends/neon/NeonLayerSupport.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd. All rights reserved. +// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once @@ -153,6 +153,11 @@ public: const L2NormalizationDescriptor& descriptor, Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; + bool IsLogSoftmaxSupported(const TensorInfo& input, + const TensorInfo& output, + const LogSoftmaxDescriptor& descriptor, + Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; + bool IsLstmSupported(const TensorInfo& input, const TensorInfo& outputStateIn, const TensorInfo& cellStateIn, diff --git a/src/backends/neon/NeonWorkloadFactory.cpp b/src/backends/neon/NeonWorkloadFactory.cpp index 34f8445f95..40010fe329 100644 --- a/src/backends/neon/NeonWorkloadFactory.cpp +++ b/src/backends/neon/NeonWorkloadFactory.cpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd. All rights reserved. +// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -320,6 +320,12 @@ std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateL2Normalization(const L2No m_MemoryManager->GetIntraLayerManager()); } +std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLogSoftmax(const LogSoftmaxQueueDescriptor& descriptor, + const WorkloadInfo& info) const +{ + return std::make_unique<NeonLogSoftmaxWorkload>(descriptor, info, m_MemoryManager->GetIntraLayerManager()); +} + std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateLstm(const LstmQueueDescriptor& descriptor, const WorkloadInfo& info) const { @@ -386,7 +392,7 @@ std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateNormalization( } std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor, - const WorkloadInfo& info) const + const WorkloadInfo& info) const { return std::make_unique<CopyMemGenericWorkload>(descriptor, info); } @@ -398,13 +404,13 @@ std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePad(const PadQueueDescript } std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& descriptor, - const WorkloadInfo& info) const + const WorkloadInfo& info) const { return std::make_unique<NeonPermuteWorkload>(descriptor, info); } std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& descriptor, - const WorkloadInfo& info) const + const WorkloadInfo& info) const { return std::make_unique<NeonPooling2dWorkload>(descriptor, info); } diff --git a/src/backends/neon/NeonWorkloadFactory.hpp b/src/backends/neon/NeonWorkloadFactory.hpp index de49146f10..b4767f1ec7 100644 --- a/src/backends/neon/NeonWorkloadFactory.hpp +++ b/src/backends/neon/NeonWorkloadFactory.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd. All rights reserved. +// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once @@ -131,6 +131,9 @@ public: std::unique_ptr<IWorkload> CreateL2Normalization(const L2NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const override; + std::unique_ptr<IWorkload> CreateLogSoftmax(const LogSoftmaxQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + std::unique_ptr<IWorkload> CreateLstm(const LstmQueueDescriptor& descriptor, const WorkloadInfo& info) const override; diff --git a/src/backends/neon/backend.mk b/src/backends/neon/backend.mk index 72d1ab3a92..aeee9154ad 100644 --- a/src/backends/neon/backend.mk +++ b/src/backends/neon/backend.mk @@ -1,5 +1,5 @@ # -# Copyright © 2017 ARM Ltd. All rights reserved. +# Copyright © 2017 ARM Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # @@ -46,6 +46,7 @@ BACKEND_SOURCES := \ workloads/NeonGatherWorkload.cpp \ workloads/NeonInstanceNormalizationWorkload.cpp \ workloads/NeonL2NormalizationFloatWorkload.cpp \ + workloads/NeonLogSoftmaxWorkload.cpp \ workloads/NeonLstmFloatWorkload.cpp \ workloads/NeonMaximumWorkload.cpp \ workloads/NeonMeanWorkload.cpp \ diff --git a/src/backends/neon/test/NeonCreateWorkloadTests.cpp b/src/backends/neon/test/NeonCreateWorkloadTests.cpp index 73491c7810..37d026f107 100644 --- a/src/backends/neon/test/NeonCreateWorkloadTests.cpp +++ b/src/backends/neon/test/NeonCreateWorkloadTests.cpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd. All rights reserved. +// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -813,6 +813,37 @@ BOOST_AUTO_TEST_CASE(CreateL2NormalizationNhwcWorkload) NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC); } +template <typename LogSoftmaxWorkloadType, typename armnn::DataType DataType> +static void NeonCreateLogSoftmaxWorkloadTest() +{ + Graph graph; + NeonWorkloadFactory factory = + NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager()); + + auto workload = CreateLogSoftmaxWorkloadTest<LogSoftmaxWorkloadType, DataType>(factory, graph); + + // Checks that outputs and inputs are as we expect them (see definition of CreateLogSoftmaxWorkloadTest). + LogSoftmaxQueueDescriptor queueDescriptor = workload->GetData(); + auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]); + auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]); + armnn::TensorInfo tensorInfo({4, 1}, DataType); + + BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, tensorInfo)); + BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, tensorInfo)); +} + +#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC +BOOST_AUTO_TEST_CASE(CreateLogSoftmaxFloat16Workload) +{ + NeonCreateLogSoftmaxWorkloadTest<NeonLogSoftmaxWorkload, DataType::Float16>(); +} +#endif + +BOOST_AUTO_TEST_CASE(CreateLogSoftmaxFloatWorkload) +{ + NeonCreateLogSoftmaxWorkloadTest<NeonLogSoftmaxWorkload, DataType::Float32>(); +} + template <typename LstmWorkloadType> static void NeonCreateLstmWorkloadTest() { diff --git a/src/backends/neon/test/NeonLayerTests.cpp b/src/backends/neon/test/NeonLayerTests.cpp index de4a305b0f..514ca5d371 100644 --- a/src/backends/neon/test/NeonLayerTests.cpp +++ b/src/backends/neon/test/NeonLayerTests.cpp @@ -506,6 +506,9 @@ ARMNN_AUTO_TEST_CASE(Simple3dSoftmaxBeta1Uint8, Simple3dSoftmaxUint8Test, 1.0f) ARMNN_AUTO_TEST_CASE(Simple4dSoftmaxBeta1, Simple4dSoftmaxTest, 1.0f) ARMNN_AUTO_TEST_CASE(Simple4dSoftmaxBeta1Uint8, Simple4dSoftmaxUint8Test, 1.0f) +// LogSoftmax +ARMNN_AUTO_TEST_CASE(LogSoftmaxFloat32_1, LogSoftmaxTest1<DataType::Float32>) + // Space To Batch Nd ARMNN_AUTO_TEST_CASE(SpaceToBatchNdSimpleFloat32, SpaceToBatchNdSimpleFloat32Test) ARMNN_AUTO_TEST_CASE(SpaceToBatchNdMultiChannelsFloat32, SpaceToBatchNdMultiChannelsFloat32Test) diff --git a/src/backends/neon/workloads/CMakeLists.txt b/src/backends/neon/workloads/CMakeLists.txt index e3b74f665f..ca9497e393 100644 --- a/src/backends/neon/workloads/CMakeLists.txt +++ b/src/backends/neon/workloads/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright © 2017 Arm Ltd. All rights reserved. +# Copyright © 2017 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # @@ -56,6 +56,8 @@ list(APPEND armnnNeonBackendWorkloads_sources NeonL2NormalizationFloatWorkload.hpp NeonLstmFloatWorkload.cpp NeonLstmFloatWorkload.hpp + NeonLogSoftmaxWorkload.cpp + NeonLogSoftmaxWorkload.hpp NeonMaximumWorkload.cpp NeonMaximumWorkload.hpp NeonMeanWorkload.cpp diff --git a/src/backends/neon/workloads/NeonLogSoftmaxWorkload.cpp b/src/backends/neon/workloads/NeonLogSoftmaxWorkload.cpp new file mode 100644 index 0000000000..058756e9af --- /dev/null +++ b/src/backends/neon/workloads/NeonLogSoftmaxWorkload.cpp @@ -0,0 +1,53 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "NeonLogSoftmaxWorkload.hpp" +#include "NeonWorkloadUtils.hpp" + +#include <armnn/utility/PolymorphicDowncast.hpp> + +#include <aclCommon/ArmComputeUtils.hpp> +#include <aclCommon/ArmComputeTensorUtils.hpp> + +#include <arm_compute/runtime/NEON/functions/NESoftmaxLayer.h> + +namespace armnn +{ + +arm_compute::Status NeonLogSoftmaxWorkloadValidate(const TensorInfo& input, + const TensorInfo& output, + const LogSoftmaxDescriptor& descriptor) +{ + const arm_compute::TensorInfo aclInputInfo = armcomputetensorutils::BuildArmComputeTensorInfo(input); + const arm_compute::TensorInfo aclOutputInfo = armcomputetensorutils::BuildArmComputeTensorInfo(output); + + int aclAxis = ComputeSoftmaxAclAxis<int>(descriptor, input); + return arm_compute::NELogSoftmaxLayer::validate(&aclInputInfo, &aclOutputInfo, descriptor.m_Beta, aclAxis); +} + +NeonLogSoftmaxWorkload::NeonLogSoftmaxWorkload(const LogSoftmaxQueueDescriptor& descriptor, + const WorkloadInfo& info, + std::shared_ptr<arm_compute::MemoryManagerOnDemand>& memoryManager) + : BaseWorkload<LogSoftmaxQueueDescriptor>(descriptor, info) +{ + m_Data.ValidateInputsOutputs("NeonLogSoftmaxWorkload", 1, 1); + + arm_compute::ITensor& input = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Inputs[0])->GetTensor(); + arm_compute::ITensor& output = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Outputs[0])->GetTensor(); + + auto layer = std::make_unique<arm_compute::NELogSoftmaxLayer>(memoryManager); + int aclAxis = ComputeSoftmaxAclAxis<int>(m_Data.m_Parameters, info.m_InputTensorInfos[0]); + layer->configure(&input, &output, m_Data.m_Parameters.m_Beta, aclAxis); + m_LogSoftmaxLayer.reset(layer.release()); +} + +void NeonLogSoftmaxWorkload::Execute() const +{ + ARMNN_SCOPED_PROFILING_EVENT_NEON("NeonLogSoftmaxWorkload_Execute"); + m_LogSoftmaxLayer->run(); +} + +} //namespace armnn + diff --git a/src/backends/neon/workloads/NeonLogSoftmaxWorkload.hpp b/src/backends/neon/workloads/NeonLogSoftmaxWorkload.hpp new file mode 100644 index 0000000000..dbfa28dd11 --- /dev/null +++ b/src/backends/neon/workloads/NeonLogSoftmaxWorkload.hpp @@ -0,0 +1,36 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include <armnn/Descriptors.hpp> +#include <backendsCommon/Workload.hpp> + +#include <arm_compute/core/Error.h> +#include <arm_compute/runtime/IFunction.h> +#include <arm_compute/runtime/MemoryManagerOnDemand.h> + +#include <memory> + +namespace armnn +{ + +arm_compute::Status NeonLogSoftmaxWorkloadValidate(const TensorInfo& input, + const TensorInfo& output, + const LogSoftmaxDescriptor& descriptor); + +class NeonLogSoftmaxWorkload : public BaseWorkload<LogSoftmaxQueueDescriptor> +{ +public: + NeonLogSoftmaxWorkload(const LogSoftmaxQueueDescriptor& descriptor, const WorkloadInfo& info, + std::shared_ptr<arm_compute::MemoryManagerOnDemand>& memoryManager); + virtual void Execute() const override; + +private: + std::unique_ptr<arm_compute::IFunction> m_LogSoftmaxLayer; +}; + +} //namespace armnn + diff --git a/src/backends/neon/workloads/NeonWorkloads.hpp b/src/backends/neon/workloads/NeonWorkloads.hpp index c1bc4cca29..590b6f7a29 100644 --- a/src/backends/neon/workloads/NeonWorkloads.hpp +++ b/src/backends/neon/workloads/NeonWorkloads.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd. All rights reserved. +// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -30,6 +30,7 @@ #include "NeonGatherWorkload.hpp" #include "NeonInstanceNormalizationWorkload.hpp" #include "NeonL2NormalizationFloatWorkload.hpp" +#include "NeonLogSoftmaxWorkload.hpp" #include "NeonLstmFloatWorkload.hpp" #include "NeonMaximumWorkload.hpp" #include "NeonMeanWorkload.hpp" |