From a6aaf48ca5327df495024038ef17cfb5dad80e3c Mon Sep 17 00:00:00 2001 From: Matthieu Schaller <matthieu.schaller@durham.ac.uk> Date: Mon, 5 Dec 2016 18:39:12 +0000 Subject: [PATCH] Created the task and dependencies --- src/cell.c | 7 +++++++ src/cell.h | 3 +++ src/engine.c | 7 +++++++ src/runner.c | 22 +++++++++++++++------- src/scheduler.c | 37 ++++++++++++++++++++++++++++++++----- src/task.c | 3 ++- src/task.h | 1 + 7 files changed, 67 insertions(+), 13 deletions(-) diff --git a/src/cell.c b/src/cell.c index e2767cdaa9..fcbbfe4ae1 100644 --- a/src/cell.c +++ b/src/cell.c @@ -878,6 +878,12 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) { } } + /* Activate the drift on both sides */ + if (t->type == task_type_pair || t->type == task_type_sub_pair) { + scheduler_activate(s, ci->drift); + scheduler_activate(s, cj->drift); + } + /* Check whether there was too much particle motion */ if (t->type == task_type_pair || t->type == task_type_sub_pair) { if (t->tight && @@ -956,6 +962,7 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) { if (c->ghost != NULL) scheduler_activate(s, c->ghost); if (c->init != NULL) scheduler_activate(s, c->init); if (c->kick != NULL) scheduler_activate(s, c->kick); + if (c->drift != NULL) scheduler_activate(s, c->drift); if (c->cooling != NULL) scheduler_activate(s, c->cooling); if (c->sourceterms != NULL) scheduler_activate(s, c->sourceterms); diff --git a/src/cell.h b/src/cell.h index 2cd13cf2ab..d978de71f7 100644 --- a/src/cell.h +++ b/src/cell.h @@ -147,6 +147,9 @@ struct cell { /*! The extra ghost task for complex hydro schemes */ struct task *extra_ghost; + /*! The drift task */ + struct task *drift; + /*! The kick task */ struct task *kick; diff --git a/src/engine.c b/src/engine.c index e989aefd53..111f0a230a 100644 --- a/src/engine.c +++ b/src/engine.c @@ -139,6 +139,9 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { c->init = scheduler_addtask(s, task_type_init, task_subtype_none, 0, 0, c, NULL, 0); + /* c->drift = scheduler_addtask(s, task_type_drift, task_subtype_none, 0, 0, */ + /* c, NULL, 0); */ + c->kick = scheduler_addtask(s, task_type_kick, task_subtype_none, 0, 0, c, NULL, 0); @@ -1990,6 +1993,10 @@ void engine_marktasks_mapper(void *map_data, int num_elements, const struct cell *ci = t->ci; const struct cell *cj = t->cj; + /* Activate the drift on both sides */ + if(ci->drift) scheduler_activate(s, ci->drift); + if(ci->drift) scheduler_activate(s, cj->drift); + /* Too much particle movement? */ if (t->tight && (max(ci->h_max, cj->h_max) + ci->dx_max + cj->dx_max > cj->dmin || diff --git a/src/runner.c b/src/runner.c index 2d6da4e4ae..a62fb87a8c 100644 --- a/src/runner.c +++ b/src/runner.c @@ -752,7 +752,7 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { * @param drift whether to actually drift the particles, will not be * necessary for non-local cells. */ -static void runner_do_drift(struct cell *c, struct engine *e, int drift) { +static void runner_do_unskip(struct cell *c, struct engine *e, int drift) { /* Unskip any active tasks. */ if (cell_is_active(c, e)) { @@ -770,7 +770,7 @@ static void runner_do_drift(struct cell *c, struct engine *e, int drift) { for (int k = 0; k < 8; k++) { if (c->progeny[k] != NULL) { struct cell *cp = c->progeny[k]; - runner_do_drift(cp, e, 0); + runner_do_unskip(cp, e, 0); } } } @@ -778,7 +778,6 @@ static void runner_do_drift(struct cell *c, struct engine *e, int drift) { } /* Now, we can drift */ - /* Get some information first */ const double timeBase = e->timeBase; const int ti_old = c->ti_old; @@ -856,7 +855,7 @@ static void runner_do_drift(struct cell *c, struct engine *e, int drift) { struct cell *cp = c->progeny[k]; /* Recurse. */ - runner_do_drift(cp, e, drift); + runner_do_unskip(cp, e, drift); dx_max = max(dx_max, cp->dx_max); h_max = max(h_max, cp->h_max); } @@ -887,13 +886,15 @@ void runner_do_drift_mapper(void *map_data, int num_elements, for (int ind = 0; ind < num_elements; ind++) { struct cell *c = &cells[ind]; #ifdef WITH_MPI - if (c != NULL) runner_do_drift(c, e, (c->nodeID == e->nodeID)); + if (c != NULL) runner_do_unskip(c, e, (c->nodeID == e->nodeID)); #else - if (c != NULL) runner_do_drift(c, e, 1); + if (c != NULL) runner_do_unskip(c, e, 1); #endif } } +void runner_do_drift(struct runner *r, struct cell *c, int timer) {} + /** * @brief Kick particles in momentum space and collect statistics (floating * time-step case) @@ -1126,7 +1127,7 @@ void *runner_main(void *data) { /* Check that we haven't scheduled an inactive task */ #ifdef SWIFT_DEBUG_CHECKS if (cj == NULL) { /* self */ - if (!cell_is_active(ci, e) && t->type != task_type_sort) + if (!cell_is_active(ci, e) && t->type != task_type_sort && t->type != task_type_drift) error( "Task (type='%s/%s') should have been skipped ti_current=%d " "c->ti_end_min=%d", @@ -1142,6 +1143,10 @@ void *runner_main(void *data) { taskID_names[t->type], subtaskID_names[t->subtype], e->ti_current, ci->ti_end_min, t->flags); + /* Special treatement for drifts */ + if (!cell_is_active(ci, e) && t->type == task_type_drift) + {;} + } else { /* pair */ if (!cell_is_active(ci, e) && !cell_is_active(cj, e)) error( @@ -1231,6 +1236,9 @@ void *runner_main(void *data) { runner_do_extra_ghost(r, ci, 1); break; #endif + case task_type_drift: + // runner_do_drift(r, ci, 1); + break; case task_type_kick: runner_do_kick(r, ci, 1); break; diff --git a/src/scheduler.c b/src/scheduler.c index 0d7c8c4754..4574d4a1d9 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -133,6 +133,7 @@ static void scheduler_splittask(struct task *t, struct scheduler *s) { /* Non-splittable task? */ if ((t->ci == NULL || (t->type == task_type_pair && t->cj == NULL)) || ((t->type == task_type_kick) && t->ci->nodeID != s->nodeID) || + ((t->type == task_type_drift) && t->ci->nodeID != s->nodeID) || ((t->type == task_type_init) && t->ci->nodeID != s->nodeID)) { t->type = task_type_none; t->skip = 1; @@ -603,7 +604,7 @@ static void scheduler_splittask(struct task *t, struct scheduler *s) { tl->flags = space_getsid(s->space, &t->ci, &t->cj, shift); } - /* Otherwise, if not spilt, stitch-up the sorting. */ + /* Otherwise, if not spilt, stitch-up the sorting and drift. */ } else { /* Create the sort for ci. */ @@ -613,9 +614,19 @@ static void scheduler_splittask(struct task *t, struct scheduler *s) { 1 << sid, 0, ci, NULL, 0); else ci->sorts->flags |= (1 << sid); + + scheduler_addunlock(s, ci->sorts, t); + + /* Create the drift for ci. */ + if (ci->drift == NULL) { + ci->drift = scheduler_addtask(s, task_type_drift, task_subtype_none, + 0, 0, ci, NULL, 0); + scheduler_addunlock(s, ci->drift, ci->sorts); + } lock_unlock_blind(&ci->lock); - scheduler_addunlock(s, ci->sorts, t); + + /* Create the sort for cj. */ lock_lock(&cj->lock); if (cj->sorts == NULL) @@ -623,8 +634,16 @@ static void scheduler_splittask(struct task *t, struct scheduler *s) { 1 << sid, 0, cj, NULL, 0); else cj->sorts->flags |= (1 << sid); - lock_unlock_blind(&cj->lock); + scheduler_addunlock(s, cj->sorts, t); + + /* Create the drift for cj. */ + if (cj->drift == NULL) { + cj->drift = scheduler_addtask(s, task_type_drift, task_subtype_none, + 0, 0, cj, NULL, 0); + scheduler_addunlock(s, cj->drift, cj->sorts); + } + lock_unlock_blind(&cj->lock); } } /* pair interaction? */ @@ -782,7 +801,9 @@ void scheduler_set_unlocks(struct scheduler *s) { for (int i = 0; i < t->nr_unlock_tasks; i++) { for (int j = i + 1; j < t->nr_unlock_tasks; j++) { if (t->unlock_tasks[i] == t->unlock_tasks[j]) - error("duplicate unlock!"); + error("duplicate unlock! t->type=%s/%s unlocking type=%s/%s", + taskID_names[t->type], subtaskID_names[t->subtype], + taskID_names[t->unlock_tasks[i]->type], subtaskID_names[t->unlock_tasks[i]->subtype]); } } } @@ -1065,7 +1086,7 @@ void scheduler_start(struct scheduler *s) { if (cj == NULL) { /* self */ if (ci->ti_end_min == ti_current && t->skip && - t->type != task_type_sort) + t->type != task_type_sort && t->type != task_type_drift) error( "Task (type='%s/%s') should not have been skipped ti_current=%d " "c->ti_end_min=%d", @@ -1081,6 +1102,11 @@ void scheduler_start(struct scheduler *s) { taskID_names[t->type], subtaskID_names[t->subtype], ti_current, ci->ti_end_min, t->flags); + /* Special treatement for drifts */ + if (ci->ti_end_min == ti_current && t->skip && + t->type == task_type_drift) + {;} + } else { /* pair */ if ((ci->ti_end_min == ti_current || cj->ti_end_min == ti_current) && @@ -1148,6 +1174,7 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) { case task_type_sort: case task_type_ghost: case task_type_kick: + case task_type_drift: case task_type_init: qid = t->ci->super->owner; break; diff --git a/src/task.c b/src/task.c index ea97fdd1bb..19a8959153 100644 --- a/src/task.c +++ b/src/task.c @@ -49,7 +49,7 @@ /* Task type names. */ const char *taskID_names[task_type_count] = { "none", "sort", "self", "pair", "sub_self", - "sub_pair", "init", "ghost", "extra_ghost", "kick", + "sub_pair", "init", "ghost", "extra_ghost", "drift", "kick", "send", "recv", "grav_gather_m", "grav_fft", "grav_mm", "grav_up", "cooling", "sourceterms"}; @@ -150,6 +150,7 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on( case task_type_kick: case task_type_send: case task_type_recv: + case task_type_drift: if (t->ci->count > 0 && t->ci->gcount > 0) return task_action_all; else if (t->ci->count > 0) diff --git a/src/task.h b/src/task.h index c9425fdd13..b4767f036c 100644 --- a/src/task.h +++ b/src/task.h @@ -45,6 +45,7 @@ enum task_types { task_type_init, task_type_ghost, task_type_extra_ghost, + task_type_drift, task_type_kick, task_type_send, task_type_recv, -- GitLab