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