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