ArmNN
 21.05
LoadedNetwork Class Reference

#include <LoadedNetwork.hpp>

Public Types

using WorkloadQueue = std::vector< std::unique_ptr< IWorkload > >
 
using ExecutionTuple = std::tuple< InputTensors, OutputTensors, std::shared_ptr< IAsyncExecutionCallback > >
 
using ExecutionQueue = std::queue< std::shared_ptr< ExecutionTuple > >
 

Public Member Functions

 ~LoadedNetwork ()
 
std::unique_ptr< IWorkingMemHandleCreateWorkingMemHandle (NetworkId networkId)
 Create a new unique WorkingMemHandle object. More...
 
TensorInfo GetInputTensorInfo (LayerBindingId layerId) const
 
TensorInfo GetOutputTensorInfo (LayerBindingId layerId) const
 
Status EnqueueWorkload (const InputTensors &inputTensors, const OutputTensors &outputTensors)
 Single thread execution of the loaded network. More...
 
Status Execute (const InputTensors &inputTensors, const OutputTensors &outputTensors, IWorkingMemHandle &workingMemHandle)
 Thread safe execution of the loaded network. More...
 
void Schedule (const InputTensors &inputTensors, const OutputTensors &outputTensors, const QosExecPriority priority, std::shared_ptr< IAsyncExecutionCallback > cb)
 Schedule an asynchronous execution on the loaded network. More...
 
const std::shared_ptr< IProfiler > & GetProfiler () const
 
void FreeWorkingMemory ()
 
void RegisterDebugCallback (const DebugCallbackFunction &func)
 
void SendNetworkStructure ()
 
bool IsAsyncEnabled ()
 
profiling::ProfilingGuid GetNetworkGuid ()
 

Static Public Member Functions

static std::unique_ptr< LoadedNetworkMakeLoadedNetwork (std::unique_ptr< IOptimizedNetwork > net, std::string &errorMessage, const INetworkProperties &networkProperties, profiling::ProfilingService &profilingService, const NetworkId networkIdOut)
 

Detailed Description

Definition at line 35 of file LoadedNetwork.hpp.

Member Typedef Documentation

◆ ExecutionQueue

using ExecutionQueue = std::queue<std::shared_ptr<ExecutionTuple> >

Definition at line 44 of file LoadedNetwork.hpp.

◆ ExecutionTuple

using ExecutionTuple = std::tuple<InputTensors, OutputTensors, std::shared_ptr<IAsyncExecutionCallback> >

Definition at line 42 of file LoadedNetwork.hpp.

◆ WorkloadQueue

using WorkloadQueue = std::vector<std::unique_ptr<IWorkload> >

Definition at line 38 of file LoadedNetwork.hpp.

Constructor & Destructor Documentation

◆ ~LoadedNetwork()

~LoadedNetwork ( )
inline

Definition at line 46 of file LoadedNetwork.hpp.

47  {
49  TerminateThreadPool();
50  }

Member Function Documentation

◆ CreateWorkingMemHandle()

std::unique_ptr< IWorkingMemHandle > CreateWorkingMemHandle ( NetworkId  networkId)

Create a new unique WorkingMemHandle object.

Create multiple handles if you wish to have overlapped Execution by calling this function from different threads.

Definition at line 1258 of file LoadedNetwork.cpp.

References ITensorHandle::Allocate(), ARMNN_ASSERT, ARMNN_NO_DEPRECATE_WARN_BEGIN, ARMNN_NO_DEPRECATE_WARN_END, armnn::Constant, ITensorHandleFactory::CreateTensorHandle(), Layer::GetBackendId(), TensorHandleFactoryRegistry::GetFactory(), Layer::GetGuid(), Layer::GetInputSlots(), TensorHandleFactoryRegistry::GetMemoryManagers(), Layer::GetNumOutputSlots(), Layer::GetOutputSlots(), Layer::GetType(), armnn::Input, ITensorHandleFactory::LegacyFactoryId, WorkingMemDescriptor::m_Inputs, WorkingMemDescriptor::m_Outputs, ITensorHandle::Manage(), armnn::MemImport, and armnn::Output.

Referenced by RuntimeImpl::CreateWorkingMemHandle().

