IVGCVSW-2006: Move ACL memory manager source code under aclCommon
authorAron Virginas-Tar <Aron.Virginas-Tar@arm.com>
Fri, 12 Oct 2018 14:18:03 +0000 (15:18 +0100)
committerMatthew Bentham <matthew.bentham@arm.com>
Mon, 22 Oct 2018 15:57:53 +0000 (16:57 +0100)
Change-Id: Ie1c74a18de5c3dd1cd5285c222bd6327489c1508

37 files changed:
Android.mk
CMakeLists.txt
src/armnn/memory/BaseMemoryManager.cpp [deleted file]
src/armnn/memory/BaseMemoryManager.hpp [deleted file]
src/armnn/memory/BlobLifetimeManager.cpp [deleted file]
src/armnn/memory/BlobLifetimeManager.hpp [deleted file]
src/armnn/memory/BlobMemoryPool.cpp [deleted file]
src/armnn/memory/BlobMemoryPool.hpp [deleted file]
src/armnn/memory/IMemoryPool.hpp [deleted file]
src/armnn/memory/IPoolManager.hpp [deleted file]
src/armnn/memory/OffsetLifetimeManager.cpp [deleted file]
src/armnn/memory/OffsetLifetimeManager.hpp [deleted file]
src/armnn/memory/OffsetMemoryPool.cpp [deleted file]
src/armnn/memory/OffsetMemoryPool.hpp [deleted file]
src/armnn/memory/PoolManager.cpp [deleted file]
src/armnn/memory/PoolManager.hpp [deleted file]
src/backends/aclCommon/CMakeLists.txt
src/backends/aclCommon/common.mk
src/backends/aclCommon/memory/BaseMemoryManager.cpp [new file with mode: 0644]
src/backends/aclCommon/memory/BaseMemoryManager.hpp [new file with mode: 0644]
src/backends/aclCommon/memory/BlobLifetimeManager.cpp [new file with mode: 0644]
src/backends/aclCommon/memory/BlobLifetimeManager.hpp [new file with mode: 0644]
src/backends/aclCommon/memory/BlobMemoryPool.cpp [new file with mode: 0644]
src/backends/aclCommon/memory/BlobMemoryPool.hpp [new file with mode: 0644]
src/backends/aclCommon/memory/IMemoryPool.hpp [new file with mode: 0644]
src/backends/aclCommon/memory/IPoolManager.hpp [new file with mode: 0644]
src/backends/aclCommon/memory/OffsetLifetimeManager.cpp [new file with mode: 0644]
src/backends/aclCommon/memory/OffsetLifetimeManager.hpp [new file with mode: 0644]
src/backends/aclCommon/memory/OffsetMemoryPool.cpp [new file with mode: 0644]
src/backends/aclCommon/memory/OffsetMemoryPool.hpp [new file with mode: 0644]
src/backends/aclCommon/memory/PoolManager.cpp [new file with mode: 0644]
src/backends/aclCommon/memory/PoolManager.hpp [new file with mode: 0644]
src/backends/cl/ClWorkloadFactory.cpp
src/backends/cl/ClWorkloadFactory.hpp
src/backends/cl/OpenClTimer.hpp
src/backends/neon/NeonWorkloadFactory.cpp
src/backends/neon/NeonWorkloadFactory.hpp

