sc_config.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2011-2013,2016 Inria
  4. * Copyright (C) 2012,2013,2016,2017 CNRS
  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. #include <sc_hypervisor_intern.h>
  18. static struct sc_hypervisor_policy_config* _create_config(void)
  19. {
  20. struct sc_hypervisor_policy_config *config = (struct sc_hypervisor_policy_config *)malloc(sizeof(struct sc_hypervisor_policy_config));
  21. config->min_nworkers = -1;
  22. config->max_nworkers = -1;
  23. config->new_workers_max_idle = -1.0;
  24. config->ispeed_ctx_sample = 0.0;
  25. config->time_sample = 0.5;
  26. int i;
  27. for(i = 0; i < STARPU_NMAXWORKERS; i++)
  28. {
  29. config->granularity = -1;
  30. config->priority[i] = -1;
  31. config->fixed_workers[i] = -1;
  32. config->max_idle[i] = -1.0;
  33. config->min_working[i] = -1.0;
  34. config->ispeed_w_sample[i] = 0.0;
  35. }
  36. return config;
  37. }
  38. static void _update_config(struct sc_hypervisor_policy_config *old, struct sc_hypervisor_policy_config* new)
  39. {
  40. old->min_nworkers = new->min_nworkers != -1 ? new->min_nworkers : old->min_nworkers ;
  41. old->max_nworkers = new->max_nworkers != -1 ? new->max_nworkers : old->max_nworkers ;
  42. old->new_workers_max_idle = new->new_workers_max_idle != -1.0 ? new->new_workers_max_idle : old->new_workers_max_idle;
  43. old->granularity = new->granularity != -1 ? new->granularity : old->granularity;
  44. int i;
  45. for(i = 0; i < STARPU_NMAXWORKERS; i++)
  46. {
  47. old->priority[i] = new->priority[i] != -1 ? new->priority[i] : old->priority[i];
  48. old->fixed_workers[i] = new->fixed_workers[i] != -1 ? new->fixed_workers[i] : old->fixed_workers[i];
  49. old->max_idle[i] = new->max_idle[i] != -1.0 ? new->max_idle[i] : old->max_idle[i];
  50. old->min_working[i] = new->min_working[i] != -1.0 ? new->min_working[i] : old->min_working[i];
  51. }
  52. }
  53. void sc_hypervisor_set_config(unsigned sched_ctx, void *config)
  54. {
  55. if(hypervisor.sched_ctx_w[sched_ctx].config != NULL && config != NULL)
  56. {
  57. _update_config(hypervisor.sched_ctx_w[sched_ctx].config, config);
  58. }
  59. else
  60. {
  61. hypervisor.sched_ctx_w[sched_ctx].config = config;
  62. }
  63. return;
  64. }
  65. void _add_config(unsigned sched_ctx)
  66. {
  67. struct sc_hypervisor_policy_config *config = _create_config();
  68. config->min_nworkers = 0;
  69. config->max_nworkers = starpu_worker_get_count();
  70. config->new_workers_max_idle = MAX_IDLE_TIME;
  71. int i;
  72. for(i = 0; i < STARPU_NMAXWORKERS; i++)
  73. {
  74. config->granularity = 1;
  75. config->priority[i] = 0;
  76. config->fixed_workers[i] = 0;
  77. config->max_idle[i] = MAX_IDLE_TIME;
  78. config->min_working[i] = MIN_WORKING_TIME;
  79. }
  80. sc_hypervisor_set_config(sched_ctx, config);
  81. }
  82. void _remove_config(unsigned sched_ctx)
  83. {
  84. sc_hypervisor_set_config(sched_ctx, NULL);
  85. }
  86. struct sc_hypervisor_policy_config* sc_hypervisor_get_config(unsigned sched_ctx)
  87. {
  88. return hypervisor.sched_ctx_w[sched_ctx].config;
  89. }
  90. static struct sc_hypervisor_policy_config* _ctl(unsigned sched_ctx, va_list varg_list, unsigned later)
  91. {
  92. struct sc_hypervisor_policy_config *config = NULL;
  93. if(later)
  94. config = _create_config();
  95. else
  96. config = sc_hypervisor_get_config(sched_ctx);
  97. assert(config != NULL);
  98. int arg_type;
  99. int i;
  100. int *workerids;
  101. int nworkers;
  102. while ((arg_type = va_arg(varg_list, int)) != SC_HYPERVISOR_NULL)
  103. {
  104. switch(arg_type)
  105. {
  106. case SC_HYPERVISOR_MAX_IDLE:
  107. workerids = va_arg(varg_list, int*);
  108. nworkers = va_arg(varg_list, int);
  109. double max_idle = va_arg(varg_list, double);
  110. for(i = 0; i < nworkers; i++)
  111. config->max_idle[workerids[i]] = max_idle;
  112. break;
  113. case SC_HYPERVISOR_MIN_WORKING:
  114. workerids = va_arg(varg_list, int*);
  115. nworkers = va_arg(varg_list, int);
  116. double min_working = va_arg(varg_list, double);
  117. for(i = 0; i < nworkers; i++)
  118. config->min_working[workerids[i]] = min_working;
  119. break;
  120. case SC_HYPERVISOR_PRIORITY:
  121. workerids = va_arg(varg_list, int*);
  122. nworkers = va_arg(varg_list, int);
  123. int priority = va_arg(varg_list, int);
  124. for(i = 0; i < nworkers; i++)
  125. config->priority[workerids[i]] = priority;
  126. break;
  127. case SC_HYPERVISOR_MIN_WORKERS:
  128. config->min_nworkers = va_arg(varg_list, unsigned);
  129. break;
  130. case SC_HYPERVISOR_MAX_WORKERS:
  131. config->max_nworkers = va_arg(varg_list, unsigned);
  132. break;
  133. case SC_HYPERVISOR_GRANULARITY:
  134. config->granularity = va_arg(varg_list, unsigned);
  135. break;
  136. case SC_HYPERVISOR_FIXED_WORKERS:
  137. workerids = va_arg(varg_list, int*);
  138. nworkers = va_arg(varg_list, int);
  139. for(i = 0; i < nworkers; i++)
  140. config->fixed_workers[workerids[i]] = 1;
  141. break;
  142. case SC_HYPERVISOR_NEW_WORKERS_MAX_IDLE:
  143. config->new_workers_max_idle = va_arg(varg_list, double);
  144. break;
  145. case SC_HYPERVISOR_ISPEED_W_SAMPLE:
  146. workerids = va_arg(varg_list, int*);
  147. nworkers = va_arg(varg_list, int);
  148. double sample = va_arg(varg_list, double);
  149. for(i = 0; i < nworkers; i++)
  150. config->ispeed_w_sample[workerids[i]] = sample;
  151. break;
  152. case SC_HYPERVISOR_ISPEED_CTX_SAMPLE:
  153. config->ispeed_ctx_sample = va_arg(varg_list, double);
  154. break;
  155. case SC_HYPERVISOR_TIME_SAMPLE:
  156. config->time_sample = va_arg(varg_list, double);
  157. break;
  158. /* not important for the strateg, needed just to jump these args in the iteration of the args */
  159. case SC_HYPERVISOR_TIME_TO_APPLY:
  160. va_arg(varg_list, int);
  161. break;
  162. case SC_HYPERVISOR_MIN_TASKS:
  163. va_arg(varg_list, int);
  164. break;
  165. }
  166. }
  167. return later ? config : NULL;
  168. }
  169. void sc_hypervisor_ctl(unsigned sched_ctx, ...)
  170. {
  171. va_list varg_list;
  172. va_start(varg_list, sched_ctx);
  173. int arg_type;
  174. int stop = 0;
  175. int task_tag = -1;
  176. while ((arg_type = va_arg(varg_list, int)) != SC_HYPERVISOR_NULL)
  177. {
  178. switch(arg_type)
  179. {
  180. case SC_HYPERVISOR_TIME_TO_APPLY:
  181. task_tag = va_arg(varg_list, int);
  182. stop = 1;
  183. break;
  184. case SC_HYPERVISOR_MIN_TASKS:
  185. hypervisor.min_tasks = va_arg(varg_list, int);
  186. hypervisor.check_min_tasks[sched_ctx] = 1;
  187. break;
  188. }
  189. if(stop) break;
  190. }
  191. va_end(varg_list);
  192. va_start(varg_list, sched_ctx);
  193. /* if config not null => save hypervisor configuration and consider it later */
  194. struct sc_hypervisor_policy_config *config = _ctl(sched_ctx, varg_list, (task_tag > 0));
  195. if(config != NULL)
  196. {
  197. struct configuration_entry *entry;
  198. entry = malloc(sizeof *entry);
  199. STARPU_ASSERT(entry != NULL);
  200. entry->task_tag = task_tag;
  201. entry->configuration = config;
  202. STARPU_PTHREAD_MUTEX_LOCK(&hypervisor.conf_mut[sched_ctx]);
  203. HASH_ADD_INT(hypervisor.configurations[sched_ctx], task_tag, entry);
  204. STARPU_PTHREAD_MUTEX_UNLOCK(&hypervisor.conf_mut[sched_ctx]);
  205. }
  206. va_end(varg_list);
  207. }