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 
16 // This test checks that slicing logic doesn`t affect result of fully
17 // connected kernel
18 //
19 // This test doesn`t replace default fully connected test
20 // (tensorflow/lite/micro/kernels/fully_connected_test.cc). It is added to the
21 // whole testset only in case MLI for ARC platform is used during generation
22 // (which is handled in arc_mli.inc). So such tests won`t be generated for other
23 // platforms.
24 
25 #include <cstdint>
26 
27 #include "tensorflow/lite/c/builtin_op_data.h"
28 #include "tensorflow/lite/c/common.h"
29 #include "tensorflow/lite/micro/all_ops_resolver.h"
30 #include "tensorflow/lite/micro/testing/micro_test.h"
31 #include "tensorflow/lite/micro/testing/test_utils.h"
32 
33 namespace tflite {
34 namespace testing {
35 namespace {
36 
37 template <typename T>
TestFullyConnectedQuantized(const int * input_dims_data,const T * input_data,const float input_min,const float input_max,const int * weights_dims_data,const T * weights_data,const float weights_min,const float weights_max,const int * bias_dims_data,const int32_t * bias_data,const float bias_scale,const T * expected_output_data,const int * output_dims_data,const float output_min,const float output_max,TfLiteFusedActivation activation,T * output_data)38 void TestFullyConnectedQuantized(
39     const int* input_dims_data, const T* input_data, const float input_min,
40     const float input_max, const int* weights_dims_data, const T* weights_data,
41     const float weights_min, const float weights_max, const int* bias_dims_data,
42     const int32_t* bias_data, const float bias_scale,
43     const T* expected_output_data, const int* output_dims_data,
44     const float output_min, const float output_max,
45     TfLiteFusedActivation activation, T* output_data) {
46   TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
47   TfLiteIntArray* weights_dims = IntArrayFromInts(weights_dims_data);
48   TfLiteIntArray* bias_dims = IntArrayFromInts(bias_dims_data);
49   TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
50   const int output_dims_count = ElementCount(*output_dims);
51 
52   constexpr int inputs_size = 3;
53   constexpr int outputs_size = 1;
54   constexpr int tensors_size = inputs_size + outputs_size;
55   TfLiteTensor tensors[tensors_size] = {
56       CreateQuantizedTensor(input_data, input_dims, "input_tensor", input_min,
57                             input_max),
58       CreateQuantizedTensor(weights_data, weights_dims, "weights_tensor",
59                             weights_min, weights_max),
60       CreateQuantized32Tensor(bias_data, bias_dims, "bias_tensor", bias_scale),
61       CreateQuantizedTensor(output_data, output_dims, "output_tensor",
62                             output_min, output_max),
63   };
64 
65   tensors[0].params.zero_point = 0;
66   tensors[1].params.zero_point = 0;
67   tensors[3].params.zero_point = 0;
68 
69   TfLiteContext context;
70   PopulateContext(tensors, tensors_size, &context);
71 
72   ::tflite::AllOpsResolver resolver;
73   const TfLiteRegistration* registration =
74       resolver.FindOp(tflite::BuiltinOperator_FULLY_CONNECTED, 4);
75   TF_LITE_MICRO_EXPECT_NE(nullptr, registration);
76 
77   TfLiteFullyConnectedParams builtin_data = {
78       activation,
79       kTfLiteFullyConnectedWeightsFormatDefault,
80   };
81   const char* init_data = reinterpret_cast<const char*>(&builtin_data);
82   size_t init_data_size = 0;
83   void* user_data = nullptr;
84   if (registration->init) {
85     user_data = registration->init(&context, init_data, init_data_size);
86   }
87 
88   int inputs_array_data[] = {3, 0, 1, 2};
89   TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
90   int outputs_array_data[] = {1, 3};
91   TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
92   int temporaries_array_data[] = {0};
93   TfLiteIntArray* temporaries_array = IntArrayFromInts(temporaries_array_data);
94 
95   TfLiteNode node;
96   node.inputs = inputs_array;
97   node.outputs = outputs_array;
98   node.temporaries = temporaries_array;
99   node.user_data = user_data;
100   node.builtin_data = reinterpret_cast<void*>(&builtin_data);
101   node.custom_initial_data = nullptr;
102   node.custom_initial_data_size = 0;
103   node.delegate = nullptr;
104 
105   if (registration->prepare) {
106     TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, registration->prepare(&context, &node));
107   }
108   TF_LITE_MICRO_EXPECT_NE(nullptr, registration->invoke);
109   TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, registration->invoke(&context, &node));
110   if (registration->free) {
111     registration->free(&context, user_data);
112   }
113   for (int i = 0; i < output_dims_count; ++i) {
114     TF_LITE_MICRO_EXPECT_EQ(expected_output_data[i], output_data[i]);
115   }
116 }
117 
118 }  // namespace
119 }  // namespace testing
120 }  // namespace tflite
121 
122 TF_LITE_MICRO_TESTS_BEGIN
123 
124 // Test group 1
TF_LITE_MICRO_TEST(SystemSimpleTestQuantized1)125 TF_LITE_MICRO_TEST(SystemSimpleTestQuantized1) {
126   const float input_min = -128.0f;
127   const float input_max = 127.0f;
128   const float weights_min = -128.0f;
129   const float weights_max = 127.0f;
130   const float bias_scale = 1.0f;
131   const float output_min = -128.0f;
132   const float output_max = 127.0f;
133 
134   const int input_dims_data[] = {2, 2, 10};
135   const int8_t input_data[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
136                                2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
137   const int weights_dims_data[] = {2, 3, 10};
138   const int8_t weights_data[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
139                                  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
140   const int bias_dims_data[] = {1, 3};
141   const int32_t bias_data[] = {1, 1, 1};
142   const int8_t expected_output_data[] = {41, 41, 41, 41, 41, 41};
143   const int output_dims_data[] = {2, 2, 3};
144 
145   const int output_dims_count = 6;
146   int8_t output_data[output_dims_count];
147   tflite::testing::TestFullyConnectedQuantized<int8_t>(
148       input_dims_data, input_data, input_min, input_max, weights_dims_data,
149       weights_data, weights_min, weights_max, bias_dims_data, bias_data,
150       bias_scale, expected_output_data, output_dims_data, output_min,
151       output_max, kTfLiteActNone, output_data);
152 }
153 
TF_LITE_MICRO_TEST(LocalSimpleTestQuantized1)154 TF_LITE_MICRO_TEST(LocalSimpleTestQuantized1) {
155   const float input_min = -128.0f;
156   const float input_max = 127.0f;
157   const float weights_min = -128.0f;
158   const float weights_max = 127.0f;
159   const float bias_scale = 1.0f;
160   const float output_min = -128.0f;
161   const float output_max = 127.0f;
162 
163   const int input_dims_data_local[] = {2, 2, 10};
164   const int weights_dims_data_local[] = {2, 3, 10};
165   const int bias_dims_data_local[] = {1, 3};
166   const int output_dims_data_local[] = {2, 2, 3};
167 
168   const int output_dims_count = 6;
169 
170 #pragma Bss(".Zdata")
171   const int8_t input_data_local[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
172                                      2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
173   const int8_t weights_data_local[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
174                                        2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
175                                        2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
176   const int32_t bias_data_local[] = {1, 1, 1};
177   int8_t output_data_local[output_dims_count];
178 #pragma Bss()
179 
180   const int8_t expected_output_data[] = {41, 41, 41, 41, 41, 41};
181 
182   tflite::testing::TestFullyConnectedQuantized<int8_t>(
183       input_dims_data_local, input_data_local, input_min, input_max,
184       weights_dims_data_local, weights_data_local, weights_min, weights_max,
185       bias_dims_data_local, bias_data_local, bias_scale, expected_output_data,
186       output_dims_data_local, output_min, output_max, kTfLiteActNone,
187       output_data_local);
188 }
189 
190 // Test group 2
TF_LITE_MICRO_TEST(SystemSimpleTestQuantized2)191 TF_LITE_MICRO_TEST(SystemSimpleTestQuantized2) {
192   const float input_min = -128.0f;
193   const float input_max = 127.0f;
194   const float weights_min = -128.0f;
195   const float weights_max = 127.0f;
196   const float bias_scale = 1.0f;
197   const float output_min = -128.0f;
198   const float output_max = 127.0f;
199 
200   const int input_dims_data_2[] = {2, 10, 4};
201   const int8_t input_data_2[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
202                                  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
203                                  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
204   const int weights_dims_data_2[] = {2, 6, 4};
205   const int8_t weights_data_2[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
206                                    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
207   const int bias_dims_data_2[] = {1, 6};
208   const int32_t bias_data_2[] = {1, 1, 1, 1, 1, 1};
209   const int8_t expected_output_data_2[] = {
210       17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
211       17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
212       17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
213       17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17};
214   const int output_dims_data_2[] = {2, 10, 6};
215 
216   const int output_dims_count_2 = 60;
217   int8_t output_data_2[output_dims_count_2];
218   tflite::testing::TestFullyConnectedQuantized<int8_t>(
219       input_dims_data_2, input_data_2, input_min, input_max,
220       weights_dims_data_2, weights_data_2, weights_min, weights_max,
221       bias_dims_data_2, bias_data_2, bias_scale, expected_output_data_2,
222       output_dims_data_2, output_min, output_max, kTfLiteActNone,
223       output_data_2);
224 }
225 
TF_LITE_MICRO_TEST(LocalSimpleTestQuantized2)226 TF_LITE_MICRO_TEST(LocalSimpleTestQuantized2) {
227   const float input_min = -128.0f;
228   const float input_max = 127.0f;
229   const float weights_min = -128.0f;
230   const float weights_max = 127.0f;
231   const float bias_scale = 1.0f;
232   const float output_min = -128.0f;
233   const float output_max = 127.0f;
234 
235   const int input_dims_data_local_2[] = {2, 10, 4};
236   const int weights_dims_data_local_2[] = {2, 6, 4};
237   const int bias_dims_data_local_2[] = {1, 6};
238   const int output_dims_data_local_2[] = {2, 10, 6};
239 
240   const int output_dims_count_local_2 = 60;
241 
242 #pragma Bss(".Zdata")
243   const int8_t input_data_local_2[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
244                                        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
245                                        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
246   const int8_t weights_data_local_2[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
247                                          2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
248   const int32_t bias_data_local_2[] = {1, 1, 1, 1, 1, 1};
249   int8_t output_data_local_2[output_dims_count_local_2];
250 #pragma Bss()
251 
252   const int8_t expected_output_data_local_2[] = {41, 41, 41, 41, 41, 41};
253 
254   tflite::testing::TestFullyConnectedQuantized<int8_t>(
255       input_dims_data_local_2, input_data_local_2, input_min, input_max,
256       weights_dims_data_local_2, weights_data_local_2, weights_min, weights_max,
257       bias_dims_data_local_2, bias_data_local_2, bias_scale,
258       expected_output_data_local_2, output_dims_data_local_2, output_min,
259       output_max, kTfLiteActNone, output_data_local_2);
260 }
261 
262 // Test group 3
TF_LITE_MICRO_TEST(SystemSimpleTestQuantized3)263 TF_LITE_MICRO_TEST(SystemSimpleTestQuantized3) {
264   const float input_min = -128.0f;
265   const float input_max = 127.0f;
266   const float weights_min = -128.0f;
267   const float weights_max = 127.0f;
268   const float bias_scale = 1.0f;
269   const float output_min = -128.0f;
270   const float output_max = 127.0f;
271 
272   const int input_dims_data_3[] = {2, 2, 5};
273   const int8_t input_data_3[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
274   const int weights_dims_data_3[] = {2, 10, 5};
275   const int8_t weights_data_3[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
276                                    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
277                                    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
278                                    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
279   const int bias_dims_data_3[] = {1, 10};
280   const int32_t bias_data_3[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
281   const int8_t expected_output_data_3[] = {21, 21, 21, 21, 21, 21, 21,
282                                            21, 21, 21, 21, 21, 21, 21,
283                                            21, 21, 21, 21, 21, 21};
284   const int output_dims_data_3[] = {2, 2, 10};
285 
286   const int output_dims_count_3 = 20;
287   int8_t output_data_3[output_dims_count_3];
288   tflite::testing::TestFullyConnectedQuantized<int8_t>(
289       input_dims_data_3, input_data_3, input_min, input_max,
290       weights_dims_data_3, weights_data_3, weights_min, weights_max,
291       bias_dims_data_3, bias_data_3, bias_scale, expected_output_data_3,
292       output_dims_data_3, output_min, output_max, kTfLiteActNone,
293       output_data_3);
294 }
295 
TF_LITE_MICRO_TEST(LocalSimpleTestQuantized3)296 TF_LITE_MICRO_TEST(LocalSimpleTestQuantized3) {
297   const float input_min = -128.0f;
298   const float input_max = 127.0f;
299   const float weights_min = -128.0f;
300   const float weights_max = 127.0f;
301   const float bias_scale = 1.0f;
302   const float output_min = -128.0f;
303   const float output_max = 127.0f;
304 
305   const int input_dims_data_local_3[] = {2, 2, 5};
306   const int weights_dims_data_local_3[] = {2, 10, 5};
307   const int bias_dims_data_local_3[] = {1, 10};
308   const int output_dims_data_local_3[] = {2, 2, 10};
309 
310   const int output_dims_count_local_3 = 20;
311 
312 #pragma Bss(".Zdata")
313   static int8_t input_data_local_3[10];
314   static int8_t weights_data_local_3[50];
315   static int32_t bias_data_local_3[10];
316   static int8_t output_data_local_3[output_dims_count_local_3];
317 #pragma Bss()
318 
319   for (int i = 0; i < 10; ++i) {
320     input_data_local_3[i] = 2;
321   }
322 
323   for (int i = 0; i < 50; ++i) {
324     weights_data_local_3[i] = 2;
325   }
326 
327   for (int i = 0; i < 10; ++i) {
328     bias_data_local_3[i] = 1;
329   }
330 
331   for (int i = 0; i < 20; ++i) {
332     output_data_local_3[i] = 0;
333   }
334 
335   const int8_t expected_output_data_local_3[] = {21, 21, 21, 21, 21, 21, 21,
336                                                  21, 21, 21, 21, 21, 21, 21,
337                                                  21, 21, 21, 21, 21, 21};
338 
339   tflite::testing::TestFullyConnectedQuantized<int8_t>(
340       input_dims_data_local_3, input_data_local_3, input_min, input_max,
341       weights_dims_data_local_3, weights_data_local_3, weights_min, weights_max,
342       bias_dims_data_local_3, bias_data_local_3, bias_scale,
343       expected_output_data_local_3, output_dims_data_local_3, output_min,
344       output_max, kTfLiteActNone, output_data_local_3);
345 }
346 
347 // Test group 4
TF_LITE_MICRO_TEST(SystemSimpleTestQuantized4)348 TF_LITE_MICRO_TEST(SystemSimpleTestQuantized4) {
349   const float input_min = -128.0f;
350   const float input_max = 127.0f;
351   const float weights_min = -128.0f;
352   const float weights_max = 127.0f;
353   const float bias_scale = 1.0f;
354   const float output_min = -128.0f;
355   const float output_max = 127.0f;
356 
357   const int input_dims_data_4[] = {2, 5, 10};
358   const int8_t input_data_4[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
359                                  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
360                                  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
361                                  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
362   const int weights_dims_data_4[] = {2, 5, 10};
363   const int8_t weights_data_4[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
364                                    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
365                                    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
366                                    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
367   const int bias_dims_data_4[] = {1, 5};
368   const int32_t bias_data_4[] = {1, 1, 1, 1, 1};
369   const int8_t expected_output_data_4[] = {41, 41, 41, 41, 41, 41, 41, 41, 41,
370                                            41, 41, 41, 41, 41, 41, 41, 41, 41,
371                                            41, 41, 41, 41, 41, 41, 41};
372   const int output_dims_data_4[] = {2, 5, 5};
373 
374   const int output_dims_count_4 = 25;
375   int8_t output_data_4[output_dims_count_4];
376   tflite::testing::TestFullyConnectedQuantized<int8_t>(
377       input_dims_data_4, input_data_4, input_min, input_max,
378       weights_dims_data_4, weights_data_4, weights_min, weights_max,
379       bias_dims_data_4, bias_data_4, bias_scale, expected_output_data_4,
380       output_dims_data_4, output_min, output_max, kTfLiteActNone,
381       output_data_4);
382 }
383 
TF_LITE_MICRO_TEST(LocalSimpleTestQuantized4)384 TF_LITE_MICRO_TEST(LocalSimpleTestQuantized4) {
385   const float input_min = -128.0f;
386   const float input_max = 127.0f;
387   const float weights_min = -128.0f;
388   const float weights_max = 127.0f;
389   const float bias_scale = 1.0f;
390   const float output_min = -128.0f;
391   const float output_max = 127.0f;
392 
393   const int input_dims_data_local_4[] = {2, 5, 10};
394   const int weights_dims_data_local_4[] = {2, 5, 10};
395   const int bias_dims_data_local_4[] = {1, 5};
396   const int output_dims_data_local_4[] = {2, 5, 5};
397 
398   const int output_dims_count_local_4 = 25;
399 
400 #pragma Bss(".Zdata")
401   const int8_t input_data_local_4[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
402                                        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
403                                        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
404                                        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
405   const int8_t weights_data_local_4[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
406                                          2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
407                                          2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
408                                          2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
409   const int32_t bias_data_local_4[] = {1, 1, 1, 1, 1};
410   int8_t output_data_local_4[output_dims_count_local_4];
411 #pragma Bss()
412 
413   const int8_t expected_output_data_local_4[] = {
414       41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
415       41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41};
416 
417   tflite::testing::TestFullyConnectedQuantized<int8_t>(
418       input_dims_data_local_4, input_data_local_4, input_min, input_max,
419       weights_dims_data_local_4, weights_data_local_4, weights_min, weights_max,
420       bias_dims_data_local_4, bias_data_local_4, bias_scale,
421       expected_output_data_local_4, output_dims_data_local_4, output_min,
422       output_max, kTfLiteActNone, output_data_local_4);
423 }
424 
425 TF_LITE_MICRO_TESTS_END
426