aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgios Pinitas <georgios.pinitas@arm.com>2018-12-14 17:11:20 +0000
committerMichele Di Giorgio <michele.digiorgio@arm.com>2018-12-14 19:45:00 +0000
commit555f1c2241d6fa8c84926a72a0c54e4158817df4 (patch)
tree0ec5da469c28559d8c5df9848cfa3ada6e0646e8
parentb4af2c6738614850aaca3754904f0e8e3b17f0b2 (diff)
downloadComputeLibrary-555f1c2241d6fa8c84926a72a0c54e4158817df4.tar.gz
COMPMID-1710: Account alignment for blob-base allocations
Change-Id: I290d33e25a5966d25a91df39ebc01c28bfa31f78 Reviewed-on: https://review.mlplatform.org/402 Reviewed-by: Anthony Barbier <Anthony.barbier@arm.com> Tested-by: Arm Jenkins <bsgcomp@arm.com>
-rw-r--r--arm_compute/runtime/BlobLifetimeManager.h6
-rw-r--r--arm_compute/runtime/BlobMemoryPool.h28
-rw-r--r--arm_compute/runtime/ILifetimeManager.h3
-rw-r--r--arm_compute/runtime/ISimpleLifetimeManager.h16
-rw-r--r--arm_compute/runtime/MemoryGroupBase.h7
-rw-r--r--arm_compute/runtime/Types.h3
-rw-r--r--src/runtime/Allocator.cpp3
-rw-r--r--src/runtime/BlobLifetimeManager.cpp14
-rw-r--r--src/runtime/BlobMemoryPool.cpp14
-rw-r--r--src/runtime/ISimpleLifetimeManager.cpp18
-rw-r--r--src/runtime/TensorAllocator.cpp2
11 files changed, 66 insertions, 48 deletions
diff --git a/arm_compute/runtime/BlobLifetimeManager.h b/arm_compute/runtime/BlobLifetimeManager.h
index edf4d43421..2dbe92d7b6 100644
--- a/arm_compute/runtime/BlobLifetimeManager.h
+++ b/arm_compute/runtime/BlobLifetimeManager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017-2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -26,7 +26,7 @@
#include "arm_compute/runtime/ISimpleLifetimeManager.h"
-#include "arm_compute/runtime/IMemoryPool.h"
+#include "arm_compute/runtime/BlobMemoryPool.h"
#include "arm_compute/runtime/Types.h"
#include <cstddef>
@@ -60,7 +60,7 @@ private:
void update_blobs_and_mappings() override;
private:
- std::vector<size_t> _blobs; /**< Memory blobs' sizes */
+ std::vector<BlobInfo> _blobs; /**< Memory blobs */
};
} // namespace arm_compute
#endif /* __ARM_COMPUTE_BLOBLIFETIMEMANAGER_H__ */
diff --git a/arm_compute/runtime/BlobMemoryPool.h b/arm_compute/runtime/BlobMemoryPool.h
index c9c4da0f54..ba97dbd94e 100644
--- a/arm_compute/runtime/BlobMemoryPool.h
+++ b/arm_compute/runtime/BlobMemoryPool.h
@@ -35,8 +35,20 @@
namespace arm_compute
{
+// Forward declaration
class IAllocator;
+/** Meta-data information for each blob */
+struct BlobInfo
+{
+ BlobInfo(size_t size_ = 0, size_t alignment_ = 0)
+ : size(size_), alignment(alignment_)
+ {
+ }
+ size_t size; /**< Blob size */
+ size_t alignment; /**< Blob alignment */
+};
+
/** Blob memory pool */
class BlobMemoryPool : public IMemoryPool
{
@@ -45,10 +57,10 @@ public:
*
* @note allocator should outlive the memory pool
*
- * @param[in] allocator Backing memory allocator
- * @param[in] blob_sizes Sizes of the blobs to be allocated
+ * @param[in] allocator Backing memory allocator
+ * @param[in] blob_info Configuration information of the blobs to be allocated
*/
- BlobMemoryPool(IAllocator *allocator, std::vector<size_t> blob_sizes);
+ BlobMemoryPool(IAllocator *allocator, std::vector<BlobInfo> blob_info);
/** Default Destructor */
~BlobMemoryPool();
/** Prevent instances of this class to be copy constructed */
@@ -69,16 +81,16 @@ public:
private:
/** Allocates internal blobs
*
- * @param sizes Size of each blob
+ * @param blob_info Size of each blob
*/
- void allocate_blobs(const std::vector<size_t> &sizes);
+ void allocate_blobs(const std::vector<BlobInfo> &blob_info);
/** Frees blobs **/
void free_blobs();
private:
- IAllocator *_allocator; /**< Allocator to use for internal allocation */
- std::vector<std::unique_ptr<IMemoryRegion>> _blobs; /**< Vector holding all the memory blobs */
- std::vector<size_t> _blob_sizes; /**< Sizes of each blob */
+ IAllocator *_allocator; /**< Allocator to use for internal allocation */
+ std::vector<std::unique_ptr<IMemoryRegion>> _blobs; /**< Vector holding all the memory blobs */
+ std::vector<BlobInfo> _blob_info; /**< Information of each blob */
};
} // namespace arm_compute
#endif /* __ARM_COMPUTE_BLOBMEMORYPOOL_H__ */
diff --git a/arm_compute/runtime/ILifetimeManager.h b/arm_compute/runtime/ILifetimeManager.h
index f2e9b497c9..3684ddf8fb 100644
--- a/arm_compute/runtime/ILifetimeManager.h
+++ b/arm_compute/runtime/ILifetimeManager.h
@@ -58,8 +58,9 @@ public:
* @param[in] obj Object
* @param[in] obj_memory Object memory
* @param[in] size Size of the given object at given time
+ * @param[in] alignment Alignment requirements for the object
*/
- virtual void end_lifetime(void *obj, IMemory &obj_memory, size_t size) = 0;
+ virtual void end_lifetime(void *obj, IMemory &obj_memory, size_t size, size_t alignment) = 0;
/** Checks if the lifetime of the registered object is complete
*
* @return True if all object lifetimes are finalized else false.
diff --git a/arm_compute/runtime/ISimpleLifetimeManager.h b/arm_compute/runtime/ISimpleLifetimeManager.h
index f2eb4f5904..4384283b94 100644
--- a/arm_compute/runtime/ISimpleLifetimeManager.h
+++ b/arm_compute/runtime/ISimpleLifetimeManager.h
@@ -58,7 +58,7 @@ public:
// Inherited methods overridden:
void register_group(IMemoryGroup *group) override;
void start_lifetime(void *obj) override;
- void end_lifetime(void *obj, IMemory &obj_memory, size_t size) override;
+ void end_lifetime(void *obj, IMemory &obj_memory, size_t size, size_t alignment) override;
bool are_all_finalized() const override;
protected:
@@ -69,14 +69,15 @@ protected:
/** Element struct */
struct Element
{
- Element(void *id_ = nullptr, IMemory *handle_ = nullptr, size_t size_ = 0, bool status_ = false)
- : id(id_), handle(handle_), size(size_), status(status_)
+ Element(void *id_ = nullptr, IMemory *handle_ = nullptr, size_t size_ = 0, size_t alignment_ = 0, bool status_ = false)
+ : id(id_), handle(handle_), size(size_), alignment(alignment_), status(status_)
{
}
- void *id; /**< Element id */
- IMemory *handle; /**< Element's memory handle */
- size_t size; /**< Element's size */
- bool status; /**< Lifetime status */
+ void *id; /**< Element id */
+ IMemory *handle; /**< Element's memory handle */
+ size_t size; /**< Element's size */
+ size_t alignment; /**< Alignment requirement */
+ bool status; /**< Lifetime status */
};
/** Blob struct */
@@ -84,6 +85,7 @@ protected:
{
void *id;
size_t max_size;
+ size_t max_alignment;
std::set<void *> bound_elements;
};
diff --git a/arm_compute/runtime/MemoryGroupBase.h b/arm_compute/runtime/MemoryGroupBase.h
index 0ceaa900c5..7dc18c8b4f 100644
--- a/arm_compute/runtime/MemoryGroupBase.h
+++ b/arm_compute/runtime/MemoryGroupBase.h
@@ -70,8 +70,9 @@ public:
* @param[in, out] obj_memory Object's memory handling interface which can be used to alter the underlying memory
* that is used by the object.
* @param[in] size Size of memory to allocate
+ * @param[in] alignment (Optional) Alignment to use
*/
- void finalize_memory(TensorType *obj, IMemory &obj_memory, size_t size);
+ void finalize_memory(TensorType *obj, IMemory &obj_memory, size_t size, size_t alignment = 0);
// Inherited methods overridden:
void acquire() override;
@@ -116,7 +117,7 @@ inline void MemoryGroupBase<TensorType>::manage(TensorType *obj)
}
template <typename TensorType>
-inline void MemoryGroupBase<TensorType>::finalize_memory(TensorType *obj, IMemory &obj_memory, size_t size)
+inline void MemoryGroupBase<TensorType>::finalize_memory(TensorType *obj, IMemory &obj_memory, size_t size, size_t alignment)
{
// TODO (geopin01) : Check size (track size in MemoryMappings)
// Check if existing mapping is valid
@@ -125,7 +126,7 @@ inline void MemoryGroupBase<TensorType>::finalize_memory(TensorType *obj, IMemor
if(_memory_manager && _mappings.empty())
{
ARM_COMPUTE_ERROR_ON(!_memory_manager->lifetime_manager());
- _memory_manager->lifetime_manager()->end_lifetime(obj, obj_memory, size);
+ _memory_manager->lifetime_manager()->end_lifetime(obj, obj_memory, size, alignment);
}
}
diff --git a/arm_compute/runtime/Types.h b/arm_compute/runtime/Types.h
index b962427ef8..f2607c0204 100644
--- a/arm_compute/runtime/Types.h
+++ b/arm_compute/runtime/Types.h
@@ -46,6 +46,5 @@ using MemoryMappings = std::map<IMemory *, size_t>;
/** A map of the groups and memory mappings */
using GroupMappings = std::map<size_t, MemoryMappings>;
-
-} // arm_compute
+} // namespace arm_compute
#endif /* __ARM_COMPUTE_RUNTIME_TYPES_H__ */
diff --git a/src/runtime/Allocator.cpp b/src/runtime/Allocator.cpp
index 7f0e37495e..d9de11ebbf 100644
--- a/src/runtime/Allocator.cpp
+++ b/src/runtime/Allocator.cpp
@@ -44,6 +44,5 @@ void Allocator::free(void *ptr)
std::unique_ptr<IMemoryRegion> Allocator::make_region(size_t size, size_t alignment)
{
- ARM_COMPUTE_UNUSED(alignment);
- return arm_compute::support::cpp14::make_unique<MemoryRegion>(size);
+ return arm_compute::support::cpp14::make_unique<MemoryRegion>(size, alignment);
} \ No newline at end of file
diff --git a/src/runtime/BlobLifetimeManager.cpp b/src/runtime/BlobLifetimeManager.cpp
index 2a4ab6ec0d..9fef943fb5 100644
--- a/src/runtime/BlobLifetimeManager.cpp
+++ b/src/runtime/BlobLifetimeManager.cpp
@@ -62,19 +62,21 @@ void BlobLifetimeManager::update_blobs_and_mappings()
{
return ba.max_size > bb.max_size;
});
- std::vector<size_t> group_sizes;
+
+ // Create group sizes vector
+ std::vector<BlobInfo> group_sizes;
std::transform(std::begin(_free_blobs), std::end(_free_blobs), std::back_inserter(group_sizes), [](const Blob & b)
{
- return b.max_size;
+ return BlobInfo(b.max_size, b.max_alignment);
});
// Update blob sizes
size_t max_size = std::max(_blobs.size(), group_sizes.size());
- _blobs.resize(max_size, 0);
- group_sizes.resize(max_size, 0);
- std::transform(std::begin(_blobs), std::end(_blobs), std::begin(group_sizes), std::begin(_blobs), [](size_t lhs, size_t rhs)
+ _blobs.resize(max_size);
+ group_sizes.resize(max_size);
+ std::transform(std::begin(_blobs), std::end(_blobs), std::begin(group_sizes), std::begin(_blobs), [](BlobInfo lhs, BlobInfo rhs)
{
- return std::max(lhs, rhs);
+ return BlobInfo(std::max(lhs.size, rhs.size), std::max(lhs.alignment, rhs.alignment));
});
// Calculate group mappings
diff --git a/src/runtime/BlobMemoryPool.cpp b/src/runtime/BlobMemoryPool.cpp
index e09451cd62..812cbdd673 100644
--- a/src/runtime/BlobMemoryPool.cpp
+++ b/src/runtime/BlobMemoryPool.cpp
@@ -33,11 +33,11 @@
using namespace arm_compute;
-BlobMemoryPool::BlobMemoryPool(IAllocator *allocator, std::vector<size_t> blob_sizes)
- : _allocator(allocator), _blobs(), _blob_sizes(std::move(blob_sizes))
+BlobMemoryPool::BlobMemoryPool(IAllocator *allocator, std::vector<BlobInfo> blob_info)
+ : _allocator(allocator), _blobs(), _blob_info(std::move(blob_info))
{
ARM_COMPUTE_ERROR_ON(!allocator);
- allocate_blobs(_blob_sizes);
+ allocate_blobs(_blob_info);
}
BlobMemoryPool::~BlobMemoryPool()
@@ -73,16 +73,16 @@ MappingType BlobMemoryPool::mapping_type() const
std::unique_ptr<IMemoryPool> BlobMemoryPool::duplicate()
{
ARM_COMPUTE_ERROR_ON(!_allocator);
- return support::cpp14::make_unique<BlobMemoryPool>(_allocator, _blob_sizes);
+ return support::cpp14::make_unique<BlobMemoryPool>(_allocator, _blob_info);
}
-void BlobMemoryPool::allocate_blobs(const std::vector<size_t> &sizes)
+void BlobMemoryPool::allocate_blobs(const std::vector<BlobInfo> &blob_info)
{
ARM_COMPUTE_ERROR_ON(!_allocator);
- for(const auto &size : sizes)
+ for(const auto &bi : blob_info)
{
- _blobs.push_back(_allocator->make_region(size, 0));
+ _blobs.push_back(_allocator->make_region(bi.size, bi.alignment));
}
}
diff --git a/src/runtime/ISimpleLifetimeManager.cpp b/src/runtime/ISimpleLifetimeManager.cpp
index 7d928d6a7a..97c20d1882 100644
--- a/src/runtime/ISimpleLifetimeManager.cpp
+++ b/src/runtime/ISimpleLifetimeManager.cpp
@@ -59,7 +59,7 @@ void ISimpleLifetimeManager::start_lifetime(void *obj)
// Check if there is a free blob
if(_free_blobs.empty())
{
- _occupied_blobs.emplace_front(Blob{ obj, 0, { obj } });
+ _occupied_blobs.emplace_front(Blob{ obj, 0, 0, { obj } });
}
else
{
@@ -71,7 +71,7 @@ void ISimpleLifetimeManager::start_lifetime(void *obj)
_active_elements.insert(std::make_pair(obj, obj));
}
-void ISimpleLifetimeManager::end_lifetime(void *obj, IMemory &obj_memory, size_t size)
+void ISimpleLifetimeManager::end_lifetime(void *obj, IMemory &obj_memory, size_t size, size_t alignment)
{
ARM_COMPUTE_ERROR_ON(obj == nullptr);
@@ -80,10 +80,11 @@ void ISimpleLifetimeManager::end_lifetime(void *obj, IMemory &obj_memory, size_t
ARM_COMPUTE_ERROR_ON(active_object_it == std::end(_active_elements));
// Update object fields and mark object as complete
- Element &el = active_object_it->second;
- el.handle = &obj_memory;
- el.size = size;
- el.status = true;
+ Element &el = active_object_it->second;
+ el.handle = &obj_memory;
+ el.size = size;
+ el.alignment = alignment;
+ el.status = true;
// Find object in the occupied lists
auto occupied_blob_it = std::find_if(std::begin(_occupied_blobs), std::end(_occupied_blobs), [&obj](const Blob & b)
@@ -94,8 +95,9 @@ void ISimpleLifetimeManager::end_lifetime(void *obj, IMemory &obj_memory, size_t
// Update occupied blob and return as free
occupied_blob_it->bound_elements.insert(obj);
- occupied_blob_it->max_size = std::max(occupied_blob_it->max_size, size);
- occupied_blob_it->id = nullptr;
+ occupied_blob_it->max_size = std::max(occupied_blob_it->max_size, size);
+ occupied_blob_it->max_alignment = std::max(occupied_blob_it->max_alignment, alignment);
+ occupied_blob_it->id = nullptr;
_free_blobs.splice(std::begin(_free_blobs), _occupied_blobs, occupied_blob_it);
// Check if all object are finalized and reset active group
diff --git a/src/runtime/TensorAllocator.cpp b/src/runtime/TensorAllocator.cpp
index 5fa51d7140..38edb8ba03 100644
--- a/src/runtime/TensorAllocator.cpp
+++ b/src/runtime/TensorAllocator.cpp
@@ -138,7 +138,7 @@ void TensorAllocator::allocate()
}
else
{
- _associated_memory_group->finalize_memory(_owner, _memory, info().total_size());
+ _associated_memory_group->finalize_memory(_owner, _memory, info().total_size(), alignment());
}
info().set_is_resizable(false);
}