blob: dc62b9a2f57c0d5374689c44f6842e390f42923d [file] [log] [blame]
//
// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//
#pragma once
#include "ExecutionData.hpp"
#include "Layer.hpp"
#include "Network.hpp"
#include "WorkingMemDescriptor.hpp"
#include <armnn/IWorkingMemHandle.hpp>
#include <armnn/Tensor.hpp>
#include <armnn/backends/IBackendInternal.hpp>
#include <unordered_map>
#include <mutex>
#include <backendsCommon/MemoryManager.hpp>
namespace armnn
{
namespace experimental
{
using BackendPtrMap = std::unordered_map<BackendId, IBackendInternalUniquePtr>;
class WorkingMemHandle final : public IWorkingMemHandle
{
public:
struct InputMemDescriptorCoords
{
LayerBindingId m_LayerBindingId;
std::vector<std::pair<unsigned int, unsigned int>> m_InputSlotCoords;
};
struct OutputMemDescriptorCoords
{
std::vector<LayerBindingId> m_LayerBindingIds;
std::pair<unsigned int, unsigned int> m_OutputSlotCoords;
std::vector<std::pair<unsigned int, unsigned int>> m_InputSlotCoords;
};
WorkingMemHandle(NetworkId networkId) : m_NetworkId(networkId){}
WorkingMemHandle(NetworkId networkId,
std::vector<InputMemDescriptorCoords> inputLayerInfo,
std::vector<OutputMemDescriptorCoords> outputLayerInfo,
std::vector<WorkingMemDescriptor> workingMemDescriptors,
std::unique_ptr<MemoryManager> memoryManager,
std::vector<std::pair<std::shared_ptr<TensorMemory>, MemorySource>> tensorMemory,
std::vector<std::unique_ptr<ITensorHandle>> managedTensorHandles,
std::vector<std::unique_ptr<ITensorHandle>> unmanagedTensorHandles,
std::vector<std::pair<BackendId, ExecutionData>> executionDataVec,
BackendPtrMap* backends);
~WorkingMemHandle()
{ Free(); }
NetworkId GetNetworkId() override
{
return m_NetworkId;
}
/// Allocate the backing memory required for execution. If this is not called, then allocation will be
/// deferred to execution time.
void Allocate() override;
/// Free the backing memory required for execution.
void Free() override;
/// IsAllocated returns true if the backing memory is currently allocated.
bool IsAllocated() override
{
return m_IsAllocated;
}
/// Get the WorkingMemDescriptor at an index. The WorkingMemDescriptors are stored in the same order as
/// the Workloads in a topologically sorted graph.
WorkingMemDescriptor& GetWorkingMemDescriptorAt(unsigned int id) override
{
return m_WorkingMemDescriptors[id];
}
/// Get the ExecutionData at an index.
/// The ExecutionData is paired with a BackendId to be able to call backend specific functions upon it.
/// The ExecutionData are stored in the same order as the Workloads in a topologically sorted graph.
std::pair<BackendId, ExecutionData>& GetExecutionDataAt(unsigned int id) override
{
return m_ExecutionDataVec[id];
}
ITensorHandle* GetInputHandle(LayerBindingId layerBindingId) const
{
return m_InputHandleMap.at(layerBindingId);
};
ITensorHandle* GetOutputHandle(LayerBindingId layerBindingId) const
{
return m_OutputHandleMap.at(layerBindingId);
};
const std::vector<std::vector<ITensorHandle*>::iterator>& GetInputConnections(LayerBindingId layerBindingId) const
{
return m_InputConnectionMap.at(layerBindingId);
};
const std::vector<std::vector<ITensorHandle*>::iterator>& GetOutputConnection(LayerBindingId layerBindingId) const
{
return m_OutputConnectionMap.at(layerBindingId);
};
void MemSyncOutputs();
std::vector<LayerBindingId>& GetBindingIdVector()
{
return m_BindingIdVec;
};
void ValidateBindingIds();
private:
using DifferenceType = std::vector<ITensorHandle*>::difference_type;
NetworkId m_NetworkId;
std::unordered_map<LayerBindingId, ITensorHandle*> m_InputHandleMap;
std::unordered_map<LayerBindingId, ITensorHandle*> m_OutputHandleMap;
std::unordered_map<LayerBindingId, std::vector<std::vector<ITensorHandle*>::iterator>> m_InputConnectionMap;
std::unordered_map<LayerBindingId, std::vector<std::vector<ITensorHandle*>::iterator>> m_OutputConnectionMap;
std::vector<WorkingMemDescriptor> m_WorkingMemDescriptors;
std::unique_ptr<MemoryManager> m_MemoryManager;
// Memory to be imported into the tensorHandles after allocation
std::vector<std::pair<std::shared_ptr<TensorMemory>, MemorySource>> m_TensorMemory;
// Tensors that will need to be allocated internally within armnn
std::vector<std::unique_ptr<ITensorHandle>> m_ManagedTensorHandles;
// Tensors that will be allocated externally by the user
std::vector<std::unique_ptr<ITensorHandle>> m_UnmanagedTensorHandles;
std::unordered_map<LayerBindingId, bool> m_InputValidationMap;
std::unordered_map<LayerBindingId, bool> m_OutputValidationMap;
std::vector<LayerBindingId> m_BindingIdVec;
DifferenceType m_InputSize;
bool m_IsAllocated;
std::vector<std::pair<BackendId, ExecutionData>> m_ExecutionDataVec;
BackendPtrMap* m_Backends;
};
} // end experimental namespace
} // end armnn namespace