• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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