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"
29 #include "quirks.hpp"
30 #include "context_setup.hpp"
31
32 namespace bc = boost::compute;
33 namespace compute = boost::compute;
34
BOOST_AUTO_TEST_CASE(squared_plus_one)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
BOOST_AUTO_TEST_CASE(abs_int)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>
check_lambda_result(const 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>
check_lambda_result(const Expr &,const 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>
check_lambda_result(const Expr &,const Arg1 &,const 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>
check_lambda_result(const Expr &,const Arg1 &,const Arg2 &,const 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
BOOST_AUTO_TEST_CASE(result_of)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
131 using boost::compute::int_;
132
133 check_lambda_result<int_>(proto::lit(1));
134 check_lambda_result<int_>(proto::lit(1) + 2);
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_;
140 using boost::compute::int4_;
141
142 check_lambda_result<int_>(_1, int_(1));
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
153 check_lambda_result<float>(length(_1), float4_(3, 2, 1, 0));
154
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
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
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
BOOST_AUTO_TEST_CASE(make_function_from_lamdba)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
BOOST_AUTO_TEST_CASE(make_function_from_binary_lamdba)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
BOOST_AUTO_TEST_CASE(lambda_binary_function_with_pointer_modf)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
BOOST_AUTO_TEST_CASE(lambda_tenary_function_with_pointer_remquo)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
BOOST_AUTO_TEST_CASE(lambda_get_vector)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
BOOST_AUTO_TEST_CASE(lambda_get_pair)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
BOOST_AUTO_TEST_CASE(lambda_get_tuple)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
BOOST_AUTO_TEST_CASE(lambda_get_zip_iterator)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
BOOST_AUTO_TEST_CASE(lambda_make_pair)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
BOOST_AUTO_TEST_CASE(lambda_make_tuple)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
BOOST_AUTO_TEST_CASE(bind_lambda_function)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
BOOST_AUTO_TEST_CASE(lambda_function_with_uint_args)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
BOOST_AUTO_TEST_CASE(lambda_function_with_short_args)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
BOOST_AUTO_TEST_CASE(lambda_function_with_uchar_args)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
BOOST_AUTO_TEST_CASE(lambda_function_with_char_args)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
617 BOOST_AUTO_TEST_SUITE_END()
618