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/debug_log.h"
20 #include "tensorflow/lite/micro/kernels/kernel_runner.h"
21 #include "tensorflow/lite/micro/test_helpers.h"
22 #include "tensorflow/lite/micro/testing/micro_test.h"
23
24 namespace tflite {
25 namespace testing {
26
27 template <int N>
28 struct OutputTensors {
29 float* data[N];
30 int* dims[N];
31 float* expected_output_data[N];
32 };
33 template <int N>
TestSplitVFloat(const int * input_dims_data,const float * input_data,const int * axis_dims_data,const int32_t * axis_data,const int * split_dims_data,const int32_t * split_data,const OutputTensors<N> & output_tensors)34 void TestSplitVFloat(const int* input_dims_data, const float* input_data,
35 const int* axis_dims_data, const int32_t* axis_data,
36 const int* split_dims_data, const int32_t* split_data,
37 const OutputTensors<N>& output_tensors) {
38 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
39 TfLiteIntArray* axis_dims = IntArrayFromInts(axis_dims_data);
40 TfLiteIntArray* split_dims = IntArrayFromInts(split_dims_data);
41 TfLiteIntArray* output_dims[N];
42 for (int i = 0; i < N; i++)
43 output_dims[i] = IntArrayFromInts(output_tensors.dims[i]);
44
45 // Place a unique value in the uninitialized output buffer.
46 for (int i = 0; i < N; i++) {
47 int dim_count = ElementCount(*output_dims[i]);
48 for (int j = 0; j < dim_count; j++) {
49 (output_tensors.data[i])[j] = 23;
50 }
51 }
52 constexpr int input_size = 1;
53 constexpr int axis_size = 1;
54 constexpr int split_size = 1;
55 constexpr int output_size = N;
56
57 constexpr int tensors_size =
58 input_size + output_size + axis_size + split_size;
59
60 // first input tensor is data
61 // second is size_splits
62 // third is axis
63 // then come outputs
64
65 TfLiteTensor tensors[tensors_size];
66 tensors[0] = CreateTensor(input_data, input_dims);
67 tensors[1] = CreateTensor(split_data, split_dims);
68 tensors[2] = CreateTensor(axis_data, axis_dims);
69
70 // add output tensors
71 for (int i = 0; i < N; i++)
72 tensors[3 + i] = CreateTensor(output_tensors.data[i], output_dims[i]);
73
74 tensors[2].allocation_type = kTfLiteMmapRo;
75 tensors[1].allocation_type = kTfLiteMmapRo;
76
77 int inputs_array_data[] = {3, 0, 1, 2};
78 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
79 int outputs_array_data[N + 1];
80 outputs_array_data[0] = N;
81 for (int i = 0; i < N; i++) outputs_array_data[i + 1] = i + 3;
82 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
83
84 const TfLiteRegistration registration =
85 tflite::ops::micro::Register_SPLIT_V();
86 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
87 outputs_array, nullptr);
88
89 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
90 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
91
92 for (int i = 0; i < N; i++) {
93 int dim_count = ElementCount(*output_dims[i]);
94 for (int j = 0; j < dim_count; j++) {
95 TF_LITE_MICRO_EXPECT_NEAR((output_tensors.expected_output_data[i])[j],
96 (output_tensors.data[i])[j], 1e-5f);
97 }
98 }
99 }
100
101 } // namespace testing
102 } // namespace tflite
103
104 TF_LITE_MICRO_TESTS_BEGIN
105
TF_LITE_MICRO_TEST(SPLIT_V_ThreeOutputs)106 TF_LITE_MICRO_TEST(SPLIT_V_ThreeOutputs) {
107 constexpr int output1_dims_count = 3;
108 constexpr int output2_dims_count = 3;
109 constexpr int output3_dims_count = 6;
110 float output1_data[output1_dims_count];
111 float output2_data[output2_dims_count];
112 float output3_data[output3_dims_count];
113 int input_shape[] = {2, 4, 3};
114 float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
115 int axis_shape[] = {1, 1};
116 int32_t axis_values[] = {0};
117 int split_shape[] = {1, 3};
118 int32_t split_values[] = {1, 1, 2};
119 int output1_shape[] = {2, 1, 3};
120 float output1_values[] = {1, 2, 3};
121 int output2_shape[] = {2, 1, 3};
122 float output2_values[] = {4, 5, 6};
123 int output3_shape[] = {2, 2, 3};
124 float output3_values[] = {7, 8, 9, 10, 11, 12};
125
126 tflite::testing::OutputTensors<3> output_tensors;
127 output_tensors.data[0] = output1_data;
128 output_tensors.data[1] = output2_data;
129 output_tensors.data[2] = output3_data;
130
131 output_tensors.dims[0] = output1_shape;
132 output_tensors.dims[1] = output2_shape;
133 output_tensors.dims[2] = output3_shape;
134
135 output_tensors.expected_output_data[0] = output1_values;
136 output_tensors.expected_output_data[1] = output2_values;
137 output_tensors.expected_output_data[2] = output3_values;
138
139 tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
140 axis_values, split_shape, split_values,
141 output_tensors);
142 }
143
TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis0)144 TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis0) {
145 constexpr int output1_dims_count = 8;
146 constexpr int output2_dims_count = 8;
147 float output1_data[output1_dims_count];
148 float output2_data[output2_dims_count];
149
150 int input_shape[] = {4, 2, 2, 2, 2};
151 float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
152 9, 10, 11, 12, 13, 14, 15, 16};
153 int axis_shape[] = {1, 1};
154 int32_t axis_values[] = {0};
155 int split_shape[] = {1, 2};
156 int32_t split_values[] = {1, 1};
157 int output1_shape[] = {4, 1, 2, 2, 2};
158 float output1_values[] = {1, 2, 3, 4, 5, 6, 7, 8};
159 int output2_shape[] = {4, 1, 2, 2, 2};
160 float output2_values[] = {9, 10, 11, 12, 13, 14, 15, 16};
161
162 tflite::testing::OutputTensors<2> output_tensors;
163
164 output_tensors.data[0] = output1_data;
165 output_tensors.data[1] = output2_data;
166
167 output_tensors.dims[0] = output1_shape;
168 output_tensors.dims[1] = output2_shape;
169
170 output_tensors.expected_output_data[0] = output1_values;
171 output_tensors.expected_output_data[1] = output2_values;
172
173 tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
174 axis_values, split_shape, split_values,
175 output_tensors);
176 }
177
TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis1)178 TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis1) {
179 constexpr int output1_dims_count = 8;
180 constexpr int output2_dims_count = 8;
181 float output1_data[output1_dims_count];
182 float output2_data[output2_dims_count];
183
184 int input_shape[] = {4, 2, 2, 2, 2};
185 float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
186 9, 10, 11, 12, 13, 14, 15, 16};
187 int axis_shape[] = {1, 1};
188 int32_t axis_values[] = {1};
189 int split_shape[] = {1, 2};
190 int32_t split_values[] = {1, 1};
191 int output1_shape[] = {4, 2, 1, 2, 2};
192 float output1_values[] = {1, 2, 3, 4, 9, 10, 11, 12};
193 int output2_shape[] = {4, 2, 1, 2, 2};
194 float output2_values[] = {5, 6, 7, 8, 13, 14, 15, 16};
195
196 tflite::testing::OutputTensors<2> output_tensors;
197
198 output_tensors.data[0] = output1_data;
199 output_tensors.data[1] = output2_data;
200
201 output_tensors.dims[0] = output1_shape;
202 output_tensors.dims[1] = output2_shape;
203
204 output_tensors.expected_output_data[0] = output1_values;
205 output_tensors.expected_output_data[1] = output2_values;
206
207 tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
208 axis_values, split_shape, split_values,
209 output_tensors);
210 }
211
TF_LITE_MICRO_TEST(SPLIT_VFourDimensionalFloatAxis2)212 TF_LITE_MICRO_TEST(SPLIT_VFourDimensionalFloatAxis2) {
213 constexpr int output1_dims_count = 8;
214 constexpr int output2_dims_count = 8;
215 float output1_data[output1_dims_count];
216 float output2_data[output2_dims_count];
217
218 int input_shape[] = {4, 2, 2, 2, 2};
219 float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
220 9, 10, 11, 12, 13, 14, 15, 16};
221 int axis_shape[] = {1, 1};
222 int32_t axis_values[] = {2};
223 int split_shape[] = {1, 2};
224 int32_t split_values[] = {1, 1};
225 int output1_shape[] = {4, 2, 2, 1, 2};
226 float output1_values[] = {1, 2, 5, 6, 9, 10, 13, 14};
227 int output2_shape[] = {4, 2, 2, 1, 2};
228 float output2_values[] = {3, 4, 7, 8, 11, 12, 15, 16};
229
230 tflite::testing::OutputTensors<2> output_tensors;
231
232 output_tensors.data[0] = output1_data;
233 output_tensors.data[1] = output2_data;
234
235 output_tensors.dims[0] = output1_shape;
236 output_tensors.dims[1] = output2_shape;
237
238 output_tensors.expected_output_data[0] = output1_values;
239 output_tensors.expected_output_data[1] = output2_values;
240
241 tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
242 axis_values, split_shape, split_values,
243 output_tensors);
244 }
245
TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis3)246 TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis3) {
247 constexpr int output1_dims_count = 8;
248 constexpr int output2_dims_count = 8;
249 float output1_data[output1_dims_count];
250 float output2_data[output2_dims_count];
251 int input_shape[] = {4, 2, 2, 2, 2};
252 float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
253 9, 10, 11, 12, 13, 14, 15, 16};
254 int axis_shape[] = {1, 1};
255 int32_t axis_values[] = {3};
256 int split_shape[] = {1, 2};
257 int32_t split_values[] = {1, 1};
258 int output1_shape[] = {4, 2, 2, 2, 1};
259 float output1_values[] = {1, 3, 5, 7, 9, 11, 13, 15};
260 int output2_shape[] = {4, 2, 2, 2, 1};
261 float output2_values[] = {2, 4, 6, 8, 10, 12, 14, 16};
262
263 tflite::testing::OutputTensors<2> output_tensors;
264
265 output_tensors.data[0] = output1_data;
266 output_tensors.data[1] = output2_data;
267
268 output_tensors.dims[0] = output1_shape;
269 output_tensors.dims[1] = output2_shape;
270
271 output_tensors.expected_output_data[0] = output1_values;
272 output_tensors.expected_output_data[1] = output2_values;
273
274 tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
275 axis_values, split_shape, split_values,
276 output_tensors);
277 }
278
TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatNegativeAxis)279 TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatNegativeAxis) {
280 constexpr int output1_dims_count = 8;
281 constexpr int output2_dims_count = 8;
282 float output1_data[output1_dims_count];
283 float output2_data[output2_dims_count];
284
285 int input_shape[] = {4, 2, 2, 2, 2};
286 float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
287 9, 10, 11, 12, 13, 14, 15, 16};
288 int axis_shape[] = {1, 1};
289 int32_t axis_values[] = {-4};
290 int split_shape[] = {1, 2};
291 int32_t split_values[] = {1, 1};
292 int output1_shape[] = {4, 1, 2, 2, 2};
293 float output1_values[] = {1, 2, 3, 4, 5, 6, 7, 8};
294 int output2_shape[] = {4, 1, 2, 2, 2};
295 float output2_values[] = {9, 10, 11, 12, 13, 14, 15, 16};
296
297 tflite::testing::OutputTensors<2> output_tensors;
298
299 output_tensors.data[0] = output1_data;
300 output_tensors.data[1] = output2_data;
301
302 output_tensors.dims[0] = output1_shape;
303 output_tensors.dims[1] = output2_shape;
304
305 output_tensors.expected_output_data[0] = output1_values;
306 output_tensors.expected_output_data[1] = output2_values;
307
308 tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
309 axis_values, split_shape, split_values,
310 output_tensors);
311 }
312
TF_LITE_MICRO_TEST(SPLIT_V_OneDimensionalFloatAxis0)313 TF_LITE_MICRO_TEST(SPLIT_V_OneDimensionalFloatAxis0) {
314 constexpr int output1_dims_count = 1;
315 constexpr int output2_dims_count = 1;
316 constexpr int output3_dims_count = 1;
317 constexpr int output4_dims_count = 1;
318 constexpr int output5_dims_count = 1;
319 constexpr int output6_dims_count = 1;
320 constexpr int output7_dims_count = 1;
321 constexpr int output8_dims_count = 1;
322
323 float output1_data[output1_dims_count];
324 float output2_data[output2_dims_count];
325 float output3_data[output3_dims_count];
326 float output4_data[output4_dims_count];
327 float output5_data[output5_dims_count];
328 float output6_data[output6_dims_count];
329 float output7_data[output7_dims_count];
330 float output8_data[output8_dims_count];
331 int input_shape[] = {1, 8};
332 float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8};
333 int axis_shape[] = {1, 1};
334 int32_t axis_value[] = {0};
335 int split_size_shape[] = {1, 8};
336 int32_t split[] = {1, 1, 1, 1, 1, 1, 1, 1};
337 int output1_shape[] = {1, 1};
338 float output1_values[] = {1};
339 int output2_shape[] = {1, 1};
340 float output2_values[] = {2};
341
342 int output3_shape[] = {1, 1};
343 float output3_values[] = {3};
344 int output4_shape[] = {1, 1};
345 float output4_values[] = {4};
346
347 int output5_shape[] = {1, 1};
348 float output5_values[] = {5};
349 int output6_shape[] = {1, 1};
350 float output6_values[] = {6};
351
352 int output7_shape[] = {1, 1};
353 float output7_values[] = {7};
354 int output8_shape[] = {1, 1};
355 float output8_values[] = {8};
356
357 tflite::testing::OutputTensors<8> output_tensors;
358
359 output_tensors.data[0] = output1_data;
360 output_tensors.data[1] = output2_data;
361 output_tensors.data[2] = output3_data;
362 output_tensors.data[3] = output4_data;
363 output_tensors.data[4] = output5_data;
364 output_tensors.data[5] = output6_data;
365 output_tensors.data[6] = output7_data;
366 output_tensors.data[7] = output8_data;
367
368 output_tensors.dims[0] = output1_shape;
369 output_tensors.dims[1] = output2_shape;
370 output_tensors.dims[2] = output3_shape;
371 output_tensors.dims[3] = output4_shape;
372 output_tensors.dims[4] = output5_shape;
373 output_tensors.dims[5] = output6_shape;
374 output_tensors.dims[6] = output7_shape;
375 output_tensors.dims[7] = output8_shape;
376
377 output_tensors.expected_output_data[0] = output1_values;
378 output_tensors.expected_output_data[1] = output2_values;
379 output_tensors.expected_output_data[2] = output3_values;
380 output_tensors.expected_output_data[3] = output4_values;
381 output_tensors.expected_output_data[4] = output5_values;
382 output_tensors.expected_output_data[5] = output6_values;
383 output_tensors.expected_output_data[6] = output7_values;
384 output_tensors.expected_output_data[7] = output8_values;
385
386 tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
387 axis_value, split_size_shape, split,
388 output_tensors);
389 }
390
TF_LITE_MICRO_TEST(SPLIT_V_OneDimensionalFloatTest2)391 TF_LITE_MICRO_TEST(SPLIT_V_OneDimensionalFloatTest2) {
392 constexpr int output1_dims_count = 1;
393 constexpr int output2_dims_count = 1;
394 constexpr int output3_dims_count = 1;
395 constexpr int output4_dims_count = 1;
396 constexpr int output5_dims_count = 1;
397 constexpr int output6_dims_count = 1;
398 constexpr int output7_dims_count = 2;
399
400 float output1_data[output1_dims_count];
401 float output2_data[output2_dims_count];
402 float output3_data[output3_dims_count];
403 float output4_data[output4_dims_count];
404 float output5_data[output5_dims_count];
405 float output6_data[output6_dims_count];
406 float output7_data[output7_dims_count];
407
408 int input_shape[] = {1, 8};
409 float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8};
410 int axis_shape[] = {1, 1};
411 int32_t axis_value[] = {0};
412 int split_size_shape[] = {1, 8};
413 int32_t split[] = {1, 1, 1, 1, 1, 1, 2, -1};
414 int output1_shape[] = {1, 1};
415 float output1_values[] = {1};
416 int output2_shape[] = {1, 1};
417 float output2_values[] = {2};
418
419 int output3_shape[] = {1, 1};
420 float output3_values[] = {3};
421 int output4_shape[] = {1, 1};
422 float output4_values[] = {4};
423
424 int output5_shape[] = {1, 1};
425 float output5_values[] = {5};
426 int output6_shape[] = {1, 1};
427 float output6_values[] = {6};
428
429 int output7_shape[] = {1, 2};
430 float output7_values[] = {7, 8};
431 int output8_shape[] = {1, 0};
432 float output8_values[1] = {};
433
434 tflite::testing::OutputTensors<8> output_tensors;
435
436 output_tensors.data[0] = output1_data;
437 output_tensors.data[1] = output2_data;
438 output_tensors.data[2] = output3_data;
439 output_tensors.data[3] = output4_data;
440 output_tensors.data[4] = output5_data;
441 output_tensors.data[5] = output6_data;
442 output_tensors.data[6] = output7_data;
443 output_tensors.data[7] = NULL;
444
445 output_tensors.dims[0] = output1_shape;
446 output_tensors.dims[1] = output2_shape;
447 output_tensors.dims[2] = output3_shape;
448 output_tensors.dims[3] = output4_shape;
449 output_tensors.dims[4] = output5_shape;
450 output_tensors.dims[5] = output6_shape;
451 output_tensors.dims[6] = output7_shape;
452 output_tensors.dims[7] = output8_shape;
453
454 output_tensors.expected_output_data[0] = output1_values;
455 output_tensors.expected_output_data[1] = output2_values;
456 output_tensors.expected_output_data[2] = output3_values;
457 output_tensors.expected_output_data[3] = output4_values;
458 output_tensors.expected_output_data[4] = output5_values;
459 output_tensors.expected_output_data[5] = output6_values;
460 output_tensors.expected_output_data[6] = output7_values;
461 output_tensors.expected_output_data[7] = output8_values;
462
463 tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
464 axis_value, split_size_shape, split,
465 output_tensors);
466 }
467
468 TF_LITE_MICRO_TESTS_END
469