diff options
Diffstat (limited to 'src/dynamic/sample')
-rw-r--r-- | src/dynamic/sample/CMakeLists.txt | 34 | ||||
-rw-r--r-- | src/dynamic/sample/SampleDynamicAdditionWorkload.cpp | 54 | ||||
-rw-r--r-- | src/dynamic/sample/SampleDynamicAdditionWorkload.hpp | 21 | ||||
-rw-r--r-- | src/dynamic/sample/SampleDynamicBackend.cpp | 91 | ||||
-rw-r--r-- | src/dynamic/sample/SampleDynamicBackend.hpp | 15 | ||||
-rw-r--r-- | src/dynamic/sample/SampleDynamicLayerSupport.cpp | 51 | ||||
-rw-r--r-- | src/dynamic/sample/SampleDynamicLayerSupport.hpp | 28 | ||||
-rw-r--r-- | src/dynamic/sample/SampleDynamicWorkloadFactory.cpp | 75 | ||||
-rw-r--r-- | src/dynamic/sample/SampleDynamicWorkloadFactory.hpp | 62 | ||||
-rw-r--r-- | src/dynamic/sample/SampleMemoryManager.cpp | 95 | ||||
-rw-r--r-- | src/dynamic/sample/SampleMemoryManager.hpp | 59 | ||||
-rw-r--r-- | src/dynamic/sample/SampleTensorHandle.cpp | 137 | ||||
-rw-r--r-- | src/dynamic/sample/SampleTensorHandle.hpp | 78 |
13 files changed, 800 insertions, 0 deletions
diff --git a/src/dynamic/sample/CMakeLists.txt b/src/dynamic/sample/CMakeLists.txt new file mode 100644 index 0000000000..aeb870c32d --- /dev/null +++ b/src/dynamic/sample/CMakeLists.txt @@ -0,0 +1,34 @@ +# +# Copyright © 2020 Arm Ltd. All rights reserved. +# SPDX-License-Identifier: MIT +# + +cmake_minimum_required (VERSION 3.0.2) +project(sample-dynamic) + +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +list(APPEND armnnSampleDynamicBackend_sources + SampleDynamicAdditionWorkload.cpp + SampleDynamicAdditionWorkload.hpp + SampleDynamicBackend.cpp + SampleDynamicBackend.hpp + SampleDynamicLayerSupport.cpp + SampleDynamicLayerSupport.hpp + SampleDynamicWorkloadFactory.cpp + SampleDynamicWorkloadFactory.hpp + SampleMemoryManager.cpp + SampleMemoryManager.hpp + SampleTensorHandle.cpp + SampleTensorHandle.hpp +) + +add_library(Arm_SampleDynamic_backend MODULE ${armnnSampleDynamicBackend_sources}) + +target_include_directories(Arm_SampleDynamic_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../include) +target_include_directories(Arm_SampleDynamic_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../third-party) +target_include_directories(Arm_SampleDynamic_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../src/armnn) +target_include_directories(Arm_SampleDynamic_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../src/armnnUtils) +target_include_directories(Arm_SampleDynamic_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../src/backends) +target_include_directories(Arm_SampleDynamic_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../src/profiling) + diff --git a/src/dynamic/sample/SampleDynamicAdditionWorkload.cpp b/src/dynamic/sample/SampleDynamicAdditionWorkload.cpp new file mode 100644 index 0000000000..0fa57a7e07 --- /dev/null +++ b/src/dynamic/sample/SampleDynamicAdditionWorkload.cpp @@ -0,0 +1,54 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include <armnn/backends/ITensorHandle.hpp> + +#include "SampleDynamicAdditionWorkload.hpp" +#include "SampleTensorHandle.hpp" + +namespace armnn +{ + +inline const TensorInfo& GetTensorInfo(const ITensorHandle* tensorHandle) +{ + // We know that reference workloads use RefTensorHandles for inputs and outputs + const SampleTensorHandle* sampleTensorHandle = + static_cast<const SampleTensorHandle*>(tensorHandle); + return sampleTensorHandle->GetTensorInfo(); +} + +const float* GetInputTensorData(unsigned int idx, const AdditionQueueDescriptor& data) +{ + const ITensorHandle* tensorHandle = data.m_Inputs[idx]; + return reinterpret_cast<const float*>(tensorHandle->Map()); +} + +float* GetOutputTensorData(unsigned int idx, const AdditionQueueDescriptor& data) +{ + ITensorHandle* tensorHandle = data.m_Outputs[idx]; + return reinterpret_cast<float*>(tensorHandle->Map()); +} + +SampleDynamicAdditionWorkload::SampleDynamicAdditionWorkload(const AdditionQueueDescriptor& descriptor, + const WorkloadInfo& info) + : BaseWorkload(descriptor, info) +{} + +void SampleDynamicAdditionWorkload::Execute() const +{ + const TensorInfo& info = GetTensorInfo(m_Data.m_Inputs[0]); + unsigned int num = info.GetNumElements(); + + const float* inputData0 = GetInputTensorData(0, m_Data); + const float* inputData1 = GetInputTensorData(1, m_Data); + float* outputData = GetOutputTensorData(0, m_Data); + + for (unsigned int i = 0; i < num; ++i) + { + outputData[i] = inputData0[i] + inputData1[i]; + } +} + +} // namespace armnn diff --git a/src/dynamic/sample/SampleDynamicAdditionWorkload.hpp b/src/dynamic/sample/SampleDynamicAdditionWorkload.hpp new file mode 100644 index 0000000000..8362588c39 --- /dev/null +++ b/src/dynamic/sample/SampleDynamicAdditionWorkload.hpp @@ -0,0 +1,21 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include <backendsCommon/Workload.hpp> +#include <backendsCommon/WorkloadData.hpp> + +namespace armnn +{ + +class SampleDynamicAdditionWorkload : public BaseWorkload<AdditionQueueDescriptor> +{ +public: + SampleDynamicAdditionWorkload(const AdditionQueueDescriptor& descriptor, const WorkloadInfo& info); + + void Execute() const override; +}; + +} // namespace armnn diff --git a/src/dynamic/sample/SampleDynamicBackend.cpp b/src/dynamic/sample/SampleDynamicBackend.cpp new file mode 100644 index 0000000000..1863c1c98c --- /dev/null +++ b/src/dynamic/sample/SampleDynamicBackend.cpp @@ -0,0 +1,91 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "SampleDynamicBackend.hpp" +#include "SampleDynamicLayerSupport.hpp" +#include "SampleDynamicWorkloadFactory.hpp" +#include "SampleMemoryManager.hpp" + +#include <armnn/backends/IBackendInternal.hpp> +#include <armnn/backends/OptimizationViews.hpp> + +namespace armnn +{ + +constexpr const char * SampleDynamicBackendId() { return "SampleDynamic"; } + +class SampleDynamicBackend : public IBackendInternal +{ +public: + SampleDynamicBackend() = default; + ~SampleDynamicBackend() = default; + + static const BackendId& GetIdStatic() + { + static const BackendId s_Id{SampleDynamicBackendId()}; + return s_Id; + } + + const BackendId& GetId() const override { return GetIdStatic(); } + + IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override + { + return std::make_unique<SampleMemoryManager>(); + } + + IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory( + const IMemoryManagerSharedPtr& memoryManager) const override + { + return std::make_unique<SampleDynamicWorkloadFactory>(); + } + + IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override + { + static ILayerSupportSharedPtr layerSupport{new SampleDynamicLayerSupport}; + return layerSupport; + } + + IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override + { + return IBackendContextPtr{}; + } + + OptimizationViews OptimizeSubgraphView(const SubgraphView& subgraph) const override + { + OptimizationViews optimizationViews; + + optimizationViews.AddUntouchedSubgraph(SubgraphView(subgraph)); + + return optimizationViews; + } + +}; + +} // namespace armnn + +const char* GetBackendId() +{ + return armnn::SampleDynamicBackend::GetIdStatic().Get().c_str(); +} + +void GetVersion(uint32_t* outMajor, uint32_t* outMinor) +{ + if (!outMajor || !outMinor) + { + return; + } + + armnn::BackendVersion apiVersion = armnn::IBackendInternal::GetApiVersion(); + + *outMajor = apiVersion.m_Major; + *outMinor = apiVersion.m_Minor; +} + +void* BackendFactory() +{ + return new armnn::SampleDynamicBackend(); +} + + diff --git a/src/dynamic/sample/SampleDynamicBackend.hpp b/src/dynamic/sample/SampleDynamicBackend.hpp new file mode 100644 index 0000000000..8be1038e03 --- /dev/null +++ b/src/dynamic/sample/SampleDynamicBackend.hpp @@ -0,0 +1,15 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include <cstdint> + +extern "C" +{ +const char* GetBackendId(); +void GetVersion(uint32_t* outMajor, uint32_t* outMinor); +void* BackendFactory(); +} diff --git a/src/dynamic/sample/SampleDynamicLayerSupport.cpp b/src/dynamic/sample/SampleDynamicLayerSupport.cpp new file mode 100644 index 0000000000..031d39cbae --- /dev/null +++ b/src/dynamic/sample/SampleDynamicLayerSupport.cpp @@ -0,0 +1,51 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "SampleDynamicLayerSupport.hpp" + +#include <InternalTypes.hpp> +#include <LayerSupportCommon.hpp> +#include <armnn/Types.hpp> + +namespace armnn +{ + +bool SampleDynamicLayerSupport::IsInputSupported(const TensorInfo& input, + Optional<std::string&> reasonIfUnsupported) const +{ + return true; +} + +bool SampleDynamicLayerSupport::IsOutputSupported(const TensorInfo& output, + Optional<std::string&> reasonIfUnsupported) const +{ + return true; +} + +bool SampleDynamicLayerSupport::IsAdditionSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + Optional<std::string&> reasonIfUnsupported) const +{ + + if (input0.GetDataType() != armnn::DataType::Float32) + { + return false; + } + + if (input0.GetDataType() != input1.GetDataType()) + { + return false; + } + + if (input0.GetDataType() != output.GetDataType()) + { + return false; + } + + return true; +} + +} // namespace armnn diff --git a/src/dynamic/sample/SampleDynamicLayerSupport.hpp b/src/dynamic/sample/SampleDynamicLayerSupport.hpp new file mode 100644 index 0000000000..f6aa0cb91f --- /dev/null +++ b/src/dynamic/sample/SampleDynamicLayerSupport.hpp @@ -0,0 +1,28 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include <backendsCommon/LayerSupportBase.hpp> + +namespace armnn +{ + +class SampleDynamicLayerSupport : public LayerSupportBase +{ +public: + bool IsAdditionSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; + + bool IsInputSupported(const TensorInfo& input, + Optional<std::string&> reasonIfUnsupported) const override; + + bool IsOutputSupported(const TensorInfo& output, + Optional<std::string&> reasonIfUnsupported) const override; +}; + +} // namespace armnn diff --git a/src/dynamic/sample/SampleDynamicWorkloadFactory.cpp b/src/dynamic/sample/SampleDynamicWorkloadFactory.cpp new file mode 100644 index 0000000000..0fb5504f41 --- /dev/null +++ b/src/dynamic/sample/SampleDynamicWorkloadFactory.cpp @@ -0,0 +1,75 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include <backendsCommon/CpuTensorHandle.hpp> +#include <backendsCommon/MemCopyWorkload.hpp> + +#include "SampleDynamicAdditionWorkload.hpp" +#include "SampleDynamicBackend.hpp" +#include "SampleDynamicWorkloadFactory.hpp" +#include "SampleTensorHandle.hpp" + +namespace armnn +{ + +namespace +{ +static const BackendId s_Id{ GetBackendId() }; +} + +SampleDynamicWorkloadFactory::SampleDynamicWorkloadFactory(const std::shared_ptr<SampleMemoryManager>& memoryManager) + : m_MemoryManager(memoryManager) +{ +} + +SampleDynamicWorkloadFactory::SampleDynamicWorkloadFactory() + : m_MemoryManager(new SampleMemoryManager()) +{ +} + +const BackendId& SampleDynamicWorkloadFactory::GetBackendId() const +{ + return s_Id; +} + +bool SampleDynamicWorkloadFactory::IsLayerSupported(const IConnectableLayer& layer, + Optional<DataType> dataType, + std::string& outReasonIfUnsupported) +{ + return IWorkloadFactory::IsLayerSupported(s_Id, layer, dataType, outReasonIfUnsupported); +} + +std::unique_ptr<ITensorHandle> SampleDynamicWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo, + const bool isMemoryManaged) const +{ + return std::make_unique<ScopedCpuTensorHandle>(tensorInfo); +} + +std::unique_ptr<ITensorHandle> SampleDynamicWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo, + DataLayout dataLayout, + const bool isMemoryManaged) const +{ + return std::make_unique<ScopedCpuTensorHandle>(tensorInfo); +} + +std::unique_ptr<IWorkload> SampleDynamicWorkloadFactory::CreateAddition(const AdditionQueueDescriptor& descriptor, + const WorkloadInfo& info) const +{ + return std::make_unique<SampleDynamicAdditionWorkload>(descriptor, info); +} + +std::unique_ptr<IWorkload> SampleDynamicWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor, + const WorkloadInfo& info) const +{ + return std::make_unique<CopyMemGenericWorkload>(descriptor, info); +} + +std::unique_ptr<IWorkload> SampleDynamicWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor, + const WorkloadInfo& info) const +{ + return std::make_unique<CopyMemGenericWorkload>(descriptor, info); +} + +} // namespace armnn diff --git a/src/dynamic/sample/SampleDynamicWorkloadFactory.hpp b/src/dynamic/sample/SampleDynamicWorkloadFactory.hpp new file mode 100644 index 0000000000..88b67987e1 --- /dev/null +++ b/src/dynamic/sample/SampleDynamicWorkloadFactory.hpp @@ -0,0 +1,62 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "SampleMemoryManager.hpp" + +#include <armnn/Optional.hpp> +#include <backendsCommon/WorkloadFactory.hpp> + +namespace armnn +{ + +// Sample Dynamic workload factory. +class SampleDynamicWorkloadFactory : public IWorkloadFactory +{ +public: + explicit SampleDynamicWorkloadFactory(const std::shared_ptr<SampleMemoryManager>& memoryManager); + SampleDynamicWorkloadFactory(); + + ~SampleDynamicWorkloadFactory() {} + + const BackendId& GetBackendId() const override; + + static bool IsLayerSupported(const IConnectableLayer& layer, + Optional<DataType> dataType, + std::string& outReasonIfUnsupported); + + bool SupportsSubTensors() const override { return false; } + + std::unique_ptr<ITensorHandle> CreateSubTensorHandle(ITensorHandle& parent, + TensorShape const& subTensorShape, + unsigned int const* subTensorOrigin) const override + { + boost::ignore_unused(parent, subTensorShape, subTensorOrigin); + return nullptr; + } + + std::unique_ptr<ITensorHandle> CreateTensorHandle(const TensorInfo& tensorInfo, + const bool IsMemoryManaged = true) const override; + + std::unique_ptr<ITensorHandle> CreateTensorHandle(const TensorInfo& tensorInfo, + DataLayout dataLayout, + const bool IsMemoryManaged = true) const override; + + std::unique_ptr<IWorkload> CreateAddition(const AdditionQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + + + std::unique_ptr<IWorkload> CreateInput(const InputQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + + std::unique_ptr<IWorkload> CreateOutput(const OutputQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + +private: + mutable std::shared_ptr<SampleMemoryManager> m_MemoryManager; + +}; + +} // namespace armnn diff --git a/src/dynamic/sample/SampleMemoryManager.cpp b/src/dynamic/sample/SampleMemoryManager.cpp new file mode 100644 index 0000000000..30a7548b02 --- /dev/null +++ b/src/dynamic/sample/SampleMemoryManager.cpp @@ -0,0 +1,95 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "SampleMemoryManager.hpp" + +#include <algorithm> + +namespace armnn +{ + +SampleMemoryManager::SampleMemoryManager() +{} + +SampleMemoryManager::~SampleMemoryManager() +{} + +SampleMemoryManager::Pool* SampleMemoryManager::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 SampleMemoryManager::Allocate(SampleMemoryManager::Pool* pool) +{ + m_FreePools.push_back(pool); +} + +void* SampleMemoryManager::GetPointer(SampleMemoryManager::Pool* pool) +{ + return pool->GetPointer(); +} + +void SampleMemoryManager::Acquire() +{ + for (Pool &pool: m_Pools) + { + pool.Acquire(); + } +} + +void SampleMemoryManager::Release() +{ + for (Pool &pool: m_Pools) + { + pool.Release(); + } +} + +SampleMemoryManager::Pool::Pool(unsigned int numBytes) + : m_Size(numBytes), + m_Pointer(nullptr) +{} + +SampleMemoryManager::Pool::~Pool() +{ + if (m_Pointer) + { + Release(); + } +} + +void* SampleMemoryManager::Pool::GetPointer() +{ + return m_Pointer; +} + +void SampleMemoryManager::Pool::Reserve(unsigned int numBytes) +{ + m_Size = std::max(m_Size, numBytes); +} + +void SampleMemoryManager::Pool::Acquire() +{ + m_Pointer = ::operator new(size_t(m_Size)); +} + +void SampleMemoryManager::Pool::Release() +{ + ::operator delete(m_Pointer); + m_Pointer = nullptr; +} + +} diff --git a/src/dynamic/sample/SampleMemoryManager.hpp b/src/dynamic/sample/SampleMemoryManager.hpp new file mode 100644 index 0000000000..0993bc1e2b --- /dev/null +++ b/src/dynamic/sample/SampleMemoryManager.hpp @@ -0,0 +1,59 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include <armnn/backends/IMemoryManager.hpp> + +#include <forward_list> +#include <vector> + +namespace armnn +{ + +// An implementation of IMemoryManager to be used with SampleTensorHandle +class SampleMemoryManager : public IMemoryManager +{ +public: + SampleMemoryManager(); + virtual ~SampleMemoryManager(); + + 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: + SampleMemoryManager(const SampleMemoryManager&) = delete; // Noncopyable + SampleMemoryManager& operator=(const SampleMemoryManager&) = delete; // Noncopyable + + std::forward_list<Pool> m_Pools; + std::vector<Pool*> m_FreePools; +}; + +} diff --git a/src/dynamic/sample/SampleTensorHandle.cpp b/src/dynamic/sample/SampleTensorHandle.cpp new file mode 100644 index 0000000000..48f8cf44fa --- /dev/null +++ b/src/dynamic/sample/SampleTensorHandle.cpp @@ -0,0 +1,137 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "SampleTensorHandle.hpp" + +namespace armnn +{ + +SampleTensorHandle::SampleTensorHandle(const TensorInfo &tensorInfo, + std::shared_ptr<SampleMemoryManager> &memoryManager) + : m_TensorInfo(tensorInfo), + m_MemoryManager(memoryManager), + m_Pool(nullptr), + m_UnmanagedMemory(nullptr), + m_ImportFlags(static_cast<MemorySourceFlags>(MemorySource::Undefined)), + m_Imported(false) +{ + +} + +SampleTensorHandle::SampleTensorHandle(const TensorInfo& tensorInfo, + std::shared_ptr<SampleMemoryManager> &memoryManager, + MemorySourceFlags importFlags) + : m_TensorInfo(tensorInfo), + m_MemoryManager(memoryManager), + m_Pool(nullptr), + m_UnmanagedMemory(nullptr), + m_ImportFlags(importFlags), + m_Imported(false) +{ + +} + +SampleTensorHandle::~SampleTensorHandle() +{ + if (!m_Pool) + { + // unmanaged + if (!m_Imported) + { + ::operator delete(m_UnmanagedMemory); + } + } +} + +void SampleTensorHandle::Manage() +{ + m_Pool = m_MemoryManager->Manage(m_TensorInfo.GetNumBytes()); +} + +void SampleTensorHandle::Allocate() +{ + if (!m_UnmanagedMemory) + { + if (!m_Pool) + { + // unmanaged + m_UnmanagedMemory = ::operator new(m_TensorInfo.GetNumBytes()); + } + else + { + m_MemoryManager->Allocate(m_Pool); + } + } + else + { + throw InvalidArgumentException("SampleTensorHandle::Allocate Trying to allocate a SampleTensorHandle" + "that already has allocated memory."); + } +} + +const void* SampleTensorHandle::Map(bool /*unused*/) const +{ + return GetPointer(); +} + +void* SampleTensorHandle::GetPointer() const +{ + if (m_UnmanagedMemory) + { + return m_UnmanagedMemory; + } + else + { + return m_MemoryManager->GetPointer(m_Pool); + } +} + +bool SampleTensorHandle::Import(void* memory, MemorySource source) +{ + + if (m_ImportFlags & static_cast<MemorySourceFlags>(source)) + { + if (source == MemorySource::Malloc) + { + // Check memory alignment + constexpr uintptr_t alignment = sizeof(size_t); + if (reinterpret_cast<uintptr_t>(memory) % alignment) + { + if (m_Imported) + { + m_Imported = false; + m_UnmanagedMemory = nullptr; + } + + return false; + } + + // m_UnmanagedMemory not yet allocated. + if (!m_Imported && !m_UnmanagedMemory) + { + m_UnmanagedMemory = memory; + m_Imported = true; + return true; + } + + // m_UnmanagedMemory initially allocated with Allocate(). + if (!m_Imported && m_UnmanagedMemory) + { + return false; + } + + // m_UnmanagedMemory previously imported. + if (m_Imported) + { + m_UnmanagedMemory = memory; + return true; + } + } + } + + return false; +} + +} diff --git a/src/dynamic/sample/SampleTensorHandle.hpp b/src/dynamic/sample/SampleTensorHandle.hpp new file mode 100644 index 0000000000..c08edc69b7 --- /dev/null +++ b/src/dynamic/sample/SampleTensorHandle.hpp @@ -0,0 +1,78 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include <backendsCommon/CpuTensorHandle.hpp> + +#include "SampleMemoryManager.hpp" + +namespace armnn +{ + +// An implementation of ITensorHandle with simple "bump the pointer" memory-management behaviour +class SampleTensorHandle : public ITensorHandle +{ +public: + SampleTensorHandle(const TensorInfo& tensorInfo, std::shared_ptr<SampleMemoryManager> &memoryManager); + + SampleTensorHandle(const TensorInfo& tensorInfo, + std::shared_ptr<SampleMemoryManager> &memoryManager, + MemorySourceFlags importFlags); + + ~SampleTensorHandle(); + + virtual void Manage() override; + + virtual void Allocate() override; + + virtual ITensorHandle* GetParent() const override + { + return nullptr; + } + + virtual const void* Map(bool /* blocking = true */) const override; + using ITensorHandle::Map; + + virtual void Unmap() const override + {} + + TensorShape GetStrides() const override + { + return GetUnpaddedTensorStrides(m_TensorInfo); + } + + TensorShape GetShape() const override + { + return m_TensorInfo.GetShape(); + } + + const TensorInfo& GetTensorInfo() const + { + return m_TensorInfo; + } + + virtual MemorySourceFlags GetImportFlags() const override + { + return m_ImportFlags; + } + + virtual bool Import(void* memory, MemorySource source) override; + +private: + void* GetPointer() const; + + SampleTensorHandle(const SampleTensorHandle& other) = delete; // noncopyable + SampleTensorHandle& operator=(const SampleTensorHandle& other) = delete; //noncopyable + + TensorInfo m_TensorInfo; + + std::shared_ptr<SampleMemoryManager> m_MemoryManager; + SampleMemoryManager::Pool* m_Pool; + mutable void *m_UnmanagedMemory; + MemorySourceFlags m_ImportFlags; + bool m_Imported; +}; + +} |