• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstdint>
17 
18 #include "tensorflow/lite/c/builtin_op_data.h"
19 #include "tensorflow/lite/c/common.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 namespace {
27 
28 // Shapes and values for mixed broadcast tests.
29 const int broadcast_output_dims_count = 36;
30 const int broadcast_num_shapes = 4;
31 
32 const int broadcast_input1_shape[] = {4, 2, 3, 1, 2};
33 const float broadcast_input1_values[] = {-0.3, 2.3, 0.9,  0.5, 0.8, -1.1,
34                                          1.2,  2.8, -1.6, 0.0, 0.7, -2.2};
35 const float broadcast_input2_values[] = {-0.2, -0.3, 0.4, -0.5, -1.0, -0.9};
36 const float
37     broadcast_goldens[broadcast_num_shapes][broadcast_output_dims_count] = {
38         {-0.1, 2.6,  -0.7, 2.8,  0.7,  3.2,  1.1, 0.8,  0.5, 1.0,  1.9, 1.4,
39          1.0,  -0.8, 0.4,  -0.6, 1.8,  -0.2, 1.4, 3.1,  0.8, 3.3,  2.2, 3.7,
40          -1.4, 0.3,  -2.0, 0.5,  -0.6, 0.9,  0.9, -1.9, 0.3, -1.7, 1.7, -1.3},
41         {-0.1, 2.6, 0.5, 1.0, 1.8, -0.2, 1.4, 3.1, -2.0, 0.5, 1.7, -1.3},
42         {-0.1, 2.5,  0.0,  2.6,  -0.7, 1.9,  1.1, 0.7,  1.2, 0.8,  0.5, 0.1,
43          1.0,  -0.9, 1.1,  -0.8, 0.4,  -1.5, 1.7, 3.3,  2.2, 3.8,  2.1, 3.7,
44          -1.1, 0.5,  -0.6, 1.0,  -0.7, 0.9,  1.2, -1.7, 1.7, -1.2, 1.6, -1.3},
45         {-0.1, 2.5, 1.2, 0.8, 0.4, -1.5, 1.7, 3.3, -0.6, 1.0, 1.6, -1.3},
46 };
47 
48 const int broadcast_max_shape_size = 5;
49 const int broadcast_input2_shapes[broadcast_num_shapes]
50                                  [broadcast_max_shape_size] = {
51                                      {4, 1, 1, 3, 2},
52                                      {4, 1, 3, 1, 2},
53                                      {4, 2, 1, 3, 1},
54                                      {4, 2, 3, 1, 1},
55 };
56 const int broadcast_output_shapes[broadcast_num_shapes]
57                                  [broadcast_max_shape_size] = {
58                                      {4, 2, 3, 3, 2},
59                                      {4, 2, 3, 1, 2},
60                                      {4, 2, 3, 3, 2},
61                                      {4, 2, 3, 1, 2},
62 };
63 
64 template <typename T>
ValidateSubGoldens(TfLiteTensor * tensors,int tensors_size,const T * golden,T * output,int output_size,TfLiteFusedActivation activation,float tolerance=1e-5)65 void ValidateSubGoldens(TfLiteTensor* tensors, int tensors_size,
66                         const T* golden, T* output, int output_size,
67                         TfLiteFusedActivation activation,
68                         float tolerance = 1e-5) {
69   TfLiteSubParams builtin_data;
70   builtin_data.activation = activation;
71 
72   int inputs_array_data[] = {2, 0, 1};
73   TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
74   int outputs_array_data[] = {1, 2};
75   TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
76 
77   const TfLiteRegistration registration = tflite::ops::micro::Register_SUB();
78   micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
79                              outputs_array, &builtin_data);
80 
81   TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
82   TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
83 
84   for (int i = 0; i < output_size; ++i) {
85     TF_LITE_MICRO_EXPECT_NEAR(golden[i], output[i], tolerance);
86   }
87 }
88 
TestSubFloat(const int * input1_dims_data,const float * input1_data,const int * input2_dims_data,const float * input2_data,const int * output_dims_data,const float * expected_output,TfLiteFusedActivation activation,float * output_data)89 void TestSubFloat(const int* input1_dims_data, const float* input1_data,
90                   const int* input2_dims_data, const float* input2_data,
91                   const int* output_dims_data, const float* expected_output,
92                   TfLiteFusedActivation activation, float* output_data) {
93   TfLiteIntArray* input1_dims = IntArrayFromInts(input1_dims_data);
94   TfLiteIntArray* input2_dims = IntArrayFromInts(input2_dims_data);
95   TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
96 
97   constexpr int inputs_size = 2;
98   constexpr int outputs_size = 1;
99   constexpr int tensors_size = inputs_size + outputs_size;
100   TfLiteTensor tensors[tensors_size] = {
101       CreateTensor(input1_data, input1_dims),
102       CreateTensor(input2_data, input2_dims),
103       CreateTensor(output_data, output_dims),
104   };
105 
106   ValidateSubGoldens(tensors, tensors_size, expected_output, output_data,
107                      ElementCount(*output_dims), activation);
108 }
109 
110 template <typename T>
TestSubQuantized(const int * input1_dims_data,const float * input1_data,T * input1_quantized,float input1_scale,int input1_zero_point,const int * input2_dims_data,const float * input2_data,T * input2_quantized,float input2_scale,int input2_zero_point,const int * output_dims_data,const float * golden,T * golden_quantized,float output_scale,int output_zero_point,TfLiteFusedActivation activation,T * output_data)111 void TestSubQuantized(const int* input1_dims_data, const float* input1_data,
112                       T* input1_quantized, float input1_scale,
113                       int input1_zero_point, const int* input2_dims_data,
114                       const float* input2_data, T* input2_quantized,
115                       float input2_scale, int input2_zero_point,
116                       const int* output_dims_data, const float* golden,
117                       T* golden_quantized, float output_scale,
118                       int output_zero_point, TfLiteFusedActivation activation,
119                       T* output_data) {
120   TfLiteIntArray* input1_dims = IntArrayFromInts(input1_dims_data);
121   TfLiteIntArray* input2_dims = IntArrayFromInts(input2_dims_data);
122   TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
123 
124   constexpr int inputs_size = 2;
125   constexpr int outputs_size = 1;
126   constexpr int tensors_size = inputs_size + outputs_size;
127   TfLiteTensor tensors[tensors_size] = {
128       tflite::testing::CreateQuantizedTensor(input1_data, input1_quantized,
129                                              input1_dims, input1_scale,
130                                              input1_zero_point),
131       tflite::testing::CreateQuantizedTensor(input2_data, input2_quantized,
132                                              input2_dims, input2_scale,
133                                              input2_zero_point),
134       tflite::testing::CreateQuantizedTensor(output_data, output_dims,
135                                              output_scale, output_zero_point),
136   };
137   tflite::Quantize(golden, golden_quantized, ElementCount(*output_dims),
138                    output_scale, output_zero_point);
139 
140   ValidateSubGoldens(tensors, tensors_size, golden_quantized, output_data,
141                      ElementCount(*output_dims), activation);
142 }
143 
144 }  // namespace
145 }  // namespace testing
146 }  // namespace tflite
147 
148 TF_LITE_MICRO_TESTS_BEGIN
149 
TF_LITE_MICRO_TEST(FloatSubNoActivation)150 TF_LITE_MICRO_TEST(FloatSubNoActivation) {
151   const int output_dims_count = 4;
152   const int inout_shape[] = {4, 1, 2, 2, 1};
153   const float input1_values[] = {-2.0, 0.2, 0.7, 0.8};
154   const float input2_values[] = {0.1, 0.2, 0.3, 0.5};
155   const float golden_values[] = {-2.1, 0.0, 0.4, 0.3};
156   float output_data[output_dims_count];
157   tflite::testing::TestSubFloat(inout_shape, input1_values, inout_shape,
158                                 input2_values, inout_shape, golden_values,
159                                 kTfLiteActNone, output_data);
160 }
161 
TF_LITE_MICRO_TEST(FloatSubActivationRelu1)162 TF_LITE_MICRO_TEST(FloatSubActivationRelu1) {
163   const int output_dims_count = 4;
164   const int inout_shape[] = {4, 1, 2, 2, 1};
165   const float input1_values[] = {-2.0, 0.2, 2.0, 0.8};
166   const float input2_values[] = {2.0, 0.2, 0.3, 0.5};
167   const float golden_values[] = {-1.0, 0.0, 1.0, 0.3};
168 
169   float output_data[output_dims_count];
170   tflite::testing::TestSubFloat(inout_shape, input1_values, inout_shape,
171                                 input2_values, inout_shape, golden_values,
172                                 kTfLiteActReluN1To1, output_data);
173 }
174 
TF_LITE_MICRO_TEST(FloatSubVariousInputShapes)175 TF_LITE_MICRO_TEST(FloatSubVariousInputShapes) {
176   const int output_dims_count = 6;
177   float output_data[output_dims_count];
178 
179   const float input1_values[] = {-2.0, 0.2, 0.7, 0.8, 1.1, 2.0};
180   const float input2_values[] = {0.1, 0.2, 0.3, 0.5, 1.1, 0.1};
181   const float expected_output[] = {-2.1, 0.0, 0.4, 0.3, 0.0, 1.9};
182 
183   constexpr int num_shapes = 4;
184   constexpr int max_shape_size = 5;
185   const int test_shapes[num_shapes][max_shape_size] = {
186       {1, 6},
187       {2, 2, 3},
188       {3, 2, 1, 3},
189       {4, 1, 3, 1, 2},
190   };
191 
192   for (int i = 0; i < num_shapes; ++i) {
193     tflite::testing::TestSubFloat(test_shapes[i], input1_values, test_shapes[i],
194                                   input2_values, test_shapes[i],
195                                   expected_output, kTfLiteActNone, output_data);
196   }
197 }
198 
TF_LITE_MICRO_TEST(FloatSubWithScalarBroadcast)199 TF_LITE_MICRO_TEST(FloatSubWithScalarBroadcast) {
200   const int output_dims_count = 6;
201   float output_data[output_dims_count];
202 
203   const float input1_values[] = {-2.0, 0.2, 0.7, 0.8, 1.1, 2.0};
204   const int input2_shape[] = {0};
205   const float input2_values[] = {0.1};
206   const float expected_output[] = {-2.1, 0.1, 0.6, 0.7, 1.0, 1.9};
207 
208   constexpr int num_shapes = 4;
209   constexpr int max_shape_size = 5;
210   const int test_shapes[num_shapes][max_shape_size] = {
211       {1, 6},
212       {2, 2, 3},
213       {3, 2, 1, 3},
214       {4, 1, 3, 1, 2},
215   };
216 
217   for (int i = 0; i < num_shapes; ++i) {
218     tflite::testing::TestSubFloat(test_shapes[i], input1_values, input2_shape,
219                                   input2_values, test_shapes[i],
220                                   expected_output, kTfLiteActNone, output_data);
221   }
222 }
223 
TF_LITE_MICRO_TEST(QuantizedSubNoActivationUint8)224 TF_LITE_MICRO_TEST(QuantizedSubNoActivationUint8) {
225   const float scales[] = {0.25, 0.5, 1.0};
226   const int zero_points[] = {125, 129, 135};
227   const int output_dims_count = 4;
228   const int inout_shape[] = {4, 1, 2, 2, 1};
229   const float input1_values[] = {-2.01, -1.01, -0.01, 0.98};
230   const float input2_values[] = {-1.01, -1.99, -2.99, -4.02};
231   const float golden_values[] = {-1, 1, 3, 5};
232 
233   uint8_t input1_quantized[output_dims_count];
234   uint8_t input2_quantized[output_dims_count];
235   uint8_t golden_quantized[output_dims_count];
236   uint8_t output[output_dims_count];
237 
238   tflite::testing::TestSubQuantized(
239       inout_shape, input1_values, input1_quantized, scales[0], zero_points[0],
240       inout_shape, input2_values, input2_quantized, scales[1], zero_points[1],
241       inout_shape, golden_values, golden_quantized, scales[2], zero_points[2],
242       kTfLiteActNone, output);
243 }
244 
TF_LITE_MICRO_TEST(QuantizedSubNoActivationInt8)245 TF_LITE_MICRO_TEST(QuantizedSubNoActivationInt8) {
246   const float scales[] = {0.25, 0.5, 1.0};
247   const int zero_points[] = {-10, 4, 13};
248   const int output_dims_count = 4;
249   const int inout_shape[] = {4, 1, 2, 2, 1};
250   const float input1_values[] = {-2.01, -1.01, -0.01, 0.98};
251   const float input2_values[] = {-1.01, -1.99, -2.99, -4.02};
252   const float golden_values[] = {-1, 1, 3, 5};
253 
254   int8_t input1_quantized[output_dims_count];
255   int8_t input2_quantized[output_dims_count];
256   int8_t golden_quantized[output_dims_count];
257   int8_t output[output_dims_count];
258 
259   tflite::testing::TestSubQuantized(
260       inout_shape, input1_values, input1_quantized, scales[0], zero_points[0],
261       inout_shape, input2_values, input2_quantized, scales[1], zero_points[1],
262       inout_shape, golden_values, golden_quantized, scales[2], zero_points[2],
263       kTfLiteActNone, output);
264 }
265 
TF_LITE_MICRO_TEST(QuantizedSubActivationRelu1Uint8)266 TF_LITE_MICRO_TEST(QuantizedSubActivationRelu1Uint8) {
267   const float scales[] = {0.25, 0.5, 1.0};
268   const int zero_points[] = {125, 129, 135};
269   const int output_dims_count = 4;
270   const int inout_shape[] = {4, 1, 2, 2, 1};
271   const float input1_values[] = {-2.01, -1.01, -0.01, 0.98};
272   const float input2_values[] = {-1.01, -1.99, -2.99, -4.02};
273   const float golden_values[] = {-1, 1, 1, 1};
274 
275   uint8_t input1_quantized[output_dims_count];
276   uint8_t input2_quantized[output_dims_count];
277   uint8_t golden_quantized[output_dims_count];
278   uint8_t output[output_dims_count];
279 
280   tflite::testing::TestSubQuantized(
281       inout_shape, input1_values, input1_quantized, scales[0], zero_points[0],
282       inout_shape, input2_values, input2_quantized, scales[1], zero_points[1],
283       inout_shape, golden_values, golden_quantized, scales[2], zero_points[2],
284       kTfLiteActReluN1To1, output);
285 }
286 
TF_LITE_MICRO_TEST(QuantizedSubActivationRelu1Int8)287 TF_LITE_MICRO_TEST(QuantizedSubActivationRelu1Int8) {
288   const float scales[] = {0.25, 0.5, 1.0};
289   const int zero_points[] = {-10, 4, 13};
290   const int output_dims_count = 4;
291   const int inout_shape[] = {4, 1, 2, 2, 1};
292   const float input1_values[] = {-2.01, -1.01, -0.01, 0.98};
293   const float input2_values[] = {-1.01, -1.99, -2.99, -4.02};
294   const float golden_values[] = {-1, 1, 1, 1};
295 
296   int8_t input1_quantized[output_dims_count];
297   int8_t input2_quantized[output_dims_count];
298   int8_t golden_quantized[output_dims_count];
299   int8_t output[output_dims_count];
300 
301   tflite::testing::TestSubQuantized(
302       inout_shape, input1_values, input1_quantized, scales[0], zero_points[0],
303       inout_shape, input2_values, input2_quantized, scales[1], zero_points[1],
304       inout_shape, golden_values, golden_quantized, scales[2], zero_points[2],
305       kTfLiteActReluN1To1, output);
306 }
307 
TF_LITE_MICRO_TEST(QuantizedSubVariousInputShapesUint8)308 TF_LITE_MICRO_TEST(QuantizedSubVariousInputShapesUint8) {
309   const float scales[] = {0.1, 0.05, 0.1};
310   const int zero_points[] = {120, 130, 139};
311   const int output_dims_count = 6;
312 
313   constexpr int num_shapes = 4;
314   constexpr int max_shape_size = 5;
315   const int test_shapes[num_shapes][max_shape_size] = {
316       {1, 6},
317       {2, 2, 3},
318       {3, 2, 1, 3},
319       {4, 1, 3, 1, 2},
320   };
321 
322   const float input1_values[] = {-2.0, 0.2, 0.7, 0.8, 1.1, 2.0};
323   const float input2_values[] = {-0.1, -0.2, -0.3, -0.5, -1.1, -0.1};
324   const float golden_values[] = {-1.9, 0.4, 1.0, 1.3, 2.2, 2.1};
325 
326   uint8_t input1_quantized[output_dims_count];
327   uint8_t input2_quantized[output_dims_count];
328   uint8_t golden_quantized[output_dims_count];
329   uint8_t output[output_dims_count];
330 
331   for (int i = 0; i < num_shapes; i++) {
332     tflite::testing::TestSubQuantized(
333         test_shapes[i], input1_values, input1_quantized, scales[0],
334         zero_points[0], test_shapes[i], input2_values, input2_quantized,
335         scales[1], zero_points[1], test_shapes[i], golden_values,
336         golden_quantized, scales[2], zero_points[2], kTfLiteActNone, output);
337   }
338 }
339 
TF_LITE_MICRO_TEST(QuantizedSubVariousInputShapesInt8)340 TF_LITE_MICRO_TEST(QuantizedSubVariousInputShapesInt8) {
341   const float scales[] = {0.1, 0.05, 0.1};
342   const int zero_points[] = {-9, 5, 14};
343   const int output_dims_count = 6;
344 
345   constexpr int num_shapes = 4;
346   constexpr int max_shape_size = 5;
347   const int test_shapes[num_shapes][max_shape_size] = {
348       {1, 6},
349       {2, 2, 3},
350       {3, 2, 1, 3},
351       {4, 1, 3, 1, 2},
352   };
353 
354   const float input1_values[] = {-2.0, 0.2, 0.7, 0.8, 1.1, 2.0};
355   const float input2_values[] = {-0.1, -0.2, -0.3, -0.5, -1.1, -0.1};
356   const float golden_values[] = {-1.9, 0.4, 1.0, 1.3, 2.2, 2.1};
357 
358   int8_t input1_quantized[output_dims_count];
359   int8_t input2_quantized[output_dims_count];
360   int8_t golden_quantized[output_dims_count];
361   int8_t output[output_dims_count];
362 
363   for (int i = 0; i < num_shapes; i++) {
364     tflite::testing::TestSubQuantized(
365         test_shapes[i], input1_values, input1_quantized, scales[0],
366         zero_points[0], test_shapes[i], input2_values, input2_quantized,
367         scales[1], zero_points[1], test_shapes[i], golden_values,
368         golden_quantized, scales[2], zero_points[2], kTfLiteActNone, output);
369   }
370 }
371 
TF_LITE_MICRO_TEST(QuantizedSubWithScalarBroadcastUint8)372 TF_LITE_MICRO_TEST(QuantizedSubWithScalarBroadcastUint8) {
373   const int output_dims_count = 6;
374 
375   const float input1_values[] = {-2.0, 0.2, 0.7, 0.8, 1.1, 2.0};
376   const int input2_shape[] = {0};
377   const float input2_values[] = {-0.1};
378   const float golden[] = {-1.9, 0.3, 0.8, 0.9, 1.2, 2.1};
379 
380   constexpr int num_shapes = 4;
381   constexpr int max_shape_size = 5;
382   const int test_shapes[num_shapes][max_shape_size] = {
383       {1, 6},
384       {2, 2, 3},
385       {3, 2, 1, 3},
386       {4, 1, 3, 1, 2},
387   };
388 
389   const float scales[] = {0.1, 0.1, 0.1};
390   const int zero_points[] = {120, 131, 139};
391 
392   uint8_t input1_quantized[output_dims_count];
393   uint8_t input2_quantized[output_dims_count];
394   uint8_t golden_quantized[output_dims_count];
395   uint8_t output[output_dims_count];
396 
397   for (int i = 0; i < num_shapes; ++i) {
398     tflite::testing::TestSubQuantized(
399         test_shapes[i], input1_values, input1_quantized, scales[0],
400         zero_points[0], input2_shape, input2_values, input2_quantized,
401         scales[1], zero_points[1], test_shapes[i], golden, golden_quantized,
402         scales[2], zero_points[2], kTfLiteActNone, output);
403   }
404 }
TF_LITE_MICRO_TEST(QuantizedSubWithScalarBroadcastFloat)405 TF_LITE_MICRO_TEST(QuantizedSubWithScalarBroadcastFloat) {
406   float output_float[tflite::testing::broadcast_output_dims_count];
407 
408   for (int i = 0; i < tflite::testing::broadcast_num_shapes; ++i) {
409     tflite::testing::TestSubFloat(tflite::testing::broadcast_input1_shape,
410                                   tflite::testing::broadcast_input1_values,
411                                   tflite::testing::broadcast_input2_shapes[i],
412                                   tflite::testing::broadcast_input2_values,
413                                   tflite::testing::broadcast_output_shapes[i],
414                                   tflite::testing::broadcast_goldens[i],
415                                   kTfLiteActNone, output_float);
416   }
417 }
418 
TF_LITE_MICRO_TEST(QuantizedSubWithScalarBroadcastInt8)419 TF_LITE_MICRO_TEST(QuantizedSubWithScalarBroadcastInt8) {
420   const int output_dims_count = 6;
421 
422   const float input1_values[] = {-2.0, 0.2, 0.7, 0.8, 1.1, 2.0};
423   const int input2_shape[] = {0};
424   const float input2_values[] = {-0.1};
425   const float golden[] = {-1.9, 0.3, 0.8, 0.9, 1.2, 2.1};
426 
427   constexpr int num_shapes = 4;
428   constexpr int max_shape_size = 5;
429   const int test_shapes[num_shapes][max_shape_size] = {
430       {1, 6},
431       {2, 2, 3},
432       {3, 2, 1, 3},
433       {4, 1, 3, 1, 2},
434   };
435 
436   const float scales[] = {0.1, 0.05, 0.05};
437   const int zero_points[] = {-8, 4, 12};
438 
439   int8_t input1_quantized[output_dims_count];
440   int8_t input2_quantized[output_dims_count];
441   int8_t golden_quantized[output_dims_count];
442   int8_t output[output_dims_count];
443 
444   for (int i = 0; i < num_shapes; ++i) {
445     tflite::testing::TestSubQuantized(
446         test_shapes[i], input1_values, input1_quantized, scales[0],
447         zero_points[0], input2_shape, input2_values, input2_quantized,
448         scales[1], zero_points[1], test_shapes[i], golden, golden_quantized,
449         scales[2], zero_points[2], kTfLiteActNone, output);
450   }
451 }
452 
TF_LITE_MICRO_TEST(QuantizedSubWithMixedBroadcastUint8)453 TF_LITE_MICRO_TEST(QuantizedSubWithMixedBroadcastUint8) {
454   const float scales[] = {0.1, 0.05, 0.1};
455   const int zero_points[] = {127, 131, 139};
456   uint8_t input1_quantized[tflite::testing::broadcast_output_dims_count];
457   uint8_t input2_quantized[tflite::testing::broadcast_output_dims_count];
458   uint8_t golden_quantized[tflite::testing::broadcast_output_dims_count];
459   uint8_t output[tflite::testing::broadcast_output_dims_count];
460 
461   for (int i = 0; i < tflite::testing::broadcast_num_shapes; ++i) {
462     tflite::testing::TestSubQuantized(
463         tflite::testing::broadcast_input1_shape,
464         tflite::testing::broadcast_input1_values, input1_quantized, scales[0],
465         zero_points[0], tflite::testing::broadcast_input2_shapes[i],
466         tflite::testing::broadcast_input2_values, input2_quantized, scales[1],
467         zero_points[1], tflite::testing::broadcast_output_shapes[i],
468         tflite::testing::broadcast_goldens[i], golden_quantized, scales[2],
469         zero_points[2], kTfLiteActNone, output);
470   }
471 }
472 
TF_LITE_MICRO_TEST(QuantizedSubWithMixedBroadcastInt8)473 TF_LITE_MICRO_TEST(QuantizedSubWithMixedBroadcastInt8) {
474   const float scales[] = {0.1, 0.05, 0.1};
475   const int zero_points[] = {-10, -5, 7};
476   int8_t input1_quantized[tflite::testing::broadcast_output_dims_count];
477   int8_t input2_quantized[tflite::testing::broadcast_output_dims_count];
478   int8_t golden_quantized[tflite::testing::broadcast_output_dims_count];
479   int8_t output[tflite::testing::broadcast_output_dims_count];
480 
481   for (int i = 0; i < tflite::testing::broadcast_num_shapes; ++i) {
482     tflite::testing::TestSubQuantized(
483         tflite::testing::broadcast_input1_shape,
484         tflite::testing::broadcast_input1_values, input1_quantized, scales[0],
485         zero_points[0], tflite::testing::broadcast_input2_shapes[i],
486         tflite::testing::broadcast_input2_values, input2_quantized, scales[1],
487         zero_points[1], tflite::testing::broadcast_output_shapes[i],
488         tflite::testing::broadcast_goldens[i], golden_quantized, scales[2],
489         zero_points[2], kTfLiteActNone, output);
490   }
491 }
492 
493 TF_LITE_MICRO_TESTS_END
494