// // Copyright © 2020 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitFillOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfLiteFillOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); switch(tfLiteFillOperatorCode) { case kTfLiteBuiltinFill: TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); break; default: return kTfLiteError; } const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteFillOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteFillTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteFillTensor, tfLiteFillOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteFillOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& fillTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteFillTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor); armnn::FillDescriptor descriptor; switch (tfLiteFillTensor.type) { case kTfLiteFloat32: descriptor.m_Value = tflite::GetTensorData(&tfLiteFillTensor)[0]; break; case kTfLiteInt32: descriptor.m_Value = tflite::GetTensorData(&tfLiteFillTensor)[0]; break; default: TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: FILL value data type is not supported in operator #%d node #%d: ", tfLiteFillOperatorCode, nodeIndex); return kTfLiteError; } bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC(__func__, tfLiteContext, IsFillSupported, delegateData.m_Backends, isSupported, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } armnn::IConnectableLayer* layer = delegateData.m_Network->AddFillLayer(descriptor); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); if(tflite::IsConstantTensor(&tfLiteInputTensor)) { auto status = ConnectConstant(layer, inputTensorInfo, tfLiteContext, tfLiteInputTensor, delegateData, tfLiteNode->inputs->data[0]); if (status == kTfLiteError) { return status; } } return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate