24 bool checkDataTypeInputandOutput(
const Layer& layer)
26 auto inputInfo = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
27 auto outputInfo = layer.GetOutputSlot(0).GetTensorInfo();
28 bool sameDataType = (inputInfo.GetDataType() == outputInfo.GetDataType());
35 bool sameScale = (inputInfo.GetQuantizationScale() == outputInfo.GetQuantizationScale());
36 bool sameOffset = (inputInfo.GetQuantizationOffset() == outputInfo.GetQuantizationOffset());
38 return (sameScale && sameOffset);
53 template<
typename LayerType>
60 replacementLayer->SetAdditionalInfoForObject(
61 std::make_shared<ActivationDescriptor>(activationDesc));
63 SubgraphView substitutionSubgraph({baseLayer, activationLayer},
64 CreateIInputsFrom({baseLayer}),
65 CreateIOutputsFrom({activationLayer}));
68 optimizationViews.
AddSubstitution({substitutionSubgraph, replacementSubgraph});
70 return replacementLayer;
73 template<
typename LayerType>
81 LayerType* replacementLayer = PolymorphicDowncast<LayerType*>(replacement);
89 return replacementLayer;
92 template<
typename LayerType>
100 LayerType* replacementLayer = PolymorphicDowncast<LayerType*>(replacement);
108 return replacementLayer;
111 template<
typename LayerType>
119 LayerType* replacementLayer = PolymorphicDowncast<LayerType*>(replacement);
127 return replacementLayer;
130 template<
typename LayerType>
138 LayerType* replacementLayer = PolymorphicDowncast<LayerType*>(replacement);
146 return replacementLayer;
149 template<
typename LayerType>
157 optimizationViews.
GetINetwork()->AddBatchNormalizationLayer(baseLayer->GetParameters(),
163 LayerType* replacementLayer = PolymorphicDowncast<LayerType*>(replacement);
171 SubgraphView substitutionSubgraph({baseLayer, activationLayer},
172 CreateIInputsFrom({baseLayer}),
173 CreateIOutputsFrom({activationLayer}));
176 return replacementLayer;
179 template<
typename LayerType>
187 ->AddConvolution2dLayer(baseLayer->GetParameters(), name.c_str());
189 LayerType* replacementLayer = PolymorphicDowncast<LayerType*>(replacement);
191 replacementLayer->m_Weight = std::move(baseLayer->m_Weight);
192 replacementLayer->m_Bias = std::move(baseLayer->m_Bias);
200 return replacementLayer;
203 template<
typename LayerType>
211 optimizationViews.
GetINetwork()->AddDepthwiseConvolution2dLayer(baseLayer->GetParameters(), name.c_str());
213 LayerType* replacementLayer = PolymorphicDowncast<LayerType*>(replacement);
215 replacementLayer->m_Weight = std::move(baseLayer->m_Weight);
216 replacementLayer->m_Bias = std::move(baseLayer->m_Bias);
224 return replacementLayer;
227 template<
typename LayerType>
235 optimizationViews.
GetINetwork()->AddFullyConnectedLayer(baseLayer->GetParameters(),
237 LayerType* replacementLayer = PolymorphicDowncast<LayerType*>(replacement);
245 replacementLayer->m_Weight = std::move(baseLayer->m_Weight);
246 replacementLayer->m_Bias = std::move(baseLayer->m_Bias);
248 return replacementLayer;
255 template<
typename LayerType>
261 std::vector<IConnectableLayer*> layers;
264 std::vector<uint32_t> axes;
265 unsigned int recalulatedAxis = 0;
267 for (
unsigned int i = 0; i != desc.
m_vAxis.size(); ++i)
270 TensorInfo layerInfo = baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo();
272 axes.emplace_back(desc.
m_vAxis[i]);
280 std::vector<uint32_t> singleAxis(1, desc.
m_vAxis[i] - recalulatedAxis);
284 newReduceDescriptor.
m_vAxis.assign(singleAxis.begin(), singleAxis.end());
287 std::string layerName =
"reduce_layer_" + std::to_string(i);
289 Layer* replacementLayer = PolymorphicDowncast<Layer*>(
290 optimizationViews.
GetINetwork()->AddReduceLayer(newReduceDescriptor,
297 layers[i - 1]->GetOutputSlot(0).Connect(replacementLayer->
GetInputSlot(0));
308 layers.emplace_back(replacementLayer);
312 ARMNN_ASSERT(baseLayer->GetOutputSlot(0).GetTensorInfo() ==
313 PolymorphicDowncast<Layer*>(layers.back())->GetOutputSlot().GetTensorInfo());
321 template<
typename LayerType>
324 std::vector<IConnectableLayer*>& layers)
326 std::list<IConnectableLayer*> replacementLayers(layers.begin(), layers.end());
329 SubgraphView replacementSubgraph(std::move(replacementLayers),
330 CreateIInputsFrom({replacementLayers.front()}),
331 CreateIOutputsFrom({replacementLayers.back()}));
333 optimizationViews.
AddSubstitution({substitutionSubgraph, replacementSubgraph});
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
constexpr bool IsQuantizedType()
LayerType * FuseConvolution2dLayer(OptimizationViews &optimizationViews, LayerType *baseLayer, ActivationLayer *activationLayer, ActivationDescriptor &activationDesc, std::string name)
bool m_KeepDims
if true then output shape has no change.
void AddSubstitution(SubstitutionPair &&substitution)
This layer represents an activation operation with the specified activation function.
Copyright (c) 2021 ARM Limited and Contributors.
The SubgraphView class represents a subgraph of a Graph.
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
LayerType * FuseDivisionLayer(OptimizationViews &optimizationViews, LayerType *baseLayer, ActivationLayer *activationLayer, ActivationDescriptor &activationDesc, std::string name)
A ReduceDescriptor for the REDUCE operators.
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
INetworkPtr & GetINetwork()
#define ARMNN_ASSERT(COND)
LayerType * FuseLayer(OptimizationViews &optimizationViews, LayerType *baseLayer, LayerType *replacementLayer, ActivationLayer *activationLayer, ActivationDescriptor &activationDesc)
LayerType * FuseBatchNormalizationLayer(OptimizationViews &optimizationViews, LayerType *baseLayer, ActivationLayer *activationLayer, ActivationDescriptor &activationDesc, std::string name)
An ActivationDescriptor for the ActivationLayer.
std::vector< uint32_t > m_vAxis
The indices of the dimensions to reduce.
std::vector< IConnectableLayer * > ChainReduceLayers(OptimizationViews &optimizationViews, LayerType *baseLayer, ReduceDescriptor &desc)
LayerType * FuseSubtractionLayer(OptimizationViews &optimizationViews, LayerType *baseLayer, ActivationLayer *activationLayer, ActivationDescriptor &activationDesc, std::string name)
void SetTensorInfo(const TensorInfo &tensorInfo) override
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
LayerType * FuseAdditionLayer(OptimizationViews &optimizationViews, LayerType *baseLayer, ActivationLayer *activationLayer, ActivationDescriptor &activationDesc, std::string name)
LayerType * FuseDepthwiseConvolution2dLayer(OptimizationViews &optimizationViews, LayerType *baseLayer, ActivationLayer *activationLayer, ActivationDescriptor &activationDesc, std::string name)
void ReplaceLayers(OptimizationViews &optimizationViews, LayerType *baseLayer, std::vector< IConnectableLayer *> &layers)
const TensorInfo ComputeReductionTensorShape(const armnn::TensorInfo &input, const std::vector< uint32_t > &vAxis, const bool keepDims)
Function to compute the output tensor shape based on the axes and if keepDims is set.
LayerType * FuseMultiplicationLayer(OptimizationViews &optimizationViews, LayerType *baseLayer, ActivationLayer *activationLayer, ActivationDescriptor &activationDesc, std::string name)
LayerType * FuseFullyConnectedLayer(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...