node_random.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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_perf_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 update_relative_childs_speedup(struct _starpu_sched_node * node)
  22. {
  23. struct _starpu_random_data * rd = node->data;
  24. rd->relative_speedup = realloc(rd->relative_speedup,sizeof(double) * node->nchilds);
  25. int i;
  26. for(i = 0; i < node->nchilds; i++)
  27. rd->relative_speedup[i] = compute_relative_speedup(node->childs[i]);
  28. }
  29. static void add_child(struct _starpu_sched_node *node,
  30. struct _starpu_sched_node *child,
  31. unsigned sched_ctx_id)
  32. {
  33. // STARPU_PTHREAD_RWLOCK_WRLOCK(&node->mutex);
  34. _starpu_sched_node_add_child(node, child, sched_ctx_id);
  35. update_relative_childs_speedup(node);
  36. // STARPU_PTHREAD_RWLOCK_UNLOCK(&node->mutex);
  37. }
  38. static void remove_child(struct _starpu_sched_node *node,
  39. struct _starpu_sched_node *child,
  40. unsigned sched_ctx_id)
  41. {
  42. // STARPU_PTHREAD_RWLOCK_WRLOCK(&node->mutex);
  43. _starpu_sched_node_remove_child(node, child, sched_ctx_id);
  44. update_relative_childs_speedup(node);
  45. // STARPU_PTHREAD_RWLOCK_UNLOCK(&node->mutex);
  46. }
  47. static int push_task(struct _starpu_sched_node * node, struct starpu_task * task)
  48. {
  49. struct _starpu_random_data * rd = node->data;
  50. // STARPU_PTHREAD_RWLOCK_RDLOCK(&node->mutex);
  51. int indexes_nodes[node->nchilds];
  52. int size=0,i;
  53. double alpha_sum = 0.0;
  54. for(i = 0; i < node->nchilds ; i++)
  55. {
  56. if(_starpu_sched_node_can_execute_task(node->childs[i],task))
  57. {
  58. indexes_nodes[size++] = i;
  59. alpha_sum += rd->relative_speedup[i];
  60. }
  61. }
  62. double random = starpu_drand48()*alpha_sum;
  63. double alpha = 0.0;
  64. struct _starpu_sched_node * select = NULL;
  65. for(i = 0; i < size ; i++)
  66. {
  67. int index = indexes_nodes[i];
  68. if(alpha + rd->relative_speedup[index] >= random)
  69. {
  70. select = node->childs[index];
  71. break;
  72. }
  73. alpha += rd->relative_speedup[index];
  74. }
  75. STARPU_ASSERT(select != NULL);
  76. int ret_val = select->push_task(select,task);
  77. node->available(node);
  78. // STARPU_PTHREAD_RWLOCK_UNLOCK(&node->mutex);
  79. return ret_val;
  80. }
  81. static void destroy_random_node(struct _starpu_sched_node * node)
  82. {
  83. struct _starpu_random_data * rd = node->data;
  84. free(rd->relative_speedup);
  85. free(rd);
  86. _starpu_sched_node_destroy(node);
  87. }
  88. struct _starpu_sched_node * _starpu_sched_node_random_create(void)
  89. {
  90. struct _starpu_sched_node * node = _starpu_sched_node_create();
  91. struct _starpu_random_data * rd = malloc(sizeof(struct _starpu_random_data));
  92. rd->relative_speedup = NULL;
  93. node->data = rd;
  94. node->destroy_node = destroy_random_node;
  95. node->push_task = push_task;
  96. node->add_child = add_child;
  97. node->remove_child = remove_child;
  98. starpu_srand48(time(NULL));
  99. return node;
  100. }
  101. static void initialize_random_center_policy(unsigned sched_ctx_id)
  102. {
  103. starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
  104. struct _starpu_sched_tree *data = malloc(sizeof(struct _starpu_sched_tree));
  105. STARPU_PTHREAD_RWLOCK_INIT(&data->mutex,NULL);
  106. data->root = _starpu_sched_node_random_create();
  107. starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)data);
  108. }
  109. static void deinitialize_random_center_policy(unsigned sched_ctx_id)
  110. {
  111. struct _starpu_sched_tree *tree = (struct _starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
  112. _starpu_tree_destroy(tree, sched_ctx_id);
  113. starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
  114. }
  115. static void add_worker_random(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
  116. {
  117. struct _starpu_sched_tree *t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
  118. // STARPU_PTHREAD_RWLOCK_WRLOCK(&t->mutex);
  119. struct _starpu_sched_node * random_node = t->root;
  120. unsigned i;
  121. for(i = 0; i < nworkers; i++)
  122. {
  123. struct _starpu_sched_node * worker = _starpu_sched_node_worker_get(workerids[i]);
  124. t->root->add_child(random_node, _starpu_sched_node_worker_get(workerids[i]), sched_ctx_id);
  125. _starpu_sched_node_set_father(worker, random_node, sched_ctx_id);
  126. }
  127. _starpu_tree_update_after_modification(t);
  128. update_relative_childs_speedup(random_node);
  129. // STARPU_PTHREAD_RWLOCK_UNLOCK(&t->mutex);
  130. }
  131. static void remove_worker_random(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
  132. {
  133. struct _starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
  134. STARPU_PTHREAD_RWLOCK_WRLOCK(&t->mutex);
  135. struct _starpu_sched_node * random_node = t->root;
  136. unsigned i;
  137. for(i = 0; i < nworkers; i++)
  138. {
  139. struct _starpu_sched_node * worker = _starpu_sched_node_worker_get(workerids[i]);
  140. random_node->remove_child(random_node, worker, sched_ctx_id);
  141. _starpu_sched_node_set_father(worker, NULL, sched_ctx_id);
  142. }
  143. _starpu_tree_update_after_modification(t);
  144. update_relative_childs_speedup(t->root);
  145. // STARPU_PTHREAD_RWLOCK_UNLOCK(&t->mutex);
  146. }
  147. struct starpu_sched_policy _starpu_sched_tree_random_policy =
  148. {
  149. .init_sched = initialize_random_center_policy,
  150. .deinit_sched = deinitialize_random_center_policy,
  151. .add_workers = add_worker_random,
  152. .remove_workers = remove_worker_random,
  153. .push_task = _starpu_tree_push_task,
  154. .pop_task = _starpu_tree_pop_task,
  155. .pre_exec_hook = NULL,
  156. .post_exec_hook = NULL,
  157. .pop_every_task = NULL,
  158. .policy_name = "tree-random",
  159. .policy_description = "random tree policy"
  160. };