component_eager.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2013-2020 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
  4. *
  5. * StarPU is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 2.1 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * StarPU is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. */
  16. #include <starpu_sched_component.h>
  17. #include <starpu_scheduler.h>
  18. struct _starpu_eager_data
  19. {
  20. struct starpu_sched_component *target;
  21. starpu_pthread_mutex_t scheduling_mutex;
  22. };
  23. static int eager_push_task(struct starpu_sched_component * component, struct starpu_task * task)
  24. {
  25. int ret;
  26. STARPU_ASSERT(component && task && starpu_sched_component_is_eager(component));
  27. STARPU_ASSERT(starpu_sched_component_can_execute_task(component,task));
  28. struct _starpu_eager_data *d = component->data;
  29. struct starpu_sched_component *target;
  30. if ((target = d->target))
  31. {
  32. /* target told us we could push to it, try to */
  33. int idworker;
  34. for(idworker = starpu_bitmap_first(&target->workers);
  35. idworker != -1;
  36. idworker = starpu_bitmap_next(&target->workers, idworker))
  37. {
  38. int nimpl;
  39. for(nimpl = 0; nimpl < STARPU_MAXIMPLEMENTATIONS; nimpl++)
  40. {
  41. if(starpu_worker_can_execute_task(idworker,task,nimpl)
  42. || starpu_combined_worker_can_execute_task(idworker, task, nimpl))
  43. {
  44. ret = starpu_sched_component_push_task(component,target,task);
  45. if (!ret)
  46. return 0;
  47. }
  48. }
  49. }
  50. }
  51. /* FIXME: should rather just loop over children before looping over its workers */
  52. int workerid;
  53. for(workerid = starpu_bitmap_first(&component->workers_in_ctx);
  54. workerid != -1;
  55. workerid = starpu_bitmap_next(&component->workers_in_ctx, workerid))
  56. {
  57. int nimpl;
  58. for(nimpl = 0; nimpl < STARPU_MAXIMPLEMENTATIONS; nimpl++)
  59. {
  60. /* FIXME: use starpu_worker_can_execute_task_first_impl instead */
  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->can_pull = starpu_sched_component_can_pull_all;
  130. component->deinit_data = eager_deinit_data;
  131. return component;
  132. }