#include #include #include /* set implementation, task->predicted and task->predicted_transfer with the first worker of workers that can execute that task * or have to be calibrated */ static void select_best_implementation_and_set_preds(struct starpu_bitmap * workers, struct starpu_task * task) { int best_impl = -1; double len = DBL_MAX; int workerid; for(workerid = starpu_bitmap_first(workers); -1 != workerid; workerid = starpu_bitmap_next(workers, workerid)) { int impl; for(impl = 0; impl < STARPU_MAXIMPLEMENTATIONS; impl++) { if(starpu_worker_can_execute_task(workerid, task, impl)) { enum starpu_perfmodel_archtype archtype = starpu_worker_get_perf_archtype(workerid); double d = starpu_task_expected_length(task, archtype, impl); if(isnan(d)) { best_impl = impl; len = 0.0; break; } if(d < len) { len = d; best_impl = impl; } } } if(best_impl != -1) break; } int memory_node = starpu_worker_get_memory_node(workerid); task->predicted = len; task->predicted_transfer = starpu_task_expected_data_transfer_time(memory_node, task); starpu_task_set_implementation(task, best_impl); } static int select_best_implementation_push_task(struct starpu_sched_node * node, struct starpu_task * task) { STARPU_ASSERT(node->nchilds == 1); select_best_implementation_and_set_preds(node->workers_in_ctx, task); return node->childs[0]->push_task(node->childs[0],task); } static struct starpu_task * select_best_implementation_pop_task(struct starpu_sched_node * node, unsigned sched_ctx_id) { struct starpu_task * t; STARPU_ASSERT(node->is_homogeneous); if(!node->fathers[sched_ctx_id]) return NULL; t = node->fathers[sched_ctx_id]->pop_task(node->fathers[sched_ctx_id], sched_ctx_id); if(t) select_best_implementation_and_set_preds(node->workers_in_ctx, t); return t; } static int select_calibration_push_task(struct starpu_sched_node * node, struct starpu_task * task) { STARPU_ASSERT(node->nchilds == 1); select_best_implementation_and_set_preds(node->workers_in_ctx, task); return node->childs[0]->push_task(node->childs[0],task); } static struct starpu_task * select_calibration_pop_task(struct starpu_sched_node * node, unsigned sched_ctx_id) { struct starpu_task * t; if(!node->fathers[sched_ctx_id]) return NULL; t = node->fathers[sched_ctx_id]->pop_task(node->fathers[sched_ctx_id], sched_ctx_id); if(t) select_best_implementation_and_set_preds(node->workers_in_ctx, t); return t; } struct starpu_sched_node * starpu_sched_node_best_implementation_create(void * ARG STARPU_ATTRIBUTE_UNUSED) { struct starpu_sched_node * node = starpu_sched_node_create(); node->push_task = select_best_implementation_push_task; node->pop_task = select_best_implementation_pop_task; return node; } struct starpu_sched_node * starpu_sched_node_calibration_create(void * arg STARPU_ATTRIBUTE_UNUSED) { struct starpu_sched_node * node = starpu_sched_node_create(); node->push_task = select_calibration_push_task; node->pop_task = select_calibration_pop_task; return node; }