1// This file is part of Eigen, a lightweight C++ template library 2// for linear algebra. 3// 4// Copyright (C) 2014-2015 Benoit Steiner <benoit.steiner.goog@gmail.com> 5// 6// This Source Code Form is subject to the terms of the Mozilla 7// Public License v. 2.0. If a copy of the MPL was not distributed 8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10#include "main.h" 11 12#include <Eigen/CXX11/Tensor> 13 14 15void test_signed_32bit() 16{ 17 // Divide by one 18 const Eigen::internal::TensorIntDivisor<int32_t, false> div_by_one(1); 19 20 for (int32_t j = 0; j < 25000; ++j) { 21 const int32_t fast_div = j / div_by_one; 22 const int32_t slow_div = j / 1; 23 VERIFY_IS_EQUAL(fast_div, slow_div); 24 } 25 26 // Standard divide by 2 or more 27 for (int32_t i = 2; i < 25000; ++i) { 28 const Eigen::internal::TensorIntDivisor<int32_t, false> div(i); 29 30 for (int32_t j = 0; j < 25000; ++j) { 31 const int32_t fast_div = j / div; 32 const int32_t slow_div = j / i; 33 VERIFY_IS_EQUAL(fast_div, slow_div); 34 } 35 } 36 37 // Optimized divide by 2 or more 38 for (int32_t i = 2; i < 25000; ++i) { 39 const Eigen::internal::TensorIntDivisor<int32_t, true> div(i); 40 41 for (int32_t j = 0; j < 25000; ++j) { 42 const int32_t fast_div = j / div; 43 const int32_t slow_div = j / i; 44 VERIFY_IS_EQUAL(fast_div, slow_div); 45 } 46 } 47} 48 49 50void test_unsigned_32bit() 51{ 52 for (uint32_t i = 1; i < 25000; ++i) { 53 const Eigen::internal::TensorIntDivisor<uint32_t> div(i); 54 55 for (uint32_t j = 0; j < 25000; ++j) { 56 const uint32_t fast_div = j / div; 57 const uint32_t slow_div = j / i; 58 VERIFY_IS_EQUAL(fast_div, slow_div); 59 } 60 } 61} 62 63 64void test_signed_64bit() 65{ 66 for (int64_t i = 1; i < 25000; ++i) { 67 const Eigen::internal::TensorIntDivisor<int64_t> div(i); 68 69 for (int64_t j = 0; j < 25000; ++j) { 70 const int64_t fast_div = j / div; 71 const int64_t slow_div = j / i; 72 VERIFY_IS_EQUAL(fast_div, slow_div); 73 } 74 } 75} 76 77 78void test_unsigned_64bit() 79{ 80 for (uint64_t i = 1; i < 25000; ++i) { 81 const Eigen::internal::TensorIntDivisor<uint64_t> div(i); 82 83 for (uint64_t j = 0; j < 25000; ++j) { 84 const uint64_t fast_div = j / div; 85 const uint64_t slow_div = j / i; 86 VERIFY_IS_EQUAL(fast_div, slow_div); 87 } 88 } 89} 90 91void test_powers_32bit() { 92 for (int expon = 1; expon < 31; expon++) { 93 int32_t div = (1 << expon); 94 for (int num_expon = 0; num_expon < 32; num_expon++) { 95 int32_t start_num = (1 << num_expon) - 100; 96 int32_t end_num = (1 << num_expon) + 100; 97 if (start_num < 0) 98 start_num = 0; 99 for (int32_t num = start_num; num < end_num; num++) { 100 Eigen::internal::TensorIntDivisor<int32_t> divider = 101 Eigen::internal::TensorIntDivisor<int32_t>(div); 102 int32_t result = num/div; 103 int32_t result_op = divider.divide(num); 104 VERIFY_IS_EQUAL(result_op, result); 105 } 106 } 107 } 108} 109 110void test_powers_64bit() { 111 for (int expon = 0; expon < 63; expon++) { 112 int64_t div = (1ull << expon); 113 for (int num_expon = 0; num_expon < 63; num_expon++) { 114 int64_t start_num = (1ull << num_expon) - 10; 115 int64_t end_num = (1ull << num_expon) + 10; 116 if (start_num < 0) 117 start_num = 0; 118 for (int64_t num = start_num; num < end_num; num++) { 119 Eigen::internal::TensorIntDivisor<int64_t> divider(div); 120 int64_t result = num/div; 121 int64_t result_op = divider.divide(num); 122 VERIFY_IS_EQUAL(result_op, result); 123 } 124 } 125 } 126} 127 128void test_specific() { 129 // A particular combination that was previously failing 130 int64_t div = 209715200; 131 int64_t num = 3238002688ll; 132 Eigen::internal::TensorIntDivisor<int64_t> divider(div); 133 int64_t result = num/div; 134 int64_t result_op = divider.divide(num); 135 VERIFY_IS_EQUAL(result, result_op); 136} 137 138void test_cxx11_tensor_intdiv() 139{ 140 CALL_SUBTEST_1(test_signed_32bit()); 141 CALL_SUBTEST_2(test_unsigned_32bit()); 142 CALL_SUBTEST_3(test_signed_64bit()); 143 CALL_SUBTEST_4(test_unsigned_64bit()); 144 CALL_SUBTEST_5(test_powers_32bit()); 145 CALL_SUBTEST_6(test_powers_64bit()); 146 CALL_SUBTEST_7(test_specific()); 147} 148