From 4e3e818e1ea73544f3aec4e2ac2621a1c3380b54 Mon Sep 17 00:00:00 2001 From: Narumol Prangnawarat Date: Wed, 14 Aug 2019 12:25:50 +0100 Subject: IVGCVSW-3622 Add Neon TensorHandleFactory Signed-off-by: James Conroy Signed-off-by: Narumol Prangnawarat Change-Id: I9f24f7d97c1e7d37ee7d58ff85c6c3f8496e52ec --- src/armnn/test/TensorHandleStrategyTest.cpp | 12 ++++ .../backendsCommon/ITensorHandleFactory.hpp | 3 + src/backends/neon/CMakeLists.txt | 2 + src/backends/neon/NeonBackend.cpp | 26 +++++++ src/backends/neon/NeonBackend.hpp | 7 ++ src/backends/neon/NeonTensorHandleFactory.cpp | 79 ++++++++++++++++++++++ src/backends/neon/NeonTensorHandleFactory.hpp | 46 +++++++++++++ src/backends/neon/backend.mk | 1 + 8 files changed, 176 insertions(+) create mode 100644 src/backends/neon/NeonTensorHandleFactory.cpp create mode 100644 src/backends/neon/NeonTensorHandleFactory.hpp diff --git a/src/armnn/test/TensorHandleStrategyTest.cpp b/src/armnn/test/TensorHandleStrategyTest.cpp index c391b04d97..2056b6fca1 100644 --- a/src/armnn/test/TensorHandleStrategyTest.cpp +++ b/src/armnn/test/TensorHandleStrategyTest.cpp @@ -50,6 +50,12 @@ public: return nullptr; } + std::unique_ptr CreateTensorHandle(const TensorInfo& tensorInfo, + DataLayout dataLayout) const override + { + return nullptr; + } + const FactoryId GetId() const override { return m_Id; } bool SupportsSubTensors() const override { return true; } @@ -82,6 +88,12 @@ public: return nullptr; } + std::unique_ptr CreateTensorHandle(const TensorInfo& tensorInfo, + DataLayout dataLayout) const override + { + return nullptr; + } + const FactoryId GetId() const override { return m_Id; } bool SupportsSubTensors() const override { return true; } diff --git a/src/backends/backendsCommon/ITensorHandleFactory.hpp b/src/backends/backendsCommon/ITensorHandleFactory.hpp index 89a2a7fa3b..9e61b5f1ed 100644 --- a/src/backends/backendsCommon/ITensorHandleFactory.hpp +++ b/src/backends/backendsCommon/ITensorHandleFactory.hpp @@ -27,6 +27,9 @@ public: virtual std::unique_ptr CreateTensorHandle(const TensorInfo& tensorInfo) const = 0; + virtual std::unique_ptr CreateTensorHandle(const TensorInfo& tensorInfo, + DataLayout dataLayout) const = 0; + virtual const FactoryId GetId() const = 0; virtual bool SupportsSubTensors() const = 0; diff --git a/src/backends/neon/CMakeLists.txt b/src/backends/neon/CMakeLists.txt index be318e9854..7464a2e623 100644 --- a/src/backends/neon/CMakeLists.txt +++ b/src/backends/neon/CMakeLists.txt @@ -15,6 +15,8 @@ if(ARMCOMPUTENEON) NeonWorkloadFactory.cpp NeonWorkloadFactory.hpp NeonTensorHandle.hpp + NeonTensorHandleFactory.cpp + NeonTensorHandleFactory.hpp NeonTimer.hpp NeonTimer.cpp ) diff --git a/src/backends/neon/NeonBackend.cpp b/src/backends/neon/NeonBackend.cpp index d7be844c21..f86509cbe6 100644 --- a/src/backends/neon/NeonBackend.cpp +++ b/src/backends/neon/NeonBackend.cpp @@ -7,6 +7,7 @@ #include "NeonBackendId.hpp" #include "NeonWorkloadFactory.hpp" #include "NeonLayerSupport.hpp" +#include "NeonTensorHandleFactory.hpp" #include @@ -58,6 +59,17 @@ IBackendInternal::IWorkloadFactoryPtr NeonBackend::CreateWorkloadFactory( boost::polymorphic_pointer_downcast(memoryManager)); } +IBackendInternal::IWorkloadFactoryPtr NeonBackend::CreateWorkloadFactory( + class TensorHandleFactoryRegistry& tensorHandleFactoryRegistry) const +{ + auto memoryManager = std::make_shared(std::make_unique(), + BaseMemoryManager::MemoryAffinity::Offset); + + tensorHandleFactoryRegistry.RegisterMemoryManager(memoryManager); + return std::make_unique( + boost::polymorphic_pointer_downcast(memoryManager)); +} + IBackendInternal::IBackendContextPtr NeonBackend::CreateBackendContext(const IRuntime::CreationOptions&) const { return IBackendContextPtr{}; @@ -83,4 +95,18 @@ OptimizationViews NeonBackend::OptimizeSubgraphView(const SubgraphView& subgraph return optimizationViews; } +std::vector NeonBackend::GetHandleFactoryPreferences() const +{ + return std::vector() = {"Arm/Neon/TensorHandleFactory"}; +} + +void NeonBackend::RegisterTensorHandleFactories(class TensorHandleFactoryRegistry& registry) +{ + auto memoryManager = std::make_shared(std::make_unique(), + BaseMemoryManager::MemoryAffinity::Offset); + + registry.RegisterMemoryManager(memoryManager); + registry.RegisterFactory(std::make_unique(memoryManager, "Arm/Neon/TensorHandleFactory")); +} + } // namespace armnn diff --git a/src/backends/neon/NeonBackend.hpp b/src/backends/neon/NeonBackend.hpp index 398337f775..49b03b0fee 100644 --- a/src/backends/neon/NeonBackend.hpp +++ b/src/backends/neon/NeonBackend.hpp @@ -23,12 +23,19 @@ public: IWorkloadFactoryPtr CreateWorkloadFactory( const IBackendInternal::IMemoryManagerSharedPtr& memoryManager = nullptr) const override; + IWorkloadFactoryPtr CreateWorkloadFactory( + class TensorHandleFactoryRegistry& tensorHandleFactoryRegistry) const override; + IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override; IBackendInternal::Optimizations GetOptimizations() const override; IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override; OptimizationViews OptimizeSubgraphView(const SubgraphView& subgraph) const override; + + std::vector GetHandleFactoryPreferences() const override; + + void RegisterTensorHandleFactories(class TensorHandleFactoryRegistry& registry) override; }; } // namespace armnn diff --git a/src/backends/neon/NeonTensorHandleFactory.cpp b/src/backends/neon/NeonTensorHandleFactory.cpp new file mode 100644 index 0000000000..ef342347d3 --- /dev/null +++ b/src/backends/neon/NeonTensorHandleFactory.cpp @@ -0,0 +1,79 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "NeonTensorHandleFactory.hpp" +#include "NeonTensorHandle.hpp" + +#include + +namespace armnn +{ + +using FactoryId = std::string; + +std::unique_ptr NeonTensorHandleFactory::CreateSubTensorHandle(ITensorHandle& parent, + TensorShape const& subTensorShape, + unsigned int const* subTensorOrigin) + const +{ + const arm_compute::TensorShape shape = armcomputetensorutils::BuildArmComputeTensorShape(subTensorShape); + + arm_compute::Coordinates coords; + coords.set_num_dimensions(subTensorShape.GetNumDimensions()); + for (unsigned int i = 0; i < subTensorShape.GetNumDimensions(); i++) + { + // Arm compute indexes tensor coords in reverse order. + unsigned int revertedIndex = subTensorShape.GetNumDimensions() - i - 1; + coords.set(i, boost::numeric_cast(subTensorOrigin[revertedIndex])); + } + + const arm_compute::TensorShape parentShape = armcomputetensorutils::BuildArmComputeTensorShape(parent.GetShape()); + if (!::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, parentShape, coords, shape)) + { + return nullptr; + } + + return std::make_unique( + boost::polymorphic_downcast(&parent), shape, coords); +} + +std::unique_ptr NeonTensorHandleFactory::CreateTensorHandle(const TensorInfo& tensorInfo) const +{ + auto tensorHandle = std::make_unique(tensorInfo); + tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup()); + + return tensorHandle; +} + +std::unique_ptr NeonTensorHandleFactory::CreateTensorHandle(const TensorInfo& tensorInfo, + DataLayout dataLayout) const +{ + auto tensorHandle = std::make_unique(tensorInfo, dataLayout); + tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup()); + + return tensorHandle; +} + +const FactoryId NeonTensorHandleFactory::GetId() const +{ + return m_Id; +} + +bool NeonTensorHandleFactory::SupportsSubTensors() const +{ + return true; +} + +MemorySourceFlags NeonTensorHandleFactory::GetExportFlags() const +{ + return m_ExportFlags; +} + +MemorySourceFlags NeonTensorHandleFactory::GetImportFlags() const +{ + return m_ImportFlags; +} + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/neon/NeonTensorHandleFactory.hpp b/src/backends/neon/NeonTensorHandleFactory.hpp new file mode 100644 index 0000000000..a2e46e22e9 --- /dev/null +++ b/src/backends/neon/NeonTensorHandleFactory.hpp @@ -0,0 +1,46 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include +#include + +namespace armnn +{ + +class NeonTensorHandleFactory : public ITensorHandleFactory +{ +public: + NeonTensorHandleFactory(std::weak_ptr mgr, ITensorHandleFactory::FactoryId id) + : m_Id(id) + , m_MemoryManager(mgr) + {} + + std::unique_ptr CreateSubTensorHandle(ITensorHandle& parent, + TensorShape const& subTensorShape, + unsigned int const* subTensorOrigin) const override; + + std::unique_ptr CreateTensorHandle(const TensorInfo& tensorInfo) const override; + + std::unique_ptr CreateTensorHandle(const TensorInfo& tensorInfo, + DataLayout dataLayout) const override; + + const FactoryId GetId() const override; + + bool SupportsSubTensors() const override; + + MemorySourceFlags GetExportFlags() const override; + + MemorySourceFlags GetImportFlags() const override; + +private: + FactoryId m_Id = "Arm/Neon/TensorHandleFactory"; + MemorySourceFlags m_ImportFlags; + MemorySourceFlags m_ExportFlags; + mutable std::shared_ptr m_MemoryManager; +}; + +} // namespace armnn diff --git a/src/backends/neon/backend.mk b/src/backends/neon/backend.mk index 7fc0c1c57f..4a0d05ecdd 100644 --- a/src/backends/neon/backend.mk +++ b/src/backends/neon/backend.mk @@ -17,6 +17,7 @@ BACKEND_SOURCES := \ NeonBackend.cpp \ NeonInterceptorScheduler.cpp \ NeonLayerSupport.cpp \ + NeonTensorHandleFactory.cpp \ NeonTimer.cpp \ NeonWorkloadFactory.cpp \ workloads/NeonActivationWorkload.cpp \ -- cgit v1.2.1