multiformat_handle_conversion.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. #include <starpu.h>
  2. #define NX 4
  3. #define DEBUG 0
  4. #if DEBUG
  5. #define SYNCHRONOUS 1 /* Easier to debug with synchronous tasks */
  6. #define ENTER() do { fprintf(stderr, "Entering %s\n", __func__); } while (0)
  7. #else
  8. #define SYNCHRONOUS 0
  9. #define ENTER()
  10. #endif
  11. /* Counting the calls to the codelets */
  12. struct stats {
  13. unsigned int cpu;
  14. #ifdef STARPU_USE_CUDA
  15. unsigned int cuda;
  16. unsigned int cpu_to_cuda;
  17. unsigned int cuda_to_cpu;
  18. #endif
  19. #ifdef STARPU_USE_OPENCL
  20. unsigned int opencl;
  21. unsigned int cpu_to_opencl;
  22. unsigned int opencl_to_cpu;
  23. #endif
  24. };
  25. struct stats global_stats;
  26. /* "Fake" conversion codelets */
  27. #ifdef STARPU_USE_CUDA
  28. static void cpu_to_cuda_func(void *buffers[], void *args)
  29. {
  30. ENTER();
  31. global_stats.cpu_to_cuda++;
  32. }
  33. static void cuda_to_cpu_func(void *buffers[], void *args)
  34. {
  35. ENTER();
  36. global_stats.cuda_to_cpu++;
  37. }
  38. struct starpu_codelet cpu_to_cuda_cl = {
  39. .where = STARPU_CUDA,
  40. .cuda_func = cpu_to_cuda_func,
  41. .nbuffers = 1
  42. };
  43. struct starpu_codelet cuda_to_cpu_cl = {
  44. .where = STARPU_CPU,
  45. .cpu_func = cuda_to_cpu_func,
  46. .nbuffers = 1
  47. };
  48. #endif /* !STARPU_USE_CUDA */
  49. #ifdef STARPU_USE_OPENCL
  50. static void cpu_to_opencl_func(void *buffers[], void *args)
  51. {
  52. ENTER();
  53. global_stats.cpu_to_opencl++;
  54. }
  55. static void opencl_to_cpu_func(void *buffers[], void *args)
  56. {
  57. ENTER();
  58. global_stats.opencl_to_cpu++;
  59. }
  60. struct starpu_codelet cpu_to_opencl_cl = {
  61. .where = STARPU_OPENCL,
  62. .opencl_func = cpu_to_opencl_func,
  63. .nbuffers = 1
  64. };
  65. struct starpu_codelet opencl_to_cpu_cl = {
  66. .where = STARPU_CPU,
  67. .cpu_func = opencl_to_cpu_func,
  68. .nbuffers = 1
  69. };
  70. #endif /* !STARPU_USE_OPENCL */
  71. static struct starpu_multiformat_data_interface_ops ops = {
  72. #ifdef STARPU_USE_CUDA
  73. .cuda_elemsize = sizeof(int),
  74. .cpu_to_cuda_cl = &cpu_to_cuda_cl,
  75. .cuda_to_cpu_cl = &cuda_to_cpu_cl,
  76. #endif
  77. #ifdef STARPU_USE_OPENCL
  78. .opencl_elemsize = sizeof(int),
  79. .cpu_to_opencl_cl = &cpu_to_opencl_cl,
  80. .opencl_to_cpu_cl = &opencl_to_cpu_cl,
  81. #endif
  82. .cpu_elemsize = sizeof(int)
  83. };
  84. static void cpu_func(void *buffers[], void *args)
  85. {
  86. ENTER();
  87. global_stats.cpu++;
  88. }
  89. #ifdef STARPU_USE_CUDA
  90. static void cuda_func(void *buffers[], void *args)
  91. {
  92. ENTER();
  93. global_stats.cuda++;
  94. }
  95. #endif /* !STARPU_USE_CUDA */
  96. #ifdef STARPU_USE_OPENCL
  97. static void opencl_func(void *buffers[], void *args)
  98. {
  99. ENTER();
  100. global_stats.opencl++;
  101. }
  102. #endif /* !STARPU_USE_OPENCL */
  103. static void
  104. create_and_submit_tasks(int where, starpu_data_handle_t handles[])
  105. {
  106. fprintf(stderr, "***** Starting Task 1\n");
  107. static struct starpu_codelet cl = {
  108. #ifdef STARPU_USE_CUDA
  109. .cuda_func = cuda_func,
  110. #endif
  111. #if STARPU_USE_OPENCL
  112. .opencl_func = opencl_func,
  113. #endif
  114. .nbuffers = 1
  115. };
  116. cl.where = where;
  117. struct starpu_task *task = starpu_task_create();
  118. task->synchronous = SYNCHRONOUS;
  119. task->cl = &cl;
  120. task->buffers[0].handle = handles[0];
  121. task->buffers[0].mode = STARPU_RW;
  122. starpu_task_submit(task);
  123. fprintf(stderr, "***** Starting Task 2\n");
  124. static struct starpu_codelet cl2 = {
  125. .where = STARPU_CPU,
  126. .cpu_func = cpu_func,
  127. .nbuffers = 1
  128. };
  129. struct starpu_task *task2 = starpu_task_create();
  130. task2->synchronous = SYNCHRONOUS;
  131. task2->cl = &cl2;
  132. task2->buffers[0].handle = handles[1];
  133. task2->buffers[0].mode = STARPU_RW;
  134. starpu_task_submit(task2);
  135. fprintf(stderr, "***** Starting Task 3\n");
  136. static struct starpu_codelet cl3 = {
  137. .cpu_func = cpu_func,
  138. #ifdef STARPU_USE_CUDA
  139. .cuda_func = cuda_func,
  140. #endif
  141. #ifdef STARPU_USE_OPENCL
  142. .opencl_func = opencl_func,
  143. #endif
  144. .nbuffers = 2
  145. };
  146. cl3.where = where;
  147. struct starpu_task *task3 = starpu_task_create();
  148. task3->synchronous = SYNCHRONOUS;
  149. task3->cl = &cl3;
  150. task3->buffers[0].handle = handles[0];
  151. task3->buffers[0].mode = STARPU_RW;
  152. task3->buffers[1].handle = handles[1];
  153. task3->buffers[1].mode = STARPU_RW;
  154. starpu_task_submit(task3);
  155. starpu_task_wait_for_all();
  156. fprintf(stderr, "***** End of all tasks\n");
  157. return;
  158. }
  159. #if DEBUG
  160. static void
  161. print_stats(struct stats *s)
  162. {
  163. fprintf(stderr, "cpu : %d\n", s->cpu);
  164. #ifdef STARPU_USE_CUDA
  165. fprintf(stderr, "cuda : %d\n"
  166. "cpu->cuda : %d\n"
  167. "cuda->cpu : %d\n",
  168. s->cuda,
  169. s->cpu_to_cuda,
  170. s->cuda_to_cpu);
  171. #endif
  172. #ifdef STARPU_USE_OPENCL
  173. fprintf(stderr, "opencl : %d\n"
  174. "cpu->opencl : %d\n"
  175. "opencl->cpu : %d\n",
  176. s->opencl,
  177. s->cpu_to_opencl,
  178. s->opencl_to_cpu);
  179. #endif
  180. }
  181. #endif /* !DEBUG */
  182. /* XXX Just a little bit of copy/pasta here... */
  183. #ifdef STARPU_USE_CUDA
  184. static int
  185. test_cuda(void)
  186. {
  187. int i;
  188. int vector1[NX];
  189. int vector2[NX];
  190. starpu_data_handle_t handles[2];
  191. for (i = 0; i < NX; i++)
  192. {
  193. vector1[i] = i;
  194. vector2[i] = i;
  195. }
  196. starpu_multiformat_data_register(handles, 0, vector1, NX, &ops);
  197. starpu_multiformat_data_register(handles+1, 0, vector2, NX, &ops);
  198. memset(&global_stats, 0, sizeof(global_stats));
  199. create_and_submit_tasks(STARPU_CUDA, handles);
  200. starpu_data_unregister(handles[0]);
  201. starpu_data_unregister(handles[1]);
  202. #if DEBUG
  203. print_stats(&global_stats);
  204. #endif
  205. return !(global_stats.cpu == 1 &&
  206. global_stats.cpu_to_cuda == 2 &&
  207. global_stats.cuda_to_cpu == 2 &&
  208. global_stats.cuda == 2);
  209. }
  210. #endif /* !STARPU_USE_CUDA */
  211. #ifdef STARPU_USE_OPENCL
  212. static int
  213. test_opencl(void)
  214. {
  215. int i;
  216. int vector1[NX];
  217. int vector2[NX];
  218. starpu_data_handle_t handles[2];
  219. for (i = 0; i < NX; i++)
  220. {
  221. vector1[i] = i;
  222. vector2[i] = i;
  223. }
  224. starpu_multiformat_data_register(handles, 0, vector1, NX, &ops);
  225. starpu_multiformat_data_register(handles+1, 0, vector2, NX, &ops);
  226. memset(&global_stats, 0, sizeof(global_stats));
  227. create_and_submit_tasks(STARPU_OPENCL, handles);
  228. starpu_data_unregister(handles[0]);
  229. starpu_data_unregister(handles[1]);
  230. #if DEBUG
  231. print_stats(&global_stats);
  232. #endif
  233. return !(global_stats.cpu == 1 &&
  234. global_stats.cpu_to_opencl == 2 &&
  235. global_stats.opencl_to_cpu == 2 &&
  236. global_stats.opencl == 2);
  237. }
  238. #endif /* !STARPU_USE_OPENCL */
  239. int
  240. main(void)
  241. {
  242. #ifdef STARPU_USE_CPU
  243. struct starpu_conf conf = {
  244. .ncpus = -1,
  245. .ncuda = 2,
  246. .nopencl = 1
  247. };
  248. starpu_init(&conf);
  249. #ifdef STARPU_USE_OPENCL
  250. if (test_opencl() != 0)
  251. {
  252. fprintf(stderr, "OPENCL FAILED\n");
  253. exit(1);
  254. }
  255. #endif
  256. #ifdef STARPU_USE_CUDA
  257. if (test_cuda() != 0)
  258. {
  259. fprintf(stderr, "CUDA FAILED \n");
  260. exit(1);
  261. }
  262. #endif
  263. starpu_shutdown();
  264. #endif
  265. /* Without the CPU, there is no point in using the multiformat
  266. * interface, so this test is pointless. */
  267. return EXIT_SUCCESS;
  268. }