1 /* Copyright 2018 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
ValidateArgMinMaxGoldens(TfLiteTensor * tensors,int tensors_size,const int32_t * golden,int32_t * output,int output_size,bool using_min)27 void ValidateArgMinMaxGoldens(TfLiteTensor* tensors, int tensors_size,
28 const int32_t* golden, int32_t* output,
29 int output_size, bool using_min) {
30 int inputs_array_data[] = {2, 0, 1};
31 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
32 int outputs_array_data[] = {1, 2};
33 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
34
35 const TfLiteRegistration registration = using_min
36 ? ops::micro::Register_ARG_MIN()
37 : ops::micro::Register_ARG_MAX();
38 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
39 outputs_array,
40 /*builtin_data=*/nullptr);
41
42 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
43 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
44
45 for (int i = 0; i < output_size; ++i) {
46 TF_LITE_MICRO_EXPECT_EQ(golden[i], output[i]);
47 }
48 }
49
TestArgMinMaxFloat(const int * input_dims_data,const float * input_values,const int * axis_dims_data,const int32_t * axis_values,const int * output_dims_data,int32_t * output,const int32_t * goldens,bool using_min)50 void TestArgMinMaxFloat(const int* input_dims_data, const float* input_values,
51 const int* axis_dims_data, const int32_t* axis_values,
52 const int* output_dims_data, int32_t* output,
53 const int32_t* goldens, bool using_min) {
54 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
55 TfLiteIntArray* axis_dims = IntArrayFromInts(axis_dims_data);
56 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
57 const int output_dims_count = ElementCount(*output_dims);
58
59 constexpr int inputs_size = 2;
60 constexpr int outputs_size = 1;
61 constexpr int tensors_size = inputs_size + outputs_size;
62 TfLiteTensor tensors[tensors_size] = {
63 CreateTensor(input_values, input_dims),
64 CreateTensor(axis_values, axis_dims),
65 CreateTensor(output, output_dims),
66 };
67
68 ValidateArgMinMaxGoldens(tensors, tensors_size, goldens, output,
69 output_dims_count, using_min);
70 }
71
72 template <typename T>
TestArgMinMaxQuantized(const int * input_dims_data,const float * input_values,T * input_quantized,float input_scale,int input_zero_point,const int * axis_dims_data,const int32_t * axis_values,const int * output_dims_data,int32_t * output,const int32_t * goldens,bool using_min)73 void TestArgMinMaxQuantized(const int* input_dims_data,
74 const float* input_values, T* input_quantized,
75 float input_scale, int input_zero_point,
76 const int* axis_dims_data,
77 const int32_t* axis_values,
78 const int* output_dims_data, int32_t* output,
79 const int32_t* goldens, bool using_min) {
80 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
81 TfLiteIntArray* axis_dims = IntArrayFromInts(axis_dims_data);
82 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
83 const int output_dims_count = ElementCount(*output_dims);
84
85 constexpr int inputs_size = 2;
86 constexpr int outputs_size = 1;
87 constexpr int tensors_size = inputs_size + outputs_size;
88 TfLiteTensor tensors[tensors_size] = {
89 CreateQuantizedTensor(input_values, input_quantized, input_dims,
90 input_scale, input_zero_point),
91 CreateTensor(axis_values, axis_dims),
92 CreateTensor(output, output_dims),
93 };
94
95 ValidateArgMinMaxGoldens(tensors, tensors_size, goldens, output,
96 output_dims_count, using_min);
97 }
98
99 } // namespace
100 } // namespace testing
101 } // namespace tflite
102
103 TF_LITE_MICRO_TESTS_BEGIN
104
TF_LITE_MICRO_TEST(GetMaxArgFloat)105 TF_LITE_MICRO_TEST(GetMaxArgFloat) {
106 int32_t output_data[1];
107 const int input_dims[] = {4, 1, 1, 1, 4};
108 const float input_values[] = {0.1, 0.9, 0.7, 0.3};
109 const int axis_dims[] = {3, 1, 1, 1};
110 const int32_t axis_values[] = {3};
111 const int output_dims[] = {3, 1, 1, 1};
112 const int32_t goldens[] = {1};
113
114 tflite::testing::TestArgMinMaxFloat(input_dims, input_values, axis_dims,
115 axis_values, output_dims, output_data,
116 goldens, false);
117 }
118
TF_LITE_MICRO_TEST(GetMinArgFloat)119 TF_LITE_MICRO_TEST(GetMinArgFloat) {
120 int32_t output_data[1];
121 const int input_dims[] = {4, 1, 1, 1, 4};
122 const float input_values[] = {0.1, 0.9, 0.7, 0.3};
123 const int axis_dims[] = {3, 1, 1, 1};
124 const int32_t axis_values[] = {3};
125 const int output_dims[] = {3, 1, 1, 1};
126 const int32_t goldens[] = {0};
127
128 tflite::testing::TestArgMinMaxFloat(input_dims, input_values, axis_dims,
129 axis_values, output_dims, output_data,
130 goldens, true);
131 }
132
TF_LITE_MICRO_TEST(GetMaxArgUInt8)133 TF_LITE_MICRO_TEST(GetMaxArgUInt8) {
134 int32_t output_data[1];
135 const int input_size = 4;
136 const int input_dims[] = {4, 1, 1, 1, input_size};
137 const float input_values[] = {1, 9, 7, 3};
138 const int axis_dims[] = {3, 1, 1, 1};
139 const int32_t axis_values[] = {3};
140 const int output_dims[] = {3, 1, 1, 1};
141 const int32_t goldens[] = {1};
142
143 float input_scale = 0.5;
144 int input_zero_point = 124;
145 uint8_t input_quantized[input_size];
146
147 tflite::testing::TestArgMinMaxQuantized(
148 input_dims, input_values, input_quantized, input_scale, input_zero_point,
149 axis_dims, axis_values, output_dims, output_data, goldens, false);
150 }
151
TF_LITE_MICRO_TEST(GetMinArgUInt8)152 TF_LITE_MICRO_TEST(GetMinArgUInt8) {
153 int32_t output_data[1];
154 const int input_size = 4;
155 const int input_dims[] = {4, 1, 1, 1, input_size};
156 const float input_values[] = {1, 9, 7, 3};
157 const int axis_dims[] = {3, 1, 1, 1};
158 const int32_t axis_values[] = {3};
159 const int output_dims[] = {3, 1, 1, 1};
160 const int32_t goldens[] = {0};
161
162 float input_scale = 0.5;
163 int input_zero_point = 124;
164 uint8_t input_quantized[input_size];
165
166 tflite::testing::TestArgMinMaxQuantized(
167 input_dims, input_values, input_quantized, input_scale, input_zero_point,
168 axis_dims, axis_values, output_dims, output_data, goldens, true);
169 }
170
TF_LITE_MICRO_TEST(GetMaxArgInt8)171 TF_LITE_MICRO_TEST(GetMaxArgInt8) {
172 int32_t output_data[1];
173 const int input_size = 4;
174 const int input_dims[] = {4, 1, 1, 1, input_size};
175 const float input_values[] = {1, 9, 7, 3};
176 const int axis_dims[] = {3, 1, 1, 1};
177 const int32_t axis_values[] = {3};
178 const int output_dims[] = {3, 1, 1, 1};
179 const int32_t goldens[] = {1};
180
181 float input_scale = 0.5;
182 int input_zero_point = -9;
183 int8_t input_quantized[input_size];
184
185 tflite::testing::TestArgMinMaxQuantized(
186 input_dims, input_values, input_quantized, input_scale, input_zero_point,
187 axis_dims, axis_values, output_dims, output_data, goldens, false);
188 }
189
TF_LITE_MICRO_TEST(GetMinArgInt8)190 TF_LITE_MICRO_TEST(GetMinArgInt8) {
191 int32_t output_data[1];
192 const int input_size = 4;
193 const int input_dims[] = {4, 1, 1, 1, input_size};
194 const float input_values[] = {1, 9, 7, 3};
195 const int axis_dims[] = {3, 1, 1, 1};
196 const int32_t axis_values[] = {3};
197 const int output_dims[] = {3, 1, 1, 1};
198 const int32_t goldens[] = {0};
199
200 float input_scale = 0.5;
201 int input_zero_point = -9;
202 int8_t input_quantized[input_size];
203
204 tflite::testing::TestArgMinMaxQuantized(
205 input_dims, input_values, input_quantized, input_scale, input_zero_point,
206 axis_dims, axis_values, output_dims, output_data, goldens, true);
207 }
208
TF_LITE_MICRO_TEST(GetMaxArgMulDimensions)209 TF_LITE_MICRO_TEST(GetMaxArgMulDimensions) {
210 int32_t output_data[2];
211 const int input_size = 8;
212 const int input_dims[] = {4, 1, 1, 2, 4};
213 const float input_values[] = {1, 2, 7, 8, 1, 9, 7, 3};
214 const int axis_dims[] = {3, 1, 1, 1};
215 const int32_t axis_values[] = {3};
216 const int output_dims[] = {3, 1, 1, 2};
217 const int32_t goldens[] = {3, 1};
218
219 float input_scale = 0.5;
220 int input_zero_point = -9;
221 int8_t input_quantized[input_size];
222
223 tflite::testing::TestArgMinMaxQuantized(
224 input_dims, input_values, input_quantized, input_scale, input_zero_point,
225 axis_dims, axis_values, output_dims, output_data, goldens, false);
226 }
227
TF_LITE_MICRO_TEST(GetMinArgMulDimensions)228 TF_LITE_MICRO_TEST(GetMinArgMulDimensions) {
229 int32_t output_data[2];
230 const int input_size = 8;
231 const int input_dims[] = {4, 1, 1, 2, 4};
232 const float input_values[] = {1, 2, 7, 8, 1, 9, 7, 3};
233 const int axis_dims[] = {3, 1, 1, 1};
234 const int32_t axis_values[] = {3};
235 const int output_dims[] = {3, 1, 1, 2};
236 const int32_t goldens[] = {0, 0};
237
238 float input_scale = 0.5;
239 int input_zero_point = -9;
240 int8_t input_quantized[input_size];
241
242 tflite::testing::TestArgMinMaxQuantized(
243 input_dims, input_values, input_quantized, input_scale, input_zero_point,
244 axis_dims, axis_values, output_dims, output_data, goldens, true);
245 }
246
TF_LITE_MICRO_TEST(GetMaxArgNegativeAxis)247 TF_LITE_MICRO_TEST(GetMaxArgNegativeAxis) {
248 const int input_size = 8;
249 const int output_size = 4;
250 const int input_dims[] = {4, 1, 1, 2, 4};
251 const float input_values[] = {1, 2, 7, 8, 1, 9, 7, 3};
252 const int axis_dims[] = {3, 1, 1, 1};
253 const int32_t axis_values[] = {-2};
254 const int output_dims[] = {3, 1, 1, 4};
255 const int32_t goldens[] = {0, 1, 0, 0};
256
257 float input_scale = 0.5;
258 int input_zero_point = -9;
259 int32_t output_data[output_size];
260 int8_t input_quantized[input_size];
261
262 tflite::testing::TestArgMinMaxQuantized(
263 input_dims, input_values, input_quantized, input_scale, input_zero_point,
264 axis_dims, axis_values, output_dims, output_data, goldens, false);
265 }
266
267 TF_LITE_MICRO_TESTS_END
268