Home | History | Annotate | Download | only in test
      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 (at) 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