1 /* Copyright 2017 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 #include "tensorflow/lite/kernels/internal/quantization_util.h"
16
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19
20 namespace tflite {
21 namespace {
22
23 using ::testing::ElementsAreArray;
24 using ::testing::Pair;
25
26 template <class FloatIn, class IntOut>
RunSafeCastTests()27 void RunSafeCastTests() {
28 const IntOut imax = std::numeric_limits<IntOut>::max();
29 EXPECT_GT(imax, 0);
30 const IntOut imin = std::numeric_limits<IntOut>::min();
31 const bool s = std::numeric_limits<IntOut>::is_signed;
32 if (s) {
33 EXPECT_LT(imin, 0);
34 } else {
35 EXPECT_EQ(0, imin);
36 }
37
38 // Some basic tests.
39 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(0.0)), 0);
40 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(-0.0)), 0);
41 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(0.99)), 0);
42 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(1.0)), 1);
43 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(1.01)), 1);
44 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(1.99)), 1);
45 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(2.0)), 2);
46 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(2.01)), 2);
47 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(-0.99)), 0);
48 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(-1.0)), s ? -1 : 0);
49 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(-1.01)), s ? -1 : 0);
50 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(-1.99)), s ? -1 : 0);
51 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(-2.0)), s ? -2 : 0);
52 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(-2.01)), s ? -2 : 0);
53 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(117.9)), 117);
54 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(118.0)), 118);
55 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(118.1)), 118);
56 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(-117.9)), s ? -117 : 0);
57 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(-118.0)), s ? -118 : 0);
58 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(-118.1)), s ? -118 : 0);
59
60 // Some edge cases.
61 EXPECT_EQ(SafeCast<IntOut>(std::numeric_limits<FloatIn>::max()), imax);
62 EXPECT_EQ(SafeCast<IntOut>(std::numeric_limits<FloatIn>::lowest()), imin);
63 EXPECT_EQ(SafeCast<IntOut>(std::numeric_limits<FloatIn>::infinity()), imax);
64 EXPECT_EQ(SafeCast<IntOut>(-std::numeric_limits<FloatIn>::infinity()), imin);
65 EXPECT_EQ(SafeCast<IntOut>(std::numeric_limits<FloatIn>::quiet_NaN()), 0);
66
67 // Some larger numbers.
68 if (sizeof(IntOut) >= 4 && sizeof(FloatIn) > 4) {
69 EXPECT_EQ(SafeCast<IntOut>(static_cast<FloatIn>(0x76543210)), 0x76543210);
70 }
71
72 if (sizeof(FloatIn) > sizeof(IntOut)) {
73 // Check values near imax.
74 EXPECT_EQ(SafeCast<IntOut>(
75 static_cast<FloatIn>(static_cast<FloatIn>(imax) + 0.1)),
76 imax);
77 EXPECT_EQ(SafeCast<IntOut>(
78 static_cast<FloatIn>(static_cast<FloatIn>(imax) + 0.99)),
79 imax);
80 EXPECT_EQ(SafeCast<IntOut>(
81 static_cast<FloatIn>(static_cast<FloatIn>(imax) + 1.0)),
82 imax);
83 EXPECT_EQ(SafeCast<IntOut>(
84 static_cast<FloatIn>(static_cast<FloatIn>(imax) + 1.99)),
85 imax);
86 EXPECT_EQ(SafeCast<IntOut>(
87 static_cast<FloatIn>(static_cast<FloatIn>(imax) + 2.0)),
88 imax);
89 EXPECT_EQ(SafeCast<IntOut>(
90 static_cast<FloatIn>(static_cast<FloatIn>(imax) - 0.1)),
91 imax - 1);
92 EXPECT_EQ(SafeCast<IntOut>(
93 static_cast<FloatIn>(static_cast<FloatIn>(imax) - 0.99)),
94 imax - 1);
95 EXPECT_EQ(SafeCast<IntOut>(
96 static_cast<FloatIn>(static_cast<FloatIn>(imax) - 1.0)),
97 imax - 1);
98 EXPECT_EQ(SafeCast<IntOut>(
99 static_cast<FloatIn>(static_cast<FloatIn>(imax) - 1.01)),
100 imax - 2);
101 EXPECT_EQ(SafeCast<IntOut>(
102 static_cast<FloatIn>(static_cast<FloatIn>(imax) - 1.99)),
103 imax - 2);
104 EXPECT_EQ(SafeCast<IntOut>(
105 static_cast<FloatIn>(static_cast<FloatIn>(imax) - 2.0)),
106 imax - 2);
107 EXPECT_EQ(SafeCast<IntOut>(
108 static_cast<FloatIn>(static_cast<FloatIn>(imax) - 2.01)),
109 imax - 3);
110 }
111
112 // Check values considerably larger in magnitude than imin and imax
113 EXPECT_EQ(
114 SafeCast<IntOut>(static_cast<FloatIn>(static_cast<FloatIn>(imax) * 2)),
115 imax);
116 EXPECT_EQ(
117 SafeCast<IntOut>(static_cast<FloatIn>(static_cast<FloatIn>(imax) * 20)),
118 imax);
119 EXPECT_EQ(
120 SafeCast<IntOut>(static_cast<FloatIn>(static_cast<FloatIn>(imax) * 100)),
121 imax);
122 EXPECT_EQ(
123 SafeCast<IntOut>(static_cast<FloatIn>(static_cast<FloatIn>(imin) * 2)),
124 imin);
125 EXPECT_EQ(
126 SafeCast<IntOut>(static_cast<FloatIn>(static_cast<FloatIn>(imin) * 20)),
127 imin);
128 EXPECT_EQ(
129 SafeCast<IntOut>(static_cast<FloatIn>(static_cast<FloatIn>(imin) * 100)),
130 imin);
131 }
132
TEST(QuantizationUtilTest,SafeCast)133 TEST(QuantizationUtilTest, SafeCast) {
134 RunSafeCastTests<float, int8_t>();
135 RunSafeCastTests<double, int8_t>();
136 RunSafeCastTests<float, int16_t>();
137 RunSafeCastTests<double, int16_t>();
138 RunSafeCastTests<float, int32_t>();
139 RunSafeCastTests<double, int32_t>();
140 RunSafeCastTests<float, int64_t>();
141 RunSafeCastTests<double, int64_t>();
142 RunSafeCastTests<float, uint8_t>();
143 RunSafeCastTests<double, uint8_t>();
144 RunSafeCastTests<float, uint16_t>();
145 RunSafeCastTests<double, uint16_t>();
146 RunSafeCastTests<float, uint32_t>();
147 RunSafeCastTests<double, uint32_t>();
148 RunSafeCastTests<float, uint64_t>();
149 RunSafeCastTests<double, uint64_t>();
150 }
151
152 // Example taken from http://www.tensorflow.org/performance/quantization
153 //
154 // Quantized | Float
155 // --------- | -----
156 // 0 | -10.0
157 // 255 | 30.0
158 // 128 | 10.0
TEST(QuantizationUtilTest,ChooseQuantizationParams)159 TEST(QuantizationUtilTest, ChooseQuantizationParams) {
160 QuantizationParams qp = ChooseQuantizationParams<uint8>(-10.0, 30.0);
161 EXPECT_NEAR(qp.scale, 0.156863, 1e-5);
162 EXPECT_EQ(qp.zero_point, 64);
163 }
164
TEST(QuantizationUtilTest,ChooseQuantizationParamsZeroPointOnMinBoundary)165 TEST(QuantizationUtilTest, ChooseQuantizationParamsZeroPointOnMinBoundary) {
166 QuantizationParams qp = ChooseQuantizationParams<uint8>(0.0, 30.0);
167 EXPECT_NEAR(qp.scale, 0.117647, 1e-5);
168 EXPECT_EQ(qp.zero_point, 0);
169 }
170
171 #ifdef GTEST_HAS_DEATH_TEST
TEST(QuantizationUtilTest,ChooseQuantizationParamsZeroNotInRange)172 TEST(QuantizationUtilTest, ChooseQuantizationParamsZeroNotInRange) {
173 // Assumption is that zero is within the range.
174 EXPECT_DEATH(ChooseQuantizationParams<uint8>(10.0, 30.0), "");
175 }
176
TEST(QuantizationUtilTest,ChooseQuantizationParamsEmptyRangePositive)177 TEST(QuantizationUtilTest, ChooseQuantizationParamsEmptyRangePositive) {
178 // Assumption is that zero is within the range.
179 EXPECT_DEATH(ChooseQuantizationParams<uint8>(30.0, 30.0), "");
180 }
181 #endif // GTEST_HAS_DEATH_TEST
182
TEST(QuantizationUtilTest,ChooseQuantizationParamsEmptyRangeZero)183 TEST(QuantizationUtilTest, ChooseQuantizationParamsEmptyRangeZero) {
184 QuantizationParams qp = ChooseQuantizationParams<uint8>(0.0, 0.0);
185 EXPECT_NEAR(qp.scale, 0.0, 1e-5);
186 EXPECT_EQ(qp.zero_point, 0);
187 }
188
TEST(QuantizationUtilTest,ChooseQuantizationParamsZeroPointOnMaxBoundary)189 TEST(QuantizationUtilTest, ChooseQuantizationParamsZeroPointOnMaxBoundary) {
190 QuantizationParams qp = ChooseQuantizationParams<uint8>(-10.0, 0.0);
191 EXPECT_NEAR(qp.scale, 0.039216, 1e-5);
192 EXPECT_EQ(qp.zero_point, 255);
193 }
194
TEST(QuantizationUtilTest,IntegerFrExp)195 TEST(QuantizationUtilTest, IntegerFrExp) {
196 int shift;
197 int64_t result = IntegerFrExp(0.0, &shift);
198 EXPECT_EQ(0, result);
199 EXPECT_EQ(0, shift);
200
201 result = IntegerFrExp(1.0, &shift);
202 EXPECT_NEAR(0x40000000, result, 1);
203 EXPECT_EQ(1, shift);
204
205 result = IntegerFrExp(0.25, &shift);
206 EXPECT_NEAR(0x40000000, result, 1);
207 EXPECT_EQ(-1, shift);
208
209 result = IntegerFrExp(-1.0, &shift);
210 EXPECT_NEAR(-(1 << 30), result, 1);
211 EXPECT_EQ(1, shift);
212
213 result = IntegerFrExp(123.45, &shift);
214 EXPECT_NEAR(2071147315, result, 1);
215 EXPECT_EQ(7, shift);
216
217 result = IntegerFrExp(NAN, &shift);
218 EXPECT_NEAR(0, result, 1);
219 EXPECT_EQ(0x7fffffff, shift);
220
221 result = IntegerFrExp(INFINITY, &shift);
222 EXPECT_NEAR(std::numeric_limits<int64_t>::max(), result, 1);
223 EXPECT_EQ(0x7fffffff, shift);
224
225 result = IntegerFrExp(-INFINITY, &shift);
226 EXPECT_NEAR(std::numeric_limits<int64_t>::min(), result, 1);
227 EXPECT_EQ(0x7fffffff, shift);
228 }
229
TEST(QuantizationUtilTest,IntegerFrExpVersusDouble)230 TEST(QuantizationUtilTest, IntegerFrExpVersusDouble) {
231 int shift;
232 int32_t result = IntegerFrExp(0.0, &shift);
233 EXPECT_EQ(result, 0);
234 EXPECT_EQ(shift, 0);
235
236 int double_shift;
237 double double_result = std::frexp(0.0, &double_shift);
238 EXPECT_EQ(double_result, 0);
239 EXPECT_EQ(double_shift, 0);
240
241 result = IntegerFrExp(1.0, &shift);
242 EXPECT_NEAR(result, 0x40000000, 1);
243 EXPECT_EQ(shift, 1);
244 double_result = std::frexp(1.0, &double_shift);
245 EXPECT_NEAR(double_result, 0.5, 1e-5);
246 EXPECT_EQ(double_shift, 1);
247
248 result = IntegerFrExp(0.25, &shift);
249 EXPECT_NEAR(result, 0x40000000, 1);
250 EXPECT_EQ(shift, -1);
251 double_result = std::frexp(0.25, &double_shift);
252 EXPECT_NEAR(double_result, 0.5, 1e-5);
253 EXPECT_EQ(double_shift, -1);
254
255 result = IntegerFrExp(-1.0, &shift);
256 EXPECT_NEAR(result, -(1 << 30), 1);
257 EXPECT_EQ(shift, 1);
258 double_result = std::frexp(-1.0, &double_shift);
259 EXPECT_NEAR(double_result, -0.5, 1e-5);
260 EXPECT_EQ(double_shift, 1);
261
262 result = IntegerFrExp(123.45, &shift);
263 EXPECT_NEAR(result, (0.964453 * (1LL << 31)), 1000);
264 EXPECT_EQ(shift, 7);
265 double_result = std::frexp(123.45, &double_shift);
266 EXPECT_NEAR(double_result, 0.964453, 1e-5);
267 EXPECT_EQ(double_shift, 7);
268 }
269
TEST(QuantizationUtilTest,DoubleFromFractionAndShift)270 TEST(QuantizationUtilTest, DoubleFromFractionAndShift) {
271 double result = DoubleFromFractionAndShift(0, 0);
272 EXPECT_EQ(0, result);
273
274 result = DoubleFromFractionAndShift(0x40000000, 1);
275 EXPECT_NEAR(1.0, result, 1e-5);
276
277 result = DoubleFromFractionAndShift(0x40000000, 2);
278 EXPECT_NEAR(2.0, result, 1e-5);
279
280 int shift;
281 int64_t fraction = IntegerFrExp(3.0, &shift);
282 result = DoubleFromFractionAndShift(fraction, shift);
283 EXPECT_NEAR(3.0, result, 1e-5);
284
285 fraction = IntegerFrExp(123.45, &shift);
286 result = DoubleFromFractionAndShift(fraction, shift);
287 EXPECT_NEAR(123.45, result, 1e-5);
288
289 fraction = IntegerFrExp(-23.232323, &shift);
290 result = DoubleFromFractionAndShift(fraction, shift);
291 EXPECT_NEAR(-23.232323, result, 1e-5);
292
293 fraction = IntegerFrExp(NAN, &shift);
294 result = DoubleFromFractionAndShift(fraction, shift);
295 EXPECT_TRUE(std::isnan(result));
296
297 fraction = IntegerFrExp(INFINITY, &shift);
298 result = DoubleFromFractionAndShift(fraction, shift);
299 EXPECT_FALSE(std::isfinite(result));
300 }
301
TEST(QuantizationUtilTest,IntegerDoubleMultiply)302 TEST(QuantizationUtilTest, IntegerDoubleMultiply) {
303 EXPECT_NEAR(1.0, IntegerDoubleMultiply(1.0, 1.0), 1e-5);
304 EXPECT_NEAR(2.0, IntegerDoubleMultiply(1.0, 2.0), 1e-5);
305 EXPECT_NEAR(2.0, IntegerDoubleMultiply(2.0, 1.0), 1e-5);
306 EXPECT_NEAR(4.0, IntegerDoubleMultiply(2.0, 2.0), 1e-5);
307 EXPECT_NEAR(0.5, IntegerDoubleMultiply(1.0, 0.5), 1e-5);
308 EXPECT_NEAR(0.25, IntegerDoubleMultiply(0.5, 0.5), 1e-5);
309 EXPECT_NEAR(-1.0, IntegerDoubleMultiply(1.0, -1.0), 1e-5);
310 EXPECT_NEAR(-1.0, IntegerDoubleMultiply(-1.0, 1.0), 1e-5);
311 EXPECT_NEAR(1.0, IntegerDoubleMultiply(-1.0, -1.0), 1e-5);
312 EXPECT_NEAR(15000000.0, IntegerDoubleMultiply(3000.0, 5000.0), 1e-5);
313 EXPECT_TRUE(std::isnan(IntegerDoubleMultiply(NAN, 5000.0)));
314 EXPECT_TRUE(std::isnan(IntegerDoubleMultiply(3000.0, NAN)));
315 }
316
TEST(QuantizationUtilTest,IntegerDoubleCompare)317 TEST(QuantizationUtilTest, IntegerDoubleCompare) {
318 EXPECT_EQ(-1, IntegerDoubleCompare(0.0, 1.0));
319 EXPECT_EQ(1, IntegerDoubleCompare(1.0, 0.0));
320 EXPECT_EQ(0, IntegerDoubleCompare(1.0, 1.0));
321 EXPECT_EQ(0, IntegerDoubleCompare(0.0, 0.0));
322 EXPECT_EQ(-1, IntegerDoubleCompare(-10.0, 10.0));
323 EXPECT_EQ(1, IntegerDoubleCompare(123.45, 10.0));
324 EXPECT_EQ(1, IntegerDoubleCompare(NAN, INFINITY));
325 EXPECT_EQ(1, IntegerDoubleCompare(INFINITY, NAN));
326 }
327
328 #ifdef GTEST_HAS_DEATH_TEST
TEST(QuantizationUtilTest,ChooseQuantizationParamsInvalidRange)329 TEST(QuantizationUtilTest, ChooseQuantizationParamsInvalidRange) {
330 EXPECT_DEATH(ChooseQuantizationParams<uint8>(10.0, -30.0), "");
331 }
332
TEST(QuantizationUtilTest,QuantizeMultiplierSmallerThanOneExp)333 TEST(QuantizationUtilTest, QuantizeMultiplierSmallerThanOneExp) {
334 auto quantize = [](double d) {
335 int32_t q;
336 int s;
337 QuantizeMultiplierSmallerThanOneExp(d, &q, &s);
338 return std::pair<int32_t, int>{q, s};
339 };
340
341 EXPECT_DEATH(quantize(-0.1), "");
342 EXPECT_DEATH(quantize(0.0), "");
343 EXPECT_THAT(quantize(0.25), Pair(1073741824, -1));
344
345 // Around 0.5 we can see the change in exponent and how we try hard to
346 // void hitting max int32.
347 EXPECT_THAT(quantize(0.50 - 5e-9), Pair(2147483627, -1));
348 EXPECT_THAT(quantize(0.50 - 1e-10), Pair(1073741824, 0));
349 EXPECT_THAT(quantize(0.50), Pair(1073741824, 0));
350
351 EXPECT_THAT(quantize(0.75), Pair(1610612736, 0));
352 EXPECT_THAT(quantize(1 - 1e-9), Pair(2147483646, 0));
353
354 // If we get close enough to 1.0 it crashes and dies in one of two ways:
355 // Either the shift becomes negative or we trigger the 'less-than-one' CHECK.
356 EXPECT_DEATH(quantize(1 - 1e-15), "");
357 EXPECT_DEATH(quantize(1 - 1e-17), "");
358 EXPECT_DEATH(quantize(1.0), "");
359 }
360
TEST(QuantizationUtilTest,QuantizeMultiplierGreaterThanOne)361 TEST(QuantizationUtilTest, QuantizeMultiplierGreaterThanOne) {
362 auto quantize = [](double d) {
363 int32_t q;
364 int s;
365 QuantizeMultiplierGreaterThanOne(d, &q, &s);
366 return std::pair<int32_t, int>{q, s};
367 };
368
369 // If we are close enough to 1.0 it crashes.
370 EXPECT_DEATH(quantize(1 + 1e-16), "");
371
372 EXPECT_THAT(quantize(1 + 1e-11), Pair(1073741824, 1));
373 EXPECT_THAT(quantize(1.25), Pair(1342177280, 1));
374 EXPECT_THAT(quantize(1.50), Pair(1610612736, 1));
375 EXPECT_THAT(quantize(1.75), Pair(1879048192, 1));
376
377 // Around the powers of two we see the change in exponent. Also,
378 // we try hard to avoid hitting max int32.
379 EXPECT_THAT(quantize(2 - 1e-9), Pair(2147483647, 1));
380 EXPECT_THAT(quantize(2 - 1e-11), Pair(1073741824, 2));
381 EXPECT_THAT(quantize(2), Pair(1073741824, 2));
382 }
383
TEST(QuantizationUtilTest,PreprocessSoftmaxScaling)384 TEST(QuantizationUtilTest, PreprocessSoftmaxScaling) {
385 auto quantize = [](double beta, double scale, int integer_bits) {
386 int32_t q;
387 int s;
388 PreprocessSoftmaxScaling(beta, scale, integer_bits, &q, &s);
389 return std::pair<int32_t, int>{q, s};
390 };
391
392 // If beta * scale is greater than fits in the number of integer bits, the
393 // result is move near the maximum. Otherwise they quantize as expected.
394 // With 4 integer bits we can represent up to 16.0.
395 EXPECT_THAT(quantize(1.0, 16.0, 4), Pair(2147483647, 31));
396 EXPECT_THAT(quantize(1.0, 8.0, 4), Pair(1073741824, 31));
397 // But with 5 bits we can go further.
398 EXPECT_THAT(quantize(2.0, 16.0, 5), Pair(2147483647, 31));
399 EXPECT_THAT(quantize(2.0, 8.0, 5), Pair(1073741824, 31));
400 }
401 #endif // GTEST_HAS_DEATH_TEST
402
TEST(QuantizationUtilTest,CalculateInputRadius)403 TEST(QuantizationUtilTest, CalculateInputRadius) {
404 EXPECT_EQ(CalculateInputRadius(4, 27), 15);
405 EXPECT_EQ(CalculateInputRadius(3, 27), 14);
406 EXPECT_EQ(CalculateInputRadius(3, 28), 7);
407 EXPECT_EQ(CalculateInputRadius(4, 2), 503316480);
408 }
409
TEST(QuantizationUtilTest,QuantizeMultiplierArray)410 TEST(QuantizationUtilTest, QuantizeMultiplierArray) {
411 const std::vector<double> weights = {-4, -2, -1, -0.5, -0.25, -0.125, 0,
412 0.125, 0.25, 0.5, 1, 2, 4};
413 const int size = weights.size();
414 std::vector<int32> effective_scale_significand(size);
415 std::vector<int> effective_scale_shift(size);
416 QuantizeMultiplierArray(weights.data(), size,
417 effective_scale_significand.data(),
418 effective_scale_shift.data());
419 const std::vector<int32> expected_effective_scale_significand = {
420 -1073741824, // float scale = -4
421 -1073741824, // float scale = -2
422 -1073741824, // float scale = -1
423 -1073741824, // float scale = -0.5
424 -1073741824, // float scale = -0.25
425 -1073741824, // float scale = -0.125
426 0, // float scale = 0
427 1073741824, // float scale = 0.125
428 1073741824, // float scale = 0.25
429 1073741824, // float scale = 0.5
430 1073741824, // float scale = 1
431 1073741824, // float scale = 2
432 1073741824, // float scale = 4
433 };
434
435 const std::vector<int> expected_effective_scale_shift = {
436 3, // float scale = -4
437 2, // float scale = -2
438 1, // float scale = -1
439 0, // float scale = -0.5
440 -1, // float scale = -0.25
441 -2, // float scale = -0.125
442 0, // float scale = 0
443 -2, // float scale = 0.125
444 -1, // float scale = 0.25
445 0, // float scale = 0.5
446 1, // float scale = 1
447 2, // float scale = 2
448 3, // float scale = 4
449 };
450 EXPECT_THAT(effective_scale_significand,
451 ElementsAreArray(expected_effective_scale_significand));
452 EXPECT_THAT(effective_scale_shift,
453 ElementsAreArray(expected_effective_scale_shift));
454 }
455
456 } // namespace
457 } // namespace tflite
458
main(int argc,char ** argv)459 int main(int argc, char** argv) {
460 // On Linux, add: tflite::LogToStderr();
461 ::testing::InitGoogleTest(&argc, argv);
462 return RUN_ALL_TESTS();
463 }
464