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