1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
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
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
11 #define BOOST_TEST_MODULE TestValarray
12 #include <boost/test/unit_test.hpp>
14 #include <boost/compute/system.hpp>
15 #include <boost/compute/command_queue.hpp>
16 #include <boost/compute/container/valarray.hpp>
18 #include "check_macros.hpp"
19 #include "context_setup.hpp"
21 BOOST_AUTO_TEST_CASE(size
)
23 boost::compute::valarray
<float> array
;
24 BOOST_CHECK_EQUAL(array
.size(), size_t(0));
27 BOOST_CHECK_EQUAL(array
.size(), size_t(10));
30 BOOST_AUTO_TEST_CASE(at
)
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));
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));
44 BOOST_AUTO_TEST_CASE(min_and_max
)
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));
50 BOOST_CHECK_EQUAL((array
.min
)(), int(1));
51 BOOST_CHECK_EQUAL((array
.max
)(), int(9));
54 BOOST_AUTO_TEST_CASE(sum
)
56 int data
[] = { 1, 2, 3, 4 };
57 boost::compute::valarray
<int> array(data
, 4);
58 boost::compute::system::finish();
60 BOOST_CHECK_EQUAL(array
.size(), size_t(4));
61 BOOST_CHECK_EQUAL(array
.sum(), int(10));
64 BOOST_AUTO_TEST_CASE(apply
)
66 int data
[] = { -1, 2, -3, 4 };
67 boost::compute::valarray
<int> array(data
, 4);
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));
79 /// Tests for compound assignment operators that works for floating
81 #define BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT(op, op_name) \
82 BOOST_AUTO_TEST_CASE(op_name##_ca_operator_no_fp) \
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(); \
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); \
96 array1 = boost::compute::valarray<float>(data, 4); \
97 boost::compute::system::finish(); \
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); \
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); \
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
)
120 #undef BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT
123 /// Tests for compound assignment operators that does NOT work for floating
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) \
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(); \
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)); \
141 array1 = boost::compute::valarray<int>(data, 4); \
142 boost::compute::system::finish(); \
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)); \
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)); \
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
)
167 #undef BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP
169 BOOST_AUTO_TEST_CASE(unary_plus_operator
)
171 int data
[] = { 1, 2, 3, 4 };
172 boost::compute::valarray
<int> array(data
, 4);
173 boost::compute::system::finish();
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)));
183 BOOST_AUTO_TEST_CASE(unary_minus_operator
)
185 int data
[] = { -1, 2, 0, 4 };
186 boost::compute::valarray
<int> array(data
, 4);
187 boost::compute::system::finish();
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));
197 BOOST_AUTO_TEST_CASE(unary_bitwise_not_operator
)
199 int data
[] = { 1, 2, 3, 4 };
200 boost::compute::valarray
<int> array(data
, 4);
201 boost::compute::system::finish();
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)));
211 BOOST_AUTO_TEST_CASE(unary_logical_not_operator
)
213 int data
[] = { 1, -2, 0, 4 };
214 boost::compute::valarray
<int> array(data
, 4);
215 boost::compute::system::finish();
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)));
226 /// Tests for binary operators that works for floating
228 #define BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR(op, op_name) \
229 BOOST_AUTO_TEST_CASE(op_name##_binary_operator) \
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(); \
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); \
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); \
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); \
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
)
264 #undef BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR
267 /// Tests for compound assignment operators that does NOT work for floating
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) \
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(); \
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)); \
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)); \
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)); \
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
)
307 #undef BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP
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) \
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(); \
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)); \
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)); \
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)); \
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
)
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)
354 BOOST_COMPUTE_TEST_VALARRAY_LOGICAL_OPERATOR(&&, logical_and
)
355 BOOST_COMPUTE_TEST_VALARRAY_LOGICAL_OPERATOR(||, logical_or
)
357 #undef BOOST_COMPUTE_TEST_VALARRAY_LOGICAL_OPERATOR
359 #undef BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR
361 BOOST_AUTO_TEST_SUITE_END()