1259 {
1260  Graph& order = m_OptimizedNetwork->pOptimizedNetworkImpl->GetGraph();
1261  std::unordered_map<LayerGuid, std::vector<std::unique_ptr<ITensorHandle> > > tensorHandleMap;
1262  std::vector<WorkingMemDescriptor> workingMemDescriptors;
1263  std::unordered_map<LayerGuid, WorkingMemDescriptor> workingMemDescriptorMap;
1264  TensorHandleFactoryRegistry tensorHandleFactoryRegistry;
1265  WorkloadFactoryMap workloadFactoryMap;
1266 
1267  std::vector<std::shared_ptr<IMemoryManager>> memoryManagers;
1268 
1269  for (auto const& backend : m_Backends)
1270  {
1271  if (backend.second->SupportsTensorAllocatorAPI())
1272  {
1273  backend.second->RegisterTensorHandleFactories(
1274  tensorHandleFactoryRegistry,
1275  static_cast<MemorySourceFlags>(m_NetworkProperties.m_InputSource),
1276  static_cast<MemorySourceFlags>(m_NetworkProperties.m_OutputSource));
1277  memoryManagers.emplace_back(tensorHandleFactoryRegistry.GetMemoryManagers().back());
1278  }
1279  else
1280  {
1281  std::shared_ptr<IMemoryManager> memoryManager = backend.second->CreateMemoryManager();
1282  auto workloadFactory = backend.second->CreateWorkloadFactory(
1283  memoryManager, m_OptimizedNetwork->pOptimizedNetworkImpl->GetModelOptions());
1284 
1285  workloadFactoryMap.emplace(
1286  std::make_pair(backend.first, std::make_pair(std::move(workloadFactory), memoryManager)));
1287  memoryManagers.emplace_back(memoryManager);
1288  }
1289  }
1290 
1291  auto GetTensorHandle = [&](Layer* layer, const OutputSlot& outputSlot, bool isMemoryManaged)
1292  {
1293  ITensorHandleFactory::FactoryId factoryId = outputSlot.GetTensorHandleFactoryId();
1294  const TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
1295 
1296  if (factoryId == ITensorHandleFactory::LegacyFactoryId)
1297  {
1298  BackendId id = layer->GetBackendId();
1300  return workloadFactoryMap.at(id).first->CreateTensorHandle(tensorInfo, isMemoryManaged);
1302  }
1303  else
1304  {
1305  ITensorHandleFactory* handleFactory = tensorHandleFactoryRegistry.GetFactory(factoryId);
1306  ARMNN_ASSERT(handleFactory);
1307  return handleFactory->CreateTensorHandle(tensorInfo, isMemoryManaged);
1308  }
1309  };
1310 
1311  std::unordered_map<const ITensorHandle*, unsigned int> handleReferenceCounts;
1312  for (auto&& layer : order)
1313  {
1314  WorkingMemDescriptor workingMemDescriptor;
1315 
1316  // Constant layers execution and management is handled during loaded network construction
1317  if (layer->GetType() == LayerType::Constant)
1318  {
1319  continue;
1320  }
1321  bool isMemoryManaged = true;
1322  bool isInputLayer = true;
1323  // Look for the layer with 1 OutputSlot which has 1 connection and that connection is an Output Layer
1324  // If Export is enabled disable memory management so we can export, otherwise we do a copy
1325  if ((layer->GetNumOutputSlots() == 1) &&
1326  (layer->GetOutputSlots()[0].GetNumConnections() == 1) &&
1327  (layer->GetOutputSlots()[0].GetConnection(0)->GetOwningLayer().GetType() == LayerType::Output))
1328  {
1329  isMemoryManaged = !m_NetworkProperties.m_ExportEnabled;
1330  }
1331  else if (layer->GetType() == LayerType::Input || layer->GetType() == LayerType::MemImport)
1332  {
1333  // Input layers/workloads will not be executed so the descriptor is not added to workingMemDescriptors
1334  // However we will still need to manage the tensorHandle
1335  isInputLayer = false;
1336  isMemoryManaged = !m_NetworkProperties.m_ExportEnabled;
1337  }
1338 
1339  // Create a tensor handle for each output slot of a layer
1340  // Once we create it, we start managing its lifetime
1341  for (auto& slot : layer->GetOutputSlots())
1342  {
1343  tensorHandleMap[layer->GetGuid()].emplace_back(GetTensorHandle(layer, slot, isMemoryManaged));
1344  ITensorHandle* tensorHandle = tensorHandleMap[layer->GetGuid()].back().get();
1345 
1346  workingMemDescriptor.m_Outputs.push_back(tensorHandle);
1347  tensorHandle->Manage();
1348  unsigned int numConnections = slot.GetNumConnections();
1349  ARMNN_ASSERT(numConnections != 0);
1350 
1351  handleReferenceCounts[tensorHandle] = numConnections;
1352  }
1353  // Loop through the input slots in the same layer and decrement the reference counter associated
1354  // to each tensor handle we encounter.
1355  // Once it reaches zero, the lifetime of the tensor handle has ended, and we mark it's memory as available
1356  // so that the next tensor handle with a non overlapping lifetime can share it's memory.
1357  for (auto& slot : layer->GetInputSlots())
1358  {
1359  ARMNN_ASSERT(slot.GetConnection());
1360  auto outputSlot = slot.GetConnectedOutputSlot();
1361  auto key = outputSlot->GetOwningLayer().GetGuid();
1362 
1363  // Constant layers execution and management is handled during loaded network construction
1364  auto found = m_ConstantTensorHandles.find(key);
1365  if (found != m_ConstantTensorHandles.end())
1366  {
1367  workingMemDescriptor.m_Inputs.push_back(found->second);
1368  continue;
1369  }
1370 
1371  auto search = tensorHandleMap.find(key);
1372  unsigned int index = outputSlot->CalculateIndexOnOwner();
1373  ITensorHandle* inputTensorHandle = search->second[index].get();
1374  workingMemDescriptor.m_Inputs.push_back(inputTensorHandle);
1375  --handleReferenceCounts.at(inputTensorHandle);
1376  if (handleReferenceCounts.at(inputTensorHandle) == 0u)
1377  {
1378  // Stop managing lifetime of tensor handle
1379  inputTensorHandle->Allocate();
1380  handleReferenceCounts.erase(inputTensorHandle);
1381  }
1382  }
1383  workingMemDescriptorMap.insert({layer->GetGuid(), workingMemDescriptor});
1384 
1385  // Input layers/workloads will not be executed, so the descriptor is not added to workingMemDescriptors
1386  // However we will still need to manage the tensorHandle
1387  if (isInputLayer)
1388  {
1389  workingMemDescriptors.push_back(workingMemDescriptor);
1390  }
1391  }
1392 
1393  return std::make_unique<WorkingMemHandle>(networkId,
1394  workingMemDescriptors,
1395  workingMemDescriptorMap,
1396  memoryManagers,
1397  std::move(tensorHandleMap));
1398 }
const MemorySource m_InputSource
Definition: IRuntime.hpp:65
#define ARMNN_NO_DEPRECATE_WARN_BEGIN
Definition: Deprecated.hpp:33
#define ARMNN_NO_DEPRECATE_WARN_END
Definition: Deprecated.hpp:34
const bool m_ExportEnabled
Deprecated and will be removed in future release.
Definition: IRuntime.hpp:60
#define ARMNN_ASSERT(COND)
Definition: Assert.hpp:14
const MemorySource m_OutputSource
Definition: IRuntime.hpp:66
static const FactoryId LegacyFactoryId

