component_eager.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2013 Inria
  4. * Copyright (C) 2017 CNRS
  5. * Copyright (C) 2014-2018 Université de Bordeaux
  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 <starpu_scheduler.h>
  20. struct _starpu_eager_data
  21. {
  22. struct starpu_sched_component *target;
  23. starpu_pthread_mutex_t scheduling_mutex;
  24. };
  25. static int eager_push_task(struct starpu_sched_component * component, struct starpu_task * task)
  26. {
  27. int ret;
  28. STARPU_ASSERT(component && task && starpu_sched_component_is_eager(component));
  29. STARPU_ASSERT(starpu_sched_component_can_execute_task(component,task));
  30. struct _starpu_eager_data *d = component->data;
  31. struct starpu_sched_component *target;
  32. if ((target = d->target))
  33. {
  34. /* target told us we could push to it, try to */
  35. int idworker;
  36. for(idworker = starpu_bitmap_first(target->workers);
  37. idworker != -1;
  38. idworker = starpu_bitmap_next(target->workers, idworker))
  39. {
  40. int nimpl;
  41. for(nimpl = 0; nimpl < STARPU_MAXIMPLEMENTATIONS; nimpl++)
  42. {
  43. if(starpu_worker_can_execute_task(idworker,task,nimpl)
  44. || starpu_combined_worker_can_execute_task(idworker, task, nimpl))
  45. {
  46. ret = starpu_sched_component_push_task(component,target,task);
  47. if (!ret)
  48. return 0;
  49. }
  50. }
  51. }
  52. }
  53. int workerid;
  54. for(workerid = starpu_bitmap_first(component->workers_in_ctx);
  55. workerid != -1;
  56. workerid = starpu_bitmap_next(component->workers_in_ctx, workerid))
  57. {
  58. int nimpl;
  59. for(nimpl = 0; nimpl < STARPU_MAXIMPLEMENTATIONS; nimpl++)
  60. {
  61. if(starpu_worker_can_execute_task(workerid,task,nimpl)
  62. || starpu_combined_worker_can_execute_task(workerid, task, nimpl))
  63. {
  64. unsigned i;
  65. for (i = 0; i < component->nchildren; i++)
  66. {
  67. int idworker;
  68. for(idworker = starpu_bitmap_first(component->children[i]->workers);
  69. idworker != -1;
  70. idworker = starpu_bitmap_next(component->children[i]->workers, idworker))
  71. {
  72. if (idworker == workerid)
  73. {
  74. if(starpu_sched_component_is_worker(component->children[i]))
  75. {
  76. if (component->children[i]->can_pull(component->children[i]))
  77. return 1;
  78. }
  79. else
  80. {
  81. ret = starpu_sched_component_push_task(component,component->children[i],task);
  82. if (!ret)
  83. return 0;
  84. }
  85. }
  86. }
  87. }
  88. }
  89. }
  90. }
  91. return 1;
  92. }
  93. /* Note: we can't use starpu_sched_component_pump_to because if a fifo below
  94. * refuses a task, we have no way to push it back to a fifo above. */
  95. static int eager_can_push(struct starpu_sched_component * component, struct starpu_sched_component * to)
  96. {
  97. int success;
  98. struct _starpu_eager_data *d = component->data;
  99. STARPU_COMPONENT_MUTEX_LOCK(&d->scheduling_mutex);
  100. /* Target flow of tasks to this child */
  101. d->target = to;
  102. success = starpu_sched_component_can_push(component, to);
  103. d->target = NULL;
  104. STARPU_COMPONENT_MUTEX_UNLOCK(&d->scheduling_mutex);
  105. return success;
  106. }
  107. static void eager_deinit_data(struct starpu_sched_component *component)
  108. {
  109. STARPU_ASSERT(starpu_sched_component_is_eager(component));
  110. struct _starpu_eager_data *d = component->data;
  111. STARPU_PTHREAD_MUTEX_DESTROY(&d->scheduling_mutex);
  112. free(d);
  113. }
  114. int starpu_sched_component_is_eager(struct starpu_sched_component * component)
  115. {
  116. return component->push_task == eager_push_task;
  117. }
  118. struct starpu_sched_component * starpu_sched_component_eager_create(struct starpu_sched_tree *tree, void *arg)
  119. {
  120. (void)arg;
  121. struct starpu_sched_component * component = starpu_sched_component_create(tree, "eager");
  122. struct _starpu_eager_data *data;
  123. _STARPU_MALLOC(data, sizeof(*data));
  124. data->target = NULL;
  125. STARPU_PTHREAD_MUTEX_INIT(&data->scheduling_mutex, NULL);
  126. component->data = data;
  127. component->push_task = eager_push_task;
  128. component->can_push = eager_can_push;
  129. component->deinit_data = eager_deinit_data;
  130. return component;
  131. }