// Copyright 2015 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.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(); }
