ArmNN
 21.11
MockBackend.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "MockBackend.hpp"
7 #include "MockBackendId.hpp"
8 
10 
14 
15 #include <Optimizer.hpp>
16 #include <SubgraphViewSelector.hpp>
17 
18 #include <algorithm>
19 
20 namespace
21 {
22 
23 bool IsLayerSupported(const armnn::Layer* layer)
24 {
25  ARMNN_ASSERT(layer != nullptr);
26 
27  armnn::LayerType layerType = layer->GetType();
28  switch (layerType)
29  {
34  // Layer supported
35  return true;
36  default:
37  // Layer unsupported
38  return false;
39  }
40 }
41 
42 bool IsLayerSupported(const armnn::Layer& layer)
43 {
44  return IsLayerSupported(&layer);
45 }
46 
47 bool IsLayerOptimizable(const armnn::Layer* layer)
48 {
49  ARMNN_ASSERT(layer != nullptr);
50 
51  // A Layer is not optimizable if its name contains "unoptimizable"
52  const std::string layerName(layer->GetName());
53  bool optimizable = layerName.find("unoptimizable") == std::string::npos;
54 
55  return optimizable;
56 }
57 
58 bool IsLayerOptimizable(const armnn::Layer& layer)
59 {
60  return IsLayerOptimizable(&layer);
61 }
62 
63 } // Anonymous namespace
64 
65 namespace armnn
66 {
67 
69 {
71  []()
72  {
74  });
75 }
76 
78 {
79  try
80  {
82  }
83  catch (...)
84  {
85  std::cerr << "could not deregister mock backend" << std::endl;
86  }
87 }
88 
90 {
91  static const BackendId s_Id{MockBackendId()};
92  return s_Id;
93 }
94 
96  const IBackendInternal::IMemoryManagerSharedPtr& /*memoryManager*/) const
97 {
98  return IWorkloadFactoryPtr{};
99 }
100 
102 {
103  return IBackendContextPtr{};
104 }
105 
107  const IRuntime::CreationOptions& options, IBackendProfilingPtr& backendProfiling)
108 {
109  IgnoreUnused(options);
110  std::shared_ptr<armnn::MockBackendProfilingContext> context =
111  std::make_shared<MockBackendProfilingContext>(backendProfiling);
113  return context;
114 }
115 
117 {
118  return IMemoryManagerUniquePtr{};
119 }
120 
122 {
123  static ILayerSupportSharedPtr layerSupport{new MockLayerSupport};
124  return layerSupport;
125 }
126 
128 {
129  // Prepare the optimization views
130  OptimizationViews optimizationViews;
131 
132  // Get the layers of the input sub-graph
133  const SubgraphView::Layers& subgraphLayers = subgraph.GetLayers();
134 
135  // Parse the layers
136  SubgraphView::Layers supportedLayers;
137  SubgraphView::Layers unsupportedLayers;
138  SubgraphView::Layers untouchedLayers;
139  std::for_each(subgraphLayers.begin(),
140  subgraphLayers.end(),
141  [&](Layer* layer)
142  {
143  bool supported = IsLayerSupported(layer);
144  if (supported)
145  {
146  // Layer supported, check if it's optimizable
147  bool optimizable = IsLayerOptimizable(layer);
148  if (optimizable)
149  {
150  // Layer fully supported
151  supportedLayers.push_back(layer);
152  }
153  else
154  {
155  // Layer supported but not optimizable
156  untouchedLayers.push_back(layer);
157  }
158  }
159  else
160  {
161  // Layer unsupported
162  unsupportedLayers.push_back(layer);
163  }
164  });
165 
166  // Check if there are supported layers
167  if (!supportedLayers.empty())
168  {
169  // Select the layers that are neither inputs or outputs, but that are optimizable
170  auto supportedSubgraphSelector = [](const Layer& layer)
171  {
172  return layer.GetType() != LayerType::Input &&
173  layer.GetType() != LayerType::Output &&
174  IsLayerSupported(layer) &&
175  IsLayerOptimizable(layer);
176  };
177 
178  // Apply the subgraph selector to the supported layers to group them into sub-graphs were appropriate
179  SubgraphView mutableSubgraph(subgraph);
180  SubgraphViewSelector::Subgraphs supportedSubgraphs =
181  SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, supportedSubgraphSelector);
182 
183  // Create a substitution pair for each supported sub-graph
184  std::for_each(supportedSubgraphs.begin(),
185  supportedSubgraphs.end(),
186  [&optimizationViews](const SubgraphView::SubgraphViewPtr& supportedSubgraph)
187  {
188  ARMNN_ASSERT(supportedSubgraph != nullptr);
189 
190  PreCompiledLayer* preCompiledLayer =
191  optimizationViews.GetGraph().AddLayer<PreCompiledLayer>(
192  PreCompiledDescriptor(supportedSubgraph->GetNumInputSlots(),
193  supportedSubgraph->GetNumOutputSlots()),
194  "pre-compiled");
195  preCompiledLayer->SetBackendId(MockBackendId());
196 
197  SubgraphView substitutionSubgraph(*supportedSubgraph);
198  SubgraphView replacementSubgraph(preCompiledLayer);
199 
200  optimizationViews.AddSubstitution({ substitutionSubgraph, replacementSubgraph });
201  });
202  }
203 
204  // Check if there are unsupported layers
205  if (!unsupportedLayers.empty())
206  {
207  // Select the layers that are neither inputs or outputs, and are not optimizable
208  auto unsupportedSubgraphSelector = [](const Layer& layer)
209  {
210  return layer.GetType() != LayerType::Input &&
211  layer.GetType() != LayerType::Output &&
212  !IsLayerSupported(layer);
213  };
214 
215  // Apply the subgraph selector to the unsupported layers to group them into sub-graphs were appropriate
216  SubgraphView mutableSubgraph(subgraph);
217  SubgraphViewSelector::Subgraphs unsupportedSubgraphs =
218  SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, unsupportedSubgraphSelector);
219 
220  // Add each unsupported sub-graph to the list of failed sub-graphs in the optimizization views
221  std::for_each(unsupportedSubgraphs.begin(),
222  unsupportedSubgraphs.end(),
223  [&optimizationViews](const SubgraphView::SubgraphViewPtr& unsupportedSubgraph)
224  {
225  ARMNN_ASSERT(unsupportedSubgraph != nullptr);
226 
227  optimizationViews.AddFailedSubgraph(SubgraphView(*unsupportedSubgraph));
228  });
229  }
230 
231  // Check if there are untouched layers
232  if (!untouchedLayers.empty())
233  {
234  // Select the layers that are neither inputs or outputs, that are supported but that and are not optimizable
235  auto untouchedSubgraphSelector = [](const Layer& layer)
236  {
237  return layer.GetType() != LayerType::Input &&
238  layer.GetType() != LayerType::Output &&
239  IsLayerSupported(layer) &&
240  !IsLayerOptimizable(layer);
241  };
242 
243  // Apply the subgraph selector to the untouched layers to group them into sub-graphs were appropriate
244  SubgraphView mutableSubgraph(subgraph);
245  SubgraphViewSelector::Subgraphs untouchedSubgraphs =
246  SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, untouchedSubgraphSelector);
247 
248  // Add each untouched sub-graph to the list of untouched sub-graphs in the optimizization views
249  std::for_each(untouchedSubgraphs.begin(),
250  untouchedSubgraphs.end(),
251  [&optimizationViews](const SubgraphView::SubgraphViewPtr& untouchedSubgraph)
252  {
253  ARMNN_ASSERT(untouchedSubgraph != nullptr);
254 
255  optimizationViews.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph));
256  });
257  }
258 
259  return optimizationViews;
260 }
261 
262 std::unique_ptr<ICustomAllocator> MockBackend::GetDefaultAllocator() const
263 {
264  return std::make_unique<DefaultAllocator>();
265 }
266 
267 } // namespace armnn
std::unique_ptr< IWorkloadFactory > IWorkloadFactoryPtr
void SetProfilingContextPtr(std::shared_ptr< MockBackendProfilingContext > shared)
void Register(const BackendId &id, FactoryFunction factory)
LayerT * AddLayer(Args &&... args)
Adds a new layer, of type LayerType, to the graph constructed with the arguments passed.
Definition: Graph.hpp:417
IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory(const IBackendInternal::IMemoryManagerSharedPtr &memoryManager=nullptr) const override
Definition: MockBackend.cpp:95
IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override
void AddSubstitution(SubstitutionPair &&substitution)
constexpr const char * MockBackendId()
IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions &) const override
Create the runtime context of the backend.
BackendRegistry & BackendRegistryInstance()
OptimizationViews OptimizeSubgraphView(const SubgraphView &subgraph) const override
Copyright (c) 2021 ARM Limited and Contributors.
std::unique_ptr< IMemoryManager > IMemoryManagerUniquePtr
void IgnoreUnused(Ts &&...)
void SetBackendId(const BackendId &id)
Definition: Layer.hpp:270
The SubgraphView class represents a subgraph of a Graph.
std::unique_ptr< armnn::profiling::IBackendProfiling > IBackendProfilingPtr
std::unique_ptr< SubgraphView > SubgraphViewPtr
std::unique_ptr< ICustomAllocator > GetDefaultAllocator() const override
Returns the default memory allocator for the backend.
std::shared_ptr< IMemoryManager > IMemoryManagerSharedPtr
static const BackendId & GetIdStatic()
Definition: MockBackend.cpp:89
void AddFailedSubgraph(SubgraphView &&subgraph)
LayerType GetType() const override
Returns the armnn::LayerType of this layer.
Definition: Layer.hpp:265
std::vector< SubgraphViewPtr > Subgraphs
#define ARMNN_ASSERT(COND)
Definition: Assert.hpp:14
static MockBackendProfilingService & Instance()
void AddUntouchedSubgraph(SubgraphView &&subgraph)
IBackendInternal::IBackendProfilingContextPtr CreateBackendProfilingContext(const IRuntime::CreationOptions &creationOptions, IBackendProfilingPtr &backendProfiling) override
Create context specifically used for profiling interaction from backends.
std::shared_ptr< ILayerSupport > ILayerSupportSharedPtr
static Subgraphs SelectSubgraphs(Graph &graph, const LayerSelectorFunction &selector)
Selects subgraphs from a graph based on the selector function and the algorithm.
void Deregister(const BackendId &id)
const Layers & GetLayers() const
const char * GetName() const override
Returns the name of the layer.
Definition: Layer.hpp:311
std::unique_ptr< IBackendInternal > IBackendInternalUniquePtr
A PreCompiledDescriptor for the PreCompiledLayer.
std::list< Layer * > Layers
std::shared_ptr< armnn::profiling::IBackendProfilingContext > IBackendProfilingContextPtr
This is the bridge between backend and backend profiling we&#39;ll keep it in the backend namespace...
IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below...
Definition: Types.hpp:443
std::unique_ptr< IBackendContext > IBackendContextPtr