1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 #include "tensorflow/lite/c/builtin_op_data.h"
16 #include "tensorflow/lite/c/common.h"
17 #include "tensorflow/lite/kernels/internal/optimized/optimized_ops.h"
18 #include "tensorflow/lite/kernels/internal/reference/reference_ops.h"
19 #include "tensorflow/lite/kernels/internal/tensor.h"
20 #include "tensorflow/lite/kernels/internal/tensor_ctypes.h"
21 #include "tensorflow/lite/kernels/internal/types.h"
22 #include "tensorflow/lite/kernels/kernel_util.h"
23
24 namespace tflite {
25 namespace ops {
26 namespace builtin {
27 namespace local_response_norm {
28
29 // This file has two implementation of LocalResponseNorm.
30 enum KernelType {
31 kReference,
32 kGenericOptimized,
33 };
34
35 constexpr int kInputTensor = 0;
36 constexpr int kOutputTensor = 0;
37
Prepare(TfLiteContext * context,TfLiteNode * node)38 TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) {
39 TF_LITE_ENSURE_EQ(context, NumInputs(node), 1);
40 TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1);
41
42 const TfLiteTensor* input;
43 TF_LITE_ENSURE_OK(context, GetInputSafe(context, node, kInputTensor, &input));
44 TfLiteTensor* output;
45 TF_LITE_ENSURE_OK(context,
46 GetOutputSafe(context, node, kOutputTensor, &output));
47
48 TF_LITE_ENSURE_EQ(context, NumDimensions(input), 4);
49
50 TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteFloat32);
51 TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type);
52
53 TfLiteIntArray* output_size = TfLiteIntArrayCreate(4);
54 output_size->data[0] = input->dims->data[0];
55 output_size->data[1] = input->dims->data[1];
56 output_size->data[2] = input->dims->data[2];
57 output_size->data[3] = input->dims->data[3];
58
59 return context->ResizeTensor(context, output, output_size);
60 }
61
62 template <KernelType kernel_type>
Eval(TfLiteContext * context,TfLiteNode * node)63 TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) {
64 auto* params =
65 reinterpret_cast<TfLiteLocalResponseNormParams*>(node->builtin_data);
66
67 const TfLiteTensor* input;
68 TF_LITE_ENSURE_OK(context, GetInputSafe(context, node, kInputTensor, &input));
69 TfLiteTensor* output;
70 TF_LITE_ENSURE_OK(context,
71 GetOutputSafe(context, node, kOutputTensor, &output));
72
73 if (output->type == kTfLiteFloat32) {
74 #define TF_LITE_LOCAL_RESPONSE_NORM(type) \
75 tflite::LocalResponseNormalizationParams op_params; \
76 op_params.range = params->radius; \
77 op_params.bias = params->bias; \
78 op_params.alpha = params->alpha; \
79 op_params.beta = params->beta; \
80 type::LocalResponseNormalization( \
81 op_params, GetTensorShape(input), GetTensorData<float>(input), \
82 GetTensorShape(output), GetTensorData<float>(output))
83 if (kernel_type == kReference) {
84 TF_LITE_LOCAL_RESPONSE_NORM(reference_ops);
85 }
86 if (kernel_type == kGenericOptimized) {
87 TF_LITE_LOCAL_RESPONSE_NORM(optimized_ops);
88 }
89 #undef TF_LITE_LOCAL_RESPONSE_NORM
90 } else {
91 context->ReportError(context, "Output type is %d, requires float.",
92 output->type);
93 return kTfLiteError;
94 }
95
96 return kTfLiteOk;
97 }
98
99 } // namespace local_response_norm
100
Register_LOCAL_RESPONSE_NORM_REF()101 TfLiteRegistration* Register_LOCAL_RESPONSE_NORM_REF() {
102 static TfLiteRegistration r = {
103 nullptr, nullptr, local_response_norm::Prepare,
104 local_response_norm::Eval<local_response_norm::kReference>};
105 return &r;
106 }
107
Register_LOCAL_RESPONSE_NORM_GENERIC_OPT()108 TfLiteRegistration* Register_LOCAL_RESPONSE_NORM_GENERIC_OPT() {
109 static TfLiteRegistration r = {
110 nullptr, nullptr, local_response_norm::Prepare,
111 local_response_norm::Eval<local_response_norm::kGenericOptimized>};
112 return &r;
113 }
114
Register_LOCAL_RESPONSE_NORMALIZATION()115 TfLiteRegistration* Register_LOCAL_RESPONSE_NORMALIZATION() {
116 return Register_LOCAL_RESPONSE_NORM_GENERIC_OPT();
117 }
118
119 } // namespace builtin
120 } // namespace ops
121 } // namespace tflite
122