• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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