]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 TestLambda | |
12 | #include <boost/test/unit_test.hpp> | |
13 | ||
14 | #include <boost/tuple/tuple_io.hpp> | |
15 | #include <boost/tuple/tuple_comparison.hpp> | |
16 | ||
17 | #include <boost/compute/function.hpp> | |
18 | #include <boost/compute/lambda.hpp> | |
19 | #include <boost/compute/algorithm/copy_n.hpp> | |
20 | #include <boost/compute/algorithm/for_each.hpp> | |
21 | #include <boost/compute/algorithm/transform.hpp> | |
22 | #include <boost/compute/container/vector.hpp> | |
23 | #include <boost/compute/functional/bind.hpp> | |
24 | #include <boost/compute/iterator/zip_iterator.hpp> | |
25 | #include <boost/compute/types/pair.hpp> | |
26 | #include <boost/compute/types/tuple.hpp> | |
27 | ||
28 | #include "check_macros.hpp" | |
b32b8144 | 29 | #include "quirks.hpp" |
7c673cae FG |
30 | #include "context_setup.hpp" |
31 | ||
32 | namespace bc = boost::compute; | |
33 | namespace compute = boost::compute; | |
34 | ||
35 | BOOST_AUTO_TEST_CASE(squared_plus_one) | |
36 | { | |
37 | bc::vector<int> vector(context); | |
38 | vector.push_back(1, queue); | |
39 | vector.push_back(2, queue); | |
40 | vector.push_back(3, queue); | |
41 | vector.push_back(4, queue); | |
42 | vector.push_back(5, queue); | |
43 | ||
44 | // multiply each value by itself and add one | |
45 | bc::transform(vector.begin(), | |
46 | vector.end(), | |
47 | vector.begin(), | |
48 | (bc::_1 * bc::_1) + 1, | |
49 | queue); | |
50 | CHECK_RANGE_EQUAL(int, 5, vector, (2, 5, 10, 17, 26)); | |
51 | } | |
52 | ||
53 | BOOST_AUTO_TEST_CASE(abs_int) | |
54 | { | |
55 | bc::vector<int> vector(context); | |
56 | vector.push_back(-1, queue); | |
57 | vector.push_back(-2, queue); | |
58 | vector.push_back(3, queue); | |
59 | vector.push_back(-4, queue); | |
60 | vector.push_back(5, queue); | |
61 | ||
62 | bc::transform(vector.begin(), | |
63 | vector.end(), | |
64 | vector.begin(), | |
65 | abs(bc::_1), | |
66 | queue); | |
67 | CHECK_RANGE_EQUAL(int, 5, vector, (1, 2, 3, 4, 5)); | |
68 | } | |
69 | ||
70 | template<class Result, class Expr> | |
71 | void check_lambda_result(const Expr &) | |
72 | { | |
73 | BOOST_STATIC_ASSERT(( | |
74 | boost::is_same< | |
75 | typename ::boost::compute::lambda::result_of<Expr>::type, | |
76 | Result | |
77 | >::value | |
78 | )); | |
79 | } | |
80 | ||
81 | template<class Result, class Expr, class Arg1> | |
82 | void check_lambda_result(const Expr &, const Arg1 &) | |
83 | { | |
84 | BOOST_STATIC_ASSERT(( | |
85 | boost::is_same< | |
86 | typename ::boost::compute::lambda::result_of< | |
87 | Expr, | |
88 | typename boost::tuple<Arg1> | |
89 | >::type, | |
90 | Result | |
91 | >::value | |
92 | )); | |
93 | } | |
94 | ||
95 | template<class Result, class Expr, class Arg1, class Arg2> | |
96 | void check_lambda_result(const Expr &, const Arg1 &, const Arg2 &) | |
97 | { | |
98 | BOOST_STATIC_ASSERT(( | |
99 | boost::is_same< | |
100 | typename ::boost::compute::lambda::result_of< | |
101 | Expr, | |
102 | typename boost::tuple<Arg1, Arg2> | |
103 | >::type, | |
104 | Result | |
105 | >::value | |
106 | )); | |
107 | } | |
108 | ||
109 | template<class Result, class Expr, class Arg1, class Arg2, class Arg3> | |
110 | void check_lambda_result(const Expr &, const Arg1 &, const Arg2 &, const Arg3 &) | |
111 | { | |
112 | BOOST_STATIC_ASSERT(( | |
113 | boost::is_same< | |
114 | typename ::boost::compute::lambda::result_of< | |
115 | Expr, | |
116 | typename boost::tuple<Arg1, Arg2, Arg3> | |
117 | >::type, | |
118 | Result | |
119 | >::value | |
120 | )); | |
121 | } | |
122 | ||
123 | BOOST_AUTO_TEST_CASE(result_of) | |
124 | { | |
125 | using ::boost::compute::lambda::_1; | |
126 | using ::boost::compute::lambda::_2; | |
127 | using ::boost::compute::lambda::_3; | |
128 | ||
129 | namespace proto = ::boost::proto; | |
130 | ||
b32b8144 FG |
131 | using boost::compute::int_; |
132 | ||
133 | check_lambda_result<int_>(proto::lit(1)); | |
134 | check_lambda_result<int_>(proto::lit(1) + 2); | |
7c673cae FG |
135 | check_lambda_result<float>(proto::lit(1.2f)); |
136 | check_lambda_result<float>(proto::lit(1) + 1.2f); | |
137 | check_lambda_result<float>(proto::lit(1) / 2 + 1.2f); | |
138 | ||
139 | using boost::compute::float4_; | |
b32b8144 | 140 | using boost::compute::int4_; |
7c673cae | 141 | |
b32b8144 | 142 | check_lambda_result<int_>(_1, int_(1)); |
7c673cae FG |
143 | check_lambda_result<float>(_1, float(1.2f)); |
144 | check_lambda_result<float4_>(_1, float4_(1, 2, 3, 4)); | |
145 | check_lambda_result<float4_>(2.0f * _1, float4_(1, 2, 3, 4)); | |
146 | check_lambda_result<float4_>(_1 * 2.0f, float4_(1, 2, 3, 4)); | |
147 | ||
148 | check_lambda_result<float>(dot(_1, _2), float4_(0, 1, 2, 3), float4_(3, 2, 1, 0)); | |
149 | check_lambda_result<float>(dot(_1, float4_(3, 2, 1, 0)), float4_(0, 1, 2, 3)); | |
150 | check_lambda_result<float>(distance(_1, _2), float4_(0, 1, 2, 3), float4_(3, 2, 1, 0)); | |
151 | check_lambda_result<float>(distance(_1, float4_(3, 2, 1, 0)), float4_(0, 1, 2, 3)); | |
152 | ||
b32b8144 FG |
153 | check_lambda_result<float>(length(_1), float4_(3, 2, 1, 0)); |
154 | ||
7c673cae FG |
155 | check_lambda_result<float4_>(cross(_1, _2), float4_(0, 1, 2, 3), float4_(3, 2, 1, 0)); |
156 | check_lambda_result<float4_>(cross(_1, float4_(3, 2, 1, 0)), float4_(0, 1, 2, 3)); | |
157 | ||
b32b8144 FG |
158 | check_lambda_result<float4_>(max(_1, _2), float4_(3, 2, 1, 0), float4_(0, 1, 2, 3)); |
159 | check_lambda_result<float4_>(max(_1, float(1.0f)), float4_(0, 1, 2, 3)); | |
160 | check_lambda_result<int4_>(max(_1, int4_(3, 2, 1, 0)), int4_(0, 1, 2, 3)); | |
161 | check_lambda_result<int4_>(max(_1, int_(1)), int4_(0, 1, 2, 3)); | |
162 | check_lambda_result<float4_>(min(_1, float4_(3, 2, 1, 0)), float4_(0, 1, 2, 3)); | |
163 | ||
164 | check_lambda_result<float4_>(step(_1, _2), float4_(3, 2, 1, 0), float4_(0, 1, 2, 3)); | |
165 | check_lambda_result<int4_>(step(_1, _2), float(3.0f), int4_(0, 1, 2, 3)); | |
166 | ||
167 | check_lambda_result<float4_>( | |
168 | smoothstep(_1, _2, _3), | |
169 | float4_(3, 2, 1, 0), float4_(3, 2, 1, 0), float4_(0, 1, 2, 3) | |
170 | ); | |
171 | check_lambda_result<int4_>( | |
172 | smoothstep(_1, _2, _3), | |
173 | float(2.0f), float(3.0f), int4_(0, 1, 2, 3) | |
174 | ); | |
175 | ||
176 | check_lambda_result<int4_>(bc::lambda::isinf(_1), float4_(0, 1, 2, 3)); | |
177 | ||
7c673cae FG |
178 | check_lambda_result<int>(_1 + 2, int(2)); |
179 | check_lambda_result<float>(_1 + 2, float(2.2f)); | |
180 | ||
181 | check_lambda_result<int>(_1 + _2, int(1), int(2)); | |
182 | check_lambda_result<float>(_1 + _2, int(1), float(2.2f)); | |
183 | ||
184 | check_lambda_result<int>(_1 + _1, int(1)); | |
185 | check_lambda_result<float>(_1 * _1, float(1)); | |
186 | ||
187 | using boost::compute::lambda::get; | |
188 | ||
189 | check_lambda_result<float>(get<0>(_1), float4_(1, 2, 3, 4)); | |
190 | check_lambda_result<bool>(get<0>(_1) < 1.f, float4_(1, 2, 3, 4)); | |
191 | check_lambda_result<bool>(_1 < 1.f, float(2)); | |
192 | ||
193 | using boost::compute::lambda::make_pair; | |
194 | ||
195 | check_lambda_result<int>(get<0>(make_pair(_1, _2)), int(1), float(1.2f)); | |
196 | check_lambda_result<float>(get<1>(make_pair(_1, _2)), int(1), float(1.2f)); | |
197 | check_lambda_result<std::pair<int, float> >(make_pair(_1, _2), int(1), float(1.2f)); | |
198 | ||
199 | using boost::compute::lambda::make_tuple; | |
200 | ||
201 | check_lambda_result<boost::tuple<int> >(make_tuple(_1), int(1)); | |
202 | check_lambda_result<boost::tuple<int, float> >(make_tuple(_1, _2), int(1), float(1.2f)); | |
203 | check_lambda_result<boost::tuple<int, int> >(make_tuple(_1, _1), int(1)); | |
204 | check_lambda_result<boost::tuple<int, float> >(make_tuple(_1, _2), int(1), float(1.4f)); | |
205 | check_lambda_result<boost::tuple<char, int, float> >( | |
206 | make_tuple(_1, _2, _3), char('a'), int(2), float(3.4f) | |
207 | ); | |
208 | check_lambda_result<boost::tuple<int, int, int> >( | |
209 | make_tuple(_1, _1, _1), int(1), float(1.4f) | |
210 | ); | |
211 | check_lambda_result<boost::tuple<int, float, int, float, int> >( | |
212 | make_tuple(_1, _2, _1, _2, _1), int(1), float(1.4f) | |
213 | ); | |
214 | } | |
215 | ||
216 | BOOST_AUTO_TEST_CASE(make_function_from_lamdba) | |
217 | { | |
218 | using boost::compute::lambda::_1; | |
219 | ||
220 | int data[] = { 2, 4, 6, 8, 10 }; | |
221 | compute::vector<int> vector(data, data + 5, queue); | |
222 | ||
223 | compute::function<int(int)> f = _1 * 2 + 3; | |
224 | ||
225 | compute::transform( | |
226 | vector.begin(), vector.end(), vector.begin(), f, queue | |
227 | ); | |
228 | CHECK_RANGE_EQUAL(int, 5, vector, (7, 11, 15, 19, 23)); | |
229 | } | |
230 | ||
231 | BOOST_AUTO_TEST_CASE(make_function_from_binary_lamdba) | |
232 | { | |
233 | using boost::compute::lambda::_1; | |
234 | using boost::compute::lambda::_2; | |
235 | using boost::compute::lambda::abs; | |
236 | ||
237 | int data1[] = { 2, 4, 6, 8, 10 }; | |
238 | int data2[] = { 10, 8, 6, 4, 2 }; | |
239 | compute::vector<int> vec1(data1, data1 + 5, queue); | |
240 | compute::vector<int> vec2(data2, data2 + 5, queue); | |
241 | compute::vector<int> result(5, context); | |
242 | ||
243 | compute::function<int(int, int)> f = abs(_1 - _2); | |
244 | ||
245 | compute::transform( | |
246 | vec1.begin(), vec1.end(), vec2.begin(), result.begin(), f, queue | |
247 | ); | |
248 | CHECK_RANGE_EQUAL(int, 5, result, (8, 4, 0, 4, 8)); | |
249 | } | |
250 | ||
b32b8144 FG |
251 | BOOST_AUTO_TEST_CASE(lambda_binary_function_with_pointer_modf) |
252 | { | |
253 | using boost::compute::lambda::_1; | |
254 | using boost::compute::lambda::_2; | |
255 | using boost::compute::lambda::abs; | |
256 | ||
257 | bc::float_ data1[] = { 2.2f, 4.2f, 6.3f, 8.3f, 10.2f }; | |
258 | compute::vector<bc::float_> vec1(data1, data1 + 5, queue); | |
259 | compute::vector<bc::float_> vec2(size_t(5), context); | |
260 | compute::vector<bc::float_> result(5, context); | |
261 | ||
262 | compute::transform( | |
263 | bc::make_transform_iterator(vec1.begin(), _1 + 0.01f), | |
264 | bc::make_transform_iterator(vec1.end(), _1 + 0.01f), | |
265 | vec2.begin(), | |
266 | result.begin(), | |
267 | bc::lambda::modf(_1, _2), | |
268 | queue | |
269 | ); | |
270 | CHECK_RANGE_CLOSE(bc::float_, 5, result, (0.21f, 0.21f, 0.31f, 0.31f, 0.21f), 0.01f); | |
271 | CHECK_RANGE_CLOSE(bc::float_, 5, vec2, (2, 4, 6, 8, 10), 0.01f); | |
272 | } | |
273 | ||
274 | BOOST_AUTO_TEST_CASE(lambda_tenary_function_with_pointer_remquo) | |
275 | { | |
276 | if(!has_remquo_func(device)) | |
277 | { | |
278 | return; | |
279 | } | |
280 | ||
281 | using boost::compute::lambda::_1; | |
282 | using boost::compute::lambda::_2; | |
283 | using boost::compute::lambda::get; | |
284 | ||
285 | bc::float_ data1[] = { 2.2f, 4.2f, 6.3f, 8.3f, 10.2f }; | |
286 | bc::float_ data2[] = { 4.4f, 4.2f, 6.3f, 16.6f, 10.2f }; | |
287 | compute::vector<bc::float_> vec1(data1, data1 + 5, queue); | |
288 | compute::vector<bc::float_> vec2(data2, data2 + 5, queue); | |
289 | compute::vector<bc::int_> vec3(size_t(5), context); | |
290 | compute::vector<bc::float_> result(5, context); | |
291 | ||
292 | compute::transform( | |
293 | compute::make_zip_iterator( | |
294 | boost::make_tuple(vec1.begin(), vec2.begin(), vec3.begin()) | |
295 | ), | |
296 | compute::make_zip_iterator( | |
297 | boost::make_tuple(vec1.end(), vec2.end(), vec3.end()) | |
298 | ), | |
299 | result.begin(), | |
300 | bc::lambda::remquo(get<0>(_1), get<1>(_1), get<2>(_1)), | |
301 | queue | |
302 | ); | |
303 | CHECK_RANGE_CLOSE(bc::float_, 5, result, (2.2f, 0.0f, 0.0f, 8.3f, 0.0f), 0.01f); | |
304 | CHECK_RANGE_EQUAL(bc::int_, 5, vec3, (0, 1, 1, 0, 1)); | |
305 | } | |
306 | ||
7c673cae FG |
307 | BOOST_AUTO_TEST_CASE(lambda_get_vector) |
308 | { | |
309 | using boost::compute::_1; | |
310 | using boost::compute::int2_; | |
311 | using boost::compute::lambda::get; | |
312 | ||
313 | int data[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; | |
314 | compute::vector<int2_> vector(4, context); | |
315 | ||
316 | compute::copy( | |
317 | reinterpret_cast<int2_ *>(data), | |
318 | reinterpret_cast<int2_ *>(data) + 4, | |
319 | vector.begin(), | |
320 | queue | |
321 | ); | |
322 | ||
323 | // extract first component of each vector | |
324 | compute::vector<int> first_component(4, context); | |
325 | compute::transform( | |
326 | vector.begin(), | |
327 | vector.end(), | |
328 | first_component.begin(), | |
329 | get<0>(_1), | |
330 | queue | |
331 | ); | |
332 | CHECK_RANGE_EQUAL(int, 4, first_component, (1, 3, 5, 7)); | |
333 | ||
334 | // extract second component of each vector | |
335 | compute::vector<int> second_component(4, context); | |
336 | compute::transform( | |
337 | vector.begin(), | |
338 | vector.end(), | |
339 | first_component.begin(), | |
340 | get<1>(_1), | |
341 | queue | |
342 | ); | |
343 | CHECK_RANGE_EQUAL(int, 4, first_component, (2, 4, 6, 8)); | |
344 | } | |
345 | ||
346 | BOOST_AUTO_TEST_CASE(lambda_get_pair) | |
347 | { | |
348 | using boost::compute::_1; | |
349 | using boost::compute::lambda::get; | |
350 | ||
351 | compute::vector<std::pair<int, float> > vector(context); | |
352 | vector.push_back(std::make_pair(1, 1.2f), queue); | |
353 | vector.push_back(std::make_pair(3, 3.4f), queue); | |
354 | vector.push_back(std::make_pair(5, 5.6f), queue); | |
355 | vector.push_back(std::make_pair(7, 7.8f), queue); | |
356 | ||
357 | // extract first compoenent of each pair | |
358 | compute::vector<int> first_component(4, context); | |
359 | compute::transform( | |
360 | vector.begin(), | |
361 | vector.end(), | |
362 | first_component.begin(), | |
363 | get<0>(_1), | |
364 | queue | |
365 | ); | |
366 | CHECK_RANGE_EQUAL(int, 4, first_component, (1, 3, 5, 7)); | |
367 | ||
368 | // extract second compoenent of each pair | |
369 | compute::vector<float> second_component(4, context); | |
370 | compute::transform( | |
371 | vector.begin(), | |
372 | vector.end(), | |
373 | second_component.begin(), | |
374 | get<1>(_1), | |
375 | queue | |
376 | ); | |
377 | CHECK_RANGE_EQUAL(float, 4, second_component, (1.2f, 3.4f, 5.6f, 7.8f)); | |
378 | } | |
379 | ||
380 | BOOST_AUTO_TEST_CASE(lambda_get_tuple) | |
381 | { | |
382 | using boost::compute::_1; | |
383 | using boost::compute::lambda::get; | |
384 | ||
385 | compute::vector<boost::tuple<int, char, float> > vector(context); | |
386 | ||
387 | vector.push_back(boost::make_tuple(1, 'a', 1.2f), queue); | |
388 | vector.push_back(boost::make_tuple(3, 'b', 3.4f), queue); | |
389 | vector.push_back(boost::make_tuple(5, 'c', 5.6f), queue); | |
390 | vector.push_back(boost::make_tuple(7, 'd', 7.8f), queue); | |
391 | ||
392 | // extract first component of each tuple | |
393 | compute::vector<int> first_component(4, context); | |
394 | compute::transform( | |
395 | vector.begin(), | |
396 | vector.end(), | |
397 | first_component.begin(), | |
398 | get<0>(_1), | |
399 | queue | |
400 | ); | |
401 | CHECK_RANGE_EQUAL(int, 4, first_component, (1, 3, 5, 7)); | |
402 | ||
403 | // extract second component of each tuple | |
404 | compute::vector<char> second_component(4, context); | |
405 | compute::transform( | |
406 | vector.begin(), | |
407 | vector.end(), | |
408 | second_component.begin(), | |
409 | get<1>(_1), | |
410 | queue | |
411 | ); | |
412 | CHECK_RANGE_EQUAL(char, 4, second_component, ('a', 'b', 'c', 'd')); | |
413 | ||
414 | // extract third component of each tuple | |
415 | compute::vector<float> third_component(4, context); | |
416 | compute::transform( | |
417 | vector.begin(), | |
418 | vector.end(), | |
419 | third_component.begin(), | |
420 | get<2>(_1), | |
421 | queue | |
422 | ); | |
423 | CHECK_RANGE_EQUAL(float, 4, third_component, (1.2f, 3.4f, 5.6f, 7.8f)); | |
424 | } | |
425 | ||
426 | BOOST_AUTO_TEST_CASE(lambda_get_zip_iterator) | |
427 | { | |
428 | using boost::compute::_1; | |
429 | using boost::compute::lambda::get; | |
430 | ||
431 | float data[] = { 1.2f, 2.3f, 3.4f, 4.5f, 5.6f, 6.7f, 7.8f, 9.0f }; | |
432 | compute::vector<float> input(8, context); | |
433 | compute::copy(data, data + 8, input.begin(), queue); | |
434 | ||
435 | compute::vector<float> output(8, context); | |
436 | ||
437 | compute::for_each( | |
438 | compute::make_zip_iterator( | |
439 | boost::make_tuple(input.begin(), output.begin()) | |
440 | ), | |
441 | compute::make_zip_iterator( | |
442 | boost::make_tuple(input.end(), output.end()) | |
443 | ), | |
444 | get<1>(_1) = get<0>(_1), | |
445 | queue | |
446 | ); | |
447 | CHECK_RANGE_EQUAL(float, 8, output, | |
448 | (1.2f, 2.3f, 3.4f, 4.5f, 5.6f, 6.7f, 7.8f, 9.0f) | |
449 | ); | |
450 | } | |
451 | ||
452 | BOOST_AUTO_TEST_CASE(lambda_make_pair) | |
453 | { | |
454 | using boost::compute::_1; | |
455 | using boost::compute::_2; | |
456 | using boost::compute::lambda::make_pair; | |
457 | ||
458 | int int_data[] = { 1, 3, 5, 7 }; | |
459 | float float_data[] = { 1.2f, 2.3f, 3.4f, 4.5f }; | |
460 | ||
461 | compute::vector<int> int_vector(int_data, int_data + 4, queue); | |
462 | compute::vector<float> float_vector(float_data, float_data + 4, queue); | |
463 | compute::vector<std::pair<int, float> > output_vector(4, context); | |
464 | ||
465 | compute::transform( | |
466 | int_vector.begin(), | |
467 | int_vector.end(), | |
468 | float_vector.begin(), | |
469 | output_vector.begin(), | |
470 | make_pair(_1 - 1, 0 - _2), | |
471 | queue | |
472 | ); | |
473 | ||
474 | std::vector<std::pair<int, float> > host_vector(4); | |
475 | compute::copy_n(output_vector.begin(), 4, host_vector.begin(), queue); | |
476 | BOOST_CHECK(host_vector[0] == std::make_pair(0, -1.2f)); | |
477 | BOOST_CHECK(host_vector[1] == std::make_pair(2, -2.3f)); | |
478 | BOOST_CHECK(host_vector[2] == std::make_pair(4, -3.4f)); | |
479 | BOOST_CHECK(host_vector[3] == std::make_pair(6, -4.5f)); | |
480 | } | |
481 | ||
482 | BOOST_AUTO_TEST_CASE(lambda_make_tuple) | |
483 | { | |
484 | using boost::compute::_1; | |
485 | using boost::compute::lambda::get; | |
486 | using boost::compute::lambda::make_tuple; | |
487 | ||
488 | std::vector<boost::tuple<int, float> > data; | |
489 | data.push_back(boost::make_tuple(2, 1.2f)); | |
490 | data.push_back(boost::make_tuple(4, 2.4f)); | |
491 | data.push_back(boost::make_tuple(6, 4.6f)); | |
492 | data.push_back(boost::make_tuple(8, 6.8f)); | |
493 | ||
494 | compute::vector<boost::tuple<int, float> > input_vector(4, context); | |
495 | compute::copy(data.begin(), data.end(), input_vector.begin(), queue); | |
496 | ||
497 | // reverse the elements in the tuple | |
498 | compute::vector<boost::tuple<float, int> > output_vector(4, context); | |
499 | ||
500 | compute::transform( | |
501 | input_vector.begin(), | |
502 | input_vector.end(), | |
503 | output_vector.begin(), | |
504 | make_tuple(get<1>(_1), get<0>(_1)), | |
505 | queue | |
506 | ); | |
507 | ||
508 | std::vector<boost::tuple<float, int> > host_vector(4); | |
509 | compute::copy_n(output_vector.begin(), 4, host_vector.begin(), queue); | |
510 | BOOST_CHECK_EQUAL(host_vector[0], boost::make_tuple(1.2f, 2)); | |
511 | BOOST_CHECK_EQUAL(host_vector[1], boost::make_tuple(2.4f, 4)); | |
512 | BOOST_CHECK_EQUAL(host_vector[2], boost::make_tuple(4.6f, 6)); | |
513 | BOOST_CHECK_EQUAL(host_vector[3], boost::make_tuple(6.8f, 8)); | |
514 | ||
515 | // duplicate each element in the tuple | |
516 | compute::vector<boost::tuple<int, int, float, float> > doubled_vector(4, context); | |
517 | compute::transform( | |
518 | input_vector.begin(), | |
519 | input_vector.end(), | |
520 | doubled_vector.begin(), | |
521 | make_tuple(get<0>(_1), get<0>(_1), get<1>(_1), get<1>(_1)), | |
522 | queue | |
523 | ); | |
524 | ||
525 | std::vector<boost::tuple<int, int, float, float> > doubled_host_vector(4); | |
526 | compute::copy_n(doubled_vector.begin(), 4, doubled_host_vector.begin(), queue); | |
527 | BOOST_CHECK_EQUAL(doubled_host_vector[0], boost::make_tuple(2, 2, 1.2f, 1.2f)); | |
528 | BOOST_CHECK_EQUAL(doubled_host_vector[1], boost::make_tuple(4, 4, 2.4f, 2.4f)); | |
529 | BOOST_CHECK_EQUAL(doubled_host_vector[2], boost::make_tuple(6, 6, 4.6f, 4.6f)); | |
530 | BOOST_CHECK_EQUAL(doubled_host_vector[3], boost::make_tuple(8, 8, 6.8f, 6.8f)); | |
531 | } | |
532 | ||
533 | BOOST_AUTO_TEST_CASE(bind_lambda_function) | |
534 | { | |
535 | using compute::placeholders::_1; | |
536 | namespace lambda = compute::lambda; | |
537 | ||
538 | int data[] = { 1, 2, 3, 4 }; | |
539 | compute::vector<int> vector(data, data + 4, queue); | |
540 | ||
541 | compute::transform( | |
542 | vector.begin(), vector.end(), vector.begin(), | |
543 | compute::bind(lambda::_1 * lambda::_2, _1, 2), | |
544 | queue | |
545 | ); | |
546 | CHECK_RANGE_EQUAL(int, 4, vector, (2, 4, 6, 8)); | |
547 | } | |
548 | ||
b32b8144 FG |
549 | BOOST_AUTO_TEST_CASE(lambda_function_with_uint_args) |
550 | { | |
551 | compute::uint_ host_data[] = { 1, 3, 5, 7, 9 }; | |
552 | compute::vector<compute::uint_> device_vector(host_data, host_data + 5, queue); | |
553 | ||
554 | using boost::compute::lambda::clamp; | |
555 | using compute::lambda::_1; | |
556 | ||
557 | compute::transform( | |
558 | device_vector.begin(), device_vector.end(), | |
559 | device_vector.begin(), | |
560 | clamp(_1, compute::uint_(4), compute::uint_(6)), | |
561 | queue | |
562 | ); | |
563 | CHECK_RANGE_EQUAL(compute::uint_, 5, device_vector, (4, 4, 5, 6, 6)); | |
564 | } | |
565 | ||
566 | BOOST_AUTO_TEST_CASE(lambda_function_with_short_args) | |
567 | { | |
568 | compute::short_ host_data[] = { 1, 3, 5, 7, 9 }; | |
569 | compute::vector<compute::short_> device_vector(host_data, host_data + 5, queue); | |
570 | ||
571 | using boost::compute::lambda::clamp; | |
572 | using compute::lambda::_1; | |
573 | ||
574 | compute::transform( | |
575 | device_vector.begin(), device_vector.end(), | |
576 | device_vector.begin(), | |
577 | clamp(_1, compute::short_(4), compute::short_(6)), | |
578 | queue | |
579 | ); | |
580 | CHECK_RANGE_EQUAL(compute::short_, 5, device_vector, (4, 4, 5, 6, 6)); | |
581 | } | |
582 | ||
583 | BOOST_AUTO_TEST_CASE(lambda_function_with_uchar_args) | |
584 | { | |
585 | compute::uchar_ host_data[] = { 1, 3, 5, 7, 9 }; | |
586 | compute::vector<compute::uchar_> device_vector(host_data, host_data + 5, queue); | |
587 | ||
588 | using boost::compute::lambda::clamp; | |
589 | using compute::lambda::_1; | |
590 | ||
591 | compute::transform( | |
592 | device_vector.begin(), device_vector.end(), | |
593 | device_vector.begin(), | |
594 | clamp(_1, compute::uchar_(4), compute::uchar_(6)), | |
595 | queue | |
596 | ); | |
597 | CHECK_RANGE_EQUAL(compute::uchar_, 5, device_vector, (4, 4, 5, 6, 6)); | |
598 | } | |
599 | ||
600 | BOOST_AUTO_TEST_CASE(lambda_function_with_char_args) | |
601 | { | |
602 | compute::char_ host_data[] = { 1, 3, 5, 7, 9 }; | |
603 | compute::vector<compute::char_> device_vector(host_data, host_data + 5, queue); | |
604 | ||
605 | using boost::compute::lambda::clamp; | |
606 | using compute::lambda::_1; | |
607 | ||
608 | compute::transform( | |
609 | device_vector.begin(), device_vector.end(), | |
610 | device_vector.begin(), | |
611 | clamp(_1, compute::char_(4), compute::char_(6)), | |
612 | queue | |
613 | ); | |
614 | CHECK_RANGE_EQUAL(compute::char_, 5, device_vector, (4, 4, 5, 6, 6)); | |
615 | } | |
616 | ||
7c673cae | 617 | BOOST_AUTO_TEST_SUITE_END() |