From 5383767a7a759c867235ab66bd71f88281e3bd06 Mon Sep 17 00:00:00 2001 From: Cathal Corbett Date: Thu, 1 Sep 2022 11:34:37 +0100 Subject: Optimize the calling of IsLayerSupported(). * Done as part of 22.11/23.02 innovation days. * IsLayerSupported() is called in model prepare (delegate, android-nn-driver and shim/support_library) and again in ArmNN once model otimization is performed. * From calling IsLayerSupported() the first time, we should know that the layers are supported and what backend they are supported on. * Solution is to set the BackendId of the IConnectableLayer when IsLayerSupported() is called the first time, * In the Optimize() function we then check if the backend is set. If so, we do not call IsLayerSupported() again. * In the case a layer that is supported gets optimized, then the BackendId of that layer get set to "Unknown" for the new optimized layer and IsLayerSupported() will get called on the newly optimized layer. * Includes bug fix IVGCVSW-7213 for Android Mean FP16 CpuAcc tests. Also related to bug IVGCVSW-7211. Signed-off-by: Cathal Corbett Change-Id: I7a7820d0cdb079ffb5a3a2e0c44e252f652df53b --- InstallationViaAptRepository.md | 2 +- delegate/src/Activation.hpp | 1 + delegate/src/ArgMinMax.hpp | 3 + delegate/src/BatchMatMul.hpp | 5 +- delegate/src/BatchSpace.hpp | 6 + delegate/src/Comparison.hpp | 4 +- delegate/src/Control.hpp | 6 + delegate/src/Convolution.hpp | 12 ++ delegate/src/DelegateUtils.hpp | 15 +- delegate/src/ElementwiseBinary.hpp | 6 + delegate/src/ElementwiseUnary.hpp | 4 +- delegate/src/Fill.hpp | 3 + delegate/src/FullyConnected.hpp | 3 + delegate/src/Gather.hpp | 5 +- delegate/src/GatherNd.hpp | 3 + delegate/src/LogicalBinary.hpp | 3 + delegate/src/Lstm.hpp | 3 + delegate/src/MultiLayerFacade.hpp | 4 +- delegate/src/Normalization.hpp | 6 + delegate/src/Pack.hpp | 5 +- delegate/src/Pad.hpp | 3 + delegate/src/Pooling.hpp | 6 + delegate/src/Prelu.hpp | 1 + delegate/src/Quantization.hpp | 6 + delegate/src/Redefine.hpp | 6 + delegate/src/Reduce.hpp | 3 + delegate/src/Resize.hpp | 1 + delegate/src/Shape.hpp | 3 + delegate/src/SharedFunctions.cpp | 3 +- delegate/src/Slice.hpp | 6 +- delegate/src/Softmax.hpp | 2 + delegate/src/SpaceDepth.hpp | 6 + delegate/src/Split.hpp | 8 +- delegate/src/StridedSlice.hpp | 4 + delegate/src/Transpose.hpp | 4 +- delegate/src/UnidirectionalSequenceLstm.hpp | 3 + delegate/src/Unpack.hpp | 6 + include/armnn/INetwork.hpp | 14 +- include/armnn/Version.hpp | 2 +- python/pyarmnn/README.md | 6 +- .../examples/image_classification/README.md | 2 +- python/pyarmnn/examples/keyword_spotting/README.md | 2 +- python/pyarmnn/examples/object_detection/README.md | 2 +- .../pyarmnn/examples/speech_recognition/README.md | 2 +- python/pyarmnn/src/pyarmnn/_version.py | 4 +- python/pyarmnn/test/test_setup.py | 8 +- python/pyarmnn/test/test_version.py | 4 +- shim/sl/canonical/ConversionUtils.cpp | 18 ++- shim/sl/canonical/ConversionUtils.hpp | 16 +- shim/sl/canonical/Converter.cpp | 171 ++++++++++++++++++++- src/armnn/Layer.hpp | 4 +- src/armnn/Network.cpp | 61 ++++++-- 52 files changed, 428 insertions(+), 58 deletions(-) diff --git a/InstallationViaAptRepository.md b/InstallationViaAptRepository.md index 037e5cc7f1..fac714f2a6 100644 --- a/InstallationViaAptRepository.md +++ b/InstallationViaAptRepository.md @@ -117,7 +117,7 @@ The easiest way to install all of the available packages for your systems archit sudo apt-get install -y python3-pyarmnn armnn-latest-all # Verify installation via python: python3 -c "import pyarmnn as ann;print(ann.GetVersion())" - # Returns '{ARMNN_MAJOR_VERSION}.0.0' e.g. 31.0.0 + # Returns '{ARMNN_MAJOR_VERSION}.0.0' e.g. 32.0.0 ``` This will install PyArmNN and the three backends for Neon (CpuAcc), OpenCL (GpuAcc) and our Reference Backend. It will also install their dependencies including the arm-compute-library package along with the Tensorflow Lite Parser diff --git a/delegate/src/Activation.hpp b/delegate/src/Activation.hpp index 0071873d16..3560bfdae7 100644 --- a/delegate/src/Activation.hpp +++ b/delegate/src/Activation.hpp @@ -29,6 +29,7 @@ TfLiteStatus ValidateActivationOperator(DelegateData& delegateData, IsActivationSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputInfo, outputInfo, activationDesc); diff --git a/delegate/src/ArgMinMax.hpp b/delegate/src/ArgMinMax.hpp index 057dc8ba0a..dd28807f67 100644 --- a/delegate/src/ArgMinMax.hpp +++ b/delegate/src/ArgMinMax.hpp @@ -91,6 +91,7 @@ TfLiteStatus VisitArgMinMaxOperator(DelegateData& delegateData, } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("ARGMINMAX", @@ -98,6 +99,7 @@ TfLiteStatus VisitArgMinMaxOperator(DelegateData& delegateData, IsArgMinMaxSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outInfo, desc); @@ -111,6 +113,7 @@ TfLiteStatus VisitArgMinMaxOperator(DelegateData& delegateData, // Add an ArgMinMax layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddArgMinMaxLayer(desc); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); diff --git a/delegate/src/BatchMatMul.hpp b/delegate/src/BatchMatMul.hpp index 391301e4d7..3b884a092f 100644 --- a/delegate/src/BatchMatMul.hpp +++ b/delegate/src/BatchMatMul.hpp @@ -68,6 +68,7 @@ namespace armnnDelegate // Check if supported bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("BATCH_MATMUL", @@ -75,6 +76,7 @@ namespace armnnDelegate IsBatchMatMulSupported, delegateData.m_Backends, isSupported, + setBackend, armnnLHSInputTensorInfo, armnnRHSInputTensorInfo, outputTensorInfo, @@ -88,6 +90,7 @@ namespace armnnDelegate } armnn::IConnectableLayer* layer = delegateData.m_Network->AddBatchMatMulLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); @@ -96,4 +99,4 @@ namespace armnnDelegate return kTfLiteOk; } -} // namespace armnnDelegate \ No newline at end of file +} // namespace armnnDelegate diff --git a/delegate/src/BatchSpace.hpp b/delegate/src/BatchSpace.hpp index 847d6f15d2..903fe37eae 100644 --- a/delegate/src/BatchSpace.hpp +++ b/delegate/src/BatchSpace.hpp @@ -72,6 +72,7 @@ TfLiteStatus VisitBatchToSpaceNdOperator(DelegateData& delegateData, // Check if supported bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("BATCH_TO_SPACE_ND", @@ -79,6 +80,7 @@ TfLiteStatus VisitBatchToSpaceNdOperator(DelegateData& delegateData, IsBatchToSpaceNdSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo, descriptor); @@ -95,6 +97,7 @@ TfLiteStatus VisitBatchToSpaceNdOperator(DelegateData& delegateData, // Add a BatchToSpace layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddBatchToSpaceNdLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); @@ -163,6 +166,7 @@ TfLiteStatus VisitSpaceToBatchNdOperator(DelegateData& delegateData, // Check if supported bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("SPACE_TO_BATCH_ND", @@ -170,6 +174,7 @@ TfLiteStatus VisitSpaceToBatchNdOperator(DelegateData& delegateData, IsSpaceToBatchNdSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo, descriptor); @@ -186,6 +191,7 @@ TfLiteStatus VisitSpaceToBatchNdOperator(DelegateData& delegateData, // Add a SpaceToBatch layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddSpaceToBatchNdLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); diff --git a/delegate/src/Comparison.hpp b/delegate/src/Comparison.hpp index 8bf53c71ef..ee121e3c5c 100644 --- a/delegate/src/Comparison.hpp +++ b/delegate/src/Comparison.hpp @@ -88,7 +88,7 @@ TfLiteStatus VisitComparisonOperator(DelegateData& delegateData, armnn::ComparisonDescriptor descriptor(comparisonOperation); bool isSupported = false; - + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("COMPARISON", @@ -96,6 +96,7 @@ TfLiteStatus VisitComparisonOperator(DelegateData& delegateData, IsComparisonSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo0, inputTensorInfo1, outputTensorInfo, @@ -109,6 +110,7 @@ TfLiteStatus VisitComparisonOperator(DelegateData& delegateData, } armnn::IConnectableLayer* comparisonLayer = delegateData.m_Network->AddComparisonLayer(descriptor); + comparisonLayer->SetBackendId(setBackend); ARMNN_ASSERT(comparisonLayer != nullptr); armnn::IOutputSlot& outputSlot = comparisonLayer->GetOutputSlot(0); diff --git a/delegate/src/Control.hpp b/delegate/src/Control.hpp index f04245bcb6..02426a5616 100644 --- a/delegate/src/Control.hpp +++ b/delegate/src/Control.hpp @@ -119,6 +119,7 @@ TfLiteStatus VisitConcatenationOperator(DelegateData& delegateData, // Check if supported bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("CONCATENATION", @@ -126,6 +127,7 @@ TfLiteStatus VisitConcatenationOperator(DelegateData& delegateData, IsConcatSupported, delegateData.m_Backends, isSupported, + setBackend, inputConstTensorInfos, outputTensorInfo, concatDescriptor); @@ -139,6 +141,7 @@ TfLiteStatus VisitConcatenationOperator(DelegateData& delegateData, // Setup layer and connect. armnn::IConnectableLayer* concatenationLayer = delegateData.m_Network->AddConcatLayer(concatDescriptor); + concatenationLayer->SetBackendId(setBackend); ARMNN_ASSERT(concatenationLayer != nullptr); // Connect the Constant Inputs @@ -258,6 +261,7 @@ TfLiteStatus VisitMeanOperator(DelegateData& delegateData, // Check if supported bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("MEAN", @@ -265,6 +269,7 @@ TfLiteStatus VisitMeanOperator(DelegateData& delegateData, IsMeanSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo, desc); @@ -278,6 +283,7 @@ TfLiteStatus VisitMeanOperator(DelegateData& delegateData, // Setup layer and connect. armnn::IConnectableLayer* meanLayer = delegateData.m_Network->AddMeanLayer(desc); + meanLayer->SetBackendId(setBackend); ARMNN_ASSERT(meanLayer != nullptr); armnn::IOutputSlot& outputSlot = meanLayer->GetOutputSlot(0); diff --git a/delegate/src/Convolution.hpp b/delegate/src/Convolution.hpp index 93da4c8ce2..e307bb9be3 100644 --- a/delegate/src/Convolution.hpp +++ b/delegate/src/Convolution.hpp @@ -144,6 +144,7 @@ TfLiteStatus VisitConv2dOperator(DelegateData& delegateData, CalcPadding(inputWidth, filterWidth, descriptor.m_StrideX, descriptor.m_DilationX, descriptor.m_PadLeft, descriptor.m_PadRight, params->padding); + armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; @@ -152,6 +153,7 @@ TfLiteStatus VisitConv2dOperator(DelegateData& delegateData, IsConvolution2dSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo, descriptor, @@ -162,6 +164,7 @@ TfLiteStatus VisitConv2dOperator(DelegateData& delegateData, // Set up filter and biases armnn::IConnectableLayer* layer = delegateData.m_Network->AddConvolution2dLayer(descriptor); + layer->SetBackendId(setBackend); if(tflite::IsConstantTensor(&tfLiteContext->tensors[tfLiteNode->inputs->data[1]])) { @@ -300,6 +303,7 @@ TfLiteStatus VisitConv3dOperator(DelegateData& delegateData, // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitConvolutionOperator will be called again to add the layer to the network as seen below. + armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; @@ -308,6 +312,7 @@ TfLiteStatus VisitConv3dOperator(DelegateData& delegateData, IsConvolution3dSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo, descriptor, @@ -317,6 +322,7 @@ TfLiteStatus VisitConv3dOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddConvolution3dLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // Add a constant layer for weights and biases if inputs are constant, @@ -497,6 +503,7 @@ TfLiteStatus VisitDepthwiseConv2dOperator(DelegateData& delegateData, biasTensorInfo = armnn::TensorInfo(armnn::TensorShape({1}), GetDataType(tfLiteInputTensor)); } + armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; @@ -505,6 +512,7 @@ TfLiteStatus VisitDepthwiseConv2dOperator(DelegateData& delegateData, IsDepthwiseConvolutionSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo, descriptor, @@ -514,6 +522,7 @@ TfLiteStatus VisitDepthwiseConv2dOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddDepthwiseConvolution2dLayer(descriptor); + layer->SetBackendId(setBackend); if(tflite::IsConstantTensor(&tfLiteFilterTensor)) { @@ -699,6 +708,7 @@ TfLiteStatus VisitTransposeConv2dOperator(DelegateData& delegateData, auto filterTensor = CreateConstTensor(&tfLiteFilterTensor, filterTensorInfo, armnn::Optional()); + armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; @@ -707,6 +717,7 @@ TfLiteStatus VisitTransposeConv2dOperator(DelegateData& delegateData, IsTransposeConvolution2dSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo, descriptor, @@ -718,6 +729,7 @@ TfLiteStatus VisitTransposeConv2dOperator(DelegateData& delegateData, armnn::IConnectableLayer* layer = delegateData.m_Network->AddTransposeConvolution2dLayer(descriptor, filterTensor, armnn::EmptyOptional()); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); diff --git a/delegate/src/DelegateUtils.hpp b/delegate/src/DelegateUtils.hpp index 58d8048be3..850b279fea 100644 --- a/delegate/src/DelegateUtils.hpp +++ b/delegate/src/DelegateUtils.hpp @@ -25,7 +25,7 @@ namespace { // Macro to call an IsSupported function and log caller name together with reason for lack of support -#define FORWARD_LAYER_SUPPORT_FUNC(opName, tfLiteContext, func, backends, supported, ...) \ +#define FORWARD_LAYER_SUPPORT_FUNC(opName, tfLiteContext, func, backends, supported, setBackend, ...) \ try \ { \ for (auto&& backendId : backends) \ @@ -38,6 +38,7 @@ try \ layerSupportObject.func(__VA_ARGS__, armnn::Optional(reasonIfUnsupported)); \ if (supported) \ { \ + setBackend = backendId; \ break; \ } \ else \ @@ -224,11 +225,13 @@ armnn::IConnectableLayer* BroadcastTensor(const armnn::TensorInfo& inputInfo0, armnn::ReshapeDescriptor reshapeDescriptor; reshapeDescriptor.m_TargetShape = reshapedInfo.GetShape(); bool isSupported = false; + armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC("RESHAPE", tfLiteContext, IsReshapeSupported, delegateData.m_Backends, isSupported, + setBackend, smallInfo, reshapedInfo, reshapeDescriptor); @@ -240,6 +243,7 @@ armnn::IConnectableLayer* BroadcastTensor(const armnn::TensorInfo& inputInfo0, ARMNN_ASSERT(delegateData.m_Network != nullptr); // Add Reshape layer armnn::IConnectableLayer* reshapeLayer = delegateData.m_Network->AddReshapeLayer(reshapeDescriptor); + reshapeLayer->SetBackendId(setBackend); ARMNN_ASSERT(reshapeLayer != nullptr); reshapeLayer->GetOutputSlot(0).SetTensorInfo(reshapedInfo); @@ -331,11 +335,13 @@ TfLiteStatus FusedActivation(TfLiteContext* tfLiteContext, } bool isSupported = false; + armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC("ACTIVATION", tfLiteContext, IsActivationSupported, data.m_Backends, isSupported, + setBackend, prevLayer->GetOutputSlot(0).GetTensorInfo(), activationOutputInfo, activationDesc); @@ -344,6 +350,7 @@ TfLiteStatus FusedActivation(TfLiteContext* tfLiteContext, return kTfLiteError; } armnn::IConnectableLayer* activationLayer = data.m_Network->AddActivationLayer(activationDesc); + activationLayer->SetBackendId(setBackend); ARMNN_ASSERT(activationLayer != nullptr); activationLayer->GetOutputSlot(0).SetTensorInfo(activationOutputInfo); @@ -566,11 +573,13 @@ TfLiteStatus ConnectConstant(armnn::IConnectableLayer* layer, { IgnoreUnused(layer); bool isSupported = false; + armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC("CONSTANT", tfLiteContext, IsConstantSupported, data.m_Backends, isSupported, + setBackend, constTensorInfo); if (!isSupported) { @@ -581,6 +590,7 @@ TfLiteStatus ConnectConstant(armnn::IConnectableLayer* layer, constTensorInfo, armnn::Optional()); armnn::IConnectableLayer* constantLayer = data.m_Network->AddConstantLayer(constantInput); + constantLayer->SetBackendId(setBackend); armnn::IOutputSlot& outputSlot = constantLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(constTensorInfo); @@ -615,11 +625,13 @@ TfLiteStatus ProcessInputs(armnn::IConnectableLayer* layer, { armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); bool isSupported = false; + armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC("CONSTANT", tfLiteContext, IsConstantSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo); if (!isSupported) { @@ -629,6 +641,7 @@ TfLiteStatus ProcessInputs(armnn::IConnectableLayer* layer, inputTensorInfo, armnn::Optional()); armnn::IConnectableLayer* constantLayer = delegateData.m_Network->AddConstantLayer(constantInput); + constantLayer->SetBackendId(setBackend); armnn::IOutputSlot& outputSlot = constantLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(inputTensorInfo); diff --git a/delegate/src/ElementwiseBinary.hpp b/delegate/src/ElementwiseBinary.hpp index 6e81db4b4f..caf02624be 100644 --- a/delegate/src/ElementwiseBinary.hpp +++ b/delegate/src/ElementwiseBinary.hpp @@ -32,6 +32,7 @@ TfLiteStatus ValidateAddOperator(DelegateData& delegateData, IsAdditionSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo); @@ -56,6 +57,7 @@ TfLiteStatus ValidateDivOperator(DelegateData& delegateData, IsDivisionSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo); @@ -108,6 +110,7 @@ TfLiteStatus ValidateMaximumOperator(DelegateData& delegateData, IsMaximumSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo); @@ -131,6 +134,7 @@ TfLiteStatus ValidateMinimumOperator(DelegateData& delegateData, IsMinimumSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo); @@ -154,6 +158,7 @@ TfLiteStatus ValidateMulOperator(DelegateData& delegateData, IsMultiplicationSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo); @@ -177,6 +182,7 @@ TfLiteStatus ValidateSubOperator(DelegateData& delegateData, IsSubtractionSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo); diff --git a/delegate/src/ElementwiseUnary.hpp b/delegate/src/ElementwiseUnary.hpp index 79d7f82249..947e531162 100644 --- a/delegate/src/ElementwiseUnary.hpp +++ b/delegate/src/ElementwiseUnary.hpp @@ -51,7 +51,7 @@ TfLiteStatus VisitElementwiseUnaryOperator(DelegateData& delegateData, armnn::ElementwiseUnaryDescriptor descriptor(unaryOperation); bool isSupported = false; - + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("ELEMENTWISE_UNARY", @@ -59,6 +59,7 @@ TfLiteStatus VisitElementwiseUnaryOperator(DelegateData& delegateData, IsElementwiseUnarySupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo, descriptor); @@ -71,6 +72,7 @@ TfLiteStatus VisitElementwiseUnaryOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddElementwiseUnaryLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); diff --git a/delegate/src/Fill.hpp b/delegate/src/Fill.hpp index dc30e53ba9..e79133e15c 100644 --- a/delegate/src/Fill.hpp +++ b/delegate/src/Fill.hpp @@ -72,6 +72,7 @@ TfLiteStatus VisitFillOperator(DelegateData& delegateData, } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("FILL", @@ -79,6 +80,7 @@ TfLiteStatus VisitFillOperator(DelegateData& delegateData, IsFillSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outInfo, descriptor); @@ -91,6 +93,7 @@ TfLiteStatus VisitFillOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddFillLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); diff --git a/delegate/src/FullyConnected.hpp b/delegate/src/FullyConnected.hpp index 6677ab900e..a2960e299b 100644 --- a/delegate/src/FullyConnected.hpp +++ b/delegate/src/FullyConnected.hpp @@ -110,6 +110,7 @@ TfLiteStatus VisitFullyConnectedOperator(DelegateData& delegateData, descriptor.m_ConstantWeights = isConstantWeights; bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("FULLY_CONNECTED", @@ -117,6 +118,7 @@ TfLiteStatus VisitFullyConnectedOperator(DelegateData& delegateData, IsFullyConnectedSupported, delegateData.m_Backends, isSupported, + setBackend, reshapedTensorInfo, outputTensorInfo, weightsTensorInfo, @@ -131,6 +133,7 @@ TfLiteStatus VisitFullyConnectedOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddFullyConnectedLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // Add a constant layer for weights and biases if inputs are constant. diff --git a/delegate/src/Gather.hpp b/delegate/src/Gather.hpp index 616de7e09e..9e98966471 100644 --- a/delegate/src/Gather.hpp +++ b/delegate/src/Gather.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2020,2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -69,6 +69,7 @@ TfLiteStatus VisitGatherOperator(DelegateData& delegateData, return kTfLiteError; } + armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported @@ -78,6 +79,7 @@ TfLiteStatus VisitGatherOperator(DelegateData& delegateData, IsGatherSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, indicesTensorInfo, outputTensorInfo, @@ -86,6 +88,7 @@ TfLiteStatus VisitGatherOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddGatherLayer(gatherDescriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); diff --git a/delegate/src/GatherNd.hpp b/delegate/src/GatherNd.hpp index 1e12c5cf68..f2192f77c3 100644 --- a/delegate/src/GatherNd.hpp +++ b/delegate/src/GatherNd.hpp @@ -46,6 +46,7 @@ TfLiteStatus VisitGatherNdOperator(DelegateData& delegateData, const armnn::TensorInfo& indicesTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteIndicesTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); + armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported @@ -55,6 +56,7 @@ TfLiteStatus VisitGatherNdOperator(DelegateData& delegateData, IsGatherNdSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, indicesTensorInfo, outputTensorInfo); @@ -62,6 +64,7 @@ TfLiteStatus VisitGatherNdOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddGatherNdLayer(); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); diff --git a/delegate/src/LogicalBinary.hpp b/delegate/src/LogicalBinary.hpp index 562b5d3438..b6a8f5d5f6 100644 --- a/delegate/src/LogicalBinary.hpp +++ b/delegate/src/LogicalBinary.hpp @@ -52,6 +52,7 @@ TfLiteStatus VisitLogicalBinaryOperator(DelegateData& delegateData, // Check if supported bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("LOGICAL_BINARY", @@ -59,6 +60,7 @@ TfLiteStatus VisitLogicalBinaryOperator(DelegateData& delegateData, IsLogicalBinarySupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo0, inputTensorInfo1, outputTensorInfo, @@ -72,6 +74,7 @@ TfLiteStatus VisitLogicalBinaryOperator(DelegateData& delegateData, } armnn::IConnectableLayer* logicalBinaryLayer = delegateData.m_Network->AddLogicalBinaryLayer(desc); + logicalBinaryLayer->SetBackendId(setBackend); ARMNN_ASSERT(logicalBinaryLayer != nullptr); armnn::IOutputSlot& outputSlot = logicalBinaryLayer->GetOutputSlot(0); diff --git a/delegate/src/Lstm.hpp b/delegate/src/Lstm.hpp index 253cd2162d..8c1f877ec9 100644 --- a/delegate/src/Lstm.hpp +++ b/delegate/src/Lstm.hpp @@ -216,6 +216,7 @@ TfLiteStatus VisitLstmOperator(DelegateData& delegateData, } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("LSTM", @@ -223,6 +224,7 @@ TfLiteStatus VisitLstmOperator(DelegateData& delegateData, IsLstmSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputStateInInfo, cellStateInInfo, @@ -241,6 +243,7 @@ TfLiteStatus VisitLstmOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddLstmLayer(desc, params); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(scratchBufferTensorInfo); diff --git a/delegate/src/MultiLayerFacade.hpp b/delegate/src/MultiLayerFacade.hpp index 2fdfc7082a..aa00be8f60 100644 --- a/delegate/src/MultiLayerFacade.hpp +++ b/delegate/src/MultiLayerFacade.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2021 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2021,2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -117,6 +117,8 @@ public: virtual const armnn::BaseDescriptor& GetParameters() const override { return m_NullDescriptor; } + void SetBackendId(const armnn::BackendId& id) override {} + protected: /// Retrieve the handles to the constant values stored by the layer. /// @return A vector of the constant tensors stored by this layer. diff --git a/delegate/src/Normalization.hpp b/delegate/src/Normalization.hpp index 0933552973..d0db43ea7c 100644 --- a/delegate/src/Normalization.hpp +++ b/delegate/src/Normalization.hpp @@ -42,6 +42,7 @@ TfLiteStatus VisitL2NormalizationOperator(DelegateData& delegateData, descriptor.m_DataLayout = armnn::DataLayout::NHWC; bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("L2_NORMALIZATION", @@ -49,6 +50,7 @@ TfLiteStatus VisitL2NormalizationOperator(DelegateData& delegateData, IsL2NormalizationSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outInfo, descriptor); @@ -62,6 +64,7 @@ TfLiteStatus VisitL2NormalizationOperator(DelegateData& delegateData, // Add a L2Normalization layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddL2NormalizationLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); @@ -112,6 +115,7 @@ TfLiteStatus VisitLocalResponseNormalizationOperator(DelegateData& delegateData, descriptor.m_NormSize = 1 + (2 * descriptor.m_NormSize); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("NORMALIZATION", @@ -119,6 +123,7 @@ TfLiteStatus VisitLocalResponseNormalizationOperator(DelegateData& delegateData, IsNormalizationSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outInfo, descriptor); @@ -132,6 +137,7 @@ TfLiteStatus VisitLocalResponseNormalizationOperator(DelegateData& delegateData, // Add a Normalization layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddNormalizationLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); diff --git a/delegate/src/Pack.hpp b/delegate/src/Pack.hpp index 458c1744c3..57d3b460f5 100644 --- a/delegate/src/Pack.hpp +++ b/delegate/src/Pack.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2021 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2021,2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -74,6 +74,7 @@ TfLiteStatus VisitPackOperator(DelegateData& delegateData, // Check if supported bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("STACK", @@ -81,6 +82,7 @@ TfLiteStatus VisitPackOperator(DelegateData& delegateData, IsStackSupported, delegateData.m_Backends, isSupported, + setBackend, inputConstTensorInfos, outputTensorInfo, desc); @@ -97,6 +99,7 @@ TfLiteStatus VisitPackOperator(DelegateData& delegateData, // The TfLite Pack operator is equivalent to the ArmNN Stack operator armnn::IConnectableLayer* layer = delegateData.m_Network->AddStackLayer(desc); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // Connect the Constant Inputs diff --git a/delegate/src/Pad.hpp b/delegate/src/Pad.hpp index daedede18d..2ecf2a06d7 100644 --- a/delegate/src/Pad.hpp +++ b/delegate/src/Pad.hpp @@ -149,6 +149,7 @@ TfLiteStatus VisitPadOperator(DelegateData& delegateData, } } + armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; @@ -157,6 +158,7 @@ TfLiteStatus VisitPadOperator(DelegateData& delegateData, IsPadSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo, descriptor); @@ -165,6 +167,7 @@ TfLiteStatus VisitPadOperator(DelegateData& delegateData, } armnn::IConnectableLayer* padLayer = delegateData.m_Network->AddPadLayer(descriptor); + padLayer->SetBackendId(setBackend); ARMNN_ASSERT(padLayer != nullptr); armnn::IOutputSlot& outputSlot = padLayer->GetOutputSlot(0); diff --git a/delegate/src/Pooling.hpp b/delegate/src/Pooling.hpp index dfe90cb1f9..824156742d 100644 --- a/delegate/src/Pooling.hpp +++ b/delegate/src/Pooling.hpp @@ -84,6 +84,7 @@ TfLiteStatus VisitPooling2dOperator(DelegateData& delegateData, descriptor.m_PadLeft, descriptor.m_PadRight, params->padding); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("POOLING_2D", @@ -91,6 +92,7 @@ TfLiteStatus VisitPooling2dOperator(DelegateData& delegateData, IsPooling2dSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo, descriptor); @@ -103,6 +105,7 @@ TfLiteStatus VisitPooling2dOperator(DelegateData& delegateData, } armnn::IConnectableLayer* poolingLayer = delegateData.m_Network->AddPooling2dLayer(descriptor); + poolingLayer->SetBackendId(setBackend); ARMNN_ASSERT(poolingLayer != nullptr); armnn::IOutputSlot& outputSlot = poolingLayer->GetOutputSlot(0); @@ -215,12 +218,14 @@ TfLiteStatus VisitPooling3dOperator(DelegateData& delegateData, // Validate the output info. bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("POOLING_3D", tfLiteContext, IsPooling3dSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo, descriptor); @@ -234,6 +239,7 @@ TfLiteStatus VisitPooling3dOperator(DelegateData& delegateData, // Create the Layer armnn::IConnectableLayer* poolingLayer = delegateData.m_Network->AddPooling3dLayer(descriptor); + poolingLayer->SetBackendId(setBackend); ARMNN_ASSERT(poolingLayer != nullptr); // Create and set output slots diff --git a/delegate/src/Prelu.hpp b/delegate/src/Prelu.hpp index 398abaf4cc..06e74ed635 100644 --- a/delegate/src/Prelu.hpp +++ b/delegate/src/Prelu.hpp @@ -29,6 +29,7 @@ TfLiteStatus ValidatePreluOperator(DelegateData& delegateData, IsPreluSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputInfo, alphaInfo, outputInfo); diff --git a/delegate/src/Quantization.hpp b/delegate/src/Quantization.hpp index 78713759fb..64f57de505 100644 --- a/delegate/src/Quantization.hpp +++ b/delegate/src/Quantization.hpp @@ -51,6 +51,7 @@ TfLiteStatus VisitDequantizeOperator(DelegateData& delegateData, UpdateConstantTensorOutputs(inputTensorInfo, outputTensorInfo); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("DEQUANTIZE", @@ -58,6 +59,7 @@ TfLiteStatus VisitDequantizeOperator(DelegateData& delegateData, IsDequantizeSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo); }; @@ -69,6 +71,7 @@ TfLiteStatus VisitDequantizeOperator(DelegateData& delegateData, } armnn::IConnectableLayer* dequantizeLayer = delegateData.m_Network->AddDequantizeLayer(); + dequantizeLayer->SetBackendId(setBackend); ARMNN_ASSERT(dequantizeLayer != nullptr); armnn::IOutputSlot& outputSlot = dequantizeLayer->GetOutputSlot(0); @@ -130,6 +133,7 @@ TfLiteStatus VisitQuantizeOperator(DelegateData& delegateData, const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("QUANTIZE", @@ -137,6 +141,7 @@ TfLiteStatus VisitQuantizeOperator(DelegateData& delegateData, IsQuantizeSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfo); }; @@ -148,6 +153,7 @@ TfLiteStatus VisitQuantizeOperator(DelegateData& delegateData, } armnn::IConnectableLayer* quantizeLayer = delegateData.m_Network->AddQuantizeLayer(); + quantizeLayer->SetBackendId(setBackend); ARMNN_ASSERT(quantizeLayer != nullptr); armnn::IOutputSlot& outputSlot = quantizeLayer->GetOutputSlot(0); diff --git a/delegate/src/Redefine.hpp b/delegate/src/Redefine.hpp index cdae719373..8f9a4e4ba0 100644 --- a/delegate/src/Redefine.hpp +++ b/delegate/src/Redefine.hpp @@ -44,6 +44,7 @@ TfLiteStatus VisitCastOperator(DelegateData& delegateData, const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("CAST", @@ -51,6 +52,7 @@ TfLiteStatus VisitCastOperator(DelegateData& delegateData, IsCastSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outInfo); }; @@ -66,6 +68,7 @@ TfLiteStatus VisitCastOperator(DelegateData& delegateData, // Add a Cast layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddCastLayer(); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); @@ -210,6 +213,7 @@ TfLiteStatus VisitReshapeOperator(DelegateData& delegateData, } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("RESHAPE", @@ -217,6 +221,7 @@ TfLiteStatus VisitReshapeOperator(DelegateData& delegateData, IsReshapeSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo0, outInfo, reshapeDesc); @@ -229,6 +234,7 @@ TfLiteStatus VisitReshapeOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddReshapeLayer(reshapeDesc); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); diff --git a/delegate/src/Reduce.hpp b/delegate/src/Reduce.hpp index 79f2f52185..3f4c118e3d 100644 --- a/delegate/src/Reduce.hpp +++ b/delegate/src/Reduce.hpp @@ -105,6 +105,7 @@ TfLiteStatus VisitReduceOperator(DelegateData& delegateData, } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("REDUCE", @@ -112,6 +113,7 @@ TfLiteStatus VisitReduceOperator(DelegateData& delegateData, IsReduceSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outInfo, desc); @@ -125,6 +127,7 @@ TfLiteStatus VisitReduceOperator(DelegateData& delegateData, // Add an Reduce layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddReduceLayer(desc); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); diff --git a/delegate/src/Resize.hpp b/delegate/src/Resize.hpp index b59006cdef..0cb15d30e4 100644 --- a/delegate/src/Resize.hpp +++ b/delegate/src/Resize.hpp @@ -33,6 +33,7 @@ TfLiteStatus ValidateResizeOperator(DelegateData& delegateData, IsResizeSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputInfo, outputInfo, descriptor); diff --git a/delegate/src/Shape.hpp b/delegate/src/Shape.hpp index 284dc9fbb7..625e6a88fb 100644 --- a/delegate/src/Shape.hpp +++ b/delegate/src/Shape.hpp @@ -52,6 +52,7 @@ TfLiteStatus VisitShapeOperator(DelegateData& delegateData, } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("SHAPE", @@ -59,6 +60,7 @@ TfLiteStatus VisitShapeOperator(DelegateData& delegateData, IsShapeSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outInfo); }; @@ -74,6 +76,7 @@ TfLiteStatus VisitShapeOperator(DelegateData& delegateData, // Add a Shape layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddShapeLayer(); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); diff --git a/delegate/src/SharedFunctions.cpp b/delegate/src/SharedFunctions.cpp index ad5d3101a2..22f578a9d7 100644 --- a/delegate/src/SharedFunctions.cpp +++ b/delegate/src/SharedFunctions.cpp @@ -1,5 +1,5 @@ // -// Copyright © 2021 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2021,2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -29,6 +29,7 @@ TfLiteStatus ValidateFloorOperator(DelegateData& delegateData, IsFloorSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputTensorInfo, outInfo); }; diff --git a/delegate/src/Slice.hpp b/delegate/src/Slice.hpp index cbcb45ec65..d5712aefad 100644 --- a/delegate/src/Slice.hpp +++ b/delegate/src/Slice.hpp @@ -99,6 +99,7 @@ TfLiteStatus VisitSliceOperator(DelegateData& delegateData, const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("SLICE", @@ -106,6 +107,7 @@ TfLiteStatus VisitSliceOperator(DelegateData& delegateData, IsSliceSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outInfo, descriptor); @@ -117,8 +119,9 @@ TfLiteStatus VisitSliceOperator(DelegateData& delegateData, return isSupported ? kTfLiteOk : kTfLiteError; } - // Add a StridedSlice layer + // Add a Slice layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddSliceLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); @@ -129,3 +132,4 @@ TfLiteStatus VisitSliceOperator(DelegateData& delegateData, } } // namespace armnnDelegate + diff --git a/delegate/src/Softmax.hpp b/delegate/src/Softmax.hpp index efc1cbae16..738f542239 100644 --- a/delegate/src/Softmax.hpp +++ b/delegate/src/Softmax.hpp @@ -27,6 +27,7 @@ TfLiteStatus ValidateSoftmaxOperator(DelegateData& delegateData, IsSoftmaxSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputInfo, outputTensorInfo, descriptor); @@ -46,6 +47,7 @@ TfLiteStatus ValidateLogSoftmaxOperator(DelegateData& delegateData, IsLogSoftmaxSupported, delegateData.m_Backends, isSupported, + armnn::BackendId(), inputInfo, outputTensorInfo, descriptor); diff --git a/delegate/src/SpaceDepth.hpp b/delegate/src/SpaceDepth.hpp index 593d0e7f87..2172d8678b 100644 --- a/delegate/src/SpaceDepth.hpp +++ b/delegate/src/SpaceDepth.hpp @@ -43,6 +43,7 @@ TfLiteStatus VisitSpaceToDepthOperator(DelegateData& delegateData, descriptor.m_BlockSize = params->block_size; bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("SPACE_TO_DEPTH", @@ -50,6 +51,7 @@ TfLiteStatus VisitSpaceToDepthOperator(DelegateData& delegateData, IsSpaceToDepthSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outInfo, descriptor); @@ -63,6 +65,7 @@ TfLiteStatus VisitSpaceToDepthOperator(DelegateData& delegateData, // Add a SpaceToDepth layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddSpaceToDepthLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); @@ -102,6 +105,7 @@ TfLiteStatus VisitDepthToSpaceOperator(DelegateData& delegateData, descriptor.m_BlockSize = params->block_size; bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("DEPTH_TO_SPACE", @@ -109,6 +113,7 @@ TfLiteStatus VisitDepthToSpaceOperator(DelegateData& delegateData, IsDepthToSpaceSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outInfo, descriptor); @@ -122,6 +127,7 @@ TfLiteStatus VisitDepthToSpaceOperator(DelegateData& delegateData, // Add a DepthToSpace layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddDepthToSpaceLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); diff --git a/delegate/src/Split.hpp b/delegate/src/Split.hpp index a535585699..5c094b405b 100644 --- a/delegate/src/Split.hpp +++ b/delegate/src/Split.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2020,2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -113,6 +113,7 @@ TfLiteStatus VisitSplitOperator(DelegateData& delegateData, splitDescriptor.SetViewOriginCoord(j, splitDim, splitterDimSizes[splitDim] * j); } + armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported @@ -122,6 +123,7 @@ TfLiteStatus VisitSplitOperator(DelegateData& delegateData, IsSplitterSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfos, splitDescriptor); @@ -129,6 +131,7 @@ TfLiteStatus VisitSplitOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddSplitterLayer(splitDescriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); for (unsigned int k = 0; k < layer->GetNumOutputSlots(); ++k) @@ -305,6 +308,7 @@ TfLiteStatus VisitSplitVOperator(DelegateData& delegateData, accumSplit += splitSize; } + armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported @@ -314,6 +318,7 @@ TfLiteStatus VisitSplitVOperator(DelegateData& delegateData, IsSplitterSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputTensorInfos, splitDescriptor); @@ -321,6 +326,7 @@ TfLiteStatus VisitSplitVOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddSplitterLayer(splitDescriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); for (unsigned int k = 0; k < layer->GetNumOutputSlots(); ++k) diff --git a/delegate/src/StridedSlice.hpp b/delegate/src/StridedSlice.hpp index 515c819ffe..d2c4d5da3a 100644 --- a/delegate/src/StridedSlice.hpp +++ b/delegate/src/StridedSlice.hpp @@ -114,6 +114,7 @@ TfLiteStatus VisitStridedSliceOperator(DelegateData& delegateData, const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("STRIDED_SLICE", @@ -121,6 +122,7 @@ TfLiteStatus VisitStridedSliceOperator(DelegateData& delegateData, IsStridedSliceSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outInfo, descriptor); @@ -134,6 +136,7 @@ TfLiteStatus VisitStridedSliceOperator(DelegateData& delegateData, // Add a StridedSlice layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddStridedSliceLayer(descriptor); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); @@ -144,3 +147,4 @@ TfLiteStatus VisitStridedSliceOperator(DelegateData& delegateData, } } // namespace armnnDelegate + diff --git a/delegate/src/Transpose.hpp b/delegate/src/Transpose.hpp index 80bb12254e..15c53101f2 100644 --- a/delegate/src/Transpose.hpp +++ b/delegate/src/Transpose.hpp @@ -71,7 +71,7 @@ TfLiteStatus VisitTransposeOperator(DelegateData& delegateData, static_cast(numEl))); bool isSupported = false; - + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("TRANSPOSE", @@ -79,6 +79,7 @@ TfLiteStatus VisitTransposeOperator(DelegateData& delegateData, IsTransposeSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo0, outputTensorInfo, descriptor); @@ -91,6 +92,7 @@ TfLiteStatus VisitTransposeOperator(DelegateData& delegateData, } armnn::IConnectableLayer* transposeLayer = delegateData.m_Network->AddTransposeLayer(descriptor); + transposeLayer->SetBackendId(setBackend); ARMNN_ASSERT(transposeLayer != nullptr); ARMNN_ASSERT(transposeLayer->GetNumInputSlots() == 1); // permutation vector given to descriptor object diff --git a/delegate/src/UnidirectionalSequenceLstm.hpp b/delegate/src/UnidirectionalSequenceLstm.hpp index 64ed778231..9408397587 100644 --- a/delegate/src/UnidirectionalSequenceLstm.hpp +++ b/delegate/src/UnidirectionalSequenceLstm.hpp @@ -253,6 +253,7 @@ TfLiteStatus VisitUnidirectionalSequenceLstmOperator(DelegateData& delegateData, } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("UNIDIRECTIONAL_SEQUENCE_LSTM", @@ -260,6 +261,7 @@ TfLiteStatus VisitUnidirectionalSequenceLstmOperator(DelegateData& delegateData, IsUnidirectionalSequenceLstmSupported, delegateData.m_Backends, isSupported, + setBackend, inputTensorInfo, outputStateInInfo, cellStateInInfo, @@ -277,6 +279,7 @@ TfLiteStatus VisitUnidirectionalSequenceLstmOperator(DelegateData& delegateData, } armnn::IConnectableLayer* layer = delegateData.m_Network->AddUnidirectionalSequenceLstmLayer(desc, params); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(outputStateOutTensorInfo); diff --git a/delegate/src/Unpack.hpp b/delegate/src/Unpack.hpp index aaea00532f..ad541adccc 100644 --- a/delegate/src/Unpack.hpp +++ b/delegate/src/Unpack.hpp @@ -133,6 +133,7 @@ TfLiteStatus VisitUnpackOperator(DelegateData& delegateData, std::vector> splitterOutputTensorInfos(splitterOutputs.begin(), splitterOutputs.end()); + armnn::BackendId setBackendSplit; if (!delegateData.m_Network) { // Check if splitter is supported @@ -142,6 +143,7 @@ TfLiteStatus VisitUnpackOperator(DelegateData& delegateData, IsSplitterSupported, delegateData.m_Backends, isSupported, + setBackendSplit, inputTensorInfo, splitterOutputTensorInfos, splitDesc); @@ -153,6 +155,7 @@ TfLiteStatus VisitUnpackOperator(DelegateData& delegateData, armnn::ReshapeDescriptor reshapeDescriptor; reshapeDescriptor.m_TargetShape = outputTensorInfos[0].get().GetShape(); + armnn::BackendId setBackendReshape; if (!delegateData.m_Network) { bool isSupported = false; @@ -161,6 +164,7 @@ TfLiteStatus VisitUnpackOperator(DelegateData& delegateData, IsReshapeSupported, delegateData.m_Backends, isSupported, + setBackendReshape, splitterOutputTensorInfos[0], outputTensorInfos[0], reshapeDescriptor); @@ -171,6 +175,7 @@ TfLiteStatus VisitUnpackOperator(DelegateData& delegateData, armnn::IConnectableLayer* splitterLayer = delegateData.m_Network->AddSplitterLayer(splitDesc, splitterLayerName.c_str()); + splitterLayer->SetBackendId(setBackendSplit); ARMNN_ASSERT(splitterLayer != nullptr); for (unsigned int k = 0; k < splitterLayer->GetNumOutputSlots(); ++k) @@ -187,6 +192,7 @@ TfLiteStatus VisitUnpackOperator(DelegateData& delegateData, std::string reshapeLayerName("Unpack Reshape"); armnn::IConnectableLayer* reshapeLayer = delegateData.m_Network->AddReshapeLayer(reshapeDescriptor, reshapeLayerName.c_str()); + reshapeLayer->SetBackendId(setBackendReshape); ARMNN_ASSERT(reshapeLayer != nullptr); splitterLayer->GetOutputSlot(outputIndex).SetTensorInfo(splitterOutputTensorInfos[outputIndex]); diff --git a/include/armnn/INetwork.hpp b/include/armnn/INetwork.hpp index 2bb9ad91f3..c9c8a04656 100644 --- a/include/armnn/INetwork.hpp +++ b/include/armnn/INetwork.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2017,2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once @@ -98,7 +98,11 @@ public: /// Apply a visitor to this layer virtual void ExecuteStrategy(IStrategy& strategy) const = 0; - /// Provide a hint for the optimizer as to which backend to prefer for this layer + /// Provide a hint for the optimizer as to which backend to prefer for this layer. + /// By providing a BackendSelectionHint there is no guarantee the input backend supports that layer. + /// If IsLayerSupported() returns false with the backend hint, we default to calling IsLayerSupported() + /// on the BackendPreferences vector. Use SetBackendId() if we can guarantee a backend supports that + /// layer (IsLayerSupported returns true for a specific backend). virtual void BackendSelectionHint(Optional backend) = 0; /// Returns the armnn::LayerType of this layer @@ -111,6 +115,12 @@ public: /// the BaseDescriptor IsNull function is invoked. virtual const BaseDescriptor& GetParameters() const = 0; + /// Set the backend of the IConnectableLayer. + /// By using SetBackendId() we guarantee that the input backend supports that + /// layer (IsLayerSupported returns true for a specific backend). If there is + /// no guarantee the input backend supports that layer use BackendSelectionHint(). + virtual void SetBackendId(const BackendId& id) = 0; + using ConstantTensors = std::vector>>; // Returns ConstantTensors of this Layer if it has any, otherwise returns empty vector. diff --git a/include/armnn/Version.hpp b/include/armnn/Version.hpp index 7fdb20ade5..aedd4a0c0b 100644 --- a/include/armnn/Version.hpp +++ b/include/armnn/Version.hpp @@ -10,7 +10,7 @@ #define STRINGIFY_MACRO(s) #s // ArmNN version components -#define ARMNN_MAJOR_VERSION 31 +#define ARMNN_MAJOR_VERSION 32 #define ARMNN_MINOR_VERSION 0 #define ARMNN_PATCH_VERSION 0 diff --git a/python/pyarmnn/README.md b/python/pyarmnn/README.md index 0d2c511a17..3962e11395 100644 --- a/python/pyarmnn/README.md +++ b/python/pyarmnn/README.md @@ -69,8 +69,8 @@ PyArmNN can be distributed as a source package or a binary package (wheel). Binary package is platform dependent, the name of the package will indicate the platform it was built for, e.g.: -* Linux x86 64bit machine: pyarmnn-31.0.0-cp36-cp36m-*linux_x86_64*.whl -* Linux Aarch 64 bit machine: pyarmnn-31.0.0-cp36-cp36m-*linux_aarch64*.whl +* Linux x86 64bit machine: pyarmnn-32.0.0-cp36-cp36m-*linux_x86_64*.whl +* Linux Aarch 64 bit machine: pyarmnn-32.0.0-cp36-cp36m-*linux_aarch64*.whl The source package is platform independent but installation involves compilation of Arm NN python extension. You will need to have g++ compatible with C++ 14 standard and a python development library installed on the build machine. @@ -110,7 +110,7 @@ $ pip show pyarmnn You can also verify it by running the following and getting output similar to below: ```bash $ python -c "import pyarmnn as ann;print(ann.GetVersion())" -'31.0.0' +'32.0.0' ``` # PyArmNN API overview diff --git a/python/pyarmnn/examples/image_classification/README.md b/python/pyarmnn/examples/image_classification/README.md index 04718e2bf4..fa0f89eba0 100644 --- a/python/pyarmnn/examples/image_classification/README.md +++ b/python/pyarmnn/examples/image_classification/README.md @@ -20,7 +20,7 @@ $ pip show pyarmnn You can also verify it by running the following and getting output similar to below: ```bash $ python -c "import pyarmnn as ann;print(ann.GetVersion())" -'31.0.0' +'32.0.0' ``` ##### Dependencies diff --git a/python/pyarmnn/examples/keyword_spotting/README.md b/python/pyarmnn/examples/keyword_spotting/README.md index 98158e6c03..905cae1070 100644 --- a/python/pyarmnn/examples/keyword_spotting/README.md +++ b/python/pyarmnn/examples/keyword_spotting/README.md @@ -18,7 +18,7 @@ You can also verify it by running the following and getting output similar to be ```bash $ python -c "import pyarmnn as ann;print(ann.GetVersion())" -'31.0.0' +'32.0.0' ``` ### Dependencies diff --git a/python/pyarmnn/examples/object_detection/README.md b/python/pyarmnn/examples/object_detection/README.md index 73bafb6038..3c4b100fd4 100644 --- a/python/pyarmnn/examples/object_detection/README.md +++ b/python/pyarmnn/examples/object_detection/README.md @@ -54,7 +54,7 @@ $ pip show pyarmnn You can also verify it by running the following and getting output similar to below: ```bash $ python -c "import pyarmnn as ann;print(ann.GetVersion())" -'31.0.0' +'32.0.0' ``` ##### Dependencies diff --git a/python/pyarmnn/examples/speech_recognition/README.md b/python/pyarmnn/examples/speech_recognition/README.md index e442aad591..af0196f4bf 100644 --- a/python/pyarmnn/examples/speech_recognition/README.md +++ b/python/pyarmnn/examples/speech_recognition/README.md @@ -18,7 +18,7 @@ You can also verify it by running the following and getting output similar to be ```bash $ python -c "import pyarmnn as ann;print(ann.GetVersion())" -'31.0.0' +'32.0.0' ``` ### Dependencies diff --git a/python/pyarmnn/src/pyarmnn/_version.py b/python/pyarmnn/src/pyarmnn/_version.py index d68a893e9c..4501f88ab5 100644 --- a/python/pyarmnn/src/pyarmnn/_version.py +++ b/python/pyarmnn/src/pyarmnn/_version.py @@ -3,7 +3,7 @@ # SPDX-License-Identifier: MIT import os -version_info = (31, 0, 0) +version_info = (32, 0, 0) __dev_version_env = os.getenv("PYARMNN_DEV_VER", "") @@ -24,7 +24,7 @@ def check_armnn_version(installed_armnn_version: str, expected_armnn_version: st """Compares expected Arm NN version and Arm NN version used to build the package. Args: - installed_armnn_version (str): Arm NN version used to generate the package (e.g. 31.0.0) + installed_armnn_version (str): Arm NN version used to generate the package (e.g. 32.0.0) expected_armnn_version (str): Expected Arm NN version Returns: diff --git a/python/pyarmnn/test/test_setup.py b/python/pyarmnn/test/test_setup.py index ada96ccad4..8275a537b4 100644 --- a/python/pyarmnn/test/test_setup.py +++ b/python/pyarmnn/test/test_setup.py @@ -87,15 +87,15 @@ def test_gcc_serch_path(): def test_armnn_version(): - check_armnn_version('31.0.0', '31.0.0') + check_armnn_version('32.0.0', '32.0.0') def test_incorrect_armnn_version(): with pytest.raises(AssertionError) as err: - check_armnn_version('31.0.0', '31.1.0') + check_armnn_version('32.0.0', '32.1.0') - assert 'Expected ArmNN version is 31.1.0 but installed ArmNN version is 31.0.0' in str(err.value) + assert 'Expected ArmNN version is 32.1.0 but installed ArmNN version is 32.0.0' in str(err.value) def test_armnn_version_patch_does_not_matter(): - check_armnn_version('31.0.0', '31.0.1') + check_armnn_version('32.0.0', '32.0.1') diff --git a/python/pyarmnn/test/test_version.py b/python/pyarmnn/test/test_version.py index f68adff0c7..145fc3bc04 100644 --- a/python/pyarmnn/test/test_version.py +++ b/python/pyarmnn/test/test_version.py @@ -18,7 +18,7 @@ def test_dev_version(): importlib.reload(v) - assert "31.0.0.dev1" == v.__version__ + assert "32.0.0.dev1" == v.__version__ del os.environ["PYARMNN_DEV_VER"] del v @@ -30,7 +30,7 @@ def test_arm_version_not_affected(): importlib.reload(v) - assert "31.0.0" == v.__arm_ml_version__ + assert "32.0.0" == v.__arm_ml_version__ del os.environ["PYARMNN_DEV_VER"] del v diff --git a/shim/sl/canonical/ConversionUtils.cpp b/shim/sl/canonical/ConversionUtils.cpp index f48af32e21..b64854856e 100644 --- a/shim/sl/canonical/ConversionUtils.cpp +++ b/shim/sl/canonical/ConversionUtils.cpp @@ -256,6 +256,7 @@ LayerInputHandle ConvertToLayerInputHandle(const Operation& operation, IsInputSupported, data.m_Backends, isInputSupported, + armnn::BackendId(), operandTensorInfo); if (!isInputSupported) @@ -292,10 +293,12 @@ LayerInputHandle ConvertToLayerInputHandle(const Operation& operation, if (tensorPin.IsValid()) { bool isSupported = false; + armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC(__func__, IsConstantSupported, data.m_Backends, isSupported, + setBackend, tensorPin.GetConstTensor().GetInfo()); if (!isSupported) { @@ -304,6 +307,7 @@ LayerInputHandle ConvertToLayerInputHandle(const Operation& operation, armnn::IConnectableLayer* constantLayer = data.m_Network->AddConstantLayer(tensorPin.GetConstTensor()); + constantLayer->SetBackendId(setBackend); armnn::IOutputSlot& outputSlot = constantLayer->GetOutputSlot(0); armnn::TensorInfo constantTensorInfo = tensorPin.GetConstTensor().GetInfo(); outputSlot.SetTensorInfo(constantTensorInfo); @@ -455,13 +459,14 @@ bool ConvertPooling2d(const Operation& operation, } bool isSupported = false; - + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsPooling2dSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, desc); @@ -483,6 +488,7 @@ bool ConvertPooling2d(const Operation& operation, } armnn::IConnectableLayer* pooling2dLayer = data.m_Network->AddPooling2dLayer(desc); + pooling2dLayer->SetBackendId(setBackend); if (!pooling2dLayer) { return Fail("%s: AddPooling2dLayer failed", __func__); @@ -547,12 +553,14 @@ bool ConvertReduce(const Operation& operation, } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsReduceSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, descriptor); @@ -573,6 +581,7 @@ bool ConvertReduce(const Operation& operation, } armnn::IConnectableLayer* const layer = data.m_Network->AddReduceLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -601,13 +610,14 @@ bool ConvertToActivation(const Operation& operation, const armnn::TensorInfo& outInfo = GetTensorInfoForOperand(*outputOperand); bool isSupported = false; - + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsActivationSupported, data.m_Backends, isSupported, + setBackend, input.GetTensorInfo(), outInfo, activationDesc); @@ -628,6 +638,7 @@ bool ConvertToActivation(const Operation& operation, } armnn::IConnectableLayer* layer = data.m_Network->AddActivationLayer(activationDesc); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -925,10 +936,12 @@ armnn::IConnectableLayer* ProcessActivation(const armnn::TensorInfo& tensorInfo, } bool isSupported = false; + armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC(__func__, IsActivationSupported, data.m_Backends, isSupported, + setBackend, prevLayer->GetOutputSlot(0).GetTensorInfo(), tensorInfo, activationDesc); @@ -938,6 +951,7 @@ armnn::IConnectableLayer* ProcessActivation(const armnn::TensorInfo& tensorInfo, } activationLayer = data.m_Network->AddActivationLayer(activationDesc); + activationLayer->SetBackendId(setBackend); prevLayer->GetOutputSlot(0).Connect(activationLayer->GetInputSlot(0)); activationLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo); diff --git a/shim/sl/canonical/ConversionUtils.hpp b/shim/sl/canonical/ConversionUtils.hpp index beee00d11a..91a8e3080c 100644 --- a/shim/sl/canonical/ConversionUtils.hpp +++ b/shim/sl/canonical/ConversionUtils.hpp @@ -150,7 +150,7 @@ static bool Fail(const char* formatStr, Args&&... args) // Convenience macro to call an Is*Supported function and log caller name together with reason for lack of support. // Called as: FORWARD_LAYER_SUPPORT_FUNC(__func__, Is*Supported, backends, a, b, c, d, e) -#define FORWARD_LAYER_SUPPORT_FUNC(funcName, func, backends, supported, ...) \ +#define FORWARD_LAYER_SUPPORT_FUNC(funcName, func, backends, supported, setBackend, ...) \ try \ { \ for (auto&& backendId : backends) \ @@ -163,6 +163,7 @@ try \ layerSupportObject.func(__VA_ARGS__, armnn::Optional(reasonIfUnsupported)); \ if (supported) \ { \ + setBackend = backendId; \ break; \ } \ else \ @@ -322,10 +323,12 @@ bool BroadcastTensor(LayerInputHandle& input0, armnn::ReshapeDescriptor reshapeDescriptor; bool isSupported = false; + armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC(__func__, IsReshapeSupported, data.m_Backends, isSupported, + setBackend, smallInfo, reshapedInfo, reshapeDescriptor); @@ -336,6 +339,7 @@ bool BroadcastTensor(LayerInputHandle& input0, ARMNN_ASSERT(data.m_Network != nullptr); armnn::IConnectableLayer& reshapeLayer = AddReshapeLayer(*data.m_Network, smallInputHandle, reshapedInfo); + reshapeLayer.SetBackendId(setBackend); if (input0IsSmaller) { @@ -527,7 +531,8 @@ inline bool RequiresReshape(armnn::TensorShape & inputShape) inline void SwizzleInputs(armnn::INetwork& network, std::vector& inputs, std::vector& inputShapes, - const armnn::PermutationVector& mapping) + const armnn::PermutationVector& mapping, + std::vector& setBackends) { if (!mapping.IsEqual(IdentityPermutation4D)) { @@ -536,6 +541,7 @@ inline void SwizzleInputs(armnn::INetwork& network, { // add swizzle layer armnn::IConnectableLayer& swizzleLayer = AddTransposeLayer(network, inputs[i], mapping); + swizzleLayer.SetBackendId(setBackends[i]); auto& outputSlot = swizzleLayer.GetOutputSlot(0); auto& outputInfo = outputSlot.GetTensorInfo(); // replace inputs with the swizzled ones @@ -553,6 +559,7 @@ bool TransposeInputTensors(ConversionData& data, // If we have a IdentityPermutation4D or IdentityPermutation3D then we are not permuting if (!mapping.IsEqual(IdentityPermutation4D) && !mapping.IsEqual(IdentityPermutation3D)) { + std::vector setBackendsVec; armnn::TensorInfo outputTransposeInfo; size_t nInputs = inputs.size(); for (size_t i=0; iAddAdditionLayer(); + startLayer->SetBackendId(setBackend); bool isReshapeSupported = BroadcastTensor(input0, input1, startLayer, data); if (!isReshapeSupported) @@ -290,13 +293,14 @@ bool Converter::ConvertArgMinMax(const Operation& operation, descriptor.m_Axis = axis; bool isSupported = false; - + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsArgMinMaxSupported, data.m_Backends, isSupported, + setBackend, inputInfo0, outputInfo, descriptor); @@ -317,6 +321,7 @@ bool Converter::ConvertArgMinMax(const Operation& operation, } armnn::IConnectableLayer* layer = data.m_Network->AddArgMinMaxLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input0.Connect(layer->GetInputSlot(0)); @@ -391,12 +396,14 @@ bool Converter::ConvertBatchMatMul(const Operation& operation, const Model& mode batchMatMulDesc.m_TransposeY = GetOptionalBool(operation, 3, model, data); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsBatchMatMulSupported, data.m_Backends, isSupported, + setBackend, inputInfo0, inputInfo1, outputInfo, @@ -419,6 +426,7 @@ bool Converter::ConvertBatchMatMul(const Operation& operation, const Model& mode } armnn::IConnectableLayer* const layer = data.m_Network->AddBatchMatMulLayer(batchMatMulDesc); + layer->SetBackendId(setBackend); assert(layer != nullptr); input0.Connect(layer->GetInputSlot(0)); input1.Connect(layer->GetInputSlot(1)); @@ -482,12 +490,14 @@ bool Converter::ConvertBatchToSpaceNd(const Operation& operation, const Model& m batchToSpaceNdDesc.m_Crops = {{0, 0}, {0, 0}}; bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsBatchToSpaceNdSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, batchToSpaceNdDesc); @@ -509,6 +519,7 @@ bool Converter::ConvertBatchToSpaceNd(const Operation& operation, const Model& m } armnn::IConnectableLayer* const layer = data.m_Network->AddBatchToSpaceNdLayer(batchToSpaceNdDesc); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -536,13 +547,14 @@ bool Converter::ConvertCast(const Operation& operation, const Model& model, Conv const TensorInfo& outputInfo = GetTensorInfoForOperand(*output); bool isSupported = false; - + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsCastSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo); }; @@ -562,6 +574,7 @@ bool Converter::ConvertCast(const Operation& operation, const Model& model, Conv } IConnectableLayer* layer = data.m_Network->AddCastLayer(); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -597,12 +610,14 @@ bool Converter::ConvertComparison(const Operation& operation, ComparisonDescriptor descriptor(comparisonOperation); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsComparisonSupported, data.m_Backends, isSupported, + setBackend, inputInfo0, inputInfo1, outputInfo, @@ -624,6 +639,7 @@ bool Converter::ConvertComparison(const Operation& operation, } IConnectableLayer* layer = data.m_Network->AddComparisonLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); bool isReshapeSupported = BroadcastTensor(input0, input1, layer, data); @@ -735,10 +751,12 @@ bool Converter::ConvertConcatenation(const Operation& operation, const Model& mo reshapeDescriptor.m_TargetShape = reshapeInfo.GetShape(); bool isSupported = false; + armnn::BackendId setBackendReshape; FORWARD_LAYER_SUPPORT_FUNC(__func__, IsReshapeSupported, data.m_Backends, isSupported, + setBackendReshape, operandInputHandle.GetTensorInfo(), reshapeInfo, reshapeDescriptor); @@ -748,6 +766,7 @@ bool Converter::ConvertConcatenation(const Operation& operation, const Model& mo return false; } armnn::IConnectableLayer& newReshape = AddReshapeLayer(*data.m_Network, operandInputHandle, reshapeInfo); + newReshape.SetBackendId(setBackendReshape); // Point to the reshape operation rather then the input operation operandShape = reshapeInfo.GetShape(); @@ -850,9 +869,16 @@ bool Converter::ConvertConcatenation(const Operation& operation, const Model& mo [](const LayerInputHandle& h)->const armnn::TensorInfo*{ return &h.GetTensorInfo(); }); bool isSupported = false; + armnn::BackendId setBackendConcat; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported){ - FORWARD_LAYER_SUPPORT_FUNC(__func__, IsConcatSupported, data.m_Backends, isSupported, inputTensorInfos, - outputInfo, concatDescriptor); + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsConcatSupported, + data.m_Backends, + isSupported, + setBackendConcat, + inputTensorInfos, + outputInfo, + concatDescriptor); }; if (!isDynamicTensor) @@ -870,6 +896,7 @@ bool Converter::ConvertConcatenation(const Operation& operation, const Model& mo } armnn::IConnectableLayer* layer = data.m_Network->AddConcatLayer(concatDescriptor); + layer->SetBackendId(setBackendConcat); assert(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(outputInfo); // Connect inputs to the layer @@ -889,10 +916,12 @@ bool Converter::ConvertConcatenation(const Operation& operation, const Model& mo armnn::TensorInfo outputTransposeInfo = armnnUtils::TransposeTensorShape(inputTransposeInfo, permutationPair.second); isSupported = false; + armnn::BackendId setBackendTranspose; FORWARD_LAYER_SUPPORT_FUNC(__func__, IsTransposeSupported, data.m_Backends, isSupported, + setBackendTranspose, inputTransposeInfo, outputTransposeInfo, transposeDesc); @@ -903,6 +932,7 @@ bool Converter::ConvertConcatenation(const Operation& operation, const Model& mo // Add permutation layer and connect the output to it, the permutation becomes the output layer armnn::IConnectableLayer& deswizzleLayer = AddTransposeLayer(*data.m_Network, layer->GetOutputSlot(0), permutationPair.second); + deswizzleLayer.SetBackendId(setBackendTranspose); layer = &deswizzleLayer; return true; @@ -945,11 +975,13 @@ bool Converter::ConvertConcatenation(const Operation& operation, const Model& mo armnn::TensorInfo concatInfo = layer->GetOutputSlot(0).GetTensorInfo(); isSupported = false; + armnn::BackendId setBackendReshape2; auto validateReshapeFunc = [&](const armnn::TensorInfo& afterConcatInfo, bool& isSupported){ FORWARD_LAYER_SUPPORT_FUNC(__func__, IsReshapeSupported, data.m_Backends, isSupported, + setBackendReshape2, concatInfo, afterConcatInfo, reshapeDescriptor); @@ -969,6 +1001,7 @@ bool Converter::ConvertConcatenation(const Operation& operation, const Model& mo return false; } layer = &AddReshapeLayer(*data.m_Network, layer->GetOutputSlot(0), afterConcatInfo); + layer->SetBackendId(setBackendReshape2); return SetupAndTrackLayerOutputSlot(operation, 0, *layer, @@ -1109,11 +1142,13 @@ bool Converter::ConvertConv2d(const Operation& operation, const Model& model, Co VLOG(DRIVER) << "Converter::ConvertConv2d(): Weights and Biases are as INPUTS."; } + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsConvolution2dSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, desc, @@ -1141,6 +1176,7 @@ bool Converter::ConvertConv2d(const Operation& operation, const Model& model, Co } armnn::IConnectableLayer* startLayer = data.m_Network->AddConvolution2dLayer(desc); + startLayer->SetBackendId(setBackend); if (!startLayer) { @@ -1194,12 +1230,14 @@ bool Converter::ConvertDepthToSpace(const Operation& operation, const Model& mod } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsDepthToSpaceSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, descriptor); @@ -1220,6 +1258,7 @@ bool Converter::ConvertDepthToSpace(const Operation& operation, const Model& mod } armnn::IConnectableLayer* const layer = data.m_Network->AddDepthToSpaceLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -1355,11 +1394,13 @@ bool Converter::ConvertDepthwiseConv2d(const Operation& operation, const Model& VLOG(DRIVER) << "Converter::ConvertDepthwiseConv2d(): Weights and Biases are as INPUTS."; } + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsDepthwiseConvolutionSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, desc, @@ -1387,6 +1428,7 @@ bool Converter::ConvertDepthwiseConv2d(const Operation& operation, const Model& } armnn::IConnectableLayer* startLayer = data.m_Network->AddDepthwiseConvolution2dLayer(desc); + startLayer->SetBackendId(setBackend); if (!startLayer) { @@ -1428,12 +1470,14 @@ bool Converter::ConvertDequantize(const Operation& operation, const Model& model const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*outputOperand); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsDequantizeSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo); }; @@ -1453,6 +1497,7 @@ bool Converter::ConvertDequantize(const Operation& operation, const Model& model } armnn::IConnectableLayer* const layer = data.m_Network->AddDequantizeLayer(); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -1488,12 +1533,14 @@ bool Converter::ConvertDiv(const Operation& operation, const Model& model, Conve const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*output); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsDivisionSupported, data.m_Backends, isSupported, + setBackend, input0.GetTensorInfo(), input1.GetTensorInfo(), outputInfo); @@ -1514,6 +1561,7 @@ bool Converter::ConvertDiv(const Operation& operation, const Model& model, Conve } armnn::IConnectableLayer* const startLayer = data.m_Network->AddDivisionLayer(); + startLayer->SetBackendId(setBackend); bool isReshapeSupported = BroadcastTensor(input0, input1, startLayer, data); if (!isReshapeSupported) @@ -1552,13 +1600,14 @@ bool Converter::ConvertElementwiseUnary(const Operation& operation, ElementwiseUnaryDescriptor descriptor(unaryOperation); bool isSupported = false; - + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsElementwiseUnarySupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, descriptor); @@ -1579,6 +1628,7 @@ bool Converter::ConvertElementwiseUnary(const Operation& operation, } IConnectableLayer* layer = data.m_Network->AddElementwiseUnaryLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -1672,12 +1722,14 @@ bool Converter::ConvertExpandDims(const Operation& operation, const Model& model reshapeDescriptor.m_TargetShape = targetShape; bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsReshapeSupported, data.m_Backends, isSupported, + setBackend, input.GetTensorInfo(), outputInfo, reshapeDescriptor); @@ -1702,6 +1754,7 @@ bool Converter::ConvertExpandDims(const Operation& operation, const Model& model } IConnectableLayer* layer = data.m_Network->AddReshapeLayer(reshapeDescriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -1769,10 +1822,12 @@ bool Converter::ConvertFill(const Operation& operation, const Model& model, Conv } bool isSupported = false; + armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC(__func__, IsFillSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, descriptor); @@ -1782,6 +1837,7 @@ bool Converter::ConvertFill(const Operation& operation, const Model& model, Conv } IConnectableLayer* const layer = data.m_Network->AddFillLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -1806,12 +1862,14 @@ bool Converter::ConvertFloor(const Operation& operation, const Model& model, Con const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*outputOperand); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsFloorSupported, data.m_Backends, isSupported, + setBackend, input.GetTensorInfo(), outputInfo); }; @@ -1831,6 +1889,7 @@ bool Converter::ConvertFloor(const Operation& operation, const Model& model, Con } armnn::IConnectableLayer* layer = data.m_Network->AddFloorLayer(); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -1912,6 +1971,7 @@ bool Converter::ConvertFullyConnected(const Operation& operation, const Model& m desc.m_ConstantWeights = IsOperandConstant(*weightsOperand); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { if (!VerifyFullyConnectedShapes(reshapedInfo.GetShape(), @@ -1928,6 +1988,7 @@ bool Converter::ConvertFullyConnected(const Operation& operation, const Model& m IsFullyConnectedSupported, data.m_Backends, isSupported, + setBackend, reshapedInfo, outputInfo, weightsInfo, @@ -1951,6 +2012,7 @@ bool Converter::ConvertFullyConnected(const Operation& operation, const Model& m // Add FullyConnected layer. Weights and bias will be connected as constant layers or non const inputs. armnn::IConnectableLayer* startLayer = data.m_Network->AddFullyConnectedLayer(desc); + startLayer->SetBackendId(setBackend); if (inputInfo.GetNumDimensions() > 2U) { @@ -2022,12 +2084,14 @@ bool Converter::ConvertGather(const Operation& operation, const Model& model, Co desc.m_Axis = axis; bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsGatherSupported, data.m_Backends, isSupported, + setBackend, input.GetTensorInfo(), indices.GetTensorInfo(), outputInfo, @@ -2049,6 +2113,7 @@ bool Converter::ConvertGather(const Operation& operation, const Model& model, Co } IConnectableLayer* layer = data.m_Network->AddGatherLayer(desc); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); indices.Connect(layer->GetInputSlot(1)); @@ -2209,10 +2274,12 @@ bool Converter::ConvertGroupedConv2d(const Operation& operation, const Model& mo } bool isSupported = false; + armnn::BackendId setBackendSplit; FORWARD_LAYER_SUPPORT_FUNC(__func__, IsSplitterSupported, data.m_Backends, isSupported, + setBackendSplit, inputInfo, splitterOutputInfos, splitterDesc); @@ -2222,6 +2289,7 @@ bool Converter::ConvertGroupedConv2d(const Operation& operation, const Model& mo } IConnectableLayer* splitterLayer = data.m_Network->AddSplitterLayer(splitterDesc); + splitterLayer->SetBackendId(setBackendSplit); if (!splitterLayer) { return Fail("%s: Failed to add SplitterLayer", __func__); @@ -2305,12 +2373,14 @@ bool Converter::ConvertGroupedConv2d(const Operation& operation, const Model& mo biasesDataOffset)); isSupported = false; + armnn::BackendId setBackendConv; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsConvolution2dSupported, data.m_Backends, isSupported, + setBackendConv, groupInputInfo, outputInfo, desc, @@ -2336,6 +2406,8 @@ bool Converter::ConvertGroupedConv2d(const Operation& operation, const Model& mo IConnectableLayer* biasLayer = data.m_Network->AddConstantLayer(groupBiases); IConnectableLayer* convLayer = data.m_Network->AddConvolution2dLayer(desc); + convLayer->SetBackendId(setBackendConv); + if (!convLayer) { return Fail("%s: AddConvolution2dLayer failed", __func__); @@ -2384,10 +2456,12 @@ bool Converter::ConvertGroupedConv2d(const Operation& operation, const Model& mo } isSupported = false; + armnn::BackendId setBackendConcat; FORWARD_LAYER_SUPPORT_FUNC(__func__, IsConcatSupported, data.m_Backends, isSupported, + setBackendConcat, std::vector(numGroups * channelMultiplier, &groupOutputInfo), outputInfo, concatDescriptor); @@ -2398,6 +2472,7 @@ bool Converter::ConvertGroupedConv2d(const Operation& operation, const Model& mo } IConnectableLayer* concatLayer = data.m_Network->AddConcatLayer(concatDescriptor); + concatLayer->SetBackendId(setBackendConcat); if (!concatLayer) { return Fail("%s: AddConcatLayer failed", __func__); @@ -2488,12 +2563,14 @@ bool Converter::ConvertInstanceNormalization(const Operation& operation, const M desc.m_DataLayout = OptionalDataLayout(operation, 4, model, data); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsInstanceNormalizationSupported, data.m_Backends, isSupported, + setBackend, input.GetTensorInfo(), outputInfo, desc); @@ -2514,6 +2591,7 @@ bool Converter::ConvertInstanceNormalization(const Operation& operation, const M } IConnectableLayer* layer = data.m_Network->AddInstanceNormalizationLayer(desc); + layer->SetBackendId(setBackend); input.Connect(layer->GetInputSlot(0)); return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); @@ -2552,12 +2630,14 @@ bool Converter::ConvertL2Normalization(const Operation& operation, const Model& desc.m_DataLayout = armnn::DataLayout::NHWC; bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsL2NormalizationSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, desc); @@ -2578,6 +2658,7 @@ bool Converter::ConvertL2Normalization(const Operation& operation, const Model& } armnn::IConnectableLayer* layer = data.m_Network->AddL2NormalizationLayer(desc); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -2640,12 +2721,14 @@ bool Converter::ConvertLocalResponseNormalization(const Operation& operation, descriptor.m_NormSize = 1 + (2 * descriptor.m_NormSize); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsNormalizationSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, descriptor); @@ -2667,6 +2750,7 @@ bool Converter::ConvertLocalResponseNormalization(const Operation& operation, armnn::IConnectableLayer* layer = data.m_Network->AddNormalizationLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -2703,13 +2787,14 @@ bool Converter::ConvertLogicalBinary(const Operation& operation, LogicalBinaryDescriptor descriptor(logicalOperation); bool isSupported = false; - + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsLogicalBinarySupported, data.m_Backends, isSupported, + setBackend, inputInfo0, inputInfo1, outputInfo, @@ -2731,6 +2816,7 @@ bool Converter::ConvertLogicalBinary(const Operation& operation, } IConnectableLayer* layer = data.m_Network->AddLogicalBinaryLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); bool isReshapeSupported = BroadcastTensor(input0, input1, layer, data); @@ -2808,12 +2894,14 @@ bool Converter::ConvertLogSoftmax(const Operation& operation, const Model& model } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsLogSoftmaxSupported, data.m_Backends, isSupported, + setBackend, input.GetTensorInfo(), outputInfo, descriptor); @@ -2834,6 +2922,7 @@ bool Converter::ConvertLogSoftmax(const Operation& operation, const Model& model } IConnectableLayer* layer = data.m_Network->AddLogSoftmaxLayer(descriptor); + layer->SetBackendId(setBackend); if (!layer) { return Fail("%s: AddLogSoftmaxLayer() returned nullptr", __func__); @@ -3193,12 +3282,14 @@ bool Converter::ConvertLstm(const Operation& operation, const Model& model, Conv } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsLstmSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputStateInInfo, cellStateInInfo, @@ -3231,6 +3322,7 @@ bool Converter::ConvertLstm(const Operation& operation, const Model& model, Conv // Add the layer IConnectableLayer* layer = data.m_Network->AddLstmLayer(desc, params, "Lstm"); + layer->SetBackendId(setBackend); input.Connect(layer->GetInputSlot(0)); outputStateIn.Connect(layer->GetInputSlot(1)); @@ -3283,12 +3375,14 @@ bool Converter::ConvertMaximum(const Operation& operation, const Model& model, C const TensorInfo& outInfo = GetTensorInfoForOperand(*outputOperand); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsMaximumSupported, data.m_Backends, isSupported, + setBackend, input0.GetTensorInfo(), input1.GetTensorInfo(), outInfo); @@ -3309,6 +3403,7 @@ bool Converter::ConvertMaximum(const Operation& operation, const Model& model, C } IConnectableLayer* layer = data.m_Network->AddMaximumLayer(); + layer->SetBackendId(setBackend); assert(layer != nullptr); bool isReshapeSupported = BroadcastTensor(input0, input1, layer, data); if (!isReshapeSupported) @@ -3370,12 +3465,14 @@ bool Converter::ConvertMean(const Operation& operation, const Model& model, Conv descriptor.m_KeepDims = keepDims > 0; bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsMeanSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, descriptor); @@ -3396,6 +3493,7 @@ bool Converter::ConvertMean(const Operation& operation, const Model& model, Conv } armnn::IConnectableLayer* const layer = data.m_Network->AddMeanLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -3423,12 +3521,14 @@ bool Converter::ConvertMinimum(const Operation& operation, const Model& model, C const TensorInfo& outputInfo = GetTensorInfoForOperand(*output); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsMinimumSupported, data.m_Backends, isSupported, + setBackend, input0.GetTensorInfo(), input1.GetTensorInfo(), outputInfo); @@ -3449,6 +3549,7 @@ bool Converter::ConvertMinimum(const Operation& operation, const Model& model, C } IConnectableLayer* const layer = data.m_Network->AddMinimumLayer(); + layer->SetBackendId(setBackend); assert(layer != nullptr); bool isReshapeSupported = BroadcastTensor(input0, input1, layer, data); if (!isReshapeSupported) @@ -3489,12 +3590,14 @@ bool Converter::ConvertMul(const Operation& operation, const Model& model, Conve const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*outputOperand); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsMultiplicationSupported, data.m_Backends, isSupported, + setBackend, input0.GetTensorInfo(), input1.GetTensorInfo(), outputInfo); @@ -3515,6 +3618,7 @@ bool Converter::ConvertMul(const Operation& operation, const Model& model, Conve } armnn::IConnectableLayer* const startLayer = data.m_Network->AddMultiplicationLayer(); + startLayer->SetBackendId(setBackend); bool isReshapeSupported = BroadcastTensor(input0, input1, startLayer, data); if (!isReshapeSupported) @@ -3564,12 +3668,14 @@ bool Converter::ConvertPad(const Operation& operation, const Model& model, Conve const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*output); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsPadSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, descriptor); @@ -3590,6 +3696,7 @@ bool Converter::ConvertPad(const Operation& operation, const Model& model, Conve } armnn::IConnectableLayer* const layer = data.m_Network->AddPadLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -3666,12 +3773,14 @@ bool Converter::ConvertPadV2(const Operation& operation, const Model& model, Con } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsPadSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, descriptor); @@ -3692,6 +3801,7 @@ bool Converter::ConvertPadV2(const Operation& operation, const Model& model, Con } IConnectableLayer* const layer = data.m_Network->AddPadLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -3722,12 +3832,14 @@ bool Converter::ConvertPrelu(const Operation& operation, const Model& model, Con const TensorInfo& outputInfo = GetTensorInfoForOperand(*output); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsPreluSupported, data.m_Backends, isSupported, + setBackend, inputInfo, alphaInfo, outputInfo); @@ -3748,6 +3860,7 @@ bool Converter::ConvertPrelu(const Operation& operation, const Model& model, Con } IConnectableLayer* const layer = data.m_Network->AddPreluLayer(); + layer->SetBackendId(setBackend); if (!layer) { @@ -3782,12 +3895,14 @@ bool Converter::ConvertQuantize(const Operation& operation, const Model& model, const TensorInfo& outputInfo = GetTensorInfoForOperand(*outputOperand); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsQuantizeSupported, data.m_Backends, isSupported, + setBackend, input.GetTensorInfo(), outputInfo); }; @@ -3807,6 +3922,7 @@ bool Converter::ConvertQuantize(const Operation& operation, const Model& model, } IConnectableLayer* const layer = data.m_Network->AddQuantizeLayer(); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -4259,12 +4375,14 @@ bool Converter::ConvertQuantizedLstm(const Operation& operation, const Model& mo // Check if the layer is supported bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& cellStateOutInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsQLstmSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputStatePrevTimeStepInfo, cellStatePrevTimeStepInfo, @@ -4295,6 +4413,7 @@ bool Converter::ConvertQuantizedLstm(const Operation& operation, const Model& mo // Add the layer IConnectableLayer* layer = data.m_Network->AddQLstmLayer(desc, params, "QLstm"); + layer->SetBackendId(setBackend); input.Connect(layer->GetInputSlot(0)); outputStatePrevTimeStep.Connect(layer->GetInputSlot(1)); @@ -4502,12 +4621,14 @@ bool Converter::ConvertQuantized16BitLstm(const Operation& operation, const Mode paramsInfo.m_OutputGateBias = &(params.m_OutputGateBias->GetInfo()); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsQuantizedLstmSupported, data.m_Backends, isSupported, + setBackend, inputInfo, previousCellStateInInfo, previousOutputInInfo, @@ -4534,6 +4655,7 @@ bool Converter::ConvertQuantized16BitLstm(const Operation& operation, const Mode } IConnectableLayer* const layer = data.m_Network->AddQuantizedLstmLayer(params, "QuantizedLstm"); + layer->SetBackendId(setBackend); input.Connect(layer->GetInputSlot(0)); previousCellStateIn.Connect(layer->GetInputSlot(1)); previousOutputIn.Connect(layer->GetInputSlot(2)); @@ -4580,10 +4702,12 @@ bool Converter::ConvertRank(const Operation& operation, const Model& model, Conv } bool isSupported = false; + armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC(__func__, IsRankSupported, data.m_Backends, isSupported, + setBackend, input.GetTensorInfo(), outInfo); if (!isSupported) @@ -4592,6 +4716,7 @@ bool Converter::ConvertRank(const Operation& operation, const Model& model, Conv } armnn::IConnectableLayer* layer = data.m_Network->AddRankLayer(); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -4620,13 +4745,14 @@ bool Converter::ConvertReLu(const Operation& operation, const Model& model, Conv const armnn::TensorInfo& outInfo = GetTensorInfoForOperand(*outputOperand); bool isSupported = false; - + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsActivationSupported, data.m_Backends, isSupported, + setBackend, input.GetTensorInfo(), outInfo, desc); @@ -4647,6 +4773,7 @@ bool Converter::ConvertReLu(const Operation& operation, const Model& model, Conv } armnn::IConnectableLayer* layer = data.m_Network->AddActivationLayer(desc); + layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -4724,12 +4851,14 @@ bool Converter::ConvertReshape(const Operation& operation, const Model& model, C const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*outputOperand); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsReshapeSupported, data.m_Backends, isSupported, + setBackend, input.GetTensorInfo(), outputInfo, reshapeDescriptor); @@ -4750,6 +4879,7 @@ bool Converter::ConvertReshape(const Operation& operation, const Model& model, C } armnn::IConnectableLayer* layer = data.m_Network->AddReshapeLayer(reshapeDescriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -4868,12 +4998,14 @@ bool Converter::ConvertResize(const Operation& operation, descriptor.m_HalfPixelCenters = GetOptionalBool(operation, 5, model, data); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsResizeSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, descriptor); @@ -4894,6 +5026,7 @@ bool Converter::ConvertResize(const Operation& operation, } IConnectableLayer* layer = data.m_Network->AddResizeLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -4982,12 +5115,14 @@ bool Converter::ConvertSpaceToBatchNd(const Operation& operation, const Model& m } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo &outputInfo, bool &isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsSpaceToBatchNdSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, descriptor); @@ -5007,6 +5142,7 @@ bool Converter::ConvertSpaceToBatchNd(const Operation& operation, const Model& m } armnn::IConnectableLayer *const layer = data.m_Network->AddSpaceToBatchNdLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -5050,12 +5186,14 @@ bool Converter::ConvertSpaceToDepth(const Operation& operation, const Model& mod desc.m_DataLayout = OptionalDataLayout(operation, 2, model, data); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsSpaceToDepthSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, desc); @@ -5076,6 +5214,7 @@ bool Converter::ConvertSpaceToDepth(const Operation& operation, const Model& mod } IConnectableLayer* const layer = data.m_Network->AddSpaceToDepthLayer(desc); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -5134,12 +5273,14 @@ bool Converter::ConvertSoftmax(const Operation& operation, const Model& model, C } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsSoftmaxSupported, data.m_Backends, isSupported, + setBackend, input.GetTensorInfo(), outputInfo, desc); @@ -5160,6 +5301,7 @@ bool Converter::ConvertSoftmax(const Operation& operation, const Model& model, C } IConnectableLayer* layer = data.m_Network->AddSoftmaxLayer(desc); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -5195,12 +5337,14 @@ bool Converter::ConvertSub(const Operation& operation, const Model& model, Conve const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*output); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsSubtractionSupported, data.m_Backends, isSupported, + setBackend, input0.GetTensorInfo(), input1.GetTensorInfo(), outputInfo); @@ -5221,6 +5365,7 @@ bool Converter::ConvertSub(const Operation& operation, const Model& model, Conve } armnn::IConnectableLayer* const startLayer = data.m_Network->AddSubtractionLayer(); + startLayer->SetBackendId(setBackend); bool isReshapeSupported = BroadcastTensor(input0, input1, startLayer, data); if (!isReshapeSupported) @@ -5413,12 +5558,14 @@ bool Converter::ConvertTransposeConv2d(const Operation& operation, const Model& Optional biases(bias.GetInfo()); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsTransposeConvolution2dSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, desc, @@ -5441,6 +5588,7 @@ bool Converter::ConvertTransposeConv2d(const Operation& operation, const Model& IConnectableLayer* startLayer = data.m_Network->AddTransposeConvolution2dLayer(desc, weights, Optional(bias)); + startLayer->SetBackendId(setBackend); if (!startLayer) { return Fail("%s: AddTransposeConvolution2dLayer failed", __func__); @@ -5526,10 +5674,12 @@ bool Converter::ConvertSqueeze(const Operation& operation, const Model& model, C reshapeDesc.m_TargetShape = outputInfo.GetShape(); bool isSupported = false; + armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC(__func__, IsReshapeSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, reshapeDesc); @@ -5540,6 +5690,7 @@ bool Converter::ConvertSqueeze(const Operation& operation, const Model& model, C } armnn::IConnectableLayer* const layer = data.m_Network->AddReshapeLayer(reshapeDesc); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -5623,12 +5774,14 @@ bool Converter::ConvertStridedSlice(const Operation& operation, const Model& mod } bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsStridedSliceSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, descriptor); @@ -5672,6 +5825,7 @@ bool Converter::ConvertStridedSlice(const Operation& operation, const Model& mod } armnn::IConnectableLayer* const layer = data.m_Network->AddStridedSliceLayer(descriptor); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); @@ -5726,12 +5880,14 @@ bool Converter::ConvertTranspose(const Operation& operation, const Model& model, const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*output); bool isSupported = false; + armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, IsTransposeSupported, data.m_Backends, isSupported, + setBackend, inputInfo, outputInfo, transposeDesc); @@ -5752,6 +5908,7 @@ bool Converter::ConvertTranspose(const Operation& operation, const Model& model, } armnn::IConnectableLayer* const layer = data.m_Network->AddTransposeLayer(transposeDesc); + layer->SetBackendId(setBackend); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); diff --git a/src/armnn/Layer.hpp b/src/armnn/Layer.hpp index b144c78889..aab5227b75 100644 --- a/src/armnn/Layer.hpp +++ b/src/armnn/Layer.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2017,2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once @@ -275,7 +275,7 @@ public: DataType GetDataType() const; const BackendId& GetBackendId() const { return m_BackendId; } - void SetBackendId(const BackendId& id) { m_BackendId = id; } + void SetBackendId(const BackendId& id) override { m_BackendId = id; } // Virtuals diff --git a/src/armnn/Network.cpp b/src/armnn/Network.cpp index 6d3058c670..a61624fb0a 100644 --- a/src/armnn/Network.cpp +++ b/src/armnn/Network.cpp @@ -12,6 +12,7 @@ #include "BackendSettings.hpp" #include "optimizations/All.hpp" #include "armnnUtils/Filesystem.hpp" +#include "armnn/utility/Timer.hpp" #include #include @@ -766,6 +767,15 @@ OptimizationResult AttemptBackendAssignment(BackendSettings& backendSettings, } } +inline std::vector GetLayerInOutDatatype(const Layer* layer) +{ + DataType dataTypeIn = layer->GetNumInputSlots() == 0 ? DataType::Float32 : + layer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo().GetDataType(); + DataType dataTypeOut = layer->GetNumOutputSlots() == 0 ? DataType::Float32 : + layer->GetOutputSlot(0).GetTensorInfo().GetDataType(); + return {dataTypeIn, dataTypeOut}; +} + // Refactor to allow passing the IConnectableLayer* rather than Layer Iterator // on Graph and SubgraphView which are different types. void AssignBackendsIConnectable(OptimizedNetworkImpl* optNetObjPtr, @@ -787,10 +797,7 @@ void AssignBackendsIConnectable(OptimizedNetworkImpl* optNetObjPtr, return; } - DataType dataTypeIn = layer->GetNumInputSlots() == 0 ? DataType::Float32 : - layer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo().GetDataType(); - DataType dataTypeOut = layer->GetNumOutputSlots() == 0 ? DataType::Float32 : - layer->GetOutputSlot(0).GetTensorInfo().GetDataType(); + std::vector inOutDataType = GetLayerInOutDatatype(layer); std::string reasonIfUnsupported; bool found = false; @@ -808,8 +815,8 @@ void AssignBackendsIConnectable(OptimizedNetworkImpl* optNetObjPtr, optNetObjPtr->GetGraph(), layer, layer->GetBackendHint().value(), - dataTypeIn, - dataTypeOut, + inOutDataType[0], + inOutDataType[1], availablePreferredBackends, reasonIfUnsupported, errMessages).IsOk()) @@ -832,8 +839,8 @@ void AssignBackendsIConnectable(OptimizedNetworkImpl* optNetObjPtr, optNetObjPtr->GetGraph(), layer, backend, - dataTypeIn, - dataTypeOut, + inOutDataType[0], + inOutDataType[1], availablePreferredBackends, reasonIfUnsupported, errMessages); @@ -903,12 +910,33 @@ OptimizationResult AssignBackends(OptimizedNetworkImpl* optNetObjPtr, for (auto it = firstLayer; it != lastLayer; ++it) { - AssignBackendsIConnectable(optNetObjPtr, - *it, - errMessages, - result, - backendSettings, - availablePreferredBackends); + auto layer = PolymorphicDowncast(*it); + std::vector inOutDataType = GetLayerInOutDatatype(layer); + + // In AttemptBackendAssignment() we check: + // - if input/output datatypes of the layer are float16 + // - if the layer is supported with these datatypes + // If the layer is not supported (failing on ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED() in clframework), + // we attempt to insert convertion layers either side of the new fp32 layer. + bool isFloat16 = false; + for (auto type : inOutDataType) + { + if (type == DataType::Float16) + { + isFloat16 = true; + break; + } + } + + if (layer->GetBackendId() == "Unknown" || isFloat16) + { + AssignBackendsIConnectable(optNetObjPtr, + *it, + errMessages, + result, + backendSettings, + availablePreferredBackends); + } } for (auto it = firstLayer; it != lastLayer; ++it) @@ -1540,6 +1568,8 @@ IOptimizedNetworkPtr Optimize(const Graph& inGraph, const OptimizerOptions& options, Optional&> messages) { + const auto start_time = armnn::GetTimeNow(); + ARMNN_LOG(debug) << options.ToString(); // Enable profiling @@ -1723,6 +1753,9 @@ IOptimizedNetworkPtr Optimize(const Graph& inGraph, optGraph.AddCompatibilityLayers(backends, tensorHandleFactoryRegistry); } + ARMNN_LOG(info) << "!! New time !! : " << std::setprecision(2) + << std::fixed << armnn::GetTimeDuration(start_time).count() << " ms."; + return optNet; } -- cgit v1.2.1