cxx11_tensor_intdiv.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. #include "main.h"
  10. #include <Eigen/CXX11/Tensor>
  11. void test_signed_32bit()
  12. {
  13. // Divide by one
  14. const Eigen::internal::TensorIntDivisor<int32_t, false> div_by_one(1);
  15. for (int32_t j = 0; j < 25000; ++j) {
  16. const int32_t fast_div = j / div_by_one;
  17. const int32_t slow_div = j / 1;
  18. VERIFY_IS_EQUAL(fast_div, slow_div);
  19. }
  20. // Standard divide by 2 or more
  21. for (int32_t i = 2; i < 25000; ++i) {
  22. const Eigen::internal::TensorIntDivisor<int32_t, false> div(i);
  23. for (int32_t j = 0; j < 25000; ++j) {
  24. const int32_t fast_div = j / div;
  25. const int32_t slow_div = j / i;
  26. VERIFY_IS_EQUAL(fast_div, slow_div);
  27. }
  28. }
  29. // Optimized divide by 2 or more
  30. for (int32_t i = 2; i < 25000; ++i) {
  31. const Eigen::internal::TensorIntDivisor<int32_t, true> div(i);
  32. for (int32_t j = 0; j < 25000; ++j) {
  33. const int32_t fast_div = j / div;
  34. const int32_t slow_div = j / i;
  35. VERIFY_IS_EQUAL(fast_div, slow_div);
  36. }
  37. }
  38. }
  39. void test_unsigned_32bit()
  40. {
  41. for (uint32_t i = 1; i < 25000; ++i) {
  42. const Eigen::internal::TensorIntDivisor<uint32_t> div(i);
  43. for (uint32_t j = 0; j < 25000; ++j) {
  44. const uint32_t fast_div = j / div;
  45. const uint32_t slow_div = j / i;
  46. VERIFY_IS_EQUAL(fast_div, slow_div);
  47. }
  48. }
  49. }
  50. void test_signed_64bit()
  51. {
  52. for (int64_t i = 1; i < 25000; ++i) {
  53. const Eigen::internal::TensorIntDivisor<int64_t> div(i);
  54. for (int64_t j = 0; j < 25000; ++j) {
  55. const int64_t fast_div = j / div;
  56. const int64_t slow_div = j / i;
  57. VERIFY_IS_EQUAL(fast_div, slow_div);
  58. }
  59. }
  60. }
  61. void test_unsigned_64bit()
  62. {
  63. for (uint64_t i = 1; i < 25000; ++i) {
  64. const Eigen::internal::TensorIntDivisor<uint64_t> div(i);
  65. for (uint64_t j = 0; j < 25000; ++j) {
  66. const uint64_t fast_div = j / div;
  67. const uint64_t slow_div = j / i;
  68. VERIFY_IS_EQUAL(fast_div, slow_div);
  69. }
  70. }
  71. }
  72. void test_powers_32bit() {
  73. for (int expon = 1; expon < 31; expon++) {
  74. int32_t div = (1 << expon);
  75. for (int num_expon = 0; num_expon < 32; num_expon++) {
  76. int32_t start_num = (1 << num_expon) - 100;
  77. int32_t end_num = (1 << num_expon) + 100;
  78. if (start_num < 0)
  79. start_num = 0;
  80. for (int32_t num = start_num; num < end_num; num++) {
  81. Eigen::internal::TensorIntDivisor<int32_t> divider =
  82. Eigen::internal::TensorIntDivisor<int32_t>(div);
  83. int32_t result = num/div;
  84. int32_t result_op = divider.divide(num);
  85. VERIFY_IS_EQUAL(result_op, result);
  86. }
  87. }
  88. }
  89. }
  90. void test_powers_64bit() {
  91. for (int expon = 0; expon < 63; expon++) {
  92. int64_t div = (1ull << expon);
  93. for (int num_expon = 0; num_expon < 63; num_expon++) {
  94. int64_t start_num = (1ull << num_expon) - 10;
  95. int64_t end_num = (1ull << num_expon) + 10;
  96. if (start_num < 0)
  97. start_num = 0;
  98. for (int64_t num = start_num; num < end_num; num++) {
  99. Eigen::internal::TensorIntDivisor<int64_t> divider(div);
  100. int64_t result = num/div;
  101. int64_t result_op = divider.divide(num);
  102. VERIFY_IS_EQUAL(result_op, result);
  103. }
  104. }
  105. }
  106. }
  107. void test_specific() {
  108. // A particular combination that was previously failing
  109. int64_t div = 209715200;
  110. int64_t num = 3238002688ll;
  111. Eigen::internal::TensorIntDivisor<int64_t> divider(div);
  112. int64_t result = num/div;
  113. int64_t result_op = divider.divide(num);
  114. VERIFY_IS_EQUAL(result, result_op);
  115. }
  116. EIGEN_DECLARE_TEST(cxx11_tensor_intdiv)
  117. {
  118. CALL_SUBTEST_1(test_signed_32bit());
  119. CALL_SUBTEST_2(test_unsigned_32bit());
  120. CALL_SUBTEST_3(test_signed_64bit());
  121. CALL_SUBTEST_4(test_unsigned_64bit());
  122. CALL_SUBTEST_5(test_powers_32bit());
  123. CALL_SUBTEST_6(test_powers_64bit());
  124. CALL_SUBTEST_7(test_specific());
  125. }