multiformat.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2011-2012 Institut National de Recherche en Informatique et Automatique
  4. *
  5. * StarPU is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 2.1 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * StarPU is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. */
  16. #include <starpu.h>
  17. #ifdef STARPU_USE_OPENCL
  18. #include <starpu_opencl.h>
  19. #endif
  20. #include "multiformat_types.h"
  21. static int ncpu = 0;
  22. #ifdef STARPU_USE_CUDA
  23. static int ncuda = 0;
  24. #endif
  25. #ifdef STARPU_USE_OPENCL
  26. static int nopencl = 0;
  27. #endif
  28. static struct point array_of_structs[N_ELEMENTS];
  29. static starpu_data_handle_t array_of_structs_handle;
  30. static void
  31. multiformat_scal_cpu_func(void *buffers[], void *args)
  32. {
  33. struct point *aos;
  34. unsigned int n, i;
  35. aos = (struct point *) STARPU_MULTIFORMAT_GET_CPU_PTR(buffers[0]);
  36. n = STARPU_MULTIFORMAT_GET_NX(buffers[0]);
  37. for (i = 0; i < n; i++)
  38. {
  39. aos[i].x *= aos[i].y;
  40. }
  41. }
  42. #ifdef STARPU_USE_CUDA
  43. extern struct starpu_codelet cpu_to_cuda_cl;
  44. extern struct starpu_codelet cuda_to_cpu_cl;
  45. #endif
  46. #ifdef STARPU_USE_OPENCL
  47. extern struct starpu_codelet cpu_to_opencl_cl;
  48. extern struct starpu_codelet opencl_to_cpu_cl;
  49. #endif
  50. static struct starpu_multiformat_data_interface_ops format_ops =
  51. {
  52. #ifdef STARPU_USE_CUDA
  53. .cuda_elemsize = 2* sizeof(float),
  54. .cpu_to_cuda_cl = &cpu_to_cuda_cl,
  55. .cuda_to_cpu_cl = &cuda_to_cpu_cl,
  56. #endif
  57. #ifdef STARPU_USE_OPENCL
  58. .opencl_elemsize = 2 * sizeof(float),
  59. .cpu_to_opencl_cl = &cpu_to_opencl_cl,
  60. .opencl_to_cpu_cl = &opencl_to_cpu_cl,
  61. #endif
  62. .cpu_elemsize = sizeof(struct point),
  63. };
  64. #ifdef STARPU_USE_CUDA
  65. extern void multiformat_scal_cuda_func(void *buffers[], void *arg);
  66. #endif
  67. #ifdef STARPU_USE_OPENCL
  68. extern void multiformat_scal_opencl_func(void *buffers[], void *arg);
  69. #endif
  70. #ifdef STARPU_USE_CPU
  71. static struct starpu_codelet cpu_cl =
  72. {
  73. .where = STARPU_CPU,
  74. .cpu_funcs = {multiformat_scal_cpu_func, NULL},
  75. .nbuffers = 1,
  76. .modes = { STARPU_RW },
  77. .name = "codelet_real"
  78. };
  79. #endif /* !STARPU_USE_CPU */
  80. #ifdef STARPU_USE_CUDA
  81. static struct starpu_codelet cuda_cl =
  82. {
  83. .where = STARPU_CUDA,
  84. .cuda_funcs = { multiformat_scal_cuda_func, NULL },
  85. .nbuffers = 1,
  86. .modes = { STARPU_RW },
  87. .name = "cuda_codelet"
  88. };
  89. #endif /* !STARPU_USE_CUDA */
  90. #ifdef STARPU_USE_OPENCL
  91. static struct starpu_codelet opencl_cl =
  92. {
  93. .where = STARPU_OPENCL,
  94. .opencl_funcs = { multiformat_scal_opencl_func, NULL },
  95. .nbuffers = 1,
  96. .modes = { STARPU_RW },
  97. .name = "opencl_codelet"
  98. };
  99. #endif /* !STARPU_USE_OPENCL */
  100. /*
  101. * Main functions
  102. */
  103. static void
  104. init_problem_data(void)
  105. {
  106. int i;
  107. for (i = 0; i < N_ELEMENTS; i++)
  108. {
  109. array_of_structs[i].x = 1.0 + i;
  110. array_of_structs[i].y = 42.0;
  111. }
  112. }
  113. static void
  114. register_data(void)
  115. {
  116. starpu_multiformat_data_register(&array_of_structs_handle,
  117. 0,
  118. &array_of_structs,
  119. N_ELEMENTS,
  120. &format_ops);
  121. }
  122. static int
  123. create_and_submit_task(unsigned int dev)
  124. {
  125. struct starpu_task *task = starpu_task_create();
  126. switch (dev)
  127. {
  128. #ifdef STARPU_USE_CPU
  129. case STARPU_CPU:
  130. task->cl = &cpu_cl;
  131. break;
  132. #endif
  133. #ifdef STARPU_USE_CUDA
  134. case STARPU_CUDA:
  135. task->cl = &cuda_cl;
  136. break;
  137. #endif
  138. #ifdef STARPU_USE_OPENCL
  139. case STARPU_OPENCL:
  140. task->cl = &opencl_cl;
  141. break;
  142. #endif
  143. default:
  144. assert(0);
  145. }
  146. task->synchronous = 1;
  147. task->handles[0] = array_of_structs_handle;
  148. task->cl_arg = NULL;
  149. task->cl_arg_size = 0;
  150. return starpu_task_submit(task);
  151. }
  152. static void
  153. create_and_submit_tasks(void)
  154. {
  155. int err;
  156. #ifdef STARPU_USE_CUDA
  157. if (ncuda > 0)
  158. {
  159. err = create_and_submit_task(STARPU_CUDA);
  160. if (err != 0)
  161. {
  162. FPRINTF(stderr, "Cuda : %s\n", strerror(-err));
  163. return;
  164. }
  165. }
  166. #endif
  167. #ifdef STARPU_USE_CPU
  168. if (ncpu > 0)
  169. {
  170. err = create_and_submit_task(STARPU_CPU);
  171. if (err != 0)
  172. {
  173. FPRINTF(stderr, "CPU : %s\n", strerror(-err));
  174. return;
  175. }
  176. }
  177. #endif
  178. #ifdef STARPU_USE_OPENCL
  179. if (nopencl > 0)
  180. {
  181. err = create_and_submit_task(STARPU_OPENCL);
  182. if (err != 0)
  183. {
  184. FPRINTF(stderr, "OpenCL : %s\n", strerror(-err));
  185. return;
  186. }
  187. }
  188. #endif /* !STARPU_USE_OPENCL */
  189. }
  190. static void
  191. unregister_data(void)
  192. {
  193. starpu_data_unregister(array_of_structs_handle);
  194. }
  195. static void
  196. print_it(void)
  197. {
  198. int i;
  199. for (i = 0; i < N_ELEMENTS; i++)
  200. {
  201. FPRINTF(stderr, "(%.2f %.2f) ",
  202. array_of_structs[i].x,
  203. array_of_structs[i].y);
  204. }
  205. FPRINTF(stderr, "\n");
  206. }
  207. static int
  208. check_it(void)
  209. {
  210. int i;
  211. for (i = 0; i < N_ELEMENTS; i++)
  212. {
  213. float expected_value = i + 1.0;
  214. #ifdef STARPU_USE_CUDA
  215. if (ncuda > 0)
  216. expected_value *= array_of_structs[i].y;
  217. #endif
  218. #ifdef STARPU_USE_OPENCL
  219. if (nopencl > 0)
  220. expected_value *= array_of_structs[i].y;
  221. #endif
  222. expected_value *= array_of_structs[i].y;
  223. if (array_of_structs[i].x != expected_value)
  224. return EXIT_FAILURE;
  225. }
  226. return EXIT_SUCCESS;
  227. }
  228. #ifdef STARPU_USE_OPENCL
  229. struct starpu_opencl_program opencl_program;
  230. struct starpu_opencl_program opencl_conversion_program;
  231. #endif
  232. static int
  233. gpus_available()
  234. {
  235. #ifdef STARPU_USE_CUDA
  236. if (ncuda > 0)
  237. return 1;
  238. #endif
  239. #ifdef STARPU_USE_OPENCL
  240. if (nopencl > 0)
  241. return 1;
  242. #endif
  243. return 0;
  244. }
  245. int
  246. main(void)
  247. {
  248. #ifdef STARPU_USE_CPU
  249. int ret;
  250. ret = starpu_init(NULL);
  251. STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
  252. ncpu = starpu_cpu_worker_get_count();
  253. #ifdef STARPU_USE_CUDA
  254. ncuda = starpu_cuda_worker_get_count();
  255. #endif
  256. #ifdef STARPU_USE_OPENCL
  257. nopencl = starpu_opencl_worker_get_count();
  258. #endif
  259. if (ncpu == 0 || !gpus_available())
  260. {
  261. starpu_shutdown();
  262. return 77;
  263. }
  264. #ifdef STARPU_USE_OPENCL
  265. ret = starpu_opencl_load_opencl_from_file("examples/basic_examples/multiformat_opencl_kernel.cl",
  266. &opencl_program, NULL);
  267. STARPU_CHECK_RETURN_VALUE(ret, "starpu_opencl_load_opencl_from_file");
  268. ret = starpu_opencl_load_opencl_from_file("examples/basic_examples/multiformat_conversion_codelets_opencl_kernel.cl",
  269. &opencl_conversion_program, NULL);
  270. STARPU_CHECK_RETURN_VALUE(ret, "starpu_opencl_load_opencl_from_file");
  271. #endif
  272. init_problem_data();
  273. print_it();
  274. register_data();
  275. create_and_submit_tasks();
  276. unregister_data();
  277. print_it();
  278. #ifdef STARPU_USE_OPENCL
  279. ret = starpu_opencl_unload_opencl(&opencl_program);
  280. STARPU_CHECK_RETURN_VALUE(ret, "starpu_opencl_unload_opencl");
  281. starpu_opencl_unload_opencl(&opencl_conversion_program);
  282. #endif
  283. starpu_shutdown();
  284. return check_it();
  285. #else
  286. /* Without the CPU, there is no point in using the multiformat
  287. * interface, so this test is pointless. */
  288. return 77;
  289. #endif
  290. }