1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
10
11 #define BOOST_TEST_MODULE TestValarray
12 #include <boost/test/unit_test.hpp>
13
14 #include <boost/compute/system.hpp>
15 #include <boost/compute/command_queue.hpp>
16 #include <boost/compute/container/valarray.hpp>
17
18 #include "check_macros.hpp"
19 #include "context_setup.hpp"
20
BOOST_AUTO_TEST_CASE(size)21 BOOST_AUTO_TEST_CASE(size)
22 {
23 boost::compute::valarray<float> array;
24 BOOST_CHECK_EQUAL(array.size(), size_t(0));
25
26 array.resize(10);
27 BOOST_CHECK_EQUAL(array.size(), size_t(10));
28 }
29
BOOST_AUTO_TEST_CASE(at)30 BOOST_AUTO_TEST_CASE(at)
31 {
32 int data[] = { 1, 2, 3, 4, 5 };
33 boost::compute::valarray<int> array(data, 5);
34 BOOST_CHECK_EQUAL(array.size(), size_t(5));
35
36 boost::compute::system::finish();
37 BOOST_CHECK_EQUAL(int(array[0]), int(1));
38 BOOST_CHECK_EQUAL(int(array[1]), int(2));
39 BOOST_CHECK_EQUAL(int(array[2]), int(3));
40 BOOST_CHECK_EQUAL(int(array[3]), int(4));
41 BOOST_CHECK_EQUAL(int(array[4]), int(5));
42 }
43
BOOST_AUTO_TEST_CASE(min_and_max)44 BOOST_AUTO_TEST_CASE(min_and_max)
45 {
46 int data[] = { 5, 2, 3, 7, 1, 9, 6, 5 };
47 boost::compute::valarray<int> array(data, 8);
48 BOOST_CHECK_EQUAL(array.size(), size_t(8));
49
50 BOOST_CHECK_EQUAL((array.min)(), int(1));
51 BOOST_CHECK_EQUAL((array.max)(), int(9));
52 }
53
BOOST_AUTO_TEST_CASE(sum)54 BOOST_AUTO_TEST_CASE(sum)
55 {
56 int data[] = { 1, 2, 3, 4 };
57 boost::compute::valarray<int> array(data, 4);
58 boost::compute::system::finish();
59
60 BOOST_CHECK_EQUAL(array.size(), size_t(4));
61 BOOST_CHECK_EQUAL(array.sum(), int(10));
62 }
63
BOOST_AUTO_TEST_CASE(apply)64 BOOST_AUTO_TEST_CASE(apply)
65 {
66 int data[] = { -1, 2, -3, 4 };
67 boost::compute::valarray<int> array(data, 4);
68
69 boost::compute::abs<int> abs;
70 boost::compute::valarray<int> result = array.apply(abs);
71 boost::compute::system::finish();
72 BOOST_CHECK_EQUAL(int(result[0]), int(1));
73 BOOST_CHECK_EQUAL(int(result[1]), int(2));
74 BOOST_CHECK_EQUAL(int(result[2]), int(3));
75 BOOST_CHECK_EQUAL(int(result[3]), int(4));
76 }
77
78 /// \internal_
79 /// Tests for compound assignment operators that works for floating
80 /// point types.
81 #define BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT(op, op_name) \
82 BOOST_AUTO_TEST_CASE(op_name##_ca_operator_no_fp) \
83 { \
84 float data[] = { 1, 2, 3, 4 }; \
85 boost::compute::valarray<float> array1(data, 4); \
86 boost::compute::valarray<float> array2(data, 4); \
87 boost::compute::system::finish(); \
88 \
89 array1 op##= 1; \
90 boost::compute::system::finish(); \
91 BOOST_CHECK_CLOSE(float(array1[0]), float(1.0f op 1.0f), 1e-4f); \
92 BOOST_CHECK_CLOSE(float(array1[1]), float(2.0f op 1.0f), 1e-4f); \
93 BOOST_CHECK_CLOSE(float(array1[2]), float(3.0f op 1.0f), 1e-4f); \
94 BOOST_CHECK_CLOSE(float(array1[3]), float(4.0f op 1.0f), 1e-4f); \
95 \
96 array1 = boost::compute::valarray<float>(data, 4); \
97 boost::compute::system::finish(); \
98 \
99 array1 op##= array2; \
100 boost::compute::system::finish(); \
101 BOOST_CHECK_CLOSE(float(array1[0]), float(1.0f op 1.0f), 1e-4f); \
102 BOOST_CHECK_CLOSE(float(array1[1]), float(2.0f op 2.0f), 1e-4f); \
103 BOOST_CHECK_CLOSE(float(array1[2]), float(3.0f op 3.0f), 1e-4f); \
104 BOOST_CHECK_CLOSE(float(array1[3]), float(4.0f op 4.0f), 1e-4f); \
105 \
106 array2 op##= array2; \
107 boost::compute::system::finish(); \
108 BOOST_CHECK_CLOSE(float(array2[0]), float(1.0f op 1.0f), 1e-4f); \
109 BOOST_CHECK_CLOSE(float(array2[1]), float(2.0f op 2.0f), 1e-4f); \
110 BOOST_CHECK_CLOSE(float(array2[2]), float(3.0f op 3.0f), 1e-4f); \
111 BOOST_CHECK_CLOSE(float(array2[3]), float(4.0f op 4.0f), 1e-4f); \
112 \
113 }
114
115 BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT(+, plus)
116 BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT(-, minus)
117 BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT(*, multiplies)
118 BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT(/, divides)
119
120 #undef BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT
121
122 /// \internal_
123 /// Tests for compound assignment operators that does NOT work for floating
124 /// point types.
125 /// Note: modulo operator works only for integer types.
126 #define BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(op, op_name) \
127 BOOST_AUTO_TEST_CASE(op_name##_ca_operator) \
128 { \
129 int data[] = { 1, 2, 3, 4 }; \
130 boost::compute::valarray<int> array1(data, 4); \
131 boost::compute::valarray<int> array2(data, 4); \
132 boost::compute::system::finish(); \
133 \
134 array1 op##= 1; \
135 boost::compute::system::finish(); \
136 BOOST_CHECK_EQUAL(int(array1[0]), int(1 op 1)); \
137 BOOST_CHECK_EQUAL(int(array1[1]), int(2 op 1)); \
138 BOOST_CHECK_EQUAL(int(array1[2]), int(3 op 1)); \
139 BOOST_CHECK_EQUAL(int(array1[3]), int(4 op 1)); \
140 \
141 array1 = boost::compute::valarray<int>(data, 4); \
142 boost::compute::system::finish(); \
143 \
144 array1 op##= array2; \
145 boost::compute::system::finish(); \
146 BOOST_CHECK_EQUAL(int(array1[0]), int(1 op 1)); \
147 BOOST_CHECK_EQUAL(int(array1[1]), int(2 op 2)); \
148 BOOST_CHECK_EQUAL(int(array1[2]), int(3 op 3)); \
149 BOOST_CHECK_EQUAL(int(array1[3]), int(4 op 4)); \
150 \
151 array2 op##= array2; \
152 boost::compute::system::finish(); \
153 BOOST_CHECK_EQUAL(int(array2[0]), int(1 op 1)); \
154 BOOST_CHECK_EQUAL(int(array2[1]), int(2 op 2)); \
155 BOOST_CHECK_EQUAL(int(array2[2]), int(3 op 3)); \
156 BOOST_CHECK_EQUAL(int(array2[3]), int(4 op 4)); \
157 \
158 }
159
160 BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(%, modulus)
161 BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(^, bit_xor)
162 BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(&, bit_and)
163 BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(|, bit_or)
164 BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(<<, shift_left)
165 BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(>>, shift_right)
166
167 #undef BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP
168
BOOST_AUTO_TEST_CASE(unary_plus_operator)169 BOOST_AUTO_TEST_CASE(unary_plus_operator)
170 {
171 int data[] = { 1, 2, 3, 4 };
172 boost::compute::valarray<int> array(data, 4);
173 boost::compute::system::finish();
174
175 boost::compute::valarray<int> result = +array;
176 boost::compute::system::finish();
177 BOOST_CHECK_EQUAL(int(result[0]), +(int(1)));
178 BOOST_CHECK_EQUAL(int(result[1]), +(int(2)));
179 BOOST_CHECK_EQUAL(int(result[2]), +(int(3)));
180 BOOST_CHECK_EQUAL(int(result[3]), +(int(4)));
181 }
182
BOOST_AUTO_TEST_CASE(unary_minus_operator)183 BOOST_AUTO_TEST_CASE(unary_minus_operator)
184 {
185 int data[] = { -1, 2, 0, 4 };
186 boost::compute::valarray<int> array(data, 4);
187 boost::compute::system::finish();
188
189 boost::compute::valarray<int> result = -array;
190 boost::compute::system::finish();
191 BOOST_CHECK_EQUAL(int(result[0]), int(1));
192 BOOST_CHECK_EQUAL(int(result[1]), int(-2));
193 BOOST_CHECK_EQUAL(int(result[2]), int(0));
194 BOOST_CHECK_EQUAL(int(result[3]), int(-4));
195 }
196
BOOST_AUTO_TEST_CASE(unary_bitwise_not_operator)197 BOOST_AUTO_TEST_CASE(unary_bitwise_not_operator)
198 {
199 int data[] = { 1, 2, 3, 4 };
200 boost::compute::valarray<int> array(data, 4);
201 boost::compute::system::finish();
202
203 boost::compute::valarray<int> result = ~array;
204 boost::compute::system::finish();
205 BOOST_CHECK_EQUAL(int(result[0]), ~(int(1)));
206 BOOST_CHECK_EQUAL(int(result[1]), ~(int(2)));
207 BOOST_CHECK_EQUAL(int(result[2]), ~(int(3)));
208 BOOST_CHECK_EQUAL(int(result[3]), ~(int(4)));
209 }
210
BOOST_AUTO_TEST_CASE(unary_logical_not_operator)211 BOOST_AUTO_TEST_CASE(unary_logical_not_operator)
212 {
213 int data[] = { 1, -2, 0, 4 };
214 boost::compute::valarray<int> array(data, 4);
215 boost::compute::system::finish();
216
217 boost::compute::valarray<char> result = !array;
218 boost::compute::system::finish();
219 BOOST_CHECK_EQUAL(bool(result[0]), !(int(1)));
220 BOOST_CHECK_EQUAL(bool(result[1]), !(int(-2)));
221 BOOST_CHECK_EQUAL(bool(result[2]), !(int(0)));
222 BOOST_CHECK_EQUAL(bool(result[3]), !(int(4)));
223 }
224
225 /// \internal_
226 /// Tests for binary operators that works for floating
227 /// point types.
228 #define BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR(op, op_name) \
229 BOOST_AUTO_TEST_CASE(op_name##_binary_operator) \
230 { \
231 float data1[] = { 1, 2, 3, 4 }; \
232 float data2[] = { 4, 2, 3, 0 }; \
233 boost::compute::valarray<float> array1(data1, 4); \
234 boost::compute::valarray<float> array2(data2, 4); \
235 boost::compute::system::finish(); \
236 \
237 boost::compute::valarray<float> result = 2.0f op array1; \
238 boost::compute::system::finish(); \
239 BOOST_CHECK_CLOSE(float(result[0]), float(2.0f op 1.0f), 1e-4f); \
240 BOOST_CHECK_CLOSE(float(result[1]), float(2.0f op 2.0f), 1e-4f); \
241 BOOST_CHECK_CLOSE(float(result[2]), float(2.0f op 3.0f), 1e-4f); \
242 BOOST_CHECK_CLOSE(float(result[3]), float(2.0f op 4.0f), 1e-4f); \
243 \
244 result = array1 op 2.0f; \
245 boost::compute::system::finish(); \
246 BOOST_CHECK_CLOSE(float(result[0]), float(1.0f op 2.0f), 1e-4f); \
247 BOOST_CHECK_CLOSE(float(result[1]), float(2.0f op 2.0f), 1e-4f); \
248 BOOST_CHECK_CLOSE(float(result[2]), float(3.0f op 2.0f), 1e-4f); \
249 BOOST_CHECK_CLOSE(float(result[3]), float(4.0f op 2.0f), 1e-4f); \
250 \
251 result = array2 op array1; \
252 boost::compute::system::finish(); \
253 BOOST_CHECK_CLOSE(float(result[0]), float(4.0f op 1.0f), 1e-4f); \
254 BOOST_CHECK_CLOSE(float(result[1]), float(2.0f op 2.0f), 1e-4f); \
255 BOOST_CHECK_CLOSE(float(result[2]), float(3.0f op 3.0f), 1e-4f); \
256 BOOST_CHECK_CLOSE(float(result[3]), float(0.0f op 4.0f), 1e-4f); \
257 }
258
259 BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR(+, plus)
260 BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR(-, minus)
261 BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR(*, multiplies)
262 BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR(/, divides)
263
264 #undef BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR
265
266 /// \internal_
267 /// Tests for compound assignment operators that does NOT work for floating
268 /// point types.
269 /// Note: modulo operator works only for integer types.
270 #define BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(op, op_name) \
271 BOOST_AUTO_TEST_CASE(op_name##_binary_operator) \
272 { \
273 int data1[] = { 1, 2, 3, 4 }; \
274 int data2[] = { 4, 5, 2, 1 }; \
275 boost::compute::valarray<int> array1(data1, 4); \
276 boost::compute::valarray<int> array2(data2, 4); \
277 boost::compute::system::finish(); \
278 \
279 boost::compute::valarray<int> result = 5 op array1; \
280 boost::compute::system::finish(); \
281 BOOST_CHECK_EQUAL(int(result[0]), int(5 op 1)); \
282 BOOST_CHECK_EQUAL(int(result[1]), int(5 op 2)); \
283 BOOST_CHECK_EQUAL(int(result[2]), int(5 op 3)); \
284 BOOST_CHECK_EQUAL(int(result[3]), int(5 op 4)); \
285 \
286 result = array1 op 5; \
287 boost::compute::system::finish(); \
288 BOOST_CHECK_EQUAL(int(result[0]), int(1 op 5)); \
289 BOOST_CHECK_EQUAL(int(result[1]), int(2 op 5)); \
290 BOOST_CHECK_EQUAL(int(result[2]), int(3 op 5)); \
291 BOOST_CHECK_EQUAL(int(result[3]), int(4 op 5)); \
292 \
293 result = array1 op array2; \
294 boost::compute::system::finish(); \
295 BOOST_CHECK_EQUAL(int(result[0]), int(1 op 4)); \
296 BOOST_CHECK_EQUAL(int(result[1]), int(2 op 5)); \
297 BOOST_CHECK_EQUAL(int(result[2]), int(3 op 2)); \
298 BOOST_CHECK_EQUAL(int(result[3]), int(4 op 1)); \
299 }
300
301 BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(^, bit_xor)
302 BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(&, bit_and)
303 BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(|, bit_or)
304 BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(<<, shift_left)
305 BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(>>, shift_right)
306
307 #undef BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP
308
309 /// \internal_
310 /// Macro for generating tests for valarray comparison operators.
311 #define BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(op, op_name) \
312 BOOST_AUTO_TEST_CASE(op_name##_comparision_operator) \
313 { \
314 int data1[] = { 1, 2, 0, 4 }; \
315 int data2[] = { 4, 0, 2, 1 }; \
316 boost::compute::valarray<int> array1(data1, 4); \
317 boost::compute::valarray<int> array2(data2, 4); \
318 boost::compute::system::finish(); \
319 \
320 boost::compute::valarray<char> result = 2 op array1; \
321 boost::compute::system::finish(); \
322 BOOST_CHECK_EQUAL(bool(result[0]), bool(2 op 1)); \
323 BOOST_CHECK_EQUAL(bool(result[1]), bool(2 op 2)); \
324 BOOST_CHECK_EQUAL(bool(result[2]), bool(2 op 0)); \
325 BOOST_CHECK_EQUAL(bool(result[3]), bool(2 op 4)); \
326 \
327 result = array1 op 2; \
328 boost::compute::system::finish(); \
329 BOOST_CHECK_EQUAL(bool(result[0]), bool(1 op 2)); \
330 BOOST_CHECK_EQUAL(bool(result[1]), bool(2 op 2)); \
331 BOOST_CHECK_EQUAL(bool(result[2]), bool(0 op 2)); \
332 BOOST_CHECK_EQUAL(bool(result[3]), bool(4 op 2)); \
333 \
334 result = array1 op array2; \
335 boost::compute::system::finish(); \
336 BOOST_CHECK_EQUAL(bool(result[0]), bool(1 op 4)); \
337 BOOST_CHECK_EQUAL(bool(result[1]), bool(2 op 0)); \
338 BOOST_CHECK_EQUAL(bool(result[2]), bool(0 op 2)); \
339 BOOST_CHECK_EQUAL(bool(result[3]), bool(4 op 1)); \
340 }
341
342 BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(==, equal_to)
343 BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(!=, not_equal_to)
344 BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(>, greater)
345 BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(<, less)
346 BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(>=, greater_equal)
347 BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(<=, less_equal)
348
349 /// \internal_
350 /// Macro for generating tests for valarray binary logical operators.
351 #define BOOST_COMPUTE_TEST_VALARRAY_LOGICAL_OPERATOR(op, op_name) \
352 BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(op, op_name)
353
354 BOOST_COMPUTE_TEST_VALARRAY_LOGICAL_OPERATOR(&&, logical_and)
355 BOOST_COMPUTE_TEST_VALARRAY_LOGICAL_OPERATOR(||, logical_or)
356
357 #undef BOOST_COMPUTE_TEST_VALARRAY_LOGICAL_OPERATOR
358
359 #undef BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR
360
361 BOOST_AUTO_TEST_SUITE_END()
362