ArmNN
 21.02
LoadedNetwork Class Reference

#include <LoadedNetwork.hpp>

Public Types

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

Public Member Functions

 ~LoadedNetwork ()
 
TensorInfo GetInputTensorInfo (LayerBindingId layerId) const
 
TensorInfo GetOutputTensorInfo (LayerBindingId layerId) const
 
Status EnqueueWorkload (const InputTensors &inputTensors, const OutputTensors &outputTensors)
 
const std::shared_ptr< IProfiler > & GetProfiler () const
 
void FreeWorkingMemory ()
 
void RegisterDebugCallback (const DebugCallbackFunction &func)
 
void SendNetworkStructure ()
 
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)
 

Detailed Description

Definition at line 34 of file LoadedNetwork.hpp.

Member Typedef Documentation

◆ WorkloadQueue

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

Definition at line 37 of file LoadedNetwork.hpp.

Constructor & Destructor Documentation

◆ ~LoadedNetwork()

~LoadedNetwork ( )
inline

Definition at line 38 of file LoadedNetwork.hpp.

References armnn::GetInputTensorInfo().

Member Function Documentation

◆ EnqueueWorkload()

Status EnqueueWorkload ( const InputTensors inputTensors,
const OutputTensors outputTensors 
)

Definition at line 470 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, armnn::Malloc, ITensorHandle::Map(), armnn::Output, armnn::Success, armnn::Undefined, ITensorHandle::Unmap(), and armnn::warning.

Referenced by RuntimeImpl::EnqueueWorkload().

