diff --git a/examples/analyse_tasks.py b/examples/analyse_tasks.py index 853013a61b1d1c4d5dcfe12756fa3ac0f3d39dd8..a72ee0ce637b6ac2da4b8b95dac5bacab3d40a99 100755 --- a/examples/analyse_tasks.py +++ b/examples/analyse_tasks.py @@ -52,10 +52,10 @@ infile = args.input # Tasks and subtypes. Indexed as in tasks.h. TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair", - "init_grav", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart", - "end_force", "kick1", "kick2", "timestep", "send", "recv", "grav_top_level", - "grav_long_range", "grav_ghost_in", "grav_ghost_out", "grav_mm", "grav_down", "cooling", - "sourceterms", "count"] + "init_grav", "init_grav_out", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart", + "end_force", "kick1", "kick2", "timestep", "send", "recv", "grav_long_range", "grav_mm", "grav_down_in", + "grav_down", "grav_mesh", "cooling", "sourceterms", "count"] + SUBTYPES = ["none", "density", "gradient", "force", "grav", "external_grav", "tend", "xv", "rho", "gpart", "multipole", "spart", "count"] diff --git a/examples/plot_tasks.py b/examples/plot_tasks.py index a123249dea8acf10e27a60a92065404f9cae77ea..9eecf6f4ca15148f544ea48cb65c97cd3802a48d 100755 --- a/examples/plot_tasks.py +++ b/examples/plot_tasks.py @@ -110,10 +110,9 @@ pl.rcParams.update(PLOT_PARAMS) # Tasks and subtypes. Indexed as in tasks.h. TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair", - "init_grav", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart", - "end_force", "kick1", "kick2", "timestep", "send", "recv", "grav_top_level", - "grav_long_range", "grav_ghost_in", "grav_ghost_out", "grav_mm", "grav_down", "cooling", - "sourceterms", "count"] + "init_grav", "init_grav_out", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart", + "end_force", "kick1", "kick2", "timestep", "send", "recv", "grav_long_range", "grav_mm", "grav_down_in", + "grav_down", "grav_mesh", "cooling", "sourceterms", "count"] SUBTYPES = ["none", "density", "gradient", "force", "grav", "external_grav", "tend", "xv", "rho", "gpart", "multipole", "spart", "count"] diff --git a/src/cell.c b/src/cell.c index 236114efe08b156fecd246f8117d0e76e0826cde..8c4dafd960b95e17f0d2bc773bafa412502d3faf 100644 --- a/src/cell.c +++ b/src/cell.c @@ -2303,11 +2303,13 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { if (c->nodeID == nodeID && cell_is_active_gravity(c, e)) { if (c->init_grav != NULL) scheduler_activate(s, c->init_grav); + if (c->init_grav_out != NULL) scheduler_activate(s, c->init_grav_out); if (c->kick1 != NULL) scheduler_activate(s, c->kick1); if (c->kick2 != NULL) scheduler_activate(s, c->kick2); if (c->timestep != NULL) scheduler_activate(s, c->timestep); if (c->end_force != NULL) scheduler_activate(s, c->end_force); if (c->grav_down != NULL) scheduler_activate(s, c->grav_down); + if (c->grav_down_in != NULL) scheduler_activate(s, c->grav_down_in); if (c->grav_mesh != NULL) scheduler_activate(s, c->grav_mesh); if (c->grav_long_range != NULL) scheduler_activate(s, c->grav_long_range); } diff --git a/src/cell.h b/src/cell.h index 62ac0d0535b49d3e0b3a3affdc645522c0b53659..05cc8d0eef7839526866411b0adf5a16c3113854 100644 --- a/src/cell.h +++ b/src/cell.h @@ -225,6 +225,9 @@ struct cell { /*! The multipole initialistation task */ struct task *init_grav; + /*! Implicit task for the gravity initialisation */ + struct task *init_grav_out; + /*! Dependency implicit task for the ghost (in->ghost->out)*/ struct task *ghost_in; @@ -258,6 +261,9 @@ struct cell { /*! Task computing long range non-periodic gravity interactions */ struct task *grav_long_range; + /*! Implicit task for the down propagation */ + struct task *grav_down_in; + /*! Task propagating the mesh forces to the particles */ struct task *grav_mesh; diff --git a/src/engine.c b/src/engine.c index 66de36764ac59b1f4a2c91d5dc3eb731bd101904..e90b662caeaea439890e40356c2e991f495b9e43 100644 --- a/src/engine.c +++ b/src/engine.c @@ -334,6 +334,12 @@ void engine_make_hierarchical_tasks_gravity(struct engine *e, struct cell *c) { c->grav_down = scheduler_addtask(s, task_type_grav_down, task_subtype_none, 0, 0, c, NULL); + /* Implicit tasks for the up and down passes */ + c->init_grav_out = scheduler_addtask(s, task_type_init_grav_out, + task_subtype_none, 0, 1, c, NULL); + c->grav_down_in = scheduler_addtask(s, task_type_grav_down_in, + task_subtype_none, 0, 1, c, NULL); + /* Gravity mesh force propagation */ if (periodic) c->grav_mesh = scheduler_addtask(s, task_type_grav_mesh, @@ -344,17 +350,41 @@ void engine_make_hierarchical_tasks_gravity(struct engine *e, struct cell *c) { scheduler_addunlock(s, c->init_grav, c->grav_long_range); scheduler_addunlock(s, c->grav_long_range, c->grav_down); scheduler_addunlock(s, c->grav_down, c->super->end_force); + + scheduler_addunlock(s, c->init_grav, c->init_grav_out); + scheduler_addunlock(s, c->grav_down_in, c->grav_down); } } - } else { /* We are above the super-cell so need to go deeper */ + } - /* Recurse. */ - if (c->split) - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) - engine_make_hierarchical_tasks_gravity(e, c->progeny[k]); + /* We are below the super-cell */ + else if (c->super_gravity != NULL) { + + // MATTHIEU stop the recursion below the level where there are tasks + + /* Local tasks only... */ + if (c->nodeID == e->nodeID) { + + if (is_self_gravity) { + + c->init_grav_out = scheduler_addtask(s, task_type_init_grav_out, + task_subtype_none, 0, 1, c, NULL); + + c->grav_down_in = scheduler_addtask(s, task_type_grav_down_in, + task_subtype_none, 0, 1, c, NULL); + + scheduler_addunlock(s, c->parent->init_grav_out, c->init_grav_out); + scheduler_addunlock(s, c->grav_down_in, c->parent->grav_down_in); + } + } } + + /* Recurse. */ + if (c->split) + for (int k = 0; k < 8; k++) + if (c->progeny[k] != NULL) + engine_make_hierarchical_tasks_gravity(e, c->progeny[k]); } void engine_make_hierarchical_tasks_mapper(void *map_data, int num_elements, @@ -2648,38 +2678,6 @@ void engine_count_and_link_tasks_mapper(void *map_data, int num_elements, } } -/** - * @brief Creates the dependency network for the 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_self_gravity_dependencies( - struct scheduler *sched, struct task *gravity, struct cell *c) { - - /* init --> gravity --> grav_down --> kick */ - scheduler_addunlock(sched, c->super_gravity->drift_gpart, gravity); - scheduler_addunlock(sched, c->super_gravity->init_grav, gravity); - scheduler_addunlock(sched, gravity, c->super_gravity->grav_down); -} - -/** - * @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_gravity->drift_gpart, gravity); - scheduler_addunlock(sched, gravity, c->super->end_force); -} - /** * @brief Creates all the task dependencies for the gravity * @@ -2699,77 +2697,119 @@ void engine_link_gravity_tasks(struct engine *e) { /* Get the cells we act on */ struct cell *ci = t->ci; struct cell *cj = t->cj; + const enum task_types t_type = t->type; + const enum task_subtypes t_subtype = t->subtype; /* 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) { + +#ifdef SWIFT_DEBUG_CHECKS + if (ci->nodeID != nodeID) error("Non-local self task"); +#endif - engine_make_self_gravity_dependencies(sched, t, ci); + /* drift ---+-> gravity --> grav_down */ + /* init --/ */ + scheduler_addunlock(sched, ci->super_gravity->drift_gpart, t); + scheduler_addunlock(sched, ci->init_grav_out, t); + scheduler_addunlock(sched, t, ci->grav_down_in); } /* Self-interaction for external gravity ? */ - if (t->type == task_type_self && t->subtype == task_subtype_external_grav) { + if (t_type == task_type_self && t_subtype == task_subtype_external_grav) { - engine_make_external_gravity_dependencies(sched, t, ci); +#ifdef SWIFT_DEBUG_CHECKS + if (ci->nodeID != nodeID) error("Non-local self task"); +#endif + /* drift -----> gravity --> end_force */ + scheduler_addunlock(sched, ci->super_gravity->drift_gpart, t); + scheduler_addunlock(sched, t, ci->end_force); } /* 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) { if (ci->nodeID == nodeID) { - engine_make_self_gravity_dependencies(sched, t, ci); + /* drift ---+-> gravity --> grav_down */ + /* init --/ */ + scheduler_addunlock(sched, ci->super_gravity->drift_gpart, t); + scheduler_addunlock(sched, ci->init_grav_out, t); + scheduler_addunlock(sched, t, ci->grav_down_in); } - - if (cj->nodeID == nodeID && ci->super_gravity != cj->super_gravity) { - - engine_make_self_gravity_dependencies(sched, t, cj); + if (cj->nodeID == nodeID) { + + /* drift ---+-> gravity --> grav_down */ + /* init --/ */ + if (ci->super_gravity != cj->super_gravity) /* Avoid double unlock */ + scheduler_addunlock(sched, cj->super_gravity->drift_gpart, t); + scheduler_addunlock(sched, cj->init_grav_out, t); + scheduler_addunlock(sched, t, cj->grav_down_in); } - } /* Otherwise, sub-self interaction? */ - else if (t->type == task_type_sub_self && t->subtype == task_subtype_grav) { + else if (t_type == task_type_sub_self && t_subtype == task_subtype_grav) { - if (ci->nodeID == nodeID) { - engine_make_self_gravity_dependencies(sched, t, ci); - } +#ifdef SWIFT_DEBUG_CHECKS + if (ci->nodeID != nodeID) error("Non-local sub-self task"); +#endif + /* drift ---+-> gravity --> grav_down */ + /* init --/ */ + scheduler_addunlock(sched, ci->super_gravity->drift_gpart, t); + scheduler_addunlock(sched, ci->init_grav_out, t); + scheduler_addunlock(sched, t, ci->grav_down_in); } /* Sub-self-interaction for external gravity ? */ - else if (t->type == task_type_sub_self && - t->subtype == task_subtype_external_grav) { + else if (t_type == task_type_sub_self && + t_subtype == task_subtype_external_grav) { - if (ci->nodeID == nodeID) { - engine_make_external_gravity_dependencies(sched, t, ci); - } +#ifdef SWIFT_DEBUG_CHECKS + if (ci->nodeID != nodeID) error("Non-local sub-self task"); +#endif + + /* drift -----> gravity --> end_force */ + scheduler_addunlock(sched, ci->super_gravity->drift_gpart, t); + scheduler_addunlock(sched, t, ci->end_force); } /* 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) { if (ci->nodeID == nodeID) { - engine_make_self_gravity_dependencies(sched, t, ci); + /* drift ---+-> gravity --> grav_down */ + /* init --/ */ + scheduler_addunlock(sched, ci->super_gravity->drift_gpart, t); + scheduler_addunlock(sched, ci->init_grav_out, t); + scheduler_addunlock(sched, t, ci->grav_down_in); } - if (cj->nodeID == nodeID && ci->super_gravity != cj->super_gravity) { - - engine_make_self_gravity_dependencies(sched, t, cj); + if (cj->nodeID == nodeID) { + + /* drift ---+-> gravity --> grav_down */ + /* init --/ */ + if (ci->super_gravity != cj->super_gravity) /* Avoid double unlock */ + scheduler_addunlock(sched, cj->super_gravity->drift_gpart, t); + scheduler_addunlock(sched, cj->init_grav_out, t); + scheduler_addunlock(sched, t, cj->grav_down_in); } } /* Otherwise M-M interaction? */ - else if (t->type == task_type_grav_mm) { + else if (t_type == task_type_grav_mm) { if (ci->nodeID == nodeID) { - scheduler_addunlock(sched, ci->super_gravity->init_grav, t); - scheduler_addunlock(sched, t, ci->super_gravity->grav_down); + /* init -----> gravity --> grav_down */ + scheduler_addunlock(sched, ci->init_grav_out, t); + scheduler_addunlock(sched, t, ci->grav_down_in); } - if (cj->nodeID == nodeID && ci->super_gravity != cj->super_gravity) { + if (cj->nodeID == nodeID) { - scheduler_addunlock(sched, cj->super_gravity->init_grav, t); - scheduler_addunlock(sched, t, cj->super_gravity->grav_down); + /* init -----> gravity --> grav_down */ + scheduler_addunlock(sched, cj->init_grav_out, t); + scheduler_addunlock(sched, t, cj->grav_down_in); } } } @@ -3571,7 +3611,9 @@ void engine_marktasks_mapper(void *map_data, int num_elements, /* Gravity stuff ? */ else if (t->type == task_type_grav_down || t->type == task_type_grav_mesh || t->type == task_type_grav_long_range || - t->type == task_type_init_grav) { + t->type == task_type_init_grav || + t->type == task_type_init_grav_out || + t->type == task_type_grav_down_in) { if (cell_is_active_gravity(t->ci, e)) scheduler_activate(s, t); } diff --git a/src/space.c b/src/space.c index 3d15973d0ea4c04b09a928c05f07cba7a6529141..b4001919a6bd13d41877eec5600fb53b91ff6d12 100644 --- a/src/space.c +++ b/src/space.c @@ -175,6 +175,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->gcount = 0; c->scount = 0; c->init_grav = NULL; + c->init_grav_out = NULL; c->extra_ghost = NULL; c->ghost_in = NULL; c->ghost_out = NULL; @@ -188,6 +189,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->cooling = NULL; c->sourceterms = NULL; c->grav_long_range = NULL; + c->grav_down_in = NULL; c->grav_down = NULL; c->super = c; c->super_hydro = c; diff --git a/src/task.c b/src/task.c index 03566868a5400582a01e9d3d88520009b7e77cdc..2782dabfc1369dedd43e9b42855a8b43acf2f1b7 100644 --- a/src/task.c +++ b/src/task.c @@ -48,11 +48,15 @@ /* Task type names. */ const char *taskID_names[task_type_count] = { - "none", "sort", "self", "pair", "sub_self", - "sub_pair", "init_grav", "ghost_in", "ghost", "ghost_out", - "extra_ghost", "drift_part", "drift_gpart", "end_force", "kick1", - "kick2", "timestep", "send", "recv", "grav_long_range", - "grav_mm", "grav_down", "grav_mesh", "cooling", "sourceterms"}; + "none", "sort", "self", + "pair", "sub_self", "sub_pair", + "init_grav", "init_grav_out", "ghost_in", + "ghost", "ghost_out", "extra_ghost", + "drift_part", "drift_gpart", "end_force", + "kick1", "kick2", "timestep", + "send", "recv", "grav_long_range", + "grav_mm", "grav_down_in", "grav_down", + "grav_mesh", "cooling", "sourceterms"}; /* Sub-task type names. */ const char *subtaskID_names[task_subtype_count] = { diff --git a/src/task.h b/src/task.h index a353ff76a8419cf728b50999aa86e6deb9660ef3..072d3979ce04990aaef46c5cc5eb0b8c62fdc860 100644 --- a/src/task.h +++ b/src/task.h @@ -46,9 +46,10 @@ enum task_types { task_type_sub_self, task_type_sub_pair, task_type_init_grav, - task_type_ghost_in, + task_type_init_grav_out, /* Implicit */ + task_type_ghost_in, /* Implicit */ task_type_ghost, - task_type_ghost_out, + task_type_ghost_out, /* Implicit */ task_type_extra_ghost, task_type_drift_part, task_type_drift_gpart, @@ -60,6 +61,7 @@ enum task_types { task_type_recv, task_type_grav_long_range, task_type_grav_mm, + task_type_grav_down_in, /* Implicit */ task_type_grav_down, task_type_grav_mesh, task_type_cooling,