ArmNN
 21.02
ArmComputeSubgraphUtils.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #pragma once
7 
9 
10 namespace armnn
11 {
12 
13 namespace
14 {
15 
16 //
17 // this helper only works if all layers where the inputs connect to are not selected
18 //
19 SubgraphView::InputSlots CreateInputsFrom(const std::vector<Layer*>& layers)
20 {
22  for (auto&& layer : layers)
23  {
24  for (auto&& it = layer->BeginInputSlots(); it != layer->EndInputSlots(); ++it)
25  {
26  result.push_back(&(*it));
27  }
28  }
29  return result;
30 }
31 
32 //
33 // this helper only works if all layers where the outputs connect to are not selected
34 //
35 SubgraphView::OutputSlots CreateOutputsFrom(const std::vector<Layer*>& layers)
36 {
38  for (auto&& layer : layers)
39  {
40  for (auto&& it = layer->BeginOutputSlots(); it != layer->EndOutputSlots(); ++it)
41  {
42  result.push_back(&(*it));
43  }
44  }
45  return result;
46 }
47 
48 bool checkDataTypeInputandOutput(const Layer& layer)
49 {
50  auto inputInfo = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
51  auto outputInfo = layer.GetOutputSlot(0).GetTensorInfo();
52  bool sameDataType = (inputInfo.GetDataType() == outputInfo.GetDataType());
53 
54  // Check is same quantization info (same scale and offset)
55  if (sameDataType)
56  {
57  if (IsQuantizedType(inputInfo.GetDataType()))
58  {
59  bool sameScale = (inputInfo.GetQuantizationScale() == outputInfo.GetQuantizationScale());
60  bool sameOffset = (inputInfo.GetQuantizationOffset() == outputInfo.GetQuantizationOffset());
61 
62  return (sameScale && sameOffset);
63  }
64  else
65  {
66  return true;
67  }
68  }
69  else
70  {
71  return false;
72  }
73 }
74 
75 } // namespace
76 
77 inline void ReportUntouchedLayers(OptimizationViews& optimizationViews, std::map<LayerGuid, Layer*> untouched)
78 {
79  std::vector<Layer*> untouchedVector;
80  for (const auto& pair : untouched)
81  {
82  Layer* layer = pair.second;
83  SubgraphView subgraphView(CreateInputsFrom({layer}),
84  CreateOutputsFrom({layer}),
85  {layer});
86  optimizationViews.AddUntouchedSubgraph(std::move(subgraphView));
87  }
88 }
89 
90 template<typename LayerType>
92  LayerType* baseLayer,
93  ActivationLayer* activationLayer,
94  ActivationDescriptor& activationDesc,
95  std::string name)
96 {
97  LayerType* replacementLayer = optimizationViews.GetGraph().AddLayer<LayerType>(name.c_str());
98 
99  replacementLayer->SetAdditionalInfoForObject(std::make_shared<ActivationDescriptor>(activationDesc));
100 
101  SubgraphView substitutionSubgraph(CreateInputsFrom({baseLayer}),
102  CreateOutputsFrom({activationLayer}),
103  {baseLayer, activationLayer});
104  SubgraphView replacementSubgraph(replacementLayer);
105 
106  optimizationViews.AddSubstitution({substitutionSubgraph, replacementSubgraph});
107  return replacementLayer;
108 }
109 
110 template<typename LayerType>
112  LayerType* baseLayer,
113  ActivationLayer* activationLayer,
114  ActivationDescriptor& activationDesc,
115  std::string name)
116 {
117  LayerType* replacementLayer = optimizationViews.GetGraph().AddLayer<LayerType>(baseLayer->GetParameters(),
118  name.c_str());
119 
120  replacementLayer->SetAdditionalInfoForObject(std::make_shared<ActivationDescriptor>(activationDesc));
121 
122  SubgraphView substitutionSubgraph(CreateInputsFrom({baseLayer}),
123  CreateOutputsFrom({activationLayer}),
124  {baseLayer, activationLayer});
125  SubgraphView replacementSubgraph(replacementLayer);
126 
127  optimizationViews.AddSubstitution({substitutionSubgraph, replacementSubgraph});
128  return replacementLayer;
129 }
130 
131 template<typename LayerType>
133  LayerType* baseLayer,
134  ActivationLayer* activationLayer,
135  ActivationDescriptor& activationDesc,
136  std::string name)
137 {
138  LayerType* replacementLayer = FuseLayerWithParameters(optimizationViews,
139  baseLayer,
140  activationLayer,
141  activationDesc,
142  name);
143 
144  replacementLayer->m_Weight = std::move(baseLayer->m_Weight);
145  replacementLayer->m_Bias = std::move(baseLayer->m_Bias);
146 
147  return replacementLayer;
148 }
149 
150 } // namespace armnn
constexpr bool IsQuantizedType()
Definition: TypesUtils.hpp:249
LayerT * AddLayer(Args &&... args)
Adds a new layer, of type LayerType, to the graph constructed with the arguments passed.
Definition: Graph.hpp:402
void ReportUntouchedLayers(OptimizationViews &optimizationViews, std::map< LayerGuid, Layer *> untouched)
std::vector< OutputSlot * > OutputSlots
void AddSubstitution(SubstitutionPair &&substitution)
This layer represents an activation operation with the specified activation function.
Copyright (c) 2021 ARM Limited and Contributors.
LayerType * FuseLayerWithParameters(OptimizationViews &optimizationViews, LayerType *baseLayer, ActivationLayer *activationLayer, ActivationDescriptor &activationDesc, std::string name)
The SubgraphView class represents a subgraph of a Graph.
LayerType * FuseLayerWithoutParameters(OptimizationViews &optimizationViews, LayerType *baseLayer, ActivationLayer *activationLayer, ActivationDescriptor &activationDesc, std::string name)
SubgraphView::InputSlots CreateInputsFrom(const std::vector< Layer *> &layers)
An ActivationDescriptor for the ActivationLayer.
Definition: Descriptors.hpp:25
void AddUntouchedSubgraph(SubgraphView &&subgraph)
std::vector< InputSlot * > InputSlots
SubgraphView::OutputSlots CreateOutputsFrom(const std::vector< Layer *> &layers)
LayerType * FuseLayerWithWeightsAndBiases(OptimizationViews &optimizationViews, LayerType *baseLayer, ActivationLayer *activationLayer, ActivationDescriptor &activationDesc, std::string name)
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below...
Definition: Types.hpp:419