• 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 "tensorflow/lite/c/builtin_op_data.h"
17 #include "tensorflow/lite/c/common.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 const int flat_size_simple = 4;
27 const float scale_simple = 0.01;
28 const int dims_simple[] = {4, 1, 2, 2, 1};
29 const float input1_simple[] = {-0.8, 0.2, 0.9, 0.7};
30 const float input2_simple[] = {0.6, 0.4, 0.9, 0.8};
31 const float golden_simple[] = {-0.48, 0.08, 0.81, 0.56};
32 const float golden_simple_relu[] = {0.0, 0.08, 0.81, 0.56};
33 
34 const int flat_size_broadcast = 6;
35 const float input_scale_broadcast = 0.05f;
36 const float output_scale_broadcast = 0.01f;
37 const int dims_broadcast[] = {4, 1, 3, 1, 2};
38 const int dims_scalar_broadcast[] = {1, 1};
39 const float input1_broadcast[] = {-2.0, 0.2, 0.7, 0.8, 1.1, 2.0};
40 const float input2_broadcast[] = {0.1};
41 const float golden_broadcast[] = {-0.2, 0.02, 0.07, 0.08, 0.11, 0.2};
42 const float golden_broadcast_relu[] = {0, 0.02, 0.07, 0.08, 0.11, 0.2};
43 
44 template <typename T>
ValidateMulGoldens(TfLiteTensor * tensors,int tensors_size,TfLiteFusedActivation activation,const T * golden,int output_len,float tolerance,T * output)45 void ValidateMulGoldens(TfLiteTensor* tensors, int tensors_size,
46                         TfLiteFusedActivation activation, const T* golden,
47                         int output_len, float tolerance, T* output) {
48   TfLiteMulParams builtin_data = {
49       .activation = activation,
50   };
51 
52   int inputs_array_data[] = {2, 0, 1};
53   TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
54   int outputs_array_data[] = {1, 2};
55   TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
56 
57   const TfLiteRegistration registration = tflite::ops::micro::Register_MUL();
58   micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
59                              outputs_array,
60                              reinterpret_cast<void*>(&builtin_data));
61 
62   TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
63   TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
64 
65   for (int i = 0; i < output_len; i++) {
66     TF_LITE_MICRO_EXPECT_NEAR(golden[i], output[i], tolerance);
67   }
68 }
69 
TestMulFloat(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 * golden,float * output_data,TfLiteFusedActivation activation)70 void TestMulFloat(const int* input1_dims_data, const float* input1_data,
71                   const int* input2_dims_data, const float* input2_data,
72                   const int* output_dims_data, const float* golden,
73                   float* output_data, TfLiteFusedActivation activation) {
74   TfLiteIntArray* input1_dims = IntArrayFromInts(input1_dims_data);
75   TfLiteIntArray* input2_dims = IntArrayFromInts(input2_dims_data);
76   TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
77   const int output_dims_count = ElementCount(*output_dims);
78 
79   constexpr int inputs_size = 2;
80   constexpr int outputs_size = 1;
81   constexpr int tensors_size = inputs_size + outputs_size;
82   TfLiteTensor tensors[tensors_size] = {
83       CreateTensor(input1_data, input1_dims),
84       CreateTensor(input2_data, input2_dims),
85       CreateTensor(output_data, output_dims),
86   };
87 
88   ValidateMulGoldens(tensors, tensors_size, activation, golden,
89                      output_dims_count, 1e-5, output_data);
90 }
91 
92 template <typename T>
TestMulQuantized(const int * input1_dims_data,const float * input1_data,T * input1_quantized,const int * input2_dims_data,const float * input2_data,T * input2_quantized,const float input_scale,const int input_zero_point,const int * output_dims_data,const float * golden,T * golden_quantized,const float output_scale,const int output_zero_point,T * output_data,TfLiteFusedActivation activation)93 void TestMulQuantized(const int* input1_dims_data, const float* input1_data,
94                       T* input1_quantized, const int* input2_dims_data,
95                       const float* input2_data, T* input2_quantized,
96                       const float input_scale, const int input_zero_point,
97                       const int* output_dims_data, const float* golden,
98                       T* golden_quantized, const float output_scale,
99                       const int output_zero_point, T* output_data,
100                       TfLiteFusedActivation activation) {
101   TfLiteIntArray* input1_dims = IntArrayFromInts(input1_dims_data);
102   TfLiteIntArray* input2_dims = IntArrayFromInts(input2_dims_data);
103   TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
104   const int output_dims_count = ElementCount(*output_dims);
105 
106   constexpr int inputs_size = 2;
107   constexpr int outputs_size = 1;
108   constexpr int tensors_size = inputs_size + outputs_size;
109   TfLiteTensor tensors[tensors_size] = {
110       CreateQuantizedTensor(input1_data, input1_quantized, input1_dims,
111                             input_scale, input_zero_point),
112       CreateQuantizedTensor(input2_data, input2_quantized, input2_dims,
113                             input_scale, input_zero_point),
114       CreateQuantizedTensor(output_data, output_dims, output_scale,
115                             output_zero_point)};
116 
117   Quantize(golden, golden_quantized, output_dims_count, output_scale,
118            output_zero_point);
119 
120   ValidateMulGoldens(tensors, tensors_size, activation, golden_quantized,
121                      output_dims_count, 1.0f, output_data);
122 }
123 
124 }  // namespace
125 
126 }  // namespace testing
127 }  // namespace tflite
128 
129 TF_LITE_MICRO_TESTS_BEGIN
130 
TF_LITE_MICRO_TEST(SimpleFloatNoAcativationShouldMatchGolden)131 TF_LITE_MICRO_TEST(SimpleFloatNoAcativationShouldMatchGolden) {
132   float output_data[tflite::testing::flat_size_simple];
133 
134   tflite::testing::TestMulFloat(
135       tflite::testing::dims_simple, tflite::testing::input1_simple,
136       tflite::testing::dims_simple, tflite::testing::input2_simple,
137       tflite::testing::dims_simple, tflite::testing::golden_simple, output_data,
138       kTfLiteActNone);
139 }
140 
TF_LITE_MICRO_TEST(SimpleFloatReluShouldMatchGolden)141 TF_LITE_MICRO_TEST(SimpleFloatReluShouldMatchGolden) {
142   float output_data[tflite::testing::flat_size_simple];
143 
144   tflite::testing::TestMulFloat(
145       tflite::testing::dims_simple, tflite::testing::input1_simple,
146       tflite::testing::dims_simple, tflite::testing::input2_simple,
147       tflite::testing::dims_simple, tflite::testing::golden_simple_relu,
148       output_data, kTfLiteActRelu);
149 }
150 
TF_LITE_MICRO_TEST(SimpleInt8NoAcativationShouldMatchGolden)151 TF_LITE_MICRO_TEST(SimpleInt8NoAcativationShouldMatchGolden) {
152   int8_t input1_quantized[tflite::testing::flat_size_simple];
153   int8_t input2_quantized[tflite::testing::flat_size_simple];
154   int8_t golden_quantized[tflite::testing::flat_size_simple];
155   int8_t output_data[tflite::testing::flat_size_simple];
156 
157   tflite::testing::TestMulQuantized(
158       tflite::testing::dims_simple, tflite::testing::input1_simple,
159       input1_quantized, tflite::testing::dims_simple,
160       tflite::testing::input2_simple, input2_quantized,
161       tflite::testing::scale_simple, 0, tflite::testing::dims_simple,
162       tflite::testing::golden_simple, golden_quantized,
163       tflite::testing::scale_simple, 0, output_data, kTfLiteActNone);
164 }
165 
TF_LITE_MICRO_TEST(SimpleUInt8NoAcativationShouldMatchGolden)166 TF_LITE_MICRO_TEST(SimpleUInt8NoAcativationShouldMatchGolden) {
167   uint8_t input1_quantized[tflite::testing::flat_size_simple];
168   uint8_t input2_quantized[tflite::testing::flat_size_simple];
169   uint8_t golden_quantized[tflite::testing::flat_size_simple];
170   uint8_t output_data[tflite::testing::flat_size_simple];
171 
172   tflite::testing::TestMulQuantized(
173       tflite::testing::dims_simple, tflite::testing::input1_simple,
174       input1_quantized, tflite::testing::dims_simple,
175       tflite::testing::input2_simple, input2_quantized,
176       tflite::testing::scale_simple, 128, tflite::testing::dims_simple,
177       tflite::testing::golden_simple, golden_quantized,
178       tflite::testing::scale_simple, 128, output_data, kTfLiteActNone);
179 }
180 
TF_LITE_MICRO_TEST(BroadcastFloatNoActivationShouldMatchGolden)181 TF_LITE_MICRO_TEST(BroadcastFloatNoActivationShouldMatchGolden) {
182   float output_data[tflite::testing::flat_size_broadcast];
183 
184   tflite::testing::TestMulFloat(
185       tflite::testing::dims_broadcast, tflite::testing::input1_broadcast,
186       tflite::testing::dims_scalar_broadcast, tflite::testing::input2_broadcast,
187       tflite::testing::dims_broadcast, tflite::testing::golden_broadcast,
188       output_data, kTfLiteActNone);
189 }
190 
TF_LITE_MICRO_TEST(BroadcastFloatReluShouldMatchGolden)191 TF_LITE_MICRO_TEST(BroadcastFloatReluShouldMatchGolden) {
192   float output_data[tflite::testing::flat_size_broadcast];
193 
194   tflite::testing::TestMulFloat(
195       tflite::testing::dims_broadcast, tflite::testing::input1_broadcast,
196       tflite::testing::dims_scalar_broadcast, tflite::testing::input2_broadcast,
197       tflite::testing::dims_broadcast, tflite::testing::golden_broadcast_relu,
198       output_data, kTfLiteActRelu);
199 }
200 
TF_LITE_MICRO_TEST(BroadcastInt8NoAcativationShouldMatchGolden)201 TF_LITE_MICRO_TEST(BroadcastInt8NoAcativationShouldMatchGolden) {
202   int8_t input1_quantized[tflite::testing::flat_size_broadcast];
203   int8_t input2_quantized[tflite::testing::flat_size_broadcast];
204   int8_t golden_quantized[tflite::testing::flat_size_broadcast];
205   int8_t output_data[tflite::testing::flat_size_broadcast];
206 
207   tflite::testing::TestMulQuantized(
208       tflite::testing::dims_broadcast, tflite::testing::input1_broadcast,
209       input1_quantized, tflite::testing::dims_scalar_broadcast,
210       tflite::testing::input2_broadcast, input2_quantized,
211       tflite::testing::input_scale_broadcast, 0,
212       tflite::testing::dims_broadcast, tflite::testing::golden_broadcast,
213       golden_quantized, tflite::testing::output_scale_broadcast, 0, output_data,
214       kTfLiteActNone);
215 }
216 
TF_LITE_MICRO_TEST(BroadcastUInt8NoAcativationShouldMatchGolden)217 TF_LITE_MICRO_TEST(BroadcastUInt8NoAcativationShouldMatchGolden) {
218   uint8_t input1_quantized[tflite::testing::flat_size_broadcast];
219   uint8_t input2_quantized[1];
220   uint8_t golden_quantized[tflite::testing::flat_size_broadcast];
221   uint8_t output_data[tflite::testing::flat_size_broadcast];
222 
223   tflite::testing::TestMulQuantized(
224       tflite::testing::dims_broadcast, tflite::testing::input1_broadcast,
225       input1_quantized, tflite::testing::dims_scalar_broadcast,
226       tflite::testing::input2_broadcast, input2_quantized,
227       tflite::testing::input_scale_broadcast, 128,
228       tflite::testing::dims_broadcast, tflite::testing::golden_broadcast,
229       golden_quantized, tflite::testing::output_scale_broadcast, 128,
230       output_data, kTfLiteActNone);
231 }
232 
233 TF_LITE_MICRO_TESTS_END
234