• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Gemmlowp 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 "test.h"
16 
17 #include <limits>
18 
19 #include "../internal/common.h"
20 
21 namespace gemmlowp {
22 
23 // Our math helpers don't intend to be reliable all the way to the
24 // limit of representable range, wrt overflow.
25 // We don't care for 2G sized matrices.
26 // This test stops at half of the representable range.
27 template <typename Integer>
ValueRangeCutoff()28 Integer ValueRangeCutoff() {
29   return std::numeric_limits<Integer>::max() / 2;
30 }
31 
RandomNonnegativeFarAwayFromOverflow()32 int RandomNonnegativeFarAwayFromOverflow() { return Random() % (1 << 24); }
33 
34 template <int Modulus>
test_round_up_down(int x)35 void test_round_up_down(int x) {
36   Check(x >= RoundDown<Modulus>(x));
37   Check(x < RoundDown<Modulus>(x) + Modulus);
38   Check(RoundDown<Modulus>(x) % Modulus == 0);
39 
40   Check(x <= RoundUp<Modulus>(x));
41   Check(x > RoundUp<Modulus>(x) - Modulus);
42   Check(RoundUp<Modulus>(x) % Modulus == 0);
43 }
44 
45 template <int Modulus>
test_round_up_down()46 void test_round_up_down() {
47   for (int i = 0; i < 100; i++) {
48     test_round_up_down<Modulus>(i);
49     const int N = ValueRangeCutoff<int>();
50     test_round_up_down<Modulus>(Random() % N);
51   }
52 }
53 
54 template <typename Integer>
test_ceil_quotient(Integer x,Integer y)55 void test_ceil_quotient(Integer x, Integer y) {
56   Check(CeilQuotient(x, y) * y >= x);
57   Check(CeilQuotient(x, y) * y < x + y);
58 }
59 
60 template <typename Integer>
test_ceil_quotient()61 void test_ceil_quotient() {
62   const Integer N = ValueRangeCutoff<Integer>();
63   const Integer K = std::min(N, Integer(100));
64   for (Integer x = 0; x < K; x++) {
65     for (Integer y = 1; y < K; y++) {
66       test_ceil_quotient(x, y);
67       test_ceil_quotient(x, Integer(1 + (Random() % (N - 1))));
68       test_ceil_quotient(Integer(Random() % N), y);
69       test_ceil_quotient(Integer(Random() % N),
70                          Integer(1 + (Random() % (N - 1))));
71     }
72   }
73 }
74 
75 template <typename Integer>
test_round_up_to_next_power_of_two(Integer x)76 void test_round_up_to_next_power_of_two(Integer x) {
77   Check(RoundUpToPowerOfTwo(RoundUpToPowerOfTwo(x) == RoundUpToPowerOfTwo(x)));
78   Check(RoundUpToPowerOfTwo(x) >= x);
79   Check(x == 0 || RoundUpToPowerOfTwo(x) < 2 * x);
80   Check((RoundUpToPowerOfTwo(x) & (RoundUpToPowerOfTwo(x) - 1)) == 0);
81 }
82 
83 template <typename Integer>
test_round_up_to_next_power_of_two()84 void test_round_up_to_next_power_of_two() {
85   const Integer N = ValueRangeCutoff<Integer>();
86   const Integer K = std::min(N, Integer(100));
87   for (Integer x = 0; x < K; x++) {
88     test_round_up_to_next_power_of_two(x);
89     test_round_up_to_next_power_of_two(Random() % N);
90   }
91 }
92 
test_math_helpers()93 void test_math_helpers() {
94   test_round_up_down<1>();
95   test_round_up_down<2>();
96   test_round_up_down<3>();
97   test_round_up_down<4>();
98   test_round_up_down<5>();
99   test_round_up_down<6>();
100   test_round_up_down<7>();
101   test_round_up_down<8>();
102   test_round_up_down<9>();
103   test_round_up_down<10>();
104   test_round_up_down<11>();
105   test_round_up_down<12>();
106   test_round_up_down<13>();
107   test_round_up_down<14>();
108   test_round_up_down<15>();
109   test_round_up_down<16>();
110 
111   test_round_up_down<50>();
112   test_round_up_down<51>();
113 
114   test_round_up_down<500>();
115   test_round_up_down<501>();
116 
117   test_ceil_quotient<std::int8_t>();
118   test_ceil_quotient<std::uint8_t>();
119   test_ceil_quotient<std::int16_t>();
120   test_ceil_quotient<std::uint16_t>();
121   test_ceil_quotient<std::int32_t>();
122   test_ceil_quotient<std::uint32_t>();
123 
124   test_round_up_to_next_power_of_two<std::int8_t>();
125   test_round_up_to_next_power_of_two<std::uint8_t>();
126   test_round_up_to_next_power_of_two<std::int16_t>();
127   test_round_up_to_next_power_of_two<std::uint16_t>();
128   test_round_up_to_next_power_of_two<std::int32_t>();
129   test_round_up_to_next_power_of_two<std::uint32_t>();
130 }
131 
132 }  // end namespace gemmlowp
133 
main()134 int main() { gemmlowp::test_math_helpers(); }
135