From f9aeef0e036df176699aa96d30d2ca8d7546534e Mon Sep 17 00:00:00 2001 From: Aron Virginas-Tar Date: Fri, 12 Oct 2018 15:18:03 +0100 Subject: IVGCVSW-2006: Move ACL memory manager source code under aclCommon Change-Id: Ie1c74a18de5c3dd1cd5285c222bd6327489c1508 --- Android.mk | 8 +- CMakeLists.txt | 17 --- src/armnn/memory/BaseMemoryManager.cpp | 125 --------------------- src/armnn/memory/BaseMemoryManager.hpp | 104 ----------------- src/armnn/memory/BlobLifetimeManager.cpp | 79 ------------- src/armnn/memory/BlobLifetimeManager.hpp | 35 ------ src/armnn/memory/BlobMemoryPool.cpp | 88 --------------- src/armnn/memory/BlobMemoryPool.hpp | 55 --------- src/armnn/memory/IMemoryPool.hpp | 22 ---- src/armnn/memory/IPoolManager.hpp | 21 ---- src/armnn/memory/OffsetLifetimeManager.cpp | 62 ---------- src/armnn/memory/OffsetLifetimeManager.hpp | 37 ------ src/armnn/memory/OffsetMemoryPool.cpp | 84 -------------- src/armnn/memory/OffsetMemoryPool.hpp | 54 --------- src/armnn/memory/PoolManager.cpp | 105 ----------------- src/armnn/memory/PoolManager.hpp | 56 --------- src/backends/aclCommon/CMakeLists.txt | 14 +++ src/backends/aclCommon/common.mk | 9 +- .../aclCommon/memory/BaseMemoryManager.cpp | 125 +++++++++++++++++++++ .../aclCommon/memory/BaseMemoryManager.hpp | 104 +++++++++++++++++ .../aclCommon/memory/BlobLifetimeManager.cpp | 79 +++++++++++++ .../aclCommon/memory/BlobLifetimeManager.hpp | 35 ++++++ src/backends/aclCommon/memory/BlobMemoryPool.cpp | 88 +++++++++++++++ src/backends/aclCommon/memory/BlobMemoryPool.hpp | 55 +++++++++ src/backends/aclCommon/memory/IMemoryPool.hpp | 22 ++++ src/backends/aclCommon/memory/IPoolManager.hpp | 21 ++++ .../aclCommon/memory/OffsetLifetimeManager.cpp | 62 ++++++++++ .../aclCommon/memory/OffsetLifetimeManager.hpp | 37 ++++++ src/backends/aclCommon/memory/OffsetMemoryPool.cpp | 84 ++++++++++++++ src/backends/aclCommon/memory/OffsetMemoryPool.hpp | 54 +++++++++ src/backends/aclCommon/memory/PoolManager.cpp | 105 +++++++++++++++++ src/backends/aclCommon/memory/PoolManager.hpp | 57 ++++++++++ src/backends/cl/ClWorkloadFactory.cpp | 2 +- src/backends/cl/ClWorkloadFactory.hpp | 6 +- src/backends/cl/OpenClTimer.hpp | 2 +- src/backends/neon/NeonWorkloadFactory.cpp | 2 +- src/backends/neon/NeonWorkloadFactory.hpp | 3 +- 37 files changed, 958 insertions(+), 960 deletions(-) delete mode 100644 src/armnn/memory/BaseMemoryManager.cpp delete mode 100644 src/armnn/memory/BaseMemoryManager.hpp delete mode 100644 src/armnn/memory/BlobLifetimeManager.cpp delete mode 100644 src/armnn/memory/BlobLifetimeManager.hpp delete mode 100644 src/armnn/memory/BlobMemoryPool.cpp delete mode 100644 src/armnn/memory/BlobMemoryPool.hpp delete mode 100644 src/armnn/memory/IMemoryPool.hpp delete mode 100644 src/armnn/memory/IPoolManager.hpp delete mode 100644 src/armnn/memory/OffsetLifetimeManager.cpp delete mode 100644 src/armnn/memory/OffsetLifetimeManager.hpp delete mode 100644 src/armnn/memory/OffsetMemoryPool.cpp delete mode 100644 src/armnn/memory/OffsetMemoryPool.hpp delete mode 100644 src/armnn/memory/PoolManager.cpp delete mode 100644 src/armnn/memory/PoolManager.hpp create mode 100644 src/backends/aclCommon/memory/BaseMemoryManager.cpp create mode 100644 src/backends/aclCommon/memory/BaseMemoryManager.hpp create mode 100644 src/backends/aclCommon/memory/BlobLifetimeManager.cpp create mode 100644 src/backends/aclCommon/memory/BlobLifetimeManager.hpp create mode 100644 src/backends/aclCommon/memory/BlobMemoryPool.cpp create mode 100644 src/backends/aclCommon/memory/BlobMemoryPool.hpp create mode 100644 src/backends/aclCommon/memory/IMemoryPool.hpp create mode 100644 src/backends/aclCommon/memory/IPoolManager.hpp create mode 100644 src/backends/aclCommon/memory/OffsetLifetimeManager.cpp create mode 100644 src/backends/aclCommon/memory/OffsetLifetimeManager.hpp create mode 100644 src/backends/aclCommon/memory/OffsetMemoryPool.cpp create mode 100644 src/backends/aclCommon/memory/OffsetMemoryPool.hpp create mode 100644 src/backends/aclCommon/memory/PoolManager.cpp create mode 100644 src/backends/aclCommon/memory/PoolManager.hpp diff --git a/Android.mk b/Android.mk index 87fec7b309..25ed834852 100644 --- a/Android.mk +++ b/Android.mk @@ -121,13 +121,7 @@ LOCAL_SRC_FILES := \ src/armnn/Tensor.cpp \ src/armnn/Utils.cpp \ src/armnn/LayerSupport.cpp \ - src/armnn/Observable.cpp \ - src/armnn/memory/BaseMemoryManager.cpp \ - src/armnn/memory/BlobLifetimeManager.cpp \ - src/armnn/memory/BlobMemoryPool.cpp \ - src/armnn/memory/OffsetLifetimeManager.cpp \ - src/armnn/memory/OffsetMemoryPool.cpp \ - src/armnn/memory/PoolManager.cpp + src/armnn/Observable.cpp LOCAL_STATIC_LIBRARIES := \ armnn-arm_compute \ diff --git a/CMakeLists.txt b/CMakeLists.txt index 1956643fb7..22eeedde03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,23 +277,6 @@ list(APPEND armnn_sources src/armnn/Observable.cpp ) -if(ARMCOMPUTENEON OR ARMCOMPUTECL) - list(APPEND armnn_sources - src/armnn/memory/IMemoryPool.hpp - src/armnn/memory/BlobMemoryPool.cpp - src/armnn/memory/BlobMemoryPool.hpp - src/armnn/memory/BlobLifetimeManager.cpp - src/armnn/memory/BlobLifetimeManager.hpp - src/armnn/memory/PoolManager.cpp - src/armnn/memory/PoolManager.hpp - src/armnn/memory/BaseMemoryManager.hpp - src/armnn/memory/BaseMemoryManager.cpp - src/armnn/memory/OffsetMemoryPool.cpp - src/armnn/memory/OffsetMemoryPool.hpp - src/armnn/memory/OffsetLifetimeManager.cpp - src/armnn/memory/OffsetLifetimeManager.hpp) -endif() - # Files used for Streamline-based profiling backend if(PROFILING_BACKEND_STREAMLINE) list(APPEND armnn_sources diff --git a/src/armnn/memory/BaseMemoryManager.cpp b/src/armnn/memory/BaseMemoryManager.cpp deleted file mode 100644 index 041c042baa..0000000000 --- a/src/armnn/memory/BaseMemoryManager.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#include "BaseMemoryManager.hpp" - -#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED) -#include "memory/BlobLifetimeManager.hpp" -#include "memory/PoolManager.hpp" -#include "memory/OffsetLifetimeManager.hpp" -#endif - -#include - -namespace armnn -{ - -#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED) -BaseMemoryManager::BaseMemoryManager(std::unique_ptr alloc, - MemoryAffinity memoryAffinity) -{ - // (Re)create the memory manager components. - m_Allocator = std::move(alloc); - - m_IntraLayerMemoryMgr = CreateArmComputeMemoryManager(memoryAffinity); - m_InterLayerMemoryMgr = CreateArmComputeMemoryManager(memoryAffinity); -} - -std::shared_ptr -BaseMemoryManager::CreateArmComputeMemoryManager(MemoryAffinity memoryAffinity) -{ - std::shared_ptr lifetimeManager = nullptr; - - if (memoryAffinity == MemoryAffinity::Buffer) - { - lifetimeManager = std::make_shared(); - } - else - { - lifetimeManager = std::make_shared(); - } - - auto poolManager = std::make_shared(); - auto memoryManager = std::make_shared(lifetimeManager, poolManager); - - // Set allocator that the memory manager will use - memoryManager->set_allocator(m_Allocator.get()); - - return memoryManager; -} - -void BaseMemoryManager::FinalizeMemoryManager(arm_compute::MemoryManagerOnDemand& memoryManager) -{ - // Number of pools that the manager will create. This specifies how many layers you want to run in parallel - memoryManager.set_num_pools(1); - - // Finalize the memory manager. (Validity checks, memory allocations, etc) - memoryManager.finalize(); -} - -void BaseMemoryManager::Finalize() -{ - BOOST_ASSERT(m_IntraLayerMemoryMgr); - FinalizeMemoryManager(*m_IntraLayerMemoryMgr.get()); - - BOOST_ASSERT(m_InterLayerMemoryMgr); - FinalizeMemoryManager(*m_InterLayerMemoryMgr.get()); -} - -void BaseMemoryManager::Acquire() -{ - // Allocate memory pools for intra-layer memory manager - BOOST_ASSERT(m_IntraLayerMemoryMgr); - IPoolManager* poolManager = boost::polymorphic_downcast(m_IntraLayerMemoryMgr->pool_manager()); - BOOST_ASSERT(poolManager); - poolManager->AllocatePools(); - - // Allocate memory pools for inter-layer memory manager - BOOST_ASSERT(m_InterLayerMemoryMgr); - poolManager = boost::polymorphic_downcast(m_InterLayerMemoryMgr->pool_manager()); - BOOST_ASSERT(poolManager); - poolManager->AllocatePools(); - - // Acquire inter-layer memory group. NOTE: This has to come after allocating the pools - BOOST_ASSERT(m_InterLayerMemoryGroup); - m_InterLayerMemoryGroup->acquire(); -} - -void BaseMemoryManager::Release() -{ - // Release inter-layer memory group. NOTE: This has to come before releasing the pools - BOOST_ASSERT(m_InterLayerMemoryGroup); - m_InterLayerMemoryGroup->release(); - - // Release memory pools managed by intra-layer memory manager - BOOST_ASSERT(m_IntraLayerMemoryMgr); - IPoolManager* poolManager = boost::polymorphic_downcast(m_IntraLayerMemoryMgr->pool_manager()); - BOOST_ASSERT(poolManager); - poolManager->ReleasePools(); - - // Release memory pools managed by inter-layer memory manager - BOOST_ASSERT(m_InterLayerMemoryMgr); - poolManager = boost::polymorphic_downcast(m_InterLayerMemoryMgr->pool_manager()); - BOOST_ASSERT(poolManager); - poolManager->ReleasePools(); -} -#endif - -#ifdef ARMCOMPUTENEON_ENABLED -std::shared_ptr -NeonMemoryManager::CreateMemoryGroup(const std::shared_ptr& memoryManager) -{ - return std::make_shared(memoryManager); -} -#endif - -#ifdef ARMCOMPUTECL_ENABLED -std::shared_ptr -ClMemoryManager::CreateMemoryGroup(const std::shared_ptr& memoryManager) -{ - return std::make_shared(memoryManager); -} -#endif - -} diff --git a/src/armnn/memory/BaseMemoryManager.hpp b/src/armnn/memory/BaseMemoryManager.hpp deleted file mode 100644 index c82eca6c1d..0000000000 --- a/src/armnn/memory/BaseMemoryManager.hpp +++ /dev/null @@ -1,104 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#pragma once - -#include - -#ifdef ARMCOMPUTENEON_ENABLED -#include -#endif - -#ifdef ARMCOMPUTECL_ENABLED -#include -#endif - -#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED) -#include -#include -#include -#endif - -namespace armnn -{ - -class BaseMemoryManager -{ -public: - enum class MemoryAffinity - { - Buffer, - Offset - }; - - BaseMemoryManager() { } - virtual ~BaseMemoryManager() { } - -#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED) - - BaseMemoryManager(std::unique_ptr alloc, MemoryAffinity memoryAffinity); - - std::shared_ptr& GetIntraLayerManager() { return m_IntraLayerMemoryMgr; } - std::shared_ptr& GetInterLayerManager() { return m_InterLayerMemoryMgr; } - std::shared_ptr& GetInterLayerMemoryGroup() { return m_InterLayerMemoryGroup; } - - void Finalize(); - void Acquire(); - void Release(); - -protected: - - std::unique_ptr m_Allocator; - std::shared_ptr m_IntraLayerMemoryMgr; - std::shared_ptr m_InterLayerMemoryMgr; - std::shared_ptr m_InterLayerMemoryGroup; - - std::shared_ptr CreateArmComputeMemoryManager(MemoryAffinity memoryAffinity); - - virtual std::shared_ptr - CreateMemoryGroup(const std::shared_ptr& memoryManager) = 0; - - void FinalizeMemoryManager(arm_compute::MemoryManagerOnDemand& memoryManager); -#endif -}; - -class NeonMemoryManager : public BaseMemoryManager -{ -public: - NeonMemoryManager() {} - virtual ~NeonMemoryManager() {} - -#ifdef ARMCOMPUTENEON_ENABLED - NeonMemoryManager(std::unique_ptr alloc, MemoryAffinity memoryAffinity) - : BaseMemoryManager(std::move(alloc), memoryAffinity) - { - m_InterLayerMemoryGroup = CreateMemoryGroup(m_InterLayerMemoryMgr); - } - -protected: - virtual std::shared_ptr - CreateMemoryGroup(const std::shared_ptr& memoryManager) override; -#endif -}; - -class ClMemoryManager : public BaseMemoryManager -{ -public: - ClMemoryManager() {} - virtual ~ClMemoryManager() {} - -#ifdef ARMCOMPUTECL_ENABLED - ClMemoryManager(std::unique_ptr alloc) - : BaseMemoryManager(std::move(alloc), MemoryAffinity::Buffer) - { - m_InterLayerMemoryGroup = CreateMemoryGroup(m_InterLayerMemoryMgr); - } - -protected: - virtual std::shared_ptr - CreateMemoryGroup(const std::shared_ptr& memoryManager) override; -#endif -}; - -} //namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/BlobLifetimeManager.cpp b/src/armnn/memory/BlobLifetimeManager.cpp deleted file mode 100644 index fb8080c7ce..0000000000 --- a/src/armnn/memory/BlobLifetimeManager.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#include "BlobLifetimeManager.hpp" -#include "BlobMemoryPool.hpp" - -#include "arm_compute/runtime/IMemoryGroup.h" - -#include "boost/assert.hpp" - -#include - -namespace armnn -{ - -BlobLifetimeManager::BlobLifetimeManager() - : m_BlobSizes() -{ -} - -arm_compute::MappingType BlobLifetimeManager::mapping_type() const -{ - return arm_compute::MappingType::BLOBS; -} - -void BlobLifetimeManager::update_blobs_and_mappings() -{ - using namespace arm_compute; - - BOOST_ASSERT(are_all_finalized()); - BOOST_ASSERT(_active_group); - - // Sort free blobs requirements in descending order. - _free_blobs.sort([](const Blob & ba, const Blob & bb) - { - return ba.max_size > bb.max_size; - }); - std::vector groupSizes; - std::transform(std::begin(_free_blobs), std::end(_free_blobs), std::back_inserter(groupSizes), [](const Blob & b) - { - return b.max_size; - }); - - // Update blob sizes - size_t max_size = std::max(m_BlobSizes.size(), groupSizes.size()); - m_BlobSizes.resize(max_size, 0); - groupSizes.resize(max_size, 0); - std::transform(std::begin(m_BlobSizes), std::end(m_BlobSizes), std::begin(groupSizes), - std::begin(m_BlobSizes), [](size_t lhs, size_t rhs) - { - return std::max(lhs, rhs); - }); - - // Calculate group mappings - auto& groupMappings = _active_group->mappings(); - unsigned int blobIdx = 0; - - for(auto& freeBlob : _free_blobs) - { - for(auto& boundElementId : freeBlob.bound_elements) - { - BOOST_ASSERT(_active_elements.find(boundElementId) != std::end(_active_elements)); - - Element& boundElement = _active_elements[boundElementId]; - groupMappings[boundElement.handle] = blobIdx; - } - - ++blobIdx; - } -} - -std::unique_ptr BlobLifetimeManager::create_pool(arm_compute::IAllocator* allocator) -{ - BOOST_ASSERT(allocator); - return std::make_unique(allocator, m_BlobSizes); -} - -} // namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/BlobLifetimeManager.hpp b/src/armnn/memory/BlobLifetimeManager.hpp deleted file mode 100644 index 7c93985a5b..0000000000 --- a/src/armnn/memory/BlobLifetimeManager.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#pragma once - -#include "arm_compute/runtime/ISimpleLifetimeManager.h" - -namespace armnn -{ - -class BlobLifetimeManager : public arm_compute::ISimpleLifetimeManager -{ -public: - BlobLifetimeManager(); - - BlobLifetimeManager(const BlobLifetimeManager&) = delete; - - BlobLifetimeManager& operator=(const BlobLifetimeManager&) = delete; - - BlobLifetimeManager(BlobLifetimeManager&&) = default; - - BlobLifetimeManager& operator=(BlobLifetimeManager&&) = default; - - std::unique_ptr create_pool(arm_compute::IAllocator* allocator) override; - - arm_compute::MappingType mapping_type() const override; - -private: - void update_blobs_and_mappings() override; - - std::vector m_BlobSizes; -}; - -} // namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/BlobMemoryPool.cpp b/src/armnn/memory/BlobMemoryPool.cpp deleted file mode 100644 index 8b0a957bb0..0000000000 --- a/src/armnn/memory/BlobMemoryPool.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#include "BlobMemoryPool.hpp" - -#include - -namespace armnn -{ - -BlobMemoryPool::BlobMemoryPool(arm_compute::IAllocator* allocator, std::vector blobSizes) - : m_Allocator(allocator) - , m_Blobs() - , m_BlobSizes(std::move(blobSizes)) - , m_MemoryAllocated(false) -{ - AllocatePool(); -} - -BlobMemoryPool::~BlobMemoryPool() -{ - ReleasePool(); -} - -void BlobMemoryPool::acquire(arm_compute::MemoryMappings& handles) -{ - // Set memory to handlers - for (auto& handle : handles) - { - BOOST_ASSERT(handle.first); - *handle.first = m_Blobs[handle.second]; - } -} - -void BlobMemoryPool::release(arm_compute::MemoryMappings &handles) -{ - for (auto& handle : handles) - { - BOOST_ASSERT(handle.first); - *handle.first = nullptr; - } -} - -arm_compute::MappingType BlobMemoryPool::mapping_type() const -{ - return arm_compute::MappingType::BLOBS; -} - -std::unique_ptr BlobMemoryPool::duplicate() -{ - BOOST_ASSERT(m_Allocator); - return std::make_unique(m_Allocator, m_BlobSizes); -} - -void BlobMemoryPool::AllocatePool() -{ - if (!m_MemoryAllocated) - { - BOOST_ASSERT(m_Allocator); - - for (const auto& blobSize : m_BlobSizes) - { - m_Blobs.push_back(m_Allocator->allocate(blobSize, 0)); - } - - m_MemoryAllocated = true; - } -} - -void BlobMemoryPool::ReleasePool() -{ - if (m_MemoryAllocated) - { - BOOST_ASSERT(m_Allocator); - - for (auto& blob : m_Blobs) - { - m_Allocator->free(blob); - } - - m_Blobs.clear(); - - m_MemoryAllocated = false; - } -} - -} // namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/BlobMemoryPool.hpp b/src/armnn/memory/BlobMemoryPool.hpp deleted file mode 100644 index 26f2ccbb9d..0000000000 --- a/src/armnn/memory/BlobMemoryPool.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#pragma once - -#include "IMemoryPool.hpp" - -#include "arm_compute/runtime/IAllocator.h" -#include "arm_compute/runtime/Types.h" - -namespace armnn -{ - -/** Blob memory pool */ -class BlobMemoryPool : public IMemoryPool -{ -public: - BlobMemoryPool(arm_compute::IAllocator* allocator, std::vector blobSizes); - - ~BlobMemoryPool(); - - BlobMemoryPool(const BlobMemoryPool&) = delete; - - BlobMemoryPool& operator=(const BlobMemoryPool&) = delete; - - BlobMemoryPool(BlobMemoryPool&&) = default; - - BlobMemoryPool& operator=(BlobMemoryPool&&) = default; - - void acquire(arm_compute::MemoryMappings &handles) override; - void release(arm_compute::MemoryMappings &handles) override; - - arm_compute::MappingType mapping_type() const override; - - std::unique_ptr duplicate() override; - - void AllocatePool() override; - void ReleasePool() override; - -private: - /// Allocator to use for internal allocation - arm_compute::IAllocator* m_Allocator; - - /// Vector holding all the memory blobs - std::vector m_Blobs; - - /// Sizes of each memory blob - std::vector m_BlobSizes; - - /// Flag indicating whether memory has been allocated for the pool - bool m_MemoryAllocated; -}; - -} // namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/IMemoryPool.hpp b/src/armnn/memory/IMemoryPool.hpp deleted file mode 100644 index e55c91589c..0000000000 --- a/src/armnn/memory/IMemoryPool.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#pragma once - -#include "arm_compute/runtime/IMemoryPool.h" - -namespace armnn -{ - -class IMemoryPool : public arm_compute::IMemoryPool -{ -public: - /// Allocates memory for the entire pool - virtual void AllocatePool() = 0; - - /// Releases all memory associated with the pool - virtual void ReleasePool() = 0; -}; - -} // namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/IPoolManager.hpp b/src/armnn/memory/IPoolManager.hpp deleted file mode 100644 index 4fbca77a67..0000000000 --- a/src/armnn/memory/IPoolManager.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#pragma once - -#include "arm_compute/runtime/IPoolManager.h" - -namespace armnn -{ - -class IPoolManager : public arm_compute::IPoolManager { -public: - // Allocates all pools within the pool manager - virtual void AllocatePools() = 0; - - // Releases all pools within the pool manager - virtual void ReleasePools() = 0; -}; - -} // namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/OffsetLifetimeManager.cpp b/src/armnn/memory/OffsetLifetimeManager.cpp deleted file mode 100644 index 6d479721d9..0000000000 --- a/src/armnn/memory/OffsetLifetimeManager.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#include "OffsetLifetimeManager.hpp" -#include "OffsetMemoryPool.hpp" - -#include "arm_compute/runtime/IMemoryGroup.h" - -#include - -#include "boost/assert.hpp" - -namespace armnn -{ - -OffsetLifetimeManager::OffsetLifetimeManager() - : m_BlobSize(0) -{ -} - -std::unique_ptr OffsetLifetimeManager::create_pool(arm_compute::IAllocator* allocator) -{ - BOOST_ASSERT(allocator); - return std::make_unique(allocator, m_BlobSize); -} - -arm_compute::MappingType OffsetLifetimeManager::mapping_type() const -{ - return arm_compute::MappingType::OFFSETS; -} - -void OffsetLifetimeManager::update_blobs_and_mappings() -{ - BOOST_ASSERT(are_all_finalized()); - BOOST_ASSERT(_active_group); - - // Update blob size - size_t maxGroupSize = std::accumulate(std::begin(_free_blobs), std::end(_free_blobs), - static_cast(0), [](size_t s, const Blob& b) - { - return s + b.max_size; - }); - m_BlobSize = std::max(m_BlobSize, maxGroupSize); - - // Calculate group mappings - auto& groupMappings = _active_group->mappings(); - size_t offset = 0; - for(auto& freeBlob : _free_blobs) - { - for(auto& boundElementId : freeBlob.bound_elements) - { - BOOST_ASSERT(_active_elements.find(boundElementId) != std::end(_active_elements)); - Element& boundElement = _active_elements[boundElementId]; - groupMappings[boundElement.handle] = offset; - } - offset += freeBlob.max_size; - BOOST_ASSERT(offset <= m_BlobSize); - } -} - -} // namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/OffsetLifetimeManager.hpp b/src/armnn/memory/OffsetLifetimeManager.hpp deleted file mode 100644 index ab4de7741e..0000000000 --- a/src/armnn/memory/OffsetLifetimeManager.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#pragma once - -#include "arm_compute/runtime/ISimpleLifetimeManager.h" - -namespace armnn -{ - -class OffsetLifetimeManager : public arm_compute::ISimpleLifetimeManager -{ -public: - OffsetLifetimeManager(); - - OffsetLifetimeManager(const OffsetLifetimeManager&) = delete; - - OffsetLifetimeManager& operator=(const OffsetLifetimeManager&) = delete; - - OffsetLifetimeManager(OffsetLifetimeManager&&) = default; - - OffsetLifetimeManager& operator=(OffsetLifetimeManager&&) = default; - - std::unique_ptr create_pool(arm_compute::IAllocator* allocator) override; - - arm_compute::MappingType mapping_type() const override; - -private: - void update_blobs_and_mappings() override; - -private: - /// Memory blob size - size_t m_BlobSize; -}; - -} // namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/OffsetMemoryPool.cpp b/src/armnn/memory/OffsetMemoryPool.cpp deleted file mode 100644 index e5587cfe63..0000000000 --- a/src/armnn/memory/OffsetMemoryPool.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#include "OffsetMemoryPool.hpp" - -#include "boost/assert.hpp" - -#include - -namespace armnn -{ - -OffsetMemoryPool::OffsetMemoryPool(arm_compute::IAllocator* allocator, size_t blobSize) - : m_Allocator(allocator) - , m_Blob() - , m_BlobSize(blobSize) - , m_MemoryAllocated(false) -{ - AllocatePool(); -} - -OffsetMemoryPool::~OffsetMemoryPool() -{ - ReleasePool(); -} - -void OffsetMemoryPool::acquire(arm_compute::MemoryMappings& handles) -{ - BOOST_ASSERT(m_Blob); - - // Set memory to handlers - for(auto& handle : handles) - { - BOOST_ASSERT(handle.first); - *handle.first = reinterpret_cast(m_Blob) + handle.second; - } -} - -void OffsetMemoryPool::release(arm_compute::MemoryMappings &handles) -{ - for(auto& handle : handles) - { - BOOST_ASSERT(handle.first); - *handle.first = nullptr; - } -} - -arm_compute::MappingType OffsetMemoryPool::mapping_type() const -{ - return arm_compute::MappingType::OFFSETS; -} - -std::unique_ptr OffsetMemoryPool::duplicate() -{ - BOOST_ASSERT(m_Allocator); - return std::make_unique(m_Allocator, m_BlobSize); -} - -void OffsetMemoryPool::AllocatePool() -{ - if (!m_MemoryAllocated) - { - BOOST_ASSERT(m_Allocator); - m_Blob = m_Allocator->allocate(m_BlobSize, 0); - - m_MemoryAllocated = true; - } -} - -void OffsetMemoryPool::ReleasePool() -{ - if (m_MemoryAllocated) - { - BOOST_ASSERT(m_Allocator); - - m_Allocator->free(m_Blob); - m_Blob = nullptr; - - m_MemoryAllocated = false; - } -} - -} // namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/OffsetMemoryPool.hpp b/src/armnn/memory/OffsetMemoryPool.hpp deleted file mode 100644 index 6843744f88..0000000000 --- a/src/armnn/memory/OffsetMemoryPool.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#pragma once - -#include "IMemoryPool.hpp" - -#include "arm_compute/runtime/IAllocator.h" -#include "arm_compute/runtime/Types.h" - -namespace armnn -{ - -class OffsetMemoryPool : public IMemoryPool -{ -public: - OffsetMemoryPool(arm_compute::IAllocator* allocator, size_t blobSize); - - ~OffsetMemoryPool(); - - OffsetMemoryPool(const OffsetMemoryPool&) = delete; - - OffsetMemoryPool& operator=(const OffsetMemoryPool&) = delete; - - OffsetMemoryPool(OffsetMemoryPool&&) = default; - - OffsetMemoryPool& operator=(OffsetMemoryPool &&) = default; - - void acquire(arm_compute::MemoryMappings& handles) override; - void release(arm_compute::MemoryMappings& handles) override; - - arm_compute::MappingType mapping_type() const override; - - std::unique_ptr duplicate() override; - - void AllocatePool() override; - void ReleasePool() override; - -private: - /// Allocator to use for internal allocation - arm_compute::IAllocator* m_Allocator; - - /// Memory blob - void* m_Blob; - - /// Size of the allocated memory blob - size_t m_BlobSize; - - /// Flag indicating whether memory has been allocated for the pool - bool m_MemoryAllocated; -}; - -} // namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/PoolManager.cpp b/src/armnn/memory/PoolManager.cpp deleted file mode 100644 index 172c46bb1c..0000000000 --- a/src/armnn/memory/PoolManager.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#include "IMemoryPool.hpp" -#include "PoolManager.hpp" - -#include "boost/assert.hpp" -#include "boost/polymorphic_cast.hpp" - -#include - -namespace armnn -{ - -PoolManager::PoolManager() - : m_FreePools() - , m_OccupiedPools() - , m_Semaphore() - , m_Mutex() -{} - -arm_compute::IMemoryPool *PoolManager::lock_pool() -{ - BOOST_ASSERT_MSG(!(m_FreePools.empty() && m_OccupiedPools.empty()), "Haven't setup any pools"); - - m_Semaphore->wait(); - std::lock_guard lock(m_Mutex); - - BOOST_ASSERT_MSG(!m_FreePools.empty(), "Empty pool must exist as semaphore has been signalled"); - m_OccupiedPools.splice(std::begin(m_OccupiedPools), m_FreePools, std::begin(m_FreePools)); - - return m_OccupiedPools.front().get(); -} - -void PoolManager::unlock_pool(arm_compute::IMemoryPool *pool) -{ - BOOST_ASSERT_MSG(!(m_FreePools.empty() && m_OccupiedPools.empty()), "Haven't setup any pools!"); - - std::lock_guard lock(m_Mutex); - - auto it = std::find_if( - std::begin(m_OccupiedPools), - std::end(m_OccupiedPools), - [pool](const std::unique_ptr &poolIterator) - { - return poolIterator.get() == pool; - } - ); - - BOOST_ASSERT_MSG(it != std::end(m_OccupiedPools), "Pool to be unlocked couldn't be found"); - m_FreePools.splice(std::begin(m_FreePools), m_OccupiedPools, it); - m_Semaphore->signal(); -} - -void PoolManager::register_pool(std::unique_ptr pool) -{ - std::lock_guard lock(m_Mutex); - BOOST_ASSERT_MSG(m_OccupiedPools.empty(), "All pools should be free in order to register a new one"); - - // Set pool - m_FreePools.push_front(std::move(pool)); - - // Update semaphore - m_Semaphore = std::make_unique(m_FreePools.size()); -} - -size_t PoolManager::num_pools() const -{ - std::lock_guard lock(m_Mutex); - - return m_FreePools.size() + m_OccupiedPools.size(); -} - -void PoolManager::AllocatePools() -{ - std::lock_guard lock(m_Mutex); - - for (auto& pool : m_FreePools) - { - boost::polymorphic_downcast(pool.get())->AllocatePool(); - } - - for (auto& pool : m_OccupiedPools) - { - boost::polymorphic_downcast(pool.get())->AllocatePool(); - } -} - -void PoolManager::ReleasePools() -{ - std::lock_guard lock(m_Mutex); - - for (auto& pool : m_FreePools) - { - boost::polymorphic_downcast(pool.get())->ReleasePool(); - } - - for (auto& pool : m_OccupiedPools) - { - boost::polymorphic_downcast(pool.get())->ReleasePool(); - } -} - -} //namespace armnn \ No newline at end of file diff --git a/src/armnn/memory/PoolManager.hpp b/src/armnn/memory/PoolManager.hpp deleted file mode 100644 index bb84440c5d..0000000000 --- a/src/armnn/memory/PoolManager.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#pragma once - -#include "IPoolManager.hpp" - -#include "arm_compute/runtime/IMemoryPool.h" -#include "arm_compute/core/Error.h" -#include "support/Mutex.h" -#include "support/Semaphore.h" - -#include -#include -#include - -namespace armnn -{ - -class PoolManager : public IPoolManager -{ -public: - PoolManager(); - - PoolManager(const PoolManager &) = delete; - - PoolManager &operator=(const PoolManager &) = delete; - - PoolManager(PoolManager &&) = default; - - PoolManager &operator=(PoolManager &&) = default; - - arm_compute::IMemoryPool *lock_pool() override; - void unlock_pool(arm_compute::IMemoryPool *pool) override; - void register_pool(std::unique_ptr pool) override; - size_t num_pools() const override; - - void AllocatePools() override; - void ReleasePools() override; - -private: - /// List of free pools - std::list> m_FreePools; - - /// List of occupied pools - std::list> m_OccupiedPools; - - /// Semaphore to control the queues - std::unique_ptr m_Semaphore; - - /// Mutex to control access to the queues - mutable arm_compute::Mutex m_Mutex; -}; - -} // namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/CMakeLists.txt b/src/backends/aclCommon/CMakeLists.txt index 6f99f4f146..d99b90b897 100644 --- a/src/backends/aclCommon/CMakeLists.txt +++ b/src/backends/aclCommon/CMakeLists.txt @@ -7,6 +7,20 @@ list(APPEND armnnAclCommon_sources ArmComputeTensorUtils.hpp ArmComputeTensorUtils.cpp ArmComputeUtils.hpp + memory/BaseMemoryManager.cpp + memory/BaseMemoryManager.hpp + memory/BlobLifetimeManager.cpp + memory/BlobLifetimeManager.hpp + memory/BlobMemoryPool.cpp + memory/BlobMemoryPool.hpp + memory/IMemoryPool.hpp + memory/IPoolManager.hpp + memory/OffsetLifetimeManager.cpp + memory/OffsetLifetimeManager.hpp + memory/OffsetMemoryPool.cpp + memory/OffsetMemoryPool.hpp + memory/PoolManager.cpp + memory/PoolManager.hpp ) add_subdirectory(test) diff --git a/src/backends/aclCommon/common.mk b/src/backends/aclCommon/common.mk index b371bfab9e..9854f6fcb5 100644 --- a/src/backends/aclCommon/common.mk +++ b/src/backends/aclCommon/common.mk @@ -7,4 +7,11 @@ # in the Android build and it is picked up by the Android.mk # file in the root of ArmNN -COMMON_SOURCES := ArmComputeTensorUtils.cpp +COMMON_SOURCES := \ + ArmComputeTensorUtils.cpp \ + memory/BaseMemoryManager.cpp \ + memory/BlobLifetimeManager.cpp \ + memory/BlobMemoryPool.cpp \ + memory/OffsetLifetimeManager.cpp \ + memory/OffsetMemoryPool.cpp \ + memory/PoolManager.cpp \ No newline at end of file diff --git a/src/backends/aclCommon/memory/BaseMemoryManager.cpp b/src/backends/aclCommon/memory/BaseMemoryManager.cpp new file mode 100644 index 0000000000..532692b1ce --- /dev/null +++ b/src/backends/aclCommon/memory/BaseMemoryManager.cpp @@ -0,0 +1,125 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#include "BaseMemoryManager.hpp" + +#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED) +#include "BlobLifetimeManager.hpp" +#include "PoolManager.hpp" +#include "OffsetLifetimeManager.hpp" +#endif + +#include + +namespace armnn +{ + +#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED) +BaseMemoryManager::BaseMemoryManager(std::unique_ptr alloc, + MemoryAffinity memoryAffinity) +{ + // (Re)create the memory manager components. + m_Allocator = std::move(alloc); + + m_IntraLayerMemoryMgr = CreateArmComputeMemoryManager(memoryAffinity); + m_InterLayerMemoryMgr = CreateArmComputeMemoryManager(memoryAffinity); +} + +std::shared_ptr +BaseMemoryManager::CreateArmComputeMemoryManager(MemoryAffinity memoryAffinity) +{ + std::shared_ptr lifetimeManager = nullptr; + + if (memoryAffinity == MemoryAffinity::Buffer) + { + lifetimeManager = std::make_shared(); + } + else + { + lifetimeManager = std::make_shared(); + } + + auto poolManager = std::make_shared(); + auto memoryManager = std::make_shared(lifetimeManager, poolManager); + + // Set allocator that the memory manager will use + memoryManager->set_allocator(m_Allocator.get()); + + return memoryManager; +} + +void BaseMemoryManager::FinalizeMemoryManager(arm_compute::MemoryManagerOnDemand& memoryManager) +{ + // Number of pools that the manager will create. This specifies how many layers you want to run in parallel + memoryManager.set_num_pools(1); + + // Finalize the memory manager. (Validity checks, memory allocations, etc) + memoryManager.finalize(); +} + +void BaseMemoryManager::Finalize() +{ + BOOST_ASSERT(m_IntraLayerMemoryMgr); + FinalizeMemoryManager(*m_IntraLayerMemoryMgr.get()); + + BOOST_ASSERT(m_InterLayerMemoryMgr); + FinalizeMemoryManager(*m_InterLayerMemoryMgr.get()); +} + +void BaseMemoryManager::Acquire() +{ + // Allocate memory pools for intra-layer memory manager + BOOST_ASSERT(m_IntraLayerMemoryMgr); + IPoolManager* poolManager = boost::polymorphic_downcast(m_IntraLayerMemoryMgr->pool_manager()); + BOOST_ASSERT(poolManager); + poolManager->AllocatePools(); + + // Allocate memory pools for inter-layer memory manager + BOOST_ASSERT(m_InterLayerMemoryMgr); + poolManager = boost::polymorphic_downcast(m_InterLayerMemoryMgr->pool_manager()); + BOOST_ASSERT(poolManager); + poolManager->AllocatePools(); + + // Acquire inter-layer memory group. NOTE: This has to come after allocating the pools + BOOST_ASSERT(m_InterLayerMemoryGroup); + m_InterLayerMemoryGroup->acquire(); +} + +void BaseMemoryManager::Release() +{ + // Release inter-layer memory group. NOTE: This has to come before releasing the pools + BOOST_ASSERT(m_InterLayerMemoryGroup); + m_InterLayerMemoryGroup->release(); + + // Release memory pools managed by intra-layer memory manager + BOOST_ASSERT(m_IntraLayerMemoryMgr); + IPoolManager* poolManager = boost::polymorphic_downcast(m_IntraLayerMemoryMgr->pool_manager()); + BOOST_ASSERT(poolManager); + poolManager->ReleasePools(); + + // Release memory pools managed by inter-layer memory manager + BOOST_ASSERT(m_InterLayerMemoryMgr); + poolManager = boost::polymorphic_downcast(m_InterLayerMemoryMgr->pool_manager()); + BOOST_ASSERT(poolManager); + poolManager->ReleasePools(); +} +#endif + +#ifdef ARMCOMPUTENEON_ENABLED +std::shared_ptr +NeonMemoryManager::CreateMemoryGroup(const std::shared_ptr& memoryManager) +{ + return std::make_shared(memoryManager); +} +#endif + +#ifdef ARMCOMPUTECL_ENABLED +std::shared_ptr +ClMemoryManager::CreateMemoryGroup(const std::shared_ptr& memoryManager) +{ + return std::make_shared(memoryManager); +} +#endif + +} diff --git a/src/backends/aclCommon/memory/BaseMemoryManager.hpp b/src/backends/aclCommon/memory/BaseMemoryManager.hpp new file mode 100644 index 0000000000..2afc1cb130 --- /dev/null +++ b/src/backends/aclCommon/memory/BaseMemoryManager.hpp @@ -0,0 +1,104 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include + +#ifdef ARMCOMPUTENEON_ENABLED +#include +#endif + +#ifdef ARMCOMPUTECL_ENABLED +#include +#endif + +#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED) +#include +#include +#include +#endif + +namespace armnn +{ + +class BaseMemoryManager +{ +public: + enum class MemoryAffinity + { + Buffer, + Offset + }; + + BaseMemoryManager() { } + virtual ~BaseMemoryManager() { } + +#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED) + + BaseMemoryManager(std::unique_ptr alloc, MemoryAffinity memoryAffinity); + + std::shared_ptr& GetIntraLayerManager() { return m_IntraLayerMemoryMgr; } + std::shared_ptr& GetInterLayerManager() { return m_InterLayerMemoryMgr; } + std::shared_ptr& GetInterLayerMemoryGroup() { return m_InterLayerMemoryGroup; } + + void Finalize(); + void Acquire(); + void Release(); + +protected: + + std::unique_ptr m_Allocator; + std::shared_ptr m_IntraLayerMemoryMgr; + std::shared_ptr m_InterLayerMemoryMgr; + std::shared_ptr m_InterLayerMemoryGroup; + + std::shared_ptr CreateArmComputeMemoryManager(MemoryAffinity memoryAffinity); + + virtual std::shared_ptr + CreateMemoryGroup(const std::shared_ptr& memoryManager) = 0; + + void FinalizeMemoryManager(arm_compute::MemoryManagerOnDemand& memoryManager); +#endif +}; + +class NeonMemoryManager : public BaseMemoryManager +{ +public: + NeonMemoryManager() {} + virtual ~NeonMemoryManager() {} + +#ifdef ARMCOMPUTENEON_ENABLED + NeonMemoryManager(std::unique_ptr alloc, MemoryAffinity memoryAffinity) + : BaseMemoryManager(std::move(alloc), memoryAffinity) + { + m_InterLayerMemoryGroup = CreateMemoryGroup(m_InterLayerMemoryMgr); + } + +protected: + virtual std::shared_ptr + CreateMemoryGroup(const std::shared_ptr& memoryManager) override; +#endif +}; + +class ClMemoryManager : public BaseMemoryManager +{ +public: + ClMemoryManager() {} + virtual ~ClMemoryManager() {} + +#ifdef ARMCOMPUTECL_ENABLED + ClMemoryManager(std::unique_ptr alloc) + : BaseMemoryManager(std::move(alloc), MemoryAffinity::Buffer) + { + m_InterLayerMemoryGroup = CreateMemoryGroup(m_InterLayerMemoryMgr); + } + +protected: + virtual std::shared_ptr + CreateMemoryGroup(const std::shared_ptr& memoryManager) override; +#endif +}; + +} //namespace armnn diff --git a/src/backends/aclCommon/memory/BlobLifetimeManager.cpp b/src/backends/aclCommon/memory/BlobLifetimeManager.cpp new file mode 100644 index 0000000000..41100e945f --- /dev/null +++ b/src/backends/aclCommon/memory/BlobLifetimeManager.cpp @@ -0,0 +1,79 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#include "BlobLifetimeManager.hpp" +#include "BlobMemoryPool.hpp" + +#include + +#include "boost/assert.hpp" + +#include + +namespace armnn +{ + +BlobLifetimeManager::BlobLifetimeManager() + : m_BlobSizes() +{ +} + +arm_compute::MappingType BlobLifetimeManager::mapping_type() const +{ + return arm_compute::MappingType::BLOBS; +} + +void BlobLifetimeManager::update_blobs_and_mappings() +{ + using namespace arm_compute; + + BOOST_ASSERT(are_all_finalized()); + BOOST_ASSERT(_active_group); + + // Sort free blobs requirements in descending order. + _free_blobs.sort([](const Blob & ba, const Blob & bb) + { + return ba.max_size > bb.max_size; + }); + std::vector groupSizes; + std::transform(std::begin(_free_blobs), std::end(_free_blobs), std::back_inserter(groupSizes), [](const Blob & b) + { + return b.max_size; + }); + + // Update blob sizes + size_t max_size = std::max(m_BlobSizes.size(), groupSizes.size()); + m_BlobSizes.resize(max_size, 0); + groupSizes.resize(max_size, 0); + std::transform(std::begin(m_BlobSizes), std::end(m_BlobSizes), std::begin(groupSizes), + std::begin(m_BlobSizes), [](size_t lhs, size_t rhs) + { + return std::max(lhs, rhs); + }); + + // Calculate group mappings + auto& groupMappings = _active_group->mappings(); + unsigned int blobIdx = 0; + + for(auto& freeBlob : _free_blobs) + { + for(auto& boundElementId : freeBlob.bound_elements) + { + BOOST_ASSERT(_active_elements.find(boundElementId) != std::end(_active_elements)); + + Element& boundElement = _active_elements[boundElementId]; + groupMappings[boundElement.handle] = blobIdx; + } + + ++blobIdx; + } +} + +std::unique_ptr BlobLifetimeManager::create_pool(arm_compute::IAllocator* allocator) +{ + BOOST_ASSERT(allocator); + return std::make_unique(allocator, m_BlobSizes); +} + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/memory/BlobLifetimeManager.hpp b/src/backends/aclCommon/memory/BlobLifetimeManager.hpp new file mode 100644 index 0000000000..d777ba59ee --- /dev/null +++ b/src/backends/aclCommon/memory/BlobLifetimeManager.hpp @@ -0,0 +1,35 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include + +namespace armnn +{ + +class BlobLifetimeManager : public arm_compute::ISimpleLifetimeManager +{ +public: + BlobLifetimeManager(); + + BlobLifetimeManager(const BlobLifetimeManager&) = delete; + + BlobLifetimeManager& operator=(const BlobLifetimeManager&) = delete; + + BlobLifetimeManager(BlobLifetimeManager&&) = default; + + BlobLifetimeManager& operator=(BlobLifetimeManager&&) = default; + + std::unique_ptr create_pool(arm_compute::IAllocator* allocator) override; + + arm_compute::MappingType mapping_type() const override; + +private: + void update_blobs_and_mappings() override; + + std::vector m_BlobSizes; +}; + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/memory/BlobMemoryPool.cpp b/src/backends/aclCommon/memory/BlobMemoryPool.cpp new file mode 100644 index 0000000000..8b0a957bb0 --- /dev/null +++ b/src/backends/aclCommon/memory/BlobMemoryPool.cpp @@ -0,0 +1,88 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#include "BlobMemoryPool.hpp" + +#include + +namespace armnn +{ + +BlobMemoryPool::BlobMemoryPool(arm_compute::IAllocator* allocator, std::vector blobSizes) + : m_Allocator(allocator) + , m_Blobs() + , m_BlobSizes(std::move(blobSizes)) + , m_MemoryAllocated(false) +{ + AllocatePool(); +} + +BlobMemoryPool::~BlobMemoryPool() +{ + ReleasePool(); +} + +void BlobMemoryPool::acquire(arm_compute::MemoryMappings& handles) +{ + // Set memory to handlers + for (auto& handle : handles) + { + BOOST_ASSERT(handle.first); + *handle.first = m_Blobs[handle.second]; + } +} + +void BlobMemoryPool::release(arm_compute::MemoryMappings &handles) +{ + for (auto& handle : handles) + { + BOOST_ASSERT(handle.first); + *handle.first = nullptr; + } +} + +arm_compute::MappingType BlobMemoryPool::mapping_type() const +{ + return arm_compute::MappingType::BLOBS; +} + +std::unique_ptr BlobMemoryPool::duplicate() +{ + BOOST_ASSERT(m_Allocator); + return std::make_unique(m_Allocator, m_BlobSizes); +} + +void BlobMemoryPool::AllocatePool() +{ + if (!m_MemoryAllocated) + { + BOOST_ASSERT(m_Allocator); + + for (const auto& blobSize : m_BlobSizes) + { + m_Blobs.push_back(m_Allocator->allocate(blobSize, 0)); + } + + m_MemoryAllocated = true; + } +} + +void BlobMemoryPool::ReleasePool() +{ + if (m_MemoryAllocated) + { + BOOST_ASSERT(m_Allocator); + + for (auto& blob : m_Blobs) + { + m_Allocator->free(blob); + } + + m_Blobs.clear(); + + m_MemoryAllocated = false; + } +} + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/memory/BlobMemoryPool.hpp b/src/backends/aclCommon/memory/BlobMemoryPool.hpp new file mode 100644 index 0000000000..4d42e6ee7a --- /dev/null +++ b/src/backends/aclCommon/memory/BlobMemoryPool.hpp @@ -0,0 +1,55 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "IMemoryPool.hpp" + +#include +#include + +namespace armnn +{ + +/** Blob memory pool */ +class BlobMemoryPool : public IMemoryPool +{ +public: + BlobMemoryPool(arm_compute::IAllocator* allocator, std::vector blobSizes); + + ~BlobMemoryPool(); + + BlobMemoryPool(const BlobMemoryPool&) = delete; + + BlobMemoryPool& operator=(const BlobMemoryPool&) = delete; + + BlobMemoryPool(BlobMemoryPool&&) = default; + + BlobMemoryPool& operator=(BlobMemoryPool&&) = default; + + void acquire(arm_compute::MemoryMappings &handles) override; + void release(arm_compute::MemoryMappings &handles) override; + + arm_compute::MappingType mapping_type() const override; + + std::unique_ptr duplicate() override; + + void AllocatePool() override; + void ReleasePool() override; + +private: + /// Allocator to use for internal allocation + arm_compute::IAllocator* m_Allocator; + + /// Vector holding all the memory blobs + std::vector m_Blobs; + + /// Sizes of each memory blob + std::vector m_BlobSizes; + + /// Flag indicating whether memory has been allocated for the pool + bool m_MemoryAllocated; +}; + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/memory/IMemoryPool.hpp b/src/backends/aclCommon/memory/IMemoryPool.hpp new file mode 100644 index 0000000000..99130699e0 --- /dev/null +++ b/src/backends/aclCommon/memory/IMemoryPool.hpp @@ -0,0 +1,22 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include + +namespace armnn +{ + +class IMemoryPool : public arm_compute::IMemoryPool +{ +public: + /// Allocates memory for the entire pool + virtual void AllocatePool() = 0; + + /// Releases all memory associated with the pool + virtual void ReleasePool() = 0; +}; + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/memory/IPoolManager.hpp b/src/backends/aclCommon/memory/IPoolManager.hpp new file mode 100644 index 0000000000..be15fdd57e --- /dev/null +++ b/src/backends/aclCommon/memory/IPoolManager.hpp @@ -0,0 +1,21 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include + +namespace armnn +{ + +class IPoolManager : public arm_compute::IPoolManager { +public: + // Allocates all pools within the pool manager + virtual void AllocatePools() = 0; + + // Releases all pools within the pool manager + virtual void ReleasePools() = 0; +}; + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/memory/OffsetLifetimeManager.cpp b/src/backends/aclCommon/memory/OffsetLifetimeManager.cpp new file mode 100644 index 0000000000..d0174f893c --- /dev/null +++ b/src/backends/aclCommon/memory/OffsetLifetimeManager.cpp @@ -0,0 +1,62 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#include "OffsetLifetimeManager.hpp" +#include "OffsetMemoryPool.hpp" + +#include + +#include + +#include + +namespace armnn +{ + +OffsetLifetimeManager::OffsetLifetimeManager() + : m_BlobSize(0) +{ +} + +std::unique_ptr OffsetLifetimeManager::create_pool(arm_compute::IAllocator* allocator) +{ + BOOST_ASSERT(allocator); + return std::make_unique(allocator, m_BlobSize); +} + +arm_compute::MappingType OffsetLifetimeManager::mapping_type() const +{ + return arm_compute::MappingType::OFFSETS; +} + +void OffsetLifetimeManager::update_blobs_and_mappings() +{ + BOOST_ASSERT(are_all_finalized()); + BOOST_ASSERT(_active_group); + + // Update blob size + size_t maxGroupSize = std::accumulate(std::begin(_free_blobs), std::end(_free_blobs), + static_cast(0), [](size_t s, const Blob& b) + { + return s + b.max_size; + }); + m_BlobSize = std::max(m_BlobSize, maxGroupSize); + + // Calculate group mappings + auto& groupMappings = _active_group->mappings(); + size_t offset = 0; + for(auto& freeBlob : _free_blobs) + { + for(auto& boundElementId : freeBlob.bound_elements) + { + BOOST_ASSERT(_active_elements.find(boundElementId) != std::end(_active_elements)); + Element& boundElement = _active_elements[boundElementId]; + groupMappings[boundElement.handle] = offset; + } + offset += freeBlob.max_size; + BOOST_ASSERT(offset <= m_BlobSize); + } +} + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/memory/OffsetLifetimeManager.hpp b/src/backends/aclCommon/memory/OffsetLifetimeManager.hpp new file mode 100644 index 0000000000..1283193052 --- /dev/null +++ b/src/backends/aclCommon/memory/OffsetLifetimeManager.hpp @@ -0,0 +1,37 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include + +namespace armnn +{ + +class OffsetLifetimeManager : public arm_compute::ISimpleLifetimeManager +{ +public: + OffsetLifetimeManager(); + + OffsetLifetimeManager(const OffsetLifetimeManager&) = delete; + + OffsetLifetimeManager& operator=(const OffsetLifetimeManager&) = delete; + + OffsetLifetimeManager(OffsetLifetimeManager&&) = default; + + OffsetLifetimeManager& operator=(OffsetLifetimeManager&&) = default; + + std::unique_ptr create_pool(arm_compute::IAllocator* allocator) override; + + arm_compute::MappingType mapping_type() const override; + +private: + void update_blobs_and_mappings() override; + +private: + /// Memory blob size + size_t m_BlobSize; +}; + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/memory/OffsetMemoryPool.cpp b/src/backends/aclCommon/memory/OffsetMemoryPool.cpp new file mode 100644 index 0000000000..48bea5e845 --- /dev/null +++ b/src/backends/aclCommon/memory/OffsetMemoryPool.cpp @@ -0,0 +1,84 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#include "OffsetMemoryPool.hpp" + +#include + +#include + +namespace armnn +{ + +OffsetMemoryPool::OffsetMemoryPool(arm_compute::IAllocator* allocator, size_t blobSize) + : m_Allocator(allocator) + , m_Blob() + , m_BlobSize(blobSize) + , m_MemoryAllocated(false) +{ + AllocatePool(); +} + +OffsetMemoryPool::~OffsetMemoryPool() +{ + ReleasePool(); +} + +void OffsetMemoryPool::acquire(arm_compute::MemoryMappings& handles) +{ + BOOST_ASSERT(m_Blob); + + // Set memory to handlers + for(auto& handle : handles) + { + BOOST_ASSERT(handle.first); + *handle.first = reinterpret_cast(m_Blob) + handle.second; + } +} + +void OffsetMemoryPool::release(arm_compute::MemoryMappings &handles) +{ + for(auto& handle : handles) + { + BOOST_ASSERT(handle.first); + *handle.first = nullptr; + } +} + +arm_compute::MappingType OffsetMemoryPool::mapping_type() const +{ + return arm_compute::MappingType::OFFSETS; +} + +std::unique_ptr OffsetMemoryPool::duplicate() +{ + BOOST_ASSERT(m_Allocator); + return std::make_unique(m_Allocator, m_BlobSize); +} + +void OffsetMemoryPool::AllocatePool() +{ + if (!m_MemoryAllocated) + { + BOOST_ASSERT(m_Allocator); + m_Blob = m_Allocator->allocate(m_BlobSize, 0); + + m_MemoryAllocated = true; + } +} + +void OffsetMemoryPool::ReleasePool() +{ + if (m_MemoryAllocated) + { + BOOST_ASSERT(m_Allocator); + + m_Allocator->free(m_Blob); + m_Blob = nullptr; + + m_MemoryAllocated = false; + } +} + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/memory/OffsetMemoryPool.hpp b/src/backends/aclCommon/memory/OffsetMemoryPool.hpp new file mode 100644 index 0000000000..25cf8cd638 --- /dev/null +++ b/src/backends/aclCommon/memory/OffsetMemoryPool.hpp @@ -0,0 +1,54 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "IMemoryPool.hpp" + +#include +#include + +namespace armnn +{ + +class OffsetMemoryPool : public IMemoryPool +{ +public: + OffsetMemoryPool(arm_compute::IAllocator* allocator, size_t blobSize); + + ~OffsetMemoryPool(); + + OffsetMemoryPool(const OffsetMemoryPool&) = delete; + + OffsetMemoryPool& operator=(const OffsetMemoryPool&) = delete; + + OffsetMemoryPool(OffsetMemoryPool&&) = default; + + OffsetMemoryPool& operator=(OffsetMemoryPool &&) = default; + + void acquire(arm_compute::MemoryMappings& handles) override; + void release(arm_compute::MemoryMappings& handles) override; + + arm_compute::MappingType mapping_type() const override; + + std::unique_ptr duplicate() override; + + void AllocatePool() override; + void ReleasePool() override; + +private: + /// Allocator to use for internal allocation + arm_compute::IAllocator* m_Allocator; + + /// Memory blob + void* m_Blob; + + /// Size of the allocated memory blob + size_t m_BlobSize; + + /// Flag indicating whether memory has been allocated for the pool + bool m_MemoryAllocated; +}; + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/memory/PoolManager.cpp b/src/backends/aclCommon/memory/PoolManager.cpp new file mode 100644 index 0000000000..363b4590b3 --- /dev/null +++ b/src/backends/aclCommon/memory/PoolManager.cpp @@ -0,0 +1,105 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#include "IMemoryPool.hpp" +#include "PoolManager.hpp" + +#include +#include + +#include + +namespace armnn +{ + +PoolManager::PoolManager() + : m_FreePools() + , m_OccupiedPools() + , m_Semaphore() + , m_Mutex() +{} + +arm_compute::IMemoryPool *PoolManager::lock_pool() +{ + BOOST_ASSERT_MSG(!(m_FreePools.empty() && m_OccupiedPools.empty()), "Haven't setup any pools"); + + m_Semaphore->wait(); + std::lock_guard lock(m_Mutex); + + BOOST_ASSERT_MSG(!m_FreePools.empty(), "Empty pool must exist as semaphore has been signalled"); + m_OccupiedPools.splice(std::begin(m_OccupiedPools), m_FreePools, std::begin(m_FreePools)); + + return m_OccupiedPools.front().get(); +} + +void PoolManager::unlock_pool(arm_compute::IMemoryPool *pool) +{ + BOOST_ASSERT_MSG(!(m_FreePools.empty() && m_OccupiedPools.empty()), "Haven't setup any pools!"); + + std::lock_guard lock(m_Mutex); + + auto it = std::find_if( + std::begin(m_OccupiedPools), + std::end(m_OccupiedPools), + [pool](const std::unique_ptr &poolIterator) + { + return poolIterator.get() == pool; + } + ); + + BOOST_ASSERT_MSG(it != std::end(m_OccupiedPools), "Pool to be unlocked couldn't be found"); + m_FreePools.splice(std::begin(m_FreePools), m_OccupiedPools, it); + m_Semaphore->signal(); +} + +void PoolManager::register_pool(std::unique_ptr pool) +{ + std::lock_guard lock(m_Mutex); + BOOST_ASSERT_MSG(m_OccupiedPools.empty(), "All pools should be free in order to register a new one"); + + // Set pool + m_FreePools.push_front(std::move(pool)); + + // Update semaphore + m_Semaphore = std::make_unique(m_FreePools.size()); +} + +size_t PoolManager::num_pools() const +{ + std::lock_guard lock(m_Mutex); + + return m_FreePools.size() + m_OccupiedPools.size(); +} + +void PoolManager::AllocatePools() +{ + std::lock_guard lock(m_Mutex); + + for (auto& pool : m_FreePools) + { + boost::polymorphic_downcast(pool.get())->AllocatePool(); + } + + for (auto& pool : m_OccupiedPools) + { + boost::polymorphic_downcast(pool.get())->AllocatePool(); + } +} + +void PoolManager::ReleasePools() +{ + std::lock_guard lock(m_Mutex); + + for (auto& pool : m_FreePools) + { + boost::polymorphic_downcast(pool.get())->ReleasePool(); + } + + for (auto& pool : m_OccupiedPools) + { + boost::polymorphic_downcast(pool.get())->ReleasePool(); + } +} + +} //namespace armnn \ No newline at end of file diff --git a/src/backends/aclCommon/memory/PoolManager.hpp b/src/backends/aclCommon/memory/PoolManager.hpp new file mode 100644 index 0000000000..39bc665415 --- /dev/null +++ b/src/backends/aclCommon/memory/PoolManager.hpp @@ -0,0 +1,57 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "IPoolManager.hpp" + +#include +#include + +#include +#include + +#include +#include +#include + +namespace armnn +{ + +class PoolManager : public IPoolManager +{ +public: + PoolManager(); + + PoolManager(const PoolManager &) = delete; + + PoolManager &operator=(const PoolManager &) = delete; + + PoolManager(PoolManager &&) = default; + + PoolManager &operator=(PoolManager &&) = default; + + arm_compute::IMemoryPool *lock_pool() override; + void unlock_pool(arm_compute::IMemoryPool *pool) override; + void register_pool(std::unique_ptr pool) override; + size_t num_pools() const override; + + void AllocatePools() override; + void ReleasePools() override; + +private: + /// List of free pools + std::list> m_FreePools; + + /// List of occupied pools + std::list> m_OccupiedPools; + + /// Semaphore to control the queues + std::unique_ptr m_Semaphore; + + /// Mutex to control access to the queues + mutable arm_compute::Mutex m_Mutex; +}; + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/cl/ClWorkloadFactory.cpp b/src/backends/cl/ClWorkloadFactory.cpp index 499d13d8e1..68d371388c 100644 --- a/src/backends/cl/ClWorkloadFactory.cpp +++ b/src/backends/cl/ClWorkloadFactory.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #endif #include diff --git a/src/backends/cl/ClWorkloadFactory.hpp b/src/backends/cl/ClWorkloadFactory.hpp index 59ae3b343a..9f8ec62db7 100644 --- a/src/backends/cl/ClWorkloadFactory.hpp +++ b/src/backends/cl/ClWorkloadFactory.hpp @@ -4,13 +4,13 @@ // #pragma once +#include + #include +#include -#include #include -#include "memory/BaseMemoryManager.hpp" - namespace armnn { diff --git a/src/backends/cl/OpenClTimer.hpp b/src/backends/cl/OpenClTimer.hpp index a7ae1387d9..0dc9ff7f2b 100644 --- a/src/backends/cl/OpenClTimer.hpp +++ b/src/backends/cl/OpenClTimer.hpp @@ -5,7 +5,7 @@ #pragma once -#include "Instrument.hpp" +#include #include #include diff --git a/src/backends/neon/NeonWorkloadFactory.cpp b/src/backends/neon/NeonWorkloadFactory.cpp index 4742ae9ebd..1e8ab1afa8 100644 --- a/src/backends/neon/NeonWorkloadFactory.cpp +++ b/src/backends/neon/NeonWorkloadFactory.cpp @@ -15,7 +15,7 @@ #include "workloads/NeonWorkloadUtils.hpp" #include "workloads/NeonWorkloads.hpp" -#include +#include #endif #include diff --git a/src/backends/neon/NeonWorkloadFactory.hpp b/src/backends/neon/NeonWorkloadFactory.hpp index 440bba672a..64951612c1 100644 --- a/src/backends/neon/NeonWorkloadFactory.hpp +++ b/src/backends/neon/NeonWorkloadFactory.hpp @@ -5,8 +5,7 @@ #pragma once #include - -#include +#include #include #include -- cgit v1.2.1