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 #include "tensorflow/lite/c/builtin_op_data.h"
17 #include "tensorflow/lite/micro/all_ops_resolver.h"
18 #include "tensorflow/lite/micro/kernels/kernel_runner.h"
19 #include "tensorflow/lite/micro/test_helpers.h"
20 #include "tensorflow/lite/micro/testing/micro_test.h"
21 
22 namespace tflite {
23 namespace testing {
24 namespace {
25 
26 using uint8_t = std::uint8_t;
27 using int32_t = std::int32_t;
28 
TestCreateTensor(const float * data,TfLiteIntArray * dims)29 TfLiteTensor TestCreateTensor(const float* data, TfLiteIntArray* dims) {
30   return CreateTensor(data, dims);
31 }
32 
TestCreateTensor(const uint8_t * data,TfLiteIntArray * dims)33 TfLiteTensor TestCreateTensor(const uint8_t* data, TfLiteIntArray* dims) {
34   return CreateQuantizedTensor(data, dims, 0, 255);
35 }
36 
TestCreateTensor(const int8_t * data,TfLiteIntArray * dims)37 TfLiteTensor TestCreateTensor(const int8_t* data, TfLiteIntArray* dims) {
38   return CreateQuantizedTensor(data, dims, -128, 127);
39 }
40 
41 // Input data expects a 4-D tensor of [batch, height, width, channels]
42 // Output data should match input datas batch and channels
43 // Expected sizes should be a 1-D tensor with 2 elements: new_height & new_width
44 template <typename T>
TestResizeNearestNeighbor(int * input_dims_data,const T * input_data,const int32_t * expected_size_data,const T * expected_output_data,int * output_dims_data,T * output_data)45 void TestResizeNearestNeighbor(int* input_dims_data, const T* input_data,
46                                const int32_t* expected_size_data,
47                                const T* expected_output_data,
48                                int* output_dims_data, T* output_data) {
49   TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
50 
51   int expected_size_dims_data[] = {1, 2};
52   TfLiteIntArray* expected_size_dims =
53       IntArrayFromInts(expected_size_dims_data);
54 
55   TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
56 
57   const int output_dims_count = ElementCount(*output_dims);
58 
59   constexpr int tensors_size = 3;
60   TfLiteTensor tensors[tensors_size] = {
61       TestCreateTensor(input_data, input_dims),
62       CreateTensor(expected_size_data, expected_size_dims),
63       TestCreateTensor(output_data, output_dims),
64   };
65 
66   tensors[1].allocation_type = kTfLiteMmapRo;
67 
68   TfLiteResizeNearestNeighborParams builtin_data = {false, false};
69 
70   int inputs_array_data[] = {2, 0, 1};
71   TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
72   int outputs_array_data[] = {1, 2};
73   TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
74 
75   const TfLiteRegistration registration =
76       tflite::ops::micro::Register_RESIZE_NEAREST_NEIGHBOR();
77   micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
78                              outputs_array, &builtin_data);
79 
80   TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
81   TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
82 
83   // compare results
84   for (int i = 0; i < output_dims_count; ++i) {
85     TF_LITE_MICRO_EXPECT_EQ(expected_output_data[i], output_data[i]);
86   }
87 }
88 
89 }  // namespace
90 }  // namespace testing
91 }  // namespace tflite
92 
93 TF_LITE_MICRO_TESTS_BEGIN
94 
TF_LITE_MICRO_TEST(HorizontalResize)95 TF_LITE_MICRO_TEST(HorizontalResize) {
96   int input_dims[] = {4, 1, 1, 2, 1};
97   const float input_data[] = {3, 6};
98   const int32_t expected_size_data[] = {1, 3};
99   const float expected_output_data[] = {3, 3, 6};
100   int output_dims[] = {4, 1, 1, 3, 1};
101   float output_data[3];
102 
103   tflite::testing::TestResizeNearestNeighbor<float>(
104       input_dims, input_data, expected_size_data, expected_output_data,
105       output_dims, output_data);
106 }
TF_LITE_MICRO_TEST(HorizontalResizeUInt8)107 TF_LITE_MICRO_TEST(HorizontalResizeUInt8) {
108   int input_dims[] = {4, 1, 1, 2, 1};
109   const uint8_t input_data[] = {3, 6};
110   const int32_t expected_size_data[] = {1, 3};
111   const uint8_t expected_output_data[] = {3, 3, 6};
112   int output_dims[] = {4, 1, 1, 3, 1};
113   uint8_t output_data[3];
114 
115   tflite::testing::TestResizeNearestNeighbor<uint8_t>(
116       input_dims, input_data, expected_size_data, expected_output_data,
117       output_dims, output_data);
118 }
TF_LITE_MICRO_TEST(HorizontalResizeInt8)119 TF_LITE_MICRO_TEST(HorizontalResizeInt8) {
120   int input_dims[] = {4, 1, 1, 2, 1};
121   const int8_t input_data[] = {-3, 6};
122   const int32_t expected_size_data[] = {1, 3};
123   const int8_t expected_output_data[] = {-3, -3, 6};
124   int output_dims[] = {4, 1, 1, 3, 1};
125   int8_t output_data[3];
126 
127   tflite::testing::TestResizeNearestNeighbor<int8_t>(
128       input_dims, input_data, expected_size_data, expected_output_data,
129       output_dims, output_data);
130 }
TF_LITE_MICRO_TEST(VerticalResize)131 TF_LITE_MICRO_TEST(VerticalResize) {
132   int input_dims[] = {4, 1, 2, 1, 1};
133   const float input_data[] = {3, 9};
134   const int32_t expected_size_data[] = {3, 1};
135   const float expected_output_data[] = {3, 3, 9};
136   int output_dims[] = {4, 1, 3, 1, 1};
137   float output_data[3];
138 
139   tflite::testing::TestResizeNearestNeighbor<float>(
140       input_dims, input_data, expected_size_data, expected_output_data,
141       output_dims, output_data);
142 }
TF_LITE_MICRO_TEST(VerticalResizeUInt8)143 TF_LITE_MICRO_TEST(VerticalResizeUInt8) {
144   int input_dims[] = {4, 1, 2, 1, 1};
145   const uint8_t input_data[] = {3, 9};
146   const int32_t expected_size_data[] = {3, 1};
147   const uint8_t expected_output_data[] = {3, 3, 9};
148   int output_dims[] = {4, 1, 3, 1, 1};
149   uint8_t output_data[3];
150 
151   tflite::testing::TestResizeNearestNeighbor<uint8_t>(
152       input_dims, input_data, expected_size_data, expected_output_data,
153       output_dims, output_data);
154 }
TF_LITE_MICRO_TEST(VerticalResizeInt8)155 TF_LITE_MICRO_TEST(VerticalResizeInt8) {
156   int input_dims[] = {4, 1, 2, 1, 1};
157   const int8_t input_data[] = {3, -9};
158   const int32_t expected_size_data[] = {3, 1};
159   const int8_t expected_output_data[] = {3, 3, -9};
160   int output_dims[] = {4, 1, 3, 1, 1};
161   int8_t output_data[3];
162 
163   tflite::testing::TestResizeNearestNeighbor<int8_t>(
164       input_dims, input_data, expected_size_data, expected_output_data,
165       output_dims, output_data);
166 }
TF_LITE_MICRO_TEST(TwoDimensionalResize)167 TF_LITE_MICRO_TEST(TwoDimensionalResize) {
168   int input_dims[] = {4, 1, 2, 2, 1};
169   const float input_data[] = {
170       3, 6,   //
171       9, 12,  //
172   };
173   const int32_t expected_size_data[] = {3, 3};
174   const float expected_output_data[] = {
175       3, 3, 6,  //
176       3, 3, 6,  //
177       9, 9, 12  //
178   };
179 
180   int output_dims[] = {4, 1, 3, 3, 1};
181   float output_data[9];
182 
183   tflite::testing::TestResizeNearestNeighbor<float>(
184       input_dims, input_data, expected_size_data, expected_output_data,
185       output_dims, output_data);
186 }
TF_LITE_MICRO_TEST(TwoDimensionalResizeUInt8)187 TF_LITE_MICRO_TEST(TwoDimensionalResizeUInt8) {
188   int input_dims[] = {4, 1, 2, 2, 1};
189   const uint8_t input_data[] = {
190       3, 6,  //
191       9, 12  //
192   };
193   const int32_t expected_size_data[] = {3, 3};
194   const uint8_t expected_output_data[] = {
195       3, 3, 6,  //
196       3, 3, 6,  //
197       9, 9, 12  //
198   };
199   int output_dims[] = {4, 1, 3, 3, 1};
200   uint8_t output_data[9];
201 
202   tflite::testing::TestResizeNearestNeighbor<uint8_t>(
203       input_dims, input_data, expected_size_data, expected_output_data,
204       output_dims, output_data);
205 }
TF_LITE_MICRO_TEST(TwoDimensionalResizeInt8)206 TF_LITE_MICRO_TEST(TwoDimensionalResizeInt8) {
207   int input_dims[] = {4, 1, 2, 2, 1};
208   const int8_t input_data[] = {
209       3, -6,  //
210       9, 12,  //
211   };
212   const int32_t expected_size_data[] = {3, 3};
213   const int8_t expected_output_data[] = {
214       3, 3, -6,  //
215       3, 3, -6,  //
216       9, 9, 12,  //
217   };
218   int output_dims[] = {4, 1, 3, 3, 1};
219   int8_t output_data[9];
220 
221   tflite::testing::TestResizeNearestNeighbor<int8_t>(
222       input_dims, input_data, expected_size_data, expected_output_data,
223       output_dims, output_data);
224 }
TF_LITE_MICRO_TEST(TwoDimensionalResizeWithTwoBatches)225 TF_LITE_MICRO_TEST(TwoDimensionalResizeWithTwoBatches) {
226   int input_dims[] = {4, 2, 2, 2, 1};
227   const float input_data[] = {
228       3,  6,   //
229       9,  12,  //
230       4,  10,  //
231       10, 16   //
232   };
233   const int32_t expected_size_data[] = {3, 3};
234   const float expected_output_data[] = {
235       3,  3,  6,   //
236       3,  3,  6,   //
237       9,  9,  12,  //
238       4,  4,  10,  //
239       4,  4,  10,  //
240       10, 10, 16,  //
241   };
242   int output_dims[] = {4, 2, 3, 3, 1};
243   float output_data[18];
244 
245   tflite::testing::TestResizeNearestNeighbor<float>(
246       input_dims, input_data, expected_size_data, expected_output_data,
247       output_dims, output_data);
248 }
TF_LITE_MICRO_TEST(TwoDimensionalResizeWithTwoBatchesUInt8)249 TF_LITE_MICRO_TEST(TwoDimensionalResizeWithTwoBatchesUInt8) {
250   int input_dims[] = {4, 2, 2, 2, 1};
251   const uint8_t input_data[] = {
252       3,  6,   //
253       9,  12,  //
254       4,  10,  //
255       10, 16   //
256   };
257   const int32_t expected_size_data[] = {3, 3};
258   const uint8_t expected_output_data[] = {
259       3,  3,  6,   //
260       3,  3,  6,   //
261       9,  9,  12,  //
262       4,  4,  10,  //
263       4,  4,  10,  //
264       10, 10, 16,  //
265   };
266   int output_dims[] = {4, 2, 3, 3, 1};
267   uint8_t output_data[18];
268 
269   tflite::testing::TestResizeNearestNeighbor<uint8_t>(
270       input_dims, input_data, expected_size_data, expected_output_data,
271       output_dims, output_data);
272 }
TF_LITE_MICRO_TEST(TwoDimensionalResizeWithTwoBatchesInt8)273 TF_LITE_MICRO_TEST(TwoDimensionalResizeWithTwoBatchesInt8) {
274   int input_dims[] = {4, 2, 2, 2, 1};
275   const int8_t input_data[] = {
276       3,  6,    //
277       9,  -12,  //
278       -4, 10,   //
279       10, 16    //
280   };
281   const int32_t expected_size_data[] = {3, 3};
282   const int8_t expected_output_data[] = {
283       3,  3,  6,    //
284       3,  3,  6,    //
285       9,  9,  -12,  //
286       -4, -4, 10,   //
287       -4, -4, 10,   //
288       10, 10, 16,   //
289   };
290   int output_dims[] = {4, 2, 3, 3, 1};
291   int8_t output_data[18];
292 
293   tflite::testing::TestResizeNearestNeighbor<int8_t>(
294       input_dims, input_data, expected_size_data, expected_output_data,
295       output_dims, output_data);
296 }
TF_LITE_MICRO_TEST(ThreeDimensionalResize)297 TF_LITE_MICRO_TEST(ThreeDimensionalResize) {
298   int input_dims[] = {4, 1, 2, 2, 2};
299   const float input_data[] = {
300       3, 4,  6,  10,  //
301       9, 10, 12, 16,  //
302   };
303   const int32_t expected_size_data[] = {3, 3};
304   const float expected_output_data[] = {
305       3, 4,  3, 4,  6,  10,  //
306       3, 4,  3, 4,  6,  10,  //
307       9, 10, 9, 10, 12, 16,  //
308   };
309   int output_dims[] = {4, 1, 3, 3, 2};
310   float output_data[18];
311 
312   tflite::testing::TestResizeNearestNeighbor<float>(
313       input_dims, input_data, expected_size_data, expected_output_data,
314       output_dims, output_data);
315 }
TF_LITE_MICRO_TEST(ThreeDimensionalResizeUInt8)316 TF_LITE_MICRO_TEST(ThreeDimensionalResizeUInt8) {
317   int input_dims[] = {4, 1, 2, 2, 2};
318   const uint8_t input_data[] = {
319       3,  4,  6,  10,  //
320       10, 12, 14, 16,  //
321   };
322   const int32_t expected_size_data[] = {3, 3};
323   const uint8_t expected_output_data[] = {
324       3,  4,  3,  4,  6,  10,  //
325       3,  4,  3,  4,  6,  10,  //
326       10, 12, 10, 12, 14, 16,  //
327   };
328   int output_dims[] = {4, 1, 3, 3, 2};
329   uint8_t output_data[18];
330 
331   tflite::testing::TestResizeNearestNeighbor<uint8_t>(
332       input_dims, input_data, expected_size_data, expected_output_data,
333       output_dims, output_data);
334 }
TF_LITE_MICRO_TEST(ThreeDimensionalResizeInt8)335 TF_LITE_MICRO_TEST(ThreeDimensionalResizeInt8) {
336   int input_dims[] = {4, 1, 2, 2, 2};
337   const int8_t input_data[] = {
338       3,  4,  -6,  10,  //
339       10, 12, -14, 16,  //
340   };
341   const int32_t expected_size_data[] = {3, 3};
342   const int8_t expected_output_data[] = {
343       3,  4,  3,  4,  -6,  10,  //
344       3,  4,  3,  4,  -6,  10,  //
345       10, 12, 10, 12, -14, 16,  //
346   };
347   int output_dims[] = {4, 1, 3, 3, 2};
348   int8_t output_data[18];
349 
350   tflite::testing::TestResizeNearestNeighbor<int8_t>(
351       input_dims, input_data, expected_size_data, expected_output_data,
352       output_dims, output_data);
353 }
354 
355 TF_LITE_MICRO_TESTS_END
356