aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Bentham <Matthew.Bentham@arm.com>2019-06-21 17:22:23 +0100
committerMatthew Bentham <matthew.bentham@arm.com>2019-07-04 09:10:46 +0000
commit7c1603a4e310c5b7b0d3bdddc0c80a63a7661107 (patch)
tree9be52766d80394d253b2b51f4ef8fd136272cf6e
parentf9ac3fd5676565b1065698158f8d54a27f24981c (diff)
downloadarmnn-7c1603a4e310c5b7b0d3bdddc0c80a63a7661107.tar.gz
IVGCVSW-3307 Add RefMemoryManager
Simple pool memory manager for use in the reference backend, in order to make the backend usable for testing large networks. Change-Id: I5694da29052c60f95b57da595c64cc114d75b8ba Signed-off-by: Matthew Bentham <Matthew.Bentham@arm.com>
-rw-r--r--src/armnnOnnxParser/test/BatchNorm.cpp2
-rw-r--r--src/backends/cl/ClTensorHandle.hpp1
-rw-r--r--src/backends/reference/CMakeLists.txt2
-rw-r--r--src/backends/reference/RefBackend.cpp5
-rw-r--r--src/backends/reference/RefMemoryManager.cpp100
-rw-r--r--src/backends/reference/RefMemoryManager.hpp59
-rw-r--r--src/backends/reference/RefTensorHandle.cpp66
-rw-r--r--src/backends/reference/RefTensorHandle.hpp29
-rw-r--r--src/backends/reference/RefWorkloadFactory.cpp10
-rw-r--r--src/backends/reference/RefWorkloadFactory.hpp8
-rw-r--r--src/backends/reference/backend.mk2
-rw-r--r--src/backends/reference/test/CMakeLists.txt2
-rw-r--r--src/backends/reference/test/RefCreateWorkloadTests.cpp48
-rw-r--r--src/backends/reference/test/RefMemoryManagerTests.cpp51
-rw-r--r--src/backends/reference/test/RefTensorHandleTests.cpp48
-rw-r--r--src/backends/reference/workloads/RefDebugWorkload.cpp1
16 files changed, 383 insertions, 51 deletions
diff --git a/src/armnnOnnxParser/test/BatchNorm.cpp b/src/armnnOnnxParser/test/BatchNorm.cpp
index 3e91feb0ca..bbe961604c 100644
--- a/src/armnnOnnxParser/test/BatchNorm.cpp
+++ b/src/armnnOnnxParser/test/BatchNorm.cpp
@@ -334,7 +334,7 @@ struct BatchNormalizationBisFixture : public armnnUtils::ParserPrototxtFixture<a
BOOST_FIXTURE_TEST_CASE(ValidBatchNormalizationBisTest, BatchNormalizationBisFixture)
{
- RunTest<4>({{"Input", {-1, 0.0, 1, 2, 3.0, 4.0}}}, // Input data.
+ RunTest<4>({{"Input", {-1, 0.0, 1, 2, 3.0, 4.0}}}, // Input data.
{{"Output", {-0.999995f, 0.0, 0.999995f,
-0.22474074f, 1.0f, 2.2247407f}}}); // Expected output data.
}
diff --git a/src/backends/cl/ClTensorHandle.hpp b/src/backends/cl/ClTensorHandle.hpp
index c0773a4ea4..f09fb024e0 100644
--- a/src/backends/cl/ClTensorHandle.hpp
+++ b/src/backends/cl/ClTensorHandle.hpp
@@ -60,6 +60,7 @@ public:
const_cast<arm_compute::CLTensor*>(&m_Tensor)->map(blocking);
return static_cast<const void*>(m_Tensor.buffer() + m_Tensor.info()->offset_first_element_in_bytes());
}
+
virtual void Unmap() const override { const_cast<arm_compute::CLTensor*>(&m_Tensor)->unmap(); }
virtual ITensorHandle* GetParent() const override { return nullptr; }
diff --git a/src/backends/reference/CMakeLists.txt b/src/backends/reference/CMakeLists.txt
index fabffea296..281e91628f 100644
--- a/src/backends/reference/CMakeLists.txt
+++ b/src/backends/reference/CMakeLists.txt
@@ -11,6 +11,8 @@ list(APPEND armnnRefBackend_sources
RefTensorHandle.cpp
RefLayerSupport.cpp
RefLayerSupport.hpp
+ RefMemoryManager.hpp
+ RefMemoryManager.cpp
RefWorkloadFactory.cpp
RefWorkloadFactory.hpp
)
diff --git a/src/backends/reference/RefBackend.cpp b/src/backends/reference/RefBackend.cpp
index 0a296be016..3680831fb3 100644
--- a/src/backends/reference/RefBackend.cpp
+++ b/src/backends/reference/RefBackend.cpp
@@ -15,6 +15,7 @@
#include <Optimizer.hpp>
#include <boost/cast.hpp>
+#include <boost/polymorphic_pointer_cast.hpp>
namespace armnn
{
@@ -43,7 +44,7 @@ const BackendId& RefBackend::GetIdStatic()
IBackendInternal::IWorkloadFactoryPtr RefBackend::CreateWorkloadFactory(
const IBackendInternal::IMemoryManagerSharedPtr& memoryManager) const
{
- return std::make_unique<RefWorkloadFactory>();
+ return std::make_unique<RefWorkloadFactory>(boost::polymorphic_pointer_downcast<RefMemoryManager>(memoryManager));
}
IBackendInternal::IBackendContextPtr RefBackend::CreateBackendContext(const IRuntime::CreationOptions&) const
@@ -53,7 +54,7 @@ IBackendInternal::IBackendContextPtr RefBackend::CreateBackendContext(const IRun
IBackendInternal::IMemoryManagerUniquePtr RefBackend::CreateMemoryManager() const
{
- return IMemoryManagerUniquePtr{};
+ return std::make_unique<RefMemoryManager>();
}
IBackendInternal::Optimizations RefBackend::GetOptimizations() const
diff --git a/src/backends/reference/RefMemoryManager.cpp b/src/backends/reference/RefMemoryManager.cpp
new file mode 100644
index 0000000000..0f4a289807
--- /dev/null
+++ b/src/backends/reference/RefMemoryManager.cpp
@@ -0,0 +1,100 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#include "RefMemoryManager.hpp"
+
+#include <boost/assert.hpp>
+
+namespace armnn
+{
+
+RefMemoryManager::RefMemoryManager()
+{}
+
+RefMemoryManager::~RefMemoryManager()
+{}
+
+RefMemoryManager::Pool* RefMemoryManager::Manage(unsigned int numBytes)
+{
+ if (!m_FreePools.empty())
+ {
+ Pool* res = m_FreePools.back();
+ m_FreePools.pop_back();
+ res->Reserve(numBytes);
+ return res;
+ }
+ else
+ {
+ m_Pools.push_front(Pool(numBytes));
+ return &m_Pools.front();
+ }
+}
+
+void RefMemoryManager::Allocate(RefMemoryManager::Pool* pool)
+{
+ BOOST_ASSERT(pool);
+ m_FreePools.push_back(pool);
+}
+
+void* RefMemoryManager::GetPointer(RefMemoryManager::Pool* pool)
+{
+ return pool->GetPointer();
+}
+
+void RefMemoryManager::Acquire()
+{
+ for (Pool &pool: m_Pools)
+ {
+ pool.Acquire();
+ }
+}
+
+void RefMemoryManager::Release()
+{
+ for (Pool &pool: m_Pools)
+ {
+ pool.Release();
+ }
+}
+
+RefMemoryManager::Pool::Pool(unsigned int numBytes)
+ : m_Size(numBytes),
+ m_Pointer(nullptr)
+{}
+
+RefMemoryManager::Pool::~Pool()
+{
+ if (m_Pointer)
+ {
+ Release();
+ }
+}
+
+void* RefMemoryManager::Pool::GetPointer()
+{
+ BOOST_ASSERT_MSG(m_Pointer, "RefMemoryManager::Pool::GetPointer() called when memory not acquired");
+ return m_Pointer;
+}
+
+void RefMemoryManager::Pool::Reserve(unsigned int numBytes)
+{
+ BOOST_ASSERT_MSG(!m_Pointer, "RefMemoryManager::Pool::Reserve() cannot be called after memory acquired");
+ m_Size = std::max(m_Size, numBytes);
+}
+
+void RefMemoryManager::Pool::Acquire()
+{
+ BOOST_ASSERT_MSG(!m_Pointer, "RefMemoryManager::Pool::Acquire() called when memory already acquired");
+ BOOST_ASSERT(m_Size >= 0);
+ m_Pointer = ::operator new(size_t(m_Size));
+}
+
+void RefMemoryManager::Pool::Release()
+{
+ BOOST_ASSERT_MSG(m_Pointer, "RefMemoryManager::Pool::Release() called when memory not acquired");
+ ::operator delete(m_Pointer);
+ m_Pointer = nullptr;
+}
+
+}
diff --git a/src/backends/reference/RefMemoryManager.hpp b/src/backends/reference/RefMemoryManager.hpp
new file mode 100644
index 0000000000..5daac79e36
--- /dev/null
+++ b/src/backends/reference/RefMemoryManager.hpp
@@ -0,0 +1,59 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include <backendsCommon/IMemoryManager.hpp>
+
+#include <forward_list>
+#include <vector>
+
+namespace armnn
+{
+
+// An implementation of IMemoryManager to be used with RefTensorHandle
+class RefMemoryManager : public IMemoryManager
+{
+public:
+ RefMemoryManager();
+ virtual ~RefMemoryManager();
+
+ class Pool;
+
+ Pool* Manage(unsigned int numBytes);
+
+ void Allocate(Pool *pool);
+
+ void* GetPointer(Pool *pool);
+
+ void Acquire() override;
+ void Release() override;
+
+ class Pool
+ {
+ public:
+ Pool(unsigned int numBytes);
+ ~Pool();
+
+ void Acquire();
+ void Release();
+
+ void* GetPointer();
+
+ void Reserve(unsigned int numBytes);
+
+ private:
+ unsigned int m_Size;
+ void* m_Pointer;
+ };
+
+private:
+ RefMemoryManager(const RefMemoryManager&) = delete; // Noncopyable
+ RefMemoryManager& operator=(const RefMemoryManager&) = delete; // Noncopyable
+
+ std::forward_list<Pool> m_Pools;
+ std::vector<Pool*> m_FreePools;
+};
+
+}
diff --git a/src/backends/reference/RefTensorHandle.cpp b/src/backends/reference/RefTensorHandle.cpp
index b7670f6f6e..fe9310f423 100644
--- a/src/backends/reference/RefTensorHandle.cpp
+++ b/src/backends/reference/RefTensorHandle.cpp
@@ -7,39 +7,83 @@
namespace armnn
{
-RefTensorHandle::RefTensorHandle(const TensorInfo &tensorInfo):
+RefTensorHandle::RefTensorHandle(const TensorInfo &tensorInfo, std::shared_ptr<RefMemoryManager> &memoryManager):
m_TensorInfo(tensorInfo),
- m_Memory(nullptr)
+ m_MemoryManager(memoryManager),
+ m_Pool(nullptr),
+ m_UnmanagedMemory(nullptr)
{
}
RefTensorHandle::~RefTensorHandle()
{
- ::operator delete(m_Memory);
+ if (!m_Pool)
+ {
+ // unmanaged
+ ::operator delete(m_UnmanagedMemory);
+ }
+}
+
+void RefTensorHandle::Manage()
+{
+ BOOST_ASSERT_MSG(!m_Pool, "RefTensorHandle::Manage() called twice");
+ BOOST_ASSERT_MSG(!m_UnmanagedMemory, "RefTensorHandle::Manage() called after Allocate()");
+
+ m_Pool = m_MemoryManager->Manage(m_TensorInfo.GetNumBytes());
}
void RefTensorHandle::Allocate()
{
- if (m_Memory == nullptr)
+ if (!m_UnmanagedMemory)
{
- m_Memory = ::operator new(m_TensorInfo.GetNumBytes());
+ if (!m_Pool)
+ {
+ // unmanaged
+ m_UnmanagedMemory = ::operator new(m_TensorInfo.GetNumBytes());
+ }
+ else
+ {
+ m_MemoryManager->Allocate(m_Pool);
+ }
}
else
{
throw InvalidArgumentException("RefTensorHandle::Allocate Trying to allocate a RefTensorHandle"
- "that already has allocated memory.");
+ "that already has allocated memory.");
+ }
+}
+
+const void* RefTensorHandle::Map(bool /*unused*/) const
+{
+ return GetPointer();
+}
+
+void* RefTensorHandle::GetPointer() const
+{
+ if (m_UnmanagedMemory)
+ {
+ return m_UnmanagedMemory;
+ }
+ else
+ {
+ BOOST_ASSERT_MSG(m_Pool, "RefTensorHandle::GetPointer called on unmanaged, unallocated tensor handle");
+ return m_MemoryManager->GetPointer(m_Pool);
}
}
-void RefTensorHandle::CopyOutTo(void* memory) const
+void RefTensorHandle::CopyOutTo(void* dest) const
{
- memcpy(memory, m_Memory, m_TensorInfo.GetNumBytes());
+ const void *src = GetPointer();
+ BOOST_ASSERT(src);
+ memcpy(dest, src, m_TensorInfo.GetNumBytes());
}
-void RefTensorHandle::CopyInFrom(const void* memory)
+void RefTensorHandle::CopyInFrom(const void* src)
{
- memcpy(m_Memory, memory, m_TensorInfo.GetNumBytes());
+ void *dest = GetPointer();
+ BOOST_ASSERT(dest);
+ memcpy(dest, src, m_TensorInfo.GetNumBytes());
}
-} \ No newline at end of file
+}
diff --git a/src/backends/reference/RefTensorHandle.hpp b/src/backends/reference/RefTensorHandle.hpp
index 66d840ab35..ad47ee597f 100644
--- a/src/backends/reference/RefTensorHandle.hpp
+++ b/src/backends/reference/RefTensorHandle.hpp
@@ -6,6 +6,8 @@
#include <backendsCommon/CpuTensorHandle.hpp>
+#include "RefMemoryManager.hpp"
+
namespace armnn
{
@@ -13,28 +15,25 @@ namespace armnn
class RefTensorHandle : public ITensorHandle
{
public:
- RefTensorHandle(const TensorInfo& tensorInfo);
+ RefTensorHandle(const TensorInfo& tensorInfo, std::shared_ptr<RefMemoryManager> &memoryManager);
~RefTensorHandle();
- virtual void Manage() override
- {}
+ virtual void Manage() override;
+
+ virtual void Allocate() override;
virtual ITensorHandle* GetParent() const override
{
return nullptr;
}
- virtual const void* Map(bool /* blocking = true */) const override
- {
- return m_Memory;
- }
+ virtual const void* Map(bool /* blocking = true */) const override;
+ using ITensorHandle::Map;
virtual void Unmap() const override
{}
- virtual void Allocate() override;
-
TensorShape GetStrides() const override
{
return GetUnpaddedTensorStrides(m_TensorInfo);
@@ -55,12 +54,16 @@ private:
void CopyOutTo(void*) const override;
void CopyInFrom(const void*) override;
- RefTensorHandle(const RefTensorHandle& other) = delete;
+ void* GetPointer() const;
- RefTensorHandle& operator=(const RefTensorHandle& other) = delete;
+ RefTensorHandle(const RefTensorHandle& other) = delete; // noncopyable
+ RefTensorHandle& operator=(const RefTensorHandle& other) = delete; //noncopyable
TensorInfo m_TensorInfo;
- void* m_Memory;
+
+ std::shared_ptr<RefMemoryManager> m_MemoryManager;
+ RefMemoryManager::Pool* m_Pool;
+ mutable void *m_UnmanagedMemory;
};
-} \ No newline at end of file
+}
diff --git a/src/backends/reference/RefWorkloadFactory.cpp b/src/backends/reference/RefWorkloadFactory.cpp
index b16e8565d5..7ae5b97dcf 100644
--- a/src/backends/reference/RefWorkloadFactory.cpp
+++ b/src/backends/reference/RefWorkloadFactory.cpp
@@ -55,7 +55,13 @@ bool IsUint8(const WorkloadInfo& info)
return IsDataType<DataType::QuantisedAsymm8>(info);
}
+RefWorkloadFactory::RefWorkloadFactory(const std::shared_ptr<RefMemoryManager>& memoryManager)
+ : m_MemoryManager(memoryManager)
+{
+}
+
RefWorkloadFactory::RefWorkloadFactory()
+ : m_MemoryManager(new RefMemoryManager())
{
}
@@ -73,13 +79,13 @@ bool RefWorkloadFactory::IsLayerSupported(const Layer& layer,
std::unique_ptr<ITensorHandle> RefWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo) const
{
- return std::make_unique<RefTensorHandle>(tensorInfo);
+ return std::make_unique<RefTensorHandle>(tensorInfo, m_MemoryManager);
}
std::unique_ptr<ITensorHandle> RefWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo,
DataLayout dataLayout) const
{
- return std::make_unique<RefTensorHandle>(tensorInfo);
+ return std::make_unique<RefTensorHandle>(tensorInfo, m_MemoryManager);
}
std::unique_ptr<IWorkload> RefWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor,
diff --git a/src/backends/reference/RefWorkloadFactory.hpp b/src/backends/reference/RefWorkloadFactory.hpp
index 1a40259eb9..9ef15221ef 100644
--- a/src/backends/reference/RefWorkloadFactory.hpp
+++ b/src/backends/reference/RefWorkloadFactory.hpp
@@ -8,6 +8,8 @@
#include <backendsCommon/WorkloadFactory.hpp>
#include <backendsCommon/OutputHandler.hpp>
+#include "RefMemoryManager.hpp"
+
#include <boost/core/ignore_unused.hpp>
@@ -30,7 +32,9 @@ constexpr bool IsOperationQueueDescriptor(const PermuteQueueDescriptor&) { retur
class RefWorkloadFactory : public IWorkloadFactory
{
public:
- explicit RefWorkloadFactory();
+ explicit RefWorkloadFactory(const std::shared_ptr<RefMemoryManager>& memoryManager);
+ RefWorkloadFactory();
+
~RefWorkloadFactory() {}
const BackendId& GetBackendId() const override;
@@ -203,6 +207,8 @@ private:
template <typename F32Workload, typename U8Workload, typename QueueDescriptorType>
std::unique_ptr<IWorkload> MakeWorkload(const QueueDescriptorType& descriptor, const WorkloadInfo& info) const;
+
+ mutable std::shared_ptr<RefMemoryManager> m_MemoryManager;
};
} // namespace armnn
diff --git a/src/backends/reference/backend.mk b/src/backends/reference/backend.mk
index a736a889a5..411ab7e615 100644
--- a/src/backends/reference/backend.mk
+++ b/src/backends/reference/backend.mk
@@ -10,6 +10,7 @@
BACKEND_SOURCES := \
RefBackend.cpp \
RefLayerSupport.cpp \
+ RefMemoryManager.cpp \
RefTensorHandle.cpp \
RefWorkloadFactory.cpp \
workloads/Activation.cpp \
@@ -85,5 +86,6 @@ BACKEND_TEST_SOURCES := \
test/RefJsonPrinterTests.cpp \
test/RefLayerSupportTests.cpp \
test/RefLayerTests.cpp \
+ test/RefMemoryManagerTests.cpp \
test/RefOptimizedNetworkTests.cpp \
test/RefRuntimeTests.cpp
diff --git a/src/backends/reference/test/CMakeLists.txt b/src/backends/reference/test/CMakeLists.txt
index 9e5711e608..b56b35354e 100644
--- a/src/backends/reference/test/CMakeLists.txt
+++ b/src/backends/reference/test/CMakeLists.txt
@@ -10,8 +10,10 @@ list(APPEND armnnRefBackendUnitTests_sources
RefJsonPrinterTests.cpp
RefLayerSupportTests.cpp
RefLayerTests.cpp
+ RefMemoryManagerTests.cpp
RefOptimizedNetworkTests.cpp
RefRuntimeTests.cpp
+ RefTensorHandleTests.cpp
RefWorkloadFactoryHelper.hpp
)
diff --git a/src/backends/reference/test/RefCreateWorkloadTests.cpp b/src/backends/reference/test/RefCreateWorkloadTests.cpp
index 945a87430c..8fe18f5d78 100644
--- a/src/backends/reference/test/RefCreateWorkloadTests.cpp
+++ b/src/backends/reference/test/RefCreateWorkloadTests.cpp
@@ -36,6 +36,14 @@ void CheckInputsOutput(std::unique_ptr<Workload> workload,
BOOST_TEST((inputHandle1->GetTensorInfo() == inputInfo1));
BOOST_TEST((outputHandle->GetTensorInfo() == outputInfo));
}
+
+armnn::RefWorkloadFactory GetFactory()
+{
+ std::shared_ptr<RefMemoryManager> memoryManager = std::make_shared<RefMemoryManager>();
+ return RefWorkloadFactory(memoryManager);
+}
+
+
}
BOOST_AUTO_TEST_SUITE(CreateWorkloadRef)
@@ -44,7 +52,7 @@ template <typename ActivationWorkloadType, armnn::DataType DataType>
static void RefCreateActivationWorkloadTest()
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateActivationWorkloadTest<ActivationWorkloadType, DataType>(factory, graph);
// Checks that outputs are as we expect them (see definition of CreateActivationWorkloadTest).
@@ -70,7 +78,7 @@ template <typename WorkloadType,
static void RefCreateElementwiseWorkloadTest()
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateElementwiseWorkloadTest<WorkloadType, DescriptorType, LayerType, DataType>(
factory, graph);
@@ -180,7 +188,7 @@ template <typename BatchNormalizationWorkloadType, armnn::DataType DataType>
static void RefCreateBatchNormalizationWorkloadTest(DataLayout dataLayout)
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>(factory,
graph,
dataLayout);
@@ -244,7 +252,7 @@ BOOST_AUTO_TEST_CASE(CreateBatchNormalizationInt16WorkloadNhwc)
BOOST_AUTO_TEST_CASE(CreateConvertFp16ToFp32Float32Workload)
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateConvertFp16ToFp32WorkloadTest<RefConvertFp16ToFp32Workload>(factory, graph);
// Checks that outputs and inputs are as we expect them
@@ -255,7 +263,7 @@ BOOST_AUTO_TEST_CASE(CreateConvertFp16ToFp32Float32Workload)
BOOST_AUTO_TEST_CASE(CreateConvertFp32ToFp16Float16Workload)
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateConvertFp32ToFp16WorkloadTest<RefConvertFp32ToFp16Workload>(factory, graph);
// Checks that outputs and inputs are as we expect them
@@ -266,7 +274,7 @@ BOOST_AUTO_TEST_CASE(CreateConvertFp32ToFp16Float16Workload)
static void RefCreateConvolution2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateConvolution2dWorkloadTest<RefConvolution2dWorkload, DataType::Float32>
(factory, graph, dataLayout);
@@ -294,7 +302,7 @@ BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNhwcWorkload)
static void RefCreateDepthwiseConvolutionWorkloadTest(DataLayout dataLayout)
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateDepthwiseConvolution2dWorkloadTest<RefDepthwiseConvolution2dWorkload, DataType::Float32>
(factory, graph, dataLayout);
@@ -318,7 +326,7 @@ template <typename FullyConnectedWorkloadType, armnn::DataType DataType>
static void RefCreateFullyConnectedWorkloadTest()
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType, DataType>(factory, graph);
// Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
@@ -348,7 +356,7 @@ template <typename NormalizationWorkloadType, armnn::DataType DataType>
static void RefCreateNormalizationWorkloadTest(DataLayout dataLayout)
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
TensorShape inputShape;
@@ -405,7 +413,7 @@ template <typename Pooling2dWorkloadType, armnn::DataType DataType>
static void RefCreatePooling2dWorkloadTest(DataLayout dataLayout)
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreatePooling2dWorkloadTest<Pooling2dWorkloadType, DataType>(factory, graph, dataLayout);
TensorShape inputShape;
@@ -463,7 +471,7 @@ template <typename SoftmaxWorkloadType, armnn::DataType DataType>
static void RefCreateSoftmaxWorkloadTest()
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
// Checks that outputs and inputs are as we expect them (see definition of CreateSoftmaxWorkloadTest).
@@ -492,7 +500,7 @@ template <typename SplitterWorkloadType, armnn::DataType DataType>
static void RefCreateSplitterWorkloadTest()
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateSplitterWorkloadTest<SplitterWorkloadType, DataType>(factory, graph);
// Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
@@ -530,7 +538,7 @@ static void RefCreateSplitterConcatWorkloadTest()
// of the concat.
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workloads = CreateSplitterConcatWorkloadTest<SplitterWorkloadType, ConcatWorkloadType, DataType>
(factory, graph);
@@ -570,7 +578,7 @@ static void RefCreateSingleOutputMultipleInputsTest()
// We created a splitter with two outputs. That each of those outputs is used by two different activation layers.
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
std::unique_ptr<SplitterWorkloadType> wlSplitter;
std::unique_ptr<ActivationWorkloadType> wlActiv0_0;
std::unique_ptr<ActivationWorkloadType> wlActiv0_1;
@@ -617,7 +625,7 @@ template <typename ResizeBilinearWorkloadType, armnn::DataType DataType>
static void RefCreateResizeBilinearTest(DataLayout dataLayout)
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateResizeBilinearWorkloadTest<ResizeBilinearWorkloadType, DataType>(factory, graph, dataLayout);
TensorShape inputShape;
@@ -665,7 +673,7 @@ template <typename RsqrtWorkloadType, armnn::DataType DataType>
static void RefCreateRsqrtTest()
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateRsqrtWorkloadTest<RsqrtWorkloadType, DataType>(factory, graph);
@@ -723,7 +731,7 @@ template <typename L2NormalizationWorkloadType, armnn::DataType DataType>
static void RefCreateL2NormalizationTest(DataLayout dataLayout)
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload =
CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
@@ -781,7 +789,7 @@ template <typename ReshapeWorkloadType, armnn::DataType DataType>
static void RefCreateReshapeWorkloadTest()
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateReshapeWorkloadTest<ReshapeWorkloadType, DataType>(factory, graph);
// Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
@@ -811,7 +819,7 @@ static void RefCreateConcatWorkloadTest(const armnn::TensorShape& outputShape,
unsigned int concatAxis)
{
Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateConcatWorkloadTest<ConcatWorkloadType, DataType>(factory, graph, outputShape, concatAxis);
CheckInputsOutput(std::move(workload),
@@ -869,7 +877,7 @@ template <typename ConstantWorkloadType, armnn::DataType DataType>
static void RefCreateConstantWorkloadTest(const armnn::TensorShape& outputShape)
{
armnn::Graph graph;
- RefWorkloadFactory factory;
+ RefWorkloadFactory factory = GetFactory();
auto workload = CreateConstantWorkloadTest<ConstantWorkloadType, DataType>(factory, graph, outputShape);
// Check output is as expected
diff --git a/src/backends/reference/test/RefMemoryManagerTests.cpp b/src/backends/reference/test/RefMemoryManagerTests.cpp
new file mode 100644
index 0000000000..15b7c2af4f
--- /dev/null
+++ b/src/backends/reference/test/RefMemoryManagerTests.cpp
@@ -0,0 +1,51 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include <reference/RefMemoryManager.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_SUITE(RefMemoryManagerTests)
+using namespace armnn;
+using Pool = RefMemoryManager::Pool;
+
+BOOST_AUTO_TEST_CASE(ManageOneThing)
+{
+ RefMemoryManager memoryManager;
+
+ Pool* pool = memoryManager.Manage(10);
+
+ BOOST_CHECK(pool);
+
+ memoryManager.Acquire();
+
+ BOOST_CHECK(memoryManager.GetPointer(pool) != nullptr); // Yields a valid pointer
+
+ memoryManager.Release();
+}
+
+BOOST_AUTO_TEST_CASE(ManageTwoThings)
+{
+ RefMemoryManager memoryManager;
+
+ Pool* pool1 = memoryManager.Manage(10);
+ Pool* pool2 = memoryManager.Manage(5);
+
+ BOOST_CHECK(pool1);
+ BOOST_CHECK(pool2);
+
+ memoryManager.Acquire();
+
+ void *p1 = memoryManager.GetPointer(pool1);
+ void *p2 = memoryManager.GetPointer(pool2);
+
+ BOOST_CHECK(p1);
+ BOOST_CHECK(p2);
+ BOOST_CHECK(p1 != p2);
+
+ memoryManager.Release();
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/backends/reference/test/RefTensorHandleTests.cpp b/src/backends/reference/test/RefTensorHandleTests.cpp
new file mode 100644
index 0000000000..accf900975
--- /dev/null
+++ b/src/backends/reference/test/RefTensorHandleTests.cpp
@@ -0,0 +1,48 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#include <reference/RefTensorHandle.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_SUITE(RefTensorHandleTests)
+using namespace armnn;
+
+BOOST_AUTO_TEST_CASE(AcquireAndRelease)
+{
+ std::shared_ptr<RefMemoryManager> memoryManager = std::make_shared<RefMemoryManager>();
+
+ TensorInfo info({1,1,1,1}, DataType::Float32);
+ RefTensorHandle handle(info, memoryManager);
+
+ handle.Manage();
+ handle.Allocate();
+
+ memoryManager->Acquire();
+ {
+ float *buffer = reinterpret_cast<float *>(handle.Map());
+
+ BOOST_CHECK(buffer != nullptr); // Yields a valid pointer
+
+ buffer[0] = 2.5f;
+
+ BOOST_CHECK(buffer[0] == 2.5f); // Memory is writable and readable
+
+ }
+ memoryManager->Release();
+
+ memoryManager->Acquire();
+ {
+ float *buffer = reinterpret_cast<float *>(handle.Map());
+
+ BOOST_CHECK(buffer != nullptr); // Yields a valid pointer
+
+ buffer[0] = 3.5f;
+
+ BOOST_CHECK(buffer[0] == 3.5f); // Memory is writable and readable
+ }
+ memoryManager->Release();
+}
+
+BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file
diff --git a/src/backends/reference/workloads/RefDebugWorkload.cpp b/src/backends/reference/workloads/RefDebugWorkload.cpp
index 64b1b1c593..be2d82f6dc 100644
--- a/src/backends/reference/workloads/RefDebugWorkload.cpp
+++ b/src/backends/reference/workloads/RefDebugWorkload.cpp
@@ -36,7 +36,6 @@ void RefDebugWorkload<DataType>::Execute() const
}
std::memcpy(outputData, inputData, inputInfo.GetNumElements()*sizeof(T));
-
}
template<armnn::DataType DataType>