Commit 7c4e0c19 authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Promoted the external gravity tasks to a self sub-type such that the super...

Promoted the external gravity tasks to a self sub-type such that the super pointer can be set correctly.
parent 9f03a0e1
...@@ -7,4 +7,4 @@ then ...@@ -7,4 +7,4 @@ then
python makeIC.py 10000 python makeIC.py 10000
fi fi
../swift -g -t 2 externalPointMass.yml 2>&1 | tee output.log ../swift -g -t 1 externalPointMass.yml 2>&1 | tee output.log
...@@ -854,8 +854,6 @@ void cell_set_super(struct cell *c, struct cell *super) { ...@@ -854,8 +854,6 @@ void cell_set_super(struct cell *c, struct cell *super) {
/* Set the super-cell */ /* Set the super-cell */
c->super = super; c->super = super;
//if (c->nr_tasks == 0 && super == NULL) message("No tasks here");
/* Recurse */ /* Recurse */
if (c->split) if (c->split)
for (int k = 0; k < 8; k++) for (int k = 0; k < 8; k++)
......
...@@ -91,8 +91,8 @@ ...@@ -91,8 +91,8 @@
#define const_gravity_eta 0.025f #define const_gravity_eta 0.025f
/* External gravity properties */ /* External gravity properties */
#define EXTERNAL_POTENTIAL_NONE //#define EXTERNAL_POTENTIAL_NONE
//#define EXTERNAL_POTENTIAL_POINTMASS #define EXTERNAL_POTENTIAL_POINTMASS
//#define EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL //#define EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL
//#define EXTERNAL_POTENTIAL_DISC_PATCH //#define EXTERNAL_POTENTIAL_DISC_PATCH
...@@ -103,6 +103,6 @@ ...@@ -103,6 +103,6 @@
//#define COOLING_GRACKLE //#define COOLING_GRACKLE
/* Are we debugging ? */ /* Are we debugging ? */
//#define SWIFT_DEBUG_CHECKS #define SWIFT_DEBUG_CHECKS
#endif /* SWIFT_CONST_H */ #endif /* SWIFT_CONST_H */
...@@ -110,72 +110,14 @@ void engine_addlink(struct engine *e, struct link **l, struct task *t) { ...@@ -110,72 +110,14 @@ void engine_addlink(struct engine *e, struct link **l, struct task *t) {
res->next = atomic_swap(l, res); res->next = atomic_swap(l, res);
} }
/**
* @brief Generate the gravity hierarchical tasks for a hierarchy of cells -
* i.e. all the O(Npart) tasks.
*
* Tasks are only created here. The dependencies will be added later on.
*
* @param e The #engine.
* @param c The #cell.
* @param gsuper The gsuper #cell.
*/
/* void engine_make_gravity_hierarchical_tasks(struct engine *e, struct cell *c)
* { */
/* struct scheduler *s = &e->sched; */
/* const int is_with_external_gravity = */
/* (e->policy & engine_policy_external_gravity); */
/* const int is_fixdt = (e->policy & engine_policy_fixdt); */
/* /\* Are we in a cell with self/pair tasks ? *\/ */
/* if (c->super == c) { */
/* /\* Local tasks only... *\/ */
/* if (c->nodeID == e->nodeID) { */
/* /\* Add the init task. *\/ */
/* if (c->init == NULL) */
/* c->init = scheduler_addtask(s, task_type_init, task_subtype_none, 0,
* 0, */
/* c, NULL, 0); */
/* /\* Add the kick task that matches the policy. *\/ */
/* if (is_fixdt) { */
/* if (c->kick == NULL) */
/* c->kick = scheduler_addtask(s, task_type_kick_fixdt, */
/* task_subtype_none, 0, 0, c, NULL, 0);
*/
/* } else { */
/* if (c->kick == NULL) */
/* c->kick = scheduler_addtask(s, task_type_kick, task_subtype_none,
* 0, */
/* 0, c, NULL, 0); */
/* } */
/* /\* External gravity task *\/ */
/* if (is_with_external_gravity && c->grav_external == NULL) */
/* c->grav_external = scheduler_addtask( */
/* s, task_type_grav_external, task_subtype_none, 0, 0, c, NULL, 0);
*/
/* } */
/* } else { */
/* /\* Recurse. *\/ */
/* if (c->split) */
/* for (int k = 0; k < 8; k++) */
/* if (c->progeny[k] != NULL) */
/* engine_make_gravity_hierarchical_tasks(e, c->progeny[k]); */
/* } */
/* } */
/** /**
* @brief Generate the hydro hierarchical tasks for a hierarchy of cells - * @brief Generate the hydro hierarchical tasks for a hierarchy of cells -
* i.e. all the O(Npart) tasks. * i.e. all the O(Npart) tasks.
* *
* Tasks are only created here. The dependencies will be added later on. * Tasks are only created here. The dependencies will be added later on.
* *
* Note that there is no need to recurse below the super-cell.
*
* @param e The #engine. * @param e The #engine.
* @param c The #cell. * @param c The #cell.
* @param super The super #cell. * @param super The super #cell.
...@@ -184,11 +126,10 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { ...@@ -184,11 +126,10 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) {
struct scheduler *s = &e->sched; struct scheduler *s = &e->sched;
const int is_fixdt = (e->policy & engine_policy_fixdt); const int is_fixdt = (e->policy & engine_policy_fixdt);
const int is_hydro = (e->policy & engine_policy_hydro);
const int is_with_cooling = (e->policy & engine_policy_cooling); const int is_with_cooling = (e->policy & engine_policy_cooling);
const int is_with_external_gravity =
(e->policy & engine_policy_external_gravity);
/* Are we in a cell with self/pair tasks ? */ /* Are we in a super-cell ? */
if (c->super == c) { if (c->super == c) {
/* Local tasks only... */ /* Local tasks only... */
...@@ -208,27 +149,28 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { ...@@ -208,27 +149,28 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) {
} }
/* Generate the ghost task. */ /* Generate the ghost task. */
c->ghost = scheduler_addtask(s, task_type_ghost, task_subtype_none, 0, 0, if (is_hydro)
c, NULL, 0); c->ghost = scheduler_addtask(s, task_type_ghost, task_subtype_none, 0, 0,
c, NULL, 0);
#ifdef EXTRA_HYDRO_LOOP #ifdef EXTRA_HYDRO_LOOP
/* Generate the extra ghost task. */ /* Generate the extra ghost task. */
c->extra_ghost = scheduler_addtask(s, task_type_extra_ghost, if (is_hydro)
task_subtype_none, 0, 0, c, NULL, 0); c->extra_ghost = scheduler_addtask(s, task_type_extra_ghost,
task_subtype_none, 0, 0, c, NULL, 0);
#endif #endif
/* External gravity task */
if (is_with_external_gravity) // && c->grav_external == NULL)
c->grav_external = scheduler_addtask(
s, task_type_grav_external, task_subtype_none, 0, 0, c, NULL, 0);
/* Cooling task */ /* Cooling task */
if (is_with_cooling) if (is_with_cooling)
c->cooling = scheduler_addtask(s, task_type_cooling, task_subtype_none, c->cooling = scheduler_addtask(s, task_type_cooling, task_subtype_none,
0, 0, c, NULL, 0); 0, 0, c, NULL, 0);
} }
} else { } else { /* We are above the super-cell so need to go deeper */
#ifdef SWIFT_DEBUG_CHECKS
if (c->super != NULL) error("Incorrectly set super pointer");
#endif
/* Recurse. */ /* Recurse. */
if (c->split) if (c->split)
...@@ -1283,6 +1225,30 @@ void engine_make_gravity_tasks(struct engine *e) { ...@@ -1283,6 +1225,30 @@ void engine_make_gravity_tasks(struct engine *e) {
} }
} }
void engine_make_external_gravity_tasks(struct engine *e) {
struct space *s = e->s;
struct scheduler *sched = &e->sched;
const int nodeID = e->nodeID;
struct cell *cells = s->cells_top;
const int nr_cells = s->nr_cells;
for (int cid = 0; cid < nr_cells; ++cid) {
struct cell *ci = &cells[cid];
/* Skip cells without gravity particles */
if (ci->gcount == 0) continue;
/* Is that neighbour local ? */
if (ci->nodeID != nodeID) continue;
/* If the cells is local build a self-interaction */
scheduler_addtask(sched, task_type_self, task_subtype_external_grav, 0, 0,
ci, NULL, 0);
}
}
/** /**
* @brief Constructs the top-level pair tasks for the first hydro loop over * @brief Constructs the top-level pair tasks for the first hydro loop over
* neighbours * neighbours
...@@ -1435,6 +1401,22 @@ static inline void engine_make_gravity_dependencies(struct scheduler *sched, ...@@ -1435,6 +1401,22 @@ static inline void engine_make_gravity_dependencies(struct scheduler *sched,
scheduler_addunlock(sched, c->super->grav_up, gravity); scheduler_addunlock(sched, c->super->grav_up, gravity);
} }
/**
* @brief Creates the dependency network for the external gravity tasks of a
* given cell.
*
* @param sched The #scheduler.
* @param gravity The gravity task to link.
* @param c The cell.
*/
static inline void engine_make_external_gravity_dependencies(
struct scheduler *sched, struct task *gravity, struct cell *c) {
/* init --> external gravity --> kick */
scheduler_addunlock(sched, c->super->init, gravity);
scheduler_addunlock(sched, gravity, c->super->kick);
}
/** /**
* @brief Creates all the task dependencies for the gravity * @brief Creates all the task dependencies for the gravity
* *
...@@ -1480,13 +1462,21 @@ void engine_link_gravity_tasks(struct engine *e) { ...@@ -1480,13 +1462,21 @@ void engine_link_gravity_tasks(struct engine *e) {
scheduler_addunlock(sched, t->ci->super->init, t); scheduler_addunlock(sched, t->ci->super->init, t);
} }
/* Self-interaction? */ /* Self-interaction for self-gravity? */
if (t->type == task_type_self && t->subtype == task_subtype_grav) { if (t->type == task_type_self && t->subtype == task_subtype_grav) {
engine_make_gravity_dependencies(sched, t, t->ci); engine_make_gravity_dependencies(sched, t, t->ci);
} }
/* Self-interaction for external gravity ? */
else if (t->type == task_type_self &&
t->subtype == task_subtype_external_grav) {
engine_make_external_gravity_dependencies(sched, t, t->ci);
}
/* Otherwise, pair interaction? */ /* Otherwise, pair interaction? */
else if (t->type == task_type_pair && t->subtype == task_subtype_grav) { else if (t->type == task_type_pair && t->subtype == task_subtype_grav) {
...@@ -1510,6 +1500,15 @@ void engine_link_gravity_tasks(struct engine *e) { ...@@ -1510,6 +1500,15 @@ void engine_link_gravity_tasks(struct engine *e) {
} }
} }
/* Sub-self-interaction for external gravity ? */
else if (t->type == task_type_sub_self &&
t->subtype == task_subtype_external_grav) {
if (t->ci->nodeID == nodeID) {
engine_make_external_gravity_dependencies(sched, t, t->ci);
}
}
/* Otherwise, sub-pair interaction? */ /* Otherwise, sub-pair interaction? */
else if (t->type == task_type_sub_pair && t->subtype == task_subtype_grav) { else if (t->type == task_type_sub_pair && t->subtype == task_subtype_grav) {
...@@ -1785,12 +1784,6 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { ...@@ -1785,12 +1784,6 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) {
#endif #endif
} }
/* External gravity tasks should depend on init and unlock the kick */
else if (t->type == task_type_grav_external) {
scheduler_addunlock(sched, t->ci->init, t);
scheduler_addunlock(sched, t, t->ci->kick);
}
/* Cooling tasks should depend on kick and does not unlock anything since /* Cooling tasks should depend on kick and does not unlock anything since
it is the last task*/ it is the last task*/
else if (t->type == task_type_cooling) { else if (t->type == task_type_cooling) {
...@@ -1859,6 +1852,12 @@ void engine_maketasks(struct engine *e) { ...@@ -1859,6 +1852,12 @@ void engine_maketasks(struct engine *e) {
/* Add the gravity mm tasks. */ /* Add the gravity mm tasks. */
if (e->policy & engine_policy_self_gravity) engine_make_gravity_tasks(e); if (e->policy & engine_policy_self_gravity) engine_make_gravity_tasks(e);
/* Add the external gravity tasks. */
if (e->policy & engine_policy_external_gravity)
engine_make_external_gravity_tasks(e);
if (e->sched.nr_tasks == 0) error("No hydro or gravity tasks created.");
/* Split the tasks. */ /* Split the tasks. */
scheduler_splittasks(sched); scheduler_splittasks(sched);
...@@ -1882,13 +1881,14 @@ void engine_maketasks(struct engine *e) { ...@@ -1882,13 +1881,14 @@ void engine_maketasks(struct engine *e) {
/* Count the number of tasks associated with each cell and /* Count the number of tasks associated with each cell and
store the density tasks in each cell, and make each sort store the density tasks in each cell, and make each sort
depend on the sorts of its progeny. */ depend on the sorts of its progeny. */
if (e->policy & engine_policy_hydro) engine_count_and_link_tasks(e); engine_count_and_link_tasks(e);
/* Now that the pair tasks are at the right level, set the super pointers. */ /* Now that the pair tasks are at the right level, set the super pointers. */
for (int k = 0; k < nr_cells; k++) cell_set_super(&cells[k], NULL); for (int k = 0; k < nr_cells; k++) cell_set_super(&cells[k], NULL);
/* Append hierarchical tasks to each cells */ /* Append hierarchical tasks to each cells */
for (int k = 0; k < nr_cells; k++) engine_make_hierarchical_tasks(e, &cells[k]); for (int k = 0; k < nr_cells; k++)
engine_make_hierarchical_tasks(e, &cells[k]);
/* Run through the tasks and make force tasks for each density task. /* Run through the tasks and make force tasks for each density task.
Each force task depends on the cell ghosts and unlocks the kick task Each force task depends on the cell ghosts and unlocks the kick task
...@@ -1896,7 +1896,7 @@ void engine_maketasks(struct engine *e) { ...@@ -1896,7 +1896,7 @@ void engine_maketasks(struct engine *e) {
if (e->policy & engine_policy_hydro) engine_make_extra_hydroloop_tasks(e); if (e->policy & engine_policy_hydro) engine_make_extra_hydroloop_tasks(e);
/* Add the dependencies for the self-gravity stuff */ /* Add the dependencies for the self-gravity stuff */
if (e->policy & engine_policy_self_gravity) engine_link_gravity_tasks(e); engine_link_gravity_tasks(e);
#ifdef WITH_MPI #ifdef WITH_MPI
...@@ -2636,7 +2636,10 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs) { ...@@ -2636,7 +2636,10 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs) {
/* Add the tasks corresponding to external gravity to the masks */ /* Add the tasks corresponding to external gravity to the masks */
if (e->policy & engine_policy_external_gravity) { if (e->policy & engine_policy_external_gravity) {
mask |= 1 << task_type_grav_external; mask |= 1 << task_type_self;
mask |= 1 << task_type_sub_self;
submask |= 1 << task_subtype_external_grav;
} }
/* Add MPI tasks if need be */ /* Add MPI tasks if need be */
...@@ -2805,7 +2808,11 @@ void engine_step(struct engine *e) { ...@@ -2805,7 +2808,11 @@ void engine_step(struct engine *e) {
/* Add the tasks corresponding to external gravity to the masks */ /* Add the tasks corresponding to external gravity to the masks */
if (e->policy & engine_policy_external_gravity) { if (e->policy & engine_policy_external_gravity) {
mask |= 1 << task_type_grav_external;
mask |= 1 << task_type_self;
mask |= 1 << task_type_sub_self;
submask |= 1 << task_subtype_external_grav;
} }
/* Add the tasks corresponding to cooling to the masks */ /* Add the tasks corresponding to cooling to the masks */
......
...@@ -147,12 +147,12 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) { ...@@ -147,12 +147,12 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) {
for (int i = 0; i < gcount; i++) { for (int i = 0; i < gcount; i++) {
/* Get a direct pointer on the part. */ /* Get a direct pointer on the part. */
struct gpart *restrict g = &gparts[i]; struct gpart *restrict gp = &gparts[i];
/* Is this part within the time step? */ /* Is this part within the time step? */
if (g->ti_end <= ti_current) { if (gp->ti_end <= ti_current) {
external_gravity_acceleration(time, potential, constants, g); external_gravity_acceleration(time, potential, constants, gp);
} }
} }
...@@ -1243,9 +1243,12 @@ void *runner_main(void *data) { ...@@ -1243,9 +1243,12 @@ void *runner_main(void *data) {
runner_doself2_force(r, ci); runner_doself2_force(r, ci);
else if (t->subtype == task_subtype_grav) else if (t->subtype == task_subtype_grav)
runner_doself_grav(r, ci, 1); runner_doself_grav(r, ci, 1);
else if (t->subtype == task_subtype_external_grav)
runner_do_grav_external(r, ci, 1);
else else
error("Unknown task subtype."); error("Unknown task subtype.");
break; break;
case task_type_pair: case task_type_pair:
if (t->subtype == task_subtype_density) if (t->subtype == task_subtype_density)
runner_dopair1_density(r, ci, cj); runner_dopair1_density(r, ci, cj);
...@@ -1260,9 +1263,7 @@ void *runner_main(void *data) { ...@@ -1260,9 +1263,7 @@ void *runner_main(void *data) {
else else
error("Unknown task subtype."); error("Unknown task subtype.");
break; break;
case task_type_sort:
runner_do_sort(r, ci, t->flags, 1);
break;
case task_type_sub_self: case task_type_sub_self:
if (t->subtype == task_subtype_density) if (t->subtype == task_subtype_density)
runner_dosub_self1_density(r, ci, 1); runner_dosub_self1_density(r, ci, 1);
...@@ -1274,9 +1275,12 @@ void *runner_main(void *data) { ...@@ -1274,9 +1275,12 @@ void *runner_main(void *data) {
runner_dosub_self2_force(r, ci, 1); runner_dosub_self2_force(r, ci, 1);
else if (t->subtype == task_subtype_grav) else if (t->subtype == task_subtype_grav)
runner_dosub_grav(r, ci, cj, 1); runner_dosub_grav(r, ci, cj, 1);
else if (t->subtype == task_subtype_external_grav)
runner_do_grav_external(r, ci, 1);
else else
error("Unknown task subtype."); error("Unknown task subtype.");
break; break;
case task_type_sub_pair: case task_type_sub_pair:
if (t->subtype == task_subtype_density) if (t->subtype == task_subtype_density)
runner_dosub_pair1_density(r, ci, cj, t->flags, 1); runner_dosub_pair1_density(r, ci, cj, t->flags, 1);
...@@ -1291,6 +1295,10 @@ void *runner_main(void *data) { ...@@ -1291,6 +1295,10 @@ void *runner_main(void *data) {
else else
error("Unknown task subtype."); error("Unknown task subtype.");
break; break;
case task_type_sort:
runner_do_sort(r, ci, t->flags, 1);
break;
case task_type_init: case task_type_init:
runner_do_init(r, ci, 1); runner_do_init(r, ci, 1);
break; break;
...@@ -1334,9 +1342,6 @@ void *runner_main(void *data) { ...@@ -1334,9 +1342,6 @@ void *runner_main(void *data) {
case task_type_grav_fft: case task_type_grav_fft:
runner_do_grav_fft(r); runner_do_grav_fft(r);
break; break;
case task_type_grav_external:
runner_do_grav_external(r, t->ci, 1);
break;
case task_type_cooling: case task_type_cooling:
runner_do_cooling(r, t->ci, 1); runner_do_cooling(r, t->ci, 1);
break; break;
......
...@@ -48,13 +48,12 @@ ...@@ -48,13 +48,12 @@
/* Task type names. */ /* Task type names. */
const char *taskID_names[task_type_count] = { const char *taskID_names[task_type_count] = {
"none", "sort", "self", "pair", "sub_self", "none", "sort", "self", "pair", "sub_self", "sub_pair",
"sub_pair", "init", "ghost", "extra_ghost", "kick", "init", "ghost", "extra_ghost", "kick", "kick_fixdt", "send",
"kick_fixdt", "send", "recv", "grav_gather_m", "grav_fft", "recv", "grav_gather_m", "grav_fft", "grav_mm", "grav_up", "cooling"};
"grav_mm", "grav_up", "grav_external", "cooling"};
const char *subtaskID_names[task_subtype_count] = { const char *subtaskID_names[task_subtype_count] = {
"none", "density", "gradient", "force", "grav", "tend"}; "none", "density", "gradient", "force", "grav", "external_grav", "tend"};
/** /**
* @brief Computes the overlap between the parts array of two given cells. * @brief Computes the overlap between the parts array of two given cells.
...@@ -134,6 +133,7 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on( ...@@ -134,6 +133,7 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on(
break; break;
case task_subtype_grav: case task_subtype_grav:
case task_subtype_external_grav:
return task_action_gpart; return task_action_gpart;
break; break;
...@@ -149,7 +149,14 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on( ...@@ -149,7 +149,14 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on(
case task_type_kick_fixdt: case task_type_kick_fixdt:
case task_type_send: case task_type_send:
case task_type_recv: case task_type_recv:
return task_action_all; if (t->ci->count > 0 && t->ci->gcount > 0)
return task_action_all;
else if (t->ci->count > 0)
return task_action_part;
else if (t->ci->gcount > 0)
return task_action_gpart;
else
error("Task without particles");
break; break;
case task_type_grav_gather_m: case task_type_grav_gather_m:
...@@ -159,10 +166,6 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on( ...@@ -159,10 +166,6 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on(
return task_action_multipole; return task_action_multipole;
break; break;
case task_type_grav_external:
return task_action_gpart;
break;
default: default:
error("Unknown task_action for task"); error("Unknown task_action for task");
return task_action_none; return task_action_none;
...@@ -392,3 +395,15 @@ void task_print_submask(unsigned int submask) { ...@@ -392,3 +395,15 @@ void task_print_submask(unsigned int submask) {
printf(" %s=%s", subtaskID_names[k], (submask & (1 << k)) ? "yes" : "no"); printf(" %s=%s", subtaskID_names[k], (submask & (1 << k)) ? "yes" : "no");
printf(" ]\n"); printf(" ]\n");
} }
/**
* @brief Print basic information about a task.
*
* @param t The #task.
*/
void task_print(const struct task *t) {
message("Type:'%s' sub_type:'%s' wait=%d nr_unlocks=%d skip=%d",
taskID_names[t->type], subtaskID_names[t->subtype], t->wait,
t->nr_unlock_tasks, t->skip);
}
...@@ -53,7 +53,6 @@ enum task_types { ...@@ -53,7 +53,6 @@ enum task_types {
task_type_grav_fft, task_type_grav_fft,
task_type_grav_mm, task_type_grav_mm,
task_type_grav_up, task_type_grav_up,
task_type_grav_external,
task_type_cooling, task_type_cooling,
task_type_count task_type_count
} __attribute__((packed));