index 87fec7b309d67a80a16692383ecdd7bb4865528d..25ed8348520a79ba050d7453aaf917e698616c9e 100644 (file)
@@ -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 \
index 1956643fb7f4f75db2622d8815e338a6218fb7ae..22eeedde0310a374170477ff2f4d2af7aaa8b519 100644 (file)
@@ -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 (file)
index 041c042..0000000
+++ /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 <boost/polymorphic_cast.hpp>
-
-namespace armnn
-{
-
-#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED)
-BaseMemoryManager::BaseMemoryManager(std::unique_ptr<arm_compute::IAllocator> 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<arm_compute::MemoryManagerOnDemand>
-BaseMemoryManager::CreateArmComputeMemoryManager(MemoryAffinity memoryAffinity)
-{
-    std::shared_ptr<arm_compute::ILifetimeManager> lifetimeManager = nullptr;
-
-    if (memoryAffinity == MemoryAffinity::Buffer)
-    {
-        lifetimeManager = std::make_shared<BlobLifetimeManager>();
-    }
-    else
-    {
-        lifetimeManager = std::make_shared<OffsetLifetimeManager>();
-    }
-
-    auto poolManager   = std::make_shared<PoolManager>();
-    auto memoryManager = std::make_shared<arm_compute::MemoryManagerOnDemand>(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<IPoolManager*>(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<IPoolManager*>(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<IPoolManager*>(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<IPoolManager*>(m_InterLayerMemoryMgr->pool_manager());
-    BOOST_ASSERT(poolManager);
-    poolManager->ReleasePools();
-}
-#endif
-
-#ifdef ARMCOMPUTENEON_ENABLED
-std::shared_ptr<arm_compute::IMemoryGroup>
-NeonMemoryManager::CreateMemoryGroup(const std::shared_ptr<arm_compute::MemoryManagerOnDemand>& memoryManager)
-{
-    return std::make_shared<arm_compute::MemoryGroup>(memoryManager);
-}
-#endif
-
-#ifdef ARMCOMPUTECL_ENABLED
-std::shared_ptr<arm_compute::IMemoryGroup>
-ClMemoryManager::CreateMemoryGroup(const std::shared_ptr<arm_compute::MemoryManagerOnDemand>& memoryManager)
-{
-    return std::make_shared<arm_compute::CLMemoryGroup>(memoryManager);
-}
-#endif
-
-}
diff --git a/src/armnn/memory/BaseMemoryManager.hpp b/src/armnn/memory/BaseMemoryManager.hpp
deleted file mode 100644 (file)
index c82eca6..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-//
-// Copyright © 2017 Arm Ltd. All rights reserved.
-// SPDX-License-Identifier: MIT
-//
-#pragma once
-
-#include <backends/WorkloadFactory.hpp>
-
-#ifdef ARMCOMPUTENEON_ENABLED
-#include <arm_compute/runtime/MemoryGroup.h>
-#endif
-
-#ifdef ARMCOMPUTECL_ENABLED
-#include <arm_compute/runtime/CL/CLMemoryGroup.h>
-#endif
-
-#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED)
-#include <arm_compute/runtime/IAllocator.h>
-#include <arm_compute/runtime/IMemoryGroup.h>
-#include <arm_compute/runtime/MemoryManagerOnDemand.h>
-#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<arm_compute::IAllocator> alloc, MemoryAffinity memoryAffinity);
-
-    std::shared_ptr<arm_compute::MemoryManagerOnDemand>& GetIntraLayerManager() { return m_IntraLayerMemoryMgr; }
-    std::shared_ptr<arm_compute::MemoryManagerOnDemand>& GetInterLayerManager() { return m_InterLayerMemoryMgr; }
-    std::shared_ptr<arm_compute::IMemoryGroup>& GetInterLayerMemoryGroup()      { return m_InterLayerMemoryGroup; }
-
-    void Finalize();
-    void Acquire();
-    void Release();
-
-protected:
-
-    std::unique_ptr<arm_compute::IAllocator>            m_Allocator;
-    std::shared_ptr<arm_compute::MemoryManagerOnDemand> m_IntraLayerMemoryMgr;
-    std::shared_ptr<arm_compute::MemoryManagerOnDemand> m_InterLayerMemoryMgr;
-    std::shared_ptr<arm_compute::IMemoryGroup>          m_InterLayerMemoryGroup;
-
-    std::shared_ptr<arm_compute::MemoryManagerOnDemand> CreateArmComputeMemoryManager(MemoryAffinity memoryAffinity);
-
-    virtual std::shared_ptr<arm_compute::IMemoryGroup>
-    CreateMemoryGroup(const std::shared_ptr<arm_compute::MemoryManagerOnDemand>& memoryManager) = 0;
-
-    void FinalizeMemoryManager(arm_compute::MemoryManagerOnDemand& memoryManager);
-#endif
-};
-
-class NeonMemoryManager : public BaseMemoryManager
-{
-public:
-    NeonMemoryManager() {}
-    virtual ~NeonMemoryManager() {}
-
-#ifdef ARMCOMPUTENEON_ENABLED
-    NeonMemoryManager(std::unique_ptr<arm_compute::IAllocator> alloc, MemoryAffinity memoryAffinity)
-    : BaseMemoryManager(std::move(alloc), memoryAffinity)
-    {
-        m_InterLayerMemoryGroup = CreateMemoryGroup(m_InterLayerMemoryMgr);
-    }
-
-protected:
-    virtual std::shared_ptr<arm_compute::IMemoryGroup>
-    CreateMemoryGroup(const std::shared_ptr<arm_compute::MemoryManagerOnDemand>& memoryManager) override;
-#endif
-};
-
-class ClMemoryManager : public BaseMemoryManager
-{
-public:
-    ClMemoryManager() {}
-    virtual ~ClMemoryManager() {}
-
-#ifdef ARMCOMPUTECL_ENABLED
-    ClMemoryManager(std::unique_ptr<arm_compute::IAllocator> alloc)
-    : BaseMemoryManager(std::move(alloc), MemoryAffinity::Buffer)
-    {
-        m_InterLayerMemoryGroup = CreateMemoryGroup(m_InterLayerMemoryMgr);
-    }
-
-protected:
-    virtual std::shared_ptr<arm_compute::IMemoryGroup>
-    CreateMemoryGroup(const std::shared_ptr<arm_compute::MemoryManagerOnDemand>& 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 (file)
index fb8080c..0000000
+++ /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 <algorithm>
-
-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<size_t> 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<arm_compute::IMemoryPool> BlobLifetimeManager::create_pool(arm_compute::IAllocator* allocator)
-{
-    BOOST_ASSERT(allocator);
-    return std::make_unique<BlobMemoryPool>(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 (file)
index 7c93985..0000000
+++ /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<arm_compute::IMemoryPool> create_pool(arm_compute::IAllocator* allocator) override;
-
-    arm_compute::MappingType mapping_type() const override;
-
-private:
-    void update_blobs_and_mappings() override;
-
-    std::vector<size_t> 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 (file)
index 8b0a957..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-//
-// Copyright © 2017 Arm Ltd. All rights reserved.
-// SPDX-License-Identifier: MIT
-//
-#include "BlobMemoryPool.hpp"
-
-#include <boost/assert.hpp>
-
-namespace armnn
-{
-
-BlobMemoryPool::BlobMemoryPool(arm_compute::IAllocator* allocator, std::vector<size_t> 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<arm_compute::IMemoryPool> BlobMemoryPool::duplicate()
-{
-    BOOST_ASSERT(m_Allocator);
-    return std::make_unique<BlobMemoryPool>(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 (file)
index 26f2ccb..0000000
+++ /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<size_t> 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<arm_compute::IMemoryPool> 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<void*> m_Blobs;
-
-    /// Sizes of each memory blob
-    std::vector<size_t> 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 (file)
index e55c915..0000000
+++ /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 (file)
index 4fbca77..0000000
+++ /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 (file)
index 6d47972..0000000
+++ /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 <numeric>
-
-#include "boost/assert.hpp"
-
-namespace armnn
-{
-
-OffsetLifetimeManager::OffsetLifetimeManager()
-    : m_BlobSize(0)
-{
-}
-
-std::unique_ptr<arm_compute::IMemoryPool> OffsetLifetimeManager::create_pool(arm_compute::IAllocator* allocator)
-{
-    BOOST_ASSERT(allocator);
-    return std::make_unique<OffsetMemoryPool>(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<size_t>(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 (file)
index ab4de77..0000000
+++ /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<arm_compute::IMemoryPool> 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 (file)
index e5587cf..0000000
+++ /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 <algorithm>
-
-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<uint8_t*>(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<arm_compute::IMemoryPool> OffsetMemoryPool::duplicate()
-{
-    BOOST_ASSERT(m_Allocator);
-    return std::make_unique<OffsetMemoryPool>(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 (file)
index 6843744..0000000
+++ /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<arm_compute::IMemoryPool> 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 (file)
index 172c46b..0000000
+++ /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 <algorithm>
-
-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<arm_compute::Mutex> 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<arm_compute::Mutex> lock(m_Mutex);
-
-    auto it = std::find_if(
-            std::begin(m_OccupiedPools),
-            std::end(m_OccupiedPools),
-            [pool](const std::unique_ptr<arm_compute::IMemoryPool> &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<arm_compute::IMemoryPool> pool)
-{
-    std::lock_guard<arm_compute::Mutex> 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<arm_compute::Semaphore>(m_FreePools.size());
-}
-
-size_t PoolManager::num_pools() const
-{
-    std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
-
-    return m_FreePools.size() + m_OccupiedPools.size();
-}
-
-void PoolManager::AllocatePools()
-{
-    std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
-
-    for (auto& pool : m_FreePools)
-    {
-        boost::polymorphic_downcast<IMemoryPool*>(pool.get())->AllocatePool();
-    }
-
-    for (auto& pool : m_OccupiedPools)
-    {
-        boost::polymorphic_downcast<IMemoryPool*>(pool.get())->AllocatePool();
-    }
-}
-
-void PoolManager::ReleasePools()
-{
-    std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
-
-    for (auto& pool : m_FreePools)
-    {
-        boost::polymorphic_downcast<IMemoryPool*>(pool.get())->ReleasePool();
-    }
-
-    for (auto& pool : m_OccupiedPools)
-    {
-        boost::polymorphic_downcast<IMemoryPool*>(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 (file)
index bb84440..0000000
+++ /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 <cstddef>
-#include <list>
-#include <memory>
-
-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<arm_compute::IMemoryPool> pool) override;
-    size_t num_pools() const override;
-
-    void AllocatePools() override;
-    void ReleasePools() override;
-
-private:
-    /// List of free pools
-    std::list<std::unique_ptr<arm_compute::IMemoryPool>> m_FreePools;
-
-    /// List of occupied pools
-    std::list<std::unique_ptr<arm_compute::IMemoryPool>> m_OccupiedPools;
-
-    /// Semaphore to control the queues
-    std::unique_ptr<arm_compute::Semaphore> m_Semaphore;
-
-    /// Mutex to control access to the queues
-    mutable arm_compute::Mutex m_Mutex;
-};
-
-} // namespace armnn
\ No newline at end of file
index 6f99f4f146ee9716529437a21ae8c8e552cfb6ed..d99b90b897a2f1442256b647e2817f40763964d0 100644 (file)
@@ -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)
index b371bfab9edc5ad1b3731c9faafd2bc09444e341..9854f6fcb5bc309413880ad667056af866457186 100644 (file)
@@ -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 (file)
index 0000000..532692b
--- /dev/null
@@ -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 <boost/polymorphic_cast.hpp>
+
+namespace armnn
+{
+
+#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED)
+BaseMemoryManager::BaseMemoryManager(std::unique_ptr<arm_compute::IAllocator> 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<arm_compute::MemoryManagerOnDemand>
+BaseMemoryManager::CreateArmComputeMemoryManager(MemoryAffinity memoryAffinity)
+{
+    std::shared_ptr<arm_compute::ILifetimeManager> lifetimeManager = nullptr;
+
+    if (memoryAffinity == MemoryAffinity::Buffer)
+    {
+        lifetimeManager = std::make_shared<BlobLifetimeManager>();
+    }
+    else
+    {
+        lifetimeManager = std::make_shared<OffsetLifetimeManager>();
+    }
+
+    auto poolManager   = std::make_shared<PoolManager>();
+    auto memoryManager = std::make_shared<arm_compute::MemoryManagerOnDemand>(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<IPoolManager*>(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<IPoolManager*>(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<IPoolManager*>(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<IPoolManager*>(m_InterLayerMemoryMgr->pool_manager());
+    BOOST_ASSERT(poolManager);
+    poolManager->ReleasePools();
+}
+#endif
+
+#ifdef ARMCOMPUTENEON_ENABLED
+std::shared_ptr<arm_compute::IMemoryGroup>
+NeonMemoryManager::CreateMemoryGroup(const std::shared_ptr<arm_compute::MemoryManagerOnDemand>& memoryManager)
+{
+    return std::make_shared<arm_compute::MemoryGroup>(memoryManager);
+}
+#endif
+
+#ifdef ARMCOMPUTECL_ENABLED
+std::shared_ptr<arm_compute::IMemoryGroup>
+ClMemoryManager::CreateMemoryGroup(const std::shared_ptr<arm_compute::MemoryManagerOnDemand>& memoryManager)
+{
+    return std::make_shared<arm_compute::CLMemoryGroup>(memoryManager);
+}
+#endif
+
+}
diff --git a/src/backends/aclCommon/memory/BaseMemoryManager.hpp b/src/backends/aclCommon/memory/BaseMemoryManager.hpp
new file mode 100644 (file)
index 0000000..2afc1cb
--- /dev/null
@@ -0,0 +1,104 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include <backends/WorkloadFactory.hpp>
+
+#ifdef ARMCOMPUTENEON_ENABLED
+#include <arm_compute/runtime/MemoryGroup.h>
+#endif
+
+#ifdef ARMCOMPUTECL_ENABLED
+#include <arm_compute/runtime/CL/CLMemoryGroup.h>
+#endif
+
+#if defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED)
+#include <arm_compute/runtime/IAllocator.h>
+#include <arm_compute/runtime/IMemoryGroup.h>
+#include <arm_compute/runtime/MemoryManagerOnDemand.h>
+#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<arm_compute::IAllocator> alloc, MemoryAffinity memoryAffinity);
+
+    std::shared_ptr<arm_compute::MemoryManagerOnDemand>& GetIntraLayerManager() { return m_IntraLayerMemoryMgr; }
+    std::shared_ptr<arm_compute::MemoryManagerOnDemand>& GetInterLayerManager() { return m_InterLayerMemoryMgr; }
+    std::shared_ptr<arm_compute::IMemoryGroup>& GetInterLayerMemoryGroup()      { return m_InterLayerMemoryGroup; }
+
+    void Finalize();
+    void Acquire();
+    void Release();
+
+protected:
+
+    std::unique_ptr<arm_compute::IAllocator>            m_Allocator;
+    std::shared_ptr<arm_compute::MemoryManagerOnDemand> m_IntraLayerMemoryMgr;
+    std::shared_ptr<arm_compute::MemoryManagerOnDemand> m_InterLayerMemoryMgr;
+    std::shared_ptr<arm_compute::IMemoryGroup>          m_InterLayerMemoryGroup;
+
+    std::shared_ptr<arm_compute::MemoryManagerOnDemand> CreateArmComputeMemoryManager(MemoryAffinity memoryAffinity);
+
+    virtual std::shared_ptr<arm_compute::IMemoryGroup>
+    CreateMemoryGroup(const std::shared_ptr<arm_compute::MemoryManagerOnDemand>& memoryManager) = 0;
+
+    void FinalizeMemoryManager(arm_compute::MemoryManagerOnDemand& memoryManager);
+#endif
+};
+
+class NeonMemoryManager : public BaseMemoryManager
+{
+public:
+    NeonMemoryManager() {}
+    virtual ~NeonMemoryManager() {}
+
+#ifdef ARMCOMPUTENEON_ENABLED
+    NeonMemoryManager(std::unique_ptr<arm_compute::IAllocator> alloc, MemoryAffinity memoryAffinity)
+    : BaseMemoryManager(std::move(alloc), memoryAffinity)
+    {
+        m_InterLayerMemoryGroup = CreateMemoryGroup(m_InterLayerMemoryMgr);
+    }
+
+protected:
+    virtual std::shared_ptr<arm_compute::IMemoryGroup>
+    CreateMemoryGroup(const std::shared_ptr<arm_compute::MemoryManagerOnDemand>& memoryManager) override;
+#endif
+};
+
+class ClMemoryManager : public BaseMemoryManager
+{
+public:
+    ClMemoryManager() {}
+    virtual ~ClMemoryManager() {}
+
+#ifdef ARMCOMPUTECL_ENABLED
+    ClMemoryManager(std::unique_ptr<arm_compute::IAllocator> alloc)
+    : BaseMemoryManager(std::move(alloc), MemoryAffinity::Buffer)
+    {
+        m_InterLayerMemoryGroup = CreateMemoryGroup(m_InterLayerMemoryMgr);
+    }
+
+protected:
+    virtual std::shared_ptr<arm_compute::IMemoryGroup>
+    CreateMemoryGroup(const std::shared_ptr<arm_compute::MemoryManagerOnDemand>& 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 (file)
index 0000000..41100e9
--- /dev/null
@@ -0,0 +1,79 @@
+//
+// 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 <algorithm>
+
+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<size_t> 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<arm_compute::IMemoryPool> BlobLifetimeManager::create_pool(arm_compute::IAllocator* allocator)
+{
+    BOOST_ASSERT(allocator);
+    return std::make_unique<BlobMemoryPool>(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 (file)
index 0000000..d777ba5
--- /dev/null
@@ -0,0 +1,35 @@
+//
+// 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<arm_compute::IMemoryPool> create_pool(arm_compute::IAllocator* allocator) override;
+
+    arm_compute::MappingType mapping_type() const override;
+
+private:
+    void update_blobs_and_mappings() override;
+
+    std::vector<size_t> 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 (file)
index 0000000..8b0a957
--- /dev/null
@@ -0,0 +1,88 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#include "BlobMemoryPool.hpp"
+
+#include <boost/assert.hpp>
+
+namespace armnn
+{
+
+BlobMemoryPool::BlobMemoryPool(arm_compute::IAllocator* allocator, std::vector<size_t> 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<arm_compute::IMemoryPool> BlobMemoryPool::duplicate()
+{
+    BOOST_ASSERT(m_Allocator);
+    return std::make_unique<BlobMemoryPool>(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 (file)
index 0000000..4d42e6e
--- /dev/null
@@ -0,0 +1,55 @@
+//
+// 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<size_t> 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<arm_compute::IMemoryPool> 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<void*> m_Blobs;
+
+    /// Sizes of each memory blob
+    std::vector<size_t> 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 (file)
index 0000000..9913069
--- /dev/null
@@ -0,0 +1,22 @@
+//
+// 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/backends/aclCommon/memory/IPoolManager.hpp b/src/backends/aclCommon/memory/IPoolManager.hpp
new file mode 100644 (file)
index 0000000..be15fdd
--- /dev/null
@@ -0,0 +1,21 @@
+//
+// 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/backends/aclCommon/memory/OffsetLifetimeManager.cpp b/src/backends/aclCommon/memory/OffsetLifetimeManager.cpp
new file mode 100644 (file)
index 0000000..d0174f8
--- /dev/null
@@ -0,0 +1,62 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#include "OffsetLifetimeManager.hpp"
+#include "OffsetMemoryPool.hpp"
+
+#include <arm_compute/runtime/IMemoryGroup.h>
+
+#include <numeric>
+
+#include <boost/assert.hpp>
+
+namespace armnn
+{
+
+OffsetLifetimeManager::OffsetLifetimeManager()
+    : m_BlobSize(0)
+{
+}
+
+std::unique_ptr<arm_compute::IMemoryPool> OffsetLifetimeManager::create_pool(arm_compute::IAllocator* allocator)
+{
+    BOOST_ASSERT(allocator);
+    return std::make_unique<OffsetMemoryPool>(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<size_t>(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 (file)
index 0000000..1283193
--- /dev/null
@@ -0,0 +1,37 @@
+//
+// 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<arm_compute::IMemoryPool> 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 (file)
index 0000000..48bea5e
--- /dev/null
@@ -0,0 +1,84 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#include "OffsetMemoryPool.hpp"
+
+#include <boost/assert.hpp>
+
+#include <algorithm>
+
+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<uint8_t*>(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<arm_compute::IMemoryPool> OffsetMemoryPool::duplicate()
+{
+    BOOST_ASSERT(m_Allocator);
+    return std::make_unique<OffsetMemoryPool>(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 (file)
index 0000000..25cf8cd
--- /dev/null
@@ -0,0 +1,54 @@
+//
+// 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<arm_compute::IMemoryPool> 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 (file)
index 0000000..363b459
--- /dev/null
@@ -0,0 +1,105 @@
+//
+// 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 <algorithm>
+
+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<arm_compute::Mutex> 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<arm_compute::Mutex> lock(m_Mutex);
+
+    auto it = std::find_if(
+            std::begin(m_OccupiedPools),
+            std::end(m_OccupiedPools),
+            [pool](const std::unique_ptr<arm_compute::IMemoryPool> &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<arm_compute::IMemoryPool> pool)
+{
+    std::lock_guard<arm_compute::Mutex> 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<arm_compute::Semaphore>(m_FreePools.size());
+}
+
+size_t PoolManager::num_pools() const
+{
+    std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
+
+    return m_FreePools.size() + m_OccupiedPools.size();
+}
+
+void PoolManager::AllocatePools()
+{
+    std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
+
+    for (auto& pool : m_FreePools)
+    {
+        boost::polymorphic_downcast<IMemoryPool*>(pool.get())->AllocatePool();
+    }
+
+    for (auto& pool : m_OccupiedPools)
+    {
+        boost::polymorphic_downcast<IMemoryPool*>(pool.get())->AllocatePool();
+    }
+}
+
+void PoolManager::ReleasePools()
+{
+    std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
+
+    for (auto& pool : m_FreePools)
+    {
+        boost::polymorphic_downcast<IMemoryPool*>(pool.get())->ReleasePool();
+    }
+
+    for (auto& pool : m_OccupiedPools)
+    {
+        boost::polymorphic_downcast<IMemoryPool*>(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 (file)
index 0000000..39bc665
--- /dev/null
@@ -0,0 +1,57 @@
+//
+// 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 <cstddef>
+#include <list>
+#include <memory>
+
+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<arm_compute::IMemoryPool> pool) override;
+    size_t num_pools() const override;
+
+    void AllocatePools() override;
+    void ReleasePools() override;
+
+private:
+    /// List of free pools
+    std::list<std::unique_ptr<arm_compute::IMemoryPool>> m_FreePools;
+
+    /// List of occupied pools
+    std::list<std::unique_ptr<arm_compute::IMemoryPool>> m_OccupiedPools;
+
+    /// Semaphore to control the queues
+    std::unique_ptr<arm_compute::Semaphore> m_Semaphore;
+
+    /// Mutex to control access to the queues
+    mutable arm_compute::Mutex m_Mutex;
+};
+
+} // namespace armnn
\ No newline at end of file
index 499d13d8e1a8d6084cb6d58449b797871b56cfab..68d371388c1e6cce51ba0a6934d0e030f1688f48 100644 (file)
@@ -21,7 +21,7 @@
 #include <backends/MemCopyWorkload.hpp>
 #include <backends/cl/ClTensorHandle.hpp>
 
-#include <memory/IPoolManager.hpp>
+#include <backends/aclCommon/memory/IPoolManager.hpp>
 #endif
 
 #include <backends/MakeWorkloadHelper.hpp>
index 59ae3b343ad2fea3132dd4021676c892c2080b0f..9f8ec62db7505e7827fe1132954f284cb741f377 100644 (file)
@@ -4,13 +4,13 @@
 //
 #pragma once
 
+#include <armnn/IRuntime.hpp>
+
 #include <backends/OutputHandler.hpp>
+#include <backends/aclCommon/memory/BaseMemoryManager.hpp>
 
-#include <armnn/IRuntime.hpp>
 #include <boost/optional.hpp>
 
-#include "memory/BaseMemoryManager.hpp"
-
 namespace armnn
 {
 
index a7ae1387d9019aee693d81f26b9e9c5a56fde8ef..0dc9ff7f2b09d63e1bddf28357bf966163ae52f2 100644 (file)
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "Instrument.hpp"
+#include <armnn/Instrument.hpp>
 
 #include <arm_compute/runtime/CL/CLScheduler.h>
 #include <arm_compute/core/CL/OpenCL.h>
index 4742ae9ebde040ec8e3a4624a0a9eda35fd159ba..1e8ab1afa88dc4ede5b56bd0b1fc20b72b5cceb3 100644 (file)
@@ -15,7 +15,7 @@
 #include "workloads/NeonWorkloadUtils.hpp"
 #include "workloads/NeonWorkloads.hpp"
 
-#include <memory/IPoolManager.hpp>
+#include <backends/aclCommon/memory/IPoolManager.hpp>
 #endif
 
 #include <backends/MakeWorkloadHelper.hpp>
index 440bba672af73ac52f005c46bec5ce182baebe53..64951612c148842c06861474d43403d5b56a2e30 100644 (file)
@@ -5,8 +5,7 @@
 #pragma once
 
 #include <backends/OutputHandler.hpp>
-
-#include <memory/BaseMemoryManager.hpp>
+#include <backends/aclCommon/memory/BaseMemoryManager.hpp>
 
 #include <boost/core/ignore_unused.hpp>
 #include <boost/optional.hpp>