hierarchical_scheduler.doxy 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * This file is part of the StarPU Handbook.
  3. * Copyright (C) 2013 Simon Archipoff
  4. * Copyright (C) 2013 INRIA
  5. * See the file version.doxy for copying conditions.
  6. */
  7. /*! \page HierarchicalScheduler Hierarchical Schedulers
  8. \section Introduction
  9. StarPU's Hierarchical Schedulers are made of individual Scheduling Components
  10. hierarchically assembled as a Scheduling Tree. Each Scheduling Component has an
  11. unique purpose, such as prioritizing tasks or mapping tasks over resources.
  12. A typical Scheduling Tree is shown below.
  13. <pre>
  14. |
  15. starpu_push_task |
  16. |
  17. v
  18. Fifo_Component
  19. | ^
  20. | |
  21. v |
  22. Eager_Component
  23. | ^
  24. | |
  25. v |
  26. --------><--------------><--------
  27. | ^ | ^
  28. | | | |
  29. v | v |
  30. Fifo_Component Fifo_Component
  31. | ^ | ^
  32. | | | |
  33. v | v |
  34. Worker_Component Worker_Component
  35. </pre>
  36. When a task is pushed by StarPU in a Hierarchical Scheduler, the task moves from
  37. a Scheduling Component to an other, following the hierarchy of the
  38. Scheduling Tree, and is stored in one of the Scheduling Components of the
  39. strategy.
  40. When a worker wants to pop a task from the Hierarchical Scheduler, the
  41. corresponding Worker Component of the Scheduling Tree tries to pull a task from
  42. its parents, following the hierarchy, and gives it to the worker if it succeded
  43. to get one.
  44. \section UsingHierarchicalSchedulers Using Hierarchical Schedulers
  45. \subsection ExistingHierarchicalSchedulers Existing Hierarchical Schedulers
  46. StarPU is currently shipped with the following pre-defined Hierarchical
  47. Schedulers :
  48. - Eager-based Schedulers (with/without prefetching) : \n
  49. Naive scheduler, which tries to map a task on the first available resource
  50. it finds.
  51. - Prio-based Schedulers (with/without prefetching) : \n
  52. Similar to Eager-Based Schedulers. Can handle tasks which have a defined
  53. priority and schedule them accordingly.
  54. - Random-based Schedulers (with/without prefetching) : \n
  55. Selects randomly a resource to be mapped on for each task.
  56. - HEFT Scheduler : \n
  57. Heterogeneous Earliest Finish Time Scheduler.
  58. This scheduler needs that every task submitted to StarPU have a
  59. defined performance model (\ref PerformanceModelCalibration)
  60. to work efficiently, but can handle tasks without a performance
  61. model.
  62. \subsection ExampleTreeEagerPrefetchingStrategy An Example : The Tree-Eager-Prefetching Strategy
  63. <pre>
  64. |
  65. starpu_push_task |
  66. |
  67. v
  68. Fifo_Component
  69. | ^
  70. Push | | Can_Push
  71. v |
  72. Eager_Component
  73. | ^
  74. | |
  75. v |
  76. --------><-------------------><---------
  77. | ^ | ^
  78. Push | | Can_Push Push | | Can_Push
  79. v | v |
  80. Fifo_Component Fifo_Component
  81. | ^ | ^
  82. Pull | | Can_Pull Pull | | Can_Pull
  83. v | v |
  84. Worker_Component Worker_Component
  85. </pre>
  86. \subsection Interface
  87. Each Scheduling Component must follow the following pre-defined Interface
  88. to be able to interact with other Scheduling Components.
  89. - Push (Caller_Component, Child_Component, Task) \n
  90. The calling Scheduling Component transfers a task to its
  91. Child Component. When the Push function returns, the task no longer
  92. belongs to the calling Component. The Hierarchical Schedulers'
  93. model relies on this function to perform prefetching.
  94. - Pull (Caller_Component, Parent_Component) -> Task \n
  95. The calling Scheduling Component requests a task from
  96. its Parent Component. When the Pull function ends, the returned
  97. task belongs to the calling Component.
  98. - Can_Push (Caller_Component, Parent_Component) \n
  99. The calling Scheduling Component notifies its Parent Component that
  100. it is ready to accept new tasks.
  101. - Can_Pull (Caller_Component, Child_Component) \n
  102. The calling Scheduling Component notifies its Child Component
  103. that it is ready to give new tasks.
  104. \section BuildAHierarchicalScheduler Build a Hierarchical Scheduler
  105. \subsection PreImplementedComponents Pre-implemented Components
  106. StarPU is currently shipped with the following four Scheduling Components :
  107. - Flow-control Components : Fifo, Prio \n
  108. Components which store tasks. They can also prioritize them if
  109. they have a defined priority. It is possible to define a threshold
  110. for those Components following two criterias : the number of tasks
  111. stored in the Component, or the sum of the expected length of all
  112. tasks stored in the Component.
  113. - Resource-Mapping Components : Mct, Heft, Eager, Random, Work-Stealing \n
  114. "Core" of the Scheduling Strategy, those Components are the
  115. ones who make scheduling choices.
  116. - Worker Components : Worker \n
  117. Each Worker Component modelize a concrete worker.
  118. - Special-Purpose Components : Perfmodel_Select, Best_Implementation \n
  119. Components dedicated to original purposes. The Perfmodel_Select
  120. Component decides which Resource-Mapping Component should be used to
  121. schedule a task. The Best_Implementation Component chooses which
  122. implementation of a task should be used on the choosen resource.
  123. \subsection ProgressionAndValidationRules Progression And Validation Rules
  124. Some rules must be followed to ensure the correctness of a Hierarchical
  125. Scheduler :
  126. - At least one Flow-control Component without threshold per Worker Component
  127. is needed in a Hierarchical Scheduler, to store incoming tasks from StarPU
  128. and to give tasks to Worker Components who asks for it. It is possible to
  129. use one Flow-control Component per Worker Component, or one for all Worker
  130. Components, depending on how the Scheduling Tree is defined.
  131. - At least one Resource-Mapping Component is needed in a Hierarchical
  132. Scheduler. Resource-Mapping Components are the only ones who can make
  133. scheduling choices, and so the only ones who can have several child.
  134. \subsection ImplementAHierarchicalScheduler Implement a Hierarchical Scheduler
  135. The following code shows how the Tree-Eager-Prefetching Scheduler
  136. shown in Section \ref ExampleTreeEagerPrefetchingStrategy is implemented :
  137. \code{.c}
  138. #define _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT 2
  139. #define _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT 1000000000.0
  140. static void initialize_eager_prefetching_center_policy(unsigned sched_ctx_id)
  141. {
  142. unsigned ntasks_threshold = _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT;
  143. double exp_len_threshold = _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT;
  144. [...]
  145. starpu_sched_ctx_create_worker_collection
  146. (sched_ctx_id, STARPU_WORKER_LIST);
  147. /* Create the Scheduling Tree */
  148. struct starpu_sched_tree * t =
  149. starpu_sched_tree_create(sched_ctx_id);
  150. /* The Root Component is a Flow-control Fifo Component */
  151. t->root = starpu_sched_component_fifo_create(NULL);
  152. /* The Resource-mapping Component of the strategy is an Eager Component
  153. */
  154. struct starpu_sched_component * eager_component =
  155. starpu_sched_component_eager_create(NULL);
  156. /* Create links between Components : the Eager Component is the child
  157. * of the Root Component */
  158. t->root->add_child
  159. (t->root, eager_component);
  160. eager_component->add_father
  161. (eager_component, t->root);
  162. /* A task threshold is set for the Flow-control Components which will
  163. * be connected to Worker Components. By doing so, this Hierarchical
  164. * Scheduler will be able to perform some prefetching on the resources
  165. */
  166. struct starpu_fifo_data fifo_data =
  167. {
  168. .ntasks_threshold = ntasks_threshold,
  169. .exp_len_threshold = exp_len_threshold,
  170. };
  171. unsigned i;
  172. for(i = 0;
  173. i < starpu_worker_get_count() +
  174. starpu_combined_worker_get_count();
  175. i++)
  176. {
  177. /* Each Worker Component has a Flow-control Fifo Component as
  178. * father */
  179. struct starpu_sched_component * worker_component =
  180. starpu_sched_component_worker_get(i);
  181. struct starpu_sched_component * fifo_component =
  182. starpu_sched_component_fifo_create(&fifo_data);
  183. fifo_component->add_child
  184. (fifo_component, worker_component);
  185. worker_component->add_father
  186. (worker_component, fifo_component);
  187. /* Each Flow-control Fifo Component associated to a Worker
  188. * Component is linked to the Eager Component as one of its
  189. * children */
  190. eager_component->add_child
  191. (eager_component, fifo_component);
  192. fifo_component->add_father
  193. (fifo_component, eager_component);
  194. }
  195. starpu_sched_tree_update_workers(t);
  196. starpu_sched_ctx_set_policy_data
  197. (sched_ctx_id, (void*)t);
  198. }
  199. /* Properly destroy the Scheduling Tree and all its Components */
  200. static void deinitialize_eager_prefetching_center_policy(unsigned sched_ctx_id)
  201. {
  202. struct starpu_sched_tree * tree =
  203. (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
  204. starpu_sched_tree_destroy(tree);
  205. starpu_sched_ctx_delete_worker_collection
  206. (sched_ctx_id);
  207. }
  208. /* Initializing the starpu_sched_policy struct associated to the Hierarchical
  209. * Scheduler : only the init_sched and deinit_sched needs to be defined to
  210. * implement a Hierarchical Scheduler */
  211. struct starpu_sched_policy _starpu_sched_tree_eager_prefetching_policy =
  212. {
  213. .init_sched = initialize_eager_prefetching_center_policy,
  214. .deinit_sched = deinitialize_eager_prefetching_center_policy,
  215. .add_workers = starpu_sched_tree_add_workers,
  216. .remove_workers = starpu_sched_tree_remove_workers,
  217. .push_task = starpu_sched_tree_push_task,
  218. .pop_task = starpu_sched_tree_pop_task,
  219. .pre_exec_hook = starpu_sched_component_worker_pre_exec_hook,
  220. .post_exec_hook = starpu_sched_component_worker_post_exec_hook,
  221. .pop_every_task = NULL,
  222. .policy_name = "tree-eager-prefetching",
  223. .policy_description = "eager with prefetching tree policy"
  224. };
  225. \endcode
  226. \section WriteASchedulingComponent Write a Scheduling Component
  227. \subsection GenericSchedulingComponent Generic Scheduling Component
  228. \subsection InstanciationRedefineInterface Instanciation : Redefine the Interface
  229. \subsection DetailedProgressionAndValidationRules Detailed Progression and Validation Rules
  230. */