|
@@ -1,6 +1,6 @@
|
|
/* StarPU --- Runtime system for heterogeneous multicore architectures.
|
|
/* StarPU --- Runtime system for heterogeneous multicore architectures.
|
|
*
|
|
*
|
|
- * Copyright (C) 2010, 2011 Centre National de la Recherche Scientifique
|
|
|
|
|
|
+ * Copyright (C) 2010, 2011, 2012 Centre National de la Recherche Scientifique
|
|
* Copyright (C) 2010, 2011 Université de Bordeaux 1
|
|
* Copyright (C) 2010, 2011 Université de Bordeaux 1
|
|
* Copyright (C) 2011 Télécom-SudParis
|
|
* Copyright (C) 2011 Télécom-SudParis
|
|
*
|
|
*
|
|
@@ -45,9 +45,10 @@
|
|
* - the total numer of tasks of a given kind is equal to the number run by the
|
|
* - the total numer of tasks of a given kind is equal to the number run by the
|
|
* application.
|
|
* application.
|
|
*/
|
|
*/
|
|
-struct bound_task_pool {
|
|
|
|
|
|
+struct bound_task_pool
|
|
|
|
+{
|
|
/* Which codelet has been executed */
|
|
/* Which codelet has been executed */
|
|
- struct starpu_codelet_t *cl;
|
|
|
|
|
|
+ struct starpu_codelet *cl;
|
|
/* Task footprint key */
|
|
/* Task footprint key */
|
|
uint32_t footprint;
|
|
uint32_t footprint;
|
|
/* Number of tasks of this kind */
|
|
/* Number of tasks of this kind */
|
|
@@ -77,14 +78,15 @@ struct bound_task_pool {
|
|
/* Note: only task-task, implicit data dependencies or task-tag dependencies
|
|
/* Note: only task-task, implicit data dependencies or task-tag dependencies
|
|
* are taken into account. Tags released in a callback or something like this
|
|
* are taken into account. Tags released in a callback or something like this
|
|
* is not taken into account, only tags associated with a task are. */
|
|
* is not taken into account, only tags associated with a task are. */
|
|
-struct bound_task {
|
|
|
|
|
|
+struct bound_task
|
|
|
|
+{
|
|
/* Unique ID */
|
|
/* Unique ID */
|
|
unsigned long id;
|
|
unsigned long id;
|
|
/* Tag ID, if any */
|
|
/* Tag ID, if any */
|
|
starpu_tag_t tag_id;
|
|
starpu_tag_t tag_id;
|
|
int use_tag;
|
|
int use_tag;
|
|
/* Which codelet has been executed */
|
|
/* Which codelet has been executed */
|
|
- struct starpu_codelet_t *cl;
|
|
|
|
|
|
+ struct starpu_codelet *cl;
|
|
/* Task footprint key */
|
|
/* Task footprint key */
|
|
uint32_t footprint;
|
|
uint32_t footprint;
|
|
/* Task priority */
|
|
/* Task priority */
|
|
@@ -100,7 +102,8 @@ struct bound_task {
|
|
struct bound_task *next;
|
|
struct bound_task *next;
|
|
};
|
|
};
|
|
|
|
|
|
-struct bound_tag_dep {
|
|
|
|
|
|
+struct bound_tag_dep
|
|
|
|
+{
|
|
starpu_tag_t tag;
|
|
starpu_tag_t tag;
|
|
starpu_tag_t dep_tag;
|
|
starpu_tag_t dep_tag;
|
|
struct bound_tag_dep *next;
|
|
struct bound_tag_dep *next;
|
|
@@ -121,7 +124,7 @@ void starpu_bound_start(int deps, int prio)
|
|
struct bound_task *t;
|
|
struct bound_task *t;
|
|
struct bound_tag_dep *td;
|
|
struct bound_tag_dep *td;
|
|
|
|
|
|
- PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
tp = task_pools;
|
|
tp = task_pools;
|
|
task_pools = NULL;
|
|
task_pools = NULL;
|
|
@@ -137,7 +140,7 @@ void starpu_bound_start(int deps, int prio)
|
|
recorddeps = deps;
|
|
recorddeps = deps;
|
|
recordprio = prio;
|
|
recordprio = prio;
|
|
|
|
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
for ( ; tp; tp = tp->next)
|
|
for ( ; tp; tp = tp->next)
|
|
free(tp);
|
|
free(tp);
|
|
@@ -149,7 +152,7 @@ void starpu_bound_start(int deps, int prio)
|
|
free(td);
|
|
free(td);
|
|
}
|
|
}
|
|
|
|
|
|
-static int good_job(starpu_job_t j)
|
|
|
|
|
|
+static int good_job(struct _starpu_job *j)
|
|
{
|
|
{
|
|
/* No codelet, nothing to measure */
|
|
/* No codelet, nothing to measure */
|
|
if (j->exclude_from_dag)
|
|
if (j->exclude_from_dag)
|
|
@@ -165,7 +168,7 @@ static int good_job(starpu_job_t j)
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-static void new_task(starpu_job_t j)
|
|
|
|
|
|
+static void new_task(struct _starpu_job *j)
|
|
{
|
|
{
|
|
struct bound_task *t;
|
|
struct bound_task *t;
|
|
|
|
|
|
@@ -178,7 +181,7 @@ static void new_task(starpu_job_t j)
|
|
t->tag_id = j->task->tag_id;
|
|
t->tag_id = j->task->tag_id;
|
|
t->use_tag = j->task->use_tag;
|
|
t->use_tag = j->task->use_tag;
|
|
t->cl = j->task->cl;
|
|
t->cl = j->task->cl;
|
|
- t->footprint = _starpu_compute_buffers_footprint(j);
|
|
|
|
|
|
+ t->footprint = _starpu_compute_buffers_footprint(NULL, STARPU_CPU_DEFAULT, 0, j);
|
|
t->priority = j->task->priority;
|
|
t->priority = j->task->priority;
|
|
t->deps = NULL;
|
|
t->deps = NULL;
|
|
t->depsn = 0;
|
|
t->depsn = 0;
|
|
@@ -187,7 +190,7 @@ static void new_task(starpu_job_t j)
|
|
tasks = t;
|
|
tasks = t;
|
|
}
|
|
}
|
|
|
|
|
|
-void _starpu_bound_record(starpu_job_t j)
|
|
|
|
|
|
+void _starpu_bound_record(struct _starpu_job *j)
|
|
{
|
|
{
|
|
if (!_starpu_bound_recording)
|
|
if (!_starpu_bound_recording)
|
|
return;
|
|
return;
|
|
@@ -195,19 +198,23 @@ void _starpu_bound_record(starpu_job_t j)
|
|
if (!good_job(j))
|
|
if (!good_job(j))
|
|
return;
|
|
return;
|
|
|
|
|
|
- PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_LOCK(&mutex);
|
|
/* Re-check, this time with mutex held */
|
|
/* Re-check, this time with mutex held */
|
|
- if (!_starpu_bound_recording) {
|
|
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ if (!_starpu_bound_recording)
|
|
|
|
+ {
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- if (recorddeps) {
|
|
|
|
|
|
+ if (recorddeps)
|
|
|
|
+ {
|
|
new_task(j);
|
|
new_task(j);
|
|
- } else {
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
struct bound_task_pool *tp;
|
|
struct bound_task_pool *tp;
|
|
|
|
|
|
- _starpu_compute_buffers_footprint(j);
|
|
|
|
|
|
+ _starpu_compute_buffers_footprint(NULL, STARPU_CPU_DEFAULT, 0, j);
|
|
|
|
|
|
if (last && last->cl == j->task->cl && last->footprint == j->footprint)
|
|
if (last && last->cl == j->task->cl && last->footprint == j->footprint)
|
|
tp = last;
|
|
tp = last;
|
|
@@ -216,7 +223,8 @@ void _starpu_bound_record(starpu_job_t j)
|
|
if (tp->cl == j->task->cl && tp->footprint == j->footprint)
|
|
if (tp->cl == j->task->cl && tp->footprint == j->footprint)
|
|
break;
|
|
break;
|
|
|
|
|
|
- if (!tp) {
|
|
|
|
|
|
+ if (!tp)
|
|
|
|
+ {
|
|
tp = (struct bound_task_pool *) malloc(sizeof(*tp));
|
|
tp = (struct bound_task_pool *) malloc(sizeof(*tp));
|
|
tp->cl = j->task->cl;
|
|
tp->cl = j->task->cl;
|
|
tp->footprint = j->footprint;
|
|
tp->footprint = j->footprint;
|
|
@@ -229,7 +237,7 @@ void _starpu_bound_record(starpu_job_t j)
|
|
tp->n++;
|
|
tp->n++;
|
|
}
|
|
}
|
|
|
|
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
}
|
|
}
|
|
|
|
|
|
void _starpu_bound_tag_dep(starpu_tag_t id, starpu_tag_t dep_id)
|
|
void _starpu_bound_tag_dep(starpu_tag_t id, starpu_tag_t dep_id)
|
|
@@ -239,10 +247,11 @@ void _starpu_bound_tag_dep(starpu_tag_t id, starpu_tag_t dep_id)
|
|
if (!_starpu_bound_recording || !recorddeps)
|
|
if (!_starpu_bound_recording || !recorddeps)
|
|
return;
|
|
return;
|
|
|
|
|
|
- PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_LOCK(&mutex);
|
|
/* Re-check, this time with mutex held */
|
|
/* Re-check, this time with mutex held */
|
|
- if (!_starpu_bound_recording || !recorddeps) {
|
|
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ if (!_starpu_bound_recording || !recorddeps)
|
|
|
|
+ {
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -251,10 +260,10 @@ void _starpu_bound_tag_dep(starpu_tag_t id, starpu_tag_t dep_id)
|
|
td->dep_tag = dep_id;
|
|
td->dep_tag = dep_id;
|
|
td->next = tag_deps;
|
|
td->next = tag_deps;
|
|
tag_deps = td;
|
|
tag_deps = td;
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
}
|
|
}
|
|
|
|
|
|
-void _starpu_bound_task_dep(starpu_job_t j, starpu_job_t dep_j)
|
|
|
|
|
|
+void _starpu_bound_task_dep(struct _starpu_job *j, struct _starpu_job *dep_j)
|
|
{
|
|
{
|
|
struct bound_task *t;
|
|
struct bound_task *t;
|
|
|
|
|
|
@@ -264,10 +273,11 @@ void _starpu_bound_task_dep(starpu_job_t j, starpu_job_t dep_j)
|
|
if (!good_job(j) || !good_job(dep_j))
|
|
if (!good_job(j) || !good_job(dep_j))
|
|
return;
|
|
return;
|
|
|
|
|
|
- PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_LOCK(&mutex);
|
|
/* Re-check, this time with mutex held */
|
|
/* Re-check, this time with mutex held */
|
|
- if (!_starpu_bound_recording || !recorddeps) {
|
|
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ if (!_starpu_bound_recording || !recorddeps)
|
|
|
|
+ {
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -276,7 +286,7 @@ void _starpu_bound_task_dep(starpu_job_t j, starpu_job_t dep_j)
|
|
t = j->bound_task;
|
|
t = j->bound_task;
|
|
t->deps = (struct bound_task **) realloc(t->deps, ++t->depsn * sizeof(t->deps[0]));
|
|
t->deps = (struct bound_task **) realloc(t->deps, ++t->depsn * sizeof(t->deps[0]));
|
|
t->deps[t->depsn-1] = dep_j->bound_task;
|
|
t->deps[t->depsn-1] = dep_j->bound_task;
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
}
|
|
}
|
|
|
|
|
|
static struct bound_task *find_job(unsigned long id)
|
|
static struct bound_task *find_job(unsigned long id)
|
|
@@ -289,7 +299,7 @@ static struct bound_task *find_job(unsigned long id)
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
-void _starpu_bound_job_id_dep(starpu_job_t j, unsigned long id)
|
|
|
|
|
|
+void _starpu_bound_job_id_dep(struct _starpu_job *j, unsigned long id)
|
|
{
|
|
{
|
|
struct bound_task *t, *dep_t;
|
|
struct bound_task *t, *dep_t;
|
|
|
|
|
|
@@ -299,55 +309,63 @@ void _starpu_bound_job_id_dep(starpu_job_t j, unsigned long id)
|
|
if (!good_job(j))
|
|
if (!good_job(j))
|
|
return;
|
|
return;
|
|
|
|
|
|
- PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_LOCK(&mutex);
|
|
/* Re-check, this time with mutex held */
|
|
/* Re-check, this time with mutex held */
|
|
- if (!_starpu_bound_recording || !recorddeps) {
|
|
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ if (!_starpu_bound_recording || !recorddeps)
|
|
|
|
+ {
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
new_task(j);
|
|
new_task(j);
|
|
dep_t = find_job(id);
|
|
dep_t = find_job(id);
|
|
- if (!dep_t) {
|
|
|
|
|
|
+ if (!dep_t)
|
|
|
|
+ {
|
|
fprintf(stderr,"dependency %lu not found !\n", id);
|
|
fprintf(stderr,"dependency %lu not found !\n", id);
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
t = j->bound_task;
|
|
t = j->bound_task;
|
|
t->deps = (struct bound_task **) realloc(t->deps, ++t->depsn * sizeof(t->deps[0]));
|
|
t->deps = (struct bound_task **) realloc(t->deps, ++t->depsn * sizeof(t->deps[0]));
|
|
t->deps[t->depsn-1] = dep_t;
|
|
t->deps[t->depsn-1] = dep_t;
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
}
|
|
}
|
|
|
|
|
|
void starpu_bound_stop(void)
|
|
void starpu_bound_stop(void)
|
|
{
|
|
{
|
|
- PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_LOCK(&mutex);
|
|
_starpu_bound_recording = 0;
|
|
_starpu_bound_recording = 0;
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
}
|
|
}
|
|
|
|
|
|
-static void _starpu_get_tasks_times(int nw, int nt, double *times) {
|
|
|
|
|
|
+static void _starpu_get_tasks_times(int nw, int nt, double *times)
|
|
|
|
+{
|
|
struct bound_task_pool *tp;
|
|
struct bound_task_pool *tp;
|
|
int w, t;
|
|
int w, t;
|
|
- for (w = 0; w < nw; w++) {
|
|
|
|
- for (t = 0, tp = task_pools; tp; t++, tp = tp->next) {
|
|
|
|
- struct starpu_job_s j = {
|
|
|
|
|
|
+ for (w = 0; w < nw; w++)
|
|
|
|
+ {
|
|
|
|
+ for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
|
|
+ {
|
|
|
|
+ struct _starpu_job j =
|
|
|
|
+ {
|
|
.footprint = tp->footprint,
|
|
.footprint = tp->footprint,
|
|
.footprint_is_computed = 1,
|
|
.footprint_is_computed = 1,
|
|
};
|
|
};
|
|
enum starpu_perf_archtype arch = starpu_worker_get_perf_archtype(w);
|
|
enum starpu_perf_archtype arch = starpu_worker_get_perf_archtype(w);
|
|
double length = _starpu_history_based_job_expected_perf(tp->cl->model, arch, &j, j.nimpl);
|
|
double length = _starpu_history_based_job_expected_perf(tp->cl->model, arch, &j, j.nimpl);
|
|
- if (length == -1.0)
|
|
|
|
- times[w*nt+t] = -1.0;
|
|
|
|
|
|
+ if (isnan(length))
|
|
|
|
+ times[w*nt+t] = NAN;
|
|
else
|
|
else
|
|
times[w*nt+t] = length / 1000.;
|
|
times[w*nt+t] = length / 1000.;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static int ancestor(struct bound_task *child, struct bound_task *parent) {
|
|
|
|
|
|
+static int ancestor(struct bound_task *child, struct bound_task *parent)
|
|
|
|
+{
|
|
int i;
|
|
int i;
|
|
- for (i = 0; i < child->depsn; i++) {
|
|
|
|
|
|
+ for (i = 0; i < child->depsn; i++)
|
|
|
|
+ {
|
|
if (parent == child->deps[i])
|
|
if (parent == child->deps[i])
|
|
return 1;
|
|
return 1;
|
|
if (ancestor(child->deps[i], parent))
|
|
if (ancestor(child->deps[i], parent))
|
|
@@ -356,18 +374,21 @@ static int ancestor(struct bound_task *child, struct bound_task *parent) {
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-void starpu_bound_print_dot(FILE *output) {
|
|
|
|
|
|
+void starpu_bound_print_dot(FILE *output)
|
|
|
|
+{
|
|
struct bound_task *t;
|
|
struct bound_task *t;
|
|
struct bound_tag_dep *td;
|
|
struct bound_tag_dep *td;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- if (!recorddeps) {
|
|
|
|
|
|
+ if (!recorddeps)
|
|
|
|
+ {
|
|
fprintf(output, "Not supported\n");
|
|
fprintf(output, "Not supported\n");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
fprintf(output, "strict digraph bounddeps {\n");
|
|
fprintf(output, "strict digraph bounddeps {\n");
|
|
- for (t = tasks; t; t = t->next) {
|
|
|
|
- fprintf(output, "\"t%lu\" [label=\"%lu: %s\"]\n", t->id, t->id, t->cl->model->symbol);
|
|
|
|
|
|
+ for (t = tasks; t; t = t->next)
|
|
|
|
+ {
|
|
|
|
+ fprintf(output, "\"t%lu\" [label=\"%lu: %s\"]\n", t->id, t->id, t->cl->name);
|
|
for (i = 0; i < t->depsn; i++)
|
|
for (i = 0; i < t->depsn; i++)
|
|
fprintf(output, "\"t%lu\" -> \"t%lu\"\n", t->deps[i]->id, t->id);
|
|
fprintf(output, "\"t%lu\" -> \"t%lu\"\n", t->deps[i]->id, t->id);
|
|
}
|
|
}
|
|
@@ -378,6 +399,9 @@ void starpu_bound_print_dot(FILE *output) {
|
|
|
|
|
|
/*
|
|
/*
|
|
* lp_solve format
|
|
* lp_solve format
|
|
|
|
+ *
|
|
|
|
+ * When dependencies are enabled, you can check the set of tasks and deps that
|
|
|
|
+ * were recorded by using tools/lp2paje and vite.
|
|
*/
|
|
*/
|
|
void starpu_bound_print_lp(FILE *output)
|
|
void starpu_bound_print_lp(FILE *output)
|
|
{
|
|
{
|
|
@@ -385,27 +409,32 @@ void starpu_bound_print_lp(FILE *output)
|
|
int nw; /* Number of different workers */
|
|
int nw; /* Number of different workers */
|
|
int t, w;
|
|
int t, w;
|
|
|
|
|
|
- PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_LOCK(&mutex);
|
|
nw = starpu_worker_get_count();
|
|
nw = starpu_worker_get_count();
|
|
|
|
|
|
- if (recorddeps) {
|
|
|
|
|
|
+ if (recorddeps)
|
|
|
|
+ {
|
|
struct bound_task *t1, *t2;
|
|
struct bound_task *t1, *t2;
|
|
struct bound_tag_dep *td;
|
|
struct bound_tag_dep *td;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
nt = 0;
|
|
nt = 0;
|
|
- for (t1 = tasks; t1; t1 = t1->next) {
|
|
|
|
- struct starpu_job_s j = {
|
|
|
|
|
|
+ for (t1 = tasks; t1; t1 = t1->next)
|
|
|
|
+ {
|
|
|
|
+ struct _starpu_job j =
|
|
|
|
+ {
|
|
.footprint = t1->footprint,
|
|
.footprint = t1->footprint,
|
|
.footprint_is_computed = 1,
|
|
.footprint_is_computed = 1,
|
|
};
|
|
};
|
|
- for (w = 0; w < nw; w++) {
|
|
|
|
|
|
+ for (w = 0; w < nw; w++)
|
|
|
|
+ {
|
|
enum starpu_perf_archtype arch = starpu_worker_get_perf_archtype(w);
|
|
enum starpu_perf_archtype arch = starpu_worker_get_perf_archtype(w);
|
|
- if (t1->duration[arch] == 0.) {
|
|
|
|
|
|
+ if (_STARPU_IS_ZERO(t1->duration[arch]))
|
|
|
|
+ {
|
|
double length = _starpu_history_based_job_expected_perf(t1->cl->model, arch, &j,j.nimpl);
|
|
double length = _starpu_history_based_job_expected_perf(t1->cl->model, arch, &j,j.nimpl);
|
|
- if (length == -1.0)
|
|
|
|
|
|
+ if (isnan(length))
|
|
/* Avoid problems with binary coding of doubles */
|
|
/* Avoid problems with binary coding of doubles */
|
|
- t1->duration[arch] = -1.0;
|
|
|
|
|
|
+ t1->duration[arch] = NAN;
|
|
else
|
|
else
|
|
t1->duration[arch] = length / 1000.;
|
|
t1->duration[arch] = length / 1000.;
|
|
}
|
|
}
|
|
@@ -422,10 +451,12 @@ void starpu_bound_print_lp(FILE *output)
|
|
fprintf(output, "c%lu <= tmax;\n", t1->id);
|
|
fprintf(output, "c%lu <= tmax;\n", t1->id);
|
|
|
|
|
|
fprintf(output, "\n/* We have tasks executing on workers, exactly one worker executes each task */\n");
|
|
fprintf(output, "\n/* We have tasks executing on workers, exactly one worker executes each task */\n");
|
|
- for (t1 = tasks; t1; t1 = t1->next) {
|
|
|
|
- for (w = 0; w < nw; w++) {
|
|
|
|
|
|
+ for (t1 = tasks; t1; t1 = t1->next)
|
|
|
|
+ {
|
|
|
|
+ for (w = 0; w < nw; w++)
|
|
|
|
+ {
|
|
enum starpu_perf_archtype arch = starpu_worker_get_perf_archtype(w);
|
|
enum starpu_perf_archtype arch = starpu_worker_get_perf_archtype(w);
|
|
- if (t1->duration[arch] != -1.0)
|
|
|
|
|
|
+ if (!isnan(t1->duration[arch]))
|
|
fprintf(output, " +t%luw%d", t1->id, w);
|
|
fprintf(output, " +t%luw%d", t1->id, w);
|
|
}
|
|
}
|
|
fprintf(output, " = 1;\n");
|
|
fprintf(output, " = 1;\n");
|
|
@@ -433,11 +464,13 @@ void starpu_bound_print_lp(FILE *output)
|
|
|
|
|
|
fprintf(output, "\n/* Completion time is start time plus computation time */\n");
|
|
fprintf(output, "\n/* Completion time is start time plus computation time */\n");
|
|
fprintf(output, "/* According to where the task is indeed executed */\n");
|
|
fprintf(output, "/* According to where the task is indeed executed */\n");
|
|
- for (t1 = tasks; t1; t1 = t1->next) {
|
|
|
|
- fprintf(output, "/* %s %x */\tc%lu = s%lu", t1->cl->model->symbol, (unsigned) t1->footprint, t1->id, t1->id);
|
|
|
|
- for (w = 0; w < nw; w++) {
|
|
|
|
|
|
+ for (t1 = tasks; t1; t1 = t1->next)
|
|
|
|
+ {
|
|
|
|
+ fprintf(output, "/* %s %x */\tc%lu = s%lu", t1->cl->name, (unsigned) t1->footprint, t1->id, t1->id);
|
|
|
|
+ for (w = 0; w < nw; w++)
|
|
|
|
+ {
|
|
enum starpu_perf_archtype arch = starpu_worker_get_perf_archtype(w);
|
|
enum starpu_perf_archtype arch = starpu_worker_get_perf_archtype(w);
|
|
- if (t1->duration[arch] != -1.0)
|
|
|
|
|
|
+ if (!isnan(t1->duration[arch]))
|
|
fprintf(output, " + %f t%luw%d", t1->duration[arch], t1->id, w);
|
|
fprintf(output, " + %f t%luw%d", t1->duration[arch], t1->id, w);
|
|
}
|
|
}
|
|
fprintf(output, ";\n");
|
|
fprintf(output, ";\n");
|
|
@@ -451,7 +484,8 @@ void starpu_bound_print_lp(FILE *output)
|
|
|
|
|
|
fprintf(output, "\n/* Each tag finishes when its corresponding task finishes */");
|
|
fprintf(output, "\n/* Each tag finishes when its corresponding task finishes */");
|
|
for (t1 = tasks; t1; t1 = t1->next)
|
|
for (t1 = tasks; t1; t1 = t1->next)
|
|
- if (t1->use_tag) {
|
|
|
|
|
|
+ if (t1->use_tag)
|
|
|
|
+ {
|
|
for (w = 0; w < nw; w++)
|
|
for (w = 0; w < nw; w++)
|
|
fprintf(output, "c%lu = tag%lu;\n", t1->id, (unsigned long) t1->tag_id);
|
|
fprintf(output, "c%lu = tag%lu;\n", t1->id, (unsigned long) t1->tag_id);
|
|
}
|
|
}
|
|
@@ -463,13 +497,17 @@ void starpu_bound_print_lp(FILE *output)
|
|
/* TODO: factorize ancestor calls */
|
|
/* TODO: factorize ancestor calls */
|
|
fprintf(output, "\n/* For each task pair and each worker, if both tasks are executed by the same worker,\n");
|
|
fprintf(output, "\n/* For each task pair and each worker, if both tasks are executed by the same worker,\n");
|
|
fprintf(output, " one is started after the other's completion */\n");
|
|
fprintf(output, " one is started after the other's completion */\n");
|
|
- for (t1 = tasks; t1; t1 = t1->next) {
|
|
|
|
|
|
+ for (t1 = tasks; t1; t1 = t1->next)
|
|
|
|
+ {
|
|
for (t2 = t1->next; t2; t2 = t2->next)
|
|
for (t2 = t1->next; t2; t2 = t2->next)
|
|
{
|
|
{
|
|
- if (!ancestor(t1, t2) && !ancestor(t2, t1)) {
|
|
|
|
- for (w = 0; w < nw; w++) {
|
|
|
|
|
|
+ if (!ancestor(t1, t2) && !ancestor(t2, t1))
|
|
|
|
+ {
|
|
|
|
+ for (w = 0; w < nw; w++)
|
|
|
|
+ {
|
|
enum starpu_perf_archtype arch = starpu_worker_get_perf_archtype(w);
|
|
enum starpu_perf_archtype arch = starpu_worker_get_perf_archtype(w);
|
|
- if (t1->duration[arch] != -1.0) {
|
|
|
|
|
|
+ if (!isnan(t1->duration[arch]))
|
|
|
|
+ {
|
|
fprintf(output, "s%lu - c%lu >= -3e5 + 1e5 t%luw%d + 1e5 t%luw%d + 1e5 t%luafter%lu;\n",
|
|
fprintf(output, "s%lu - c%lu >= -3e5 + 1e5 t%luw%d + 1e5 t%luw%d + 1e5 t%luafter%lu;\n",
|
|
t1->id, t2->id, t1->id, w, t2->id, w, t1->id, t2->id);
|
|
t1->id, t2->id, t1->id, w, t2->id, w, t1->id, t2->id);
|
|
fprintf(output, "s%lu - c%lu >= -2e5 + 1e5 t%luw%d + 1e5 t%luw%d - 1e5 t%luafter%lu;\n",
|
|
fprintf(output, "s%lu - c%lu >= -2e5 + 1e5 t%luw%d + 1e5 t%luw%d - 1e5 t%luafter%lu;\n",
|
|
@@ -491,26 +529,32 @@ void starpu_bound_print_lp(FILE *output)
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- if (recordprio) {
|
|
|
|
|
|
+ if (recordprio)
|
|
|
|
+ {
|
|
fprintf(output, "\n/* For StarPU, a priority means given schedulable tasks it will consider the\n");
|
|
fprintf(output, "\n/* For StarPU, a priority means given schedulable tasks it will consider the\n");
|
|
fprintf(output, " * more prioritized first */\n");
|
|
fprintf(output, " * more prioritized first */\n");
|
|
- for (t1 = tasks; t1; t1 = t1->next) {
|
|
|
|
|
|
+ for (t1 = tasks; t1; t1 = t1->next)
|
|
|
|
+ {
|
|
for (t2 = t1->next; t2; t2 = t2->next)
|
|
for (t2 = t1->next; t2; t2 = t2->next)
|
|
{
|
|
{
|
|
if (!ancestor(t1, t2) && !ancestor(t2, t1)
|
|
if (!ancestor(t1, t2) && !ancestor(t2, t1)
|
|
- && t1->priority != t2->priority) {
|
|
|
|
- if (t1->priority > t2->priority) {
|
|
|
|
|
|
+ && t1->priority != t2->priority)
|
|
|
|
+ {
|
|
|
|
+ if (t1->priority > t2->priority)
|
|
|
|
+ {
|
|
/* Either t2 is scheduled before t1, but then it
|
|
/* Either t2 is scheduled before t1, but then it
|
|
needs to be scheduled before some t dep finishes */
|
|
needs to be scheduled before some t dep finishes */
|
|
|
|
|
|
/* One of the t1 deps to give the maximum start time for t2 */
|
|
/* One of the t1 deps to give the maximum start time for t2 */
|
|
- if (t1->depsn > 1) {
|
|
|
|
|
|
+ if (t1->depsn > 1)
|
|
|
|
+ {
|
|
for (i = 0; i < t1->depsn; i++)
|
|
for (i = 0; i < t1->depsn; i++)
|
|
fprintf(output, " + t%lut%lud%d", t2->id, t1->id, i);
|
|
fprintf(output, " + t%lut%lud%d", t2->id, t1->id, i);
|
|
fprintf(output, " = 1;\n");
|
|
fprintf(output, " = 1;\n");
|
|
}
|
|
}
|
|
|
|
|
|
- for (i = 0; i < t1->depsn; i++) {
|
|
|
|
|
|
+ for (i = 0; i < t1->depsn; i++)
|
|
|
|
+ {
|
|
fprintf(output, "c%lu - s%lu >= ", t1->deps[i]->id, t2->id);
|
|
fprintf(output, "c%lu - s%lu >= ", t1->deps[i]->id, t2->id);
|
|
if (t1->depsn > 1)
|
|
if (t1->depsn > 1)
|
|
/* Only checks this when it's this dependency that is chosen */
|
|
/* Only checks this when it's this dependency that is chosen */
|
|
@@ -524,18 +568,22 @@ void starpu_bound_print_lp(FILE *output)
|
|
|
|
|
|
/* Or t2 is scheduled after t1 is. */
|
|
/* Or t2 is scheduled after t1 is. */
|
|
fprintf(output, "s%lu - s%lu >= -1e5 t%luafter%lu;\n", t2->id, t1->id, t1->id, t2->id);
|
|
fprintf(output, "s%lu - s%lu >= -1e5 t%luafter%lu;\n", t2->id, t1->id, t1->id, t2->id);
|
|
- } else {
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
/* Either t1 is scheduled before t2, but then it
|
|
/* Either t1 is scheduled before t2, but then it
|
|
needs to be scheduled before some t2 dep finishes */
|
|
needs to be scheduled before some t2 dep finishes */
|
|
|
|
|
|
/* One of the t2 deps to give the maximum start time for t1 */
|
|
/* One of the t2 deps to give the maximum start time for t1 */
|
|
- if (t2->depsn > 1) {
|
|
|
|
|
|
+ if (t2->depsn > 1)
|
|
|
|
+ {
|
|
for (i = 0; i < t2->depsn; i++)
|
|
for (i = 0; i < t2->depsn; i++)
|
|
fprintf(output, " + t%lut%lud%d", t1->id, t2->id, i);
|
|
fprintf(output, " + t%lut%lud%d", t1->id, t2->id, i);
|
|
fprintf(output, " = 1;\n");
|
|
fprintf(output, " = 1;\n");
|
|
}
|
|
}
|
|
|
|
|
|
- for (i = 0; i < t2->depsn; i++) {
|
|
|
|
|
|
+ for (i = 0; i < t2->depsn; i++)
|
|
|
|
+ {
|
|
fprintf(output, "c%lu - s%lu >= ", t2->deps[i]->id, t1->id);
|
|
fprintf(output, "c%lu - s%lu >= ", t2->deps[i]->id, t1->id);
|
|
if (t2->depsn > 1)
|
|
if (t2->depsn > 1)
|
|
/* Only checks this when it's this dependency that is chosen */
|
|
/* Only checks this when it's this dependency that is chosen */
|
|
@@ -555,14 +603,19 @@ void starpu_bound_print_lp(FILE *output)
|
|
|
|
|
|
for (t1 = tasks; t1; t1 = t1->next)
|
|
for (t1 = tasks; t1; t1 = t1->next)
|
|
for (t2 = t1->next; t2; t2 = t2->next)
|
|
for (t2 = t1->next; t2; t2 = t2->next)
|
|
- if (!ancestor(t1, t2) && !ancestor(t2, t1)) {
|
|
|
|
|
|
+ if (!ancestor(t1, t2) && !ancestor(t2, t1))
|
|
|
|
+ {
|
|
fprintf(output, "bin t%luafter%lu;\n", t1->id, t2->id);
|
|
fprintf(output, "bin t%luafter%lu;\n", t1->id, t2->id);
|
|
- if (recordprio && t1->priority != t2->priority) {
|
|
|
|
- if (t1->priority > t2->priority) {
|
|
|
|
|
|
+ if (recordprio && t1->priority != t2->priority)
|
|
|
|
+ {
|
|
|
|
+ if (t1->priority > t2->priority)
|
|
|
|
+ {
|
|
if (t1->depsn > 1)
|
|
if (t1->depsn > 1)
|
|
for (i = 0; i < t1->depsn; i++)
|
|
for (i = 0; i < t1->depsn; i++)
|
|
fprintf(output, "bin t%lut%lud%d;\n", t2->id, t1->id, i);
|
|
fprintf(output, "bin t%lut%lud%d;\n", t2->id, t1->id, i);
|
|
- } else {
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
if (t2->depsn > 1)
|
|
if (t2->depsn > 1)
|
|
for (i = 0; i < t2->depsn; i++)
|
|
for (i = 0; i < t2->depsn; i++)
|
|
fprintf(output, "bin t%lut%lud%d;\n", t1->id, t2->id, i);
|
|
fprintf(output, "bin t%lut%lud%d;\n", t1->id, t2->id, i);
|
|
@@ -573,7 +626,9 @@ void starpu_bound_print_lp(FILE *output)
|
|
for (t1 = tasks; t1; t1 = t1->next)
|
|
for (t1 = tasks; t1; t1 = t1->next)
|
|
for (w = 0; w < nw; w++)
|
|
for (w = 0; w < nw; w++)
|
|
fprintf(output, "bin t%luw%d;\n", t1->id, w);
|
|
fprintf(output, "bin t%luw%d;\n", t1->id, w);
|
|
- } else {
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
struct bound_task_pool *tp;
|
|
struct bound_task_pool *tp;
|
|
nt = 0;
|
|
nt = 0;
|
|
for (tp = task_pools; tp; tp = tp->next)
|
|
for (tp = task_pools; tp; tp = tp->next)
|
|
@@ -589,12 +644,14 @@ void starpu_bound_print_lp(FILE *output)
|
|
fprintf(output, "min: tmax;\n\n");
|
|
fprintf(output, "min: tmax;\n\n");
|
|
|
|
|
|
fprintf(output, "/* Which is the maximum of all worker execution times (ms) */\n");
|
|
fprintf(output, "/* Which is the maximum of all worker execution times (ms) */\n");
|
|
- for (w = 0; w < nw; w++) {
|
|
|
|
|
|
+ for (w = 0; w < nw; w++)
|
|
|
|
+ {
|
|
char name[32];
|
|
char name[32];
|
|
starpu_worker_get_name(w, name, sizeof(name));
|
|
starpu_worker_get_name(w, name, sizeof(name));
|
|
- fprintf(output, "/* worker %s */\n", name);
|
|
|
|
- for (t = 0, tp = task_pools; tp; t++, tp = tp->next) {
|
|
|
|
- if (times[w*nt+t] != -1.0)
|
|
|
|
|
|
+ fprintf(output, "/* worker %s */\n0", name);
|
|
|
|
+ for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
|
|
+ {
|
|
|
|
+ if (!isnan(times[w*nt+t]))
|
|
fprintf(output, "\t%+f * w%dt%dn", (float) times[w*nt+t], w, t);
|
|
fprintf(output, "\t%+f * w%dt%dn", (float) times[w*nt+t], w, t);
|
|
}
|
|
}
|
|
fprintf(output, " <= tmax;\n");
|
|
fprintf(output, " <= tmax;\n");
|
|
@@ -602,10 +659,11 @@ void starpu_bound_print_lp(FILE *output)
|
|
fprintf(output, "\n");
|
|
fprintf(output, "\n");
|
|
|
|
|
|
fprintf(output, "/* And we have to have computed exactly all tasks */\n");
|
|
fprintf(output, "/* And we have to have computed exactly all tasks */\n");
|
|
- for (t = 0, tp = task_pools; tp; t++, tp = tp->next) {
|
|
|
|
- fprintf(output, "/* task %s key %x */\n", tp->cl->model->symbol, (unsigned) tp->footprint);
|
|
|
|
|
|
+ for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
|
|
+ {
|
|
|
|
+ fprintf(output, "/* task %s key %x */\n0", tp->cl->name, (unsigned) tp->footprint);
|
|
for (w = 0; w < nw; w++)
|
|
for (w = 0; w < nw; w++)
|
|
- if (times[w*nt+t] != -1.0)
|
|
|
|
|
|
+ if (!isnan(times[w*nt+t]))
|
|
fprintf(output, "\t+w%dt%dn", w, t);
|
|
fprintf(output, "\t+w%dt%dn", w, t);
|
|
fprintf(output, " = %lu;\n", tp->n);
|
|
fprintf(output, " = %lu;\n", tp->n);
|
|
/* Show actual values */
|
|
/* Show actual values */
|
|
@@ -619,7 +677,8 @@ void starpu_bound_print_lp(FILE *output)
|
|
fprintf(output, "/* int ");
|
|
fprintf(output, "/* int ");
|
|
int first = 1;
|
|
int first = 1;
|
|
for (w = 0; w < nw; w++)
|
|
for (w = 0; w < nw; w++)
|
|
- for (t = 0, tp = task_pools; tp; t++, tp = tp->next) {
|
|
|
|
|
|
+ for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
|
|
+ {
|
|
if (!first)
|
|
if (!first)
|
|
fprintf(output, ",");
|
|
fprintf(output, ",");
|
|
else
|
|
else
|
|
@@ -630,7 +689,7 @@ void starpu_bound_print_lp(FILE *output)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -643,18 +702,18 @@ void starpu_bound_print_mps(FILE *output)
|
|
int nw; /* Number of different workers */
|
|
int nw; /* Number of different workers */
|
|
int t, w;
|
|
int t, w;
|
|
|
|
|
|
- if (recorddeps) {
|
|
|
|
|
|
+ if (recorddeps)
|
|
|
|
+ {
|
|
fprintf(output, "Not supported\n");
|
|
fprintf(output, "Not supported\n");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
nw = starpu_worker_get_count();
|
|
nw = starpu_worker_get_count();
|
|
nt = 0;
|
|
nt = 0;
|
|
for (tp = task_pools; tp; tp = tp->next)
|
|
for (tp = task_pools; tp; tp = tp->next)
|
|
nt++;
|
|
nt++;
|
|
-
|
|
|
|
{
|
|
{
|
|
double times[nw*nt];
|
|
double times[nw*nt];
|
|
|
|
|
|
@@ -668,7 +727,8 @@ void starpu_bound_print_mps(FILE *output)
|
|
fprintf(output, " N TMAX\n");
|
|
fprintf(output, " N TMAX\n");
|
|
|
|
|
|
fprintf(output, "\n* Which is the maximum of all worker execution times (ms)\n");
|
|
fprintf(output, "\n* Which is the maximum of all worker execution times (ms)\n");
|
|
- for (w = 0; w < nw; w++) {
|
|
|
|
|
|
+ for (w = 0; w < nw; w++)
|
|
|
|
+ {
|
|
char name[32];
|
|
char name[32];
|
|
starpu_worker_get_name(w, name, sizeof(name));
|
|
starpu_worker_get_name(w, name, sizeof(name));
|
|
fprintf(output, "* worker %s\n", name);
|
|
fprintf(output, "* worker %s\n", name);
|
|
@@ -676,8 +736,9 @@ void starpu_bound_print_mps(FILE *output)
|
|
}
|
|
}
|
|
|
|
|
|
fprintf(output, "\n* And we have to have computed exactly all tasks\n");
|
|
fprintf(output, "\n* And we have to have computed exactly all tasks\n");
|
|
- for (t = 0, tp = task_pools; tp; t++, tp = tp->next) {
|
|
|
|
- fprintf(output, "* task %s key %x\n", tp->cl->model->symbol, (unsigned) tp->footprint);
|
|
|
|
|
|
+ for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
|
|
+ {
|
|
|
|
+ fprintf(output, "* task %s key %x\n", tp->cl->name, (unsigned) tp->footprint);
|
|
fprintf(output, " E T%d\n", t);
|
|
fprintf(output, " E T%d\n", t);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -686,7 +747,8 @@ void starpu_bound_print_mps(FILE *output)
|
|
fprintf(output, "\n* Execution times and completion of all tasks\n");
|
|
fprintf(output, "\n* Execution times and completion of all tasks\n");
|
|
for (w = 0; w < nw; w++)
|
|
for (w = 0; w < nw; w++)
|
|
for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
- if (times[w*nt+t] != -1.0) {
|
|
|
|
|
|
+ if (!isnan(times[w*nt+t]))
|
|
|
|
+ {
|
|
char name[9];
|
|
char name[9];
|
|
snprintf(name, sizeof(name), "W%dT%d", w, t);
|
|
snprintf(name, sizeof(name), "W%dT%d", w, t);
|
|
fprintf(stderr," %-8s W%-7d %12f\n", name, w, times[w*nt+t]);
|
|
fprintf(stderr," %-8s W%-7d %12f\n", name, w, times[w*nt+t]);
|
|
@@ -707,7 +769,7 @@ void starpu_bound_print_mps(FILE *output)
|
|
fprintf(output, "ENDATA\n");
|
|
fprintf(output, "ENDATA\n");
|
|
}
|
|
}
|
|
|
|
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -751,7 +813,8 @@ static glp_prob *_starpu_bound_glp_resolve(int integer)
|
|
glp_set_obj_coef(lp, nw*nt+1, 1.);
|
|
glp_set_obj_coef(lp, nw*nt+1, 1.);
|
|
|
|
|
|
for (w = 0; w < nw; w++)
|
|
for (w = 0; w < nw; w++)
|
|
- for (t = 0, tp = task_pools; tp; t++, tp = tp->next) {
|
|
|
|
|
|
+ for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
|
|
+ {
|
|
char name[32];
|
|
char name[32];
|
|
snprintf(name, sizeof(name), "w%dt%dn", w, t);
|
|
snprintf(name, sizeof(name), "w%dt%dn", w, t);
|
|
glp_set_col_name(lp, colnum(w, t), name);
|
|
glp_set_col_name(lp, colnum(w, t), name);
|
|
@@ -763,15 +826,30 @@ static glp_prob *_starpu_bound_glp_resolve(int integer)
|
|
|
|
|
|
/* Total worker execution time */
|
|
/* Total worker execution time */
|
|
glp_add_rows(lp, nw);
|
|
glp_add_rows(lp, nw);
|
|
- for (w = 0; w < nw; w++) {
|
|
|
|
|
|
+ for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
|
|
+ {
|
|
|
|
+ int someone = 0;
|
|
|
|
+ for (w = 0; w < nw; w++)
|
|
|
|
+ if (!isnan(times[w*nt+t]))
|
|
|
|
+ someone = 1;
|
|
|
|
+ if (!someone)
|
|
|
|
+ {
|
|
|
|
+ /* This task does not have any performance model at all, abort */
|
|
|
|
+ glp_delete_prob(lp);
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for (w = 0; w < nw; w++)
|
|
|
|
+ {
|
|
char name[32], title[64];
|
|
char name[32], title[64];
|
|
starpu_worker_get_name(w, name, sizeof(name));
|
|
starpu_worker_get_name(w, name, sizeof(name));
|
|
snprintf(title, sizeof(title), "worker %s", name);
|
|
snprintf(title, sizeof(title), "worker %s", name);
|
|
glp_set_row_name(lp, w+1, title);
|
|
glp_set_row_name(lp, w+1, title);
|
|
- for (t = 0, tp = task_pools; tp; t++, tp = tp->next) {
|
|
|
|
|
|
+ for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
|
|
+ {
|
|
ia[n] = w+1;
|
|
ia[n] = w+1;
|
|
ja[n] = colnum(w, t);
|
|
ja[n] = colnum(w, t);
|
|
- if (times[w*nt+t] == -1.)
|
|
|
|
|
|
+ if (isnan(times[w*nt+t]))
|
|
ar[n] = 1000000000.;
|
|
ar[n] = 1000000000.;
|
|
else
|
|
else
|
|
ar[n] = times[w*nt+t];
|
|
ar[n] = times[w*nt+t];
|
|
@@ -787,12 +865,14 @@ static glp_prob *_starpu_bound_glp_resolve(int integer)
|
|
|
|
|
|
/* Total task completion */
|
|
/* Total task completion */
|
|
glp_add_rows(lp, nt);
|
|
glp_add_rows(lp, nt);
|
|
- for (t = 0, tp = task_pools; tp; t++, tp = tp->next) {
|
|
|
|
|
|
+ for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
|
|
+ {
|
|
char name[32], title[64];
|
|
char name[32], title[64];
|
|
starpu_worker_get_name(w, name, sizeof(name));
|
|
starpu_worker_get_name(w, name, sizeof(name));
|
|
- snprintf(title, sizeof(title), "task %s key %x", tp->cl->model->symbol, (unsigned) tp->footprint);
|
|
|
|
|
|
+ snprintf(title, sizeof(title), "task %s key %x", tp->cl->name, (unsigned) tp->footprint);
|
|
glp_set_row_name(lp, nw+t+1, title);
|
|
glp_set_row_name(lp, nw+t+1, title);
|
|
- for (w = 0; w < nw; w++) {
|
|
|
|
|
|
+ for (w = 0; w < nw; w++)
|
|
|
|
+ {
|
|
ia[n] = nw+t+1;
|
|
ia[n] = nw+t+1;
|
|
ja[n] = colnum(w, t);
|
|
ja[n] = colnum(w, t);
|
|
ar[n] = 1;
|
|
ar[n] = 1;
|
|
@@ -810,12 +890,14 @@ static glp_prob *_starpu_bound_glp_resolve(int integer)
|
|
glp_init_smcp(&parm);
|
|
glp_init_smcp(&parm);
|
|
parm.msg_lev = GLP_MSG_OFF;
|
|
parm.msg_lev = GLP_MSG_OFF;
|
|
ret = glp_simplex(lp, &parm);
|
|
ret = glp_simplex(lp, &parm);
|
|
- if (ret) {
|
|
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
glp_delete_prob(lp);
|
|
glp_delete_prob(lp);
|
|
lp = NULL;
|
|
lp = NULL;
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
- if (integer) {
|
|
|
|
|
|
+ if (integer)
|
|
|
|
+ {
|
|
glp_iocp iocp;
|
|
glp_iocp iocp;
|
|
glp_init_iocp(&iocp);
|
|
glp_init_iocp(&iocp);
|
|
iocp.msg_lev = GLP_MSG_OFF;
|
|
iocp.msg_lev = GLP_MSG_OFF;
|
|
@@ -826,16 +908,19 @@ static glp_prob *_starpu_bound_glp_resolve(int integer)
|
|
}
|
|
}
|
|
#endif /* HAVE_GLPK_H */
|
|
#endif /* HAVE_GLPK_H */
|
|
|
|
|
|
-void starpu_bound_print(FILE *output, int integer __attribute__ ((unused))) {
|
|
|
|
|
|
+void starpu_bound_print(FILE *output, int integer __attribute__ ((unused)))
|
|
|
|
+{
|
|
#ifdef HAVE_GLPK_H
|
|
#ifdef HAVE_GLPK_H
|
|
- if (recorddeps) {
|
|
|
|
|
|
+ if (recorddeps)
|
|
|
|
+ {
|
|
fprintf(output, "Not supported\n");
|
|
fprintf(output, "Not supported\n");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_LOCK(&mutex);
|
|
glp_prob *lp = _starpu_bound_glp_resolve(integer);
|
|
glp_prob *lp = _starpu_bound_glp_resolve(integer);
|
|
- if (lp) {
|
|
|
|
|
|
+ if (lp)
|
|
|
|
+ {
|
|
struct bound_task_pool * tp;
|
|
struct bound_task_pool * tp;
|
|
int t, w;
|
|
int t, w;
|
|
int nw; /* Number of different workers */
|
|
int nw; /* Number of different workers */
|
|
@@ -850,8 +935,9 @@ void starpu_bound_print(FILE *output, int integer __attribute__ ((unused))) {
|
|
|
|
|
|
fprintf(output, "Theoretical minimum execution time: %f ms\n", tmax);
|
|
fprintf(output, "Theoretical minimum execution time: %f ms\n", tmax);
|
|
|
|
|
|
- for (t = 0, tp = task_pools; tp; t++, tp = tp->next) {
|
|
|
|
- fprintf(output, "%s key %x\n", tp->cl->model->symbol, (unsigned) tp->footprint);
|
|
|
|
|
|
+ for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
|
|
|
|
+ {
|
|
|
|
+ fprintf(output, "%s key %x\n", tp->cl->name, (unsigned) tp->footprint);
|
|
for (w = 0; w < nw; w++)
|
|
for (w = 0; w < nw; w++)
|
|
if (integer)
|
|
if (integer)
|
|
fprintf(output, "\tw%dt%dn %f", w, t, glp_mip_col_val(lp, colnum(w, t)));
|
|
fprintf(output, "\tw%dt%dn %f", w, t, glp_mip_col_val(lp, colnum(w, t)));
|
|
@@ -861,34 +947,40 @@ void starpu_bound_print(FILE *output, int integer __attribute__ ((unused))) {
|
|
}
|
|
}
|
|
|
|
|
|
glp_delete_prob(lp);
|
|
glp_delete_prob(lp);
|
|
- } else {
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
fprintf(stderr, "Simplex failed\n");
|
|
fprintf(stderr, "Simplex failed\n");
|
|
}
|
|
}
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
#else /* HAVE_GLPK_H */
|
|
#else /* HAVE_GLPK_H */
|
|
fprintf(output, "Please rebuild StarPU with glpk installed.\n");
|
|
fprintf(output, "Please rebuild StarPU with glpk installed.\n");
|
|
#endif /* HAVE_GLPK_H */
|
|
#endif /* HAVE_GLPK_H */
|
|
}
|
|
}
|
|
|
|
|
|
-void starpu_bound_compute(double *res, double *integer_res __attribute__ ((unused)), int integer __attribute__ ((unused))) {
|
|
|
|
|
|
+void starpu_bound_compute(double *res, double *integer_res __attribute__ ((unused)), int integer __attribute__ ((unused)))
|
|
|
|
+{
|
|
#ifdef HAVE_GLPK_H
|
|
#ifdef HAVE_GLPK_H
|
|
double ret;
|
|
double ret;
|
|
|
|
|
|
- if (recorddeps) {
|
|
|
|
|
|
+ if (recorddeps)
|
|
|
|
+ {
|
|
*res = 0.;
|
|
*res = 0.;
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- PTHREAD_MUTEX_LOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_LOCK(&mutex);
|
|
glp_prob *lp = _starpu_bound_glp_resolve(integer);
|
|
glp_prob *lp = _starpu_bound_glp_resolve(integer);
|
|
- if (lp) {
|
|
|
|
|
|
+ if (lp)
|
|
|
|
+ {
|
|
ret = glp_get_obj_val(lp);
|
|
ret = glp_get_obj_val(lp);
|
|
if (integer)
|
|
if (integer)
|
|
*integer_res = glp_mip_obj_val(lp);
|
|
*integer_res = glp_mip_obj_val(lp);
|
|
glp_delete_prob(lp);
|
|
glp_delete_prob(lp);
|
|
- } else
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
ret = 0.;
|
|
ret = 0.;
|
|
- PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
|
|
|
|
+ _STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
|
|
*res = ret;
|
|
*res = ret;
|
|
#else /* HAVE_GLPK_H */
|
|
#else /* HAVE_GLPK_H */
|
|
*res = 0.;
|
|
*res = 0.;
|