test_copy_type_mismatch.cpp 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380
  1. //---------------------------------------------------------------------------//
  2. // Copyright (c) 2016 Jakub Szuppe <j.szuppe@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. // Undefining BOOST_COMPUTE_USE_OFFLINE_CACHE macro as we want to modify cached
  11. // parameters for copy algorithm without any undesirable consequences (like
  12. // saving modified values of those parameters).
  13. #ifdef BOOST_COMPUTE_USE_OFFLINE_CACHE
  14. #undef BOOST_COMPUTE_USE_OFFLINE_CACHE
  15. #endif
  16. #define BOOST_TEST_MODULE TestCopyTypeMismatch
  17. #include <boost/test/unit_test.hpp>
  18. #include <list>
  19. #include <vector>
  20. #include <string>
  21. #include <sstream>
  22. #include <iterator>
  23. #include <iostream>
  24. #include <boost/compute/svm.hpp>
  25. #include <boost/compute/system.hpp>
  26. #include <boost/compute/functional.hpp>
  27. #include <boost/compute/command_queue.hpp>
  28. #include <boost/compute/algorithm/copy.hpp>
  29. #include <boost/compute/async/future.hpp>
  30. #include <boost/compute/container/vector.hpp>
  31. #include <boost/compute/detail/device_ptr.hpp>
  32. #include <boost/compute/memory/svm_ptr.hpp>
  33. #include <boost/compute/detail/parameter_cache.hpp>
  34. #include "quirks.hpp"
  35. #include "check_macros.hpp"
  36. #include "context_setup.hpp"
  37. namespace bc = boost::compute;
  38. namespace compute = boost::compute;
  39. BOOST_AUTO_TEST_CASE(is_same_ignore_const)
  40. {
  41. BOOST_STATIC_ASSERT((
  42. boost::compute::detail::is_same_value_type<
  43. std::vector<int>::iterator,
  44. compute::buffer_iterator<int>
  45. >::value
  46. ));
  47. BOOST_STATIC_ASSERT((
  48. boost::compute::detail::is_same_value_type<
  49. std::vector<int>::const_iterator,
  50. compute::buffer_iterator<int>
  51. >::value
  52. ));
  53. BOOST_STATIC_ASSERT((
  54. boost::compute::detail::is_same_value_type<
  55. std::vector<int>::iterator,
  56. compute::buffer_iterator<const int>
  57. >::value
  58. ));
  59. BOOST_STATIC_ASSERT((
  60. boost::compute::detail::is_same_value_type<
  61. std::vector<int>::const_iterator,
  62. compute::buffer_iterator<const int>
  63. >::value
  64. ));
  65. }
  66. BOOST_AUTO_TEST_CASE(copy_to_device_float_to_double)
  67. {
  68. if(!device.supports_extension("cl_khr_fp64")) {
  69. std::cout << "skipping test: device does not support double" << std::endl;
  70. return;
  71. }
  72. using compute::double_;
  73. using compute::float_;
  74. float_ host[] = { 6.1f, 10.2f, 19.3f, 25.4f };
  75. bc::vector<double_> device_vector(4, context);
  76. // copy host float data to double device vector
  77. bc::copy(host, host + 4, device_vector.begin(), queue);
  78. CHECK_RANGE_EQUAL(double_, 4, device_vector, (6.1f, 10.2f, 19.3f, 25.4f));
  79. }
  80. BOOST_AUTO_TEST_CASE(copy_to_device_float_to_int)
  81. {
  82. using compute::int_;
  83. using compute::float_;
  84. float_ host[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  85. bc::vector<int_> device_vector(4, context);
  86. // copy host float data to int device vector
  87. bc::copy(host, host + 4, device_vector.begin(), queue);
  88. CHECK_RANGE_EQUAL(
  89. int_,
  90. 4,
  91. device_vector,
  92. (
  93. static_cast<int_>(6.1f),
  94. static_cast<int_>(-10.2f),
  95. static_cast<int_>(19.3f),
  96. static_cast<int_>(25.4f)
  97. )
  98. );
  99. }
  100. // HOST -> DEVICE
  101. BOOST_AUTO_TEST_CASE(copy_to_device_float_to_int_mapping_device_vector)
  102. {
  103. using compute::int_;
  104. using compute::uint_;
  105. using compute::float_;
  106. float_ host[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  107. bc::vector<int_> device_vector(4, context);
  108. std::string cache_key =
  109. std::string("__boost_compute_copy_to_device_float_int");
  110. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  111. bc::detail::parameter_cache::get_global_cache(device);
  112. // save
  113. uint_ map_copy_threshold =
  114. parameters->get(cache_key, "map_copy_threshold", 0);
  115. // force copy_to_device_map (mapping device vector to the host)
  116. parameters->set(cache_key, "map_copy_threshold", 1024);
  117. // copy host float data to int device vector
  118. bc::copy(host, host + 4, device_vector.begin(), queue);
  119. CHECK_RANGE_EQUAL(
  120. int_,
  121. 4,
  122. device_vector,
  123. (
  124. static_cast<int_>(6.1f),
  125. static_cast<int_>(-10.2f),
  126. static_cast<int_>(19.3f),
  127. static_cast<int_>(25.4f)
  128. )
  129. );
  130. // restore
  131. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  132. }
  133. BOOST_AUTO_TEST_CASE(copy_to_device_float_to_int_convert_on_host)
  134. {
  135. using compute::int_;
  136. using compute::uint_;
  137. using compute::float_;
  138. std::string cache_key =
  139. std::string("__boost_compute_copy_to_device_float_int");
  140. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  141. bc::detail::parameter_cache::get_global_cache(device);
  142. // save
  143. uint_ map_copy_threshold =
  144. parameters->get(cache_key, "map_copy_threshold", 0);
  145. uint_ direct_copy_threshold =
  146. parameters->get(cache_key, "direct_copy_threshold", 0);
  147. // force copying by casting input data on host and performing
  148. // normal copy host->device (since types match now)
  149. parameters->set(cache_key, "map_copy_threshold", 0);
  150. parameters->set(cache_key, "direct_copy_threshold", 1024);
  151. float_ host[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  152. bc::vector<int_> device_vector(4, context);
  153. // copy host float data to int device vector
  154. bc::copy(host, host + 4, device_vector.begin(), queue);
  155. CHECK_RANGE_EQUAL(
  156. int_,
  157. 4,
  158. device_vector,
  159. (
  160. static_cast<int_>(6.1f),
  161. static_cast<int_>(-10.2f),
  162. static_cast<int_>(19.3f),
  163. static_cast<int_>(25.4f)
  164. )
  165. );
  166. // restore
  167. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  168. parameters->set(cache_key, "direct_copy_threshold", direct_copy_threshold);
  169. }
  170. BOOST_AUTO_TEST_CASE(copy_to_device_float_to_int_with_transform)
  171. {
  172. using compute::int_;
  173. using compute::uint_;
  174. using compute::float_;
  175. std::string cache_key =
  176. std::string("__boost_compute_copy_to_device_float_int");
  177. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  178. bc::detail::parameter_cache::get_global_cache(device);
  179. // save
  180. uint_ map_copy_threshold =
  181. parameters->get(cache_key, "map_copy_threshold", 0);
  182. uint_ direct_copy_threshold =
  183. parameters->get(cache_key, "direct_copy_threshold", 0);
  184. // force copying by mapping input data to the device memory
  185. // and using transform operation for casting & copying
  186. parameters->set(cache_key, "map_copy_threshold", 0);
  187. parameters->set(cache_key, "direct_copy_threshold", 0);
  188. float_ host[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  189. bc::vector<int_> device_vector(4, context);
  190. // copy host float data to int device vector
  191. bc::copy(host, host + 4, device_vector.begin(), queue);
  192. CHECK_RANGE_EQUAL(
  193. int_,
  194. 4,
  195. device_vector,
  196. (
  197. static_cast<int_>(6.1f),
  198. static_cast<int_>(-10.2f),
  199. static_cast<int_>(19.3f),
  200. static_cast<int_>(25.4f)
  201. )
  202. );
  203. // restore
  204. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  205. parameters->set(cache_key, "direct_copy_threshold", direct_copy_threshold);
  206. }
  207. BOOST_AUTO_TEST_CASE(copy_async_to_device_float_to_int)
  208. {
  209. using compute::int_;
  210. using compute::float_;
  211. float_ host[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  212. bc::vector<int_> device_vector(4, context);
  213. // copy host float data to int device vector
  214. compute::future<void> future =
  215. bc::copy_async(host, host + 4, device_vector.begin(), queue);
  216. future.wait();
  217. CHECK_RANGE_EQUAL(
  218. int_,
  219. 4,
  220. device_vector,
  221. (
  222. static_cast<int_>(6.1f),
  223. static_cast<int_>(-10.2f),
  224. static_cast<int_>(19.3f),
  225. static_cast<int_>(25.4f)
  226. )
  227. );
  228. }
  229. BOOST_AUTO_TEST_CASE(copy_async_to_device_float_to_int_empty)
  230. {
  231. using compute::int_;
  232. using compute::float_;
  233. float_ host[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  234. bc::vector<int_> device_vector(size_t(4), int_(1), queue);
  235. // copy nothing to int device vector
  236. compute::future<bc::vector<int_>::iterator > future =
  237. bc::copy_async(host, host, device_vector.begin(), queue);
  238. if(future.valid()) {
  239. future.wait();
  240. }
  241. CHECK_RANGE_EQUAL(
  242. int_,
  243. 4,
  244. device_vector,
  245. (
  246. int_(1),
  247. int_(1),
  248. int_(1),
  249. int_(1)
  250. )
  251. );
  252. }
  253. // Test copying from a std::list to a bc::vector. This differs from
  254. // the test copying from std::vector because std::list has non-contiguous
  255. // storage for its data values.
  256. BOOST_AUTO_TEST_CASE(copy_to_device_float_to_int_list_device_map)
  257. {
  258. using compute::int_;
  259. using compute::uint_;
  260. using compute::float_;
  261. std::string cache_key =
  262. std::string("__boost_compute_copy_to_device_float_int");
  263. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  264. bc::detail::parameter_cache::get_global_cache(device);
  265. // save
  266. uint_ map_copy_threshold =
  267. parameters->get(cache_key, "map_copy_threshold", 0);
  268. // force copy_to_device_map (mapping device vector to the host)
  269. parameters->set(cache_key, "map_copy_threshold", 1024);
  270. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  271. std::list<float_> host(data, data + 4);
  272. bc::vector<int_> device_vector(4, context);
  273. // copy host float data to int device vector
  274. bc::copy(host.begin(), host.end(), device_vector.begin(), queue);
  275. CHECK_RANGE_EQUAL(
  276. int_,
  277. 4,
  278. device_vector,
  279. (
  280. static_cast<int_>(6.1f),
  281. static_cast<int_>(-10.2f),
  282. static_cast<int_>(19.3f),
  283. static_cast<int_>(25.4f)
  284. )
  285. );
  286. // restore
  287. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  288. }
  289. // Test copying from a std::list to a bc::vector. This differs from
  290. // the test copying from std::vector because std::list has non-contiguous
  291. // storage for its data values.
  292. BOOST_AUTO_TEST_CASE(copy_to_device_float_to_int_list_convert_on_host)
  293. {
  294. using compute::int_;
  295. using compute::uint_;
  296. using compute::float_;
  297. std::string cache_key =
  298. std::string("__boost_compute_copy_to_device_float_int");
  299. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  300. bc::detail::parameter_cache::get_global_cache(device);
  301. // save
  302. uint_ map_copy_threshold =
  303. parameters->get(cache_key, "map_copy_threshold", 0);
  304. uint_ direct_copy_threshold =
  305. parameters->get(cache_key, "direct_copy_threshold", 0);
  306. // force copying by casting input data on host and performing
  307. // normal copy host->device (since types match now)
  308. parameters->set(cache_key, "map_copy_threshold", 0);
  309. parameters->set(cache_key, "direct_copy_threshold", 1024);
  310. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  311. std::list<float_> host(data, data + 4);
  312. bc::vector<int_> device_vector(4, context);
  313. // copy host float data to int device vector
  314. bc::copy(host.begin(), host.end(), device_vector.begin(), queue);
  315. CHECK_RANGE_EQUAL(
  316. int_,
  317. 4,
  318. device_vector,
  319. (
  320. static_cast<int_>(6.1f),
  321. static_cast<int_>(-10.2f),
  322. static_cast<int_>(19.3f),
  323. static_cast<int_>(25.4f)
  324. )
  325. );
  326. // restore
  327. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  328. parameters->set(cache_key, "direct_copy_threshold", direct_copy_threshold);
  329. }
  330. // SVM requires OpenCL 2.0
  331. #if defined(BOOST_COMPUTE_CL_VERSION_2_0) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
  332. BOOST_AUTO_TEST_CASE(copy_to_device_svm_float_to_int_map)
  333. {
  334. REQUIRES_OPENCL_VERSION(2, 0);
  335. using compute::int_;
  336. using compute::uint_;
  337. using compute::float_;
  338. std::string cache_key =
  339. std::string("__boost_compute_copy_to_device_float_int");
  340. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  341. bc::detail::parameter_cache::get_global_cache(device);
  342. // save
  343. uint_ map_copy_threshold =
  344. parameters->get(cache_key, "map_copy_threshold", 0);
  345. // force copy_to_device_map (mapping device vector to the host)
  346. parameters->set(cache_key, "map_copy_threshold", 1024);
  347. float_ host[] = { 5.1f, -10.3f, 19.4f, 26.7f };
  348. compute::svm_ptr<int_> ptr = compute::svm_alloc<int_>(context, 4);
  349. // copy host float data to int device vector
  350. bc::copy(host, host + 4, ptr, queue);
  351. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_READ);
  352. CHECK_HOST_RANGE_EQUAL(
  353. int_,
  354. 4,
  355. static_cast<int_*>(ptr.get()),
  356. (
  357. static_cast<int_>(5.1f),
  358. static_cast<int_>(-10.3f),
  359. static_cast<int_>(19.4f),
  360. static_cast<int_>(26.7f)
  361. )
  362. );
  363. queue.enqueue_svm_unmap(ptr.get()).wait();
  364. compute::svm_free(context, ptr);
  365. // restore
  366. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  367. }
  368. BOOST_AUTO_TEST_CASE(copy_to_device_svm_float_to_int_convert_on_host)
  369. {
  370. REQUIRES_OPENCL_VERSION(2, 0);
  371. if(bug_in_svmmemcpy(device)){
  372. std::cerr << "skipping svmmemcpy test case" << std::endl;
  373. return;
  374. }
  375. using compute::int_;
  376. using compute::uint_;
  377. using compute::float_;
  378. std::string cache_key =
  379. std::string("__boost_compute_copy_to_device_float_int");
  380. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  381. bc::detail::parameter_cache::get_global_cache(device);
  382. // save
  383. uint_ map_copy_threshold =
  384. parameters->get(cache_key, "map_copy_threshold", 0);
  385. uint_ direct_copy_threshold =
  386. parameters->get(cache_key, "direct_copy_threshold", 0);
  387. // force copying by casting input data on host and performing
  388. // normal copy host->device (since types match now)
  389. parameters->set(cache_key, "map_copy_threshold", 0);
  390. parameters->set(cache_key, "direct_copy_threshold", 1024);
  391. float_ host[] = { 0.1f, 10.3f, 9.4f, -26.7f };
  392. compute::svm_ptr<int_> ptr = compute::svm_alloc<int_>(context, 4);
  393. // copy host float data to int device vector
  394. bc::copy(host, host + 4, ptr, queue);
  395. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_READ);
  396. CHECK_HOST_RANGE_EQUAL(
  397. int_,
  398. 4,
  399. static_cast<int_*>(ptr.get()),
  400. (
  401. static_cast<int_>(0.1f),
  402. static_cast<int_>(10.3f),
  403. static_cast<int_>(9.4f),
  404. static_cast<int_>(-26.7f)
  405. )
  406. );
  407. queue.enqueue_svm_unmap(ptr.get()).wait();
  408. compute::svm_free(context, ptr);
  409. // restore
  410. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  411. parameters->set(cache_key, "direct_copy_threshold", direct_copy_threshold);
  412. }
  413. BOOST_AUTO_TEST_CASE(copy_to_device_svm_float_to_int_with_transform)
  414. {
  415. REQUIRES_OPENCL_VERSION(2, 0);
  416. using compute::int_;
  417. using compute::uint_;
  418. using compute::float_;
  419. std::string cache_key =
  420. std::string("__boost_compute_copy_to_device_float_int");
  421. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  422. bc::detail::parameter_cache::get_global_cache(device);
  423. // save
  424. uint_ map_copy_threshold =
  425. parameters->get(cache_key, "map_copy_threshold", 0);
  426. uint_ direct_copy_threshold =
  427. parameters->get(cache_key, "direct_copy_threshold", 0);
  428. // force copying by mapping input data to the device memory
  429. // and using transform operation (copy kernel) for casting & copying
  430. parameters->set(cache_key, "map_copy_threshold", 0);
  431. parameters->set(cache_key, "direct_copy_threshold", 0);
  432. float_ host[] = { 4.1f, -11.3f, 219.4f, -26.7f };
  433. compute::svm_ptr<int_> ptr = compute::svm_alloc<int_>(context, 4);
  434. // copy host float data to int device vector
  435. bc::copy(host, host + 4, ptr, queue);
  436. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_READ);
  437. CHECK_HOST_RANGE_EQUAL(
  438. int_,
  439. 4,
  440. static_cast<int_*>(ptr.get()),
  441. (
  442. static_cast<int_>(4.1f),
  443. static_cast<int_>(-11.3f),
  444. static_cast<int_>(219.4f),
  445. static_cast<int_>(-26.7f)
  446. )
  447. );
  448. queue.enqueue_svm_unmap(ptr.get()).wait();
  449. compute::svm_free(context, ptr);
  450. // restore
  451. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  452. parameters->set(cache_key, "direct_copy_threshold", direct_copy_threshold);
  453. }
  454. BOOST_AUTO_TEST_CASE(copy_async_to_device_svm_float_to_int)
  455. {
  456. REQUIRES_OPENCL_VERSION(2, 0);
  457. using compute::int_;
  458. using compute::uint_;
  459. using compute::float_;
  460. float_ host[] = { 44.1f, -14.3f, 319.4f, -26.7f };
  461. compute::svm_ptr<int_> ptr = compute::svm_alloc<int_>(context, 4);
  462. // copy host float data to int device vector
  463. compute::future<void> future =
  464. bc::copy_async(host, host + 4, ptr, queue);
  465. future.wait();
  466. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_READ);
  467. CHECK_HOST_RANGE_EQUAL(
  468. int_,
  469. 4,
  470. static_cast<int_*>(ptr.get()),
  471. (
  472. static_cast<int_>(44.1f),
  473. static_cast<int_>(-14.3f),
  474. static_cast<int_>(319.4f),
  475. static_cast<int_>(-26.7f)
  476. )
  477. );
  478. queue.enqueue_svm_unmap(ptr.get()).wait();
  479. compute::svm_free(context, ptr);
  480. }
  481. #endif
  482. // DEVICE -> DEVICE
  483. BOOST_AUTO_TEST_CASE(copy_on_device_float_to_int)
  484. {
  485. using compute::int_;
  486. using compute::float_;
  487. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  488. bc::vector<float_> device_fvector(data, data + 4, queue);
  489. bc::vector<int_> device_ivector(4, context);
  490. // copy device float vector to device int vector
  491. bc::copy(
  492. device_fvector.begin(),
  493. device_fvector.end(),
  494. device_ivector.begin(),
  495. queue
  496. );
  497. CHECK_RANGE_EQUAL(
  498. int_,
  499. 4,
  500. device_ivector,
  501. (
  502. static_cast<int_>(6.1f),
  503. static_cast<int_>(-10.2f),
  504. static_cast<int_>(19.3f),
  505. static_cast<int_>(25.4f)
  506. )
  507. );
  508. }
  509. BOOST_AUTO_TEST_CASE(copy_async_on_device_float_to_int)
  510. {
  511. using compute::int_;
  512. using compute::float_;
  513. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  514. bc::vector<float_> device_fvector(data, data + 4, queue);
  515. bc::vector<int_> device_ivector(4, context);
  516. // copy device float vector to device int vector
  517. compute::future<void> future =
  518. bc::copy_async(
  519. device_fvector.begin(),
  520. device_fvector.end(),
  521. device_ivector.begin(),
  522. queue
  523. );
  524. future.wait();
  525. CHECK_RANGE_EQUAL(
  526. int_,
  527. 4,
  528. device_ivector,
  529. (
  530. static_cast<int_>(6.1f),
  531. static_cast<int_>(-10.2f),
  532. static_cast<int_>(19.3f),
  533. static_cast<int_>(25.4f)
  534. )
  535. );
  536. }
  537. BOOST_AUTO_TEST_CASE(copy_async_on_device_float_to_int_empty)
  538. {
  539. using compute::int_;
  540. using compute::float_;
  541. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  542. bc::vector<float_> device_fvector(data, data + 4, queue);
  543. bc::vector<int_> device_ivector(size_t(4), int_(1), queue);
  544. // copy device float vector to device int vector
  545. compute::future<void> future =
  546. bc::copy_async(
  547. device_fvector.begin(),
  548. device_fvector.begin(),
  549. device_ivector.begin(),
  550. queue
  551. );
  552. if(future.valid()) {
  553. future.wait();
  554. }
  555. CHECK_RANGE_EQUAL(
  556. int_,
  557. 4,
  558. device_ivector,
  559. (
  560. int_(1),
  561. int_(1),
  562. int_(1),
  563. int_(1)
  564. )
  565. );
  566. }
  567. // SVM requires OpenCL 2.0
  568. #if defined(BOOST_COMPUTE_CL_VERSION_2_0) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
  569. BOOST_AUTO_TEST_CASE(copy_on_device_buffer_to_svm_float_to_int)
  570. {
  571. REQUIRES_OPENCL_VERSION(2, 0);
  572. using compute::int_;
  573. using compute::float_;
  574. float_ data[] = { 65.1f, -110.2f, -19.3f, 26.7f };
  575. bc::vector<float_> device_vector(data, data + 4, queue);
  576. compute::svm_ptr<int_> ptr = compute::svm_alloc<int_>(context, 4);
  577. // copy host float data to int svm memory
  578. bc::copy(device_vector.begin(), device_vector.end(), ptr, queue);
  579. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_READ);
  580. CHECK_HOST_RANGE_EQUAL(
  581. int_,
  582. 4,
  583. static_cast<int_*>(ptr.get()),
  584. (
  585. static_cast<int_>(65.1f),
  586. static_cast<int_>(-110.2f),
  587. static_cast<int_>(-19.3f),
  588. static_cast<int_>(26.7f)
  589. )
  590. );
  591. queue.enqueue_svm_unmap(ptr.get()).wait();
  592. compute::svm_free(context, ptr);
  593. }
  594. BOOST_AUTO_TEST_CASE(copy_on_device_svm_to_buffer_float_to_int)
  595. {
  596. REQUIRES_OPENCL_VERSION(2, 0);
  597. using compute::int_;
  598. using compute::float_;
  599. float_ data[] = { 6.1f, 11.2f, 19.3f, 6.7f };
  600. bc::vector<int_> device_vector(4, context);
  601. compute::svm_ptr<float_> ptr = compute::svm_alloc<float_>(context, 4);
  602. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_WRITE);
  603. for(size_t i = 0; i < 4; i++) {
  604. static_cast<float_*>(ptr.get())[i] = data[i];
  605. }
  606. queue.enqueue_svm_unmap(ptr.get()).wait();
  607. // copy host float svm data to int device vector
  608. bc::copy(ptr, ptr + 4, device_vector.begin(), queue);
  609. CHECK_RANGE_EQUAL(
  610. int_,
  611. 4,
  612. device_vector,
  613. (
  614. static_cast<int_>(6.1f),
  615. static_cast<int_>(11.2f),
  616. static_cast<int_>(19.3f),
  617. static_cast<int_>(6.7f)
  618. )
  619. );
  620. compute::svm_free(context, ptr);
  621. }
  622. BOOST_AUTO_TEST_CASE(copy_on_device_svm_to_svm_float_to_int)
  623. {
  624. REQUIRES_OPENCL_VERSION(2, 0);
  625. using compute::int_;
  626. using compute::float_;
  627. float_ data[] = { 0.1f, -10.2f, -1.3f, 2.7f };
  628. compute::svm_ptr<float_> ptr = compute::svm_alloc<float_>(context, 4);
  629. compute::svm_ptr<int_> ptr2 = compute::svm_alloc<int_>(context, 4);
  630. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_WRITE);
  631. for(size_t i = 0; i < 4; i++) {
  632. static_cast<float_*>(ptr.get())[i] = data[i];
  633. }
  634. queue.enqueue_svm_unmap(ptr.get()).wait();
  635. // copy host float svm to int svm
  636. bc::copy(ptr, ptr + 4, ptr2, queue);
  637. queue.enqueue_svm_map(ptr2.get(), 4 * sizeof(cl_int), CL_MAP_READ);
  638. CHECK_HOST_RANGE_EQUAL(
  639. int_,
  640. 4,
  641. static_cast<int_*>(ptr2.get()),
  642. (
  643. static_cast<int_>(0.1f),
  644. static_cast<int_>(-10.2f),
  645. static_cast<int_>(-1.3f),
  646. static_cast<int_>(2.7f)
  647. )
  648. );
  649. queue.enqueue_svm_unmap(ptr2.get()).wait();
  650. compute::svm_free(context, ptr);
  651. compute::svm_free(context, ptr2);
  652. }
  653. BOOST_AUTO_TEST_CASE(copy_async_on_device_buffer_to_svm_float_to_int)
  654. {
  655. REQUIRES_OPENCL_VERSION(2, 0);
  656. using compute::int_;
  657. using compute::float_;
  658. float_ data[] = { 65.1f, -110.2f, -19.3f, 26.7f };
  659. bc::vector<float_> device_vector(data, data + 4, queue);
  660. compute::svm_ptr<int_> ptr = compute::svm_alloc<int_>(context, 4);
  661. // copy host float data to int svm memory
  662. compute::future<bc::svm_ptr<int_> > future =
  663. bc::copy_async(device_vector.begin(), device_vector.end(), ptr, queue);
  664. future.wait();
  665. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_READ);
  666. CHECK_HOST_RANGE_EQUAL(
  667. int_,
  668. 4,
  669. static_cast<int_*>(ptr.get()),
  670. (
  671. static_cast<int_>(65.1f),
  672. static_cast<int_>(-110.2f),
  673. static_cast<int_>(-19.3f),
  674. static_cast<int_>(26.7f)
  675. )
  676. );
  677. queue.enqueue_svm_unmap(ptr.get()).wait();
  678. compute::svm_free(context, ptr);
  679. }
  680. BOOST_AUTO_TEST_CASE(copy_async_on_device_svm_to_buffer_float_to_int)
  681. {
  682. REQUIRES_OPENCL_VERSION(2, 0);
  683. using compute::int_;
  684. using compute::float_;
  685. float_ data[] = { 65.1f, -110.2f, -19.3f, 26.7f };
  686. bc::vector<int_> device_vector(4, context);
  687. compute::svm_ptr<float_> ptr = compute::svm_alloc<float_>(context, 4);
  688. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_WRITE);
  689. for(size_t i = 0; i < 4; i++) {
  690. static_cast<float_*>(ptr.get())[i] = data[i];
  691. }
  692. queue.enqueue_svm_unmap(ptr.get()).wait();
  693. // copy host float svm data to int device vector
  694. compute::future<bc::vector<int_>::iterator > future =
  695. bc::copy_async(ptr, ptr + 4, device_vector.begin(), queue);
  696. future.wait();
  697. CHECK_RANGE_EQUAL(
  698. int_,
  699. 4,
  700. device_vector,
  701. (
  702. static_cast<int_>(65.1f),
  703. static_cast<int_>(-110.2f),
  704. static_cast<int_>(-19.3f),
  705. static_cast<int_>(26.7f)
  706. )
  707. );
  708. compute::svm_free(context, ptr);
  709. }
  710. BOOST_AUTO_TEST_CASE(copy_async_on_device_svm_to_svm_float_to_int)
  711. {
  712. REQUIRES_OPENCL_VERSION(2, 0);
  713. using compute::int_;
  714. using compute::float_;
  715. float_ data[] = { 0.1f, -10.2f, -1.3f, 2.7f };
  716. compute::svm_ptr<float_> ptr = compute::svm_alloc<float_>(context, 4);
  717. compute::svm_ptr<int_> ptr2 = compute::svm_alloc<int_>(context, 4);
  718. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_WRITE);
  719. for(size_t i = 0; i < 4; i++) {
  720. static_cast<float_*>(ptr.get())[i] = data[i];
  721. }
  722. queue.enqueue_svm_unmap(ptr.get()).wait();
  723. // copy host float svm to int svm
  724. compute::future<bc::svm_ptr<int_> > future =
  725. bc::copy_async(ptr, ptr + 4, ptr2, queue);
  726. future.wait();
  727. queue.enqueue_svm_map(ptr2.get(), 4 * sizeof(cl_int), CL_MAP_READ);
  728. CHECK_HOST_RANGE_EQUAL(
  729. int_,
  730. 4,
  731. static_cast<int_*>(ptr2.get()),
  732. (
  733. static_cast<int_>(0.1f),
  734. static_cast<int_>(-10.2f),
  735. static_cast<int_>(-1.3f),
  736. static_cast<int_>(2.7f)
  737. )
  738. );
  739. queue.enqueue_svm_unmap(ptr2.get()).wait();
  740. compute::svm_free(context, ptr);
  741. compute::svm_free(context, ptr2);
  742. }
  743. #endif
  744. // DEVICE -> HOST
  745. BOOST_AUTO_TEST_CASE(copy_to_host_float_to_int)
  746. {
  747. using compute::int_;
  748. using compute::float_;
  749. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  750. bc::vector<float_> device_vector(data, data + 4, queue);
  751. std::vector<int_> host_vector(4);
  752. // copy device float vector to int host vector
  753. bc::copy(device_vector.begin(), device_vector.end(), host_vector.begin(), queue);
  754. CHECK_HOST_RANGE_EQUAL(
  755. int_,
  756. 4,
  757. host_vector.begin(),
  758. (
  759. static_cast<int_>(6.1f),
  760. static_cast<int_>(-10.2f),
  761. static_cast<int_>(19.3f),
  762. static_cast<int_>(25.4f)
  763. )
  764. );
  765. }
  766. BOOST_AUTO_TEST_CASE(copy_to_host_float_to_int_map)
  767. {
  768. using compute::int_;
  769. using compute::uint_;
  770. using compute::float_;
  771. std::string cache_key =
  772. std::string("__boost_compute_copy_to_host_float_int");
  773. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  774. bc::detail::parameter_cache::get_global_cache(device);
  775. // save
  776. uint_ map_copy_threshold =
  777. parameters->get(cache_key, "map_copy_threshold", 0);
  778. // force copy_to_host_map (mapping device vector to the host)
  779. parameters->set(cache_key, "map_copy_threshold", 1024);
  780. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  781. bc::vector<float_> device_vector(data, data + 4, queue);
  782. std::vector<int_> host_vector(4);
  783. // copy device float vector to int host vector
  784. bc::copy(device_vector.begin(), device_vector.end(), host_vector.begin(), queue);
  785. CHECK_HOST_RANGE_EQUAL(
  786. int_,
  787. 4,
  788. host_vector.begin(),
  789. (
  790. static_cast<int_>(6.1f),
  791. static_cast<int_>(-10.2f),
  792. static_cast<int_>(19.3f),
  793. static_cast<int_>(25.4f)
  794. )
  795. );
  796. // restore
  797. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  798. }
  799. BOOST_AUTO_TEST_CASE(copy_to_host_float_to_int_convert_on_host)
  800. {
  801. using compute::int_;
  802. using compute::uint_;
  803. using compute::float_;
  804. std::string cache_key =
  805. std::string("__boost_compute_copy_to_host_float_int");
  806. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  807. bc::detail::parameter_cache::get_global_cache(device);
  808. // save
  809. uint_ map_copy_threshold =
  810. parameters->get(cache_key, "map_copy_threshold", 0);
  811. uint_ direct_copy_threshold =
  812. parameters->get(cache_key, "direct_copy_threshold", 0);
  813. // force copying by copying input device vector to temporary
  814. // host vector of the same type and then copying from that temporary
  815. // vector to result using std::copy()
  816. parameters->set(cache_key, "map_copy_threshold", 0);
  817. parameters->set(cache_key, "direct_copy_threshold", 1024);
  818. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  819. bc::vector<float_> device_vector(data, data + 4, queue);
  820. std::vector<int_> host_vector(4);
  821. // copy device float vector to int host vector
  822. bc::copy(device_vector.begin(), device_vector.end(), host_vector.begin(), queue);
  823. CHECK_HOST_RANGE_EQUAL(
  824. int_,
  825. 4,
  826. host_vector.begin(),
  827. (
  828. static_cast<int_>(6.1f),
  829. static_cast<int_>(-10.2f),
  830. static_cast<int_>(19.3f),
  831. static_cast<int_>(25.4f)
  832. )
  833. );
  834. // restore
  835. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  836. parameters->set(cache_key, "direct_copy_threshold", direct_copy_threshold);
  837. }
  838. BOOST_AUTO_TEST_CASE(copy_to_host_float_to_int_convert_on_device)
  839. {
  840. using compute::int_;
  841. using compute::uint_;
  842. using compute::float_;
  843. std::string cache_key =
  844. std::string("__boost_compute_copy_to_host_float_int");
  845. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  846. bc::detail::parameter_cache::get_global_cache(device);
  847. // save
  848. uint_ map_copy_threshold =
  849. parameters->get(cache_key, "map_copy_threshold", 0);
  850. uint_ direct_copy_threshold =
  851. parameters->get(cache_key, "direct_copy_threshold", 0);
  852. // force copying by mapping output data to the device memory
  853. // and using transform operation for casting & copying
  854. parameters->set(cache_key, "map_copy_threshold", 0);
  855. parameters->set(cache_key, "direct_copy_threshold", 0);
  856. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  857. bc::vector<float_> device_vector(data, data + 4, queue);
  858. std::vector<int_> host_vector(4);
  859. // copy device float vector to int host vector
  860. bc::copy(device_vector.begin(), device_vector.end(), host_vector.begin(), queue);
  861. CHECK_HOST_RANGE_EQUAL(
  862. int_,
  863. 4,
  864. host_vector.begin(),
  865. (
  866. static_cast<int_>(6.1f),
  867. static_cast<int_>(-10.2f),
  868. static_cast<int_>(19.3f),
  869. static_cast<int_>(25.4f)
  870. )
  871. );
  872. // restore
  873. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  874. parameters->set(cache_key, "direct_copy_threshold", direct_copy_threshold);
  875. }
  876. // Test copying from a bc::vector to a std::list . This differs from
  877. // the test copying to std::vector because std::list has non-contiguous
  878. // storage for its data values.
  879. BOOST_AUTO_TEST_CASE(copy_to_host_list_float_to_int_map)
  880. {
  881. using compute::int_;
  882. using compute::uint_;
  883. using compute::float_;
  884. std::string cache_key =
  885. std::string("__boost_compute_copy_to_host_float_int");
  886. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  887. bc::detail::parameter_cache::get_global_cache(device);
  888. // save
  889. uint_ map_copy_threshold =
  890. parameters->get(cache_key, "map_copy_threshold", 0);
  891. // force copy_to_host_map (mapping device vector to the host)
  892. parameters->set(cache_key, "map_copy_threshold", 1024);
  893. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  894. bc::vector<float_> device_vector(data, data + 4, queue);
  895. std::list<int_> host_list(4);
  896. // copy device float vector to int host vector
  897. bc::copy(device_vector.begin(), device_vector.end(), host_list.begin(), queue);
  898. int_ expected[4] = {
  899. static_cast<int_>(6.1f),
  900. static_cast<int_>(-10.2f),
  901. static_cast<int_>(19.3f),
  902. static_cast<int_>(25.4f)
  903. };
  904. BOOST_CHECK_EQUAL_COLLECTIONS(
  905. host_list.begin(), host_list.end(),
  906. expected, expected + 4
  907. );
  908. // restore
  909. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  910. }
  911. // Test copying from a bc::vector to a std::list . This differs from
  912. // the test copying to std::vector because std::list has non-contiguous
  913. // storage for its data values.
  914. BOOST_AUTO_TEST_CASE(copy_to_host_list_float_to_int_covert_on_host)
  915. {
  916. using compute::int_;
  917. using compute::uint_;
  918. using compute::float_;
  919. std::string cache_key =
  920. std::string("__boost_compute_copy_to_host_float_int");
  921. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  922. bc::detail::parameter_cache::get_global_cache(device);
  923. // save
  924. uint_ map_copy_threshold =
  925. parameters->get(cache_key, "map_copy_threshold", 0);
  926. uint_ direct_copy_threshold =
  927. parameters->get(cache_key, "direct_copy_threshold", 0);
  928. // force copying by copying input device vector to temporary
  929. // host vector of the same type and then copying from that temporary
  930. // vector to result using std::copy()
  931. parameters->set(cache_key, "map_copy_threshold", 0);
  932. parameters->set(cache_key, "direct_copy_threshold", 1024);
  933. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  934. bc::vector<float_> device_vector(data, data + 4, queue);
  935. std::list<int_> host_list(4);
  936. // copy device float vector to int host vector
  937. bc::copy(device_vector.begin(), device_vector.end(), host_list.begin(), queue);
  938. int_ expected[4] = {
  939. static_cast<int_>(6.1f),
  940. static_cast<int_>(-10.2f),
  941. static_cast<int_>(19.3f),
  942. static_cast<int_>(25.4f)
  943. };
  944. BOOST_CHECK_EQUAL_COLLECTIONS(
  945. host_list.begin(), host_list.end(),
  946. expected, expected + 4
  947. );
  948. // restore
  949. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  950. parameters->set(cache_key, "direct_copy_threshold", direct_copy_threshold);
  951. }
  952. BOOST_AUTO_TEST_CASE(copy_async_to_host_float_to_int)
  953. {
  954. using compute::int_;
  955. using compute::float_;
  956. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  957. bc::vector<float_> device_vector(data, data + 4, queue);
  958. std::vector<int_> host_vector(device_vector.size());
  959. // copy device float vector to host int vector
  960. compute::future<void> future =
  961. bc::copy_async(
  962. device_vector.begin(),
  963. device_vector.end(),
  964. host_vector.begin(),
  965. queue
  966. );
  967. future.wait();
  968. CHECK_HOST_RANGE_EQUAL(
  969. int_,
  970. 4,
  971. host_vector.begin(),
  972. (
  973. static_cast<int_>(6.1f),
  974. static_cast<int_>(-10.2f),
  975. static_cast<int_>(19.3f),
  976. static_cast<int_>(25.4f)
  977. )
  978. );
  979. }
  980. BOOST_AUTO_TEST_CASE(copy_async_to_host_float_to_int_empty)
  981. {
  982. using compute::int_;
  983. using compute::float_;
  984. float_ data[] = { 6.1f, -10.2f, 19.3f, 25.4f };
  985. bc::vector<float_> device_vector(data, data + 4, queue);
  986. std::vector<int_> host_vector(device_vector.size(), int_(1));
  987. // copy device float vector to host int vector
  988. compute::future<void> future =
  989. bc::copy_async(
  990. device_vector.begin(),
  991. device_vector.begin(),
  992. host_vector.begin(),
  993. queue
  994. );
  995. if(future.valid()) {
  996. future.wait();
  997. }
  998. CHECK_HOST_RANGE_EQUAL(
  999. int_,
  1000. 4,
  1001. host_vector.begin(),
  1002. (
  1003. int_(1),
  1004. int_(1),
  1005. int_(1),
  1006. int_(1)
  1007. )
  1008. );
  1009. }
  1010. // SVM requires OpenCL 2.0
  1011. #if defined(BOOST_COMPUTE_CL_VERSION_2_0) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
  1012. BOOST_AUTO_TEST_CASE(copy_to_host_svm_float_to_int_map)
  1013. {
  1014. REQUIRES_OPENCL_VERSION(2, 0);
  1015. using compute::int_;
  1016. using compute::uint_;
  1017. using compute::float_;
  1018. std::string cache_key =
  1019. std::string("__boost_compute_copy_to_host_float_int");
  1020. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  1021. bc::detail::parameter_cache::get_global_cache(device);
  1022. // save
  1023. uint_ map_copy_threshold =
  1024. parameters->get(cache_key, "map_copy_threshold", 0);
  1025. // force copy_to_host_map (mapping device vector to the host)
  1026. parameters->set(cache_key, "map_copy_threshold", 1024);
  1027. float_ data[] = { 6.1f, 1.2f, 1.3f, -66.7f };
  1028. std::vector<int_> host_vector(4, 0);
  1029. compute::svm_ptr<float_> ptr = compute::svm_alloc<float_>(context, 4);
  1030. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_WRITE);
  1031. for(size_t i = 0; i < 4; i++) {
  1032. static_cast<float_*>(ptr.get())[i] = data[i];
  1033. }
  1034. queue.enqueue_svm_unmap(ptr.get()).wait();
  1035. // copy host float svm data to int host vector
  1036. bc::copy(ptr, ptr + 4, host_vector.begin(), queue);
  1037. CHECK_HOST_RANGE_EQUAL(
  1038. int_,
  1039. 4,
  1040. host_vector.begin(),
  1041. (
  1042. static_cast<int_>(6.1f),
  1043. static_cast<int_>(1.2f),
  1044. static_cast<int_>(1.3f),
  1045. static_cast<int_>(-66.7f)
  1046. )
  1047. );
  1048. compute::svm_free(context, ptr);
  1049. // restore
  1050. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  1051. }
  1052. BOOST_AUTO_TEST_CASE(copy_to_host_svm_float_to_int_convert_on_host)
  1053. {
  1054. REQUIRES_OPENCL_VERSION(2, 0);
  1055. if(bug_in_svmmemcpy(device)){
  1056. std::cerr << "skipping svmmemcpy test case" << std::endl;
  1057. return;
  1058. }
  1059. using compute::int_;
  1060. using compute::uint_;
  1061. using compute::float_;
  1062. std::string cache_key =
  1063. std::string("__boost_compute_copy_to_host_float_int");
  1064. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  1065. bc::detail::parameter_cache::get_global_cache(device);
  1066. // save
  1067. uint_ map_copy_threshold =
  1068. parameters->get(cache_key, "map_copy_threshold", 0);
  1069. uint_ direct_copy_threshold =
  1070. parameters->get(cache_key, "direct_copy_threshold", 0);
  1071. // force copying by copying input device vector to temporary
  1072. // host vector of the same type and then copying from that temporary
  1073. // vector to result using std::copy()
  1074. parameters->set(cache_key, "map_copy_threshold", 0);
  1075. parameters->set(cache_key, "direct_copy_threshold", 1024);
  1076. float_ data[] = { 6.1f, 1.2f, 1.3f, 766.7f };
  1077. std::vector<int_> host_vector(4, 0);
  1078. compute::svm_ptr<float_> ptr = compute::svm_alloc<float_>(context, 4);
  1079. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_WRITE);
  1080. for(size_t i = 0; i < 4; i++) {
  1081. static_cast<float_*>(ptr.get())[i] = data[i];
  1082. }
  1083. queue.enqueue_svm_unmap(ptr.get()).wait();
  1084. // copy host float svm data to int host vector
  1085. bc::copy(ptr, ptr + 4, host_vector.begin(), queue);
  1086. CHECK_HOST_RANGE_EQUAL(
  1087. int_,
  1088. 4,
  1089. host_vector.begin(),
  1090. (
  1091. static_cast<int_>(6.1f),
  1092. static_cast<int_>(1.2f),
  1093. static_cast<int_>(1.3f),
  1094. static_cast<int_>(766.7f)
  1095. )
  1096. );
  1097. compute::svm_free(context, ptr);
  1098. // restore
  1099. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  1100. parameters->set(cache_key, "direct_copy_threshold", direct_copy_threshold);
  1101. }
  1102. BOOST_AUTO_TEST_CASE(copy_to_host_svm_float_to_int_transform)
  1103. {
  1104. REQUIRES_OPENCL_VERSION(2, 0);
  1105. using compute::int_;
  1106. using compute::uint_;
  1107. using compute::float_;
  1108. std::string cache_key =
  1109. std::string("__boost_compute_copy_to_host_float_int");
  1110. boost::shared_ptr<bc::detail::parameter_cache> parameters =
  1111. bc::detail::parameter_cache::get_global_cache(device);
  1112. // save
  1113. uint_ map_copy_threshold =
  1114. parameters->get(cache_key, "map_copy_threshold", 0);
  1115. uint_ direct_copy_threshold =
  1116. parameters->get(cache_key, "direct_copy_threshold", 0);
  1117. // force copying by copying input device vector to temporary
  1118. // host vector of the same type and then copying from that temporary
  1119. // vector to result using std::copy()
  1120. parameters->set(cache_key, "map_copy_threshold", 0);
  1121. parameters->set(cache_key, "direct_copy_threshold", 0);
  1122. float_ data[] = { 0.1f, 11.2f, 1.3f, -66.7f };
  1123. std::vector<int_> host_vector(4, 0);
  1124. compute::svm_ptr<float_> ptr = compute::svm_alloc<float_>(context, 4);
  1125. queue.enqueue_svm_map(ptr.get(), 4 * sizeof(cl_int), CL_MAP_WRITE);
  1126. for(size_t i = 0; i < 4; i++) {
  1127. static_cast<float_*>(ptr.get())[i] = data[i];
  1128. }
  1129. queue.enqueue_svm_unmap(ptr.get()).wait();
  1130. // copy host float svm data to int host vector
  1131. bc::copy(ptr, ptr + 4, host_vector.begin(), queue);
  1132. CHECK_HOST_RANGE_EQUAL(
  1133. int_,
  1134. 4,
  1135. host_vector.begin(),
  1136. (
  1137. static_cast<int_>(0.1f),
  1138. static_cast<int_>(11.2f),
  1139. static_cast<int_>(1.3f),
  1140. static_cast<int_>(-66.7f)
  1141. )
  1142. );
  1143. compute::svm_free(context, ptr);
  1144. // restore
  1145. parameters->set(cache_key, "map_copy_threshold", map_copy_threshold);
  1146. parameters->set(cache_key, "direct_copy_threshold", direct_copy_threshold);
  1147. }
  1148. #endif
  1149. BOOST_AUTO_TEST_SUITE_END()