hierarchical_scheduler.doxy 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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 fathers, 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. - tree-eager
  52. - tree-eager-prefetching
  53. - Prio-based Schedulers (with/without prefetching) : \n
  54. Similar to Eager-Based Schedulers. Can handle tasks which have a defined
  55. priority and schedule them accordingly.
  56. - tree-prio
  57. - tree-prio-prefetching
  58. - Random-based Schedulers (with/without prefetching) : \n
  59. Selects randomly a resource to be mapped on for each task.
  60. - With fifos :
  61. - tree-random
  62. - tree-random-prefetching
  63. - With prios :
  64. - tree-random-prio
  65. - tree-random-prio-prefetching
  66. - HEFT Scheduler : \n
  67. Heterogeneous Earliest Finish Time Scheduler.
  68. This scheduler needs that every task submitted to StarPU have a
  69. defined performance model (\ref PerformanceModelCalibration)
  70. to work efficiently, but can handle tasks without a performance
  71. model.
  72. - tree-heft
  73. \subsection ExampleTreeEagerPrefetchingStrategy An Example : The Tree-Eager-Prefetching Strategy
  74. <pre>
  75. |
  76. starpu_push_task |
  77. |
  78. v
  79. Fifo_Component
  80. | ^
  81. Push | | Can_Push
  82. v |
  83. Eager_Component
  84. | ^
  85. | |
  86. v |
  87. --------><-------------------><---------
  88. | ^ | ^
  89. Push | | Can_Push Push | | Can_Push
  90. v | v |
  91. Fifo_Component Fifo_Component
  92. | ^ | ^
  93. Pull | | Can_Pull Pull | | Can_Pull
  94. v | v |
  95. Worker_Component Worker_Component
  96. </pre>
  97. \subsection Interface
  98. Each Scheduling Component must follow the following pre-defined Interface
  99. to be able to interact with other Scheduling Components.
  100. - Push (Caller_Component, Child_Component, Task) \n
  101. The calling Scheduling Component transfers a task to its
  102. Child Component. When the Push function returns, the task no longer
  103. belongs to the calling Component. The Hierarchical Schedulers'
  104. model relies on this function to perform prefetching.
  105. - Pull (Caller_Component, Parent_Component) -> Task \n
  106. The calling Scheduling Component requests a task from
  107. its Parent Component. When the Pull function ends, the returned
  108. task belongs to the calling Component.
  109. - Can_Push (Caller_Component, Parent_Component) \n
  110. The calling Scheduling Component notifies its Parent Component that
  111. it is ready to accept new tasks.
  112. - Can_Pull (Caller_Component, Child_Component) \n
  113. The calling Scheduling Component notifies its Child Component
  114. that it is ready to give new tasks.
  115. \section BuildAHierarchicalScheduler Build a Hierarchical Scheduler
  116. \subsection PreImplementedComponents Pre-implemented Components
  117. StarPU is currently shipped with the following four Scheduling Components :
  118. - Flow-control Components :
  119. Those Components store tasks. They can also prioritize them if
  120. they have a defined priority.
  121. - Fifo, Prio
  122. - Resource-Mapping Components :
  123. "Core" of the Scheduling Strategy, those Components are the
  124. ones who make scheduling choices.
  125. - Mct, Eager, Random, Work-Stealing
  126. - Worker Components :
  127. Each Worker Component modelize a concrete worker.
  128. - Worker
  129. - Special-Purpose Components :
  130. Components dedicated to original purposes. The Perfmodel_Select
  131. Component decides which Resource-Mapping Component should be used to
  132. schedule a task. The Best_Implementation Component chooses which
  133. implementation of a task should be used on the choosen resource.
  134. - Perfmodel_Select, Best_Implementation
  135. \subsection ProgressionAndValidationRules Progression And Validation Rules
  136. Some rules must be followed to ensure the correctness of a Hierarchical
  137. Scheduler :
  138. - At least one Flow-control Component per Worker Component is needed in
  139. a Hierarchical Scheduler, to store incoming tasks from StarPU and to
  140. give tasks to Worker Components who asks for it. It is possible to use
  141. one Flow-control Component per Worker Component, or one for all Worker
  142. Components, depending on how the Scheduling Tree is defined.
  143. - At least one Resource-Mapping Component is needed in a Hierarchical
  144. Scheduler. Resource-Mapping Components are the only ones who can make
  145. scheduling choices, and so the only ones who can have several child.
  146. \subsection ImplementAHierarchicalScheduler Implement a Hierarchical Scheduler
  147. The following code present how the Tree-Eager-Prefetching Scheduler
  148. shown in Section \ref ExampleTreeEagerPrefetchingStrategy is implemented :
  149. \code{.c}
  150. static void initialize_eager_prefetching_center_policy(unsigned sched_ctx_id)
  151. {
  152. unsigned ntasks_threshold = _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT;
  153. double exp_len_threshold = _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT;
  154. [...]
  155. starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
  156. /* Creating the Scheduling Tree */
  157. struct starpu_sched_tree *t = starpu_sched_tree_create(sched_ctx_id);
  158. /* The Root Component is a Flow-control Fifo Component */
  159. t->root = starpu_sched_component_fifo_create(NULL);
  160. /* The Resource-mapping Component of the strategy is an Eager Component */
  161. struct starpu_sched_component * eager_component = starpu_sched_component_eager_create(NULL);
  162. /* Creating links between Components : the Eager Component is the child
  163. * of the Root Component */
  164. t->root->add_child(t->root, eager_component);
  165. eager_component->add_father(eager_component, t->root);
  166. /* It is possible to define thresholds following several criterias for
  167. * Flow-control Components : this will be explained further in Section 4.1°)
  168. */
  169. struct starpu_fifo_data fifo_data =
  170. {
  171. .ntasks_threshold = ntasks_threshold,
  172. .exp_len_threshold = exp_len_threshold,
  173. };
  174. unsigned i;
  175. for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count() ; i++)
  176. {
  177. /* Each Worker Component has a Flow-control Fifo Component as father */
  178. struct starpu_sched_component * worker_component = starpu_sched_component_worker_get(i);
  179. struct starpu_sched_component * fifo_component = starpu_sched_component_fifo_create(&fifo_data);
  180. fifo_component->add_child(fifo_component, worker_component);
  181. worker_component->add_father(worker_component, fifo_component);
  182. /* Each Flow-control Fifo Component associated to a Worker Component
  183. * is linked to the Eager Component as one of its children */
  184. eager_component->add_child(eager_component, fifo_component);
  185. fifo_component->add_father(fifo_component, eager_component);
  186. }
  187. starpu_sched_tree_update_workers(t);
  188. starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
  189. }
  190. /* Properly destroy the Scheduling Tree and all its Components */
  191. static void deinitialize_eager_prefetching_center_policy(unsigned sched_ctx_id)
  192. {
  193. struct starpu_sched_tree *tree = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
  194. starpu_sched_tree_destroy(tree);
  195. starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
  196. }
  197. /* Initializing the starpu_sched_policy struct associated to the Hierarchical
  198. * Scheduler : only the init_sched and deinit_sched needs to be defined to
  199. * implement a Hierarchical Scheduler */
  200. struct starpu_sched_policy _starpu_sched_tree_eager_prefetching_policy =
  201. {
  202. .init_sched = initialize_eager_prefetching_center_policy,
  203. .deinit_sched = deinitialize_eager_prefetching_center_policy,
  204. .add_workers = starpu_sched_tree_add_workers,
  205. .remove_workers = starpu_sched_tree_remove_workers,
  206. .push_task = starpu_sched_tree_push_task,
  207. .pop_task = starpu_sched_tree_pop_task,
  208. .pre_exec_hook = starpu_sched_component_worker_pre_exec_hook,
  209. .post_exec_hook = starpu_sched_component_worker_post_exec_hook,
  210. .pop_every_task = NULL,
  211. .policy_name = "tree-eager-prefetching",
  212. .policy_description = "eager with prefetching tree policy"
  213. };
  214. \endcode
  215. \section WriteASchedulingComponent Write a Scheduling Component
  216. \subsection SchedulingComponentsProgressionAndValidationRules Scheduling Components : Progression and Validation Rules by Type
  217. \subsection GenericComponentsInstanciation Generic Components' instanciation
  218. */