sched_ctx.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2011-2021 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
  4. * Copyright (C) 2016 Uppsala University
  5. *
  6. * StarPU is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation; either version 2.1 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * StarPU is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. *
  15. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  16. */
  17. #ifndef __SCHED_CONTEXT_H__
  18. #define __SCHED_CONTEXT_H__
  19. /** @file */
  20. #include <starpu.h>
  21. #include <starpu_sched_ctx.h>
  22. #include <starpu_sched_ctx_hypervisor.h>
  23. #include <starpu_scheduler.h>
  24. #include <common/config.h>
  25. #include <common/barrier_counter.h>
  26. #include <common/utils.h>
  27. #include <profiling/profiling.h>
  28. #include <semaphore.h>
  29. #include <core/task.h>
  30. #include "sched_ctx_list.h"
  31. #ifdef STARPU_HAVE_HWLOC
  32. #include <hwloc.h>
  33. #endif
  34. #pragma GCC visibility push(hidden)
  35. #define NO_RESIZE -1
  36. #define REQ_RESIZE 0
  37. #define DO_RESIZE 1
  38. #define STARPU_GLOBAL_SCHED_CTX 0
  39. #define STARPU_NMAXSMS 13
  40. struct _starpu_sched_ctx
  41. {
  42. /** id of the context used in user mode*/
  43. unsigned id;
  44. /** boolean indicating whether the scheduling_ctx will be considered for scheduling (1) or not (0)*/
  45. unsigned do_schedule;
  46. /** name of context */
  47. const char *name;
  48. /** policy of the context */
  49. struct starpu_sched_policy *sched_policy;
  50. /** data necessary for the policy */
  51. void *policy_data;
  52. /** pointer for application use */
  53. void *user_data;
  54. struct starpu_worker_collection *workers;
  55. /** we keep an initial sched which we never delete */
  56. unsigned is_initial_sched;
  57. /** wait for the tasks submitted to the context to be executed */
  58. struct _starpu_barrier_counter tasks_barrier;
  59. /** wait for the tasks ready of the context to be executed */
  60. struct _starpu_barrier_counter ready_tasks_barrier;
  61. /** amount of ready flops in a context */
  62. double ready_flops;
  63. /** Iteration number, as advertised by application */
  64. long iterations[2];
  65. int iteration_level;
  66. /*ready tasks that couldn't be pushed because the ctx has no workers*/
  67. struct starpu_task_list empty_ctx_tasks;
  68. /*ready tasks that couldn't be pushed because the the window of tasks was already full*/
  69. struct starpu_task_list waiting_tasks;
  70. /** min CPUs to execute*/
  71. int min_ncpus;
  72. /** max CPUs to execute*/
  73. int max_ncpus;
  74. /** min GPUs to execute*/
  75. int min_ngpus;
  76. /** max GPUs to execute*/
  77. int max_ngpus;
  78. /** in case we delete the context leave resources to the inheritor*/
  79. unsigned inheritor;
  80. /** indicates whether the application finished submitting tasks
  81. to this context*/
  82. unsigned finished_submit;
  83. /** By default we have a binary type of priority: either a task is a priority
  84. * task (level 1) or it is not (level 0). */
  85. int min_priority;
  86. int max_priority;
  87. int min_priority_is_set;
  88. int max_priority_is_set;
  89. /** hwloc tree structure of workers */
  90. #ifdef STARPU_HAVE_HWLOC
  91. hwloc_bitmap_t hwloc_workers_set;
  92. #endif
  93. #ifdef STARPU_USE_SC_HYPERVISOR
  94. /** a structure containing a series of performance counters determining the resize procedure */
  95. struct starpu_sched_ctx_performance_counters *perf_counters;
  96. #endif //STARPU_USE_SC_HYPERVISOR
  97. /** callback called when the context finished executed its submitted tasks */
  98. void (*close_callback)(unsigned sched_ctx_id, void* args);
  99. void *close_args;
  100. /** value placing the contexts in their hierarchy */
  101. unsigned hierarchy_level;
  102. /** if we execute non-StarPU code inside the context
  103. we have a single master worker that stays awake,
  104. if not master is -1 */
  105. int main_master;
  106. /** ctx nesting the current ctx */
  107. unsigned nesting_sched_ctx;
  108. /** perf model for the device comb of the ctx */
  109. struct starpu_perfmodel_arch perf_arch;
  110. /** For parallel workers, say whether it is viewed as sequential or not. This
  111. is a helper for the prologue code. */
  112. unsigned parallel_view;
  113. /** for ctxs without policy: flag to indicate that we want to get
  114. the threads to sleep in order to replace them with other threads or leave
  115. them awake & use them in the parallel code*/
  116. unsigned awake_workers;
  117. /** callback function called when initializing the scheduler */
  118. void (*callback_sched)(unsigned);
  119. int sub_ctxs[STARPU_NMAXWORKERS];
  120. int nsub_ctxs;
  121. /** nr of SMs assigned to this ctx if we partition gpus*/
  122. int nsms;
  123. int sms_start_idx;
  124. int sms_end_idx;
  125. int stream_worker;
  126. starpu_pthread_rwlock_t rwlock;
  127. starpu_pthread_t lock_write_owner;
  128. };
  129. /** per-worker list of deferred ctx_change ops */
  130. LIST_TYPE(_starpu_ctx_change,
  131. int sched_ctx_id;
  132. int op;
  133. int nworkers_to_notify;
  134. int *workerids_to_notify;
  135. int nworkers_to_change;
  136. int *workerids_to_change;
  137. );
  138. struct _starpu_machine_config;
  139. /** init sched_ctx_id of all contextes*/
  140. void _starpu_init_all_sched_ctxs(struct _starpu_machine_config *config);
  141. /** allocate all structures belonging to a context */
  142. struct _starpu_sched_ctx* _starpu_create_sched_ctx(struct starpu_sched_policy *policy, int *workerid, int nworkerids, unsigned is_init_sched, const char *sched_name,
  143. int min_prio_set, int min_prio,
  144. int max_prio_set, int max_prio, unsigned awake_workers, void (*sched_policy_callback)(unsigned), void *user_data,
  145. int nsub_ctxs, int *sub_ctxs, int nsms);
  146. /** delete all sched_ctx */
  147. void _starpu_delete_all_sched_ctxs();
  148. /** This function waits until all the tasks that were already submitted to a specific
  149. * context have been executed. */
  150. int _starpu_wait_for_all_tasks_of_sched_ctx(unsigned sched_ctx_id);
  151. /** This function waits until at most n tasks are still submitted. */
  152. int _starpu_wait_for_n_submitted_tasks_of_sched_ctx(unsigned sched_ctx_id, unsigned n);
  153. /** In order to implement starpu_wait_for_all_tasks_of_ctx, we keep track of the number of
  154. * task currently submitted to the context */
  155. void _starpu_decrement_nsubmitted_tasks_of_sched_ctx(unsigned sched_ctx_id);
  156. void _starpu_increment_nsubmitted_tasks_of_sched_ctx(unsigned sched_ctx_id);
  157. int _starpu_get_nsubmitted_tasks_of_sched_ctx(unsigned sched_ctx_id);
  158. int _starpu_check_nsubmitted_tasks_of_sched_ctx(unsigned sched_ctx_id);
  159. void _starpu_decrement_nready_tasks_of_sched_ctx(unsigned sched_ctx_id, double ready_flops);
  160. unsigned _starpu_increment_nready_tasks_of_sched_ctx(unsigned sched_ctx_id, double ready_flops, struct starpu_task *task);
  161. int _starpu_wait_for_no_ready_of_sched_ctx(unsigned sched_ctx_id);
  162. /** Return the corresponding index of the workerid in the ctx table */
  163. int _starpu_get_index_in_ctx_of_workerid(unsigned sched_ctx, unsigned workerid);
  164. /** Get the mutex corresponding to the global workerid */
  165. starpu_pthread_mutex_t *_starpu_get_sched_mutex(struct _starpu_sched_ctx *sched_ctx, int worker);
  166. /** Get workers belonging to a certain context, it returns the number of workers
  167. take care: no mutex taken, the list of workers might not be updated */
  168. int _starpu_get_workers_of_sched_ctx(unsigned sched_ctx_id, int *pus, enum starpu_worker_archtype arch);
  169. /** Let the worker know it does not belong to the context and that
  170. it should stop poping from it */
  171. void _starpu_worker_gets_out_of_ctx(unsigned sched_ctx_id, struct _starpu_worker *worker);
  172. /** Check if the worker belongs to another sched_ctx */
  173. unsigned _starpu_worker_belongs_to_a_sched_ctx(int workerid, unsigned sched_ctx_id);
  174. /** indicates wheather this worker should go to sleep or not
  175. (if it is the last one awake in a context he should better keep awake) */
  176. unsigned _starpu_sched_ctx_last_worker_awake(struct _starpu_worker *worker);
  177. /** If starpu_sched_ctx_set_context() has been called, returns the context
  178. * id set by its last call, or the id of the initial context */
  179. unsigned _starpu_sched_ctx_get_current_context();
  180. /** verify that some worker can execute a certain task */
  181. int _starpu_workers_able_to_execute_task(struct starpu_task *task, struct _starpu_sched_ctx *sched_ctx);
  182. void _starpu_fetch_tasks_from_empty_ctx_list(struct _starpu_sched_ctx *sched_ctx);
  183. unsigned _starpu_sched_ctx_allow_hypervisor(unsigned sched_ctx_id);
  184. struct starpu_perfmodel_arch * _starpu_sched_ctx_get_perf_archtype(unsigned sched_ctx);
  185. #ifdef STARPU_USE_SC_HYPERVISOR
  186. /** Notifies the hypervisor that a tasks was poped from the workers' list */
  187. void _starpu_sched_ctx_post_exec_task_cb(int workerid, struct starpu_task *task, size_t data_size, uint32_t footprint);
  188. #endif //STARPU_USE_SC_HYPERVISOR
  189. void starpu_sched_ctx_add_combined_workers(int *combined_workers_to_add, unsigned n_combined_workers_to_add, unsigned sched_ctx_id);
  190. /** if the worker is the master of a parallel context, and the job is meant to be executed on this parallel context, return a pointer to the context */
  191. struct _starpu_sched_ctx *__starpu_sched_ctx_get_sched_ctx_for_worker_and_job(struct _starpu_worker *worker, struct _starpu_job *j);
  192. #define _starpu_sched_ctx_get_sched_ctx_for_worker_and_job(w,j) \
  193. (_starpu_get_nsched_ctxs() <= 1 ? _starpu_get_sched_ctx_struct(0) : __starpu_sched_ctx_get_sched_ctx_for_worker_and_job((w),(j)))
  194. static inline struct _starpu_sched_ctx *_starpu_get_sched_ctx_struct(unsigned id);
  195. static inline int _starpu_sched_ctx_check_write_locked(unsigned sched_ctx_id)
  196. {
  197. struct _starpu_sched_ctx *sched_ctx = _starpu_get_sched_ctx_struct(sched_ctx_id);
  198. return starpu_pthread_equal(sched_ctx->lock_write_owner, starpu_pthread_self());
  199. }
  200. #define STARPU_SCHED_CTX_CHECK_LOCK(sched_ctx_id) STARPU_ASSERT(_starpu_sched_ctx_check_write_locked((sched_ctx_id)))
  201. static inline void _starpu_sched_ctx_lock_write(unsigned sched_ctx_id)
  202. {
  203. struct _starpu_sched_ctx *sched_ctx = _starpu_get_sched_ctx_struct(sched_ctx_id);
  204. STARPU_HG_DISABLE_CHECKING(sched_ctx->lock_write_owner);
  205. STARPU_ASSERT(!starpu_pthread_equal(sched_ctx->lock_write_owner, starpu_pthread_self()));
  206. STARPU_HG_ENABLE_CHECKING(sched_ctx->lock_write_owner);
  207. STARPU_PTHREAD_RWLOCK_WRLOCK(&sched_ctx->rwlock);
  208. sched_ctx->lock_write_owner = starpu_pthread_self();
  209. }
  210. static inline void _starpu_sched_ctx_unlock_write(unsigned sched_ctx_id)
  211. {
  212. struct _starpu_sched_ctx *sched_ctx = _starpu_get_sched_ctx_struct(sched_ctx_id);
  213. STARPU_HG_DISABLE_CHECKING(sched_ctx->lock_write_owner);
  214. STARPU_ASSERT(starpu_pthread_equal(sched_ctx->lock_write_owner, starpu_pthread_self()));
  215. memset(&sched_ctx->lock_write_owner, 0, sizeof(sched_ctx->lock_write_owner));
  216. STARPU_HG_ENABLE_CHECKING(sched_ctx->lock_write_owner);
  217. STARPU_PTHREAD_RWLOCK_UNLOCK(&sched_ctx->rwlock);
  218. }
  219. static inline void _starpu_sched_ctx_lock_read(unsigned sched_ctx_id)
  220. {
  221. struct _starpu_sched_ctx *sched_ctx = _starpu_get_sched_ctx_struct(sched_ctx_id);
  222. STARPU_HG_DISABLE_CHECKING(sched_ctx->lock_write_owner);
  223. STARPU_ASSERT(!starpu_pthread_equal(sched_ctx->lock_write_owner, starpu_pthread_self()));
  224. STARPU_HG_ENABLE_CHECKING(sched_ctx->lock_write_owner);
  225. STARPU_PTHREAD_RWLOCK_RDLOCK(&sched_ctx->rwlock);
  226. }
  227. static inline void _starpu_sched_ctx_unlock_read(unsigned sched_ctx_id)
  228. {
  229. struct _starpu_sched_ctx *sched_ctx = _starpu_get_sched_ctx_struct(sched_ctx_id);
  230. STARPU_HG_DISABLE_CHECKING(sched_ctx->lock_write_owner);
  231. STARPU_ASSERT(!starpu_pthread_equal(sched_ctx->lock_write_owner, starpu_pthread_self()));
  232. STARPU_HG_ENABLE_CHECKING(sched_ctx->lock_write_owner);
  233. STARPU_PTHREAD_RWLOCK_UNLOCK(&sched_ctx->rwlock);
  234. }
  235. static inline unsigned _starpu_sched_ctx_worker_is_master_for_child_ctx(unsigned sched_ctx_id, unsigned workerid, struct starpu_task *task)
  236. {
  237. unsigned child_sched_ctx = starpu_sched_ctx_worker_is_master_for_child_ctx(workerid, sched_ctx_id);
  238. if(child_sched_ctx != STARPU_NMAX_SCHED_CTXS)
  239. {
  240. starpu_sched_ctx_move_task_to_ctx_locked(task, child_sched_ctx, 1);
  241. starpu_sched_ctx_revert_task_counters_ctx_locked(sched_ctx_id, task->flops);
  242. return 1;
  243. }
  244. return 0;
  245. }
  246. /** Go through the list of deferred ctx changes of the current worker and apply
  247. * any ctx change operation found until the list is empty */
  248. void _starpu_worker_apply_deferred_ctx_changes(void);
  249. #pragma GCC visibility pop
  250. #endif // __SCHED_CONTEXT_H__