ArmNN
 20.02
SubgraphViewSelector Class Referencefinal

Algorithm that splits a Graph into Subgraphs based on a filtering of layers (e.g. More...

#include <SubgraphViewSelector.hpp>

Public Types

using SubgraphViewPtr = std::unique_ptr< SubgraphView >
 
using Subgraphs = std::vector< SubgraphViewPtr >
 
using LayerSelectorFunction = std::function< bool(const Layer &)>
 

Static Public Member Functions

static Subgraphs SelectSubgraphs (Graph &graph, const LayerSelectorFunction &selector)
 Selects subgraphs from a graph based on the selector function and the algorithm. More...
 
static Subgraphs SelectSubgraphs (SubgraphView &subgraph, const LayerSelectorFunction &selector)
 

Detailed Description

Algorithm that splits a Graph into Subgraphs based on a filtering of layers (e.g.

which layers are appropriate for a certain backend). The resulting subgraphs are guaranteed to be form a DAG (i.e. there are no dependency loops).

The algorithm aims to produce as few subgraphs as possible.

Definition at line 21 of file SubgraphViewSelector.hpp.

Member Typedef Documentation

◆ LayerSelectorFunction

using LayerSelectorFunction = std::function<bool(const Layer&)>

Definition at line 26 of file SubgraphViewSelector.hpp.

◆ Subgraphs

using Subgraphs = std::vector<SubgraphViewPtr>

Definition at line 25 of file SubgraphViewSelector.hpp.

◆ SubgraphViewPtr

using SubgraphViewPtr = std::unique_ptr<SubgraphView>

Definition at line 24 of file SubgraphViewSelector.hpp.

Member Function Documentation

◆ SelectSubgraphs() [1/2]

SubgraphViewSelector::Subgraphs SelectSubgraphs ( Graph graph,
const LayerSelectorFunction selector 
)
static

Selects subgraphs from a graph based on the selector function and the algorithm.

Since the Subgraphs object returns modifiable pointers to the input and output slots of the graph: 1) the graph/sub-graph cannot be const 2) the caller needs to make sure that the Subgraphs lifetime is shorter than the parent graph's

Definition at line 254 of file SubgraphViewSelector.cpp.

Referenced by armnn::ApplyBackendOptimizations(), BOOST_AUTO_TEST_CASE(), and MockBackend::OptimizeSubgraphView().

255 {
256  SubgraphView subgraph(graph);
257  return SubgraphViewSelector::SelectSubgraphs(subgraph, selector);
258 }
static Subgraphs SelectSubgraphs(Graph &graph, const LayerSelectorFunction &selector)
Selects subgraphs from a graph based on the selector function and the algorithm.

◆ SelectSubgraphs() [2/2]

SubgraphViewSelector::Subgraphs SelectSubgraphs ( SubgraphView subgraph,
const LayerSelectorFunction selector 
)
static

Definition at line 384 of file SubgraphViewSelector.cpp.

References armnn::AssignSplitId(), armnn::ForEachLayerOutput(), armnn::info, and armnn::IsReadyForSplitAssignment().

385 {
386  LayerSelectionInfo::LayerInfoContainer layerInfos;
387 
388  LayerSelectionInfo::LayerInfoQueue processQueue;
389  for (auto& layer : subgraph)
390  {
391  auto emplaced = layerInfos.emplace(layer, LayerSelectionInfo{layer, selector});
392  LayerSelectionInfo& layerInfo = emplaced.first->second;
393 
394  // Start with Input type layers
395  if (layerInfo.IsInputLayer())
396  {
397  processQueue.push(&layerInfo);
398  }
399  }
400 
401  const SubgraphView::InputSlots& subgraphInputSlots = subgraph.GetInputSlots();
402  for (auto& inputSlot : subgraphInputSlots)
403  {
404  Layer& layer = inputSlot->GetOwningLayer();
405  auto emplaced = layerInfos.emplace(&layer, LayerSelectionInfo{&layer, selector});
406  LayerSelectionInfo& layerInfo = emplaced.first->second;
407 
408  processQueue.push(&layerInfo);
409  }
410 
411  while (!processQueue.empty())
412  {
413  LayerSelectionInfo& layerInfo = *processQueue.front();
414  processQueue.pop(); // remove front from queue
415 
416  // This layerInfo may have been added to the queue multiple times, so skip if we have already processed it
417  if (!layerInfo.m_IsProcessed)
418  {
419  // Only process this layerInfo if all inputs have been processed
420  if (!IsReadyForSplitAssignment(layerInfos, layerInfo))
421  {
422  // Put back of the process queue if we can't process it just yet
423  processQueue.push(&layerInfo);
424  continue; // Skip to next iteration
425  }
426 
427  // Now we do the processing
428  AssignSplitId(layerInfos, layerInfo);
429 
430  // Queue any child nodes for processing
431  ForEachLayerOutput(layerInfos, layerInfo, [&processQueue](LayerSelectionInfo& childInfo)
432  {
433  processQueue.push(&childInfo);
434  });
435 
436  // We don't need to process this node again
437  layerInfo.m_IsProcessed = true;
438  }
439  }
440 
441  // Collect all selected layers keyed by subgraph representative into a map
442  using SelectionInfoPtrs = std::vector<LayerSelectionInfo*>;
443  std::map<PartialSubgraph*, SelectionInfoPtrs> splitMap;
444  for (auto& info : layerInfos)
445  {
446  if (info.second.m_IsSelected)
447  {
448  auto it = splitMap.find(info.second.m_Subgraph->GetRepresentative());
449  if (it == splitMap.end())
450  {
451  splitMap.insert(
452  std::make_pair(info.second.m_Subgraph->GetRepresentative(), SelectionInfoPtrs{&info.second}));
453  }
454  else
455  {
456  it->second.push_back(&info.second);
457  }
458  }
459  }
460 
461  // Now each entry in splitMap represents a subgraph
462  Subgraphs result;
463  for (auto& splitGraph : splitMap)
464  {
467  SubgraphView::Layers layers;
468  for (auto&& infoPtr : splitGraph.second)
469  {
470  infoPtr->CollectNonSelectedInputs(layerInfos, inputs);
471  infoPtr->CollectNonSelectedOutputSlots(layerInfos, outputs);
472  layers.push_back(infoPtr->m_Layer);
473  }
474  // Create a new sub-graph with the new lists of input/output slots and layer
475  result.emplace_back(std::make_unique<SubgraphView>(std::move(inputs),
476  std::move(outputs),
477  std::move(layers)));
478  }
479 
480  return result;
481 }
void AssignSplitId(LayerSelectionInfo::LayerInfoContainer &layerInfos, LayerSelectionInfo &layerInfo)
std::vector< OutputSlot * > OutputSlots
bool IsReadyForSplitAssignment(LayerSelectionInfo::LayerInfoContainer &layerInfos, LayerSelectionInfo &layerInfo)
std::vector< SubgraphViewPtr > Subgraphs
std::vector< InputSlot * > InputSlots
std::list< Layer * > Layers
void ForEachLayerOutput(LayerSelectionInfo::LayerInfoContainer &layerInfos, LayerSelectionInfo &layerInfo, Delegate function)

The documentation for this class was generated from the following files: