diff options
Diffstat (limited to 'src/armnn/optimizations')
-rw-r--r-- | src/armnn/optimizations/FoldPadIntoLayer2d.hpp | 58 | ||||
-rw-r--r-- | src/armnn/optimizations/FuseBatchNorm.hpp | 68 | ||||
-rw-r--r-- | src/armnn/optimizations/RedirectMembersToConstantInputs.hpp | 1 |
3 files changed, 63 insertions, 64 deletions
diff --git a/src/armnn/optimizations/FoldPadIntoLayer2d.hpp b/src/armnn/optimizations/FoldPadIntoLayer2d.hpp index bbaabb815e..eb6bc90afd 100644 --- a/src/armnn/optimizations/FoldPadIntoLayer2d.hpp +++ b/src/armnn/optimizations/FoldPadIntoLayer2d.hpp @@ -146,8 +146,22 @@ Layer2dT* FoldPadIntoLayer2dImpl(Graph& graph, InputSlot& connection) const std::string name = std::string("folded-") + padLayer.GetName() + "-into-" + layer2d.GetName(); auto& newLayer2d = *graph.InsertNewLayer<Layer2dT>(padLayer.GetInputSlot(0), newLayer2dDescriptor, name.c_str()); - // Reconnect the pad layer with its original parent. newLayer2d.GetOutputSlot().MoveAllConnections(parentSlot); + // Start at 1 to connect only weights and bias + for (unsigned int i = 1; i < layer2d.GetNumInputSlots(); ++i) + { + if (layer2d.GetInputSlot(i).GetConnectedOutputSlot() != nullptr) + { + Layer& tgtLayer = layer2d.GetInputSlot(i).GetConnectedOutputSlot()->GetOwningLayer(); + // Ensure we are definitely connecting the necessary constant layers + if (tgtLayer.GetType() == armnn::LayerType::Constant) + { + // Remove old connection and connect to new layer2d + tgtLayer.GetOutputSlot(0).Disconnect(layer2d.GetInputSlot(i)); + tgtLayer.GetOutputSlot(0).Connect(newLayer2d.GetInputSlot(i)); + } + } + } // Moves connections in old layer2d layer output to new layer. // Old layer2d layer will be removed as it's left unconnected. @@ -168,14 +182,19 @@ public: { const auto conv2dLayer = PolymorphicDowncast<Convolution2dLayer*>(&connection.GetOwningLayer()); // Copy weights and bias to the new convolution layer - ARMNN_ASSERT_MSG(conv2dLayer->m_Weight != nullptr, - "FoldPadIntoConvolution2d: Weights data should not be null."); + ARMNN_ASSERT_MSG(newConv2dLayer->GetInputSlot(1).GetConnection() != nullptr, + "FoldPadIntoConvolution2d: New convolution layer is missing connection to weights layer"); + + // Deprecated 22.11 newConv2dLayer->m_Weight = std::move(conv2dLayer->m_Weight); if (conv2dLayer->GetParameters().m_BiasEnabled) { - ARMNN_ASSERT_MSG(conv2dLayer->m_Bias != nullptr, - "FoldPadIntoConvolution2d: Bias data should not be null if bias is enabled."); + ARMNN_ASSERT_MSG(newConv2dLayer->GetInputSlot(2).GetConnection() != nullptr, + "FoldPadIntoConvolution2d: New convolution layer is missing " + "connection to bias layer."); + + // Deprecated 22.11 newConv2dLayer->m_Bias = std::move(conv2dLayer->m_Bias); } } @@ -191,26 +210,25 @@ class FoldPadIntoDepthwiseConvolution2dImpl public: void Run(Graph& graph, InputSlot& connection) const { - const auto newLayer2d = FoldPadIntoLayer2dImpl<DepthwiseConvolution2dLayer>(graph, connection); + const auto newConv2dLayer = FoldPadIntoLayer2dImpl<DepthwiseConvolution2dLayer>(graph, connection); - if (newLayer2d != nullptr) + if (newConv2dLayer != nullptr) { - const auto layer2d = PolymorphicDowncast<DepthwiseConvolution2dLayer*>(&connection.GetOwningLayer()); + const auto conv2dLayer = PolymorphicDowncast<DepthwiseConvolution2dLayer*>(&connection.GetOwningLayer()); + // Copy weights and bias to the new convolution layer + ARMNN_ASSERT_MSG(newConv2dLayer->GetInputSlot(1).GetConnection() != nullptr, + "FoldPadIntoDepthwiseConvolution2d: New convolution layer is missing connection to weights layer"); - // Move weights and bias layer connections to the new convolution layer - ARMNN_ASSERT_MSG(layer2d->GetInputSlot(1).GetConnection() != nullptr, - "FoldPadIntoDepthwiseConvolution2d: Weights data should not be null."); - Layer& weightLayer = layer2d->GetInputSlot(1).GetConnectedOutputSlot()->GetOwningLayer(); - weightLayer.GetOutputSlot(0).Disconnect(layer2d->GetInputSlot(1)); - weightLayer.GetOutputSlot(0).Connect(newLayer2d->GetInputSlot(1)); + // Deprecated 22.11 + newConv2dLayer->m_Weight = std::move(conv2dLayer->m_Weight); - if (layer2d->GetParameters().m_BiasEnabled) + if (conv2dLayer->GetParameters().m_BiasEnabled) { - ARMNN_ASSERT_MSG(layer2d->GetInputSlot(2).GetConnection() != nullptr, - "FoldPadIntoDepthwiseConvolution2d: Bias data should not be null if bias is enabled."); - Layer& biasLayer = layer2d->GetInputSlot(2).GetConnectedOutputSlot()->GetOwningLayer(); - biasLayer.GetOutputSlot(0).Disconnect(layer2d->GetInputSlot(2)); - biasLayer.GetOutputSlot(0).Connect(newLayer2d->GetInputSlot(2)); + ARMNN_ASSERT_MSG(newConv2dLayer->GetInputSlot(2).GetConnection() != nullptr, + "FoldPadIntoConvolution2d: New convolution layer is missing " + "connection to bias layer."); + // Deprecated 22.11 + newConv2dLayer->m_Bias = std::move(conv2dLayer->m_Bias); } } } diff --git a/src/armnn/optimizations/FuseBatchNorm.hpp b/src/armnn/optimizations/FuseBatchNorm.hpp index 6a50fc4a0c..bca0c7d00a 100644 --- a/src/armnn/optimizations/FuseBatchNorm.hpp +++ b/src/armnn/optimizations/FuseBatchNorm.hpp @@ -14,8 +14,8 @@ namespace armnn namespace optimizations { -template <typename ConvLayer, armnn::DataType ArmnnType, - typename T = armnn::ResolveType<ArmnnType>> +template<typename ConvLayer, armnn::DataType ArmnnType, + typename T = armnn::ResolveType<ArmnnType>> class FuseBatchNorm { public: @@ -26,7 +26,7 @@ public: /// combined with the parameters of the child BatchNorm layer. void Run(Graph& graph, InputSlot& connection) const { - Layer& base = connection.GetConnectedOutputSlot()->GetOwningLayer(); + Layer& base = connection.GetConnectedOutputSlot()->GetOwningLayer(); Layer& child = connection.GetOwningLayer(); bool depthwise = (base.GetType() == LayerType::DepthwiseConvolution2d); @@ -37,7 +37,7 @@ public: if (base.GetDataType() == ArmnnType && child.GetDataType() == ArmnnType) { OutputSlot* parentOut = base.GetInputSlot(0).GetConnectedOutputSlot(); - auto convLayer = PolymorphicDowncast<ConvLayer*>(&base); + auto convLayer = PolymorphicDowncast<ConvLayer*>(&base); auto batchNormLayer = PolymorphicDowncast<BatchNormalizationLayer*>(&child); // Read convolution and batch norm parameters @@ -50,25 +50,16 @@ public: ConstTensor meanTensor(batchNormLayer->m_Mean->GetTensorInfo(), batchNormLayer->m_Mean->Map(true)); ConstTensor varTensor(batchNormLayer->m_Variance->GetTensorInfo(), batchNormLayer->m_Variance->Map(true)); - auto convDescriptor = convLayer->GetParameters(); + auto convDescriptor = convLayer->GetParameters(); ConstTensor weightsTensor; - if (convLayer->GetNumInputSlots() > 1) - { - ARMNN_ASSERT_MSG(convLayer->GetInputSlots()[1].GetConnection() != nullptr, - "FuseBatchNorm: Weight data should not be null."); - InputSlot & oldSlotWeights = const_cast<InputSlot&>(convLayer->GetInputSlots()[1]); - OutputSlot & constantSlotWeights = const_cast<OutputSlot&>(*oldSlotWeights.GetConnectedOutputSlot()); - ConstantLayer* weightLayer = PolymorphicDowncast<ConstantLayer*>( - &constantSlotWeights.GetOwningLayer()); - weightsTensor = ConstTensor(weightLayer->m_LayerOutput->GetTensorInfo(), - weightLayer->m_LayerOutput->Map(true)); - } - else - { - ARMNN_ASSERT_MSG(convLayer->m_Weight != nullptr, - "FuseBatchNorm: Bias data should not be null if bias is enabled."); - weightsTensor = ConstTensor(convLayer->m_Weight->GetTensorInfo(), convLayer->m_Weight->Map(true)); - } + ARMNN_ASSERT_MSG(convLayer->GetInputSlots()[1].GetConnection() != nullptr, + "FuseBatchNorm: Weight data should not be null."); + + ConstantLayer* weightLayer = PolymorphicDowncast<ConstantLayer*>( + &base.GetInputSlot(1).GetConnectedOutputSlot()->GetOwningLayer()); + + weightsTensor = ConstTensor(weightLayer->m_LayerOutput->GetTensorInfo(), + weightLayer->m_LayerOutput->Map(true)); armnnUtils::DataLayoutIndexed dataLayout(convDescriptor.m_DataLayout); auto weightsShape = weightsTensor.GetInfo().GetShape(); @@ -76,9 +67,9 @@ public: const unsigned int depthMultiplier = depthwise ? weightsShape[3] / inputChannels : 1; const unsigned int outputChannels = depthwise ? weightsShape[3] : weightsShape[0]; const unsigned int weightsHeight = depthwise ? weightsShape[1] : - weightsShape[dataLayout.GetHeightIndex()]; + weightsShape[dataLayout.GetHeightIndex()]; const unsigned int weightsWidth = depthwise ? weightsShape[2] : - weightsShape[dataLayout.GetWidthIndex()]; + weightsShape[dataLayout.GetWidthIndex()]; const auto* weightsBuffer = static_cast<const T*>(weightsTensor.GetMemoryArea()); const auto* betaBuffer = static_cast<const T*>(betaTensor.GetMemoryArea()); @@ -99,7 +90,7 @@ public: { for (unsigned int cOut = 0; cOut < outputChannels; ++cOut) { - T mult = gammaVector[cOut] / static_cast<T>(sqrtf (varianceVector[cOut] + epsilon)); + T mult = gammaVector[cOut] / static_cast<T>(sqrtf(varianceVector[cOut] + epsilon)); for (unsigned int h = 0; h < weightsHeight; ++h) { @@ -140,23 +131,14 @@ public: if (biasWasEnabledBeforeOpt) { ConstTensor biasTensor; - if (convLayer->GetNumInputSlots() > 1) - { - ARMNN_ASSERT_MSG(convLayer->GetInputSlots()[2].GetConnection() != nullptr, - "FuseBatchNorm: Bias data should not be null if bias is enabled."); - InputSlot & oldSlotBias = const_cast<InputSlot&>(convLayer->GetInputSlots()[2]); - OutputSlot & constantSlotBias = const_cast<OutputSlot&>(*oldSlotBias.GetConnectedOutputSlot()); - ConstantLayer* biasLayer = PolymorphicDowncast<ConstantLayer*>( - &constantSlotBias.GetOwningLayer()); - biasTensor = ConstTensor(biasLayer->m_LayerOutput->GetTensorInfo(), - biasLayer->m_LayerOutput->Map(true)); - } - else - { - ARMNN_ASSERT_MSG(convLayer->m_Bias != nullptr, - "FuseBatchNorm: Bias data should not be null if bias is enabled."); - biasTensor = ConstTensor(convLayer->m_Bias->GetTensorInfo(), convLayer->m_Bias->Map(true)); - } + ARMNN_ASSERT_MSG(convLayer->GetInputSlots()[2].GetConnection() != nullptr, + "FuseBatchNorm: Bias data should not be null if bias is enabled."); + + ConstantLayer* biasLayer = PolymorphicDowncast<ConstantLayer*>( + &base.GetInputSlot(2).GetConnectedOutputSlot()->GetOwningLayer()); + + biasTensor = ConstTensor(biasLayer->m_LayerOutput->GetTensorInfo(), + biasLayer->m_LayerOutput->Map(true)); const auto* biasBuffer = static_cast<const T*>(biasTensor.GetMemoryArea()); std::vector<T> biasVector(biasBuffer, biasBuffer + biasTensor.GetNumElements()); @@ -192,8 +174,6 @@ public: // This optimization will always have 3 input slots on the Conv2d base layer if (newConv2dLayer.GetNumInputSlots() > 1) { - ConstantLayer* weightLayer = PolymorphicDowncast<ConstantLayer*>( - &base.GetInputSlot(1).GetConnectedOutputSlot()->GetOwningLayer()); // Remove old connection and connect to new layer2d weightLayer->GetOutputSlot(0).Disconnect(base.GetInputSlot(1)); weightLayer->GetOutputSlot(0).Connect(newConv2dLayer.GetInputSlot(1)); diff --git a/src/armnn/optimizations/RedirectMembersToConstantInputs.hpp b/src/armnn/optimizations/RedirectMembersToConstantInputs.hpp index cb97a0fe32..483377452e 100644 --- a/src/armnn/optimizations/RedirectMembersToConstantInputs.hpp +++ b/src/armnn/optimizations/RedirectMembersToConstantInputs.hpp @@ -29,6 +29,7 @@ public: case LayerType::BatchNormalization: break; case LayerType::Convolution2d: + RedirectWeightsAndBiases<Convolution2dLayer>(&layer); break; case LayerType::DepthwiseConvolution2d: RedirectWeightsAndBiases<DepthwiseConvolution2dLayer>(&layer); |