fplan_notautomatic.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2018 CNRS
  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. #define FPRINTF(ofile, fmt, ...) do { if (!getenv("STARPU_SSILENT")) {fprintf(ofile, fmt, ## __VA_ARGS__); }} while(0)
  18. #define NX 9
  19. #define PARTS 3
  20. struct starpu_codelet t1_codelet;
  21. struct starpu_codelet t2_codelet;
  22. // CPU implementations
  23. void t1_cpu(void *descr[], void *args)
  24. {
  25. int *values = (int*)STARPU_VECTOR_GET_PTR(descr[0]);
  26. int nx = STARPU_VECTOR_GET_NX(descr[0]);
  27. int i, add;
  28. char message[10000];
  29. int cur = 0;
  30. starpu_codelet_unpack_args(args, &add);
  31. cur += snprintf(&message[cur], 10000, "[t1] Values ");
  32. for(i=0 ; i<nx ; i++)
  33. {
  34. values[i] += add;
  35. cur += snprintf(&message[cur], 10000-cur, "%d ", values[i]);
  36. }
  37. FPRINTF(stderr, "%s\n", message);
  38. }
  39. void t2_cpu(void *descr[], void *args)
  40. {
  41. int *values = (int*)STARPU_VECTOR_GET_PTR(descr[0]);
  42. int nx = STARPU_VECTOR_GET_NX(descr[0]);
  43. int i, mult;
  44. char message[10000];
  45. int cur = 0;
  46. starpu_codelet_unpack_args(args, &mult);
  47. cur += snprintf(&message[cur], 10000, "[t2] Values ");
  48. for(i=0 ; i<nx ; i++)
  49. {
  50. values[i] *= mult;
  51. cur += snprintf(&message[cur], 10000-cur, "%d ", values[i]);
  52. }
  53. FPRINTF(stderr, "%s\n", message);
  54. }
  55. void split_cpu(void *descr[], void *args)
  56. {
  57. (void)descr;
  58. // starpu_data_handle_t data_handle = starpu_data_lookup((void*)STARPU_VECTOR_GET_PTR(descr[0]));
  59. starpu_data_handle_t value_handle, sub_handles[PARTS];
  60. starpu_codelet_unpack_args(args, &value_handle, &sub_handles);
  61. FPRINTF(stderr, " Partition for handle %p into handles %p %p and %p\n", value_handle, sub_handles[0], sub_handles[1], sub_handles[2]);
  62. starpu_data_partition_submit_sequential_consistency(value_handle, PARTS, sub_handles, 0);
  63. }
  64. void b1_cpu(void *descr[], void *args)
  65. {
  66. (void)descr;
  67. // starpu_data_handle_t data_handle = starpu_data_lookup((void*)STARPU_VECTOR_GET_PTR(descr[0]));
  68. starpu_data_handle_t sub_handles[PARTS];
  69. int add;
  70. starpu_codelet_unpack_args(args, &sub_handles, &add);
  71. FPRINTF(stderr, "[B1] Submitting tasks on %d subdata\n", PARTS);
  72. int i;
  73. for(i=0 ; i<PARTS ; i++)
  74. {
  75. int ret = starpu_task_insert(&t1_codelet,
  76. STARPU_RW, sub_handles[i],
  77. STARPU_VALUE, &add, sizeof(add),
  78. 0);
  79. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
  80. }
  81. }
  82. void b2_cpu(void *descr[], void *args)
  83. {
  84. (void)descr;
  85. // starpu_data_handle_t data_handle = starpu_data_lookup((void*)STARPU_VECTOR_GET_PTR(descr[0]));
  86. int factor;
  87. starpu_data_handle_t sub_handles[PARTS];
  88. starpu_codelet_unpack_args(args, &sub_handles, &factor);
  89. FPRINTF(stderr, "[B2] Submitting tasks on subdata\n");
  90. int i;
  91. for(i=0 ; i<PARTS ; i++)
  92. {
  93. int ret = starpu_task_insert(&t2_codelet,
  94. STARPU_RW, sub_handles[i],
  95. STARPU_VALUE, &factor, sizeof(factor),
  96. 0);
  97. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
  98. }
  99. }
  100. void merge_cpu(void *descr[], void *args)
  101. {
  102. (void)descr;
  103. // starpu_data_handle_t value_handle = starpu_data_lookup((void*)STARPU_VECTOR_GET_PTR(descr[0]));
  104. starpu_data_handle_t value_handle, sub_handles[PARTS];
  105. starpu_codelet_unpack_args(args, &value_handle, &sub_handles);
  106. FPRINTF(stderr, "Unpartition for handle %p from handles %p %p and %p\n", value_handle, sub_handles[0], sub_handles[1], sub_handles[2]);
  107. starpu_data_unpartition_submit_sequential_consistency(value_handle, PARTS, sub_handles, STARPU_MAIN_RAM, 0);
  108. }
  109. // Codelets
  110. struct starpu_codelet t1_codelet =
  111. {
  112. .cpu_funcs = {t1_cpu},
  113. .nbuffers = 1,
  114. .modes = {STARPU_RW},
  115. .name = "t1_codelet"
  116. };
  117. struct starpu_codelet t2_codelet =
  118. {
  119. .cpu_funcs = {t2_cpu},
  120. .nbuffers = 1,
  121. .modes = {STARPU_RW},
  122. .name = "t2_codelet"
  123. };
  124. struct starpu_codelet b1_codelet =
  125. {
  126. .cpu_funcs = {b1_cpu},
  127. .nbuffers = 1,
  128. .modes = {STARPU_RW},
  129. .name = "b1_codelet"
  130. };
  131. struct starpu_codelet b2_codelet =
  132. {
  133. .cpu_funcs = {b2_cpu},
  134. .nbuffers = 1,
  135. .modes = {STARPU_RW},
  136. .name = "b2_codelet"
  137. };
  138. struct starpu_codelet split_codelet =
  139. {
  140. .cpu_funcs = {split_cpu},
  141. .nbuffers = 1,
  142. .modes = {STARPU_RW},
  143. .name = "split_codelet"
  144. };
  145. struct starpu_codelet merge_codelet =
  146. {
  147. .cpu_funcs = {merge_cpu},
  148. .nbuffers = 1,
  149. .modes = {STARPU_RW},
  150. .name = "merge_codelet"
  151. };
  152. int main(void)
  153. {
  154. int ret, i;
  155. int values[NX];
  156. int check[NX];
  157. int factor=2;
  158. int add=1;
  159. starpu_data_handle_t value_handle;
  160. starpu_data_handle_t sub_handles[PARTS];
  161. ret = starpu_init(NULL);
  162. STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
  163. if (starpu_cpu_worker_get_count() == 0)
  164. {
  165. FPRINTF(stderr, "We need at least 1 CPU worker.\n");
  166. starpu_shutdown();
  167. return 77;
  168. }
  169. struct starpu_data_filter f =
  170. {
  171. .filter_func = starpu_vector_filter_block,
  172. .nchildren = PARTS
  173. };
  174. values[NX-1] = 2;
  175. for(i=NX-2 ; i>= 0 ; i--) values[i] = values[i+1] * 2;
  176. for(i=0 ; i<NX ; i++) check[i] = (values[i] + 1 + 1) * 2 + 1;
  177. starpu_vector_data_register(&value_handle, STARPU_MAIN_RAM, (uintptr_t)&values[0], NX, sizeof(values[0]));
  178. starpu_data_partition_plan(value_handle, &f, sub_handles);
  179. // tell StarPU not to partition data, the application will decide itself when to do it
  180. starpu_data_partition_not_automatic(value_handle);
  181. for(i=0 ; i<PARTS ; i++)
  182. starpu_data_partition_not_automatic(sub_handles[i]);
  183. // insert a task on the whole data
  184. ret = starpu_task_insert(&t1_codelet, STARPU_RW, value_handle,
  185. STARPU_VALUE, &add, sizeof(add),
  186. STARPU_NAME, "t1", 0);
  187. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
  188. // insert a task to split the data
  189. ret = starpu_task_insert(&split_codelet, STARPU_RW, value_handle,
  190. STARPU_VALUE, &value_handle, sizeof(starpu_data_handle_t),
  191. STARPU_VALUE, sub_handles, PARTS*sizeof(starpu_data_handle_t),
  192. STARPU_NAME, "split", 0);
  193. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
  194. // insert a task that will work on the subdata
  195. ret = starpu_task_insert(&b1_codelet, STARPU_RW, value_handle,
  196. STARPU_VALUE, sub_handles, PARTS*sizeof(starpu_data_handle_t),
  197. STARPU_VALUE, &add, sizeof(add),
  198. STARPU_NAME, "b1", 0);
  199. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
  200. // insert another task that will work on the subdata
  201. ret = starpu_task_insert(&b2_codelet, STARPU_RW, value_handle,
  202. STARPU_VALUE, sub_handles, PARTS*sizeof(starpu_data_handle_t),
  203. STARPU_VALUE, &factor, sizeof(factor),
  204. STARPU_NAME, "b2", 0);
  205. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
  206. // insert a task to merge the data
  207. ret = starpu_task_insert(&merge_codelet, STARPU_RW, value_handle,
  208. STARPU_VALUE, &value_handle, sizeof(starpu_data_handle_t),
  209. STARPU_VALUE, sub_handles, PARTS*sizeof(starpu_data_handle_t),
  210. STARPU_NAME, "merge", 0);
  211. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
  212. // insert a task that will work on the whole data
  213. ret = starpu_task_insert(&t1_codelet, STARPU_RW, value_handle,
  214. STARPU_VALUE, &add, sizeof(add),
  215. STARPU_NAME, "t1", 0);
  216. STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
  217. starpu_task_wait_for_all();
  218. starpu_data_partition_clean(value_handle, PARTS, sub_handles);
  219. starpu_data_unregister(value_handle);
  220. FPRINTF(stderr, "Values : ");
  221. for(i=0 ; i<NX ; i++)
  222. {
  223. FPRINTF(stderr, "%d ", values[i]);
  224. }
  225. FPRINTF(stderr, "\n");
  226. for(i=0 ; i<NX ; i++)
  227. {
  228. if (values[i] != check[i])
  229. {
  230. FPRINTF(stderr, "Incorrect value for %d. %d != %d\n", i, values[i], check[i]);
  231. ret = 1;
  232. }
  233. }
  234. starpu_shutdown();
  235. return ret;
  236. }