blob: 562ce1fd9f0a2786d0eccedd952717d29cea1b82 [file] [log] [blame]
Sadik Armagan62483be2020-10-23 17:14:43 +01001//
Ryan OShea4c231de2023-01-17 15:19:20 +00002// Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved.
Sadik Armagan62483be2020-10-23 17:14:43 +01003// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Teresa Charlinad1b3d72023-03-14 12:10:28 +00008#include <DelegateUtils.hpp>
Sadik Armagan62483be2020-10-23 17:14:43 +01009
10#include <armnn/utility/Assert.hpp>
11
12#include <tensorflow/lite/builtin_ops.h>
13#include <tensorflow/lite/c/builtin_op_data.h>
14#include <tensorflow/lite/c/common.h>
15#include <tensorflow/lite/minimal_logging.h>
16
17namespace armnnDelegate
18{
19
20TfLiteStatus VisitElementwiseUnaryOperator(DelegateData& delegateData,
21 TfLiteContext* tfLiteContext,
22 TfLiteNode* tfLiteNode,
23 int nodeIndex,
24 armnn::UnaryOperation unaryOperation)
25{
26 TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex));
27 TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex));
28
29 const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors;
30 const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]];
31 if (IsDynamicTensor(tfLiteInputTensor))
32 {
33 TF_LITE_MAYBE_KERNEL_LOG(
34 tfLiteContext,
35 "TfLiteArmnnDelegate: Dynamic input tensors are not supported in node #%d: ",
36 nodeIndex);
37 return kTfLiteError;
38 }
39 const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]];
40 if (IsDynamicTensor(tfLiteOutputTensor))
41 {
42 TF_LITE_MAYBE_KERNEL_LOG(
43 tfLiteContext,
44 "TfLiteArmnnDelegate: Dynamic output tensors are not supported in node #%d: ",
45 nodeIndex);
46 return kTfLiteError;
47 }
48
49 const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor);
Sadik Armagan90a119b2022-08-05 16:12:49 +010050 const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true);
Sadik Armagan62483be2020-10-23 17:14:43 +010051
52 armnn::ElementwiseUnaryDescriptor descriptor(unaryOperation);
53 bool isSupported = false;
Cathal Corbett53837672022-09-01 11:34:37 +010054 armnn::BackendId setBackend;
Sadik Armagan62483be2020-10-23 17:14:43 +010055 auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported)
56 {
Sadik Armaganbfa767c2022-02-09 14:58:03 +000057 FORWARD_LAYER_SUPPORT_FUNC("ELEMENTWISE_UNARY",
Sadik Armagan62483be2020-10-23 17:14:43 +010058 tfLiteContext,
59 IsElementwiseUnarySupported,
60 delegateData.m_Backends,
61 isSupported,
Cathal Corbett53837672022-09-01 11:34:37 +010062 setBackend,
Sadik Armagan62483be2020-10-23 17:14:43 +010063 inputTensorInfo,
64 outputTensorInfo,
65 descriptor);
66 };
67
68 if (!delegateData.m_Network)
69 {
70 validateFunc(outputTensorInfo, isSupported);
71 return isSupported ? kTfLiteOk : kTfLiteError;
72 }
73
74 armnn::IConnectableLayer* layer = delegateData.m_Network->AddElementwiseUnaryLayer(descriptor);
Cathal Corbett53837672022-09-01 11:34:37 +010075 layer->SetBackendId(setBackend);
Sadik Armagan62483be2020-10-23 17:14:43 +010076 ARMNN_ASSERT(layer != nullptr);
77
78 armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0);
79 outputSlot.SetTensorInfo(outputTensorInfo);
80
Ryan OShea4c231de2023-01-17 15:19:20 +000081 // try to connect the Constant Inputs if there are any
82 if(ProcessInputs(layer,delegateData, tfLiteContext, tfLiteNode) != kTfLiteOk )
83 {
84 return kTfLiteError;
85 }
86
Sadik Armagan62483be2020-10-23 17:14:43 +010087 // Connect
Sadik Armagan67e95f22020-10-29 16:14:54 +000088 return Connect(layer, tfLiteNode, delegateData);
Sadik Armagan62483be2020-10-23 17:14:43 +010089}
90
91} // namespace armnnDelegate