◆ EnqueueWorkload()

Status EnqueueWorkload ( const InputTensors inputTensors,
const OutputTensors outputTensors 
)

Single thread execution of the loaded network.

Definition at line 535 of file LoadedNetwork.cpp.

References ARMNN_ASSERT_MSG, ARMNN_LOG, LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS, ARMNN_SCOPED_HEAP_PROFILING, ARMNN_SCOPED_PROFILING_EVENT, armnn::CheckFlag(), LabelsAndEventClasses::EXECUTION_OF_GUID, armnn::Failure, ITensorHandle::GetImportFlags(), Graph::GetInputLayers(), Layer::GetInputSlots(), Graph::GetNumInputs(), Layer::GetNumInputSlots(), Graph::GetNumLayers(), Graph::GetNumOutputs(), Layer::GetNumOutputSlots(), Layer::GetOutputHandler(), Graph::GetOutputLayers(), TimelineUtilityMethods::GetTimelineUtils(), Layer::GetType(), armnn::IgnoreUnused(), ITensorHandle::Import(), LabelsAndEventClasses::INFERENCE_GUID, armnn::info, armnn::Input, QueueDescriptor::m_Inputs, WorkloadInfo::m_InputTensorInfos, QueueDescriptor::m_Outputs, WorkloadInfo::m_OutputTensorInfos, ITensorHandle::Map(), armnn::Output, armnn::Success, armnn::Undefined, ITensorHandle::Unmap(), and armnn::warning.

