diff options
author | Benoit Jacob <benoitjacob@google.com> | 2015-06-25 15:50:59 -0400 |
---|---|---|
committer | Benoit Jacob <benoitjacob@google.com> | 2015-06-25 15:53:04 -0400 |
commit | 75c4ec0ba4dd86e4f763a54e01002ff29f1d57ae (patch) | |
tree | c8e35a06c7d959e6ad0a90b4929305055919e3f8 /test/test_math_helpers.cc | |
download | gemmlowp-75c4ec0ba4dd86e4f763a54e01002ff29f1d57ae.tar.gz |
initial import
Diffstat (limited to 'test/test_math_helpers.cc')
-rw-r--r-- | test/test_math_helpers.cc | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/test/test_math_helpers.cc b/test/test_math_helpers.cc new file mode 100644 index 0000000..c1482f7 --- /dev/null +++ b/test/test_math_helpers.cc @@ -0,0 +1,134 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "test/test.h" + +#include <limits> + +#include "internal/common.h" + +namespace gemmlowp { + +// Our math helpers don't intend to be reliable all the way to the +// limit of representable range, wrt overflow. +// We don't care for 2G sized matrices. +// This test stops at half of the representable range. +template <typename Integer> +Integer ValueRangeCutoff() { + return std::numeric_limits<Integer>::max() / 2; +} + +int RandomNonnegativeFarAwayFromOverflow() { return Random() % (1 << 24); } + +template <int Modulus> +void test_round_up_down(int x) { + Check(x >= RoundDown<Modulus>(x)); + Check(x < RoundDown<Modulus>(x) + Modulus); + Check(RoundDown<Modulus>(x) % Modulus == 0); + + Check(x <= RoundUp<Modulus>(x)); + Check(x > RoundUp<Modulus>(x) - Modulus); + Check(RoundUp<Modulus>(x) % Modulus == 0); +} + +template <int Modulus> +void test_round_up_down() { + for (int i = 0; i < 100; i++) { + test_round_up_down<Modulus>(i); + const int N = ValueRangeCutoff<int>(); + test_round_up_down<Modulus>(Random() % N); + } +} + +template <typename Integer> +void test_ceil_quotient(Integer x, Integer y) { + Check(CeilQuotient(x, y) * y >= x); + Check(CeilQuotient(x, y) * y < x + y); +} + +template <typename Integer> +void test_ceil_quotient() { + const Integer N = ValueRangeCutoff<Integer>(); + const Integer K = std::min(N, Integer(100)); + for (Integer x = 0; x < K; x++) { + for (Integer y = 1; y < K; y++) { + test_ceil_quotient(x, y); + test_ceil_quotient(x, Integer(1 + (Random() % (N - 1)))); + test_ceil_quotient(Integer(Random() % N), y); + test_ceil_quotient(Integer(Random() % N), + Integer(1 + (Random() % (N - 1)))); + } + } +} + +template <typename Integer> +void test_round_up_to_next_power_of_two(Integer x) { + Check(RoundUpToPowerOfTwo(RoundUpToPowerOfTwo(x) == RoundUpToPowerOfTwo(x))); + Check(RoundUpToPowerOfTwo(x) >= x); + Check(x == 0 || RoundUpToPowerOfTwo(x) < 2 * x); + Check((RoundUpToPowerOfTwo(x) & (RoundUpToPowerOfTwo(x) - 1)) == 0); +} + +template <typename Integer> +void test_round_up_to_next_power_of_two() { + const Integer N = ValueRangeCutoff<Integer>(); + const Integer K = std::min(N, Integer(100)); + for (Integer x = 0; x < K; x++) { + test_round_up_to_next_power_of_two(x); + test_round_up_to_next_power_of_two(Random() % N); + } +} + +void test_math_helpers() { + test_round_up_down<1>(); + test_round_up_down<2>(); + test_round_up_down<3>(); + test_round_up_down<4>(); + test_round_up_down<5>(); + test_round_up_down<6>(); + test_round_up_down<7>(); + test_round_up_down<8>(); + test_round_up_down<9>(); + test_round_up_down<10>(); + test_round_up_down<11>(); + test_round_up_down<12>(); + test_round_up_down<13>(); + test_round_up_down<14>(); + test_round_up_down<15>(); + test_round_up_down<16>(); + + test_round_up_down<50>(); + test_round_up_down<51>(); + + test_round_up_down<500>(); + test_round_up_down<501>(); + + test_ceil_quotient<std::int8_t>(); + test_ceil_quotient<std::uint8_t>(); + test_ceil_quotient<std::int16_t>(); + test_ceil_quotient<std::uint16_t>(); + test_ceil_quotient<std::int32_t>(); + test_ceil_quotient<std::uint32_t>(); + + test_round_up_to_next_power_of_two<std::int8_t>(); + test_round_up_to_next_power_of_two<std::uint8_t>(); + test_round_up_to_next_power_of_two<std::int16_t>(); + test_round_up_to_next_power_of_two<std::uint16_t>(); + test_round_up_to_next_power_of_two<std::int32_t>(); + test_round_up_to_next_power_of_two<std::uint32_t>(); +} + +} // end namespace gemmlowp + +int main() { gemmlowp::test_math_helpers(); } |