350_modularized_scheduler.doxy 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2013 Inria
  4. * Copyright (C) 2014,2016-2018 CNRS
  5. * Copyright (C) 2014,2017 Université de Bordeaux
  6. * Copyright (C) 2013 Simon Archipoff
  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. /*! \page ModularizedScheduler Modularized Schedulers
  20. \section Introduction
  21. StarPU's Modularized Schedulers are made of individual Scheduling Components
  22. Modularizedly assembled as a Scheduling Tree. Each Scheduling Component has an
  23. unique purpose, such as prioritizing tasks or mapping tasks over resources.
  24. A typical Scheduling Tree is shown below.
  25. <pre>
  26. |
  27. starpu_push_task |
  28. |
  29. v
  30. Fifo_Component
  31. | ^
  32. | |
  33. v |
  34. Eager_Component
  35. | ^
  36. | |
  37. v |
  38. --------><--------------><--------
  39. | ^ | ^
  40. | | | |
  41. v | v |
  42. Fifo_Component Fifo_Component
  43. | ^ | ^
  44. | | | |
  45. v | v |
  46. Worker_Component Worker_Component
  47. </pre>
  48. When a task is pushed by StarPU in a Modularized Scheduler, the task moves from
  49. a Scheduling Component to an other, following the hierarchy of the
  50. Scheduling Tree, and is stored in one of the Scheduling Components of the
  51. strategy.
  52. When a worker wants to pop a task from the Modularized Scheduler, the
  53. corresponding Worker Component of the Scheduling Tree tries to pull a task from
  54. its parents, following the hierarchy, and gives it to the worker if it succeded
  55. to get one.
  56. \section UsingModularizedSchedulers Using Modularized Schedulers
  57. \subsection ExistingModularizedSchedulers Existing Modularized Schedulers
  58. StarPU is currently shipped with the following pre-defined Modularized
  59. Schedulers :
  60. - Eager-based Schedulers (with/without prefetching) : \n
  61. Naive scheduler, which tries to map a task on the first available resource
  62. it finds.
  63. - Prio-based Schedulers (with/without prefetching) : \n
  64. Similar to Eager-Based Schedulers. Can handle tasks which have a defined
  65. priority and schedule them accordingly.
  66. - Random-based Schedulers (with/without prefetching) : \n
  67. Selects randomly a resource to be mapped on for each task.
  68. - HEFT Scheduler : \n
  69. Heterogeneous Earliest Finish Time Scheduler.
  70. This scheduler needs that every task submitted to StarPU have a
  71. defined performance model (\ref PerformanceModelCalibration)
  72. to work efficiently, but can handle tasks without a performance
  73. model.
  74. To use one of these schedulers, one can set the environment variable \ref STARPU_SCHED.
  75. All modularized schedulers are named following the RE <c>tree-*</c>
  76. \subsection ExampleTreeEagerPrefetchingStrategy An Example : The Tree-Eager-Prefetching Strategy
  77. <pre>
  78. |
  79. starpu_push_task |
  80. |
  81. v
  82. Fifo_Component
  83. | ^
  84. Push | | Can_Push
  85. v |
  86. Eager_Component
  87. | ^
  88. | |
  89. v |
  90. --------><-------------------><---------
  91. | ^ | ^
  92. Push | | Can_Push Push | | Can_Push
  93. v | v |
  94. Fifo_Component Fifo_Component
  95. | ^ | ^
  96. Pull | | Can_Pull Pull | | Can_Pull
  97. v | v |
  98. Worker_Component Worker_Component
  99. </pre>
  100. \subsection Interface
  101. Each Scheduling Component must follow the following pre-defined Interface
  102. to be able to interact with other Scheduling Components.
  103. - Push (Caller_Component, Child_Component, Task) \n
  104. The calling Scheduling Component transfers a task to its
  105. Child Component. When the Push function returns, the task no longer
  106. belongs to the calling Component. The Modularized Schedulers'
  107. model relies on this function to perform prefetching.
  108. See starpu_sched_component::push_task for more details
  109. - Pull (Caller_Component, Parent_Component) -> Task \n
  110. The calling Scheduling Component requests a task from
  111. its Parent Component. When the Pull function ends, the returned
  112. task belongs to the calling Component.
  113. See starpu_sched_component::pull_task for more details
  114. - Can_Push (Caller_Component, Parent_Component) \n
  115. The calling Scheduling Component notifies its Parent Component that
  116. it is ready to accept new tasks.
  117. See starpu_sched_component::can_push for more details
  118. - Can_Pull (Caller_Component, Child_Component) \n
  119. The calling Scheduling Component notifies its Child Component
  120. that it is ready to give new tasks.
  121. See starpu_sched_component::can_pull for more details
  122. \section BuildAModularizedScheduler Building a Modularized Scheduler
  123. \subsection PreImplementedComponents Pre-implemented Components
  124. StarPU is currently shipped with the following four Scheduling Components :
  125. - Flow-control Components : Fifo, Prio \n
  126. Components which store tasks. They can also prioritize them if
  127. they have a defined priority. It is possible to define a threshold
  128. for those Components following two criterias : the number of tasks
  129. stored in the Component, or the sum of the expected length of all
  130. tasks stored in the Component.
  131. - Resource-Mapping Components : Mct, Heft, Eager, Random, Work-Stealing \n
  132. "Core" of the Scheduling Strategy, those Components are the
  133. ones who make scheduling choices.
  134. - Worker Components : Worker \n
  135. Each Worker Component modelize a concrete worker.
  136. - Special-Purpose Components : Perfmodel_Select, Best_Implementation \n
  137. Components dedicated to original purposes. The Perfmodel_Select
  138. Component decides which Resource-Mapping Component should be used to
  139. schedule a task. The Best_Implementation Component chooses which
  140. implementation of a task should be used on the choosen resource.
  141. \subsection ProgressionAndValidationRules Progression And Validation Rules
  142. Some rules must be followed to ensure the correctness of a Modularized
  143. Scheduler :
  144. - At least one Flow-control Component without threshold per Worker Component
  145. is needed in a Modularized Scheduler, to store incoming tasks from StarPU
  146. and to give tasks to Worker Components who asks for it. It is possible to
  147. use one Flow-control Component per Worker Component, or one for all Worker
  148. Components, depending on how the Scheduling Tree is defined.
  149. - At least one Resource-Mapping Component is needed in a Modularized
  150. Scheduler. Resource-Mapping Components are the only ones who can make
  151. scheduling choices, and so the only ones who can have several child.
  152. \subsection ImplementAModularizedScheduler Implementing a Modularized Scheduler
  153. The following code shows how the Tree-Eager-Prefetching Scheduler
  154. shown in Section \ref ExampleTreeEagerPrefetchingStrategy is implemented :
  155. \code{.c}
  156. #define _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT 2
  157. #define _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT 1000000000.0
  158. static void initialize_eager_prefetching_center_policy(unsigned sched_ctx_id)
  159. {
  160. unsigned ntasks_threshold = _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT;
  161. double exp_len_threshold = _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT;
  162. [...]
  163. starpu_sched_ctx_create_worker_collection
  164. (sched_ctx_id, STARPU_WORKER_LIST);
  165. /* Create the Scheduling Tree */
  166. struct starpu_sched_tree * t = starpu_sched_tree_create(sched_ctx_id);
  167. /* The Root Component is a Flow-control Fifo Component */
  168. t->root = starpu_sched_component_fifo_create(NULL);
  169. /* The Resource-mapping Component of the strategy is an Eager Component
  170. */
  171. struct starpu_sched_component *eager_component = starpu_sched_component_eager_create(NULL);
  172. /* Create links between Components : the Eager Component is the child
  173. * of the Root Component */
  174. t->root->add_child(t->root, eager_component);
  175. eager_component->add_father(eager_component, t->root);
  176. /* A task threshold is set for the Flow-control Components which will
  177. * be connected to Worker Components. By doing so, this Modularized
  178. * Scheduler will be able to perform some prefetching on the resources
  179. */
  180. struct starpu_sched_component_fifo_data fifo_data =
  181. {
  182. .ntasks_threshold = ntasks_threshold,
  183. .exp_len_threshold = exp_len_threshold,
  184. };
  185. unsigned i;
  186. for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
  187. {
  188. /* Each Worker Component has a Flow-control Fifo Component as
  189. * father */
  190. struct starpu_sched_component * worker_component = starpu_sched_component_worker_new(i);
  191. struct starpu_sched_component * fifo_component = starpu_sched_component_fifo_create(&fifo_data);
  192. fifo_component->add_child(fifo_component, worker_component);
  193. worker_component->add_father(worker_component, fifo_component);
  194. /* Each Flow-control Fifo Component associated to a Worker
  195. * Component is linked to the Eager Component as one of its
  196. * children */
  197. eager_component->add_child(eager_component, fifo_component);
  198. fifo_component->add_father(fifo_component, eager_component);
  199. }
  200. starpu_sched_tree_update_workers(t);
  201. starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
  202. }
  203. /* Properly destroy the Scheduling Tree and all its Components */
  204. static void deinitialize_eager_prefetching_center_policy(unsigned sched_ctx_id)
  205. {
  206. struct starpu_sched_tree * tree = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
  207. starpu_sched_tree_destroy(tree);
  208. starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
  209. }
  210. /* Initializing the starpu_sched_policy struct associated to the Modularized
  211. * Scheduler : only the init_sched and deinit_sched needs to be defined to
  212. * implement a Modularized Scheduler */
  213. struct starpu_sched_policy _starpu_sched_tree_eager_prefetching_policy =
  214. {
  215. .init_sched = initialize_eager_prefetching_center_policy,
  216. .deinit_sched = deinitialize_eager_prefetching_center_policy,
  217. .add_workers = starpu_sched_tree_add_workers,
  218. .remove_workers = starpu_sched_tree_remove_workers,
  219. .push_task = starpu_sched_tree_push_task,
  220. .pop_task = starpu_sched_tree_pop_task,
  221. .pre_exec_hook = starpu_sched_component_worker_pre_exec_hook,
  222. .post_exec_hook = starpu_sched_component_worker_post_exec_hook,
  223. .pop_every_task = NULL,
  224. .policy_name = "tree-eager-prefetching",
  225. .policy_description = "eager with prefetching tree policy"
  226. };
  227. \endcode
  228. \section WriteASchedulingComponent Writing a Scheduling Component
  229. \subsection GenericSchedulingComponent Generic Scheduling Component
  230. Each Scheduling Component is instantiated from a Generic Scheduling Component,
  231. which implements a generic version of the Interface. The generic implementation
  232. of Pull, Can_Pull and Can_Push functions are recursive calls to their parents
  233. (respectively to their children). However, as a Generic Scheduling Component do
  234. not know how much children it will have when it will be instantiated, it does
  235. not implement the Push function.
  236. \subsection InstantiationRedefineInterface Instantiation : Redefining the Interface
  237. A Scheduling Component must implement all the functions of the Interface. It is
  238. so necessary to implement a Push function to instantiate a Scheduling Component.
  239. The implemented Push function is the "fingerprint" of a Scheduling Component.
  240. Depending on how functionalities or properties the programmer wants to give
  241. to the Scheduling Component he is implementing, it is possible to reimplement
  242. all the functions of the Interface. For example, a Flow-control Component
  243. reimplements the Pull and the Can_Push functions of the Interface, allowing him
  244. to catch the generic recursive calls of these functions. The Pull function of
  245. a Flow-control Component can, for example, pop a task from the local storage
  246. queue of the Component, and give it to the calling Component which asks for it.
  247. \subsection DetailedProgressionAndValidationRules Detailed Progression and Validation Rules
  248. - A Reservoir is a Scheduling Component which redefines a Push and a Pull
  249. function, in order to store tasks into it. A Reservoir delimit Scheduling
  250. Areas in the Scheduling Tree.
  251. - A Pump is the engine source of the Scheduler : it pushes/pulls tasks
  252. to/from a Scheduling Component to an other. Native Pumps of a Scheduling
  253. Tree are located at the root of the Tree (incoming Push calls from StarPU),
  254. and at the leafs of the Tree (Pop calls coming from StarPU Workers).
  255. Pre-implemented Scheduling Components currently shipped with Pumps are
  256. Flow-Control Components and the Resource-Mapping Component Heft, within
  257. their defined Can_Push functions.
  258. - A correct Scheduling Tree requires a Pump per Scheduling Area and per
  259. Execution Flow.
  260. The Tree-Eager-Prefetching Scheduler shown in Section
  261. \ref ExampleTreeEagerPrefetchingStrategy follows the previous assumptions :
  262. <pre>
  263. starpu_push_task
  264. <b>Pump</b>
  265. |
  266. Area 1 |
  267. |
  268. v
  269. -----------------------Fifo_Component-----------------------------
  270. <b>Pump</b>
  271. | ^
  272. Push | | Can_Push
  273. v |
  274. Area 2 Eager_Component
  275. | ^
  276. | |
  277. v |
  278. --------><-------------------><---------
  279. | ^ | ^
  280. Push | | Can_Push Push | | Can_Push
  281. v | v |
  282. -----Fifo_Component-----------------------Fifo_Component----------
  283. | ^ | ^
  284. Pull | | Can_Pull Pull | | Can_Pull
  285. Area 3 v | v |
  286. <b>Pump</b> <b>Pump</b>
  287. Worker_Component Worker_Component
  288. </pre>
  289. */