1 #define BOOST_TEST_MODULE MultivectorArithmetics
2 #include <boost/test/unit_test.hpp>
3 #include <vexcl/constants.hpp>
4 #include <vexcl/multivector.hpp>
5 #include <vexcl/reductor.hpp>
6 #include <vexcl/element_index.hpp>
7 #include <vexcl/function.hpp>
8 #include "context_setup.hpp"
9
BOOST_AUTO_TEST_CASE(arithmetics)10 BOOST_AUTO_TEST_CASE(arithmetics)
11 {
12 typedef std::array<double, 4> elem_t;
13
14 const size_t n = 1024;
15
16 vex::multivector<double, 4> x(ctx, n);
17 vex::multivector<double, 4> y(ctx, random_vector<double>(n * 4));
18 vex::multivector<double, 4> z(ctx, random_vector<double>(n * 4));
19
20 vex::Reductor<double,vex::MIN> min(ctx);
21 vex::Reductor<double,vex::MAX> max(ctx);
22
23 elem_t v = {{0, 1, 2, 3}};
24 x = v;
25
26 BOOST_CHECK(min(x) == v);
27 BOOST_CHECK(max(x) == v);
28
29 x = std::make_tuple(1, 2, 3, 4) * y + z;
30
31 check_sample(x, y, z, [](size_t, elem_t a, elem_t b, elem_t c) {
32 for(size_t i = 0; i < 4; ++i)
33 BOOST_CHECK_CLOSE(a[i], (i + 1) * b[i] + c[i], 1e-8);
34 });
35 }
36
BOOST_AUTO_TEST_CASE(multivector_multiexpressions)37 BOOST_AUTO_TEST_CASE(multivector_multiexpressions)
38 {
39 typedef std::array<double, 2> elem_t;
40
41 const size_t n = 1024;
42
43 vex::multivector<double, 2> x(ctx, n);
44 vex::multivector<double, 2> y(ctx, random_vector<double>(n * 2));
45
46 x = std::tie(
47 sin( y(0) ) + cos( y(1) ),
48 cos( y(0) ) + sin( y(1) )
49 );
50
51 check_sample(x, y, [](size_t, elem_t a, elem_t b) {
52 BOOST_CHECK_CLOSE(a[0], sin(b[0]) + cos(b[1]), 1e-8);
53 BOOST_CHECK_CLOSE(a[1], cos(b[0]) + sin(b[1]), 1e-8);
54 });
55 }
56
BOOST_AUTO_TEST_CASE(tied_vectors)57 BOOST_AUTO_TEST_CASE(tied_vectors)
58 {
59 const size_t n = 1024;
60
61 vex::vector<double> X(ctx, random_vector<double>(n));
62 vex::vector<double> Y(ctx, random_vector<double>(n));
63
64 vex::vector<double> A(ctx, n);
65 vex::vector<double> B(ctx, n);
66
67 vex::tie(A, B) = std::tie(X + Y, X - Y);
68
69 check_sample(A, X, Y, [](size_t, double a, double x, double y) {
70 BOOST_CHECK(a == x + y);
71 });
72
73 check_sample(B, X, Y, [](size_t, double b, double x, double y) {
74 BOOST_CHECK(b == x - y);
75 });
76 }
77
BOOST_AUTO_TEST_CASE(builtin_functions)78 BOOST_AUTO_TEST_CASE(builtin_functions)
79 {
80 typedef std::array<double, 2> elem_t;
81 const size_t n = 1024;
82
83 vex::multivector<double, 2> x(ctx, random_vector<double>(n * 2));
84 vex::multivector<double, 2> y(ctx, n);
85
86 y = pow(sin(x), 2.0) + pow(cos(x), 2.0);
87
88 check_sample(y, [](size_t, elem_t a) {
89 BOOST_CHECK_CLOSE(a[0], 1, 1e-8);
90 BOOST_CHECK_CLOSE(a[1], 1, 1e-8);
91 });
92 }
93
BOOST_AUTO_TEST_CASE(user_defined_functions)94 BOOST_AUTO_TEST_CASE(user_defined_functions)
95 {
96 typedef std::array<double, 2> elem_t;
97
98 const size_t n = 1024;
99 const size_t m = 2;
100
101 vex::multivector<double, m> x(ctx, n);
102 vex::multivector<double, m> y(ctx, n);
103
104 elem_t v1 = {{1, 2}};
105 elem_t v2 = {{2, 1}};
106
107 VEX_FUNCTION(size_t, greater, (double, x)(double, y), return x > y;);
108
109 x = v1;
110 y = v2;
111
112 x = greater(x, y);
113
114 check_sample(x, [](size_t, elem_t a) {
115 BOOST_CHECK(a[0] == 0);
116 BOOST_CHECK(a[1] == 1);
117 });
118 }
119
BOOST_AUTO_TEST_CASE(reduction)120 BOOST_AUTO_TEST_CASE(reduction)
121 {
122 typedef std::array<double, 2> elem_t;
123
124 const size_t n = 1024;
125
126 std::vector<double> x = random_vector<double>(n);
127 std::vector<double> y = random_vector<double>(n);
128
129 vex::multivector<double, 2> m(ctx, n);
130 copy(x, m(0));
131 copy(y, m(1));
132
133 vex::Reductor<double, vex::SUM> sum(ctx);
134 vex::Reductor<double, vex::MIN> min(ctx);
135 vex::Reductor<double, vex::MAX> max(ctx);
136
137 elem_t summ = sum(m);
138 elem_t minm = min(m);
139 elem_t maxm = max(m);
140
141 BOOST_CHECK_CLOSE(summ[0], std::accumulate(x.begin(), x.end(), 0.0), 1e-6);
142 BOOST_CHECK_CLOSE(summ[1], std::accumulate(y.begin(), y.end(), 0.0), 1e-6);
143
144 BOOST_CHECK_CLOSE(minm[0], *std::min_element(x.begin(), x.end()), 1e-12);
145 BOOST_CHECK_CLOSE(minm[1], *std::min_element(y.begin(), y.end()), 1e-12);
146
147 BOOST_CHECK_CLOSE(maxm[0], *std::max_element(x.begin(), x.end()), 1e-12);
148 BOOST_CHECK_CLOSE(maxm[1], *std::max_element(y.begin(), y.end()), 1e-12);
149 }
150
BOOST_AUTO_TEST_CASE(element_index)151 BOOST_AUTO_TEST_CASE(element_index)
152 {
153 typedef std::array<double, 2> elem_t;
154
155 const size_t N = 1024;
156
157 vex::multivector<double, 2> x(ctx, N);
158
159 x = 0.5 * vex::element_index();
160
161 check_sample(x, [](size_t idx, elem_t a) {
162 BOOST_CHECK_CLOSE(a[0], 0.5 * idx, 1e-12);
163 BOOST_CHECK_CLOSE(a[1], 0.5 * idx, 1e-12);
164 });
165
166 x = std::tie(
167 sin(0.5 * vex::element_index()),
168 cos(0.5 * vex::element_index())
169 );
170
171 check_sample(x, [](size_t idx, elem_t a) {
172 BOOST_CHECK_CLOSE(a[0], sin(0.5 * idx), 1e-6);
173 BOOST_CHECK_CLOSE(a[1], cos(0.5 * idx), 1e-6);
174 });
175 }
176
BOOST_AUTO_TEST_CASE(compound_assignment)177 BOOST_AUTO_TEST_CASE(compound_assignment)
178 {
179 const size_t n = 1024;
180 const size_t m = 2;
181
182 typedef std::array<double, m> elem_t;
183
184 vex::multivector<double, m> x(ctx, n);
185 vex::multivector<double, m> y(ctx, random_vector<double>(n * m));
186
187 x = 0;
188
189 x += sin(2 * y);
190
191 check_sample(x, y, [&](size_t, elem_t a, elem_t b) {
192 for(size_t i = 0; i < m; ++i)
193 BOOST_CHECK_CLOSE(a[i], sin(2 * b[i]), 1e-8);
194 });
195
196 x = 0;
197 x -= sin(2 * y);
198
199 check_sample(x, y, [&](size_t, elem_t a, elem_t b) {
200 for(size_t i = 0; i < m; ++i)
201 BOOST_CHECK_CLOSE(a[i], -sin(2 * b[i]), 1e-8);
202 });
203
204 x = 1;
205 x *= std::tie(y(1), sin(y(0)));
206
207 check_sample(x, y, [](size_t, elem_t a, elem_t b) {
208 BOOST_CHECK_CLOSE(a[0], b[1], 1e-8);
209 BOOST_CHECK_CLOSE(a[1], sin(b[0]), 1e-8);
210 });
211 }
212
BOOST_AUTO_TEST_CASE(integral_constants)213 BOOST_AUTO_TEST_CASE(integral_constants)
214 {
215 typedef std::array<double, 4> elem_t;
216
217 const size_t n = 1024;
218
219 vex::multivector<double, 4> x(ctx, n);
220
221 x = std::integral_constant<int, 42>();
222 check_sample(x, [](size_t, elem_t a) {
223 for(size_t i = 0; i < 4; ++i) BOOST_CHECK_EQUAL(a[i], 42);
224 });
225
226 x = sin( vex::constants::e() * vex::element_index() );
227 check_sample(x, [](size_t idx, elem_t a) {
228 for(size_t i = 0; i < 4; ++i)
229 BOOST_CHECK_CLOSE(a[i], sin(boost::math::constants::e<double>() * idx), 1e-8);
230 });
231 }
232
233 #if (VEXCL_CHECK_SIZES > 0)
BOOST_AUTO_TEST_CASE(expression_size_check)234 BOOST_AUTO_TEST_CASE(expression_size_check)
235 {
236 vex::multivector<int, 2> x(ctx, 16);
237 vex::multivector<int, 2> y(ctx, 32);
238
239 BOOST_CHECK_THROW(x = y, std::runtime_error);
240 }
241 #endif
242
243 BOOST_AUTO_TEST_SUITE_END()
244