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