From 03ee5d8a21688555c4e0a68d8400f4c3e3d844e2 Mon Sep 17 00:00:00 2001 From: Teresa Charlin Date: Tue, 28 Jun 2022 16:52:18 +0100 Subject: IVGCVSW-6962 Adding Const layer in the graph immediately after Input instead of immediately before output Signed-off-by: Teresa Charlin Change-Id: I2d89a1efdabfdb4be24a8998a03fe1f502d26183 --- src/armnn/Graph.hpp | 33 +++++++++++- src/armnn/test/optimizations/FoldPadTests.cpp | 61 ++++++++++------------ .../Fp32NetworkToBf16ConverterTests.cpp | 34 +++++++----- 3 files changed, 81 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/armnn/Graph.hpp b/src/armnn/Graph.hpp index 4623461302..482d9277e8 100644 --- a/src/armnn/Graph.hpp +++ b/src/armnn/Graph.hpp @@ -246,6 +246,15 @@ private: } return it; } + Iterator ForwardToEndOfInputsAndConstants(Iterator it) const + { + while ((it != m_Layers.end()) && + ((*it)->GetType() == LayerType::Input || (*it)->GetType() == LayerType::Constant)) + { + ++it; + } + return it; + } Iterator RewindToBeginOfOutputs(Iterator it) const { @@ -335,7 +344,7 @@ protected: Graph* m_Graph; }; -/// Input/Output layers specialize this template. +/// Input/Output/Constant layers specialize this template. template class Graph::LayerInGraph final : public LayerInGraphBase { @@ -352,12 +361,32 @@ public: LayerInGraph(Graph& graph, Iterator insertBefore, Args&&... args) : LayerInGraphBase(graph, // Make sure it's inserted after all inputs and before all outputs. - graph.ForwardToEndOfInputs(graph.RewindToBeginOfOutputs(insertBefore)), + graph.ForwardToEndOfInputsAndConstants(graph.RewindToBeginOfOutputs(insertBefore)), std::forward(args)...) { } }; +template <> +class Graph::LayerInGraph final : public LayerInGraphBase +{ +public: + template + LayerInGraph(Graph& graph, Args&&... args) + : LayerInGraphBase(graph, + // Always add to the back of the inputs. + std::next(graph.begin(), IteratorDifference(graph.GetNumInputs())), + std::forward(args)...) + {} + template + LayerInGraph(Graph& graph, Iterator, Args&&... args) + // Ignore Iterator argument. Always add to the back of the inputs. + : LayerInGraph(graph, std::forward(args)...) + {} + ~LayerInGraph() override + {} +}; + /// Inputs add/remove their binding id to m_InputIds in the graph. template <> class Graph::LayerInGraph final : public LayerInGraphBase diff --git a/src/armnn/test/optimizations/FoldPadTests.cpp b/src/armnn/test/optimizations/FoldPadTests.cpp index 14c211f9bf..4d7defcabe 100644 --- a/src/armnn/test/optimizations/FoldPadTests.cpp +++ b/src/armnn/test/optimizations/FoldPadTests.cpp @@ -25,6 +25,7 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer") TensorInfo inputInfo(4, inputShape, DataType::Float32); TensorInfo paddedInfo(4, paddedShape, DataType::Float32); + TensorInfo weightsInfo(4, weightsShape, DataType::Float32, 1.0f, 0, true); TensorInfo outputInfo(4, outputShape, DataType::Float32); Layer* input = graph.AddLayer(0, "input"); @@ -45,16 +46,13 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer") convolution2dDescriptor.m_DataLayout = DataLayout::NHWC; std::vector weightsVector(18); - ConstTensor weights(TensorInfo(4, weightsShape, DataType::Float32, 0.0f, 0, true), weightsVector); + ConstTensor weights(weightsInfo, weightsVector); ConstantLayer* weightsLayer = graph.AddLayer("Weights"); weightsLayer->m_LayerOutput = std::make_shared(weights); - - TensorInfo weightsInfo = weightsLayer->m_LayerOutput->GetTensorInfo(); weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsInfo); Convolution2dLayer* conv2dLayer = graph.AddLayer(convolution2dDescriptor, "conv2d"); - conv2dLayer->m_Weight = std::make_unique(weights); conv2dLayer->GetOutputSlot().SetTensorInfo(outputInfo); Layer* output = graph.AddLayer(0, "output"); @@ -75,12 +73,11 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer") (conv2dLayerParams.m_BiasEnabled == false) && (conv2dLayerParams.m_DataLayout == DataLayout::NHWC); }; - CHECK(CheckSequence(graph.cbegin(), graph.cend(), - &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType, - checkSimpleConv2d, - &IsLayerOfType)); + CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + checkSimpleConv2d, + &IsLayerOfType)); armnn::Optimizer::Pass(graph, armnn::MakeOptimizations(FoldPadIntoConvolution2d())); @@ -94,11 +91,10 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer") (conv2dLayerParams.m_BiasEnabled == false) && (conv2dLayerParams.m_DataLayout == DataLayout::NHWC); }; - CHECK(CheckSequence(graph.cbegin(), graph.cend(), - &IsLayerOfType, - checkPadFoldedIntoConv2d, - &IsLayerOfType, - &IsLayerOfType)); + CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType, + &IsLayerOfType, + checkPadFoldedIntoConv2d, + &IsLayerOfType)); } TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer") @@ -111,6 +107,7 @@ TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer") TensorInfo inputInfo(4, inputShape, DataType::Float32); TensorInfo paddedInfo(4, paddedShape, DataType::Float32); + TensorInfo weightsInfo(4, weightsShape, DataType::Float32, 1.0f, 0, true); TensorInfo outputInfo(4, outputShape, DataType::Float32); Layer* input = graph.AddLayer(0, "input"); @@ -131,15 +128,15 @@ TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer") depthwiseConvolution2dDescriptor.m_DataLayout = DataLayout::NHWC; std::vector weightsVector(18); - ConstTensor weights(TensorInfo(4, weightsShape, DataType::Float32, 0.0f, 0, true), weightsVector); + ConstTensor weights(weightsInfo, weightsVector); - auto* depthwiseConv2dLayer = graph.AddLayer(depthwiseConvolution2dDescriptor, - "depthwiseConv2d"); auto* weightsLayer = graph.AddLayer("weights"); + weightsLayer->GetOutputSlot().SetTensorInfo(weightsInfo); + weightsLayer->m_LayerOutput = std::make_shared(weights); - weightsLayer->GetOutputSlot().SetTensorInfo(weights.GetInfo()); + auto* depthwiseConv2dLayer = graph.AddLayer(depthwiseConvolution2dDescriptor, + "depthwiseConv2d"); depthwiseConv2dLayer->GetOutputSlot().SetTensorInfo(outputInfo); - depthwiseConv2dLayer->m_Weight = std::make_shared(weights); Layer* output = graph.AddLayer(0, "output"); @@ -160,12 +157,11 @@ TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer") (depthwiseConv2dLayerParams.m_DataLayout == DataLayout::NHWC); }; - CHECK(CheckSequence(graph.cbegin(), graph.cend(), - &IsLayerOfType, - &IsLayerOfType, - checkSimpleDepthwiseConv2d, - &IsLayerOfType, - &IsLayerOfType)); + CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + checkSimpleDepthwiseConv2d, + &IsLayerOfType)); armnn::Optimizer::Pass(graph, MakeOptimizations(FoldPadIntoDepthwiseConvolution2d())); @@ -181,11 +177,10 @@ TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer") (depthwiseConv2dLayerParams.m_DataLayout == DataLayout::NHWC); }; - CHECK(CheckSequence(graph.cbegin(), graph.cend(), - &IsLayerOfType, - checkPadFoldedIntoDepthwiseConv2d, - &IsLayerOfType, - &IsLayerOfType)); + CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType, + &IsLayerOfType, + checkPadFoldedIntoDepthwiseConv2d, + &IsLayerOfType)); } TEST_CASE("FoldPadLayerIntoPooling2dLayer") @@ -631,10 +626,10 @@ TEST_CASE("FoldPadLayerIntoConv2dLayer_ExecuteInferenceWithAndWithoutOptimizatio 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42}; - TensorInfo weightsInfo(4, weightsShape, DataType::Float32, 0.0f, 0, true); + TensorInfo weightsInfo(4, weightsShape, DataType::Float32, 1.0f, 0, true); ConstTensor weights(weightsInfo, weightsData); std::vector biasVector = {5, 6, 7, 8}; - TensorInfo biasInfo({4}, DataType::Float32, 0.0f, 0, true); + TensorInfo biasInfo({4}, DataType::Float32, 1.0f, 0, true); ConstTensor bias(biasInfo, biasVector); IConnectableLayer* conv2dLayer = network->AddConvolution2dLayer(convDescriptor, "Conv2D"); diff --git a/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp b/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp index d3a6932a48..66893ce1f5 100644 --- a/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp +++ b/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp @@ -92,18 +92,23 @@ TEST_CASE("Fp32NetworkToBf16OptimizationConv2DTest") conv->GetOutputSlot().Connect(output->GetInputSlot(0)); CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType, - &IsLayerOfType, &IsLayerOfType, - &IsLayerOfType, &IsLayerOfType)); + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType)); // Run the optimizer armnn::Optimizer::Pass(graph, armnn::MakeOptimizations(RedirectMembersToConstantInputs(), Fp32NetworkToBf16Converter())); + CHECK(7 == graph.GetNumLayers()); CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType, &IsLayerOfType, - &IsLayerOfType, &IsLayerOfType, - &IsLayerOfType)); + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType)); armnn::TensorInfo inputTensor = conv->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(); armnn::TensorInfo weightTensor = conv->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(); @@ -179,17 +184,23 @@ TEST_CASE("Fp32NetworkToBf16OptimizationFullyConnectedTest") fc->GetOutputSlot().Connect(output->GetInputSlot(0)); CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType, - &IsLayerOfType, &IsLayerOfType, - &IsLayerOfType, &IsLayerOfType)); + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType)); // Run the optimizer armnn::Optimizer::Pass(graph, armnn::MakeOptimizations(RedirectMembersToConstantInputs(), Fp32NetworkToBf16Converter())); + CHECK(7 == graph.GetNumLayers()); CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType, - &IsLayerOfType, &IsLayerOfType, - &IsLayerOfType, &IsLayerOfType, - &IsLayerOfType, &IsLayerOfType)); + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType)); armnn::TensorInfo inputTensor = fc->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(); armnn::TensorInfo weightTensor = fc->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(); @@ -215,5 +226,4 @@ TEST_CASE("Fp32NetworkToBf16OptimizationFullyConnectedTest") CHECK(data[7] == armnn::BFloat16(-9.131327E-10f)); // 0xB07B } - } \ No newline at end of file -- cgit v1.2.1