ArmNN
 21.11
LoadedNetwork.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
7 #include "Network.hpp"
8 #include "LayerFwd.hpp"
9 #include "Profiling.hpp"
10 
11 #include <armnn/Tensor.hpp>
20 
21 
22 #include <ProfilingService.hpp>
24 
25 #include <common/include/LabelsAndEventClasses.hpp>
26 
27 #include <mutex>
28 #include <condition_variable>
29 #include <unordered_map>
30 
31 namespace cl
32 {
33 class Context;
34 class CommandQueue;
35 class Device;
36 }
37 
38 namespace armnn
39 {
40 
42 {
43 public:
44  using WorkloadQueue = std::vector<std::unique_ptr<IWorkload>>;
45 
47  {
48  FreeWorkingMemory();
49  }
50 
51  /// Create a new unique WorkingMemHandle object. Create multiple handles if you wish to have
52  /// overlapped Execution by calling this function from different threads.
53  std::unique_ptr<IWorkingMemHandle> CreateWorkingMemHandle(NetworkId networkId);
54 
55  TensorInfo GetInputTensorInfo(LayerBindingId layerId) const;
56  TensorInfo GetOutputTensorInfo(LayerBindingId layerId) const;
57 
58  std::vector<ImportedInputId> ImportInputs(const InputTensors& inputTensors);
59  std::vector<ImportedOutputId> ImportOutputs(const OutputTensors& outputTensors);
60 
61  void ClearImportedInputs(const std::vector<ImportedInputId> inputIds);
62  void ClearImportedOutputs(const std::vector<ImportedOutputId> outputIds);
63 
64  /// Single thread execution of the loaded network
65  Status EnqueueWorkload(const InputTensors& inputTensors, const OutputTensors& outputTensors);
66 
67  /// Thread safe execution of the loaded network
68  Status Execute(const InputTensors& inputTensors,
69  const OutputTensors& outputTensors,
70  IWorkingMemHandle& workingMemHandle,
71  std::vector<ImportedInputId> preImportedInputs = {},
72  std::vector<ImportedOutputId> preImportedOutputs = {});
73 
74  static std::unique_ptr<LoadedNetwork> MakeLoadedNetwork(std::unique_ptr<IOptimizedNetwork> net,
75  std::string& errorMessage,
76  const INetworkProperties& networkProperties,
77  profiling::ProfilingService& profilingService);
78 
79  // NOTE we return by reference as the purpose of this method is only to provide
80  // access to the private m_Profiler and in theory we should not need to increment
81  // the shared_ptr's reference counter
82  const std::shared_ptr<IProfiler>& GetProfiler() const { return m_OptimizedNetwork->GetProfiler(); }
83 
84  void FreeWorkingMemory();
85 
86  void RegisterDebugCallback(const DebugCallbackFunction& func);
87 
88  void SendNetworkStructure();
89 
91  {
92  return m_NetworkProperties.m_AsyncEnabled;
93  }
94 
95  profiling::ProfilingGuid GetNetworkGuid();
96 
97 private:
98 
99 
100  void AllocateWorkingMemory(std::lock_guard<std::mutex>& lock);
101  void AllocateAndExecuteConstantWorkloads();
102  void AllocateAndExecuteConstantWorkloadsAsync();
103 
104  std::unordered_map<LayerGuid, std::unique_ptr<IWorkload>> m_ConstantWorkloads;
105  std::unordered_map<LayerGuid, ITensorHandle*> m_ConstantTensorHandles;
106 
107  std::unique_ptr<IMemoryOptimizerStrategy> m_ConstantStrategy = std::make_unique<SingleAxisPriorityList>();
108 
109  LoadedNetwork(std::unique_ptr<IOptimizedNetwork> net,
110  const INetworkProperties& networkProperties,
111  profiling::ProfilingService& profilingService);
112 
113  void EnqueueInput(const BindableLayer& layer, ITensorHandle* tensorHandle, const TensorInfo& tensorInfo);
114 
115  void EnqueueOutput(const BindableLayer& layer, ITensorHandle* tensorHandle, const TensorInfo& tensorInfo);
116 
117  void EnqueueInput(const ConstTensor& inputTensor, ITensorHandle* inputTensorHandle);
118 
119  void ImportOutputTensor(const Tensor& outputTensor, ITensorHandle* outputTensorHandle);
120 
121  bool Execute(std::unique_ptr<profiling::TimelineUtilityMethods>& timelineUtils,
122  profiling::ProfilingGuid inferenceGuid);
123 
124  const IWorkloadFactory& GetWorkloadFactory(const Layer& layer) const;
125 
126  inline LayerBindingId ValidateImportedInputID(ImportedInputId id);
127  inline LayerBindingId ValidateImportedOutputID(ImportedOutputId id);
128 
129  void CreateMemoryProfile();
130  void CreateMemoryProfileAsync();
131 
132  std::unique_ptr<MemoryManager> CreateExternalMemoryManger(
133  std::vector<std::pair<std::shared_ptr<TensorMemory>, MemorySource>>& tensorMemory);
134 
135  using BackendPtrMap = std::unordered_map<BackendId, IBackendInternalUniquePtr>;
136 
137  BackendPtrMap m_Backends;
138  std::vector<IBackendInternal::IMemoryManagerSharedPtr> m_BackendMemoryMangers;
139 
140  using WorkloadFactoryMap = std::unordered_map<BackendId, IBackendInternal::IWorkloadFactoryPtr>;
141  WorkloadFactoryMap m_WorkloadFactories;
142 
143  std::unique_ptr<IOptimizedNetwork> m_OptimizedNetwork;
144 
145  WorkloadQueue m_InputQueue;
146  WorkloadQueue m_WorkloadQueue;
147  WorkloadQueue m_OutputQueue;
148 
149  mutable std::mutex m_WorkingMemMutex;
150 
151  bool m_IsWorkingMemAllocated = false;
152 
153  INetworkProperties m_NetworkProperties;
154 
155  TensorHandleFactoryRegistry m_TensorHandleFactoryRegistry;
156 
157  profiling::ProfilingService& m_ProfilingService;
158 
159  struct ImportedTensorHandlePin
160  {
161  ImportedTensorHandlePin()
162  {}
163 
164  ImportedTensorHandlePin(LayerBindingId layerBindingId,
165  std::unique_ptr<ITensorHandle> tensorHandle)
166  : m_LayerBindingId(layerBindingId)
167  , m_TensorHandle(std::move(tensorHandle))
168  {}
169 
170  ImportedTensorHandlePin(ImportedTensorHandlePin&&) = default;
171 
172  ~ImportedTensorHandlePin()
173  {
174  if (m_TensorHandle)
175  {
176  m_TensorHandle->Unimport();
177  }
178  }
179 
180  LayerBindingId m_LayerBindingId;
181  std::unique_ptr<ITensorHandle> m_TensorHandle;
182  };
183 
184  std::vector<ImportedTensorHandlePin> m_PreImportedInputHandles;
185  std::vector<ImportedTensorHandlePin> m_PreImportedOutputHandles;
186 
187  ImportedInputId m_CurImportedInputId = 0;
188  ImportedInputId m_CurImportedOutputId = 0;
189 
190  std::unordered_map<BackendId, std::vector<MemBlock>> m_MemBlockMap;
191  std::unordered_map<BackendId, std::vector<MemBin>> m_MemBinMap;
192 
193  std::vector<ITensorHandle*> m_Tensorhandles;
194 
195  std::vector<std::pair<std::shared_ptr<TensorMemory>, MemorySource>> m_TensorMemory;
196 
197  std::unique_ptr<MemoryManager> m_ExternalMemoryManager;
198 
199  std::unordered_map<BackendId, bool> m_SupportsExternallyManagedMemory;
200 };
201 
202 }
unsigned int ImportedOutputId
Definition: Types.hpp:279
std::vector< std::pair< LayerBindingId, class ConstTensor > > InputTensors
Definition: Tensor.hpp:392
Copyright (c) 2021 ARM Limited and Contributors.
std::function< void(LayerGuid guid, unsigned int slotIndex, ITensorHandle *tensorHandle)> DebugCallbackFunction
Define the type of callback for the Debug layer to call.
Definition: Types.hpp:357
int LayerBindingId
Type of identifiers for bindable layers (inputs, outputs).
Definition: Types.hpp:277
A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
Definition: Tensor.hpp:319
int NetworkId
Definition: IRuntime.hpp:25
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
Definition: Tensor.hpp:327
std::vector< std::pair< LayerBindingId, class Tensor > > OutputTensors
Definition: Tensor.hpp:393
Status
enumeration
Definition: Types.hpp:29
std::vector< std::unique_ptr< IWorkload > > WorkloadQueue
unsigned int ImportedInputId
Definition: Types.hpp:278
const std::shared_ptr< IProfiler > & GetProfiler() const
MemorySource
Define the Memory Source to reduce copies.
Definition: Types.hpp:217