1 /* Copyright 2021 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
16 #include "tensorflow/lite/c/builtin_op_data.h"
17 #include "tensorflow/lite/c/common.h"
18 #include "tensorflow/lite/micro/all_ops_resolver.h"
19 #include "tensorflow/lite/micro/kernels/kernel_runner.h"
20 #include "tensorflow/lite/micro/test_helpers.h"
21 #include "tensorflow/lite/micro/testing/micro_test.h"
22
23 namespace tflite {
24 namespace testing {
25 namespace {
26
TestReluFloat(int * input_dims_data,const float * input_data,int * output_dims_data,const float * golden,float * output_data)27 void TestReluFloat(int* input_dims_data, const float* input_data,
28 int* output_dims_data, const float* golden,
29 float* output_data) {
30 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
31 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
32 const int output_elements_count = ElementCount(*output_dims);
33
34 constexpr int inputs_size = 1;
35 constexpr int outputs_size = 1;
36 constexpr int tensors_size = inputs_size + outputs_size;
37 TfLiteTensor tensors[tensors_size] = {
38 CreateTensor(input_data, input_dims),
39 CreateTensor(output_data, output_dims),
40 };
41
42 int inputs_array_data[] = {1, 0};
43 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
44 int outputs_array_data[] = {1, 1};
45 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
46
47 const TfLiteRegistration registration = Register_RELU();
48 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
49 outputs_array,
50 /*builtin_data=*/nullptr);
51
52 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
53 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
54
55 for (int i = 0; i < output_elements_count; ++i) {
56 TF_LITE_MICRO_EXPECT_NEAR(golden[i], output_data[i], 1e-5f);
57 }
58 }
59
TestRelu6Float(int * input_dims_data,const float * input_data,int * output_dims_data,const float * golden,float * output_data)60 void TestRelu6Float(int* input_dims_data, const float* input_data,
61 int* output_dims_data, const float* golden,
62 float* output_data) {
63 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
64 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
65 const int output_elements_count = ElementCount(*output_dims);
66
67 constexpr int inputs_size = 1;
68 constexpr int outputs_size = 1;
69 constexpr int tensors_size = inputs_size + outputs_size;
70 TfLiteTensor tensors[tensors_size] = {
71 CreateTensor(input_data, input_dims),
72 CreateTensor(output_data, output_dims),
73 };
74
75 int inputs_array_data[] = {1, 0};
76 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
77 int outputs_array_data[] = {1, 1};
78 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
79
80 const TfLiteRegistration registration = Register_RELU6();
81 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
82 outputs_array,
83 /*builtin_data=*/nullptr);
84
85 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
86 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
87
88 for (int i = 0; i < output_elements_count; ++i) {
89 TF_LITE_MICRO_EXPECT_NEAR(golden[i], output_data[i], 1e-5f);
90 }
91 }
92
TestReluInt8(int * input_dims_data,const float * input_data,int8_t * input_data_quantized,const float input_scale,const int input_zero_point,const float * golden,int8_t * golden_quantized,int * output_dims_data,const float output_scale,const int output_zero_point,int8_t * output_data)93 void TestReluInt8(int* input_dims_data, const float* input_data,
94 int8_t* input_data_quantized, const float input_scale,
95 const int input_zero_point, const float* golden,
96 int8_t* golden_quantized, int* output_dims_data,
97 const float output_scale, const int output_zero_point,
98 int8_t* output_data) {
99 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
100 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
101 const int output_elements_count = ElementCount(*output_dims);
102 constexpr int inputs_size = 1;
103 constexpr int outputs_size = 1;
104 constexpr int tensors_size = inputs_size + outputs_size;
105 TfLiteTensor tensors[tensors_size] = {
106 CreateQuantizedTensor(input_data, input_data_quantized, input_dims,
107 input_scale, input_zero_point),
108 CreateQuantizedTensor(output_data, output_dims, output_scale,
109 output_zero_point),
110 };
111
112 int inputs_array_data[] = {1, 0};
113 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
114 int outputs_array_data[] = {1, 1};
115 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
116
117 const TfLiteRegistration registration = Register_RELU();
118 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
119 outputs_array,
120 /*builtin_data=*/nullptr);
121
122 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
123 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
124
125 Quantize(golden, golden_quantized, output_elements_count, output_scale,
126 output_zero_point);
127
128 for (int i = 0; i < output_elements_count; ++i) {
129 TF_LITE_MICRO_EXPECT_EQ(golden_quantized[i], output_data[i]);
130 }
131 }
132
TestRelu6Int8(int * input_dims_data,const float * input_data,int8_t * input_data_quantized,const float input_scale,const int input_zero_point,const float * golden,int8_t * golden_quantized,int * output_dims_data,const float output_scale,const int output_zero_point,int8_t * output_data)133 void TestRelu6Int8(int* input_dims_data, const float* input_data,
134 int8_t* input_data_quantized, const float input_scale,
135 const int input_zero_point, const float* golden,
136 int8_t* golden_quantized, int* output_dims_data,
137 const float output_scale, const int output_zero_point,
138 int8_t* output_data) {
139 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
140 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
141 const int output_elements_count = ElementCount(*output_dims);
142 constexpr int inputs_size = 1;
143 constexpr int outputs_size = 1;
144 constexpr int tensors_size = inputs_size + outputs_size;
145 TfLiteTensor tensors[tensors_size] = {
146 CreateQuantizedTensor(input_data, input_data_quantized, input_dims,
147 input_scale, input_zero_point),
148 CreateQuantizedTensor(output_data, output_dims, output_scale,
149 output_zero_point),
150 };
151
152 int inputs_array_data[] = {1, 0};
153 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
154 int outputs_array_data[] = {1, 1};
155 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
156
157 const TfLiteRegistration registration = Register_RELU6();
158 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
159 outputs_array,
160 /*builtin_data=*/nullptr);
161
162 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
163 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
164
165 Quantize(golden, golden_quantized, output_elements_count, output_scale,
166 output_zero_point);
167
168 for (int i = 0; i < output_elements_count; ++i) {
169 TF_LITE_MICRO_EXPECT_EQ(golden_quantized[i], output_data[i]);
170 }
171 }
172
173 } // namespace
174 } // namespace testing
175 } // namespace tflite
176
177 TF_LITE_MICRO_TESTS_BEGIN
178
TF_LITE_MICRO_TEST(SimpleReluTestFloat)179 TF_LITE_MICRO_TEST(SimpleReluTestFloat) {
180 const int output_elements_count = 10;
181 int input_shape[] = {2, 1, 5};
182 const float input_data[] = {
183 1.0, 2.0, 3.0, 4.0, 5.0, -1.0, -2.0, -3.0, -4.0, -5.0,
184 };
185 const float golden[] = {1.0, 2.0, 3.0, 4.0, 5.0, 0, 0, 0, 0, 0};
186 int output_shape[] = {2, 1, 5};
187 float output_data[output_elements_count];
188 tflite::testing::TestReluFloat(input_shape, input_data, output_shape, golden,
189 output_data);
190 }
191
TF_LITE_MICRO_TEST(SimpleRelu6TestFloat)192 TF_LITE_MICRO_TEST(SimpleRelu6TestFloat) {
193 const int output_elements_count = 10;
194 float output_data[output_elements_count];
195 int input_shape[] = {2, 1, 5};
196 const float input_data[] = {4.0, 5.0, 6.0, 7.0, 8.0,
197 -4.0, -5.0, -6.0, -7.0, -8.0};
198 int output_shape[] = {2, 1, 5};
199 const float golden[] = {
200 4.0, 5.0, 6.0, 6.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0,
201 };
202
203 tflite::testing::TestRelu6Float(input_shape, input_data, output_shape, golden,
204 output_data);
205 }
206
TF_LITE_MICRO_TEST(SimpleReluTestInt8)207 TF_LITE_MICRO_TEST(SimpleReluTestInt8) {
208 const int elements_count = 10;
209
210 int input_shape[] = {2, 1, 5};
211 const float input_data[] = {1, 2, 3, 4, 5, -1, -2, -3, -4, -5};
212 int8_t input_quantized[elements_count];
213 int output_shape[] = {2, 1, 5};
214 const float golden[] = {1, 2, 3, 4, 5, 0, 0, 0, 0, 0};
215 int8_t golden_quantized[elements_count];
216 int8_t output_data[elements_count];
217
218 const float input_scale = 0.5f;
219 const int input_zero_point = 0;
220 const float output_scale = 0.5f;
221 const int output_zero_point = 0;
222
223 tflite::testing::TestReluInt8(input_shape, input_data, input_quantized,
224 input_scale, input_zero_point, golden,
225 golden_quantized, output_shape, output_scale,
226 output_zero_point, output_data);
227 }
228
TF_LITE_MICRO_TEST(SimpleRelu6TestInt8)229 TF_LITE_MICRO_TEST(SimpleRelu6TestInt8) {
230 const int elements_count = 10;
231
232 int input_shape[] = {2, 1, 5};
233 const float input_data[] = {4, 5, 6, 7, 8, -1, -2, -3, -4, -5};
234 int8_t input_quantized[elements_count];
235 int output_shape[] = {2, 1, 5};
236 const float golden[] = {4, 5, 6, 6, 6, 0, 0, 0, 0, 0};
237 int8_t golden_quantized[elements_count];
238 int8_t output_data[elements_count];
239
240 const float input_scale = 0.5f;
241 const int input_zero_point = 127;
242 const float output_scale = 0.5f;
243 const int output_zero_point = 127;
244
245 tflite::testing::TestRelu6Int8(input_shape, input_data, input_quantized,
246 input_scale, input_zero_point, golden,
247 golden_quantized, output_shape, output_scale,
248 output_zero_point, output_data);
249 }
250
251 TF_LITE_MICRO_TESTS_END
252