component_best_implementation.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2013 Inria
  4. * Copyright (C) 2014,2016,2017 CNRS
  5. * Copyright (C) 2014-2018,2020 Université de Bordeaux
  6. * Copyright (C) 2013 Simon Archipoff
  7. *
  8. * StarPU is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU Lesser General Public License as published by
  10. * the Free Software Foundation; either version 2.1 of the License, or (at
  11. * your option) any later version.
  12. *
  13. * StarPU is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16. *
  17. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  18. */
  19. #include <float.h>
  20. #include <starpu_sched_component.h>
  21. #include <starpu_scheduler.h>
  22. #include <core/workers.h>
  23. /* return true if workerid can execute task, and fill task->predicted and task->predicted_transfer
  24. * according to best implementation predictions
  25. */
  26. static int find_best_impl(unsigned sched_ctx_id, struct starpu_task * task, int workerid)
  27. {
  28. double len = DBL_MAX;
  29. int best_impl = -1;
  30. unsigned impl;
  31. if (!task->cl->model)
  32. {
  33. /* No perfmodel, first available will be fine */
  34. starpu_worker_can_execute_task_first_impl(workerid, task, &impl);
  35. best_impl = impl;
  36. len = 0.0;
  37. }
  38. else
  39. {
  40. struct starpu_perfmodel_arch* archtype = starpu_worker_get_perf_archtype(workerid, sched_ctx_id);
  41. for(impl = 0; impl < STARPU_MAXIMPLEMENTATIONS; impl++)
  42. {
  43. if(starpu_worker_can_execute_task(workerid, task, impl))
  44. {
  45. double d = starpu_task_expected_length(task, archtype, impl);
  46. if(isnan(d))
  47. {
  48. best_impl = impl;
  49. len = 0.0;
  50. break;
  51. }
  52. if(d < len)
  53. {
  54. len = d;
  55. best_impl = impl;
  56. }
  57. }
  58. }
  59. }
  60. if(best_impl == -1)
  61. return 0;
  62. task->predicted = len;
  63. task->predicted_transfer = starpu_task_expected_data_transfer_time_for(task, workerid);
  64. starpu_task_set_implementation(task, best_impl);
  65. return 1;
  66. }
  67. /* set implementation, task->predicted and task->predicted_transfer with the first worker of workers that can execute that task
  68. * or have to be calibrated
  69. */
  70. static void select_best_implementation_and_set_preds(unsigned sched_ctx_id, struct starpu_bitmap * workers, struct starpu_task * task)
  71. {
  72. int workerid;
  73. for(workerid = starpu_bitmap_first(workers);
  74. -1 != workerid;
  75. workerid = starpu_bitmap_next(workers, workerid))
  76. if(find_best_impl(sched_ctx_id, task, workerid))
  77. break;
  78. }
  79. static int best_implementation_push_task(struct starpu_sched_component * component, struct starpu_task * task)
  80. {
  81. STARPU_ASSERT(component->nchildren == 1);
  82. select_best_implementation_and_set_preds(component->tree->sched_ctx_id, component->workers_in_ctx, task);
  83. return starpu_sched_component_push_task(component,component->children[0],task);
  84. }
  85. int starpu_sched_component_is_best_implementation(struct starpu_sched_component * component)
  86. {
  87. return component->push_task == best_implementation_push_task;
  88. }
  89. static struct starpu_task * best_implementation_pull_task(struct starpu_sched_component * component, struct starpu_sched_component * from STARPU_ATTRIBUTE_UNUSED)
  90. {
  91. struct starpu_task * task = NULL;
  92. unsigned i;
  93. for(i=0; i < component->nparents; i++)
  94. {
  95. if(component->parents[i] == NULL)
  96. continue;
  97. else
  98. {
  99. task = starpu_sched_component_pull_task(component->parents[i], component);
  100. if(task)
  101. break;
  102. }
  103. }
  104. if(task)
  105. /* this worker can execute this task as it was returned by a pop*/
  106. (void)find_best_impl(component->tree->sched_ctx_id, task, starpu_worker_get_id_check());
  107. return task;
  108. }
  109. struct starpu_sched_component * starpu_sched_component_best_implementation_create(struct starpu_sched_tree *tree, void *arg)
  110. {
  111. (void)arg;
  112. struct starpu_sched_component * component = starpu_sched_component_create(tree, "best_impl");
  113. component->push_task = best_implementation_push_task;
  114. component->pull_task = best_implementation_pull_task;
  115. return component;
  116. }