node_random.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <core/workers.h>
  2. #include "node_sched.h"
  3. struct _starpu_random_data
  4. {
  5. double * relative_speedup;
  6. };
  7. static double compute_relative_speedup(struct _starpu_sched_node * node)
  8. {
  9. if(_starpu_sched_node_is_worker(node))
  10. {
  11. int id = _starpu_sched_node_worker_get_workerid(node);
  12. enum starpu_perfmodel_archtype perf_arch = starpu_worker_get_perf_archtype(id);
  13. return starpu_worker_get_relative_speedup(perf_arch);
  14. }
  15. double sum = 0.0;
  16. int i;
  17. for(i = 0; i < node->nchilds; i++)
  18. sum += compute_relative_speedup(node->childs[i]);
  19. return sum;
  20. }
  21. static void init_data_random(struct _starpu_sched_node * node)
  22. {
  23. struct _starpu_random_data * rd = malloc(sizeof(struct _starpu_random_data));
  24. node->data = rd;
  25. rd->relative_speedup = malloc(sizeof(double) * node->nchilds);
  26. int i;
  27. for(i = 0; i < node->nchilds; i++)
  28. rd->relative_speedup[i] = compute_relative_speedup(node->childs[i]);
  29. }
  30. static void deinit_data_random(struct _starpu_sched_node * node)
  31. {
  32. struct _starpu_random_data * rd = node->data;
  33. free(rd->relative_speedup);
  34. free(rd);
  35. }
  36. static int push_task(struct _starpu_sched_node * node, struct starpu_task * task)
  37. {
  38. struct _starpu_random_data * rd = node->data;
  39. int indexes_nodes[node->nchilds];
  40. int size=0,i;
  41. double alpha_sum = 0.0;
  42. for(i = 0; i < node->nchilds ; i++)
  43. {
  44. if(_starpu_sched_node_can_execute_task(node->childs[i],task))
  45. {
  46. indexes_nodes[size++] = i;
  47. alpha_sum += rd->relative_speedup[i];
  48. }
  49. }
  50. double random = starpu_drand48()*alpha_sum;
  51. double alpha = 0.0;
  52. struct _starpu_sched_node * select = NULL;
  53. for(i = 0; i < size ; i++)
  54. {
  55. int index = indexes_nodes[i];
  56. if(alpha + rd->relative_speedup[index] >= random)
  57. {
  58. select = node->childs[index];
  59. break;
  60. }
  61. alpha += rd->relative_speedup[index];
  62. }
  63. STARPU_ASSERT(select != NULL);
  64. int ret_val = select->push_task(select,task);
  65. node->available(node);
  66. return ret_val;
  67. }
  68. struct _starpu_sched_node * _starpu_sched_node_random_create(void * arg STARPU_ATTRIBUTE_UNUSED)
  69. {
  70. struct _starpu_sched_node * node = _starpu_sched_node_create();
  71. node->data = NULL;
  72. node->init_data = init_data_random;
  73. node->deinit_data = deinit_data_random;
  74. node->push_task = push_task;
  75. starpu_srand48(time(NULL));
  76. return node;
  77. }
  78. int _starpu_sched_node_is_random(struct _starpu_sched_node *node)
  79. {
  80. return node->init_data == init_data_random;
  81. }
  82. static void initialize_random_center_policy(unsigned sched_ctx_id)
  83. {
  84. starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
  85. struct _starpu_sched_tree *data = malloc(sizeof(struct _starpu_sched_tree));
  86. STARPU_PTHREAD_RWLOCK_INIT(&data->lock,NULL);
  87. data->root = _starpu_sched_node_random_create(NULL);
  88. data->workers = _starpu_bitmap_create();
  89. unsigned i;
  90. for(i = 0; i < starpu_worker_get_count(); i++)
  91. {
  92. struct _starpu_sched_node * node = _starpu_sched_node_worker_get(i);
  93. if(!node)
  94. continue;
  95. node->fathers[sched_ctx_id] = data->root;
  96. _starpu_sched_node_add_child(data->root, node);
  97. }
  98. _starpu_set_workers_bitmaps();
  99. _starpu_tree_call_init_data(data);
  100. starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)data);
  101. }
  102. static void deinitialize_random_center_policy(unsigned sched_ctx_id)
  103. {
  104. struct _starpu_sched_tree *tree = (struct _starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
  105. _starpu_sched_tree_destroy(tree, sched_ctx_id);
  106. starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
  107. }
  108. struct starpu_sched_policy _starpu_sched_tree_random_policy =
  109. {
  110. .init_sched = initialize_random_center_policy,
  111. .deinit_sched = deinitialize_random_center_policy,
  112. .add_workers = _starpu_tree_add_workers,
  113. .remove_workers = _starpu_tree_remove_workers,
  114. .push_task = _starpu_tree_push_task,
  115. .pop_task = _starpu_tree_pop_task,
  116. .pre_exec_hook = NULL,
  117. .post_exec_hook = NULL,
  118. .pop_every_task = NULL,
  119. .policy_name = "tree-random",
  120. .policy_description = "random tree policy"
  121. };