node_best_implementation.c 2.5 KB

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