helper_mct.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2013-2014, 2016-2017 Université de Bordeaux
  4. * Copyright (C) 2013, 2017 INRIA
  5. * Copyright (C) 2013 Simon Archipoff
  6. *
  7. * StarPU is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation; either version 2.1 of the License, or (at
  10. * your option) any later version.
  11. *
  12. * StarPU is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. *
  16. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  17. */
  18. #include <starpu_sched_component.h>
  19. #include "helper_mct.h"
  20. /* Alpha, Beta and Gamma are MCT-specific values, which allows the
  21. * user to set more precisely the weight of each computing value.
  22. * Beta, for example, controls the weight of communications between
  23. * memories for the computation of the best component to choose.
  24. */
  25. #define _STARPU_SCHED_ALPHA_DEFAULT 1.0
  26. #define _STARPU_SCHED_BETA_DEFAULT 1.0
  27. #define _STARPU_SCHED_GAMMA_DEFAULT 1000.0
  28. #ifdef STARPU_USE_TOP
  29. static void param_modified(struct starpu_top_param* d)
  30. {
  31. /* Just to show parameter modification. */
  32. _STARPU_MSG("%s has been modified : %f\n", d->name, *(double*) d->value);
  33. }
  34. #endif /* !STARPU_USE_TOP */
  35. #ifdef STARPU_USE_TOP
  36. static const float alpha_minimum=0;
  37. static const float alpha_maximum=10.0;
  38. static const float beta_minimum=0;
  39. static const float beta_maximum=10.0;
  40. static const float gamma_minimum=0;
  41. static const float gamma_maximum=10000.0;
  42. static const float idle_power_minimum=0;
  43. static const float idle_power_maximum=10000.0;
  44. #endif /* !STARPU_USE_TOP */
  45. struct _starpu_mct_data *starpu_mct_init_parameters(struct starpu_sched_component_mct_data *params)
  46. {
  47. struct _starpu_mct_data *data;
  48. _STARPU_MALLOC(data, sizeof(*data));
  49. if (params)
  50. {
  51. data->alpha = params->alpha;
  52. data->beta = params->beta;
  53. data->_gamma = params->_gamma;
  54. data->idle_power = params->idle_power;
  55. }
  56. else
  57. {
  58. data->alpha = starpu_get_env_float_default("STARPU_SCHED_ALPHA", _STARPU_SCHED_ALPHA_DEFAULT);
  59. data->beta = starpu_get_env_float_default("STARPU_SCHED_BETA", _STARPU_SCHED_BETA_DEFAULT);
  60. data->_gamma = starpu_get_env_float_default("STARPU_SCHED_GAMMA", _STARPU_SCHED_GAMMA_DEFAULT);
  61. data->idle_power = starpu_get_env_float_default("STARPU_IDLE_POWER", 0.0);
  62. }
  63. #ifdef STARPU_USE_TOP
  64. starpu_top_register_parameter_float("MCT_ALPHA", &data->alpha,
  65. alpha_minimum, alpha_maximum, param_modified);
  66. starpu_top_register_parameter_float("MCT_BETA", &data->beta,
  67. beta_minimum, beta_maximum, param_modified);
  68. starpu_top_register_parameter_float("MCT_GAMMA", &data->_gamma,
  69. gamma_minimum, gamma_maximum, param_modified);
  70. starpu_top_register_parameter_float("MCT_IDLE_POWER", &data->idle_power,
  71. idle_power_minimum, idle_power_maximum, param_modified);
  72. #endif /* !STARPU_USE_TOP */
  73. return data;
  74. }
  75. /* compute predicted_end by taking into account the case of the predicted transfer and the predicted_end overlap
  76. */
  77. static double compute_expected_time(double now, double predicted_end, double predicted_length, double predicted_transfer)
  78. {
  79. STARPU_ASSERT(!isnan(now + predicted_end + predicted_length + predicted_transfer));
  80. STARPU_ASSERT_MSG(now >= 0.0 && predicted_end >= 0.0 && predicted_length >= 0.0 && predicted_transfer >= 0.0, "now=%lf, predicted_end=%lf, predicted_length=%lf, predicted_transfer=%lf\n", now, predicted_end, predicted_length, predicted_transfer);
  81. /* TODO: actually schedule transfers */
  82. /* Compute the transfer time which will not be overlapped */
  83. /* However, no modification in calling function so that the whole transfer time is counted as a penalty */
  84. if (now + predicted_transfer < predicted_end)
  85. {
  86. /* We may hope that the transfer will be finished by
  87. * the start of the task. */
  88. predicted_transfer = 0;
  89. }
  90. else
  91. {
  92. /* The transfer will not be finished by then, take the
  93. * remainder into account */
  94. predicted_transfer -= (predicted_end - now);
  95. }
  96. predicted_end += predicted_transfer;
  97. predicted_end += predicted_length;
  98. return predicted_end;
  99. }
  100. double starpu_mct_compute_fitness(struct _starpu_mct_data * d, double exp_end, double min_exp_end, double max_exp_end, double transfer_len, double local_energy)
  101. {
  102. /* Note: the expected end includes the data transfer duration, which we want to be able to tune separately */
  103. return d->alpha * (exp_end - min_exp_end)
  104. + d->beta * transfer_len
  105. + d->_gamma * local_energy
  106. + d->_gamma * d->idle_power * (exp_end - max_exp_end);
  107. }
  108. unsigned starpu_mct_compute_execution_times(struct starpu_sched_component *component, struct starpu_task *task,
  109. double *estimated_lengths, double *estimated_transfer_length, unsigned *suitable_components)
  110. {
  111. unsigned nsuitable_components = 0;
  112. unsigned i;
  113. for(i = 0; i < component->nchildren; i++)
  114. {
  115. struct starpu_sched_component * c = component->children[i];
  116. if(starpu_sched_component_execute_preds(c, task, estimated_lengths + i))
  117. {
  118. if(isnan(estimated_lengths[i]))
  119. /* The perfmodel had been purged since the task was pushed
  120. * onto the mct component. */
  121. continue;
  122. STARPU_ASSERT_MSG(estimated_lengths[i]>=0, "component=%p, child[%u]=%p, estimated_lengths[%u]=%lf\n", component, i, c, i, estimated_lengths[i]);
  123. estimated_transfer_length[i] = starpu_sched_component_transfer_length(c, task);
  124. suitable_components[nsuitable_components++] = i;
  125. }
  126. }
  127. return nsuitable_components;
  128. }
  129. void starpu_mct_compute_expected_times(struct starpu_sched_component *component, struct starpu_task *task STARPU_ATTRIBUTE_UNUSED,
  130. double *estimated_lengths, double *estimated_transfer_length, double *estimated_ends_with_task,
  131. double *min_exp_end_with_task, double *max_exp_end_with_task, unsigned *suitable_components, unsigned nsuitable_components)
  132. {
  133. unsigned i;
  134. double now = starpu_timing_now();
  135. for(i = 0; i < nsuitable_components; i++)
  136. {
  137. unsigned icomponent = suitable_components[i];
  138. struct starpu_sched_component * c = component->children[icomponent];
  139. /* Estimated availability of worker */
  140. double estimated_end = c->estimated_end(c);
  141. if (estimated_end < now)
  142. estimated_end = now;
  143. estimated_ends_with_task[icomponent] = compute_expected_time(now,
  144. estimated_end,
  145. estimated_lengths[icomponent],
  146. estimated_transfer_length[icomponent]);
  147. if(estimated_ends_with_task[icomponent] < *min_exp_end_with_task)
  148. *min_exp_end_with_task = estimated_ends_with_task[icomponent];
  149. if(estimated_ends_with_task[icomponent] > *max_exp_end_with_task)
  150. *max_exp_end_with_task = estimated_ends_with_task[icomponent];
  151. }
  152. }