starpu_scheduler.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2010-2021 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
  4. * Copyright (C) 2011 Télécom-SudParis
  5. * Copyright (C) 2013 Thibaut Lambert
  6. * Copyright (C) 2016 Uppsala University
  7. *
  8. * StarPU is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU Lesser General Public License as published by
  10. * the Free Software Foundation; either version 2.1 of the License, or (at
  11. * your option) any later version.
  12. *
  13. * StarPU is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16. *
  17. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  18. */
  19. #ifndef __STARPU_SCHEDULER_H__
  20. #define __STARPU_SCHEDULER_H__
  21. #include <starpu.h>
  22. #ifdef __cplusplus
  23. extern "C"
  24. {
  25. #endif
  26. /**
  27. @defgroup API_Scheduling_Policy Scheduling Policy
  28. @brief TODO. While StarPU comes with a variety of scheduling
  29. policies (see \ref TaskSchedulingPolicy), it may sometimes be
  30. desirable to implement custom policies to address specific
  31. problems. The API described below allows users to write their own
  32. scheduling policy.
  33. @{
  34. */
  35. struct starpu_task;
  36. /**
  37. Contain all the methods that implement a scheduling policy. An
  38. application may specify which scheduling strategy in the field
  39. starpu_conf::sched_policy passed to the function starpu_init().
  40. For each task going through the scheduler, the following methods
  41. get called in the given order:
  42. <ul>
  43. <li>starpu_sched_policy::submit_hook when the task is
  44. submitted</li>
  45. <li>starpu_sched_policy::push_task when the task becomes ready. The
  46. scheduler is here <b>given</b> the task</li>
  47. <li>starpu_sched_policy::pop_task when the worker is idle. The
  48. scheduler here <b>gives</b> back the task to the core. It must not
  49. access this task any more</li>
  50. <li>starpu_sched_policy::pre_exec_hook right before the worker
  51. actually starts the task computation (after transferring any
  52. missing data).</li>
  53. <li>starpu_sched_policy::post_exec_hook right after the worker
  54. actually completes the task computation.</li>
  55. </ul>
  56. For each task not going through the scheduler (because
  57. starpu_task::execute_on_a_specific_worker was set), these get
  58. called:
  59. <ul>
  60. <li>starpu_sched_policy::submit_hook when the task is
  61. submitted</li>
  62. <li>starpu_sched_policy::push_task_notify when the task becomes
  63. ready. This is just a notification, the scheduler does not have to
  64. do anything about the task.</li>
  65. <li>starpu_sched_policy::pre_exec_hook right before the worker
  66. actually starts the task computation (after transferring any
  67. missing data).</li>
  68. <li>starpu_sched_policy::post_exec_hook right after the worker
  69. actually completes the task computation.</li>
  70. </ul>
  71. */
  72. struct starpu_sched_policy
  73. {
  74. /**
  75. Initialize the scheduling policy, called before any other
  76. method.
  77. */
  78. void (*init_sched)(unsigned sched_ctx_id);
  79. /**
  80. Cleanup the scheduling policy
  81. */
  82. void (*deinit_sched)(unsigned sched_ctx_id);
  83. /**
  84. Insert a task into the scheduler, called when the task
  85. becomes ready for execution. This must call
  86. starpu_push_task_end() once it has effectively pushed the
  87. task to a queue (to note the time when this was done in the
  88. task), but before releasing mutexes (so that the task
  89. hasn't been already taken by a worker).
  90. */
  91. int (*push_task)(struct starpu_task *);
  92. double (*simulate_push_task)(struct starpu_task *);
  93. /**
  94. Notify the scheduler that a task was pushed on a given
  95. worker. This method is called when a task that was
  96. explicitly assigned to a worker becomes ready and is about
  97. to be executed by the worker. This method therefore permits
  98. to keep the state of the scheduler coherent even when
  99. StarPU bypasses the scheduling strategy.
  100. Note: to get an estimation of the task duration, \p perf_workerid
  101. needs to be used rather than \p workerid, for the case of parallel
  102. tasks.
  103. */
  104. void (*push_task_notify)(struct starpu_task *, int workerid, int perf_workerid, unsigned sched_ctx_id);
  105. /**
  106. Get a task from the scheduler.
  107. If this method returns NULL, the worker will start
  108. sleeping. If later on some task are pushed for this worker,
  109. starpu_wake_worker() must be called to wake the worker so
  110. it can call the pop_task() method again.
  111. The mutex associated to the worker is already taken when
  112. this method is called. This method may release it (e.g. for
  113. scalability reasons when doing work stealing), but it must
  114. acquire it again before taking the decision whether to
  115. return a task or NULL, so the atomicity of deciding to
  116. return NULL and making the worker actually sleep is
  117. preserved. Otherwise in simgrid or blocking driver mode the
  118. worker might start sleeping while a task has just been
  119. pushed for it.
  120. If this method is defined as <c>NULL</c>, the worker will
  121. only execute tasks from its local queue. In this case, the
  122. push_task method should use the starpu_push_local_task
  123. method to assign tasks to the different workers.
  124. */
  125. struct starpu_task *(*pop_task)(unsigned sched_ctx_id);
  126. /**
  127. Remove all available tasks from the scheduler (tasks are
  128. chained by the means of the field starpu_task::prev and
  129. starpu_task::next). The mutex associated to the worker is
  130. already taken when this method is called. This is currently
  131. not used and can be discarded.
  132. */
  133. struct starpu_task *(*pop_every_task)(unsigned sched_ctx_id);
  134. /**
  135. Optional field. This method is called when a task is
  136. submitted.
  137. */
  138. void (*submit_hook)(struct starpu_task *task);
  139. /**
  140. Optional field. This method is called every time a task is
  141. starting.
  142. */
  143. void (*pre_exec_hook)(struct starpu_task *, unsigned sched_ctx_id);
  144. /**
  145. Optional field. This method is called every time a task has
  146. been executed.
  147. */
  148. void (*post_exec_hook)(struct starpu_task *, unsigned sched_ctx_id);
  149. /**
  150. Optional field. This method is called when it is a good
  151. time to start scheduling tasks. This is notably called when
  152. the application calls starpu_task_wait_for_all() or
  153. starpu_do_schedule() explicitly.
  154. */
  155. void (*do_schedule)(unsigned sched_ctx_id);
  156. /**
  157. Initialize scheduling structures corresponding to each
  158. worker used by the policy.
  159. */
  160. void (*add_workers)(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
  161. /**
  162. Deinitialize scheduling structures corresponding to each
  163. worker used by the policy.
  164. */
  165. void (*remove_workers)(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
  166. /** Whether this scheduling policy does data prefetching, and thus the
  167. core should not try to do it opportunistically.
  168. */
  169. int prefetches;
  170. /**
  171. Optional field. Name of the policy.
  172. */
  173. const char *policy_name;
  174. /**
  175. Optional field. Human readable description of the policy.
  176. */
  177. const char *policy_description;
  178. enum starpu_worker_collection_type worker_type;
  179. };
  180. /**
  181. Return an <c>NULL</c>-terminated array of all the predefined
  182. scheduling policies.
  183. */
  184. struct starpu_sched_policy **starpu_sched_get_predefined_policies(void);
  185. /**
  186. When there is no available task for a worker, StarPU blocks this
  187. worker on a condition variable. This function specifies which
  188. condition variable (and the associated mutex) should be used to
  189. block (and to wake up) a worker. Note that multiple workers may use
  190. the same condition variable. For instance, in the case of a
  191. scheduling strategy with a single task queue, the same condition
  192. variable would be used to block and wake up all workers.
  193. */
  194. void starpu_worker_get_sched_condition(int workerid, starpu_pthread_mutex_t **sched_mutex, starpu_pthread_cond_t **sched_cond);
  195. unsigned long starpu_task_get_job_id(struct starpu_task *task);
  196. /**
  197. TODO: check if this is correct
  198. Return the current minimum priority level supported by the scheduling
  199. policy
  200. */
  201. int starpu_sched_get_min_priority(void);
  202. /**
  203. TODO: check if this is correct
  204. Return the current maximum priority level supported by the
  205. scheduling policy
  206. */
  207. int starpu_sched_get_max_priority(void);
  208. /**
  209. TODO: check if this is correct
  210. Define the minimum task priority level supported by the scheduling
  211. policy. The default minimum priority level is the same as the
  212. default priority level which is 0 by convention. The application
  213. may access that value by calling the function
  214. starpu_sched_get_min_priority(). This function should only be
  215. called from the initialization method of the scheduling policy, and
  216. should not be used directly from the application.
  217. */
  218. int starpu_sched_set_min_priority(int min_prio);
  219. /**
  220. TODO: check if this is correct
  221. Define the maximum priority level supported by the scheduling
  222. policy. The default maximum priority level is 1. The application
  223. may access that value by calling the function
  224. starpu_sched_get_max_priority(). This function should only be
  225. called from the initialization method of the scheduling policy, and
  226. should not be used directly from the application.
  227. */
  228. int starpu_sched_set_max_priority(int max_prio);
  229. /**
  230. Check if the worker specified by workerid can execute the codelet.
  231. Schedulers need to call it before assigning a task to a worker,
  232. otherwise the task may fail to execute.
  233. */
  234. int starpu_worker_can_execute_task(unsigned workerid, struct starpu_task *task, unsigned nimpl);
  235. /**
  236. Check if the worker specified by workerid can execute the codelet
  237. and return which implementation numbers can be used.
  238. Schedulers need to call it before assigning a task to a worker,
  239. otherwise the task may fail to execute.
  240. This should be preferred rather than calling
  241. starpu_worker_can_execute_task() for each and every implementation.
  242. It can also be used with <c>impl_mask == NULL</c> to check for at
  243. least one implementation without determining which.
  244. */
  245. int starpu_worker_can_execute_task_impl(unsigned workerid, struct starpu_task *task, unsigned *impl_mask);
  246. /**
  247. Check if the worker specified by workerid can execute the codelet
  248. and return the first implementation which can be used.
  249. Schedulers need to call it before assigning a task to a worker,
  250. otherwise the task may fail to execute. This should be preferred
  251. rather than calling starpu_worker_can_execute_task() for
  252. each and every implementation. It can also be used with
  253. <c>impl_mask == NULL</c> to check for at least one implementation
  254. without determining which.
  255. */
  256. int starpu_worker_can_execute_task_first_impl(unsigned workerid, struct starpu_task *task, unsigned *nimpl);
  257. /**
  258. The scheduling policy may put tasks directly into a worker’s local
  259. queue so that it is not always necessary to create its own queue
  260. when the local queue is sufficient. \p back is ignored: the task priority is
  261. used to order tasks in this queue.
  262. */
  263. int starpu_push_local_task(int workerid, struct starpu_task *task, int back);
  264. /**
  265. Must be called by a scheduler to notify that the given
  266. task has just been pushed.
  267. */
  268. int starpu_push_task_end(struct starpu_task *task);
  269. /**
  270. Whether \ref STARPU_PREFETCH was set
  271. */
  272. int starpu_get_prefetch_flag(void);
  273. /**
  274. Prefetch data for a given p task on a given p node with a given
  275. priority
  276. */
  277. int starpu_prefetch_task_input_on_node_prio(struct starpu_task *task, unsigned node, int prio);
  278. /**
  279. Prefetch data for a given p task on a given p node
  280. */
  281. int starpu_prefetch_task_input_on_node(struct starpu_task *task, unsigned node);
  282. /**
  283. Prefetch data for a given p task on a given p node when the bus is
  284. idle with a given priority
  285. */
  286. int starpu_idle_prefetch_task_input_on_node_prio(struct starpu_task *task, unsigned node, int prio);
  287. /**
  288. Prefetch data for a given p task on a given p node when the bus is
  289. idle
  290. */
  291. int starpu_idle_prefetch_task_input_on_node(struct starpu_task *task, unsigned node);
  292. /**
  293. Prefetch data for a given p task on a given p worker with a given
  294. priority
  295. */
  296. int starpu_prefetch_task_input_for_prio(struct starpu_task *task, unsigned worker, int prio);
  297. /**
  298. Prefetch data for a given p task on a given p worker
  299. */
  300. int starpu_prefetch_task_input_for(struct starpu_task *task, unsigned worker);
  301. /**
  302. Prefetch data for a given p task on a given p worker when the bus
  303. is idle with a given priority
  304. */
  305. int starpu_idle_prefetch_task_input_for_prio(struct starpu_task *task, unsigned worker, int prio);
  306. /**
  307. Prefetch data for a given p task on a given p worker when the bus
  308. is idle
  309. */
  310. int starpu_idle_prefetch_task_input_for(struct starpu_task *task, unsigned worker);
  311. /**
  312. Return the footprint for a given task, taking into account
  313. user-provided perfmodel footprint or size_base functions.
  314. */
  315. uint32_t starpu_task_footprint(struct starpu_perfmodel *model, struct starpu_task *task, struct starpu_perfmodel_arch *arch, unsigned nimpl);
  316. /**
  317. Return the raw footprint for the data of a given task (without
  318. taking into account user-provided functions).
  319. */
  320. uint32_t starpu_task_data_footprint(struct starpu_task *task);
  321. /**
  322. Return expected task duration in micro-seconds.
  323. */
  324. double starpu_task_expected_length(struct starpu_task *task, struct starpu_perfmodel_arch *arch, unsigned nimpl);
  325. /**
  326. Same as starpu_task_expected_length() but for a precise worker.
  327. */
  328. double starpu_task_worker_expected_length(struct starpu_task *task, unsigned workerid, unsigned sched_ctx_id, unsigned nimpl);
  329. /**
  330. Return an estimated speedup factor relative to CPU speed
  331. */
  332. double starpu_worker_get_relative_speedup(struct starpu_perfmodel_arch *perf_arch);
  333. /**
  334. Return expected data transfer time in micro-seconds for the given \p
  335. memory_node. Prefer using starpu_task_expected_data_transfer_time_for() which is
  336. more precise.
  337. */
  338. double starpu_task_expected_data_transfer_time(unsigned memory_node, struct starpu_task *task);
  339. /**
  340. Return expected data transfer time in micro-seconds for the given
  341. \p worker.
  342. */
  343. double starpu_task_expected_data_transfer_time_for(struct starpu_task *task, unsigned worker);
  344. /**
  345. Predict the transfer time (in micro-seconds) to move \p handle to a
  346. memory node
  347. */
  348. double starpu_data_expected_transfer_time(starpu_data_handle_t handle, unsigned memory_node, enum starpu_data_access_mode mode);
  349. /**
  350. Return expected energy consumption in J
  351. */
  352. double starpu_task_expected_energy(struct starpu_task *task, struct starpu_perfmodel_arch *arch, unsigned nimpl);
  353. /**
  354. Same as starpu_task_expected_energy but for a precise worker
  355. */
  356. double starpu_task_worker_expected_energy(struct starpu_task *task, unsigned workerid, unsigned sched_ctx_id, unsigned nimpl);
  357. /**
  358. Return expected conversion time in ms (multiformat interface only)
  359. */
  360. double starpu_task_expected_conversion_time(struct starpu_task *task, struct starpu_perfmodel_arch *arch, unsigned nimpl);
  361. typedef void (*starpu_notify_ready_soon_func)(void *data, struct starpu_task *task, double delay);
  362. /**
  363. Register a callback to be called when it is determined when a task
  364. will be ready an estimated amount of time from now, because its
  365. last dependency has just started and we know how long it will take.
  366. */
  367. void starpu_task_notify_ready_soon_register(starpu_notify_ready_soon_func f, void *data);
  368. /**
  369. The scheduling policies indicates if the worker may pop tasks from
  370. the list of other workers or if there is a central list with task
  371. for all the workers
  372. */
  373. void starpu_sched_ctx_worker_shares_tasks_lists(int workerid, int sched_ctx_id);
  374. void starpu_sched_task_break(struct starpu_task *task);
  375. /**
  376. @name Worker operations
  377. @{
  378. */
  379. /**
  380. Wake up \p workerid while temporarily entering the current worker
  381. relax state if needed during the waiting process. Return 1 if \p
  382. workerid has been woken up or its state_keep_awake flag has been
  383. set to \c 1, and \c 0 otherwise (if \p workerid was not in the
  384. STATE_SLEEPING or in the STATE_SCHEDULING).
  385. */
  386. int starpu_wake_worker_relax(int workerid);
  387. /**
  388. Must be called to wake up a worker that is sleeping on the cond.
  389. Return 0 whenever the worker is not in a sleeping state or has the
  390. state_keep_awake flag on.
  391. */
  392. int starpu_wake_worker_no_relax(int workerid);
  393. /**
  394. Version of starpu_wake_worker_no_relax() which assumes that the
  395. sched mutex is locked
  396. */
  397. int starpu_wake_worker_locked(int workerid);
  398. /**
  399. Light version of starpu_wake_worker_relax() which, when possible,
  400. speculatively set keep_awake on the target worker without waiting
  401. for the worker to enter the relax state.
  402. */
  403. int starpu_wake_worker_relax_light(int workerid);
  404. /** @} */
  405. /** @} */
  406. #ifdef __cplusplus
  407. }
  408. #endif
  409. #endif /* __STARPU_SCHEDULER_H__ */