node_calibrator.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2013 Marc Sergent
  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_node.h>
  17. #include <starpu_scheduler.h>
  18. struct _starpu_calibrator_data
  19. {
  20. struct starpu_sched_node * no_perf_model_node;
  21. struct starpu_sched_node * next_node;
  22. };
  23. static int calibrator_push_task(struct starpu_sched_node * node, struct starpu_task * task)
  24. {
  25. STARPU_ASSERT(node && node->data && task && starpu_sched_node_is_calibrator(node));
  26. STARPU_ASSERT(starpu_sched_node_can_execute_task(node,task));
  27. struct _starpu_calibrator_data * data = node->data;
  28. starpu_task_bundle_t bundle = task->bundle;
  29. int workerid;
  30. for(workerid = starpu_bitmap_first(node->workers_in_ctx);
  31. workerid != -1;
  32. workerid = starpu_bitmap_next(node->workers_in_ctx, workerid))
  33. {
  34. struct starpu_perfmodel_arch* archtype = starpu_worker_get_perf_archtype(workerid);
  35. int nimpl;
  36. for(nimpl = 0; nimpl < STARPU_MAXIMPLEMENTATIONS; nimpl++)
  37. {
  38. if(starpu_worker_can_execute_task(workerid,task,nimpl)
  39. || starpu_combined_worker_can_execute_task(workerid, task, nimpl))
  40. {
  41. double d;
  42. if(bundle)
  43. d = starpu_task_bundle_expected_length(bundle, archtype, nimpl);
  44. else
  45. d = starpu_task_expected_length(task, archtype, nimpl);
  46. if(isnan(d))
  47. {
  48. int i;
  49. for (i = 0; i < node->nchilds; i++)
  50. {
  51. int idworker;
  52. for(idworker = starpu_bitmap_first(node->childs[i]->workers);
  53. idworker != -1;
  54. idworker = starpu_bitmap_next(node->childs[i]->workers, idworker))
  55. {
  56. if (idworker == workerid)
  57. return node->childs[i]->push_task(node->childs[i],task);
  58. }
  59. }
  60. }
  61. if(_STARPU_IS_ZERO(d))
  62. return data->no_perf_model_node->push_task(data->no_perf_model_node,task);
  63. }
  64. }
  65. }
  66. return data->next_node->push_task(data->next_node,task);
  67. }
  68. int starpu_sched_node_is_calibrator(struct starpu_sched_node * node)
  69. {
  70. return node->push_task == calibrator_push_task;
  71. }
  72. void calibrator_add_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
  73. {
  74. STARPU_ASSERT(starpu_sched_node_is_calibrator(node));
  75. starpu_sched_node_add_child(node, child);
  76. struct _starpu_calibrator_data * data = node->data;
  77. starpu_sched_node_add_child(data->no_perf_model_node,child);
  78. starpu_sched_node_add_child(data->next_node, child);
  79. }
  80. void calibrator_remove_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
  81. {
  82. STARPU_ASSERT(starpu_sched_node_is_calibrator(node));
  83. starpu_sched_node_remove_child(node, child);
  84. struct _starpu_calibrator_data * data = node->data;
  85. starpu_sched_node_remove_child(data->no_perf_model_node,child);
  86. starpu_sched_node_remove_child(data->next_node, child);
  87. }
  88. static void calibrator_notify_change_in_workers(struct starpu_sched_node * node)
  89. {
  90. STARPU_ASSERT(starpu_sched_node_is_calibrator(node));
  91. struct _starpu_calibrator_data * data = node->data;
  92. starpu_bitmap_unset_all(data->no_perf_model_node->workers_in_ctx);
  93. starpu_bitmap_unset_all(data->no_perf_model_node->workers);
  94. starpu_bitmap_or(data->no_perf_model_node->workers_in_ctx, node->workers_in_ctx);
  95. starpu_bitmap_or(data->no_perf_model_node->workers, node->workers);
  96. data->no_perf_model_node->properties = node->properties;
  97. starpu_bitmap_unset_all(data->next_node->workers_in_ctx);
  98. starpu_bitmap_unset_all(data->next_node->workers);
  99. starpu_bitmap_or(data->next_node->workers_in_ctx, node->workers_in_ctx);
  100. starpu_bitmap_or(data->next_node->workers, node->workers);
  101. data->next_node->properties = node->properties;
  102. }
  103. void calibrator_node_deinit_data(struct starpu_sched_node * node)
  104. {
  105. STARPU_ASSERT(node && node->data);
  106. struct _starpu_calibrator_data * d = node->data;
  107. starpu_sched_node_destroy(d->no_perf_model_node);
  108. starpu_sched_node_destroy(d->next_node);
  109. free(d);
  110. }
  111. struct starpu_sched_node * starpu_sched_node_calibrator_create(struct starpu_calibrator_data * params)
  112. {
  113. STARPU_ASSERT(params);
  114. struct starpu_sched_node * node = starpu_sched_node_create();
  115. struct _starpu_calibrator_data * data = malloc(sizeof(*data));
  116. data->no_perf_model_node = params->no_perf_model_node_create(params->arg_no_perf_model);
  117. data->next_node = params->next_node;
  118. node->data = data;
  119. node->push_task = calibrator_push_task;
  120. node->add_child = calibrator_add_child;
  121. node->remove_child = calibrator_remove_child;
  122. node->deinit_data = calibrator_node_deinit_data;
  123. node->notify_change_workers = calibrator_notify_change_in_workers;
  124. return node;
  125. }