ArmNN
 20.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 
13 
14 #include <Optimizer.hpp>
15 #include <SubgraphViewSelector.hpp>
16 
17 #include <algorithm>
18 
19 namespace
20 {
21 
22 bool IsLayerSupported(const armnn::Layer* layer)
23 {
24  ARMNN_ASSERT(layer != nullptr);
25 
26  armnn::LayerType layerType = layer->GetType();
27  switch (layerType)
28  {
33  // Layer supported
34  return true;
35  default:
36  // Layer unsupported
37  return false;
38  }
39 }
40 
41 bool IsLayerSupported(const armnn::Layer& layer)
42 {
43  return IsLayerSupported(&layer);
44 }
45 
46 bool IsLayerOptimizable(const armnn::Layer* layer)
47 {
48  ARMNN_ASSERT(layer != nullptr);
49 
50  // A Layer is not optimizable if its name contains "unoptimizable"
51  const std::string layerName(layer->GetName());
52  bool optimizable = layerName.find("unoptimizable") == std::string::npos;
53 
54  return optimizable;
55 }
56 
57 bool IsLayerOptimizable(const armnn::Layer& layer)
58 {
59  return IsLayerOptimizable(&layer);
60 }
61 
62 } // Anonymous namespace
63 
64 namespace armnn
65 {
66 
68 {
70  []()
71  {
73  });
74 }
75 
77 {
78  try
79  {
81  }
82  catch (...)
83  {
84  std::cerr << "could not deregister mock backend" << std::endl;
85  }
86 }
87 
89 {
90  static const BackendId s_Id{MockBackendId()};
91  return s_Id;
92 }
93 
95  const IBackendInternal::IMemoryManagerSharedPtr& /*memoryManager*/) const
96 {
97  return IWorkloadFactoryPtr{};
98 }
99 
101 {
102  return IBackendContextPtr{};
103 }
104 
106  const IRuntime::CreationOptions& options, IBackendProfilingPtr& backendProfiling)
107 {
108  IgnoreUnused(options);
109  std::shared_ptr<armnn::MockBackendProfilingContext> context =
110  std::make_shared<MockBackendProfilingContext>(backendProfiling);
112  return context;
113 }
114 
116 {
117  return IMemoryManagerUniquePtr{};
118 }
119 
121 {
122  return Optimizations{};
123 }
124 
126 {
127  static ILayerSupportSharedPtr layerSupport{new MockLayerSupport};
128  return layerSupport;
129 }
130 
132 {
133  // Prepare the optimization views
134  OptimizationViews optimizationViews;
135 
136  // Get the layers of the input sub-graph
137  const SubgraphView::Layers& subgraphLayers = subgraph.GetLayers();
138 
139  // Parse the layers
140  SubgraphView::Layers supportedLayers;
141  SubgraphView::Layers unsupportedLayers;
142  SubgraphView::Layers untouchedLayers;
143  std::for_each(subgraphLayers.begin(),
144  subgraphLayers.end(),
145  [&](Layer* layer)
146  {
147  bool supported = IsLayerSupported(layer);
148  if (supported)
149  {
150  // Layer supported, check if it's optimizable
151  bool optimizable = IsLayerOptimizable(layer);
152  if (optimizable)
153  {
154  // Layer fully supported
155  supportedLayers.push_back(layer);
156  }
157  else
158  {
159  // Layer supported but not optimizable
160  untouchedLayers.push_back(layer);
161  }
162  }
163  else
164  {
165  // Layer unsupported
166  unsupportedLayers.push_back(layer);
167  }
168  });
169 
170  // Check if there are supported layers
171  if (!supportedLayers.empty())
172  {
173  // Select the layers that are neither inputs or outputs, but that are optimizable
174  auto supportedSubgraphSelector = [](const Layer& layer)
175  {
176  return layer.GetType() != LayerType::Input &&
177  layer.GetType() != LayerType::Output &&
178  IsLayerSupported(layer) &&
179  IsLayerOptimizable(layer);
180  };
181 
182  // Apply the subgraph selector to the supported layers to group them into sub-graphs were appropriate
183  SubgraphView mutableSubgraph(subgraph);
184  SubgraphViewSelector::Subgraphs supportedSubgraphs =
185  SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, supportedSubgraphSelector);
186 
187  // Create a substitution pair for each supported sub-graph
188  std::for_each(supportedSubgraphs.begin(),
189  supportedSubgraphs.end(),
190  [&optimizationViews](const SubgraphView::SubgraphViewPtr& supportedSubgraph)
191  {
192  ARMNN_ASSERT(supportedSubgraph != nullptr);
193 
194  PreCompiledLayer* preCompiledLayer =
195  optimizationViews.GetGraph().AddLayer<PreCompiledLayer>(
196  PreCompiledDescriptor(supportedSubgraph->GetNumInputSlots(),
197  supportedSubgraph->GetNumOutputSlots()),
198  "pre-compiled");
199  preCompiledLayer->SetBackendId(MockBackendId());
200 
201  SubgraphView substitutionSubgraph(*supportedSubgraph);
202  SubgraphView replacementSubgraph(preCompiledLayer);
203 
204  optimizationViews.AddSubstitution({ substitutionSubgraph, replacementSubgraph });
205  });
206  }
207 
208  // Check if there are unsupported layers
209  if (!unsupportedLayers.empty())
210  {
211  // Select the layers that are neither inputs or outputs, and are not optimizable
212  auto unsupportedSubgraphSelector = [](const Layer& layer)
213  {
214  return layer.GetType() != LayerType::Input &&
215  layer.GetType() != LayerType::Output &&
216  !IsLayerSupported(layer);
217  };
218 
219  // Apply the subgraph selector to the unsupported layers to group them into sub-graphs were appropriate
220  SubgraphView mutableSubgraph(subgraph);
221  SubgraphViewSelector::Subgraphs unsupportedSubgraphs =
222  SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, unsupportedSubgraphSelector);
223 
224  // Add each unsupported sub-graph to the list of failed sub-graphs in the optimizization views
225  std::for_each(unsupportedSubgraphs.begin(),
226  unsupportedSubgraphs.end(),
227  [&optimizationViews](const SubgraphView::SubgraphViewPtr& unsupportedSubgraph)
228  {
229  ARMNN_ASSERT(unsupportedSubgraph != nullptr);
230 
231  optimizationViews.AddFailedSubgraph(SubgraphView(*unsupportedSubgraph));
232  });
233  }
234 
235  // Check if there are untouched layers
236  if (!untouchedLayers.empty())
237  {
238  // Select the layers that are neither inputs or outputs, that are supported but that and are not optimizable
239  auto untouchedSubgraphSelector = [](const Layer& layer)
240  {
241  return layer.GetType() != LayerType::Input &&
242  layer.GetType() != LayerType::Output &&
243  IsLayerSupported(layer) &&
244  !IsLayerOptimizable(layer);
245  };
246 
247  // Apply the subgraph selector to the untouched layers to group them into sub-graphs were appropriate
248  SubgraphView mutableSubgraph(subgraph);
249  SubgraphViewSelector::Subgraphs untouchedSubgraphs =
250  SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, untouchedSubgraphSelector);
251 
252  // Add each untouched sub-graph to the list of untouched sub-graphs in the optimizization views
253  std::for_each(untouchedSubgraphs.begin(),
254  untouchedSubgraphs.end(),
255  [&optimizationViews](const SubgraphView::SubgraphViewPtr& untouchedSubgraph)
256  {
257  ARMNN_ASSERT(untouchedSubgraph != nullptr);
258 
259  optimizationViews.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph));
260  });
261  }
262 
263  return optimizationViews;
264 }
265 
266 } // namespace armnn
std::unique_ptr< IWorkloadFactory > IWorkloadFactoryPtr
void SetProfilingContextPtr(std::shared_ptr< MockBackendProfilingContext > shared)
std::vector< OptimizationPtr > Optimizations
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:402
IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory(const IBackendInternal::IMemoryManagerSharedPtr &memoryManager=nullptr) const override
Definition: MockBackend.cpp:94
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) 2020 ARM Limited.
std::unique_ptr< IMemoryManager > IMemoryManagerUniquePtr
void IgnoreUnused(Ts &&...)
void SetBackendId(const BackendId &id)
Definition: Layer.hpp:267
IBackendInternal::Optimizations GetOptimizations() const override
The SubgraphView class represents a subgraph of a Graph.
std::unique_ptr< armnn::profiling::IBackendProfiling > IBackendProfilingPtr
std::unique_ptr< SubgraphView > SubgraphViewPtr
std::shared_ptr< IMemoryManager > IMemoryManagerSharedPtr
static const BackendId & GetIdStatic()
Definition: MockBackend.cpp:88
void AddFailedSubgraph(SubgraphView &&subgraph)
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
LayerType GetType() const
Definition: Layer.hpp:262
const char * GetName() const override
Returns the name of the layer.
Definition: Layer.hpp:308
std::unique_ptr< IBackendInternal > IBackendInternalUniquePtr
A PreCompiledDescriptor for the PreCompiledLayer.
std::list< Layer * > Layers
std::unique_ptr< ISubGraphConverter > supported
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
std::unique_ptr< IBackendContext > IBackendContextPtr