starpu_sched_component.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2013-2020 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
  4. * Copyright (C) 2013 Simon Archipoff
  5. * Copyright (C) 2017 Arthur Chevalier
  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. #ifndef __STARPU_SCHED_COMPONENT_H__
  19. #define __STARPU_SCHED_COMPONENT_H__
  20. #include <starpu.h>
  21. #ifdef STARPU_HAVE_HWLOC
  22. #include <hwloc.h>
  23. #endif
  24. #ifdef __cplusplus
  25. extern "C"
  26. {
  27. #endif
  28. /**
  29. @defgroup API_Modularized_Scheduler Modularized Scheduler Interface
  30. @{
  31. */
  32. /**
  33. flags for starpu_sched_component::properties
  34. */
  35. enum starpu_sched_component_properties
  36. {
  37. /** indicate that all workers have the same starpu_worker_archtype */
  38. STARPU_SCHED_COMPONENT_HOMOGENEOUS = (1<<0),
  39. /** indicate that all workers have the same memory component */
  40. STARPU_SCHED_COMPONENT_SINGLE_MEMORY_NODE = (1<<1)
  41. };
  42. /**
  43. indicate if component is homogeneous
  44. */
  45. #define STARPU_SCHED_COMPONENT_IS_HOMOGENEOUS(component) ((component)->properties & STARPU_SCHED_COMPONENT_HOMOGENEOUS)
  46. /**
  47. indicate if all workers have the same memory component
  48. */
  49. #define STARPU_SCHED_COMPONENT_IS_SINGLE_MEMORY_NODE(component) ((component)->properties & STARPU_SCHED_COMPONENT_SINGLE_MEMORY_NODE)
  50. /**
  51. Structure for a scheduler module. A scheduler is a
  52. tree-like structure of them, some parts of scheduler can be shared by
  53. several contexes to perform some local optimisations, so, for all
  54. components, a list of parent is defined by \c sched_ctx_id. They
  55. embed there specialised method in a pseudo object-style, so calls are
  56. like <c>component->push_task(component,task)</c>
  57. */
  58. struct starpu_sched_component
  59. {
  60. /** The tree containing the component*/
  61. struct starpu_sched_tree *tree;
  62. /** set of underlying workers */
  63. struct starpu_bitmap workers;
  64. /**
  65. subset of starpu_sched_component::workers that is currently available in the context
  66. The push method should take this value into account, it is set with:
  67. component->workers UNION tree->workers UNION
  68. component->child[i]->workers_in_ctx iff exist x such as component->children[i]->parents[x] == component
  69. */
  70. struct starpu_bitmap workers_in_ctx;
  71. /** private data */
  72. void *data;
  73. char *name;
  74. /** number of compoments's children */
  75. unsigned nchildren;
  76. /** vector of component's children */
  77. struct starpu_sched_component **children;
  78. /** number of component's parents */
  79. unsigned nparents;
  80. /** vector of component's parents */
  81. struct starpu_sched_component **parents;
  82. /** add a child to component */
  83. void (*add_child)(struct starpu_sched_component *component, struct starpu_sched_component *child);
  84. /** remove a child from component */
  85. void (*remove_child)(struct starpu_sched_component *component, struct starpu_sched_component *child);
  86. void (*add_parent)(struct starpu_sched_component *component, struct starpu_sched_component *parent);
  87. void (*remove_parent)(struct starpu_sched_component *component, struct starpu_sched_component *parent);
  88. /**
  89. push a task in the scheduler module. this function is called to
  90. push a task on component subtree, this can either perform a
  91. recursive call on a child or store the task in the component,
  92. then it will be returned by a further pull_task call.
  93. the caller must ensure that component is able to execute task.
  94. This method must either return 0 if it the task was properly stored or
  95. passed over to a child component, or return a value different from 0 if the
  96. task could not be consumed (e.g. the queue is full).
  97. */
  98. int (*push_task)(struct starpu_sched_component *, struct starpu_task *);
  99. /**
  100. pop a task from the scheduler module. this function is called by workers to get a task from their
  101. parents. this function should first return a locally stored task
  102. or perform a recursive call on the parents.
  103. the task returned by this function should be executable by the caller
  104. */
  105. struct starpu_task *(*pull_task)(struct starpu_sched_component *from, struct starpu_sched_component *to);
  106. /**
  107. This function is called by a component which implements a queue,
  108. allowing it to signify to its parents that an empty slot is
  109. available in its queue. This should return 1 if some tasks could be pushed
  110. The basic implementation of this function
  111. is a recursive call to its parents, the user has to specify a
  112. personally-made function to catch those calls.
  113. */
  114. int (*can_push)(struct starpu_sched_component *from, struct starpu_sched_component *to);
  115. /**
  116. This function allow a component to wake up a worker. It is
  117. currently called by component which implements a queue, to
  118. signify to its children that a task have been pushed in its local
  119. queue, and is available to be popped by a worker, for example.
  120. This should return 1 if some some container or worker could (or will) pull
  121. some tasks.
  122. The basic implementation of this function is a recursive call to
  123. its children, until at least one worker have been woken up.
  124. */
  125. int (*can_pull)(struct starpu_sched_component *component);
  126. int (*notify)(struct starpu_sched_component* component, int message_ID, void* arg);
  127. /**
  128. heuristic to compute load of scheduler module. Basically the number of tasks divided by the sum
  129. of relatives speedup of workers available in context.
  130. estimated_load(component) = sum(estimated_load(component_children)) + nb_local_tasks / average(relative_speedup(underlying_worker))
  131. */
  132. double (*estimated_load)(struct starpu_sched_component *component);
  133. /**
  134. return the time when a worker will enter in starvation. This function is relevant only if the task->predicted
  135. member has been set.
  136. */
  137. double (*estimated_end)(struct starpu_sched_component *component);
  138. /**
  139. called by starpu_sched_component_destroy. Should free data allocated during creation
  140. */
  141. void (*deinit_data)(struct starpu_sched_component *component);
  142. /**
  143. this function is called for each component when workers are added or removed from a context
  144. */
  145. void (*notify_change_workers)(struct starpu_sched_component *component);
  146. int properties;
  147. #ifdef STARPU_HAVE_HWLOC
  148. /**
  149. the hwloc object associated to scheduler module. points to the
  150. part of topology that is binded to this component, eg: a numa
  151. node for a ws component that would balance load between
  152. underlying sockets
  153. */
  154. hwloc_obj_t obj;
  155. #else
  156. void *obj;
  157. #endif
  158. };
  159. /**
  160. The actual scheduler
  161. */
  162. struct starpu_sched_tree
  163. {
  164. /**
  165. entry module of the scheduler
  166. */
  167. struct starpu_sched_component *root;
  168. /**
  169. set of workers available in this context, this value is used to mask workers in modules
  170. */
  171. struct starpu_bitmap workers;
  172. /**
  173. context id of the scheduler
  174. */
  175. unsigned sched_ctx_id;
  176. /**
  177. lock used to protect the scheduler, it is taken in read mode pushing a task and in write mode for adding or
  178. removing workers
  179. */
  180. starpu_pthread_mutex_t lock;
  181. };
  182. void starpu_initialize_prio_center_policy(unsigned sched_ctx_id);
  183. /**
  184. @name Scheduling Tree API
  185. @{
  186. */
  187. /**
  188. create a empty initialized starpu_sched_tree
  189. */
  190. struct starpu_sched_tree *starpu_sched_tree_create(unsigned sched_ctx_id) STARPU_ATTRIBUTE_MALLOC;
  191. /**
  192. destroy tree and free all non shared component in it.
  193. */
  194. void starpu_sched_tree_destroy(struct starpu_sched_tree *tree);
  195. struct starpu_sched_tree *starpu_sched_tree_get(unsigned sched_ctx_id);
  196. /**
  197. recursively set all starpu_sched_component::workers, do not take into account shared parts (except workers).
  198. */
  199. void starpu_sched_tree_update_workers(struct starpu_sched_tree *t);
  200. /**
  201. recursively set all starpu_sched_component::workers_in_ctx, do not take into account shared parts (except workers)
  202. */
  203. void starpu_sched_tree_update_workers_in_ctx(struct starpu_sched_tree *t);
  204. /**
  205. compatibility with starpu_sched_policy interface
  206. */
  207. int starpu_sched_tree_push_task(struct starpu_task *task);
  208. /**
  209. compatibility with starpu_sched_policy interface
  210. */
  211. struct starpu_task *starpu_sched_tree_pop_task(unsigned sched_ctx);
  212. /**
  213. Push a task to a component. This is a helper for <c>component->push_task(component, task)</c> plus tracing.
  214. */
  215. int starpu_sched_component_push_task(struct starpu_sched_component *from, struct starpu_sched_component *to, struct starpu_task *task);
  216. /**
  217. Pull a task from a component. This is a helper for <c>component->pull_task(component)</c> plus tracing.
  218. */
  219. struct starpu_task *starpu_sched_component_pull_task(struct starpu_sched_component *from, struct starpu_sched_component *to);
  220. struct starpu_task* starpu_sched_component_pump_to(struct starpu_sched_component *component, struct starpu_sched_component *to, int* success);
  221. struct starpu_task* starpu_sched_component_pump_downstream(struct starpu_sched_component *component, int* success);
  222. int starpu_sched_component_send_can_push_to_parents(struct starpu_sched_component * component);
  223. /**
  224. compatibility with starpu_sched_policy interface
  225. */
  226. void starpu_sched_tree_add_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
  227. /**
  228. compatibility with starpu_sched_policy interface
  229. */
  230. void starpu_sched_tree_remove_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
  231. /**
  232. Attach component \p child to parent \p parent. Some component may accept only one child, others accept several (e.g. MCT)
  233. */
  234. void starpu_sched_component_connect(struct starpu_sched_component *parent, struct starpu_sched_component *child);
  235. /** @} */
  236. /**
  237. @name Generic Scheduling Component API
  238. @{
  239. */
  240. typedef struct starpu_sched_component * (*starpu_sched_component_create_t)(struct starpu_sched_tree *tree, void *data);
  241. /**
  242. allocate and initialize component field with defaults values :
  243. .pop_task make recursive call on father
  244. .estimated_load compute relative speedup and tasks in sub tree
  245. .estimated_end return the minimum of recursive call on children
  246. .add_child is starpu_sched_component_add_child
  247. .remove_child is starpu_sched_component_remove_child
  248. .notify_change_workers does nothing
  249. .deinit_data does nothing
  250. */
  251. struct starpu_sched_component *starpu_sched_component_create(struct starpu_sched_tree *tree, const char *name) STARPU_ATTRIBUTE_MALLOC;
  252. /**
  253. free data allocated by starpu_sched_component_create and call component->deinit_data(component)
  254. set to <c>NULL</c> the member starpu_sched_component::fathers[sched_ctx_id] of all child if its equal to \p component
  255. */
  256. void starpu_sched_component_destroy(struct starpu_sched_component *component);
  257. /**
  258. recursively destroy non shared parts of a \p component 's tree
  259. */
  260. void starpu_sched_component_destroy_rec(struct starpu_sched_component *component);
  261. void starpu_sched_component_add_child(struct starpu_sched_component* component, struct starpu_sched_component * child);
  262. /**
  263. return true iff \p component can execute \p task, this function take into account the workers available in the scheduling context
  264. */
  265. int starpu_sched_component_can_execute_task(struct starpu_sched_component *component, struct starpu_task *task);
  266. /**
  267. return a non <c>NULL</c> value if \p component can execute \p task.
  268. write the execution prediction length for the best implementation of the best worker available and write this at \p length address.
  269. this result is more relevant if starpu_sched_component::is_homogeneous is non <c>NULL</c>.
  270. if a worker need to be calibrated for an implementation, nan is set to \p length.
  271. */
  272. int STARPU_WARN_UNUSED_RESULT starpu_sched_component_execute_preds(struct starpu_sched_component *component, struct starpu_task *task, double *length);
  273. /**
  274. return the average time to transfer \p task data to underlying \p component workers.
  275. */
  276. double starpu_sched_component_transfer_length(struct starpu_sched_component *component, struct starpu_task *task);
  277. void starpu_sched_component_prefetch_on_node(struct starpu_sched_component *component, struct starpu_task *task);
  278. /** @} */
  279. /**
  280. @name Worker Component API
  281. @{
  282. */
  283. /**
  284. return the struct starpu_sched_component corresponding to \p workerid. Undefined if \p workerid is not a valid workerid
  285. */
  286. struct starpu_sched_component *starpu_sched_component_worker_get(unsigned sched_ctx, int workerid);
  287. struct starpu_sched_component *starpu_sched_component_worker_new(unsigned sched_ctx, int workerid);
  288. /**
  289. Create a combined worker that pushes tasks in parallel to workers \p workers (size \p nworkers).
  290. */
  291. struct starpu_sched_component *starpu_sched_component_parallel_worker_create(struct starpu_sched_tree *tree, unsigned nworkers, unsigned *workers);
  292. /**
  293. return the workerid of \p worker_component, undefined if starpu_sched_component_is_worker(worker_component) == 0
  294. */
  295. int starpu_sched_component_worker_get_workerid(struct starpu_sched_component *worker_component);
  296. /**
  297. return true iff \p component is a worker component
  298. */
  299. int starpu_sched_component_is_worker(struct starpu_sched_component *component);
  300. /**
  301. return true iff \p component is a simple worker component
  302. */
  303. int starpu_sched_component_is_simple_worker(struct starpu_sched_component *component);
  304. /**
  305. return true iff \p component is a combined worker component
  306. */
  307. int starpu_sched_component_is_combined_worker(struct starpu_sched_component *component);
  308. /**
  309. compatibility with starpu_sched_policy interface
  310. update predictions for workers
  311. */
  312. void starpu_sched_component_worker_pre_exec_hook(struct starpu_task *task, unsigned sched_ctx_id);
  313. /**
  314. compatibility with starpu_sched_policy interface
  315. */
  316. void starpu_sched_component_worker_post_exec_hook(struct starpu_task *task, unsigned sched_ctx_id);
  317. /** @} */
  318. /**
  319. @name Flow-control Fifo Component API
  320. @{
  321. */
  322. /**
  323. default function for the pull component method, just call pull of parents until one of them returns a task
  324. */
  325. struct starpu_task * starpu_sched_component_parents_pull_task(struct starpu_sched_component * component, struct starpu_sched_component * to);
  326. /**
  327. default function for the can_push component method, just call can_push of parents until one of them returns non-zero
  328. */
  329. int starpu_sched_component_can_push(struct starpu_sched_component * component, struct starpu_sched_component * to);
  330. /**
  331. default function for the can_pull component method, just call can_pull of children until one of them returns non-zero
  332. */
  333. int starpu_sched_component_can_pull(struct starpu_sched_component * component);
  334. /**
  335. function for the can_pull component method, call can_pull of all children
  336. */
  337. int starpu_sched_component_can_pull_all(struct starpu_sched_component * component);
  338. /**
  339. default function for the estimated_load component method, just sum up the loads
  340. of the children of the component.
  341. */
  342. double starpu_sched_component_estimated_load(struct starpu_sched_component * component);
  343. /**
  344. function that can be used for the estimated_end component method, compute the minimum completion time of the children.
  345. */
  346. double starpu_sched_component_estimated_end_min(struct starpu_sched_component * component);
  347. /**
  348. function that can be used for the estimated_end component method, compute
  349. the minimum completion time of the children, and add to it an estimation of how
  350. existing queued work, plus the exp_len work, can be completed. This is typically
  351. used instead of starpu_sched_component_estimated_end_min when the component
  352. contains a queue of tasks, which thus needs to be added to the estimations.
  353. */
  354. double starpu_sched_component_estimated_end_min_add(struct starpu_sched_component * component, double exp_len);
  355. /**
  356. default function for the estimated_end component method, compute the average completion time of the children.
  357. */
  358. double starpu_sched_component_estimated_end_average(struct starpu_sched_component * component);
  359. struct starpu_sched_component_fifo_data
  360. {
  361. unsigned ntasks_threshold;
  362. double exp_len_threshold;
  363. int ready;
  364. int exp;
  365. };
  366. /**
  367. Return a struct starpu_sched_component with a fifo. A stable sort is performed according to tasks priorities.
  368. A push_task call on this component does not perform recursive calls, underlying components will have to call pop_task to get it.
  369. starpu_sched_component::estimated_end function compute the estimated length by dividing the sequential length by the number of underlying workers.
  370. */
  371. struct starpu_sched_component *starpu_sched_component_fifo_create(struct starpu_sched_tree *tree, struct starpu_sched_component_fifo_data *fifo_data) STARPU_ATTRIBUTE_MALLOC;
  372. /**
  373. return true iff \p component is a fifo component
  374. */
  375. int starpu_sched_component_is_fifo(struct starpu_sched_component *component);
  376. /** @} */
  377. /**
  378. @name Flow-control Prio Component API
  379. @{
  380. */
  381. struct starpu_sched_component_prio_data
  382. {
  383. unsigned ntasks_threshold;
  384. double exp_len_threshold;
  385. int ready;
  386. int exp;
  387. };
  388. struct starpu_sched_component *starpu_sched_component_prio_create(struct starpu_sched_tree *tree, struct starpu_sched_component_prio_data *prio_data) STARPU_ATTRIBUTE_MALLOC;
  389. int starpu_sched_component_is_prio(struct starpu_sched_component *component);
  390. /** @} */
  391. /**
  392. @name Resource-mapping Work-Stealing Component API
  393. @{
  394. */
  395. /**
  396. return a component that perform a work stealing scheduling. Tasks are pushed in a round robin way. estimated_end return the average of expected length of fifos, starting at the average of the expected_end of his children. When a worker have to steal a task, it steal a task in a round robin way, and get the last pushed task of the higher priority.
  397. */
  398. struct starpu_sched_component *starpu_sched_component_work_stealing_create(struct starpu_sched_tree *tree, void *arg) STARPU_ATTRIBUTE_MALLOC;
  399. /**
  400. return true iff \p component is a work stealing component
  401. */
  402. int starpu_sched_component_is_work_stealing(struct starpu_sched_component *component);
  403. /**
  404. undefined if there is no work stealing component in the scheduler. If any, \p task is pushed in a default way if the caller is the application, and in the caller's fifo if its a worker.
  405. */
  406. int starpu_sched_tree_work_stealing_push_task(struct starpu_task *task);
  407. /** @} */
  408. /**
  409. @name Resource-mapping Random Component API
  410. @{
  411. */
  412. /**
  413. create a component that perform a random scheduling
  414. */
  415. struct starpu_sched_component *starpu_sched_component_random_create(struct starpu_sched_tree *tree, void *arg) STARPU_ATTRIBUTE_MALLOC;
  416. /**
  417. return true iff \p component is a random component
  418. */
  419. int starpu_sched_component_is_random(struct starpu_sched_component *);
  420. /** @} */
  421. /**
  422. @name Resource-mapping Eager Component API
  423. @{
  424. */
  425. struct starpu_sched_component *starpu_sched_component_eager_create(struct starpu_sched_tree *tree, void *arg) STARPU_ATTRIBUTE_MALLOC;
  426. int starpu_sched_component_is_eager(struct starpu_sched_component *);
  427. /** @} */
  428. /**
  429. @name Resource-mapping Eager Prio Component API
  430. @{
  431. */
  432. struct starpu_sched_component *starpu_sched_component_eager_prio_create(struct starpu_sched_tree *tree, void *arg) STARPU_ATTRIBUTE_MALLOC;
  433. int starpu_sched_component_is_eager_prio(struct starpu_sched_component *);
  434. /** @} */
  435. /**
  436. @name Resource-mapping Eager-Calibration Component API
  437. @{
  438. */
  439. struct starpu_sched_component *starpu_sched_component_eager_calibration_create(struct starpu_sched_tree *tree, void *arg) STARPU_ATTRIBUTE_MALLOC;
  440. int starpu_sched_component_is_eager_calibration(struct starpu_sched_component *);
  441. /** @} */
  442. /**
  443. @name Resource-mapping MCT Component API
  444. @{
  445. */
  446. struct starpu_sched_component_mct_data
  447. {
  448. double alpha;
  449. double beta;
  450. double _gamma;
  451. double idle_power;
  452. };
  453. /**
  454. create a component with mct_data paremeters. the mct component doesnt
  455. do anything but pushing tasks on no_perf_model_component and
  456. calibrating_component
  457. */
  458. struct starpu_sched_component *starpu_sched_component_mct_create(struct starpu_sched_tree *tree, struct starpu_sched_component_mct_data *mct_data) STARPU_ATTRIBUTE_MALLOC;
  459. int starpu_sched_component_is_mct(struct starpu_sched_component *component);
  460. /** @} */
  461. /**
  462. @name Resource-mapping Heft Component API
  463. @{
  464. */
  465. struct starpu_sched_component *starpu_sched_component_heft_create(struct starpu_sched_tree *tree, struct starpu_sched_component_mct_data *mct_data) STARPU_ATTRIBUTE_MALLOC;
  466. int starpu_sched_component_is_heft(struct starpu_sched_component *component);
  467. /** @} */
  468. /**
  469. @name Resource-mapping Heteroprio Component API
  470. @{
  471. */
  472. struct starpu_sched_component_heteroprio_data
  473. {
  474. struct starpu_sched_component_mct_data *mct;
  475. unsigned batch;
  476. };
  477. struct starpu_sched_component * starpu_sched_component_heteroprio_create(struct starpu_sched_tree *tree, struct starpu_sched_component_heteroprio_data * params) STARPU_ATTRIBUTE_MALLOC;
  478. int starpu_sched_component_is_heteroprio(struct starpu_sched_component *component);
  479. /** @} */
  480. /**
  481. @name Special-purpose Best_Implementation Component API
  482. @{
  483. */
  484. /**
  485. Select the implementation that offer the shortest computation length for the first worker that can execute the task.
  486. Or an implementation that need to be calibrated.
  487. Also set starpu_task::predicted and starpu_task::predicted_transfer for memory component of the first suitable workerid.
  488. If starpu_sched_component::push method is called and starpu_sched_component::nchild > 1 the result is undefined.
  489. */
  490. struct starpu_sched_component *starpu_sched_component_best_implementation_create(struct starpu_sched_tree *tree, void *arg) STARPU_ATTRIBUTE_MALLOC;
  491. /** @} */
  492. /**
  493. @name Special-purpose Perfmodel_Select Component API
  494. @{
  495. */
  496. struct starpu_sched_component_perfmodel_select_data
  497. {
  498. struct starpu_sched_component *calibrator_component;
  499. struct starpu_sched_component *no_perfmodel_component;
  500. struct starpu_sched_component *perfmodel_component;
  501. };
  502. struct starpu_sched_component *starpu_sched_component_perfmodel_select_create(struct starpu_sched_tree *tree, struct starpu_sched_component_perfmodel_select_data *perfmodel_select_data) STARPU_ATTRIBUTE_MALLOC;
  503. int starpu_sched_component_is_perfmodel_select(struct starpu_sched_component *component);
  504. /** @} */
  505. /**
  506. @name Staged pull Component API
  507. @{
  508. */
  509. struct starpu_sched_component * starpu_sched_component_stage_create(struct starpu_sched_tree *tree, void *arg) STARPU_ATTRIBUTE_MALLOC;
  510. int starpu_sched_component_is_stage(struct starpu_sched_component *component);
  511. /** @} */
  512. /**
  513. @name User-choice push Component API
  514. @{
  515. */
  516. struct starpu_sched_component * starpu_sched_component_userchoice_create(struct starpu_sched_tree *tree, void *arg) STARPU_ATTRIBUTE_MALLOC;
  517. int starpu_sched_component_is_userchoice(struct starpu_sched_component *component);
  518. /** @} */
  519. /**
  520. @name Recipe Component API
  521. @{
  522. */
  523. /**
  524. parameters for starpu_sched_component_composed_component_create
  525. */
  526. struct starpu_sched_component_composed_recipe;
  527. /**
  528. return an empty recipe for a composed component, it should not be used without modification
  529. */
  530. struct starpu_sched_component_composed_recipe *starpu_sched_component_composed_recipe_create(void) STARPU_ATTRIBUTE_MALLOC;
  531. /**
  532. return a recipe to build a composed component with a \p create_component
  533. */
  534. struct starpu_sched_component_composed_recipe *starpu_sched_component_composed_recipe_create_singleton(struct starpu_sched_component *(*create_component)(struct starpu_sched_tree *tree, void *arg), void *arg) STARPU_ATTRIBUTE_MALLOC;
  535. /**
  536. add \p create_component under all previous components in recipe
  537. */
  538. void starpu_sched_component_composed_recipe_add(struct starpu_sched_component_composed_recipe *recipe, struct starpu_sched_component *(*create_component)(struct starpu_sched_tree *tree, void *arg), void *arg);
  539. /**
  540. destroy composed_sched_component, this should be done after starpu_sched_component_composed_component_create was called
  541. */
  542. void starpu_sched_component_composed_recipe_destroy(struct starpu_sched_component_composed_recipe *);
  543. /**
  544. create a component that behave as all component of recipe where linked. Except that you cant use starpu_sched_component_is_foo function
  545. if recipe contain a single create_foo arg_foo pair, create_foo(arg_foo) is returned instead of a composed component
  546. */
  547. struct starpu_sched_component *starpu_sched_component_composed_component_create(struct starpu_sched_tree *tree, struct starpu_sched_component_composed_recipe *recipe) STARPU_ATTRIBUTE_MALLOC;
  548. #ifdef STARPU_HAVE_HWLOC
  549. /**
  550. Define how build a scheduler according to topology. Each level (except for hwloc_machine_composed_sched_component) can be <c>NULL</c>, then
  551. the level is just skipped. Bugs everywhere, do not rely on.
  552. */
  553. struct starpu_sched_component_specs
  554. {
  555. /**
  556. the composed component to put on the top of the scheduler
  557. this member must not be <c>NULL</c> as it is the root of the topology
  558. */
  559. struct starpu_sched_component_composed_recipe *hwloc_machine_composed_sched_component;
  560. /**
  561. the composed component to put for each memory component
  562. */
  563. struct starpu_sched_component_composed_recipe *hwloc_component_composed_sched_component;
  564. /**
  565. the composed component to put for each socket
  566. */
  567. struct starpu_sched_component_composed_recipe *hwloc_socket_composed_sched_component;
  568. /**
  569. the composed component to put for each cache
  570. */
  571. struct starpu_sched_component_composed_recipe *hwloc_cache_composed_sched_component;
  572. /**
  573. a function that return a starpu_sched_component_composed_recipe to put on top of a worker of type \p archtype.
  574. <c>NULL</c> is a valid return value, then no component will be added on top
  575. */
  576. struct starpu_sched_component_composed_recipe *(*worker_composed_sched_component)(enum starpu_worker_archtype archtype);
  577. /**
  578. this flag is a dirty hack because of the poor expressivity of this interface. As example, if you want to build
  579. a heft component with a fifo component per numa component, and you also have GPUs, if this flag is set, GPUs will share those fifos.
  580. If this flag is not set, a new fifo will be built for each of them (if they have the same starpu_perf_arch and the same
  581. numa component it will be shared. it indicates if heterogenous workers should be brothers or cousins, as example, if a gpu and a cpu should share or not there numa node
  582. */
  583. int mix_heterogeneous_workers;
  584. };
  585. /**
  586. build a scheduler for \p sched_ctx_id according to \p s and the hwloc topology of the machine.
  587. */
  588. struct starpu_sched_tree *starpu_sched_component_make_scheduler(unsigned sched_ctx_id, struct starpu_sched_component_specs s);
  589. #endif /* STARPU_HAVE_HWLOC */
  590. /**
  591. @name Basic API
  592. @{
  593. */
  594. #define STARPU_SCHED_SIMPLE_DECIDE_MASK (3<<0)
  595. /**
  596. Request to create downstream queues per worker, i.e. the scheduling decision-making component will choose exactly which workers tasks should got to.
  597. */
  598. #define STARPU_SCHED_SIMPLE_DECIDE_WORKERS (1<<0)
  599. /**
  600. Request to create downstream queues per memory nodes, i.e. the scheduling decision-making component will choose which memory node tasks will go to.
  601. */
  602. #define STARPU_SCHED_SIMPLE_DECIDE_MEMNODES (2<<0)
  603. /**
  604. Request to create downstream queues per computation arch, i.e. the scheduling decision-making component will choose whether tasks go to CPUs, or CUDA, or OpenCL, etc.
  605. */
  606. #define STARPU_SCHED_SIMPLE_DECIDE_ARCHS (3<<0)
  607. /**
  608. Request to create the scheduling decision-making component even if there is only one available choice. This is useful for instance when the decision-making component will store tasks itself (and not use STARPU_SCHED_SIMPLE_FIFO_ABOVE) to decide in which order tasks should be passed below.
  609. */
  610. #define STARPU_SCHED_SIMPLE_DECIDE_ALWAYS (1<<3)
  611. /**
  612. Request to add a perfmodel selector above the scheduling decision-making component. That way, only tasks with a calibrated performance model will be given to the component, other tasks will go to an eager branch that will distributed tasks so that their performance models will get calibrated.
  613. In other words, this is needed when using a component which needs performance models for tasks.
  614. */
  615. #define STARPU_SCHED_SIMPLE_PERFMODEL (1<<4)
  616. /**
  617. Request that a component be added just above workers, that chooses the best task implementation.
  618. */
  619. #define STARPU_SCHED_SIMPLE_IMPL (1<<5)
  620. /**
  621. Request to create a fifo above the scheduling decision-making component, otherwise tasks will be pushed directly to the component.
  622. This is useful to store tasks if there is a fifo below which limits the number of tasks to be scheduld in advance. The scheduling decision-making component can also store tasks itself, in which case this flag is not useful.
  623. */
  624. #define STARPU_SCHED_SIMPLE_FIFO_ABOVE (1<<6)
  625. /**
  626. Request that the fifo above be sorted by priorities
  627. */
  628. #define STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO (1<<7)
  629. /**
  630. Request to create fifos below the scheduling decision-making component, otherwise tasks will be pulled directly from workers.
  631. This is useful to be able to schedule a (tunable) small number of tasks in advance only.
  632. */
  633. #define STARPU_SCHED_SIMPLE_FIFOS_BELOW (1<<8)
  634. /**
  635. Request that the fifos below be sorted by priorities
  636. */
  637. #define STARPU_SCHED_SIMPLE_FIFOS_BELOW_PRIO (1<<9)
  638. /**
  639. Request that the fifos below be pulled rather ready tasks
  640. */
  641. #define STARPU_SCHED_SIMPLE_FIFOS_BELOW_READY (1<<10)
  642. /**
  643. Request that work between workers using the same fifo below be distributed using a work stealing component.
  644. */
  645. #define STARPU_SCHED_SIMPLE_WS_BELOW (1<<11)
  646. /**
  647. Request to not only choose between simple workers, but also choose between combined workers.
  648. */
  649. #define STARPU_SCHED_SIMPLE_COMBINED_WORKERS (1<<12)
  650. /**
  651. Request that the fifos below keep track of expected duration, start and end time of theirs elements
  652. */
  653. #define STARPU_SCHED_SIMPLE_FIFOS_BELOW_EXP (1<<13)
  654. /**
  655. Create a simple modular scheduler tree around a scheduling decision-making
  656. component \p component. The details of what should be built around \p component
  657. is described by \p flags. The different STARPU_SCHED_SIMPL_DECIDE_* flags are
  658. mutually exclusive. \p data is passed to the \p create_decision_component
  659. function when creating the decision component.
  660. */
  661. void starpu_sched_component_initialize_simple_scheduler(starpu_sched_component_create_t create_decision_component, void *data, unsigned flags, unsigned sched_ctx_id);
  662. /**
  663. Create a simple modular scheduler tree around several scheduling decision-making
  664. components. The parameters are similar to
  665. starpu_sched_component_initialize_simple_scheduler, but per scheduling decision, for instance:
  666. starpu_sched_component_initialize_simple_schedulers(sched_ctx_id, 2,
  667. create1, data1, flags1,
  668. create2, data2, flags2);
  669. The different flags parameters must be coherent: same decision flags. They
  670. must not include the perfmodel flag (not supported yet).
  671. */
  672. void starpu_sched_component_initialize_simple_schedulers(unsigned sched_ctx_id, unsigned ndecisions, ...);
  673. /** @} */
  674. #define STARPU_COMPONENT_MUTEX_LOCK(m) \
  675. do \
  676. { \
  677. const int _relaxed_state = starpu_worker_get_relax_state(); \
  678. if (!_relaxed_state) \
  679. starpu_worker_relax_on(); \
  680. STARPU_PTHREAD_MUTEX_LOCK((m)); \
  681. if (!_relaxed_state) \
  682. starpu_worker_relax_off(); \
  683. } \
  684. while(0)
  685. #define STARPU_COMPONENT_MUTEX_TRYLOCK(m) STARPU_PTHREAD_MUTEX_TRYLOCK((m))
  686. #define STARPU_COMPONENT_MUTEX_UNLOCK(m) STARPU_PTHREAD_MUTEX_UNLOCK((m))
  687. /** @} */
  688. #ifdef __cplusplus
  689. }
  690. #endif
  691. #endif /* __STARPU_SCHED_COMPONENT_H__ */