starpu_task_insert_utils.c 23 KB

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