node_best_implementation.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include <starpu_sched_node.h>
  2. #include <starpu_scheduler.h>
  3. #include <float.h>
  4. /* set implementation, task->predicted and task->predicted_transfer with the first worker of workers that can execute that task
  5. * or have to be calibrated
  6. */
  7. static void select_best_implementation_and_set_preds(struct starpu_bitmap * workers, struct starpu_task * task)
  8. {
  9. int best_impl = -1;
  10. double len = DBL_MAX;
  11. int workerid;
  12. for(workerid = starpu_bitmap_first(workers);
  13. -1 != workerid;
  14. workerid = starpu_bitmap_next(workers, workerid))
  15. {
  16. int impl;
  17. for(impl = 0; impl < STARPU_MAXIMPLEMENTATIONS; impl++)
  18. {
  19. if(starpu_worker_can_execute_task(workerid, task, impl))
  20. {
  21. enum starpu_perfmodel_archtype archtype = starpu_worker_get_perf_archtype(workerid);
  22. double d = starpu_task_expected_length(task, archtype, impl);
  23. if(isnan(d))
  24. {
  25. best_impl = impl;
  26. len = 0.0;
  27. break;
  28. }
  29. if(d < len)
  30. {
  31. len = d;
  32. best_impl = impl;
  33. }
  34. }
  35. }
  36. if(best_impl != -1)
  37. break;
  38. }
  39. int memory_node = starpu_worker_get_memory_node(workerid);
  40. task->predicted = len;
  41. task->predicted_transfer = starpu_task_expected_data_transfer_time(memory_node, task);
  42. starpu_task_set_implementation(task, best_impl);
  43. }
  44. static int select_best_implementation_push_task(struct starpu_sched_node * node, struct starpu_task * task)
  45. {
  46. STARPU_ASSERT(node->nchilds == 1);
  47. select_best_implementation_and_set_preds(node->workers_in_ctx, task);
  48. return node->childs[0]->push_task(node->childs[0],task);
  49. }
  50. static struct starpu_task * select_best_implementation_pop_task(struct starpu_sched_node * node, unsigned sched_ctx_id)
  51. {
  52. struct starpu_task * t;
  53. STARPU_ASSERT(node->is_homogeneous);
  54. if(!node->fathers[sched_ctx_id])
  55. return NULL;
  56. t = node->fathers[sched_ctx_id]->pop_task(node->fathers[sched_ctx_id], sched_ctx_id);
  57. if(t)
  58. select_best_implementation_and_set_preds(node->workers_in_ctx, t);
  59. return t;
  60. }
  61. static int select_calibration_push_task(struct starpu_sched_node * node, struct starpu_task * task)
  62. {
  63. STARPU_ASSERT(node->nchilds == 1);
  64. select_best_implementation_and_set_preds(node->workers_in_ctx, task);
  65. return node->childs[0]->push_task(node->childs[0],task);
  66. }
  67. static struct starpu_task * select_calibration_pop_task(struct starpu_sched_node * node, unsigned sched_ctx_id)
  68. {
  69. struct starpu_task * t;
  70. if(!node->fathers[sched_ctx_id])
  71. return NULL;
  72. t = node->fathers[sched_ctx_id]->pop_task(node->fathers[sched_ctx_id], sched_ctx_id);
  73. if(t)
  74. select_best_implementation_and_set_preds(node->workers_in_ctx, t);
  75. return t;
  76. }
  77. struct starpu_sched_node * starpu_sched_node_best_implementation_create(void * ARG STARPU_ATTRIBUTE_UNUSED)
  78. {
  79. struct starpu_sched_node * node = starpu_sched_node_create();
  80. node->push_task = select_best_implementation_push_task;
  81. node->pop_task = select_best_implementation_pop_task;
  82. return node;
  83. }
  84. struct starpu_sched_node * starpu_sched_node_calibration_create(void * arg STARPU_ATTRIBUTE_UNUSED)
  85. {
  86. struct starpu_sched_node * node = starpu_sched_node_create();
  87. node->push_task = select_calibration_push_task;
  88. node->pop_task = select_calibration_pop_task;
  89. return node;
  90. }