1 /* Copyright 2019 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(const int * input_dims_data,const float * input_data,const int * output_dims_data,const float * golden,float * output_data)27 void TestReluFloat(const int* input_dims_data, const float* input_data,
28 const 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 = ops::micro::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(const int * input_dims_data,const float * input_data,const int * output_dims_data,const float * golden,float * output_data)60 void TestRelu6Float(const int* input_dims_data, const float* input_data,
61 const 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 = ops::micro::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
TestReluUint8(const int * input_dims_data,const float * input_data,uint8_t * input_data_quantized,const float input_scale,const int input_zero_point,const float * golden,uint8_t * golden_quantized,const int * output_dims_data,const float output_scale,const int output_zero_point,uint8_t * output_data)93 void TestReluUint8(const int* input_dims_data, const float* input_data,
94 uint8_t* input_data_quantized, const float input_scale,
95 const int input_zero_point, const float* golden,
96 uint8_t* golden_quantized, const int* output_dims_data,
97 const float output_scale, const int output_zero_point,
98 uint8_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
103 constexpr int inputs_size = 1;
104 constexpr int outputs_size = 1;
105 constexpr int tensors_size = inputs_size + outputs_size;
106 TfLiteTensor tensors[tensors_size] = {
107 CreateQuantizedTensor(input_data, input_data_quantized, input_dims,
108 input_scale, input_zero_point),
109 CreateQuantizedTensor(output_data, output_dims, output_scale,
110 output_zero_point),
111 };
112
113 int inputs_array_data[] = {1, 0};
114 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
115 int outputs_array_data[] = {1, 1};
116 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
117
118 const TfLiteRegistration registration = ops::micro::Register_RELU();
119 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
120 outputs_array,
121 /*builtin_data=*/nullptr);
122
123 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
124 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
125
126 Quantize(golden, golden_quantized, output_elements_count, output_scale,
127 output_zero_point);
128
129 for (int i = 0; i < output_elements_count; ++i) {
130 TF_LITE_MICRO_EXPECT_EQ(golden_quantized[i], output_data[i]);
131 }
132 }
133
TestRelu6Uint8(const int * input_dims_data,const float * input_data,uint8_t * input_data_quantized,const float input_scale,const int input_zero_point,const float * golden,uint8_t * golden_quantized,const int * output_dims_data,const float output_scale,const int output_zero_point,uint8_t * output_data)134 void TestRelu6Uint8(const int* input_dims_data, const float* input_data,
135 uint8_t* input_data_quantized, const float input_scale,
136 const int input_zero_point, const float* golden,
137 uint8_t* golden_quantized, const int* output_dims_data,
138 const float output_scale, const int output_zero_point,
139 uint8_t* output_data) {
140 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
141 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
142 const int output_elements_count = ElementCount(*output_dims);
143
144 constexpr int inputs_size = 1;
145 constexpr int outputs_size = 1;
146 constexpr int tensors_size = inputs_size + outputs_size;
147 TfLiteTensor tensors[tensors_size] = {
148 CreateQuantizedTensor(input_data, input_data_quantized, input_dims,
149 input_scale, input_zero_point),
150 CreateQuantizedTensor(output_data, output_dims, output_scale,
151 output_zero_point),
152 };
153
154 int inputs_array_data[] = {1, 0};
155 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
156 int outputs_array_data[] = {1, 1};
157 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
158
159 const TfLiteRegistration registration = ops::micro::Register_RELU6();
160 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
161 outputs_array,
162 /*builtin_data=*/nullptr);
163
164 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
165 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
166
167 Quantize(golden, golden_quantized, output_elements_count, output_scale,
168 output_zero_point);
169
170 for (int i = 0; i < output_elements_count; ++i) {
171 TF_LITE_MICRO_EXPECT_EQ(golden_quantized[i], output_data[i]);
172 }
173 }
174
TestReluInt8(const 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,const int * output_dims_data,const float output_scale,const int output_zero_point,int8_t * output_data)175 void TestReluInt8(const int* input_dims_data, const float* input_data,
176 int8_t* input_data_quantized, const float input_scale,
177 const int input_zero_point, const float* golden,
178 int8_t* golden_quantized, const int* output_dims_data,
179 const float output_scale, const int output_zero_point,
180 int8_t* output_data) {
181 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
182 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
183 const int output_elements_count = ElementCount(*output_dims);
184 constexpr int inputs_size = 1;
185 constexpr int outputs_size = 1;
186 constexpr int tensors_size = inputs_size + outputs_size;
187 TfLiteTensor tensors[tensors_size] = {
188 CreateQuantizedTensor(input_data, input_data_quantized, input_dims,
189 input_scale, input_zero_point),
190 CreateQuantizedTensor(output_data, output_dims, output_scale,
191 output_zero_point),
192 };
193
194 int inputs_array_data[] = {1, 0};
195 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
196 int outputs_array_data[] = {1, 1};
197 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
198
199 const TfLiteRegistration registration = ops::micro::Register_RELU();
200 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
201 outputs_array,
202 /*builtin_data=*/nullptr);
203
204 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
205 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
206
207 Quantize(golden, golden_quantized, output_elements_count, output_scale,
208 output_zero_point);
209
210 for (int i = 0; i < output_elements_count; ++i) {
211 TF_LITE_MICRO_EXPECT_EQ(golden_quantized[i], output_data[i]);
212 }
213 }
214
TestRelu6Int8(const 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,const int * output_dims_data,const float output_scale,const int output_zero_point,int8_t * output_data)215 void TestRelu6Int8(const int* input_dims_data, const float* input_data,
216 int8_t* input_data_quantized, const float input_scale,
217 const int input_zero_point, const float* golden,
218 int8_t* golden_quantized, const int* output_dims_data,
219 const float output_scale, const int output_zero_point,
220 int8_t* output_data) {
221 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
222 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
223 const int output_elements_count = ElementCount(*output_dims);
224 constexpr int inputs_size = 1;
225 constexpr int outputs_size = 1;
226 constexpr int tensors_size = inputs_size + outputs_size;
227 TfLiteTensor tensors[tensors_size] = {
228 CreateQuantizedTensor(input_data, input_data_quantized, input_dims,
229 input_scale, input_zero_point),
230 CreateQuantizedTensor(output_data, output_dims, output_scale,
231 output_zero_point),
232 };
233
234 int inputs_array_data[] = {1, 0};
235 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
236 int outputs_array_data[] = {1, 1};
237 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
238
239 const TfLiteRegistration registration = ops::micro::Register_RELU6();
240 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
241 outputs_array,
242 /*builtin_data=*/nullptr);
243
244 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
245 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
246
247 Quantize(golden, golden_quantized, output_elements_count, output_scale,
248 output_zero_point);
249
250 for (int i = 0; i < output_elements_count; ++i) {
251 TF_LITE_MICRO_EXPECT_EQ(golden_quantized[i], output_data[i]);
252 }
253 }
254
255 } // namespace
256 } // namespace testing
257 } // namespace tflite
258
259 TF_LITE_MICRO_TESTS_BEGIN
260
TF_LITE_MICRO_TEST(SimpleReluTestFloat)261 TF_LITE_MICRO_TEST(SimpleReluTestFloat) {
262 const int output_elements_count = 10;
263 const int input_shape[] = {2, 1, 5};
264 const float input_data[] = {
265 1.0, 2.0, 3.0, 4.0, 5.0, -1.0, -2.0, -3.0, -4.0, -5.0,
266 };
267 const float golden[] = {1.0, 2.0, 3.0, 4.0, 5.0, 0, 0, 0, 0, 0};
268 const int output_shape[] = {2, 1, 5};
269 float output_data[output_elements_count];
270 tflite::testing::TestReluFloat(input_shape, input_data, output_shape, golden,
271 output_data);
272 }
273
TF_LITE_MICRO_TEST(SimpleRelu6TestFloat)274 TF_LITE_MICRO_TEST(SimpleRelu6TestFloat) {
275 const int output_elements_count = 10;
276 float output_data[output_elements_count];
277 const int input_shape[] = {2, 1, 5};
278 const float input_data[] = {4.0, 5.0, 6.0, 7.0, 8.0,
279 -4.0, -5.0, -6.0, -7.0, -8.0};
280 const int output_shape[] = {2, 1, 5};
281 const float golden[] = {
282 4.0, 5.0, 6.0, 6.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0,
283 };
284
285 tflite::testing::TestRelu6Float(input_shape, input_data, output_shape, golden,
286 output_data);
287 }
288
TF_LITE_MICRO_TEST(SimpleReluTestUint8)289 TF_LITE_MICRO_TEST(SimpleReluTestUint8) {
290 const int elements_count = 10;
291
292 const int input_shape[] = {2, 1, 5};
293 const float input_data[] = {1, 2, 3, 4, 5, -1, -2, -3, -4, -5};
294 uint8_t input_quantized[elements_count];
295 const int output_shape[] = {2, 1, 5};
296 const float golden[] = {1, 2, 3, 4, 5, 0, 0, 0, 0, 0};
297 uint8_t golden_quantized[elements_count];
298 uint8_t output_data[elements_count];
299
300 const float input_scale = 0.5f;
301 const int input_zero_point = 127;
302 const float output_scale = 0.5f;
303 const int output_zero_point = 127;
304
305 tflite::testing::TestReluUint8(input_shape, input_data, input_quantized,
306 input_scale, input_zero_point, golden,
307 golden_quantized, output_shape, output_scale,
308 output_zero_point, output_data);
309 }
310
TF_LITE_MICRO_TEST(SimpleRelu6TestUint8)311 TF_LITE_MICRO_TEST(SimpleRelu6TestUint8) {
312 const int elements_count = 10;
313
314 const int input_shape[] = {2, 1, 5};
315 const float input_data[] = {4, 5, 6, 7, 8, -1, -2, -3, -4, -5};
316 uint8_t input_quantized[elements_count];
317 const int output_shape[] = {2, 1, 5};
318 const float golden[] = {4, 5, 6, 6, 6, 0, 0, 0, 0, 0};
319 uint8_t golden_quantized[elements_count];
320 uint8_t output_data[elements_count];
321
322 const float input_scale = 0.5f;
323 const int input_zero_point = 127;
324 const float output_scale = 0.5f;
325 const int output_zero_point = 127;
326
327 tflite::testing::TestRelu6Uint8(input_shape, input_data, input_quantized,
328 input_scale, input_zero_point, golden,
329 golden_quantized, output_shape, output_scale,
330 output_zero_point, output_data);
331 }
332
TF_LITE_MICRO_TEST(SimpleReluTestInt8)333 TF_LITE_MICRO_TEST(SimpleReluTestInt8) {
334 const int elements_count = 10;
335
336 const int input_shape[] = {2, 1, 5};
337 const float input_data[] = {1, 2, 3, 4, 5, -1, -2, -3, -4, -5};
338 int8_t input_quantized[elements_count];
339 const int output_shape[] = {2, 1, 5};
340 const float golden[] = {1, 2, 3, 4, 5, 0, 0, 0, 0, 0};
341 int8_t golden_quantized[elements_count];
342 int8_t output_data[elements_count];
343
344 const float input_scale = 0.5f;
345 const int input_zero_point = 0;
346 const float output_scale = 0.5f;
347 const int output_zero_point = 0;
348
349 tflite::testing::TestReluInt8(input_shape, input_data, input_quantized,
350 input_scale, input_zero_point, golden,
351 golden_quantized, output_shape, output_scale,
352 output_zero_point, output_data);
353 }
354
TF_LITE_MICRO_TEST(SimpleRelu6TestInt8)355 TF_LITE_MICRO_TEST(SimpleRelu6TestInt8) {
356 const int elements_count = 10;
357
358 const int input_shape[] = {2, 1, 5};
359 const float input_data[] = {4, 5, 6, 7, 8, -1, -2, -3, -4, -5};
360 int8_t input_quantized[elements_count];
361 const int output_shape[] = {2, 1, 5};
362 const float golden[] = {4, 5, 6, 6, 6, 0, 0, 0, 0, 0};
363 int8_t golden_quantized[elements_count];
364 int8_t output_data[elements_count];
365
366 const float input_scale = 0.5f;
367 const int input_zero_point = 127;
368 const float output_scale = 0.5f;
369 const int output_zero_point = 127;
370
371 tflite::testing::TestRelu6Int8(input_shape, input_data, input_quantized,
372 input_scale, input_zero_point, golden,
373 golden_quantized, output_shape, output_scale,
374 output_zero_point, output_data);
375 }
376
377 TF_LITE_MICRO_TESTS_END
378