ArmNN
 21.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 255 of file SubgraphViewSelector.cpp.

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

256 {
257  SubgraphView subgraph(graph);
258  return SubgraphViewSelector::SelectSubgraphs(subgraph, selector);
259 }
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 385 of file SubgraphViewSelector.cpp.

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

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