variable_parameters.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2010-2020 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
  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. #include "../helper.h"
  18. /*
  19. * Test the variable interface
  20. */
  21. static starpu_data_handle_t handle1, handle2, handle3, handle4;
  22. /*
  23. * Increment codelet
  24. */
  25. #ifdef STARPU_USE_OPENCL
  26. /* dummy OpenCL implementation */
  27. static void increment_opencl_kernel(void *descr[], void *cl_arg)
  28. {
  29. (void)cl_arg;
  30. int num = starpu_task_get_current()->nbuffers;
  31. int i;
  32. for (i = 0; i < num; i++)
  33. {
  34. cl_mem d_token = (cl_mem)STARPU_VARIABLE_GET_PTR(descr[i]);
  35. unsigned h_token;
  36. cl_command_queue queue;
  37. starpu_opencl_get_current_queue(&queue);
  38. clEnqueueReadBuffer(queue, d_token, CL_TRUE, 0, sizeof(unsigned), (void *)&h_token, 0, NULL, NULL);
  39. h_token++;
  40. clEnqueueWriteBuffer(queue, d_token, CL_TRUE, 0, sizeof(unsigned), (void *)&h_token, 0, NULL, NULL);
  41. clFinish(queue);
  42. }
  43. }
  44. #endif
  45. #ifdef STARPU_USE_CUDA
  46. static void increment_cuda_kernel(void *descr[], void *cl_arg)
  47. {
  48. (void)cl_arg;
  49. int num = starpu_task_get_current()->nbuffers;
  50. int i;
  51. for (i = 0; i < num; i++)
  52. {
  53. unsigned *tokenptr = (unsigned *)STARPU_VARIABLE_GET_PTR(descr[i]);
  54. unsigned host_token;
  55. /* This is a dummy technique of course */
  56. cudaMemcpyAsync(&host_token, tokenptr, sizeof(unsigned), cudaMemcpyDeviceToHost, starpu_cuda_get_local_stream());
  57. cudaStreamSynchronize(starpu_cuda_get_local_stream());
  58. host_token++;
  59. cudaMemcpyAsync(tokenptr, &host_token, sizeof(unsigned), cudaMemcpyHostToDevice, starpu_cuda_get_local_stream());
  60. }
  61. cudaStreamSynchronize(starpu_cuda_get_local_stream());
  62. }
  63. #endif
  64. void increment_cpu_kernel(void *descr[], void *cl_arg)
  65. {
  66. (void)cl_arg;
  67. int num = starpu_task_get_current()->nbuffers;
  68. int i;
  69. for (i = 0; i < num; i++)
  70. {
  71. unsigned *tokenptr = (unsigned *)STARPU_VARIABLE_GET_PTR(descr[i]);
  72. *tokenptr = *tokenptr + 1;
  73. }
  74. }
  75. static struct starpu_codelet increment_cl =
  76. {
  77. #ifdef STARPU_USE_CUDA
  78. .cuda_funcs = {increment_cuda_kernel},
  79. #endif
  80. #ifdef STARPU_USE_OPENCL
  81. .opencl_funcs = {increment_opencl_kernel},
  82. #endif
  83. .cpu_funcs = {increment_cpu_kernel},
  84. /* starpu_task_get_current() doesn't work on MIC */
  85. /*.cpu_funcs_name = {"increment_cpu_kernel"},*/
  86. .nbuffers = STARPU_VARIABLE_NBUFFERS,
  87. };
  88. int main(void)
  89. {
  90. unsigned *pvar = NULL;
  91. int ret;
  92. unsigned var1 = 0, var2 = 0, var3 = 0, var4 = 0;
  93. ret = starpu_init(NULL);
  94. if (ret == -ENODEV) return STARPU_TEST_SKIPPED;
  95. STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
  96. starpu_variable_data_register(&handle1, STARPU_MAIN_RAM, (uintptr_t)&var1, sizeof(unsigned));
  97. starpu_variable_data_register(&handle2, STARPU_MAIN_RAM, (uintptr_t)&var2, sizeof(unsigned));
  98. starpu_variable_data_register(&handle3, STARPU_MAIN_RAM, (uintptr_t)&var3, sizeof(unsigned));
  99. starpu_variable_data_register(&handle4, STARPU_MAIN_RAM, (uintptr_t)&var4, sizeof(unsigned));
  100. #ifdef STARPU_QUICK_CHECK
  101. unsigned nloops = 4;
  102. #else
  103. unsigned nloops = 16;
  104. #endif
  105. unsigned loop;
  106. unsigned t;
  107. for (loop = 0; loop < nloops; loop++)
  108. {
  109. for (t = 0; t <= 4; t++)
  110. {
  111. struct starpu_task *task = starpu_task_create();
  112. unsigned i;
  113. task->cl = &increment_cl;
  114. task->handles[0] = handle1;
  115. task->handles[1] = handle2;
  116. task->handles[2] = handle3;
  117. task->handles[3] = handle4;
  118. for (i = 0; i < t; i++)
  119. task->modes[i] = STARPU_RW;
  120. task->nbuffers = t;
  121. ret = starpu_task_submit(task);
  122. if (ret == -ENODEV) goto enodev;
  123. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
  124. }
  125. starpu_task_insert(&increment_cl,
  126. STARPU_RW, handle1,
  127. 0);
  128. starpu_task_insert(&increment_cl,
  129. STARPU_RW, handle1,
  130. STARPU_RW, handle2,
  131. 0);
  132. starpu_task_insert(&increment_cl,
  133. STARPU_RW, handle1,
  134. STARPU_RW, handle2,
  135. STARPU_RW, handle3,
  136. 0);
  137. starpu_task_insert(&increment_cl,
  138. STARPU_RW, handle1,
  139. STARPU_RW, handle2,
  140. STARPU_RW, handle3,
  141. STARPU_RW, handle4,
  142. 0);
  143. }
  144. ret = starpu_data_acquire(handle1, STARPU_R);
  145. STARPU_CHECK_RETURN_VALUE(ret, "starpu_data_acquire");
  146. if (var1 != 8*nloops)
  147. {
  148. FPRINTF(stderr, "[end of loop] Value %u != Expected value %u\n", var1, 8*nloops);
  149. starpu_data_release(handle1);
  150. goto err;
  151. }
  152. starpu_data_release(handle1);
  153. ret = starpu_data_acquire(handle2, STARPU_R);
  154. STARPU_CHECK_RETURN_VALUE(ret, "starpu_data_acquire");
  155. if (var2 != 6*nloops)
  156. {
  157. FPRINTF(stderr, "[end of loop] Value %u != Expected value %u\n", var2, 6*nloops);
  158. starpu_data_release(handle2);
  159. goto err;
  160. }
  161. starpu_data_release(handle2);
  162. ret = starpu_data_acquire(handle3, STARPU_R);
  163. STARPU_CHECK_RETURN_VALUE(ret, "starpu_data_acquire");
  164. if (var3 != 4*nloops)
  165. {
  166. FPRINTF(stderr, "[end of loop] Value %u != Expected value %u\n", var3, 4*nloops);
  167. starpu_data_release(handle3);
  168. goto err;
  169. }
  170. starpu_data_release(handle3);
  171. ret = starpu_data_acquire(handle4, STARPU_R);
  172. STARPU_CHECK_RETURN_VALUE(ret, "starpu_data_acquire");
  173. if (var4 != 2*nloops)
  174. {
  175. FPRINTF(stderr, "[end of loop] Value %u != Expected value %u\n", var4, 2*nloops);
  176. starpu_data_release(handle4);
  177. goto err;
  178. }
  179. starpu_data_release(handle4);
  180. starpu_data_unregister(handle1);
  181. starpu_data_unregister(handle2);
  182. starpu_data_unregister(handle3);
  183. starpu_data_unregister(handle4);
  184. starpu_shutdown();
  185. return EXIT_SUCCESS;
  186. enodev:
  187. starpu_data_unregister(handle1);
  188. starpu_data_unregister(handle2);
  189. starpu_data_unregister(handle3);
  190. starpu_data_unregister(handle4);
  191. fprintf(stderr, "WARNING: No one can execute this task\n");
  192. /* yes, we do not perform the computation but we did detect that no one
  193. * could perform the kernel, so this is not an error from StarPU */
  194. starpu_shutdown();
  195. return STARPU_TEST_SKIPPED;
  196. err:
  197. starpu_data_unregister(handle1);
  198. starpu_data_unregister(handle2);
  199. starpu_data_unregister(handle3);
  200. starpu_data_unregister(handle4);
  201. starpu_shutdown();
  202. return EXIT_FAILURE;
  203. }