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