test_lambda.cpp 20 KB

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