11963df9ac4a0424674e72ef5da522b5d830605fdMiao Wang// Copyright 2015 The Gemmlowp Authors. All Rights Reserved. 275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// 375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// Licensed under the Apache License, Version 2.0 (the "License"); 475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// you may not use this file except in compliance with the License. 575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// You may obtain a copy of the License at 675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// 775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// http://www.apache.org/licenses/LICENSE-2.0 875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// 975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// Unless required by applicable law or agreed to in writing, software 1075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// distributed under the License is distributed on an "AS IS" BASIS, 1175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// See the License for the specific language governing permissions and 1375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// limitations under the License. 1475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 15544690cac8f06f1b2f5fa3799e1e8f13c75d95e9Miao Wang#include "test.h" 1675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 1775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob#include <limits> 1875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 19544690cac8f06f1b2f5fa3799e1e8f13c75d95e9Miao Wang#include "../internal/common.h" 2075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 2175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobnamespace gemmlowp { 2275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 2375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// Our math helpers don't intend to be reliable all the way to the 2475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// limit of representable range, wrt overflow. 2575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// We don't care for 2G sized matrices. 2675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// This test stops at half of the representable range. 2775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobtemplate <typename Integer> 2875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit JacobInteger ValueRangeCutoff() { 2975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob return std::numeric_limits<Integer>::max() / 2; 3075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob} 3175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 3275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobint RandomNonnegativeFarAwayFromOverflow() { return Random() % (1 << 24); } 3375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 3475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobtemplate <int Modulus> 3575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobvoid test_round_up_down(int x) { 3675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check(x >= RoundDown<Modulus>(x)); 3775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check(x < RoundDown<Modulus>(x) + Modulus); 3875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check(RoundDown<Modulus>(x) % Modulus == 0); 3975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 4075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check(x <= RoundUp<Modulus>(x)); 4175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check(x > RoundUp<Modulus>(x) - Modulus); 4275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check(RoundUp<Modulus>(x) % Modulus == 0); 4375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob} 4475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 4575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobtemplate <int Modulus> 4675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobvoid test_round_up_down() { 4775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob for (int i = 0; i < 100; i++) { 4875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<Modulus>(i); 4975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob const int N = ValueRangeCutoff<int>(); 5075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<Modulus>(Random() % N); 5175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob } 5275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob} 5375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 5475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobtemplate <typename Integer> 5575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobvoid test_ceil_quotient(Integer x, Integer y) { 5675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check(CeilQuotient(x, y) * y >= x); 5775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check(CeilQuotient(x, y) * y < x + y); 5875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob} 5975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 6075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobtemplate <typename Integer> 6175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobvoid test_ceil_quotient() { 6275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob const Integer N = ValueRangeCutoff<Integer>(); 6375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob const Integer K = std::min(N, Integer(100)); 6475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob for (Integer x = 0; x < K; x++) { 6575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob for (Integer y = 1; y < K; y++) { 6675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_ceil_quotient(x, y); 6775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_ceil_quotient(x, Integer(1 + (Random() % (N - 1)))); 6875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_ceil_quotient(Integer(Random() % N), y); 6975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_ceil_quotient(Integer(Random() % N), 7075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Integer(1 + (Random() % (N - 1)))); 7175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob } 7275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob } 7375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob} 7475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 7575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobtemplate <typename Integer> 7675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobvoid test_round_up_to_next_power_of_two(Integer x) { 7775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check(RoundUpToPowerOfTwo(RoundUpToPowerOfTwo(x) == RoundUpToPowerOfTwo(x))); 7875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check(RoundUpToPowerOfTwo(x) >= x); 7975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check(x == 0 || RoundUpToPowerOfTwo(x) < 2 * x); 8075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Check((RoundUpToPowerOfTwo(x) & (RoundUpToPowerOfTwo(x) - 1)) == 0); 8175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob} 8275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 8375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobtemplate <typename Integer> 8475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobvoid test_round_up_to_next_power_of_two() { 8575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob const Integer N = ValueRangeCutoff<Integer>(); 8675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob const Integer K = std::min(N, Integer(100)); 8775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob for (Integer x = 0; x < K; x++) { 8875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_to_next_power_of_two(x); 8975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_to_next_power_of_two(Random() % N); 9075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob } 9175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob} 9275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 9375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobvoid test_math_helpers() { 9475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<1>(); 9575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<2>(); 9675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<3>(); 9775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<4>(); 9875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<5>(); 9975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<6>(); 10075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<7>(); 10175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<8>(); 10275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<9>(); 10375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<10>(); 10475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<11>(); 10575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<12>(); 10675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<13>(); 10775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<14>(); 10875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<15>(); 10975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<16>(); 11075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 11175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<50>(); 11275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<51>(); 11375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 11475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<500>(); 11575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_down<501>(); 11675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 11775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_ceil_quotient<std::int8_t>(); 11875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_ceil_quotient<std::uint8_t>(); 11975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_ceil_quotient<std::int16_t>(); 12075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_ceil_quotient<std::uint16_t>(); 12175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_ceil_quotient<std::int32_t>(); 12275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_ceil_quotient<std::uint32_t>(); 12375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 12475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_to_next_power_of_two<std::int8_t>(); 12575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_to_next_power_of_two<std::uint8_t>(); 12675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_to_next_power_of_two<std::int16_t>(); 12775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_to_next_power_of_two<std::uint16_t>(); 12875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_to_next_power_of_two<std::int32_t>(); 12975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob test_round_up_to_next_power_of_two<std::uint32_t>(); 13075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob} 13175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 13275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob} // end namespace gemmlowp 13375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 13475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobint main() { gemmlowp::test_math_helpers(); } 135