starpu_task_insert_utils.c 28 KB

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