• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2020 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 constexpr int tanh_vec_size = 90;
27 
28 const float tanh_input_vec_fp[tanh_vec_size] = {
29     -8.0000000000, -7.8181818182, -7.6363636364, -7.4545454545, -7.2727272727,
30     -7.0909090909, -6.9090909091, -6.7272727273, -6.5454545455, -6.3636363636,
31     -6.1818181818, -6.0000000000, -5.8181818182, -5.6363636364, -5.4545454545,
32     -5.2727272727, -5.0909090909, -4.9090909091, -4.7272727273, -4.5454545455,
33     -4.3636363636, -4.1818181818, -4.0000000000, -3.8181818182, -3.6363636364,
34     -3.4545454545, -3.2727272727, -3.0909090909, -2.9090909091, -2.7272727273,
35     -2.5454545455, -2.3636363636, -2.1818181818, -2.0000000000, -1.8181818182,
36     -1.6363636364, -1.4545454545, -1.2727272727, -1.0909090909, -0.9090909091,
37     -0.7272727273, -0.5454545455, -0.3636363636, -0.1818181818, 0.0000000000,
38     0.1818181818,  0.3636363636,  0.5454545455,  0.7272727273,  0.9090909091,
39     1.0909090909,  1.2727272727,  1.4545454545,  1.6363636364,  1.8181818182,
40     2.0000000000,  2.1818181818,  2.3636363636,  2.5454545455,  2.7272727273,
41     2.9090909091,  3.0909090909,  3.2727272727,  3.4545454545,  3.6363636364,
42     3.8181818182,  4.0000000000,  4.1818181818,  4.3636363636,  4.5454545455,
43     4.7272727273,  4.9090909091,  5.0909090909,  5.2727272727,  5.4545454545,
44     5.6363636364,  5.8181818182,  6.0000000000,  6.1818181818,  6.3636363636,
45     6.5454545455,  6.7272727273,  6.9090909091,  7.0909090909,  7.2727272727,
46     7.4545454545,  7.6363636364,  7.8181818182,  8.0000000000};
47 
48 const float tanh_output_vec_fp[tanh_vec_size] = {
49     -0.9999997749, -0.9999996762, -0.9999995342, -0.9999993300, -0.9999990361,
50     -0.9999986134, -0.9999980053, -0.9999971306, -0.9999958722, -0.9999940619,
51     -0.9999914578, -0.9999877117, -0.9999823226, -0.9999745703, -0.9999634183,
52     -0.9999473758, -0.9999242982, -0.9998911009, -0.9998433469, -0.9997746542,
53     -0.9996758446, -0.9995337191, -0.9993292997, -0.9990353053, -0.9986125310,
54     -0.9980046622, -0.9971308601, -0.9958751909, -0.9940716137, -0.9914827859,
55     -0.9877703933, -0.9824541388, -0.9748561217, -0.9640275801, -0.9486568273,
56     -0.9269625051, -0.8965880154, -0.8545351057, -0.7972097087, -0.7206956332,
57     -0.6213939966, -0.4971057414, -0.3484130125, -0.1798408185, 0.0000000000,
58     0.1798408185,  0.3484130125,  0.4971057414,  0.6213939966,  0.7206956332,
59     0.7972097087,  0.8545351057,  0.8965880154,  0.9269625051,  0.9486568273,
60     0.9640275801,  0.9748561217,  0.9824541388,  0.9877703933,  0.9914827859,
61     0.9940716137,  0.9958751909,  0.9971308601,  0.9980046622,  0.9986125310,
62     0.9990353053,  0.9993292997,  0.9995337191,  0.9996758446,  0.9997746542,
63     0.9998433469,  0.9998911009,  0.9999242982,  0.9999473758,  0.9999634183,
64     0.9999745703,  0.9999823226,  0.9999877117,  0.9999914578,  0.9999940619,
65     0.9999958722,  0.9999971306,  0.9999980053,  0.9999986134,  0.9999990361,
66     0.9999993300,  0.9999995342,  0.9999996762,  0.9999997749};
67 
TestTanhFloat(const int input_dims_data[],const float * input_data,const float * expected_output_data,const int output_dims_data[],float * output_data,const float tolerance)68 void TestTanhFloat(const int input_dims_data[], const float* input_data,
69                    const float* expected_output_data,
70                    const int output_dims_data[], float* output_data,
71                    const float tolerance) {
72   TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
73   TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
74   const int output_elements_count = ElementCount(*output_dims);
75 
76   constexpr int inputs_size = 1;
77   constexpr int outputs_size = 1;
78   constexpr int tensors_size = inputs_size + outputs_size;
79   TfLiteTensor tensors[tensors_size] = {
80       CreateTensor(input_data, input_dims),
81       CreateTensor(output_data, output_dims),
82   };
83 
84   int inputs_array_data[] = {1, 0};
85   TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
86   int outputs_array_data[] = {1, 1};
87   TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
88 
89   const TfLiteRegistration registration = tflite::ops::micro::Register_TANH();
90   micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
91                              outputs_array, /*builtin_data=*/nullptr);
92 
93   TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
94   TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
95 
96   for (int i = 0; i < output_elements_count; ++i) {
97     TF_LITE_MICRO_EXPECT_NEAR(expected_output_data[i], output_data[i],
98                               tolerance);
99   }
100 }
101 
102 template <typename T>
TestTanhQuantized(const int input_dims_data[],const float * input_data,T * input_quantized,float input_scale,int input_zero_point,const float * expected_output_data,T * expected_output_quantized,const int output_dims_data[],float output_scale,int output_zero_point,T * output_quantized,const int tolerance)103 void TestTanhQuantized(const int input_dims_data[], const float* input_data,
104                        T* input_quantized, float input_scale,
105                        int input_zero_point, const float* expected_output_data,
106                        T* expected_output_quantized,
107                        const int output_dims_data[], float output_scale,
108                        int output_zero_point, T* output_quantized,
109                        const int tolerance) {
110   static_assert(sizeof(T) == 1, "Valid only for 8bit data types");
111   TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
112   TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
113   const int output_elements_count = ElementCount(*output_dims);
114 
115   tflite::Quantize(expected_output_data, expected_output_quantized,
116                    output_elements_count, output_scale, output_zero_point);
117 
118   constexpr int inputs_size = 1;
119   constexpr int outputs_size = 1;
120   constexpr int tensors_size = inputs_size + outputs_size;
121   TfLiteTensor tensors[tensors_size] = {
122       CreateQuantizedTensor(input_data, input_quantized, input_dims,
123                             input_scale, input_zero_point),
124       CreateQuantizedTensor(output_quantized, output_dims, output_scale,
125                             output_zero_point)};
126 
127   int inputs_array_data[] = {1, 0};
128   TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
129   int outputs_array_data[] = {1, 1};
130   TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
131 
132   const TfLiteRegistration registration = tflite::ops::micro::Register_TANH();
133   micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
134                              outputs_array, /*builtin_data=*/nullptr);
135 
136   TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
137   TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
138 
139   for (int i = 0; i < output_elements_count; ++i) {
140     TF_LITE_MICRO_EXPECT_NEAR(expected_output_quantized[i], output_quantized[i],
141                               tolerance);
142   }
143 }
144 
145 }  // namespace
146 }  // namespace testing
147 }  // namespace tflite
148 
149 TF_LITE_MICRO_TESTS_BEGIN
150 
TF_LITE_MICRO_TEST(SimpleTestTanhFloat)151 TF_LITE_MICRO_TEST(SimpleTestTanhFloat) {
152   using tflite::testing::tanh_input_vec_fp;
153   using tflite::testing::tanh_output_vec_fp;
154   using tflite::testing::tanh_vec_size;
155 
156   const int input_shape[] = {2, 1, tanh_vec_size};
157   const int output_shape[] = {2, 1, tanh_vec_size};
158 
159   float output_data[tanh_vec_size];
160   tflite::testing::TestTanhFloat(  //
161       input_shape,                 // Input shape.
162       tanh_input_vec_fp,           // Input data
163       tanh_output_vec_fp,          // Expected results.
164       output_shape,                // Output shape.
165       output_data, 1e-7 /* tolerance */);
166 }
167 
TF_LITE_MICRO_TEST(SimpleTestTanhUInt8)168 TF_LITE_MICRO_TEST(SimpleTestTanhUInt8) {
169   using tflite::testing::tanh_input_vec_fp;
170   using tflite::testing::tanh_output_vec_fp;
171   using tflite::testing::tanh_vec_size;
172 
173   const float input_scale = 16 / 256.f;
174   const int input_zero_point = 128;
175   const float output_scale = 1.99999955f / 256.f;
176   const int output_zero_point = 128;
177 
178   const int input_shape[] = {2, 1, tanh_vec_size};
179   const int output_shape[] = {2, 1, tanh_vec_size};
180 
181   uint8_t input_quantized[tanh_vec_size];
182   uint8_t expected_output_quantized[tanh_vec_size];
183   uint8_t output_quantized[tanh_vec_size];
184   tflite::testing::TestTanhQuantized<uint8_t>(        //
185       input_shape,                                    // Input shape.
186       tanh_input_vec_fp, input_quantized,             // Input data.
187       input_scale, input_zero_point,                  // Input quantized info.
188       tanh_output_vec_fp, expected_output_quantized,  // Expected results.
189       output_shape,                                   // Output shape.
190       output_scale, output_zero_point,                // Output quantized info.
191       output_quantized,                               // Operation results
192       2                                               // Tolerance.
193   );
194 }
195 
TF_LITE_MICRO_TEST(SimpleTestTanhUInt8)196 TF_LITE_MICRO_TEST(SimpleTestTanhUInt8) {
197   using tflite::testing::tanh_input_vec_fp;
198   using tflite::testing::tanh_output_vec_fp;
199   using tflite::testing::tanh_vec_size;
200 
201   const float input_scale = 16 / 256.f;
202   const int input_zero_point = 0;
203   const float output_scale = 1.99999955f / 256.f;
204   const int output_zero_point = 0;
205 
206   const int input_shape[] = {2, 1, tanh_vec_size};
207   const int output_shape[] = {2, 1, tanh_vec_size};
208 
209   int8_t input_quantized[tanh_vec_size];
210   int8_t expected_output_quantized[tanh_vec_size];
211   int8_t output_quantized[tanh_vec_size];
212   tflite::testing::TestTanhQuantized<int8_t>(         //
213       input_shape,                                    // Input shape.
214       tanh_input_vec_fp, input_quantized,             // Input data.
215       input_scale, input_zero_point,                  // Input quantized info.
216       tanh_output_vec_fp, expected_output_quantized,  // Expected results.
217       output_shape,                                   // Output shape.
218       output_scale, output_zero_point,                // Output quantized info.
219       output_quantized,                               // Operation results
220       2                                               // Tolerance.
221   );
222 }
223 
224 TF_LITE_MICRO_TESTS_END
225