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 15 void 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 50 void 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 64 void 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 78 void 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 91 void 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 110 void 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 128 void 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 138 void 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