• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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