From b4dd5cc86d4eb841de670f0f102ede599e0d9c40 Mon Sep 17 00:00:00 2001 From: Keith Davis Date: Thu, 7 Apr 2022 11:32:00 +0100 Subject: IVGCVSW-6124 ConstTensorsAsInput: Conv2d - FrontEnd * Update Front-end and Tools. * Updated Serializer, Deserializer and unit tests to reflect this. * Updated TfLiteDelegate, TfLiteParser and OnnxParser. * Updated Ref. * Fixed resulting Neon / CL tests * Unified optimizers for conv2d ops * Optimizer Fix - Fp32ToBf16 * Partial implementation for ACL backends to fix VTS failures !android-nn-driver:7477 Signed-off-by: Keith Davis Change-Id: I5fb18877f7ee32643e15a9818945356274bb401b --- src/armnn/test/ConstTensorLayerVisitor.cpp | 48 ++++++++-- src/armnn/test/ConstTensorLayerVisitor.hpp | 20 +--- src/armnn/test/NetworkTests.cpp | 21 ++-- src/armnn/test/OptimizerTests.cpp | 62 +++++++++--- src/armnn/test/ShapeInferenceTests.cpp | 15 +-- src/armnn/test/SubgraphViewTests.cpp | 72 ++++++++++---- src/armnn/test/optimizations/FoldPadTests.cpp | 27 ++++-- .../test/optimizations/FuseActivationTests.cpp | 5 +- .../test/optimizations/FuseBatchNormTests.cpp | 106 ++++++++------------- 9 files changed, 221 insertions(+), 155 deletions(-) (limited to 'src/armnn/test') diff --git a/src/armnn/test/ConstTensorLayerVisitor.cpp b/src/armnn/test/ConstTensorLayerVisitor.cpp index af0581ce4c..701327b120 100644 --- a/src/armnn/test/ConstTensorLayerVisitor.cpp +++ b/src/armnn/test/ConstTensorLayerVisitor.cpp @@ -119,16 +119,22 @@ TEST_CASE("CheckConvolution2dLayer") descriptor.m_StrideX = 2; descriptor.m_StrideY = 3; descriptor.m_DataLayout = DataLayout::NHWC; + descriptor.m_BiasEnabled = false; std::vector data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}; std::vector dimensions = {1, 1, 3, 3}; ConstTensor weights(TensorInfo(4, dimensions.data(), DataType::Float32, 0.0f, 0, true), data); - TestConvolution2dLayerVisitor visitor(descriptor, weights, EmptyOptional()); + TestConstantLayerVisitor weightsVisitor(weights); + TestConvolution2dLayerVisitor visitor(descriptor); NetworkImpl net; - IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, weights, EmptyOptional()); + IConnectableLayer* const weightsLayer = net.AddConstantLayer(weights); + IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor); + weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1)); + + weightsLayer->ExecuteStrategy(weightsVisitor); layer->ExecuteStrategy(visitor); } @@ -148,11 +154,17 @@ TEST_CASE("CheckNamedConvolution2dLayer") std::vector dimensions = {1, 1, 3, 3}; ConstTensor weights(TensorInfo(4, dimensions.data(), DataType::Float32, 0.0f, 0, true), data); - TestConvolution2dLayerVisitor visitor(descriptor, weights, EmptyOptional(), layerName); + TestConstantLayerVisitor weightsVisitor(weights); + TestConvolution2dLayerVisitor visitor(descriptor, layerName); NetworkImpl net; - IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, weights, EmptyOptional(), layerName); + IConnectableLayer* const weightsLayer = net.AddConstantLayer(weights); + IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, layerName); + + weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1)); + + weightsLayer->ExecuteStrategy(weightsVisitor); layer->ExecuteStrategy(visitor); } @@ -175,13 +187,21 @@ TEST_CASE("CheckConvolution2dLayerWithBiases") std::vector biasData = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}; std::vector biasDimensions = {1, 1, 3, 3}; ConstTensor biases(TensorInfo(4, biasDimensions.data(), DataType::Float32, 0.0f, 0, true), biasData); - Optional optionalBiases(biases); - TestConvolution2dLayerVisitor visitor(descriptor, weights, optionalBiases); + TestConstantLayerVisitor weightsVisitor(weights); + TestConstantLayerVisitor biasVisitor(biases); + TestConvolution2dLayerVisitor visitor(descriptor); NetworkImpl net; + IConnectableLayer* const weightsLayer = net.AddConstantLayer(weights); + IConnectableLayer* const biasLayer = net.AddConstantLayer(biases); + IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor); - IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, weights, optionalBiases); + weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1)); + biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2)); + + biasLayer->ExecuteStrategy(biasVisitor); + weightsLayer->ExecuteStrategy(weightsVisitor); layer->ExecuteStrategy(visitor); } @@ -205,13 +225,21 @@ TEST_CASE("CheckNamedConvolution2dLayerWithBiases") std::vector biasData = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}; std::vector biasDimensions = {1, 1, 3, 3}; ConstTensor biases(TensorInfo(4, biasDimensions.data(), DataType::Float32, 0.0f, 0, true), biasData); - Optional optionalBiases(biases); - TestConvolution2dLayerVisitor visitor(descriptor, weights, optionalBiases, layerName); + TestConstantLayerVisitor weightsVisitor(weights); + TestConstantLayerVisitor biasVisitor(biases); + TestConvolution2dLayerVisitor visitor(descriptor, layerName); NetworkImpl net; + IConnectableLayer* const weightsLayer = net.AddConstantLayer(weights); + IConnectableLayer* const biasLayer = net.AddConstantLayer(biases); + IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, layerName); - IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, weights, optionalBiases, layerName); + weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1)); + biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2)); + + biasLayer->ExecuteStrategy(biasVisitor); + weightsLayer->ExecuteStrategy(weightsVisitor); layer->ExecuteStrategy(visitor); } diff --git a/src/armnn/test/ConstTensorLayerVisitor.hpp b/src/armnn/test/ConstTensorLayerVisitor.hpp index 00d17b4ae8..1f1b3f5262 100644 --- a/src/armnn/test/ConstTensorLayerVisitor.hpp +++ b/src/armnn/test/ConstTensorLayerVisitor.hpp @@ -21,22 +21,18 @@ class TestConvolution2dLayerVisitor : public TestLayerVisitor { public: explicit TestConvolution2dLayerVisitor(const Convolution2dDescriptor& convolution2dDescriptor, - const ConstTensor& weights, - const Optional& biases, const char* name = nullptr) : TestLayerVisitor(name) , m_Descriptor(convolution2dDescriptor) - , m_Weights(weights) - , m_Biases(biases) {} virtual ~TestConvolution2dLayerVisitor() {} void ExecuteStrategy(const armnn::IConnectableLayer* layer, - const armnn::BaseDescriptor& descriptor, - const std::vector& constants, - const char* name, - const armnn::LayerBindingId id = 0) override + const armnn::BaseDescriptor& descriptor, + const std::vector& constants, + const char* name, + const armnn::LayerBindingId id = 0) override { armnn::IgnoreUnused(descriptor, constants, id); switch (layer->GetType()) @@ -46,12 +42,6 @@ public: CheckLayerPointer(layer); CheckLayerName(name); CheckDescriptor(static_cast(descriptor)); - CheckConstTensors(m_Weights, constants[0]); - if (m_Biases.has_value()) - { - CHECK(constants.size() == 2); - CheckConstTensors(m_Biases.value(), constants[1]); - } break; } default: @@ -66,8 +56,6 @@ protected: private: Convolution2dDescriptor m_Descriptor; - ConstTensor m_Weights; - Optional m_Biases; }; class TestDepthwiseConvolution2dLayerVisitor : public TestLayerVisitor diff --git a/src/armnn/test/NetworkTests.cpp b/src/armnn/test/NetworkTests.cpp index c64c0a0d40..7756f40623 100644 --- a/src/armnn/test/NetworkTests.cpp +++ b/src/armnn/test/NetworkTests.cpp @@ -77,18 +77,18 @@ TEST_CASE("NetworkModification") armnn::ConstTensor weights(armnn::TensorInfo(4, dims, armnn::DataType::Float32, 0.0f, 0, true), convWeightsData); armnn::Convolution2dDescriptor convDesc2d; - armnn::IConnectableLayer* const convLayer = net.AddConvolution2dLayer(convDesc2d, - weights, - armnn::EmptyOptional(), - "conv layer"); + armnn::IConnectableLayer* const weightsLayer = net.AddConstantLayer(weights, "conv const weights"); + armnn::IConnectableLayer* const convLayer = net.AddConvolution2dLayer(convDesc2d, "conv layer"); CHECK(convLayer); + CHECK(weightsLayer); inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0)); + weightsLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(1)); armnn::FullyConnectedDescriptor fullyConnectedDesc; // Constant layer that now holds weights data for FullyConnected - armnn::IConnectableLayer* const constantWeightsLayer = net.AddConstantLayer(weights, "const weights"); + armnn::IConnectableLayer* const constantWeightsLayer = net.AddConstantLayer(weights, "fc const weights"); armnn::IConnectableLayer* const fullyConnectedLayer = net.AddFullyConnectedLayer(fullyConnectedDesc, "fully connected"); CHECK(constantWeightsLayer); @@ -155,12 +155,13 @@ TEST_CASE("NetworkModification") multiplicationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); //Tests that all layers are present in the graph. - CHECK(net.GetGraph().GetNumLayers() == 12); + CHECK(net.GetGraph().GetNumLayers() == 13); //Tests that the vertices exist and have correct names. CHECK(GraphHasNamedLayer(net.GetGraph(), "input layer")); CHECK(GraphHasNamedLayer(net.GetGraph(), "conv layer")); - CHECK(GraphHasNamedLayer(net.GetGraph(), "const weights")); + CHECK(GraphHasNamedLayer(net.GetGraph(), "conv const weights")); + CHECK(GraphHasNamedLayer(net.GetGraph(), "fc const weights")); CHECK(GraphHasNamedLayer(net.GetGraph(), "fully connected")); CHECK(GraphHasNamedLayer(net.GetGraph(), "pooling2d")); CHECK(GraphHasNamedLayer(net.GetGraph(), "activation")); @@ -239,8 +240,8 @@ TEST_CASE("NetworkModification") CHECK(AreAllLayerInputSlotsConnected(*outputLayer)); // Checks connectivity. - checkOneOutputToOneInputConnection(inputLayer, convLayer, 0); - checkOneOutputToTwoInputConnectionForTwoDifferentLayers(convLayer, constantWeightsLayer, fullyConnectedLayer, 1, 0); + checkOneOutputToTwoInputConnectionForTwoDifferentLayers(inputLayer, weightsLayer, convLayer, 0, 0); + checkOneOutputToTwoInputConnectionForTwoDifferentLayers(convLayer, constantWeightsLayer, fullyConnectedLayer, 2, 0); checkOneOutputToOneInputConnection(fullyConnectedLayer, poolingLayer, 2, 1); checkOneOutputToOneInputConnection(poolingLayer, activationLayer); checkOneOutputToOneInputConnection(activationLayer, normalizationLayer); @@ -619,10 +620,12 @@ TEST_CASE("ObtainConv2DDescriptorFromIConnectableLayer") convDesc2d.m_DilationY = 3; convDesc2d.m_BiasEnabled = false; convDesc2d.m_DataLayout = armnn::DataLayout::NCHW; + ARMNN_NO_DEPRECATE_WARN_BEGIN armnn::IConnectableLayer* const convLayer = net.AddConvolution2dLayer(convDesc2d, weights, armnn::EmptyOptional(), "conv layer"); + ARMNN_NO_DEPRECATE_WARN_END CHECK(convLayer); const armnn::BaseDescriptor& descriptor = convLayer->GetParameters(); diff --git a/src/armnn/test/OptimizerTests.cpp b/src/armnn/test/OptimizerTests.cpp index 6a13dc6456..3dd55279c6 100644 --- a/src/armnn/test/OptimizerTests.cpp +++ b/src/armnn/test/OptimizerTests.cpp @@ -441,6 +441,11 @@ void CreateConvolution2dGraph(Graph &graph, const unsigned int* inputShape, Layer* input = graph.AddLayer(0, "input"); input->GetOutputSlot().SetTensorInfo(inputInfo); + ConstantLayer* weightsLayer = nullptr; + weightsLayer = graph.AddLayer("Weights"); + weightsLayer->m_LayerOutput = std::make_shared(weights); + weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsLayer->m_LayerOutput->GetTensorInfo()); + Convolution2dLayer* layer = graph.AddLayer(desc, "conv2d"); layer->m_Weight = std::make_unique(weights); layer->GetOutputSlot().SetTensorInfo(outputInfo); @@ -448,6 +453,7 @@ void CreateConvolution2dGraph(Graph &graph, const unsigned int* inputShape, Layer* output = graph.AddLayer(0, "output"); input->GetOutputSlot().Connect(layer->GetInputSlot(0)); layer->GetOutputSlot().Connect(output->GetInputSlot(0)); + weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1)); } TEST_CASE("Conv2dValidateTensorShapesFromInputs") @@ -875,40 +881,70 @@ TEST_CASE("OptimizeForExclusiveConnectionsFuseTest") ConstTensor mean(TensorInfo(1, outputChannelSize, DataType::Float32, 0.0f, 0, true), meanVector); ConstTensor variance(TensorInfo(1, outputChannelSize, DataType::Float32, 0.0f, 0, true), varianceVector); + ConstantLayer* biasLayer = nullptr; + // Define the network Graph graph; auto input = graph.AddLayer(0, "input"); + auto weightsLayer = graph.AddLayer("Weights"); auto conv = graph.AddLayer(convolution2dDescriptor, "convolution"); auto batchNorm = graph.AddLayer(batchNormDescriptor, "batchNorm"); auto output = graph.AddLayer(0, "output"); // Set layer information input->GetOutputSlot().SetTensorInfo(inputInfo); + + weightsLayer->m_LayerOutput = std::make_shared(weights); + weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsLayer->m_LayerOutput->GetTensorInfo()); conv->GetOutputSlot().SetTensorInfo(outputInfo); + batchNorm->GetOutputSlot().SetTensorInfo(outputInfo); - conv->m_Weight = std::make_unique(weights); batchNorm->m_Beta = std::make_unique(beta); batchNorm->m_Gamma = std::make_unique(gamma); batchNorm->m_Mean = std::make_unique(mean); batchNorm->m_Variance = std::make_unique(variance); + if (convolution2dDescriptor.m_BiasEnabled) { std::vector biasVector = { 11 }; ConstTensor bias(TensorInfo(1, outputChannelSize, DataType::Float32, 0.0f, 0, true), biasVector); - conv->m_Bias = std::make_unique(bias); + biasLayer =graph.AddLayer("Bias"); + biasLayer->m_LayerOutput = std::make_shared(bias); + biasLayer->GetOutputSlot(0).SetTensorInfo(biasLayer->m_LayerOutput->GetTensorInfo()); + biasLayer->GetOutputSlot(0).Connect(conv->GetInputSlot(2)); + conv->m_Bias = biasLayer->m_LayerOutput; } // Connect layers input->GetOutputSlot(0).Connect(conv->GetInputSlot(0)); + weightsLayer->GetOutputSlot(0).Connect(conv->GetInputSlot(1)); conv->GetOutputSlot(0).Connect(batchNorm->GetInputSlot(0)); batchNorm->GetOutputSlot(0).Connect(output->GetInputSlot(0)); - CHECK(4 == graph.GetNumLayers()); - CHECK(CheckSequence(graph.cbegin(), graph.cend(), - &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType)); + // Temporary workaround to ensure the descriptor weights are populated + conv->m_Weight = weightsLayer->m_LayerOutput; + + if (convolution2dDescriptor.m_BiasEnabled) + { + CHECK(6 == graph.GetNumLayers()); + CHECK(CheckSequence(graph.cbegin(), graph.cend(), + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType)); + } + else + { + CHECK(5 == graph.GetNumLayers()); + CHECK(CheckSequence(graph.cbegin(), graph.cend(), + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType)); + } // Optimize graph armnn::Optimizer::Pass(graph, MakeOptimizations(FuseBatchNormIntoConvolution2DFloat32())); @@ -918,11 +954,13 @@ TEST_CASE("OptimizeForExclusiveConnectionsFuseTest") (layer->GetNameStr() == "fused-batchNorm-into-convolution"); }; - CHECK(3 == graph.GetNumLayers()); + CHECK(5 == graph.GetNumLayers()); CHECK(CheckSequence(graph.cbegin(), graph.cend(), - &IsLayerOfType, - checkFusedConv2d, - &IsLayerOfType)); + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + checkFusedConv2d, + &IsLayerOfType)); } // Tests that OptimizeForExclusiveConnections works, not fusing when not needed, using BatchNorm fusing as example diff --git a/src/armnn/test/ShapeInferenceTests.cpp b/src/armnn/test/ShapeInferenceTests.cpp index d45c9900c0..a3800ade09 100644 --- a/src/armnn/test/ShapeInferenceTests.cpp +++ b/src/armnn/test/ShapeInferenceTests.cpp @@ -275,8 +275,6 @@ TEST_CASE("Convolution2dTest") { const TensorShape inputShape{1, 1, 10, 10}; - Graph graph; - Convolution2dDescriptor descriptor; descriptor.m_PadLeft = 0; @@ -288,16 +286,9 @@ TEST_CASE("Convolution2dTest") descriptor.m_DilationX = 3; descriptor.m_DilationY = 3; - auto layer = BuildGraph(&graph, - {inputShape}, - descriptor, - "conv2d"); - - const float Datum = 0.0f; - ConstTensor weights({{1, 1, 3, 3}, DataType::Float32, 0.0f, 0, true}, &Datum); - layer->m_Weight = std::make_unique(weights); - - RunShapeInferenceTest(layer, {{ 1, 1, 4, 4 }}); + CreateGraphAndRunTest({ inputShape, { 1, 1, 3, 3 } }, + { { 1, 1, 4, 4 } }, descriptor, + "convd"); } TEST_CASE("DebugLayerTest") diff --git a/src/armnn/test/SubgraphViewTests.cpp b/src/armnn/test/SubgraphViewTests.cpp index 048c4f51fd..d7465c8361 100644 --- a/src/armnn/test/SubgraphViewTests.cpp +++ b/src/armnn/test/SubgraphViewTests.cpp @@ -42,28 +42,44 @@ bool AreAnySubgraphLayersPresentInGraph(const SubgraphView::IConnectableLayers & // // this helper only works if all layers where the inputs connect to are not selected // -SubgraphView::InputSlots CreateInputsFrom(const std::vector& layers) +SubgraphView::InputSlots CreateInputsFrom(const std::vector& layers, + std::vector ignoreSlots = {}) { SubgraphView::InputSlots result; for (auto&& layer : layers) { for (auto&& it = layer->BeginInputSlots(); it != layer->EndInputSlots(); ++it) { - result.push_back(&(*it)); + if (std::find(ignoreSlots.begin(), ignoreSlots.end(), it->GetSlotIndex()) != ignoreSlots.end()) + { + continue; + } + else + { + result.push_back(&(*it)); + } } } return result; } /// Duplication for IConnectableLayer -SubgraphView::IInputSlots CreateIInputsFrom(const std::vector& layers) +SubgraphView::IInputSlots CreateIInputsFrom(const std::vector& layers, + std::vector ignoreSlots = {}) { SubgraphView::IInputSlots result; - for (auto&& layer : layers) + for (auto&& layer: layers) { - for (unsigned int i = 0 ; i < layer->GetNumInputSlots(); ++i) + for (unsigned int i = 0; i < layer->GetNumInputSlots(); ++i) { - result.push_back(&(layer->GetInputSlot(i))); + if (std::find(ignoreSlots.begin(), ignoreSlots.end(), i) != ignoreSlots.end()) + { + continue; + } + else + { + result.push_back(&(layer->GetInputSlot(i))); + } } } return result; @@ -241,7 +257,7 @@ TEST_CASE("SubgraphViewSlots") // Construct sub-graph SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom({}, - CreateIInputsFrom({convLayer1}), + CreateIInputsFrom({convLayer1}, {1, 2}), CreateIOutputsFrom({convLayer2})); // Test that both old and new are initialized @@ -327,17 +343,20 @@ TEST_CASE("SingleInputSingleOutput") Convolution2dDescriptor convDescriptor; Layer* const convLayer1 = graph.AddLayer(convDescriptor, "conv1"); Layer* const convLayer2 = graph.AddLayer(convDescriptor, "conv2"); - + Layer* const weightsLayer1 = graph.AddLayer("weights1"); + Layer* const weightsLayer2 = graph.AddLayer("weights2"); Layer* const outputLayer = graph.AddLayer(0, "output"); inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0)); + weightsLayer1->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(1)); convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0)); + weightsLayer2->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(1)); convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom({}, - CreateIInputsFrom({convLayer1}), + CreateIInputsFrom({convLayer1}, {1}), CreateIOutputsFrom({convLayer2})); // Save sub-graph connections for comparison after substitution @@ -377,7 +396,7 @@ TEST_CASE("SingleInputSingleOutputAddPrecompiledLayerSubstituteSubgraph1") convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph - SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}), + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}, {1}), CreateOutputsFrom({convLayer2}), {}); @@ -421,7 +440,7 @@ TEST_CASE("SingleInputSingleOutputAddPrecompiledLayerSubstituteSubgraph2") convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph - SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}), + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}, {1}), CreateOutputsFrom({convLayer2}), {}); @@ -467,7 +486,7 @@ TEST_CASE("SingleInputSingleOutputSubstituteGraph") // Construct sub-graph SubgraphViewSelector::SubgraphViewPtr subgraph = - CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}), + CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}, {1}), CreateOutputsFrom({convLayer2}), {}); @@ -519,7 +538,7 @@ TEST_CASE("MultiInputSingleOutput") concatLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph - auto subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1, convLayer2}), + auto subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1, convLayer2}, {1}), CreateOutputsFrom({concatLayer}), {}); @@ -621,7 +640,7 @@ TEST_CASE("MultiInputMultiOutput") // Construct sub-graph SubgraphViewSelector::SubgraphViewPtr subgraph = - CreateSubgraphViewFrom(CreateInputsFrom({convLayer1, convLayer2}), + CreateSubgraphViewFrom(CreateInputsFrom({convLayer1, convLayer2}, {1}), CreateOutputsFrom({convLayer1, convLayer2}), {}); @@ -942,7 +961,8 @@ TEST_CASE("MultipleSimpleSubgraphs") // This test case represents the scenario when we have two distinct subgraphs // in a simple linear network. The selected nodes are the M* and the // non-selected ones are the X* - // + // W2 ->-> + // | // X1 -> M1 -> M2 -> X2 -> M3 -> X3 // // The expected results is two subgraphs, one with {M1, M2} and another one @@ -952,12 +972,17 @@ TEST_CASE("MultipleSimpleSubgraphs") // the graph is constructed in reverse order auto x3 = graph.AddLayer(0, "output"); + auto m3 = graph.InsertNewLayer(x3->GetInputSlot(0), ActivationDescriptor{}, "m3"); + auto x2 = graph.InsertNewLayer(m3->GetInputSlot(0), - Convolution2dDescriptor{}, - "x2"); + Convolution2dDescriptor{}, + "x2"); + + auto w2 = graph.InsertNewLayer(x2->GetInputSlot(1), "w2"); + auto m2 = graph.InsertNewLayer(x2->GetInputSlot(0), ActivationDescriptor{}, "m2"); @@ -966,6 +991,7 @@ TEST_CASE("MultipleSimpleSubgraphs") "m1"); graph.InsertNewLayer(m1->GetInputSlot(0), 0, "x1"); + IgnoreUnused(w2); // All selected 'M*' layers will be of Activation type SubgraphViewSelector::Subgraphs subgraphs = SubgraphViewSelector::SelectSubgraphs( @@ -1636,10 +1662,17 @@ TEST_CASE("SingleSubgraph") Layer* const convLayer2 = graph.AddLayer(convDescriptor, "conv2"); convLayer2->SetBackendId(Compute::GpuAcc); + Layer* const weights1 = graph.AddLayer("weights1"); + weights1->SetBackendId(Compute::GpuAcc); + Layer* const weights2 = graph.AddLayer("weights2"); + weights2->SetBackendId(Compute::GpuAcc); + Layer* const outputLayer = graph.AddLayer(0, "output"); inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0)); + weights1->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(1)); convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0)); + weights2->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(1)); convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // GpuAcc sub graph selector @@ -1702,6 +1735,9 @@ TEST_CASE("MultipleSubgraphs") Layer* const convLayer1 = graph.AddLayer(convDescriptor, "conv1"); Layer* const convLayer2 = graph.AddLayer(convDescriptor, "conv2"); + Layer* const weights1 = graph.AddLayer("weights1"); + Layer* const weights2 = graph.AddLayer("weights2"); + OriginsDescriptor concatDescriptor(2); Layer* const pConcatLayer = graph.AddLayer(concatDescriptor, "concat"); pConcatLayer->SetBackendId(Compute::CpuAcc); @@ -1711,7 +1747,9 @@ TEST_CASE("MultipleSubgraphs") inputLayer->GetOutputSlot(0).Connect(splitterLayer->GetInputSlot(0)); splitterLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0)); splitterLayer->GetOutputSlot(1).Connect(convLayer2->GetInputSlot(0)); + weights1->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(1)); convLayer1->GetOutputSlot(0).Connect(pConcatLayer->GetInputSlot(0)); + weights2->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(1)); convLayer2->GetOutputSlot(0).Connect(pConcatLayer->GetInputSlot(1)); pConcatLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); diff --git a/src/armnn/test/optimizations/FoldPadTests.cpp b/src/armnn/test/optimizations/FoldPadTests.cpp index 9919c6d0e6..027b10377d 100644 --- a/src/armnn/test/optimizations/FoldPadTests.cpp +++ b/src/armnn/test/optimizations/FoldPadTests.cpp @@ -47,6 +47,12 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer") std::vector weightsVector(18); ConstTensor weights(TensorInfo(4, weightsShape, DataType::Float32, 0.0f, 0, true), 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); @@ -56,6 +62,7 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer") // Connect up layers - input -> pad -> conv2d -> output input->GetOutputSlot().Connect(padLayer->GetInputSlot(0)); padLayer->GetOutputSlot().Connect(conv2dLayer->GetInputSlot(0)); + weightsLayer->GetOutputSlot().Connect(conv2dLayer->GetInputSlot(1)); conv2dLayer->GetOutputSlot().Connect(output->GetInputSlot(0)); auto checkSimpleConv2d = [](const Layer* const layer)->bool { @@ -69,10 +76,11 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer") }; CHECK(CheckSequence(graph.cbegin(), graph.cend(), - &IsLayerOfType, - &IsLayerOfType, - checkSimpleConv2d, - &IsLayerOfType)); + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + checkSimpleConv2d, + &IsLayerOfType)); armnn::Optimizer::Pass(graph, armnn::MakeOptimizations(FoldPadIntoConvolution2d())); @@ -87,9 +95,10 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer") }; CHECK(CheckSequence(graph.cbegin(), graph.cend(), - &IsLayerOfType, - checkPadFoldedIntoConv2d, - &IsLayerOfType)); + &IsLayerOfType, + checkPadFoldedIntoConv2d, + &IsLayerOfType, + &IsLayerOfType)); } TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer") @@ -628,12 +637,12 @@ TEST_CASE("FoldPadLayerIntoConv2dLayer_ExecuteInferenceWithAndWithoutOptimizatio TensorInfo biasInfo({4}, DataType::Float32, 0.0f, 0, true); ConstTensor bias(biasInfo, biasVector); Optional optionalBias = Optional(bias); - + ARMNN_NO_DEPRECATE_WARN_BEGIN IConnectableLayer* conv2dLayer = network->AddConvolution2dLayer(convDescriptor, weights, optionalBias, "Conv2D"); - + ARMNN_NO_DEPRECATE_WARN_END TensorInfo outputInfo(4, outputShape, DataType::Float32); conv2dLayer->GetOutputSlot(0).SetTensorInfo(outputInfo); diff --git a/src/armnn/test/optimizations/FuseActivationTests.cpp b/src/armnn/test/optimizations/FuseActivationTests.cpp index e5f54208f0..0cca86f93b 100644 --- a/src/armnn/test/optimizations/FuseActivationTests.cpp +++ b/src/armnn/test/optimizations/FuseActivationTests.cpp @@ -42,7 +42,7 @@ struct Convolution2dTest { using LayerType = Convolution2dLayer; static const bool isElementWise = false; - static const bool isConstTensorAsInputSupported = false; + static const bool isConstTensorAsInputSupported = true; static TensorShape GetInputShape() { return TensorShape( {1, 4, 4, 3}); } // NHWCin static TensorShape GetOutputShape() { return TensorShape( {1, 3, 3, 4}); } // NHWCout @@ -69,8 +69,9 @@ struct Convolution2dTest TensorInfo weightsInfo(GetWeightsShape(), ArmnnType, scale, offset, true); ConstTensor weights(weightsInfo, weightsVector); Optional optionalBias; - + ARMNN_NO_DEPRECATE_WARN_BEGIN return network->AddConvolution2dLayer(descriptor, weights, optionalBias, name); + ARMNN_NO_DEPRECATE_WARN_END } static std::vector AddConstantLayers(INetwork* network, diff --git a/src/armnn/test/optimizations/FuseBatchNormTests.cpp b/src/armnn/test/optimizations/FuseBatchNormTests.cpp index b28bb17773..4a94f7889b 100644 --- a/src/armnn/test/optimizations/FuseBatchNormTests.cpp +++ b/src/armnn/test/optimizations/FuseBatchNormTests.cpp @@ -24,7 +24,6 @@ class Conv2dTest public: using ConvDescriptorType = armnn::Convolution2dDescriptor; using ConvLayerType = armnn::Convolution2dLayer; - static const bool isConstTensorAsInputSupported = false; static IConnectableLayer *AddConvolution(INetwork *network, const Convolution2dDescriptor &descriptor, @@ -32,7 +31,9 @@ public: const Optional &biases, const char *name) { + ARMNN_NO_DEPRECATE_WARN_BEGIN return network->AddConvolution2dLayer(descriptor, weights, biases, name); + ARMNN_NO_DEPRECATE_WARN_END } static std::vector AddConstantLayers(INetwork *network, @@ -54,13 +55,12 @@ class DepthwiseConv2dTest public: using ConvDescriptorType = armnn::DepthwiseConvolution2dDescriptor; using ConvLayerType = armnn::DepthwiseConvolution2dLayer; - static const bool isConstTensorAsInputSupported = true; - static IConnectableLayer *AddConvolution(INetwork *network, - const DepthwiseConvolution2dDescriptor &descriptor, - const ConstTensor &weights, - const Optional &biases, - const char *name) + static IConnectableLayer* AddConvolution(INetwork* network, + const DepthwiseConvolution2dDescriptor& descriptor, + const ConstTensor& weights, + const Optional& biases, + const char* name) { IgnoreUnused(weights); IgnoreUnused(biases); @@ -183,19 +183,15 @@ INetworkPtr CreateNetwork(bool depthwise, bool preventFusing) output2Layer = network->AddOutputLayer(1); } - // If ConstTensorAsInputs is supported weights and bias are stored as constant layers. - if (Conv2dTest::isConstTensorAsInputSupported) - { - std::vector constantLayers = Conv2dTest::AddConstantLayers(network.get(), - convolution2dDescriptor, - weights, - Optional()); + std::vector constantLayers = Conv2dTest::AddConstantLayers(network.get(), + convolution2dDescriptor, + weights, + Optional()); - // Connect constant layers to receiverLayer. - for (unsigned int i = 0; i < constantLayers.size(); ++i) - { - constantLayers[i]->GetOutputSlot(0).Connect(convLayer->GetInputSlot(i + 1)); - } + // Connect constant layers to receiverLayer. + for (unsigned int i = 0; i < constantLayers.size(); ++i) + { + constantLayers[i]->GetOutputSlot(0).Connect(convLayer->GetInputSlot(i + 1)); } // Set layer information @@ -241,26 +237,14 @@ void FuseBatchNormIntoConvTest(bool depthwise, float tolerance, armnn::Compute b (layer->GetNameStr() == "fused-batchNorm-into-convolution"); }; - if (Conv2dTest::isConstTensorAsInputSupported) - { - CHECK(5 == graphFused.GetNumLayers()); - CHECK(CheckSequence(graphFused.cbegin(), - graphFused.cend(), - &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType, - checkFusedConv2d, - &IsLayerOfType)); - } - else - { - CHECK(3 == graphFused.GetNumLayers()); - CHECK(CheckSequence(graphFused.cbegin(), - graphFused.cend(), - &IsLayerOfType, - checkFusedConv2d, - &IsLayerOfType)); - } + CHECK(5 == graphFused.GetNumLayers()); + CHECK(CheckSequence(graphFused.cbegin(), + graphFused.cend(), + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + checkFusedConv2d, + &IsLayerOfType)); // Load network into runtime NetworkId networkIdentifier; @@ -278,10 +262,10 @@ void FuseBatchNormIntoConvTest(bool depthwise, float tolerance, armnn::Compute b TensorInfo inputTensorInfo = run->GetInputTensorInfo(networkIdentifier, 0); inputTensorInfo.SetConstant(true); - InputTensors inputTensorsFused { + InputTensors inputTensorsFused { {0, ConstTensor(inputTensorInfo, inputDataFused.data())}}; OutputTensors outputTensorsFused{ - {0, Tensor(run->GetOutputTensorInfo(networkIdentifier, 0), outputDataFused.data())}}; + {0, Tensor(run->GetOutputTensorInfo(networkIdentifier, 0), outputDataFused.data())}}; // Execute network run->EnqueueWorkload(networkIdentifier, inputTensorsFused, outputTensorsFused); @@ -294,33 +278,19 @@ void FuseBatchNormIntoConvTest(bool depthwise, float tolerance, armnn::Compute b IRuntimePtr runNotFused = IRuntime::Create(IRuntime::CreationOptions()); // default options // Optimise ArmNN network - IOptimizedNetworkPtr optNetNotFused = Optimize(*networkNotFused, {backendId}, runNotFused->GetDeviceSpec()); + IOptimizedNetworkPtr optNetNotFused = Optimize(*networkNotFused, { backendId }, runNotFused->GetDeviceSpec()); Graph& graphNotFused = GetGraphForTesting(optNetNotFused.get()); - if (Conv2dTest::isConstTensorAsInputSupported) - { - CHECK(6 == graphNotFused.GetNumLayers()); - CHECK(CheckSequence(graphNotFused.cbegin(), - graphNotFused.cend(), - &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType)); - } - else - { - CHECK(5 == graphNotFused.GetNumLayers()); - CHECK(CheckSequence(graphNotFused.cbegin(), - graphNotFused.cend(), - &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType, - &IsLayerOfType)); - } + CHECK(6 == graphNotFused.GetNumLayers()); + CHECK(CheckSequence(graphNotFused.cbegin(), + graphNotFused.cend(), + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType, + &IsLayerOfType)); // Load network into runtime NetworkId networkIdentifierNotFused; @@ -341,10 +311,10 @@ void FuseBatchNormIntoConvTest(bool depthwise, float tolerance, armnn::Compute b TensorInfo inputTensorInfo2 = runNotFused->GetInputTensorInfo(networkIdentifierNotFused, 0); inputTensorInfo2.SetConstant(true); InputTensors inputTensorsNotFused{ - {0, ConstTensor(inputTensorInfo2, inputDataNotFused.data())}}; + { 0, ConstTensor(inputTensorInfo2, inputDataNotFused.data()) } }; OutputTensors outputTensorsNotFused{ - {0, Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 0), outputDataNotFused.data())}, - {1, Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 1), outputData2NotFused.data())}}; + { 0, Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 0), outputDataNotFused.data()) }, + { 1, Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 1), outputData2NotFused.data()) } }; // Execute network runNotFused->EnqueueWorkload(networkIdentifierNotFused, inputTensorsNotFused, outputTensorsNotFused); -- cgit v1.2.1