Referenced by RuntimeImpl::EnqueueWorkload().

537 {
538  const Graph& graph = m_OptimizedNetwork->pOptimizedNetworkImpl->GetGraph();
539 
540  // Walk graph to determine the order of execution.
541  if (graph.GetNumLayers() < 2)
542  {
543  ARMNN_LOG(warning) << "IRuntime::EnqueueWorkload()::Less than two nodes in graph";
544  return Status::Failure;
545  }
546 
547  // Data that must be kept alive for the entire execution of the workload.
548  WorkloadData workloadData(inputTensors, outputTensors);
549 
550  if (graph.GetNumInputs() != inputTensors.size())
551  {
552  throw InvalidArgumentException("Number of inputs provided does not match network.");
553  }
554 
555  // For each input to the network, call EnqueueInput with the data passed by the user.
556  {
558  m_InputQueue.clear();
559  m_InputQueue.reserve(graph.GetNumInputs());
560  for (const BindableLayer* inputLayer : graph.GetInputLayers())
561  {
562  const TensorPin& pin = workloadData.GetInputTensorPin(inputLayer->GetBindingId());
563  EnqueueInput(*inputLayer, pin.GetTensorHandle(), pin.GetTensorInfo());
564  }
565  }
566 
567  // For each output to the network, call EnqueueOutput with the data passed by the user.
568  {
570  m_OutputQueue.clear();
571  m_OutputQueue.reserve(graph.GetNumOutputs());
572  for (const BindableLayer* outputLayer : graph.GetOutputLayers())
573  {
574  const TensorPin& pin = workloadData.GetOutputTensorPin(outputLayer->GetBindingId());
575  EnqueueOutput(*outputLayer, pin.GetTensorHandle(), pin.GetTensorInfo());
576  }
577  }
578 
579  std::unique_ptr<TimelineUtilityMethods> timelineUtils =
580  TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
581  ProfilingGuid inferenceGuid = m_ProfilingService.GetNextGuid();
582  if (timelineUtils)
583  {
584  // Add inference timeline trace if profiling is enabled.
585  ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid();
586  timelineUtils->CreateTypedEntity(inferenceGuid, LabelsAndEventClasses::INFERENCE_GUID);
587  timelineUtils->CreateRelationship(ProfilingRelationshipType::RetentionLink,
588  networkGuid,
589  inferenceGuid,
591  timelineUtils->RecordEvent(inferenceGuid, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
592  }
593 
594  bool executionSucceeded = true;
595 
596  {
597  if (m_ProfilingService.IsProfilingEnabled())
598  {
599  m_ProfilingService.IncrementCounterValue(armnn::profiling::INFERENCES_RUN);
600  }
602  ARMNN_SCOPED_HEAP_PROFILING("Executing");
603  executionSucceeded = Execute(timelineUtils, inferenceGuid);
604  }
605 
606  if (timelineUtils)
607  {
608  // Add end of life of the inference timeline if profiling is enabled.
609  timelineUtils->RecordEvent(inferenceGuid, LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS);
610  timelineUtils->Commit();
611  }
612  return executionSucceeded ? Status::Success : Status::Failure;
613 }
static ARMNN_DLLEXPORT ProfilingStaticGuid INFERENCE_GUID
static std::unique_ptr< TimelineUtilityMethods > GetTimelineUtils(ProfilingService &profilingService)
#define ARMNN_LOG(severity)
Definition: Logging.hpp:202
uint32_t IncrementCounterValue(uint16_t counterUid) override
static ARMNN_DLLEXPORT ProfilingStaticGuid ARMNN_PROFILING_EOL_EVENT_CLASS
#define ARMNN_SCOPED_PROFILING_EVENT(backendId, name)
Definition: Profiling.hpp:173
static ARMNN_DLLEXPORT ProfilingStaticGuid ARMNN_PROFILING_SOL_EVENT_CLASS
Status Execute(const InputTensors &inputTensors, const OutputTensors &outputTensors, IWorkingMemHandle &workingMemHandle)
Thread safe execution of the loaded network.
#define ARMNN_SCOPED_HEAP_PROFILING(TAG)
static ARMNN_DLLEXPORT ProfilingStaticGuid EXECUTION_OF_GUID
bool IsProfilingEnabled() const override
static ProfilingDynamicGuid GetNextGuid()

◆ Execute()

Status Execute ( const InputTensors inputTensors,
const OutputTensors outputTensors,
IWorkingMemHandle workingMemHandle 
)

Thread safe execution of the loaded network.

Definition at line 1154 of file LoadedNetwork.cpp.

References WorkingMemHandle::Allocate(), ARMNN_LOG, LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS, ARMNN_SCOPED_PROFILING_EVENT, armnn::error, LabelsAndEventClasses::EXECUTION_OF_GUID, armnn::Failure, Graph::GetInputLayers(), armnn::GetInputTensor(), WorkingMemHandle::GetMutex(), Graph::GetNumInputs(), Graph::GetNumLayers(), Graph::GetOutputLayers(), armnn::GetOutputTensor(), TimelineUtilityMethods::GetTimelineUtils(), WorkingMemHandle::GetWorkingMemDescriptorAt(), LabelsAndEventClasses::INFERENCE_GUID, WorkingMemHandle::IsAllocated(), armnn::profiling::RetentionLink, armnn::Success, armnn::Undefined, and armnn::warning.

Referenced by RuntimeImpl::Execute(), and LoadedNetwork::FreeWorkingMemory().

1157 {
1158  const Graph& graph = m_OptimizedNetwork->pOptimizedNetworkImpl->GetGraph();
1159 
1160  // Walk graph to determine the order of execution.
1161  if (graph.GetNumLayers() < 2)
1162  {
1163  ARMNN_LOG(warning) << "IRuntime::EnqueueWorkload()::Less than two nodes in graph";
1164  return Status::Failure;
1165  }
1166 
1167  if (graph.GetNumInputs() != inputTensors.size())
1168  {
1169  throw InvalidArgumentException("Number of inputs provided does not match network.");
1170  }
1171 
1172  std::unique_ptr<profiling::TimelineUtilityMethods> timelineUtils =
1174  profiling::ProfilingGuid inferenceGuid = m_ProfilingService.GetNextGuid();
1175  if (timelineUtils)
1176  {
1177  // Add inference timeline trace if profiling is enabled.
1178  profiling::ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid();
1179  timelineUtils->CreateTypedEntity(inferenceGuid, profiling::LabelsAndEventClasses::INFERENCE_GUID);
1180  timelineUtils->CreateRelationship(profiling::ProfilingRelationshipType::RetentionLink,
1181  networkGuid,
1182  inferenceGuid,
1184  timelineUtils->RecordEvent(inferenceGuid, profiling::LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
1185  }
1186 
1187  bool executionSucceeded = true;
1188 
1189  if (timelineUtils)
1190  {
1191  // Add end of life of the inference timeline if profiling is enabled.
1192  timelineUtils->RecordEvent(inferenceGuid, profiling::LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS);
1193  timelineUtils->Commit();
1194  }
1195  WorkingMemHandle& workingMemHandle = dynamic_cast<WorkingMemHandle&>(iWorkingMemHandle);
1196  std::lock_guard<std::mutex> lockGuard(workingMemHandle.GetMutex());
1197 
1198  if (!workingMemHandle.IsAllocated())
1199  {
1200  workingMemHandle.Allocate();
1201  }
1202 
1203  {
1205  for (const BindableLayer* inputLayer : graph.GetInputLayers())
1206  {
1207  EnqueueInput(*inputLayer, GetInputTensor(inputLayer->GetBindingId(), inputTensors), workingMemHandle);
1208  }
1209  }
1210 
1211  auto Fail = [&](const std::exception& error)
1212  {
1213  ARMNN_LOG(error) << "An error occurred attempting to execute a workload: " << error.what();
1214  executionSucceeded = false;
1215  };
1216  profiling::ProfilingDynamicGuid workloadInferenceID(0);
1217 
1218  try
1219  {
1220  for (unsigned int i = 0; i < m_WorkloadQueue.size(); ++i)
1221  {
1222  auto& workload = m_WorkloadQueue[i];
1223  if (timelineUtils)
1224  {
1225  workloadInferenceID = timelineUtils->RecordWorkloadInferenceAndStartOfLifeEvent(workload->GetGuid(),
1226  inferenceGuid);
1227  }
1228  workload->ExecuteAsync(workingMemHandle.GetWorkingMemDescriptorAt(i));
1229 
1230  if (timelineUtils)
1231  {
1232  timelineUtils->RecordEndOfLifeEvent(workloadInferenceID);
1233  }
1234  }
1235  }
1236  catch (const RuntimeException& error)
1237  {
1238  Fail(error);
1239  }
1240  catch (const std::runtime_error& error)
1241  {
1242  Fail(error);
1243  }
1244  // For each output to the network, call EnqueueOutput with the data passed by the user.
1245  {
1247  for (const BindableLayer *outputLayer : graph.GetOutputLayers())
1248  {
1249  EnqueueOutput(*outputLayer, GetOutputTensor(outputLayer->GetBindingId(), outputTensors), workingMemHandle);
1250  }
1251  }
1252 
1253  return executionSucceeded ? Status::Success : Status::Failure;
1254 }
static ARMNN_DLLEXPORT ProfilingStaticGuid INFERENCE_GUID
static std::unique_ptr< TimelineUtilityMethods > GetTimelineUtils(ProfilingService &profilingService)
const armnn::Tensor GetOutputTensor(const LayerBindingId layerId, const OutputTensors &outputTensors)
#define ARMNN_LOG(severity)
Definition: Logging.hpp:202
static ARMNN_DLLEXPORT ProfilingStaticGuid ARMNN_PROFILING_EOL_EVENT_CLASS
#define ARMNN_SCOPED_PROFILING_EVENT(backendId, name)
Definition: Profiling.hpp:173
static ARMNN_DLLEXPORT ProfilingStaticGuid ARMNN_PROFILING_SOL_EVENT_CLASS
static ARMNN_DLLEXPORT ProfilingStaticGuid EXECUTION_OF_GUID
static ProfilingDynamicGuid GetNextGuid()
const armnn::ConstTensor GetInputTensor(const LayerBindingId layerId, const InputTensors &inputTensors)

◆ FreeWorkingMemory()

void FreeWorkingMemory ( )

Definition at line 791 of file LoadedNetwork.cpp.

References ARMNN_LOG, armnn::error, and LoadedNetwork::Execute().

Referenced by RuntimeImpl::CreateWorkingMemHandle(), and RuntimeImpl::EnqueueWorkload().

792 {
793  std::lock_guard<std::mutex> lockGuard(m_WorkingMemMutex);
794  if (!m_IsWorkingMemAllocated)
795  {
796  return;
797  }
798  // Informs the memory managers to release memory in it's respective memory group
799  for (auto&& workloadFactory : m_WorkloadFactories)
800  {
801  IBackendInternal::IMemoryManagerSharedPtr memoryManager = workloadFactory.second.second;
802  if (memoryManager)
803  {
804  memoryManager->Release();
805  }
806  }
807  m_TensorHandleFactoryRegistry.ReleaseMemory();
808  m_IsWorkingMemAllocated = false;
809 }
std::shared_ptr< IMemoryManager > IMemoryManagerSharedPtr
void ReleaseMemory()
Release memory required for inference.

◆ GetInputTensorInfo()

TensorInfo GetInputTensorInfo ( LayerBindingId  layerId) const

Definition at line 386 of file LoadedNetwork.cpp.

References ARMNN_ASSERT_MSG.

Referenced by RuntimeImpl::GetInputTensorInfo().

387 {
388  for (auto&& inputLayer : m_OptimizedNetwork->pOptimizedNetworkImpl->GetGraph().GetInputLayers())
389  {
390  ARMNN_ASSERT_MSG(inputLayer->GetNumOutputSlots() == 1, "Input layer should have exactly 1 output slot");
391  if (inputLayer->GetBindingId() == layerId)
392  {
393  return inputLayer->GetOutputSlot(0).GetTensorInfo();
394  }
395  }
396 
397  throw InvalidArgumentException(fmt::format("No input layer is associated with id {}", layerId));
398 }
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15

◆ GetNetworkGuid()

profiling::ProfilingGuid GetNetworkGuid ( )

Definition at line 381 of file LoadedNetwork.cpp.

382 {
383  return m_OptimizedNetwork->GetGuid();
384 }

◆ GetOutputTensorInfo()

TensorInfo GetOutputTensorInfo ( LayerBindingId  layerId) const

Definition at line 400 of file LoadedNetwork.cpp.

References ARMNN_ASSERT_MSG, CHECK_LOCATION, BackendId::Get(), Layer::GetBackendId(), Layer::GetNameStr(), armnn::IgnoreUnused(), armnn::info, and IWorkloadFactory::IsLayerSupported().

Referenced by RuntimeImpl::GetOutputTensorInfo().

401 {
402  for (auto&& outputLayer : m_OptimizedNetwork->pOptimizedNetworkImpl->GetGraph().GetOutputLayers())
403  {
404  ARMNN_ASSERT_MSG(outputLayer->GetNumInputSlots() == 1, "Output layer should have exactly 1 input slot");
405  ARMNN_ASSERT_MSG(outputLayer->GetInputSlot(0).GetConnection(), "Input slot on Output layer must be connected");
406  if (outputLayer->GetBindingId() == layerId)
407  {
408  return outputLayer->GetInputSlot(0).GetConnection()->GetTensorInfo();
409  }
410  }
411 
412  throw InvalidArgumentException(fmt::format("No output layer is associated with id {}", layerId));
413 }
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15

◆ GetProfiler()

const std::shared_ptr<IProfiler>& GetProfiler ( ) const
inline

◆ IsAsyncEnabled()

bool IsAsyncEnabled ( )
inline

Definition at line 90 of file LoadedNetwork.hpp.

Referenced by RuntimeImpl::CreateWorkingMemHandle(), RuntimeImpl::EnqueueWorkload(), RuntimeImpl::Execute(), and RuntimeImpl::Schedule().

91  {
92  return m_NetworkProperties.m_AsyncEnabled;
93  }

◆ MakeLoadedNetwork()

std::unique_ptr< LoadedNetwork > MakeLoadedNetwork ( std::unique_ptr< IOptimizedNetwork net,
std::string &  errorMessage,
const INetworkProperties networkProperties,
profiling::ProfilingService profilingService,
const NetworkId  networkIdOut 
)
static

Definition at line 85 of file LoadedNetwork.cpp.

References ITensorHandle::Allocate(), ARMNN_ASSERT, ARMNN_LOG, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS, armnn::BackendRegistryInstance(), armnn::Constant, IBackendInternal::CreateMemoryManager(), IBackendInternal::CreateWorkloadFactory(), armnn::error, armnnUtils::Processes::GetCurrentId(), BackendRegistry::GetFactory(), ProfilerManager::GetInstance(), TimelineUtilityMethods::GetTimelineUtils(), armnn::Input, ITensorHandleFactory::LegacyFactoryId, INetworkProperties::m_AsyncEnabled, WorkingMemDescriptor::m_Outputs, armnn::MemImport, LabelsAndEventClasses::NETWORK_GUID, armnn::Output, LabelsAndEventClasses::PROCESS_ID_GUID, ProfilerManager::RegisterProfiler(), IBackendInternal::SupportsTensorAllocatorAPI(), and Graph::TopologicalSort().

Referenced by RuntimeImpl::LoadNetwork().

90 {
91  std::unique_ptr<LoadedNetwork> loadedNetwork;
92 
93  auto Fail = [&](const std::exception& error) -> std::unique_ptr<LoadedNetwork>
94  {
95  errorMessage = ToErrorMessage("An error occurred when preparing the network workloads: ", error);
96  ARMNN_LOG(error) << errorMessage;
97 
98  return std::unique_ptr<LoadedNetwork>();
99  };
100 
101  try
102  {
103  loadedNetwork.reset(new LoadedNetwork(std::move(net), networkProperties, profilingService, networkIdOut));
104  }
105  catch (const armnn::RuntimeException& error)
106  {
107  return Fail(error);
108  }
109  catch (const armnn::Exception& error)
110  {
111  return Fail(error);
112  }
113  catch (const std::runtime_error& error)
114  {
115  return Fail(error);
116  }
117 
118  return loadedNetwork;
119 }
#define ARMNN_LOG(severity)
Definition: Logging.hpp:202
Base class for all ArmNN exceptions so that users can filter to just those.
Definition: Exceptions.hpp:46

◆ RegisterDebugCallback()

void RegisterDebugCallback ( const DebugCallbackFunction func)

Definition at line 1400 of file LoadedNetwork.cpp.

Referenced by RuntimeImpl::RegisterDebugCallback().

1401 {
1402  for (auto&& workloadPtr: m_WorkloadQueue)
1403  {
1404  workloadPtr.get()->RegisterDebugCallback(func);
1405  }
1406 }

◆ Schedule()

void Schedule ( const InputTensors inputTensors,
const OutputTensors outputTensors,
const QosExecPriority  priority,
std::shared_ptr< IAsyncExecutionCallback cb 
)

Schedule an asynchronous execution on the loaded network.

Definition at line 892 of file LoadedNetwork.cpp.

References ARMNN_ASSERT_MSG, ARMNN_SCOPED_PROFILING_EVENT, armnn::CheckFlag(), armnn::CopyTensorContentsGeneric(), armnn::EXPIRE_RATE, armnn::Failure, Layer::GetGuid(), ITensorHandle::GetImportFlags(), BaseTensor< MemoryType >::GetInfo(), Layer::GetInputSlots(), BaseTensor< MemoryType >::GetMemoryArea(), Layer::GetNumInputSlots(), armnn::GetTimeNow(), Layer::GetType(), WorkingMemHandle::GetWorkingMemDescriptor(), armnn::High, ITensorHandle::Import(), armnn::Input, armnn::Low, WorkingMemDescriptor::m_Inputs, WorkingMemDescriptor::m_Outputs, ITensorHandle::Map(), armnn::Medium, armnn::Output, armnn::Success, armnn::Undefined, and ITensorHandle::Unmap().

Referenced by RuntimeImpl::Schedule().

896 {
897  // Group execution parameters so that they can be easily added to the queue
898  ExecutionTuple groupExecParams = std::make_tuple(inputTensors, outputTensors, cb);
899  std::shared_ptr<ExecutionTuple> operation = make_shared<ExecutionTuple>(groupExecParams);
900 
901  // Add a message to the queue and notify the request thread
902  std::unique_lock<std::mutex> lock(m_ThreadPoolMutex);
903  switch (priority) {
905  m_HighPriorityQueue.push(operation);
906  break;
908  m_LowPriorityQueue.push(operation);
909  break;
911  default:
912  m_MediumPriorityQueue.push(operation);
913  }
914  m_ThreadPoolEvent.notify_one();
915 }
std::tuple< InputTensors, OutputTensors, std::shared_ptr< IAsyncExecutionCallback > > ExecutionTuple

◆ SendNetworkStructure()

void SendNetworkStructure ( )

Definition at line 344 of file LoadedNetwork.cpp.

References TimelineUtilityMethods::GetTimelineUtils(), armnn::Input, LabelsAndEventClasses::NETWORK_GUID, armnn::Output, and Graph::TopologicalSort().

345 {
346  Graph& order = m_OptimizedNetwork->pOptimizedNetworkImpl->GetGraph().TopologicalSort();
347  ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid();
348 
349  std::unique_ptr<TimelineUtilityMethods> timelineUtils =
350  TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
351 
352  timelineUtils->CreateTypedEntity(networkGuid, LabelsAndEventClasses::NETWORK_GUID);
353 
354  for (auto&& layer : order)
355  {
356  // Add layer to the post-optimisation network structure
357  AddLayerStructure(timelineUtils, *layer, networkGuid);
358  switch (layer->GetType())
359  {
360  case LayerType::Input:
361  case LayerType::Output:
362  {
363  // Inputs and outputs are treated in a special way - see EnqueueInput() and EnqueueOutput().
364  break;
365  }
366  default:
367  {
368  for (auto& workload : m_WorkloadQueue)
369  {
370  // Add workload to the post-optimisation network structure
371  AddWorkloadStructure(timelineUtils, workload, *layer);
372  }
373  break;
374  }
375  }
376  }
377  // Commit to send the post-optimisation network structure
378  timelineUtils->Commit();
379 }
static std::unique_ptr< TimelineUtilityMethods > GetTimelineUtils(ProfilingService &profilingService)
static ARMNN_DLLEXPORT ProfilingStaticGuid NETWORK_GUID

The documentation for this class was generated from the following files: