From 05e9fd2f00fcd17b7103c02be06e305076739e15 Mon Sep 17 00:00:00 2001 From: Sadik Armagan Date: Tue, 17 Nov 2020 12:01:47 +0000 Subject: IVGCVSW-5539 'Elementwise layers with const tensors are not connecting up' * Added Constant Input support to ElementwiseBinary Layers Signed-off-by: Sadik Armagan Change-Id: I1d429fd7958fe2aa53f06c229a863243569c0d71 --- delegate/src/DelegateUtils.hpp | 47 ++++++++++++++++++++++++++++++++++++-- delegate/src/ElementwiseBinary.hpp | 37 ++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 6 deletions(-) diff --git a/delegate/src/DelegateUtils.hpp b/delegate/src/DelegateUtils.hpp index e9f579b699..0537ba911b 100644 --- a/delegate/src/DelegateUtils.hpp +++ b/delegate/src/DelegateUtils.hpp @@ -17,6 +17,8 @@ #include #include +#include "tensorflow/lite/kernels/kernel_util.h" + namespace { @@ -365,8 +367,20 @@ armnn::TensorInfo GetTensorInfoForTfLiteTensor(const TfLiteTensor& tfLiteTensor, auto tensorDimensionSize = tfLiteTensor.dims->size; if (tensorDimensionSize == 0) { - armnn::TensorShape tensorShape(armnn::Dimensionality::NotSpecified); - ret = armnn::TensorInfo(tensorShape, type); + if(tflite::IsConstantTensor(&tfLiteTensor)) + { + std::vector safeShape = { 1 }; + bool dimensionsSpecificity[1] = { true }; + armnn::TensorShape tensorShape(armnn::numeric_cast(safeShape.size()), + safeShape.data(), + dimensionsSpecificity); + ret = armnn::TensorInfo(tensorShape, type); + } + else + { + armnn::TensorShape tensorShape(armnn::Dimensionality::NotSpecified); + ret = armnn::TensorInfo(tensorShape, type); + } } else { @@ -468,6 +482,35 @@ void CalcPadding(uint32_t inputSize, } } +TfLiteStatus ConnectConstant(armnn::IConnectableLayer* layer, + armnn::TensorInfo& constTensorInfo, + TfLiteContext* tfLiteContext, + const TfLiteTensor& tfLiteTensor, + armnnDelegate::DelegateData& data, + unsigned int slotIndex) +{ + bool isSupported = false; + FORWARD_LAYER_SUPPORT_FUNC(__func__, + tfLiteContext, + IsConstantSupported, + data.m_Backends, + isSupported, + constTensorInfo); + if (!isSupported) + { + return kTfLiteError; + } + + auto constantInput = CreateConstTensor(&tfLiteTensor, + constTensorInfo, + armnn::Optional()); + armnn::IConnectableLayer* constantLayer = data.m_Network->AddConstantLayer(constantInput); + armnn::IOutputSlot& outputSlot = constantLayer->GetOutputSlot(0); + outputSlot.SetTensorInfo(constTensorInfo); + + data.m_OutputSlotForNode[static_cast(slotIndex)] = &outputSlot; + return kTfLiteOk; +} } // namespace anonymous diff --git a/delegate/src/ElementwiseBinary.hpp b/delegate/src/ElementwiseBinary.hpp index 3d3f1a0799..e5270057f5 100644 --- a/delegate/src/ElementwiseBinary.hpp +++ b/delegate/src/ElementwiseBinary.hpp @@ -11,6 +11,7 @@ #include #include #include +#include "tensorflow/lite/delegates/utils.h" namespace armnnDelegate { @@ -193,8 +194,9 @@ TfLiteStatus VisitElementwiseBinaryOperator(DelegateData& delegateData, return kTfLiteError; } - const armnn::TensorInfo& inputTensorInfo0 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor0); - const armnn::TensorInfo& inputTensorInfo1 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor1); + armnn::TensorInfo inputTensorInfo0 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor0); + armnn::TensorInfo inputTensorInfo1 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor1); + const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor); if (!delegateData.m_Network) @@ -268,10 +270,37 @@ TfLiteStatus VisitElementwiseBinaryOperator(DelegateData& delegateData, return kTfLiteError; } ARMNN_ASSERT(elementwiseBinaryLayer != nullptr); - armnn::IOutputSlot& outputSlot = elementwiseBinaryLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); + if(tflite::IsConstantTensor(&tfLiteInputTensor0)) + { + auto status = ConnectConstant(elementwiseBinaryLayer, + inputTensorInfo0, + tfLiteContext, + tfLiteInputTensor0, + delegateData, + tfLiteNode->inputs->data[0]); + if (status == kTfLiteError) + { + return status; + } + } + + if(tflite::IsConstantTensor(&tfLiteInputTensor1)) + { + auto status = ConnectConstant(elementwiseBinaryLayer, + inputTensorInfo1, + tfLiteContext, + tfLiteInputTensor1, + delegateData, + tfLiteNode->inputs->data[1]); + if (status == kTfLiteError) + { + return status; + } + } + auto reshapeLayer = BroadcastTensor(inputTensorInfo0, inputTensorInfo1, elementwiseBinaryLayer, @@ -291,7 +320,7 @@ TfLiteStatus VisitElementwiseBinaryOperator(DelegateData& delegateData, } // Check activation TfLiteFusedActivation activationType = tfLiteNodeParameters->activation; - return FusedActivation(tfLiteContext, tfLiteNode, activationType, reshapeLayer, 0, delegateData); + return FusedActivation(tfLiteContext, tfLiteNode, activationType, elementwiseBinaryLayer, 0, delegateData); } } // namespace armnnDelegate -- cgit v1.2.1