starpu_task_insert_utils.c 27 KB

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