ArmNN  NotReleased
SubgraphViewSelector Class Referencefinal

#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)
 
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 251 of file SubgraphViewSelector.cpp.

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

252 {
253  SubgraphView subgraph(graph);
254  return SubgraphViewSelector::SelectSubgraphs(subgraph, selector);
255 }
static Subgraphs SelectSubgraphs(Graph &graph, const LayerSelectorFunction &selector)

◆ SelectSubgraphs() [2/2]

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

Definition at line 381 of file SubgraphViewSelector.cpp.

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

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

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