starpu_task_insert_utils.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2011-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 <util/starpu_task_insert_utils.h>
  17. #include <common/config.h>
  18. #include <common/utils.h>
  19. #include <core/task.h>
  20. void starpu_codelet_pack_arg_init(struct starpu_codelet_pack_arg_data *state)
  21. {
  22. state->arg_buffer = NULL;
  23. state->arg_buffer_size = 0;
  24. state->current_offset = sizeof(int);
  25. state->nargs = 0;
  26. }
  27. void starpu_codelet_pack_arg(struct starpu_codelet_pack_arg_data *state, const void *ptr, size_t ptr_size)
  28. {
  29. STARPU_ASSERT_MSG(state->current_offset >= sizeof(int), "struct starpu_codelet_pack_arg has to be initialized with starpu_codelet_pack_arg_init");
  30. if (state->current_offset + sizeof(ptr_size) + ptr_size > state->arg_buffer_size)
  31. {
  32. if (state->arg_buffer_size == 0)
  33. state->arg_buffer_size = 128 + sizeof(ptr_size) + ptr_size;
  34. else
  35. state->arg_buffer_size = 2 * state->arg_buffer_size + sizeof(ptr_size) + ptr_size;
  36. _STARPU_REALLOC(state->arg_buffer, state->arg_buffer_size);
  37. }
  38. memcpy(state->arg_buffer+state->current_offset, (void *)&ptr_size, sizeof(ptr_size));
  39. state->current_offset += sizeof(ptr_size);
  40. memcpy(state->arg_buffer+state->current_offset, ptr, ptr_size);
  41. state->current_offset += ptr_size;
  42. STARPU_ASSERT(state->current_offset <= state->arg_buffer_size);
  43. state->nargs++;
  44. }
  45. void starpu_codelet_pack_arg_fini(struct starpu_codelet_pack_arg_data *state, void **cl_arg, size_t *cl_arg_size)
  46. {
  47. if (state->nargs)
  48. {
  49. memcpy(state->arg_buffer, &state->nargs, sizeof(state->nargs));
  50. }
  51. else
  52. {
  53. free(state->arg_buffer);
  54. state->arg_buffer = NULL;
  55. }
  56. *cl_arg = state->arg_buffer;
  57. *cl_arg_size = state->arg_buffer_size;
  58. }
  59. int _starpu_codelet_pack_args(void **arg_buffer, size_t *arg_buffer_size, va_list varg_list)
  60. {
  61. int arg_type;
  62. struct starpu_codelet_pack_arg_data state;
  63. starpu_codelet_pack_arg_init(&state);
  64. while((arg_type = va_arg(varg_list, int)) != 0)
  65. {
  66. if (arg_type & STARPU_R || arg_type & STARPU_W || arg_type & STARPU_SCRATCH || arg_type & STARPU_REDUX)
  67. {
  68. (void)va_arg(varg_list, starpu_data_handle_t);
  69. }
  70. else if (arg_type==STARPU_DATA_ARRAY)
  71. {
  72. (void)va_arg(varg_list, starpu_data_handle_t*);
  73. (void)va_arg(varg_list, int);
  74. }
  75. else if (arg_type==STARPU_DATA_MODE_ARRAY)
  76. {
  77. (void)va_arg(varg_list, struct starpu_data_descr*);
  78. (void)va_arg(varg_list, int);
  79. }
  80. else if (arg_type==STARPU_VALUE)
  81. {
  82. /* We have a constant value: this should be followed by a pointer to the cst value and the size of the constant */
  83. void *ptr = va_arg(varg_list, void *);
  84. size_t ptr_size = va_arg(varg_list, size_t);
  85. starpu_codelet_pack_arg(&state, ptr, ptr_size);
  86. }
  87. else if (arg_type==STARPU_CL_ARGS)
  88. {
  89. (void)va_arg(varg_list, void *);
  90. (void)va_arg(varg_list, size_t);
  91. }
  92. else if (arg_type==STARPU_CL_ARGS_NFREE)
  93. {
  94. (void)va_arg(varg_list, void *);
  95. (void)va_arg(varg_list, size_t);
  96. }
  97. else if (arg_type==STARPU_TASK_DEPS_ARRAY)
  98. {
  99. (void)va_arg(varg_list, unsigned);
  100. (void)va_arg(varg_list, struct starpu_task **);
  101. }
  102. else if (arg_type==STARPU_TASK_END_DEPS_ARRAY)
  103. {
  104. (void)va_arg(varg_list, unsigned);
  105. (void)va_arg(varg_list, struct starpu_task **);
  106. }
  107. else if (arg_type==STARPU_CALLBACK)
  108. {
  109. (void)va_arg(varg_list, _starpu_callback_func_t);
  110. }
  111. else if (arg_type==STARPU_CALLBACK_WITH_ARG)
  112. {
  113. va_arg(varg_list, _starpu_callback_func_t);
  114. va_arg(varg_list, void *);
  115. }
  116. else if (arg_type==STARPU_CALLBACK_WITH_ARG_NFREE)
  117. {
  118. va_arg(varg_list, _starpu_callback_func_t);
  119. va_arg(varg_list, void *);
  120. }
  121. else if (arg_type==STARPU_CALLBACK_ARG)
  122. {
  123. (void)va_arg(varg_list, void *);
  124. }
  125. else if (arg_type==STARPU_CALLBACK_ARG_NFREE)
  126. {
  127. (void)va_arg(varg_list, void *);
  128. }
  129. else if (arg_type==STARPU_PROLOGUE_CALLBACK)
  130. {
  131. va_arg(varg_list, _starpu_callback_func_t);
  132. }
  133. else if (arg_type==STARPU_PROLOGUE_CALLBACK_ARG)
  134. {
  135. (void)va_arg(varg_list, void *);
  136. }
  137. else if (arg_type==STARPU_PROLOGUE_CALLBACK_ARG_NFREE)
  138. {
  139. (void)va_arg(varg_list, void *);
  140. }
  141. else if (arg_type==STARPU_PROLOGUE_CALLBACK_POP)
  142. {
  143. va_arg(varg_list, _starpu_callback_func_t);
  144. }
  145. else if (arg_type==STARPU_PROLOGUE_CALLBACK_POP_ARG)
  146. {
  147. (void)va_arg(varg_list, void *);
  148. }
  149. else if (arg_type==STARPU_PROLOGUE_CALLBACK_POP_ARG_NFREE)
  150. {
  151. (void)va_arg(varg_list, void *);
  152. }
  153. else if (arg_type==STARPU_PRIORITY)
  154. {
  155. (void)va_arg(varg_list, int);
  156. }
  157. else if (arg_type==STARPU_EXECUTE_ON_NODE)
  158. {
  159. (void)va_arg(varg_list, int);
  160. }
  161. else if (arg_type==STARPU_EXECUTE_ON_DATA)
  162. {
  163. (void)va_arg(varg_list, starpu_data_handle_t);
  164. }
  165. else if (arg_type==STARPU_EXECUTE_WHERE)
  166. {
  167. (void)va_arg(varg_list, unsigned long long);
  168. }
  169. else if (arg_type==STARPU_EXECUTE_ON_WORKER)
  170. {
  171. (void)va_arg(varg_list, int);
  172. }
  173. else if (arg_type==STARPU_WORKER_ORDER)
  174. {
  175. va_arg(varg_list, unsigned);
  176. }
  177. else if (arg_type==STARPU_SCHED_CTX)
  178. {
  179. (void)va_arg(varg_list, unsigned);
  180. }
  181. else if (arg_type==STARPU_HYPERVISOR_TAG)
  182. {
  183. (void)va_arg(varg_list, int);
  184. }
  185. else if (arg_type==STARPU_POSSIBLY_PARALLEL)
  186. {
  187. (void)va_arg(varg_list, unsigned);
  188. }
  189. else if (arg_type==STARPU_FLOPS)
  190. {
  191. (void)va_arg(varg_list, double);
  192. }
  193. else if (arg_type==STARPU_TAG || arg_type==STARPU_TAG_ONLY)
  194. {
  195. (void)va_arg(varg_list, starpu_tag_t);
  196. }
  197. else if (arg_type==STARPU_NAME)
  198. {
  199. (void)va_arg(varg_list, const char *);
  200. }
  201. else if (arg_type==STARPU_NODE_SELECTION_POLICY)
  202. {
  203. (void)va_arg(varg_list, int);
  204. }
  205. else if (arg_type==STARPU_TASK_COLOR)
  206. {
  207. (void)va_arg(varg_list, int);
  208. }
  209. else if (arg_type==STARPU_TASK_SYNCHRONOUS)
  210. {
  211. (void)va_arg(varg_list, int);
  212. }
  213. else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
  214. {
  215. (void)va_arg(varg_list, unsigned char *);
  216. }
  217. else if (arg_type==STARPU_TASK_END_DEP)
  218. {
  219. (void)va_arg(varg_list, int);
  220. }
  221. else if (arg_type==STARPU_TASK_WORKERIDS)
  222. {
  223. (void)va_arg(varg_list, unsigned);
  224. (void)va_arg(varg_list, uint32_t*);
  225. }
  226. else if (arg_type==STARPU_SEQUENTIAL_CONSISTENCY)
  227. {
  228. (void)va_arg(varg_list, unsigned);
  229. }
  230. else if (arg_type==STARPU_TASK_PROFILING_INFO)
  231. {
  232. (void)va_arg(varg_list, struct starpu_profiling_task_info *);
  233. }
  234. else if (arg_type==STARPU_TASK_NO_SUBMITORDER)
  235. {
  236. (void)va_arg(varg_list, unsigned);
  237. }
  238. else if (arg_type==STARPU_TASK_SCHED_DATA)
  239. {
  240. (void)va_arg(varg_list, void *);
  241. }
  242. else
  243. {
  244. STARPU_ABORT_MSG("Unrecognized argument %d, did you perhaps forget to end arguments with 0?\n", arg_type);
  245. }
  246. }
  247. starpu_codelet_pack_arg_fini(&state, arg_buffer, arg_buffer_size);
  248. return 0;
  249. }
  250. void starpu_task_insert_data_make_room(struct starpu_codelet *cl, struct starpu_task *task, int *allocated_buffers, int current_buffer, int room)
  251. {
  252. if (current_buffer + room > STARPU_NMAXBUFS)
  253. {
  254. if (*allocated_buffers == 0)
  255. {
  256. int i;
  257. struct starpu_codelet *cl2 = task->cl;
  258. *allocated_buffers = (current_buffer + room) * 2;
  259. _STARPU_MALLOC(task->dyn_handles, *allocated_buffers * sizeof(starpu_data_handle_t));
  260. for(i=0 ; i<current_buffer ; i++)
  261. {
  262. task->dyn_handles[i] = task->handles[i];
  263. }
  264. if (cl2->nbuffers == STARPU_VARIABLE_NBUFFERS || !cl2->dyn_modes)
  265. {
  266. _STARPU_MALLOC(task->dyn_modes, *allocated_buffers * sizeof(enum starpu_data_access_mode));
  267. for(i=0 ; i<current_buffer ; i++)
  268. {
  269. task->dyn_modes[i] = task->modes[i];
  270. }
  271. }
  272. }
  273. else if (current_buffer + room > *allocated_buffers)
  274. {
  275. *allocated_buffers = (current_buffer + room) * 2;
  276. _STARPU_REALLOC(task->dyn_handles, *allocated_buffers * sizeof(starpu_data_handle_t));
  277. if (cl->nbuffers == STARPU_VARIABLE_NBUFFERS || !cl->dyn_modes)
  278. {
  279. _STARPU_REALLOC(task->dyn_modes, *allocated_buffers * sizeof(enum starpu_data_access_mode));
  280. }
  281. }
  282. }
  283. }
  284. void starpu_task_insert_data_process_arg(struct starpu_codelet *cl, struct starpu_task *task, int *allocated_buffers, int *current_buffer, int arg_type, starpu_data_handle_t handle)
  285. {
  286. enum starpu_data_access_mode mode = (enum starpu_data_access_mode) arg_type & ~STARPU_SSEND;
  287. STARPU_ASSERT(cl != NULL);
  288. STARPU_ASSERT_MSG(cl->nbuffers == STARPU_VARIABLE_NBUFFERS || *current_buffer < cl->nbuffers, "Too many data passed to starpu_task_insert");
  289. starpu_task_insert_data_make_room(cl, task, allocated_buffers, *current_buffer, 1);
  290. STARPU_TASK_SET_HANDLE(task, handle, *current_buffer);
  291. if (cl->nbuffers == STARPU_VARIABLE_NBUFFERS || (cl->nbuffers > STARPU_NMAXBUFS && !cl->dyn_modes))
  292. STARPU_TASK_SET_MODE(task, mode,* current_buffer);
  293. else if (STARPU_CODELET_GET_MODE(cl, *current_buffer))
  294. {
  295. STARPU_ASSERT_MSG(STARPU_CODELET_GET_MODE(cl, *current_buffer) == mode,
  296. "The codelet <%s> defines the access mode %d for the buffer %d which is different from the mode %d given to starpu_task_insert\n",
  297. cl->name, STARPU_CODELET_GET_MODE(cl, *current_buffer),
  298. *current_buffer, mode);
  299. }
  300. else
  301. {
  302. #ifdef STARPU_DEVEL
  303. # warning shall we print a warning to the user
  304. /* Morse uses it to avoid having to set it in the codelet structure */
  305. #endif
  306. STARPU_CODELET_SET_MODE(cl, mode, *current_buffer);
  307. }
  308. (*current_buffer)++;
  309. }
  310. void starpu_task_insert_data_process_array_arg(struct starpu_codelet *cl, struct starpu_task *task, int *allocated_buffers, int *current_buffer, int nb_handles, starpu_data_handle_t *handles)
  311. {
  312. STARPU_ASSERT(cl != NULL);
  313. starpu_task_insert_data_make_room(cl, task, allocated_buffers, *current_buffer, nb_handles);
  314. int i;
  315. for(i=0 ; i<nb_handles ; i++)
  316. {
  317. STARPU_TASK_SET_HANDLE(task, handles[i], *current_buffer);
  318. (*current_buffer)++;
  319. }
  320. }
  321. void starpu_task_insert_data_process_mode_array_arg(struct starpu_codelet *cl, struct starpu_task *task, int *allocated_buffers, int *current_buffer, int nb_descrs, struct starpu_data_descr *descrs)
  322. {
  323. STARPU_ASSERT(cl != NULL);
  324. starpu_task_insert_data_make_room(cl, task, allocated_buffers, *current_buffer, nb_descrs);
  325. int i;
  326. for(i=0 ; i<nb_descrs ; i++)
  327. {
  328. STARPU_ASSERT_MSG(cl->nbuffers == STARPU_VARIABLE_NBUFFERS || *current_buffer < cl->nbuffers, "Too many data passed to starpu_task_insert");
  329. STARPU_TASK_SET_HANDLE(task, descrs[i].handle, *current_buffer);
  330. if (task->dyn_modes)
  331. {
  332. task->dyn_modes[*current_buffer] = descrs[i].mode;
  333. }
  334. else if (cl->nbuffers == STARPU_VARIABLE_NBUFFERS || (cl->nbuffers > STARPU_NMAXBUFS && !cl->dyn_modes))
  335. STARPU_TASK_SET_MODE(task, descrs[i].mode, *current_buffer);
  336. else if (STARPU_CODELET_GET_MODE(cl, *current_buffer))
  337. {
  338. STARPU_ASSERT_MSG(STARPU_CODELET_GET_MODE(cl, *current_buffer) == descrs[i].mode,
  339. "The codelet <%s> defines the access mode %d for the buffer %d which is different from the mode %d given to starpu_task_insert\n",
  340. cl->name, STARPU_CODELET_GET_MODE(cl, *current_buffer),
  341. *current_buffer, descrs[i].mode);
  342. }
  343. else
  344. {
  345. STARPU_CODELET_SET_MODE(cl, descrs[i].mode, *current_buffer);
  346. }
  347. (*current_buffer)++;
  348. }
  349. }
  350. int _starpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *task, va_list varg_list)
  351. {
  352. int arg_type;
  353. int current_buffer;
  354. int allocated_buffers = 0;
  355. unsigned ndeps = 0;
  356. unsigned nend_deps = 0;
  357. struct starpu_task **task_deps_array = NULL;
  358. struct starpu_task **task_end_deps_array = NULL;
  359. _STARPU_TRACE_TASK_BUILD_START();
  360. task->cl = cl;
  361. current_buffer = 0;
  362. struct starpu_codelet_pack_arg_data state;
  363. starpu_codelet_pack_arg_init(&state);
  364. while((arg_type = va_arg(varg_list, int)) != 0)
  365. {
  366. if (arg_type & STARPU_R || arg_type & STARPU_W || arg_type & STARPU_SCRATCH || arg_type & STARPU_REDUX)
  367. {
  368. /* We have an access mode : we expect to find a handle */
  369. starpu_data_handle_t handle = va_arg(varg_list, starpu_data_handle_t);
  370. starpu_task_insert_data_process_arg(cl, task, &allocated_buffers, &current_buffer, arg_type, handle);
  371. }
  372. else if (arg_type == STARPU_DATA_ARRAY)
  373. {
  374. // Expect to find a array of handles and its size
  375. starpu_data_handle_t *handles = va_arg(varg_list, starpu_data_handle_t *);
  376. int nb_handles = va_arg(varg_list, int);
  377. starpu_task_insert_data_process_array_arg(cl, task, &allocated_buffers, &current_buffer, nb_handles, handles);
  378. }
  379. else if (arg_type==STARPU_DATA_MODE_ARRAY)
  380. {
  381. // Expect to find a array of descr and its size
  382. struct starpu_data_descr *descrs = va_arg(varg_list, struct starpu_data_descr *);
  383. int nb_descrs = va_arg(varg_list, int);
  384. starpu_task_insert_data_process_mode_array_arg(cl, task, &allocated_buffers, &current_buffer, nb_descrs, descrs);
  385. }
  386. else if (arg_type==STARPU_VALUE)
  387. {
  388. void *ptr = va_arg(varg_list, void *);
  389. size_t ptr_size = va_arg(varg_list, size_t);
  390. starpu_codelet_pack_arg(&state, ptr, ptr_size);
  391. }
  392. else if (arg_type==STARPU_CL_ARGS)
  393. {
  394. task->cl_arg = va_arg(varg_list, void *);
  395. task->cl_arg_size = va_arg(varg_list, size_t);
  396. task->cl_arg_free = 1;
  397. }
  398. else if (arg_type==STARPU_CL_ARGS_NFREE)
  399. {
  400. task->cl_arg = va_arg(varg_list, void *);
  401. task->cl_arg_size = va_arg(varg_list, size_t);
  402. task->cl_arg_free = 0;
  403. }
  404. else if (arg_type==STARPU_TASK_DEPS_ARRAY)
  405. {
  406. STARPU_ASSERT_MSG(task_deps_array == NULL, "Parameter 'STARPU_TASK_DEPS_ARRAY' passed twice not supported yet");
  407. ndeps = va_arg(varg_list, unsigned);
  408. task_deps_array = va_arg(varg_list, struct starpu_task **);
  409. }
  410. else if (arg_type==STARPU_TASK_END_DEPS_ARRAY)
  411. {
  412. STARPU_ASSERT_MSG(task_end_deps_array == NULL, "Parameter 'STARPU_TASK_END_DEPS_ARRAY' passed twice not supported yet");
  413. nend_deps = va_arg(varg_list, unsigned);
  414. task_end_deps_array = va_arg(varg_list, struct starpu_task **);
  415. }
  416. else if (arg_type==STARPU_CALLBACK)
  417. {
  418. task->callback_func = va_arg(varg_list, _starpu_callback_func_t);
  419. }
  420. else if (arg_type==STARPU_CALLBACK_WITH_ARG)
  421. {
  422. task->callback_func = va_arg(varg_list, _starpu_callback_func_t);
  423. task->callback_arg = va_arg(varg_list, void *);
  424. task->callback_arg_free = 1;
  425. }
  426. else if (arg_type==STARPU_CALLBACK_WITH_ARG_NFREE)
  427. {
  428. task->callback_func = va_arg(varg_list, _starpu_callback_func_t);
  429. task->callback_arg = va_arg(varg_list, void *);
  430. task->callback_arg_free = 0;
  431. }
  432. else if (arg_type==STARPU_CALLBACK_ARG)
  433. {
  434. task->callback_arg = va_arg(varg_list, void *);
  435. task->callback_arg_free = 1;
  436. }
  437. else if (arg_type==STARPU_CALLBACK_ARG_NFREE)
  438. {
  439. task->callback_arg = va_arg(varg_list, void *);
  440. task->callback_arg_free = 0;
  441. }
  442. else if (arg_type==STARPU_PROLOGUE_CALLBACK)
  443. {
  444. task->prologue_callback_func = va_arg(varg_list, _starpu_callback_func_t);
  445. }
  446. else if (arg_type==STARPU_PROLOGUE_CALLBACK_ARG)
  447. {
  448. task->prologue_callback_arg = va_arg(varg_list, void *);
  449. task->prologue_callback_arg_free = 1;
  450. }
  451. else if (arg_type==STARPU_PROLOGUE_CALLBACK_ARG_NFREE)
  452. {
  453. task->prologue_callback_arg = va_arg(varg_list, void *);
  454. task->prologue_callback_arg_free = 0;
  455. }
  456. else if (arg_type==STARPU_PROLOGUE_CALLBACK_POP)
  457. {
  458. task->prologue_callback_pop_func = va_arg(varg_list, _starpu_callback_func_t);
  459. }
  460. else if (arg_type==STARPU_PROLOGUE_CALLBACK_POP_ARG)
  461. {
  462. task->prologue_callback_pop_arg = va_arg(varg_list, void *);
  463. task->prologue_callback_pop_arg_free = 1;
  464. }
  465. else if (arg_type==STARPU_PROLOGUE_CALLBACK_POP_ARG_NFREE)
  466. {
  467. task->prologue_callback_pop_arg = va_arg(varg_list, void *);
  468. task->prologue_callback_pop_arg_free = 0;
  469. }
  470. else if (arg_type==STARPU_PRIORITY)
  471. {
  472. /* Followed by a priority level */
  473. int prio = va_arg(varg_list, int);
  474. task->priority = prio;
  475. }
  476. else if (arg_type==STARPU_EXECUTE_ON_NODE)
  477. {
  478. (void)va_arg(varg_list, int);
  479. }
  480. else if (arg_type==STARPU_EXECUTE_ON_DATA)
  481. {
  482. (void)va_arg(varg_list, starpu_data_handle_t);
  483. }
  484. else if (arg_type==STARPU_EXECUTE_WHERE)
  485. {
  486. task->where = va_arg(varg_list, unsigned long long);
  487. }
  488. else if (arg_type==STARPU_EXECUTE_ON_WORKER)
  489. {
  490. int worker = va_arg(varg_list, int);
  491. if (worker != -1)
  492. {
  493. task->workerid = worker;
  494. task->execute_on_a_specific_worker = 1;
  495. }
  496. }
  497. else if (arg_type==STARPU_WORKER_ORDER)
  498. {
  499. unsigned order = va_arg(varg_list, unsigned);
  500. if (order != 0)
  501. {
  502. STARPU_ASSERT_MSG(task->execute_on_a_specific_worker, "worker order only makes sense if a workerid is provided");
  503. task->workerorder = order;
  504. }
  505. }
  506. else if (arg_type==STARPU_SCHED_CTX)
  507. {
  508. unsigned sched_ctx = va_arg(varg_list, unsigned);
  509. task->sched_ctx = sched_ctx;
  510. }
  511. else if (arg_type==STARPU_HYPERVISOR_TAG)
  512. {
  513. int hypervisor_tag = va_arg(varg_list, int);
  514. task->hypervisor_tag = hypervisor_tag;
  515. }
  516. else if (arg_type==STARPU_POSSIBLY_PARALLEL)
  517. {
  518. unsigned possibly_parallel = va_arg(varg_list, unsigned);
  519. task->possibly_parallel = possibly_parallel;
  520. }
  521. else if (arg_type==STARPU_FLOPS)
  522. {
  523. double flops = va_arg(varg_list, double);
  524. task->flops = flops;
  525. }
  526. else if (arg_type==STARPU_TAG)
  527. {
  528. starpu_tag_t tag = va_arg(varg_list, starpu_tag_t);
  529. task->tag_id = tag;
  530. task->use_tag = 1;
  531. }
  532. else if (arg_type==STARPU_TAG_ONLY)
  533. {
  534. starpu_tag_t tag = va_arg(varg_list, starpu_tag_t);
  535. task->tag_id = tag;
  536. }
  537. else if (arg_type==STARPU_NAME)
  538. {
  539. const char *name = va_arg(varg_list, const char *);
  540. task->name = name;
  541. }
  542. else if (arg_type==STARPU_NODE_SELECTION_POLICY)
  543. {
  544. (void)va_arg(varg_list, int);
  545. }
  546. else if (arg_type==STARPU_TASK_COLOR)
  547. {
  548. task->color = va_arg(varg_list, int);
  549. }
  550. else if (arg_type==STARPU_TASK_SYNCHRONOUS)
  551. {
  552. task->synchronous = va_arg(varg_list, int);
  553. }
  554. else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
  555. {
  556. task->handles_sequential_consistency = va_arg(varg_list, unsigned char *);
  557. }
  558. else if (arg_type==STARPU_TASK_END_DEP)
  559. {
  560. int end_dep = va_arg(varg_list, int);
  561. starpu_task_end_dep_add(task, end_dep);
  562. }
  563. else if (arg_type==STARPU_TASK_WORKERIDS)
  564. {
  565. task->workerids_len = va_arg(varg_list, unsigned);
  566. task->workerids = va_arg(varg_list, uint32_t*);
  567. }
  568. else if (arg_type==STARPU_SEQUENTIAL_CONSISTENCY)
  569. {
  570. task->sequential_consistency = va_arg(varg_list, unsigned);
  571. }
  572. else if (arg_type==STARPU_TASK_PROFILING_INFO)
  573. {
  574. task->profiling_info = va_arg(varg_list, struct starpu_profiling_task_info *);
  575. }
  576. else if (arg_type==STARPU_TASK_NO_SUBMITORDER)
  577. {
  578. task->no_submitorder = va_arg(varg_list, unsigned);
  579. }
  580. else if (arg_type==STARPU_TASK_SCHED_DATA)
  581. {
  582. task->sched_data = va_arg(varg_list, void *);
  583. }
  584. else
  585. {
  586. STARPU_ABORT_MSG("Unrecognized argument %d, did you perhaps forget to end arguments with 0?\n", arg_type);
  587. }
  588. }
  589. if (cl)
  590. {
  591. if (cl->nbuffers == STARPU_VARIABLE_NBUFFERS)
  592. {
  593. task->nbuffers = current_buffer;
  594. }
  595. else
  596. {
  597. STARPU_ASSERT_MSG(current_buffer == cl->nbuffers, "Incoherent number of buffers between cl (%d) and number of parameters (%d)", cl->nbuffers, current_buffer);
  598. }
  599. }
  600. if (state.nargs)
  601. {
  602. if (task->cl_arg != NULL)
  603. {
  604. _STARPU_DISP("Parameters STARPU_CL_ARGS and STARPU_VALUE cannot be used in the same call\n");
  605. free(state.arg_buffer);
  606. return -EINVAL;
  607. }
  608. starpu_codelet_pack_arg_fini(&state, &task->cl_arg, &task->cl_arg_size);
  609. }
  610. if (task_deps_array)
  611. {
  612. starpu_task_declare_deps_array(task, ndeps, task_deps_array);
  613. }
  614. if (task_end_deps_array)
  615. {
  616. starpu_task_declare_end_deps_array(task, nend_deps, task_end_deps_array);
  617. }
  618. _STARPU_TRACE_TASK_BUILD_END();
  619. return 0;
  620. }
  621. int _fstarpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *task, void **arglist)
  622. {
  623. int arg_i = 0;
  624. int current_buffer = 0;
  625. int allocated_buffers = 0;
  626. unsigned ndeps = 0;
  627. unsigned nend_deps = 0;
  628. struct starpu_task **task_deps_array = NULL;
  629. struct starpu_task **task_end_deps_array = NULL;
  630. _STARPU_TRACE_TASK_BUILD_START();
  631. struct starpu_codelet_pack_arg_data state;
  632. starpu_codelet_pack_arg_init(&state);
  633. task->cl = cl;
  634. task->name = NULL;
  635. task->cl_arg_free = 1;
  636. while (arglist[arg_i] != NULL)
  637. {
  638. const int arg_type = (int)(intptr_t)arglist[arg_i];
  639. if (arg_type & STARPU_R
  640. || arg_type & STARPU_W
  641. || arg_type & STARPU_SCRATCH
  642. || arg_type & STARPU_REDUX)
  643. {
  644. arg_i++;
  645. starpu_data_handle_t handle = arglist[arg_i];
  646. starpu_task_insert_data_process_arg(cl, task, &allocated_buffers, &current_buffer, arg_type, handle);
  647. }
  648. else if (arg_type == STARPU_DATA_ARRAY)
  649. {
  650. arg_i++;
  651. starpu_data_handle_t *handles = arglist[arg_i];
  652. arg_i++;
  653. int nb_handles = *(int *)arglist[arg_i];
  654. starpu_task_insert_data_process_array_arg(cl, task, &allocated_buffers, &current_buffer, nb_handles, handles);
  655. }
  656. else if (arg_type == STARPU_DATA_MODE_ARRAY)
  657. {
  658. arg_i++;
  659. struct starpu_data_descr *descrs = arglist[arg_i];
  660. arg_i++;
  661. int nb_descrs = *(int *)arglist[arg_i];
  662. starpu_task_insert_data_process_mode_array_arg(cl, task, &allocated_buffers, &current_buffer, nb_descrs, descrs);
  663. }
  664. else if (arg_type == STARPU_VALUE)
  665. {
  666. arg_i++;
  667. void *ptr = arglist[arg_i];
  668. arg_i++;
  669. size_t ptr_size = (size_t)(intptr_t)arglist[arg_i];
  670. starpu_codelet_pack_arg(&state, ptr, ptr_size);
  671. }
  672. else if (arg_type == STARPU_CL_ARGS)
  673. {
  674. arg_i++;
  675. task->cl_arg = arglist[arg_i];
  676. arg_i++;
  677. task->cl_arg_size = (size_t)(intptr_t)arglist[arg_i];
  678. task->cl_arg_free = 1;
  679. }
  680. else if (arg_type == STARPU_CL_ARGS_NFREE)
  681. {
  682. arg_i++;
  683. task->cl_arg = arglist[arg_i];
  684. arg_i++;
  685. task->cl_arg_size = (size_t)(intptr_t)arglist[arg_i];
  686. task->cl_arg_free = 0;
  687. }
  688. else if (arg_type==STARPU_TASK_DEPS_ARRAY)
  689. {
  690. STARPU_ASSERT_MSG(task_deps_array == NULL, "Parameter 'STARPU_TASK_DEPS_ARRAY' passed twice not supported yet");
  691. arg_i++;
  692. ndeps = *(unsigned *)arglist[arg_i];
  693. arg_i++;
  694. task_deps_array = arglist[arg_i];
  695. }
  696. else if (arg_type==STARPU_TASK_END_DEPS_ARRAY)
  697. {
  698. STARPU_ASSERT_MSG(task_end_deps_array == NULL, "Parameter 'STARPU_TASK_END_DEPS_ARRAY' passed twice not supported yet");
  699. arg_i++;
  700. nend_deps = *(unsigned *)arglist[arg_i];
  701. arg_i++;
  702. task_end_deps_array = arglist[arg_i];
  703. }
  704. else if (arg_type == STARPU_CALLBACK)
  705. {
  706. arg_i++;
  707. task->callback_func = (_starpu_callback_func_t)arglist[arg_i];
  708. }
  709. else if (arg_type == STARPU_CALLBACK_WITH_ARG)
  710. {
  711. arg_i++;
  712. task->callback_func = (_starpu_callback_func_t)arglist[arg_i];
  713. arg_i++;
  714. task->callback_arg = arglist[arg_i];
  715. task->callback_arg_free = 1;
  716. }
  717. else if (arg_type == STARPU_CALLBACK_WITH_ARG_NFREE)
  718. {
  719. arg_i++;
  720. task->callback_func = (_starpu_callback_func_t)arglist[arg_i];
  721. arg_i++;
  722. task->callback_arg = arglist[arg_i];
  723. task->callback_arg_free = 0;
  724. }
  725. else if (arg_type == STARPU_CALLBACK_ARG)
  726. {
  727. arg_i++;
  728. task->callback_arg = arglist[arg_i];
  729. task->callback_arg_free = 1;
  730. }
  731. else if (arg_type == STARPU_CALLBACK_ARG_NFREE)
  732. {
  733. arg_i++;
  734. task->callback_arg = arglist[arg_i];
  735. task->callback_arg_free = 0;
  736. }
  737. else if (arg_type == STARPU_PROLOGUE_CALLBACK)
  738. {
  739. arg_i++;
  740. task->prologue_callback_func = (_starpu_callback_func_t)arglist[arg_i];
  741. }
  742. else if (arg_type == STARPU_PROLOGUE_CALLBACK_ARG)
  743. {
  744. arg_i++;
  745. task->prologue_callback_arg = arglist[arg_i];
  746. task->prologue_callback_arg_free = 1;
  747. }
  748. else if (arg_type == STARPU_PROLOGUE_CALLBACK_ARG_NFREE)
  749. {
  750. arg_i++;
  751. task->prologue_callback_arg = arglist[arg_i];
  752. task->prologue_callback_arg_free = 0;
  753. }
  754. else if (arg_type == STARPU_PROLOGUE_CALLBACK_POP)
  755. {
  756. arg_i++;
  757. task->prologue_callback_pop_func = (_starpu_callback_func_t)arglist[arg_i];
  758. }
  759. else if (arg_type == STARPU_PROLOGUE_CALLBACK_POP_ARG)
  760. {
  761. arg_i++;
  762. task->prologue_callback_pop_arg = arglist[arg_i];
  763. task->prologue_callback_pop_arg_free = 1;
  764. }
  765. else if (arg_type == STARPU_PROLOGUE_CALLBACK_POP_ARG_NFREE)
  766. {
  767. arg_i++;
  768. task->prologue_callback_pop_arg = arglist[arg_i];
  769. task->prologue_callback_pop_arg_free = 0;
  770. }
  771. else if (arg_type == STARPU_PRIORITY)
  772. {
  773. arg_i++;
  774. task->priority = *(int *)arglist[arg_i];
  775. }
  776. else if (arg_type == STARPU_EXECUTE_ON_NODE)
  777. {
  778. arg_i++;
  779. (void)arglist[arg_i];
  780. }
  781. else if (arg_type == STARPU_EXECUTE_ON_DATA)
  782. {
  783. arg_i++;
  784. (void)arglist[arg_i];
  785. }
  786. else if (arg_type == STARPU_EXECUTE_WHERE)
  787. {
  788. assert(0);
  789. arg_i++;
  790. unsigned long long where = *(unsigned long long *)arglist[arg_i];
  791. task->where = where;
  792. }
  793. else if (arg_type == STARPU_EXECUTE_ON_WORKER)
  794. {
  795. arg_i++;
  796. int worker = *(int *)arglist[arg_i];
  797. if (worker != -1)
  798. {
  799. task->workerid = worker;
  800. task->execute_on_a_specific_worker = 1;
  801. }
  802. }
  803. else if (arg_type == STARPU_WORKER_ORDER)
  804. {
  805. arg_i++;
  806. unsigned order = *(unsigned *)arglist[arg_i];
  807. if (order != 0)
  808. {
  809. STARPU_ASSERT_MSG(task->execute_on_a_specific_worker, "worker order only makes sense if a workerid is provided");
  810. task->workerorder = order;
  811. }
  812. }
  813. else if (arg_type == STARPU_SCHED_CTX)
  814. {
  815. arg_i++;
  816. task->sched_ctx = *(unsigned *)arglist[arg_i];
  817. }
  818. else if (arg_type == STARPU_HYPERVISOR_TAG)
  819. {
  820. arg_i++;
  821. task->hypervisor_tag = *(int *)arglist[arg_i];
  822. }
  823. else if (arg_type == STARPU_POSSIBLY_PARALLEL)
  824. {
  825. arg_i++;
  826. task->possibly_parallel = *(unsigned *)arglist[arg_i];
  827. }
  828. else if (arg_type == STARPU_FLOPS)
  829. {
  830. arg_i++;
  831. task->flops = *(double *)arglist[arg_i];
  832. }
  833. else if (arg_type == STARPU_TAG)
  834. {
  835. arg_i++;
  836. task->tag_id = *(starpu_tag_t *)arglist[arg_i];
  837. task->use_tag = 1;
  838. }
  839. else if (arg_type == STARPU_TAG_ONLY)
  840. {
  841. arg_i++;
  842. task->tag_id = *(starpu_tag_t *)arglist[arg_i];
  843. }
  844. else if (arg_type == STARPU_NAME)
  845. {
  846. arg_i++;
  847. task->name = arglist[arg_i];
  848. }
  849. else if (arg_type == STARPU_NODE_SELECTION_POLICY)
  850. {
  851. arg_i++;
  852. (void)arglist[arg_i];
  853. }
  854. else if (arg_type == STARPU_TASK_COLOR)
  855. {
  856. arg_i++;
  857. task->color = *(int *)arglist[arg_i];
  858. }
  859. else if (arg_type == STARPU_TASK_SYNCHRONOUS)
  860. {
  861. arg_i++;
  862. task->synchronous = *(int *)arglist[arg_i];
  863. }
  864. else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
  865. {
  866. task->handles_sequential_consistency = (unsigned char *)arglist[arg_i];
  867. }
  868. else if (arg_type==STARPU_TASK_END_DEP)
  869. {
  870. arg_i++;
  871. starpu_task_end_dep_add(task, *(int*)arglist[arg_i]);
  872. }
  873. else if (arg_type==STARPU_TASK_WORKERIDS)
  874. {
  875. arg_i++;
  876. task->workerids_len = *(unsigned *)arglist[arg_i];
  877. arg_i++;
  878. task->workerids = (uint32_t *)arglist[arg_i];
  879. }
  880. else if (arg_type==STARPU_SEQUENTIAL_CONSISTENCY)
  881. {
  882. arg_i++;
  883. task->sequential_consistency = *(unsigned *)arglist[arg_i];
  884. }
  885. else if (arg_type==STARPU_TASK_PROFILING_INFO)
  886. {
  887. arg_i++;
  888. task->profiling_info = (struct starpu_profiling_task_info *)arglist[arg_i];
  889. }
  890. else if (arg_type==STARPU_TASK_NO_SUBMITORDER)
  891. {
  892. arg_i++;
  893. task->no_submitorder = *(unsigned *)arglist[arg_i];
  894. }
  895. else if (arg_type == STARPU_TASK_SCHED_DATA)
  896. {
  897. arg_i++;
  898. task->sched_data = (void*)arglist[arg_i];
  899. }
  900. else
  901. {
  902. STARPU_ABORT_MSG("unknown/unsupported argument %d, did you perhaps forget to end arguments with 0?", arg_type);
  903. }
  904. arg_i++;
  905. }
  906. if (cl)
  907. {
  908. if (cl->nbuffers == STARPU_VARIABLE_NBUFFERS)
  909. {
  910. task->nbuffers = current_buffer;
  911. }
  912. else
  913. {
  914. STARPU_ASSERT_MSG(current_buffer == cl->nbuffers, "Incoherent number of buffers between cl (%d) and number of parameters (%d)", cl->nbuffers, current_buffer);
  915. }
  916. }
  917. if (state.nargs)
  918. {
  919. if (task->cl_arg != NULL)
  920. {
  921. _STARPU_DISP("Parameters STARPU_CL_ARGS and STARPU_VALUE cannot be used in the same call\n");
  922. free(state.arg_buffer);
  923. return -EINVAL;
  924. }
  925. starpu_codelet_pack_arg_fini(&state, &task->cl_arg, &task->cl_arg_size);
  926. }
  927. if (task_deps_array)
  928. {
  929. starpu_task_declare_deps_array(task, ndeps, task_deps_array);
  930. }
  931. if (task_end_deps_array)
  932. {
  933. starpu_task_declare_end_deps_array(task, nend_deps, task_end_deps_array);
  934. }
  935. _STARPU_TRACE_TASK_BUILD_END();
  936. return 0;
  937. }
  938. /* Fortran interface to task_insert */
  939. void fstarpu_task_insert(void **arglist)
  940. {
  941. struct starpu_codelet *cl = arglist[0];
  942. if (cl == NULL)
  943. {
  944. STARPU_ABORT_MSG("task without codelet");
  945. }
  946. struct starpu_task *task = starpu_task_create();
  947. int ret = _fstarpu_task_insert_create(cl, task, arglist+1);
  948. if (ret != 0)
  949. {
  950. STARPU_ABORT_MSG("task creation failed");
  951. }
  952. ret = starpu_task_submit(task);
  953. if (ret != 0)
  954. {
  955. STARPU_ABORT_MSG("starpu_task_submit failed");
  956. }
  957. }
  958. /* fstarpu_insert_task: aliased to fstarpu_task_insert in fstarpu_mod.f90 */