|
@@ -5,147 +5,73 @@
|
|
|
#include <float.h>
|
|
|
|
|
|
|
|
|
-struct _starpu_dmda_data
|
|
|
-{
|
|
|
- double alpha;
|
|
|
- double beta;
|
|
|
- double gamma;
|
|
|
- double idle_power;
|
|
|
- struct starpu_sched_node * no_model_node;
|
|
|
-};
|
|
|
|
|
|
-static double compute_fitness_calibration(struct starpu_sched_node * child,
|
|
|
- struct _starpu_dmda_data * data STARPU_ATTRIBUTE_UNUSED,
|
|
|
- struct starpu_task_execute_preds *pred,
|
|
|
- double best_exp_end STARPU_ATTRIBUTE_UNUSED,
|
|
|
- double max_exp_end STARPU_ATTRIBUTE_UNUSED)
|
|
|
+static double compute_fitness(struct starpu_heft_data * d, double exp_end, double best_exp_end, double max_exp_end, double transfer_len, double local_power)
|
|
|
{
|
|
|
- if(pred->state == CALIBRATING)
|
|
|
- return child->estimated_load(child);
|
|
|
- return DBL_MAX;
|
|
|
-}
|
|
|
-
|
|
|
-static double compute_fitness_perf_model(struct starpu_sched_node * child STARPU_ATTRIBUTE_UNUSED,
|
|
|
- struct _starpu_dmda_data * data,
|
|
|
- struct starpu_task_execute_preds * preds,
|
|
|
- double best_exp_end,
|
|
|
- double max_exp_end)
|
|
|
-{
|
|
|
- double fitness;
|
|
|
- switch(preds->state)
|
|
|
- {
|
|
|
- case CANNOT_EXECUTE:
|
|
|
- case NO_PERF_MODEL:
|
|
|
- return DBL_MAX;
|
|
|
- case PERF_MODEL:
|
|
|
- fitness = data->alpha * (preds->expected_finish_time - best_exp_end)
|
|
|
- + data->beta * preds->expected_transfer_length
|
|
|
- + data->gamma * preds->expected_power
|
|
|
- + data->gamma * data->idle_power * (max_exp_end - best_exp_end) / 1000000.0;
|
|
|
- return fitness;
|
|
|
- case CALIBRATING:
|
|
|
- STARPU_ASSERT_MSG(0,"we should have calibrate this task");
|
|
|
- default:
|
|
|
- STARPU_ABORT();
|
|
|
- break;
|
|
|
- }
|
|
|
+ return d->alpha * (exp_end - best_exp_end)
|
|
|
+ + d->beta * transfer_len
|
|
|
+ + d->gamma * local_power
|
|
|
+ + d->gamma * d->idle_power * (exp_end - max_exp_end);
|
|
|
}
|
|
|
|
|
|
static int push_task(struct starpu_sched_node * node, struct starpu_task * task)
|
|
|
{
|
|
|
- struct starpu_task_execute_preds preds[node->nchilds];
|
|
|
+ struct starpu_heft_data * d = node->data;
|
|
|
+ struct starpu_sched_node * best_node = NULL;
|
|
|
+ double estimated_ends[node->nchilds];
|
|
|
+ double estimated_ends_with_task[node->nchilds];
|
|
|
+ double best_exp_end_with_task = DBL_MAX;
|
|
|
+ double max_exp_end_with_task = 0.0;
|
|
|
+ double estimated_lengths[node->nchilds];
|
|
|
+ double estimated_transfer_length[node->nchilds];
|
|
|
+ int suitable_nodes[node->nchilds];
|
|
|
+ int nsuitable_nodes = 0;
|
|
|
+ double now = starpu_timing_now();
|
|
|
int i;
|
|
|
- int calibrating = 0;
|
|
|
- int perf_model = 0;
|
|
|
- int can_execute = 0;
|
|
|
- double best_exp_end = DBL_MAX;
|
|
|
- double max_exp_end = DBL_MIN;
|
|
|
for(i = 0; i < node->nchilds; i++)
|
|
|
{
|
|
|
- preds[i] = node->childs[i]->estimated_execute_preds(node->childs[i], task);
|
|
|
- switch(preds[i].state)
|
|
|
+ struct starpu_sched_node * c = node->childs[i];
|
|
|
+ if(starpu_sched_node_execute_preds(c, task, estimated_lengths + i))
|
|
|
{
|
|
|
- case PERF_MODEL:
|
|
|
- STARPU_ASSERT(!isnan(preds[i].expected_finish_time));
|
|
|
- perf_model = 1;
|
|
|
- can_execute = 1;
|
|
|
- if(preds[i].expected_finish_time < best_exp_end)
|
|
|
- best_exp_end = preds[i].expected_finish_time;
|
|
|
- else if(preds[i].expected_finish_time > max_exp_end)
|
|
|
- max_exp_end = preds[i].expected_finish_time;
|
|
|
- break;
|
|
|
- case CALIBRATING:
|
|
|
- calibrating = 1;
|
|
|
- can_execute = 1;
|
|
|
- break;
|
|
|
- case NO_PERF_MODEL:
|
|
|
- can_execute = 1;
|
|
|
- break;
|
|
|
- case CANNOT_EXECUTE:
|
|
|
- break;
|
|
|
+ if(isnan(estimated_lengths[i]))
|
|
|
+ return d->calibrating_node->push_task(d->calibrating_node, task);
|
|
|
+ if(_STARPU_IS_ZERO(estimated_lengths[i]))
|
|
|
+ return d->no_perf_model_node->push_task(d->no_perf_model_node, task);
|
|
|
+ estimated_transfer_length[i] = starpu_sched_node_transfer_length(c, task);
|
|
|
+ estimated_ends[i] = c->estimated_end(c);
|
|
|
+ estimated_ends_with_task[i] = starpu_sched_compute_expected_time(now,
|
|
|
+ estimated_ends[i],
|
|
|
+ estimated_lengths[i],
|
|
|
+ estimated_transfer_length[i]);
|
|
|
+ if(estimated_ends_with_task[i] < best_exp_end_with_task)
|
|
|
+ best_exp_end_with_task = estimated_ends_with_task[i];
|
|
|
+ if(estimated_ends_with_task[i] > max_exp_end_with_task)
|
|
|
+ max_exp_end_with_task = estimated_ends_with_task[i];
|
|
|
+ suitable_nodes[nsuitable_nodes++] = i;
|
|
|
}
|
|
|
}
|
|
|
- if(!can_execute)
|
|
|
- {
|
|
|
- return -ENODEV;
|
|
|
- }
|
|
|
-
|
|
|
- struct _starpu_dmda_data * data = node->data;
|
|
|
-
|
|
|
- if(!calibrating && !perf_model)
|
|
|
- {
|
|
|
- int ret = data->no_model_node->push_task(data->no_model_node, task);
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- double (*fitness_fun)(struct starpu_sched_node *,
|
|
|
- struct _starpu_dmda_data *,
|
|
|
- struct starpu_task_execute_preds*,
|
|
|
- double,
|
|
|
- double) = compute_fitness_perf_model;
|
|
|
-
|
|
|
- if(calibrating)
|
|
|
- fitness_fun = compute_fitness_calibration;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
double best_fitness = DBL_MAX;
|
|
|
- int index_best_fitness = -1;
|
|
|
- for(i = 0; i < node->nchilds; i++)
|
|
|
+ int best_inode = -1;
|
|
|
+ for(i = 0; i < nsuitable_nodes; i++)
|
|
|
{
|
|
|
- double tmp = fitness_fun(node->childs[i],
|
|
|
- node->data,
|
|
|
- preds + i,
|
|
|
- best_exp_end,
|
|
|
- max_exp_end);
|
|
|
-// fprintf(stderr,"fitness for worker %d is %f\n",i,tmp == DBL_MAX ? -1 : tmp);
|
|
|
- if(tmp < best_fitness)
|
|
|
+ int inode = suitable_nodes[i];
|
|
|
+ double tmp = compute_fitness(d,
|
|
|
+ estimated_ends_with_task[inode],
|
|
|
+ best_exp_end_with_task,
|
|
|
+ max_exp_end_with_task,
|
|
|
+ estimated_transfer_length[inode],
|
|
|
+ 0.0);
|
|
|
+ if(best_fitness > tmp)
|
|
|
{
|
|
|
best_fitness = tmp;
|
|
|
- index_best_fitness = i;
|
|
|
+ best_inode = inode;
|
|
|
}
|
|
|
}
|
|
|
-// fprintf(stderr,"push on worker %d\n",index_best_fitness);
|
|
|
- STARPU_ASSERT(best_fitness != DBL_MAX);
|
|
|
-
|
|
|
- struct starpu_sched_node * c = node->childs[index_best_fitness];
|
|
|
- starpu_task_set_implementation(task, preds[index_best_fitness].impl);
|
|
|
- task->predicted = preds[index_best_fitness].expected_length;
|
|
|
- task->predicted_transfer = preds[index_best_fitness].expected_transfer_length;
|
|
|
- return c->push_task(c, task);
|
|
|
-}
|
|
|
-/*
|
|
|
-static void update_helper_node(struct starpu_sched_node * heft_node)
|
|
|
-{
|
|
|
- struct _starpu_dmda_data * data = heft_node->data;
|
|
|
- struct starpu_sched_node * node = data->no_model_node;
|
|
|
- node->nchilds = heft_node->nchilds;
|
|
|
- node->childs = realloc(node->childs, sizeof(struct starpu_sched_node *) * node->nchilds);
|
|
|
- memcpy(node->childs, heft_node->childs, sizeof(struct starpu_sched_node*) * node->nchilds);
|
|
|
- node->nworkers = heft_node->nworkers;
|
|
|
- memcpy(node->workerids, heft_node->workerids, sizeof(int) * node->nworkers);
|
|
|
+ fprintf(stderr,"%d best inode\n",best_inode);
|
|
|
+ best_node = node->childs[best_inode];
|
|
|
+ return best_node->push_task(best_node, task);
|
|
|
}
|
|
|
-*/
|
|
|
+
|
|
|
|
|
|
|
|
|
#define _STARPU_SCHED_ALPHA_DEFAULT 1.0
|
|
@@ -212,9 +138,9 @@ void init_heft_data(struct starpu_sched_node *node)
|
|
|
idle_power_minimum, idle_power_maximum, param_modified);
|
|
|
#endif /* !STARPU_USE_TOP */
|
|
|
|
|
|
-
|
|
|
- struct _starpu_dmda_data * data = malloc(sizeof(*data));
|
|
|
- memset(data, 0, sizeof(*data));
|
|
|
+ struct starpu_heft_data * old = node->data;
|
|
|
+ struct starpu_heft_data * data = malloc(sizeof(*data));
|
|
|
+ *data = *old;
|
|
|
data->alpha = alpha;
|
|
|
data->beta = beta;
|
|
|
data->gamma = _gamma;
|
|
@@ -222,45 +148,23 @@ void init_heft_data(struct starpu_sched_node *node)
|
|
|
|
|
|
node->data = data;
|
|
|
|
|
|
- starpu_sched_node_heft_set_no_model_node(node, starpu_sched_node_random_create,NULL);
|
|
|
}
|
|
|
|
|
|
-static void destroy_no_model_node(struct starpu_sched_node * heft_node)
|
|
|
-{
|
|
|
- struct _starpu_dmda_data * data = heft_node->data;
|
|
|
- if(data->no_model_node)
|
|
|
- {
|
|
|
- starpu_sched_node_destroy(data->no_model_node);
|
|
|
- }
|
|
|
-}
|
|
|
|
|
|
void deinit_heft_data(struct starpu_sched_node * node)
|
|
|
{
|
|
|
- destroy_no_model_node(node);
|
|
|
free(node->data);
|
|
|
}
|
|
|
|
|
|
-void starpu_sched_node_heft_set_no_model_node(struct starpu_sched_node * heft_node,
|
|
|
- struct starpu_sched_node * (*create_no_model_node)(void *),void * arg)
|
|
|
-{
|
|
|
- destroy_no_model_node(heft_node);
|
|
|
- struct _starpu_dmda_data * data = heft_node->data;
|
|
|
- struct starpu_sched_node * no_model_node = create_no_model_node(arg);
|
|
|
- no_model_node->childs = malloc(heft_node->nchilds * sizeof(struct starpu_sched_node *));
|
|
|
- memcpy(no_model_node->childs, heft_node->childs, heft_node->nchilds * sizeof(struct _strapu_sched_node *));
|
|
|
-
|
|
|
- no_model_node->nchilds = heft_node->nchilds;
|
|
|
- no_model_node->init_data(no_model_node);
|
|
|
- data->no_model_node = no_model_node;
|
|
|
-}
|
|
|
|
|
|
-struct starpu_sched_node * starpu_sched_node_heft_create(void * arg STARPU_ATTRIBUTE_UNUSED)
|
|
|
+struct starpu_sched_node * starpu_sched_node_heft_create(struct starpu_heft_data * data)
|
|
|
{
|
|
|
struct starpu_sched_node * node = starpu_sched_node_create();
|
|
|
|
|
|
node->push_task = push_task;
|
|
|
node->init_data = init_heft_data;
|
|
|
node->deinit_data = deinit_heft_data;
|
|
|
+ node->data = data;
|
|
|
|
|
|
return node;
|
|
|
}
|
|
@@ -277,7 +181,17 @@ static void initialize_heft_center_policy(unsigned sched_ctx_id)
|
|
|
starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
|
|
|
|
|
|
struct starpu_sched_tree * t = starpu_sched_tree_create();
|
|
|
- t->root = starpu_sched_node_heft_create(NULL);
|
|
|
+ struct starpu_sched_node * random = starpu_sched_node_random_create(NULL);
|
|
|
+ struct starpu_heft_data data =
|
|
|
+ {
|
|
|
+ .alpha = 1.0,
|
|
|
+ .beta = 1.0,
|
|
|
+ .gamma = 1.0,
|
|
|
+ .idle_power = 200,
|
|
|
+ random,
|
|
|
+ random
|
|
|
+ };
|
|
|
+ t->root = starpu_sched_node_heft_create(&data);
|
|
|
|
|
|
unsigned i;
|
|
|
for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
|
|
@@ -289,13 +203,16 @@ static void initialize_heft_center_policy(unsigned sched_ctx_id)
|
|
|
starpu_sched_node_add_child(fifo_node, worker_node);
|
|
|
starpu_sched_node_set_father(worker_node, fifo_node, sched_ctx_id);
|
|
|
*/
|
|
|
+
|
|
|
starpu_sched_node_add_child(t->root, worker_node);
|
|
|
+ starpu_sched_node_add_child(random, worker_node);
|
|
|
starpu_sched_node_set_father(worker_node, t->root, sched_ctx_id);
|
|
|
}
|
|
|
|
|
|
_starpu_set_workers_bitmaps();
|
|
|
starpu_sched_tree_call_init_data(t);
|
|
|
-
|
|
|
+ starpu_bitmap_destroy(random->workers_in_ctx);
|
|
|
+ random->workers_in_ctx = t->root->workers_in_ctx;
|
|
|
starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
|
|
|
}
|
|
|
|