472 {
473  const Graph& graph = m_OptimizedNetwork->pOptimizedNetworkImpl->GetGraph();
474 
475  // Walk graph to determine the order of execution.
476  if (graph.GetNumLayers() < 2)
477  {
478  ARMNN_LOG(warning) << "IRuntime::EnqueueWorkload()::Less than two nodes in graph";
479  return Status::Failure;
480  }
481 
482  // Data that must be kept alive for the entire execution of the workload.
483  WorkloadData workloadData(inputTensors, outputTensors);
484 
485  if (graph.GetNumInputs() != inputTensors.size())
486  {
487  throw InvalidArgumentException("Number of inputs provided does not match network.");
488  }
489 
490  // For each input to the network, call EnqueueInput with the data passed by the user.
491  {
493  m_InputQueue.clear();
494  m_InputQueue.reserve(graph.GetNumInputs());
495  for (const BindableLayer* inputLayer : graph.GetInputLayers())
496  {
497  const TensorPin& pin = workloadData.GetInputTensorPin(inputLayer->GetBindingId());
498  EnqueueInput(*inputLayer, pin.GetTensorHandle(), pin.GetTensorInfo());
499  }
500  }
501 
502  // For each output to the network, call EnqueueOutput with the data passed by the user.
503  {
505  m_OutputQueue.clear();
506  m_OutputQueue.reserve(graph.GetNumOutputs());
507  for (const BindableLayer* outputLayer : graph.GetOutputLayers())
508  {
509  const TensorPin& pin = workloadData.GetOutputTensorPin(outputLayer->GetBindingId());
510  EnqueueOutput(*outputLayer, pin.GetTensorHandle(), pin.GetTensorInfo());
511  }
512  }
513 
514  std::unique_ptr<TimelineUtilityMethods> timelineUtils =
515  TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
516  ProfilingGuid inferenceGuid = m_ProfilingService.GetNextGuid();
517  if (timelineUtils)
518  {
519  // Add inference timeline trace if profiling is enabled.
520  ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid();
521  timelineUtils->CreateTypedEntity(inferenceGuid, LabelsAndEventClasses::INFERENCE_GUID);
522  timelineUtils->CreateRelationship(ProfilingRelationshipType::RetentionLink,
523  networkGuid,
524  inferenceGuid,
526  timelineUtils->RecordEvent(inferenceGuid, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
527  }
528 
529  bool executionSucceeded = true;
530 
531  {
532  if (m_ProfilingService.IsProfilingEnabled())
533  {
534  m_ProfilingService.IncrementCounterValue(armnn::profiling::INFERENCES_RUN);
535  }
537  ARMNN_SCOPED_HEAP_PROFILING("Executing");
538  executionSucceeded = Execute(timelineUtils, inferenceGuid);
539  }
540 
541  if (timelineUtils)
542  {
543  // Add end of life of the inference timeline if profiling is enabled.
544  timelineUtils->RecordEvent(inferenceGuid, LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS);
545  timelineUtils->Commit();
546  }
547  return executionSucceeded ? Status::Success : Status::Failure;
548 }
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
#define ARMNN_SCOPED_HEAP_PROFILING(TAG)
static ARMNN_DLLEXPORT ProfilingStaticGuid EXECUTION_OF_GUID
bool IsProfilingEnabled() const override
static ProfilingDynamicGuid GetNextGuid()

◆ FreeWorkingMemory()

void FreeWorkingMemory ( )

Definition at line 725 of file LoadedNetwork.cpp.

References ARMNN_LOG, and armnn::error.

Referenced by RuntimeImpl::EnqueueWorkload().

726 {
727  std::lock_guard<std::mutex> lockGuard(m_WorkingMemMutex);
728  if (!m_IsWorkingMemAllocated)
729  {
730  return;
731  }
732  // Informs the memory managers to release memory in it's respective memory group
733  for (auto&& workloadFactory : m_WorkloadFactories)
734  {
735  IBackendInternal::IMemoryManagerSharedPtr memoryManager = workloadFactory.second.second;
736  if (memoryManager)
737  {
738  memoryManager->Release();
739  }
740  }
741  m_TensorHandleFactoryRegistry.ReleaseMemory();
742  m_IsWorkingMemAllocated = false;
743 }
std::shared_ptr< IMemoryManager > IMemoryManagerSharedPtr
void ReleaseMemory()
Release memory required for inference.

◆ GetInputTensorInfo()

TensorInfo GetInputTensorInfo ( LayerBindingId  layerId) const

Definition at line 321 of file LoadedNetwork.cpp.

References ARMNN_ASSERT_MSG.

Referenced by RuntimeImpl::GetInputTensorInfo().

322 {
323  for (auto&& inputLayer : m_OptimizedNetwork->pOptimizedNetworkImpl->GetGraph().GetInputLayers())
324  {
325  ARMNN_ASSERT_MSG(inputLayer->GetNumOutputSlots() == 1, "Input layer should have exactly 1 output slot");
326  if (inputLayer->GetBindingId() == layerId)
327  {
328  return inputLayer->GetOutputSlot(0).GetTensorInfo();
329  }
330  }
331 
332  throw InvalidArgumentException(fmt::format("No input layer is associated with id {}", layerId));
333 }
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15

◆ GetNetworkGuid()

profiling::ProfilingGuid GetNetworkGuid ( )

Definition at line 316 of file LoadedNetwork.cpp.

317 {
318  return m_OptimizedNetwork->GetGuid();
319 }

◆ GetOutputTensorInfo()

TensorInfo GetOutputTensorInfo ( LayerBindingId  layerId) const

Definition at line 335 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().

336 {
337  for (auto&& outputLayer : m_OptimizedNetwork->pOptimizedNetworkImpl->GetGraph().GetOutputLayers())
338  {
339  ARMNN_ASSERT_MSG(outputLayer->GetNumInputSlots() == 1, "Output layer should have exactly 1 input slot");
340  ARMNN_ASSERT_MSG(outputLayer->GetInputSlot(0).GetConnection(), "Input slot on Output layer must be connected");
341  if (outputLayer->GetBindingId() == layerId)
342  {
343  return outputLayer->GetInputSlot(0).GetConnection()->GetTensorInfo();
344  }
345  }
346 
347  throw InvalidArgumentException(fmt::format("No output layer is associated with id {}", layerId));
348 }
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15

◆ GetProfiler()

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

Definition at line 53 of file LoadedNetwork.hpp.

Referenced by RuntimeImpl::EnqueueWorkload().

53 { return m_Profiler; }

◆ MakeLoadedNetwork()

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

Definition at line 83 of file LoadedNetwork.cpp.

References ARMNN_LOG, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS, armnn::BackendRegistryInstance(), IBackendInternal::CreateMemoryManager(), IBackendInternal::CreateWorkloadFactory(), armnn::error, armnnUtils::Processes::GetCurrentId(), BackendRegistry::GetFactory(), ProfilerManager::GetInstance(), TimelineUtilityMethods::GetTimelineUtils(), armnn::Input, INetworkProperties::m_ExportEnabled, INetworkProperties::m_ImportEnabled, armnn::MemImport, LabelsAndEventClasses::NETWORK_GUID, armnn::Output, LabelsAndEventClasses::PROCESS_ID_GUID, ProfilerManager::RegisterProfiler(), IBackendInternal::SupportsTensorAllocatorAPI(), and Graph::TopologicalSort().

Referenced by RuntimeImpl::LoadNetwork().

87 {
88  std::unique_ptr<LoadedNetwork> loadedNetwork;
89 
90  auto Fail = [&](const std::exception& error) -> std::unique_ptr<LoadedNetwork>
91  {
92  errorMessage = ToErrorMessage("An error occurred when preparing the network workloads: ", error);
93  ARMNN_LOG(error) << errorMessage;
94 
95  return std::unique_ptr<LoadedNetwork>();
96  };
97 
98  try
99  {
100  loadedNetwork.reset(new LoadedNetwork(std::move(net), networkProperties, profilingService));
101  }
102  catch (const armnn::RuntimeException& error)
103  {
104  return Fail(error);
105  }
106  catch (const armnn::Exception& error)
107  {
108  return Fail(error);
109  }
110  catch (const std::runtime_error& error)
111  {
112  return Fail(error);
113  }
114 
115  return loadedNetwork;
116 }
#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 795 of file LoadedNetwork.cpp.

Referenced by RuntimeImpl::RegisterDebugCallback().

796 {
797  for (auto&& workloadPtr: m_WorkloadQueue)
798  {
799  workloadPtr.get()->RegisterDebugCallback(func);
800  }
801 }

◆ SendNetworkStructure()

void SendNetworkStructure ( )

Definition at line 279 of file LoadedNetwork.cpp.

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

280 {
281  Graph& order = m_OptimizedNetwork->pOptimizedNetworkImpl->GetGraph().TopologicalSort();
282  ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid();
283 
284  std::unique_ptr<TimelineUtilityMethods> timelineUtils =
285  TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
286 
287  timelineUtils->CreateTypedEntity(networkGuid, LabelsAndEventClasses::NETWORK_GUID);
288 
289  for (auto&& layer : order)
290  {
291  // Add layer to the post-optimisation network structure
292  AddLayerStructure(timelineUtils, *layer, networkGuid);
293  switch (layer->GetType())
294  {
295  case LayerType::Input:
296  case LayerType::Output:
297  {
298  // Inputs and outputs are treated in a special way - see EnqueueInput() and EnqueueOutput().
299  break;
300  }
301  default:
302  {
303  for (auto& workload : m_WorkloadQueue)
304  {
305  // Add workload to the post-optimisation network structure
306  AddWorkloadStructure(timelineUtils, workload, *layer);
307  }
308  break;
309  }
310  }
311  }
312  // Commit to send the post-optimisation network structure
313  timelineUtils->Commit();
314 }
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: