blob: 5ac92f88024fe2ca00210f60e25b2860fdfff6e8 [file] [log] [blame]
Sadik Armagan62483be2020-10-23 17:14:43 +01001//
2// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
David Monahan0cf84422020-11-16 15:53:03 +00008#include "DelegateUtils.hpp"
Finn Williams6f9f9902020-11-13 13:23:15 +00009
Sadik Armagan62483be2020-10-23 17:14:43 +010010#include <tensorflow/lite/builtin_ops.h>
11#include <tensorflow/lite/c/builtin_op_data.h>
12#include <tensorflow/lite/c/common.h>
13#include <tensorflow/lite/minimal_logging.h>
14
15namespace armnnDelegate
16{
17
David Monahan0cf84422020-11-16 15:53:03 +000018TfLiteStatus ValidateActivationOperator(DelegateData& delegateData,
19 TfLiteContext* tfLiteContext,
20 const armnn::TensorInfo& inputInfo,
21 const armnn::TensorInfo& outputInfo,
22 armnn::ActivationDescriptor& activationDesc)
23{
24 bool isSupported = false;
Keith Davis892fafe2020-11-26 17:40:35 +000025 auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported)
David Monahan0cf84422020-11-16 15:53:03 +000026 {
Sadik Armaganbfa767c2022-02-09 14:58:03 +000027 FORWARD_LAYER_SUPPORT_FUNC("ACTIVATION",
David Monahan0cf84422020-11-16 15:53:03 +000028 tfLiteContext,
29 IsActivationSupported,
30 delegateData.m_Backends,
31 isSupported,
32 inputInfo,
33 outputInfo,
34 activationDesc);
35 };
36
37 validateFunc(outputInfo, isSupported);
38 return isSupported ? kTfLiteOk : kTfLiteError;
39}
40
Sadik Armagan62483be2020-10-23 17:14:43 +010041TfLiteStatus VisitActivationOperator(DelegateData& delegateData,
42 TfLiteContext* tfLiteContext,
43 TfLiteNode* tfLiteNode,
44 int nodeIndex,
David Monahan0cf84422020-11-16 15:53:03 +000045 int32_t operatorCode)
Sadik Armagan62483be2020-10-23 17:14:43 +010046{
David Monahan0cf84422020-11-16 15:53:03 +000047 TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex));
48 TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex));
Finn Williams6f9f9902020-11-13 13:23:15 +000049
David Monahan0cf84422020-11-16 15:53:03 +000050 const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors;
51 const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]];
Matthew Sloyan7515d072020-12-16 12:50:01 +000052 if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex))
David Monahan0cf84422020-11-16 15:53:03 +000053 {
David Monahan0cf84422020-11-16 15:53:03 +000054 return kTfLiteError;
55 }
Matthew Sloyan7515d072020-12-16 12:50:01 +000056
David Monahan0cf84422020-11-16 15:53:03 +000057 const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]];
Matthew Sloyan7515d072020-12-16 12:50:01 +000058 if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex))
David Monahan0cf84422020-11-16 15:53:03 +000059 {
David Monahan0cf84422020-11-16 15:53:03 +000060 return kTfLiteError;
61 }
Finn Williams6f9f9902020-11-13 13:23:15 +000062
David Monahan0cf84422020-11-16 15:53:03 +000063 const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor);
64 const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor);
65
66 armnn::ActivationDescriptor activationDesc;
67 switch(operatorCode)
68 {
69 case kTfLiteBuiltinRelu:
70 {
71 activationDesc.m_Function = armnn::ActivationFunction::ReLu;
72 break;
73 }
74 case kTfLiteBuiltinRelu6:
75 {
76 activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu;
77 activationDesc.m_A = 6.0f;
78 break;
79 }
80 case kTfLiteBuiltinLogistic:
81 {
82 activationDesc.m_Function = armnn::ActivationFunction::Sigmoid;
83 break;
84 }
85 case kTfLiteBuiltinTanh:
86 {
87 activationDesc.m_Function = armnn::ActivationFunction::TanH;
88 activationDesc.m_A = 1.0f;
89 activationDesc.m_B = 1.0f;
90 break;
91 }
Matthew Sloyan7515d072020-12-16 12:50:01 +000092 case kTfLiteBuiltinElu:
93 {
94 activationDesc.m_Function = armnn::ActivationFunction::Elu;
95 activationDesc.m_A = 1.0f;
96 break;
97 }
98 case kTfLiteBuiltinHardSwish:
99 {
100 activationDesc.m_Function = armnn::ActivationFunction::HardSwish;
101 break;
102 }
David Monahan0cf84422020-11-16 15:53:03 +0000103 default:
104 {
105 return kTfLiteError;
106 }
107 }
108 if (!delegateData.m_Network)
109 {
110 return ValidateActivationOperator(delegateData,
111 tfLiteContext,
112 inputTensorInfo,
113 outputTensorInfo,
114 activationDesc);
115 }
116 armnn::IConnectableLayer* activationLayer = delegateData.m_Network->AddActivationLayer(activationDesc);
117 ARMNN_ASSERT(activationLayer != nullptr);
118
119 armnn::IOutputSlot& outputSlot = activationLayer->GetOutputSlot(0);
120 outputSlot.SetTensorInfo(outputTensorInfo);
121
122 // Connect
123 return Connect(activationLayer, tfLiteNode, delegateData);
Sadik Armagan62483be2020-10-23 17:14:43 +0100124}
125
126} // namespace armnnDelegate