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/armnnTestUtils/CommonTestUtils.cpp | 33 ++++++++- src/armnnTestUtils/CommonTestUtils.hpp | 5 +- src/armnnTestUtils/CreateWorkload.hpp | 124 +++++++++++++++++++++++---------- src/armnnTestUtils/MockBackend.cpp | 1 + 4 files changed, 122 insertions(+), 41 deletions(-) (limited to 'src/armnnTestUtils') diff --git a/src/armnnTestUtils/CommonTestUtils.cpp b/src/armnnTestUtils/CommonTestUtils.cpp index c85330577d..472716c97c 100644 --- a/src/armnnTestUtils/CommonTestUtils.cpp +++ b/src/armnnTestUtils/CommonTestUtils.cpp @@ -9,15 +9,42 @@ using namespace armnn; -SubgraphView::InputSlots CreateInputsFrom(const std::vector& layers) +SubgraphView::InputSlots CreateInputsFrom(Layer* layer, + std::vector ignoreSlots) { SubgraphView::InputSlots result; - for (auto&& layer : layers) + for (auto&& it = layer->BeginInputSlots(); it != layer->EndInputSlots(); ++it) { - for (auto&& it = layer->BeginInputSlots(); it != layer->EndInputSlots(); ++it) + if (std::find(ignoreSlots.begin(), ignoreSlots.end(), it->GetSlotIndex()) != ignoreSlots.end()) + { + continue; + } + else { result.push_back(&(*it)); } + } + return result; +} + +// ignoreSlots assumes you want to ignore the same slots all on layers within the vector +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) + { + if (std::find(ignoreSlots.begin(), ignoreSlots.end(), it->GetSlotIndex()) != ignoreSlots.end()) + { + continue; + } + else + { + result.push_back(&(*it)); + } + } } return result; } diff --git a/src/armnnTestUtils/CommonTestUtils.hpp b/src/armnnTestUtils/CommonTestUtils.hpp index b75a32be61..5b4b356247 100644 --- a/src/armnnTestUtils/CommonTestUtils.hpp +++ b/src/armnnTestUtils/CommonTestUtils.hpp @@ -79,8 +79,11 @@ void SetWeightAndBias(ConvolutionLayer* layer, const armnn::TensorInfo& weightIn layer->m_Weight->Allocate(); layer->m_Bias->Allocate(); } +armnn::SubgraphView::InputSlots CreateInputsFrom(armnn::Layer* layer, + std::vector ignoreSlots = {}); -armnn::SubgraphView::InputSlots CreateInputsFrom(const std::vector& layers); +armnn::SubgraphView::InputSlots CreateInputsFrom(const std::vector& layers, + std::vector ignoreSlots = {}); armnn::SubgraphView::OutputSlots CreateOutputsFrom(const std::vector& layers); diff --git a/src/armnnTestUtils/CreateWorkload.hpp b/src/armnnTestUtils/CreateWorkload.hpp index 2590ae89b2..7700a5573a 100644 --- a/src/armnnTestUtils/CreateWorkload.hpp +++ b/src/armnnTestUtils/CreateWorkload.hpp @@ -483,28 +483,37 @@ std::unique_ptr CreateConvolution2dWorkloadTest(armnn::IW layerDesc.m_PadBottom = 1; layerDesc.m_StrideX = 2; layerDesc.m_StrideY = 4; - layerDesc.m_BiasEnabled = true; + layerDesc.m_BiasEnabled = false; layerDesc.m_DataLayout = dataLayout; + float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0; + float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0; + Convolution2dLayer* const layer = graph.AddLayer(layerDesc, "layer"); TensorShape weightShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 5, 3} : TensorShape{2, 5, 3, 3}; TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3}; TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2}; + // As optimization isn't run member variables need to be updated. layer->m_Weight = std::make_unique(TensorInfo(weightShape, DataType)); - layer->m_Bias = std::make_unique(TensorInfo({2}, GetBiasDataType(DataType))); - layer->m_Weight->Allocate(); - layer->m_Bias->Allocate(); + + armnn::TensorInfo weightsTensorInfo(weightShape, DataType, inputsQScale); + weightsTensorInfo.SetConstant(); // Creates extra layers. Layer* const input = graph.AddLayer(0, "input"); + auto const weights = graph.AddLayer("weights"); Layer* const output = graph.AddLayer(0, "output"); + weights->m_LayerOutput = std::make_unique(weightsTensorInfo); + weights->m_LayerOutput->Allocate(); + // Connects up. - Connect(input, layer, TensorInfo(inputShape, DataType)); - Connect(layer, output, TensorInfo(outputShape, DataType)); + Connect(input, layer, TensorInfo(inputShape, DataType, inputsQScale)); + Connect(weights, layer, weightsTensorInfo, 0, 1); + Connect(layer, output, TensorInfo(outputShape, DataType, outputQScale)); CreateTensorHandles(graph, factory); // Makes the workload and checks it. @@ -517,14 +526,11 @@ std::unique_ptr CreateConvolution2dWorkloadTest(armnn::IW CHECK(queueDescriptor.m_Parameters.m_PadRight == 3); CHECK(queueDescriptor.m_Parameters.m_PadTop == 1); CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1); - CHECK(queueDescriptor.m_Parameters.m_BiasEnabled); + CHECK(!queueDescriptor.m_Parameters.m_BiasEnabled); CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout)); - CHECK(queueDescriptor.m_Inputs.size() == 1); + CHECK(queueDescriptor.m_Inputs.size() == 2); CHECK(queueDescriptor.m_Outputs.size() == 1); - CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo(weightShape, DataType))); - CHECK((queueDescriptor.m_Bias->GetTensorInfo() == - TensorInfo({2}, GetBiasDataType(DataType)))); // Returns so we can do extra, backend-specific tests. return workload; @@ -548,19 +554,26 @@ std::unique_ptr CreateConvolution2dFusedActivationWithBlo layerDesc.m_BiasEnabled = true; layerDesc.m_DataLayout = dataLayout; + float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0; + float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0; Convolution2dLayer* const layer = graph.AddLayer(layerDesc, "layer"); TensorShape weightShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 5, 3} : TensorShape{2, 5, 3, 3}; TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3}; TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2}; - + // As optimization isn't run member variables need to be updated. layer->m_Weight = std::make_unique(TensorInfo(weightShape, DataType)); layer->m_Bias = std::make_unique(TensorInfo({2}, GetBiasDataType(DataType))); layer->m_Weight->Allocate(); layer->m_Bias->Allocate(); + armnn::TensorInfo weightsTensorInfo(weightShape, DataType, inputsQScale); + weightsTensorInfo.SetConstant(); + armnn::TensorInfo biasTensorInfo({2}, DataType, inputsQScale); + biasTensorInfo.SetConstant(); + auto activationDesc = std::make_shared(); activationDesc->m_A = 10.0f; activationDesc->m_B = 5.0f; @@ -579,11 +592,20 @@ std::unique_ptr CreateConvolution2dFusedActivationWithBlo // Creates extra layers. Layer* const input = graph.AddLayer(0, "input"); + auto const weights = graph.AddLayer("weights"); + auto const bias = graph.AddLayer("bias"); Layer* const output = graph.AddLayer(0, "output"); + weights->m_LayerOutput = std::make_unique(weightsTensorInfo); + weights->m_LayerOutput->Allocate(); + bias->m_LayerOutput = std::make_unique(biasTensorInfo); + bias->m_LayerOutput->Allocate(); + // Connects up. - Connect(input, layer, TensorInfo(inputShape, DataType)); - Connect(layer, output, TensorInfo(outputShape, DataType)); + Connect(input, layer, TensorInfo(inputShape, DataType, inputsQScale)); + Connect(weights, layer, weightsTensorInfo, 0, 1); + Connect(bias, layer, biasTensorInfo, 0, 2); + Connect(layer, output, TensorInfo(outputShape, DataType, outputQScale)); CreateTensorHandles(graph, factory); // Makes the workload and checks it. @@ -606,11 +628,9 @@ std::unique_ptr CreateConvolution2dFusedActivationWithBlo CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1); CHECK(queueDescriptor.m_Parameters.m_BiasEnabled); CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout)); + CHECK(queueDescriptor.m_Outputs.size() == 1); - CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo(weightShape, DataType))); - CHECK((queueDescriptor.m_Bias->GetTensorInfo() == - TensorInfo({2}, GetBiasDataType(DataType)))); - CHECK(queueDescriptor.m_Inputs.size() == 1); + CHECK(queueDescriptor.m_Inputs.size() == 3); // Returns so we can do extra, backend-specific tests. return workload; @@ -630,28 +650,41 @@ std::unique_ptr CreateConvolution2dWorkloadFastMathTest(a layerDesc.m_PadBottom = 0; layerDesc.m_StrideX = 1; layerDesc.m_StrideY = 1; - layerDesc.m_BiasEnabled = false; + layerDesc.m_BiasEnabled = true; layerDesc.m_DataLayout = dataLayout; - Convolution2dLayer* const layer = graph.AddLayer(layerDesc, "layer"); + float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0; + float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0; - TensorShape weightShape = TensorShape{32, 32, 3, 3}; - TensorShape inputShape = TensorShape{1, 32, 149, 149}; - TensorShape outputShape = TensorShape{1, 32, 147, 147}; + Convolution2dLayer* const layer = graph.AddLayer(layerDesc, "layer"); + TensorShape weightShape = TensorShape{ 32, 32, 3, 3 }; + TensorShape biasShape = TensorShape{ 32 }; + TensorShape inputShape = TensorShape{ 1, 32, 149, 149 }; + TensorShape outputShape = TensorShape{ 1, 32, 147, 147 }; + // As optimization isn't run member variables need to be updated. layer->m_Weight = std::make_unique(TensorInfo(weightShape, DataType)); - layer->m_Bias = std::make_unique(TensorInfo({2}, GetBiasDataType(DataType))); + layer->m_Bias = std::make_unique(TensorInfo(biasShape, GetBiasDataType(DataType))); layer->m_Weight->Allocate(); layer->m_Bias->Allocate(); + armnn::TensorInfo weightsTensorInfo(weightShape, DataType, inputsQScale); + weightsTensorInfo.SetConstant(); + armnn::TensorInfo biasTensorInfo(biasShape, DataType, inputsQScale); + biasTensorInfo.SetConstant(); + // Creates extra layers. Layer* const input = graph.AddLayer(0, "input"); + auto const weights = graph.AddLayer("weights"); + auto const bias = graph.AddLayer("bias"); Layer* const output = graph.AddLayer(0, "output"); // Connects up. Connect(input, layer, TensorInfo(inputShape, DataType)); - Connect(layer, output, TensorInfo(outputShape, DataType)); + Connect(weights, layer, weightsTensorInfo, 0, 1); + Connect(bias, layer, biasTensorInfo, 0, 2); + Connect(layer, output, TensorInfo(outputShape, DataType, outputQScale)); CreateTensorHandles(graph, factory); // Makes the workload and checks it. @@ -666,9 +699,8 @@ std::unique_ptr CreateConvolution2dWorkloadFastMathTest(a CHECK(queueDescriptor.m_Parameters.m_PadBottom == 0); CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout)); - CHECK(queueDescriptor.m_Inputs.size() == 1); + CHECK(queueDescriptor.m_Inputs.size() == 3); CHECK(queueDescriptor.m_Outputs.size() == 1); - CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo(weightShape, DataType))); // Returns so we can do extra, backend-specific tests. return workload; @@ -1074,9 +1106,9 @@ std::unique_ptr CreateQLstmWorkloadTest(armnn::IWorkloadFactory& return workload; } -template +template std::unique_ptr CreateDirectConvolution2dWorkloadTest(armnn::IWorkloadFactory& factory, - armnn::Graph& graph) + armnn::Graph& graph) { // Creates the layer we're testing. Convolution2dDescriptor layerDesc; @@ -1093,18 +1125,34 @@ std::unique_ptr CreateDirectConvolution2dWorkloadTest(arm float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0; float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0; - layer->m_Weight = std::make_unique(TensorInfo({ 2, 3, 3, 3 }, DataType, inputsQScale)); - layer->m_Bias = std::make_unique - (TensorInfo({2}, GetBiasDataType(DataType), inputsQScale)); + TensorShape biasShape = TensorShape{ 2 }; + TensorShape weightShape = TensorShape{ 2, 3, 3, 3 }; + armnn::TensorInfo weightsTensorInfo(weightShape, DataType, inputsQScale); + weightsTensorInfo.SetConstant(); + armnn::TensorInfo biasTensorInfo(biasShape, GetBiasDataType(DataType), inputsQScale); + biasTensorInfo.SetConstant(); + + layer->m_Weight = std::make_unique(weightsTensorInfo); + layer->m_Bias = std::make_unique(biasTensorInfo); + layer->m_Weight->Allocate(); layer->m_Bias->Allocate(); // Creates extra layers. Layer* const input = graph.AddLayer(0, "input"); + auto const weights = graph.AddLayer("weights"); + auto const bias = graph.AddLayer("bias"); Layer* const output = graph.AddLayer(0, "output"); + weights->m_LayerOutput = std::make_unique(weightsTensorInfo); + weights->m_LayerOutput->Allocate(); + bias->m_LayerOutput = std::make_unique(biasTensorInfo); + bias->m_LayerOutput->Allocate(); + // Connects up. Connect(input, layer, TensorInfo({2, 3, 6, 6}, DataType, inputsQScale)); + Connect(weights, layer, weightsTensorInfo, 0, 1); + Connect(bias, layer, biasTensorInfo, 0, 2); Connect(layer, output, TensorInfo({2, 2, 6, 6}, DataType, outputQScale)); CreateTensorHandles(graph, factory); @@ -1120,12 +1168,10 @@ std::unique_ptr CreateDirectConvolution2dWorkloadTest(arm CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1); CHECK(queueDescriptor.m_Parameters.m_BiasEnabled == true); - CHECK(queueDescriptor.m_Inputs.size() == 1); + CHECK(queueDescriptor.m_Inputs.size() == 3); CHECK(queueDescriptor.m_Outputs.size() == 1); - CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo({2, 3, 3, 3}, - DataType, inputsQScale))); - CHECK((queueDescriptor.m_Bias->GetTensorInfo() - == TensorInfo({2}, GetBiasDataType(DataType), inputsQScale))); + CHECK((queueDescriptor.m_Weight->GetTensorInfo() == weightsTensorInfo)); + CHECK((queueDescriptor.m_Bias->GetTensorInfo() == biasTensorInfo)); // Returns so we can do extra, backend-specific tests. return workload; @@ -2094,18 +2140,22 @@ std::pair> Cre armnn::ConstTensor biases(biasTensorInfo, biasData); // Create convolution layer with biases + ARMNN_NO_DEPRECATE_WARN_BEGIN convLayer = net->AddConvolution2dLayer(convDesc2d, weights, Optional(biases), convLayerName.c_str()); + ARMNN_NO_DEPRECATE_WARN_END } else { // Create convolution layer without biases + ARMNN_NO_DEPRECATE_WARN_BEGIN convLayer = net->AddConvolution2dLayer(convDesc2d, weights, EmptyOptional(), convLayerName.c_str()); + ARMNN_NO_DEPRECATE_WARN_END } CHECK(convLayer); diff --git a/src/armnnTestUtils/MockBackend.cpp b/src/armnnTestUtils/MockBackend.cpp index ac7f7c7fef..5dfe9a3b8b 100644 --- a/src/armnnTestUtils/MockBackend.cpp +++ b/src/armnnTestUtils/MockBackend.cpp @@ -66,6 +66,7 @@ bool IsLayerSupported(const armnn::Layer* layer) { case armnn::LayerType::Input: case armnn::LayerType::Output: + case armnn::LayerType::Constant: case armnn::LayerType::Addition: case armnn::LayerType::Convolution2d: // Layer supported -- cgit v1.2.1