cxx11_tensor_uint128.cpp
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 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 #if EIGEN_COMP_MSVC || !defined(__SIZEOF_INT128__)
16 #define EIGEN_NO_INT128
17 #else
18 typedef __uint128_t uint128_t;
19 #endif
20 
21 // Only run the test on compilers that support 128bit integers natively
22 #ifndef EIGEN_NO_INT128
23 
26 
27 void VERIFY_EQUAL(TensorUInt128<uint64_t, uint64_t> actual, uint128_t expected) {
28  bool matchl = actual.lower() == static_cast<uint64_t>(expected);
29  bool matchh = actual.upper() == static_cast<uint64_t>(expected >> 64);
30  if (!matchl || !matchh) {
31  const char* testname = g_test_stack.back().c_str();
32  std::cerr << "Test " << testname << " failed in " << __FILE__
33  << " (" << __LINE__ << ")"
34  << std::endl;
35  abort();
36  }
37 }
38 
39 
40 void test_add() {
41  uint64_t incr = internal::random<uint64_t>(1, 9999999999);
42  for (uint64_t i1 = 0; i1 < 100; ++i1) {
43  for (uint64_t i2 = 1; i2 < 100 * incr; i2 += incr) {
44  TensorUInt128<uint64_t, uint64_t> i(i1, i2);
45  uint128_t a = (static_cast<uint128_t>(i1) << 64) + static_cast<uint128_t>(i2);
46  for (uint64_t j1 = 0; j1 < 100; ++j1) {
47  for (uint64_t j2 = 1; j2 < 100 * incr; j2 += incr) {
48  TensorUInt128<uint64_t, uint64_t> j(j1, j2);
49  uint128_t b = (static_cast<uint128_t>(j1) << 64) + static_cast<uint128_t>(j2);
50  TensorUInt128<uint64_t, uint64_t> actual = i + j;
51  uint128_t expected = a + b;
52  VERIFY_EQUAL(actual, expected);
53  }
54  }
55  }
56  }
57 }
58 
59 void test_sub() {
60  uint64_t incr = internal::random<uint64_t>(1, 9999999999);
61  for (uint64_t i1 = 0; i1 < 100; ++i1) {
62  for (uint64_t i2 = 1; i2 < 100 * incr; i2 += incr) {
63  TensorUInt128<uint64_t, uint64_t> i(i1, i2);
64  uint128_t a = (static_cast<uint128_t>(i1) << 64) + static_cast<uint128_t>(i2);
65  for (uint64_t j1 = 0; j1 < 100; ++j1) {
66  for (uint64_t j2 = 1; j2 < 100 * incr; j2 += incr) {
67  TensorUInt128<uint64_t, uint64_t> j(j1, j2);
68  uint128_t b = (static_cast<uint128_t>(j1) << 64) + static_cast<uint128_t>(j2);
69  TensorUInt128<uint64_t, uint64_t> actual = i - j;
70  uint128_t expected = a - b;
71  VERIFY_EQUAL(actual, expected);
72  }
73  }
74  }
75  }
76 }
77 
78 void test_mul() {
79  uint64_t incr = internal::random<uint64_t>(1, 9999999999);
80  for (uint64_t i1 = 0; i1 < 100; ++i1) {
81  for (uint64_t i2 = 1; i2 < 100 * incr; i2 += incr) {
82  TensorUInt128<uint64_t, uint64_t> i(i1, i2);
83  uint128_t a = (static_cast<uint128_t>(i1) << 64) + static_cast<uint128_t>(i2);
84  for (uint64_t j1 = 0; j1 < 100; ++j1) {
85  for (uint64_t j2 = 1; j2 < 100 * incr; j2 += incr) {
86  TensorUInt128<uint64_t, uint64_t> j(j1, j2);
87  uint128_t b = (static_cast<uint128_t>(j1) << 64) + static_cast<uint128_t>(j2);
88  TensorUInt128<uint64_t, uint64_t> actual = i * j;
89  uint128_t expected = a * b;
90  VERIFY_EQUAL(actual, expected);
91  }
92  }
93  }
94  }
95 }
96 
97 void test_div() {
98  uint64_t incr = internal::random<uint64_t>(1, 9999999999);
99  for (uint64_t i1 = 0; i1 < 100; ++i1) {
100  for (uint64_t i2 = 1; i2 < 100 * incr; i2 += incr) {
101  TensorUInt128<uint64_t, uint64_t> i(i1, i2);
102  uint128_t a = (static_cast<uint128_t>(i1) << 64) + static_cast<uint128_t>(i2);
103  for (uint64_t j1 = 0; j1 < 100; ++j1) {
104  for (uint64_t j2 = 1; j2 < 100 * incr; j2 += incr) {
105  TensorUInt128<uint64_t, uint64_t> j(j1, j2);
106  uint128_t b = (static_cast<uint128_t>(j1) << 64) + static_cast<uint128_t>(j2);
107  TensorUInt128<uint64_t, uint64_t> actual = i / j;
108  uint128_t expected = a / b;
109  VERIFY_EQUAL(actual, expected);
110  }
111  }
112  }
113  }
114 }
115 
116 void test_misc1() {
117  uint64_t incr = internal::random<uint64_t>(1, 9999999999);
118  for (uint64_t i2 = 1; i2 < 100 * incr; i2 += incr) {
119  TensorUInt128<static_val<0>, uint64_t> i(0, i2);
120  uint128_t a = static_cast<uint128_t>(i2);
121  for (uint64_t j2 = 1; j2 < 100 * incr; j2 += incr) {
122  TensorUInt128<static_val<0>, uint64_t> j(0, j2);
123  uint128_t b = static_cast<uint128_t>(j2);
124  uint64_t actual = (i * j).upper();
125  uint64_t expected = (a * b) >> 64;
126  VERIFY_IS_EQUAL(actual, expected);
127  }
128  }
129 }
130 
131 void test_misc2() {
132  int64_t incr = internal::random<int64_t>(1, 100);
133  for (int64_t log_div = 0; log_div < 63; ++log_div) {
134  for (int64_t divider = 1; divider <= 1000000 * incr; divider += incr) {
135  uint64_t expected = (static_cast<uint128_t>(1) << (64+log_div)) / static_cast<uint128_t>(divider) - (static_cast<uint128_t>(1) << 64) + 1;
136  uint64_t shift = 1ULL << log_div;
137 
138  TensorUInt128<uint64_t, uint64_t> result = (TensorUInt128<uint64_t, static_val<0> >(shift, 0) / TensorUInt128<static_val<0>, uint64_t>(divider) - TensorUInt128<static_val<1>, static_val<0> >(1, 0) + TensorUInt128<static_val<0>, static_val<1> >(1));
139  uint64_t actual = static_cast<uint64_t>(result);
140  VERIFY_IS_EQUAL(actual, expected);
141  }
142  }
143 }
144 #endif
145 
146 
147 EIGEN_DECLARE_TEST(cxx11_tensor_uint128)
148 {
149 #ifdef EIGEN_NO_INT128
150  // Skip the test on compilers that don't support 128bit integers natively
151  return;
152 #else
153  CALL_SUBTEST_1(test_add());
154  CALL_SUBTEST_2(test_sub());
155  CALL_SUBTEST_3(test_mul());
156  CALL_SUBTEST_4(test_div());
157  CALL_SUBTEST_5(test_misc1());
158  CALL_SUBTEST_6(test_misc2());
159 #endif
160 }
Eigen::internal::TensorUInt128
Definition: TensorUInt128.h:33
Eigen::g_test_stack
static std::vector< std::string > g_test_stack
Definition: main.h:165
VERIFY_IS_EQUAL
#define VERIFY_IS_EQUAL(a, b)
Definition: main.h:386
b
Scalar * b
Definition: benchVecAdd.cpp:17
result
Values result
Definition: OdometryOptimize.cpp:8
CALL_SUBTEST_4
#define CALL_SUBTEST_4(FUNC)
Definition: split_test_helper.h:22
CALL_SUBTEST_3
#define CALL_SUBTEST_3(FUNC)
Definition: split_test_helper.h:16
CALL_SUBTEST_1
#define CALL_SUBTEST_1(FUNC)
Definition: split_test_helper.h:4
j
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
int64_t
signed __int64 int64_t
Definition: ms_stdint.h:94
cholesky::expected
Matrix expected
Definition: testMatrix.cpp:971
CALL_SUBTEST_5
#define CALL_SUBTEST_5(FUNC)
Definition: split_test_helper.h:28
CALL_SUBTEST_6
#define CALL_SUBTEST_6(FUNC)
Definition: split_test_helper.h:34
CALL_SUBTEST_2
#define CALL_SUBTEST_2(FUNC)
Definition: split_test_helper.h:10
a
ArrayXXi a
Definition: Array_initializer_list_23_cxx11.cpp:1
EIGEN_DECLARE_TEST
EIGEN_DECLARE_TEST(cxx11_tensor_uint128)
Definition: cxx11_tensor_uint128.cpp:147
Eigen::internal::static_val
Definition: TensorUInt128.h:18
i1
double i1(double x)
Definition: i1.c:150
main.h
uint64_t
unsigned __int64 uint64_t
Definition: ms_stdint.h:95
j1
double j1(double x)
Definition: j1.c:174
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9


gtsam
Author(s):
autogenerated on Sat Nov 16 2024 04:02:09