diff --git a/src/cell.c b/src/cell.c index 5d6a1b10a36a912eed8c71a09760b437c904947e..ccc101243ccdffbb25d8a71353e65c9d393b7148 100644 --- a/src/cell.c +++ b/src/cell.c @@ -1754,6 +1754,7 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) { if (c->extra_ghost != NULL) scheduler_activate(s, c->extra_ghost); if (c->ghost_in != NULL) scheduler_activate(s, c->ghost_in); if (c->ghost_out != NULL) scheduler_activate(s, c->ghost_out); + if (c->ghost != NULL) scheduler_activate(s, c->ghost); if (c->init_grav != NULL) scheduler_activate(s, c->init_grav); if (c->drift != NULL) scheduler_activate(s, c->drift); if (c->kick1 != NULL) scheduler_activate(s, c->kick1); diff --git a/src/cell.h b/src/cell.h index e72cba2032a9fcaae223a62dc69d07f5c3f78305..05fed82d79b0c3c4f8e4343813a4d6938d402bf8 100644 --- a/src/cell.h +++ b/src/cell.h @@ -154,6 +154,7 @@ struct cell { /*! The ghost tasks */ struct task *ghost_in; struct task *ghost_out; + struct task *ghost; /*! The extra ghost task for complex hydro schemes */ struct task *extra_ghost; diff --git a/src/engine.c b/src/engine.c index f04bc6cb984b1fe8690a18fd0ca74cc3ed98fa25..414b40f959ac4d3ecb449759823a3631b9a657a3 100644 --- a/src/engine.c +++ b/src/engine.c @@ -119,6 +119,24 @@ void engine_addlink(struct engine *e, struct link **l, struct task *t) { res->next = atomic_swap(l, res); } +/** + * @brief Recursively add non-implicit ghost tasks to a cell hierarchy. + */ +void engine_add_ghosts(struct engine *e, struct cell *c, struct task *ghost_in, + struct task *ghost_out) { + if (!c->split || c->count < engine_max_parts_per_ghost) { + struct scheduler *s = &e->sched; + c->ghost = + scheduler_addtask(s, task_type_ghost, task_subtype_none, 0, 0, c, NULL); + scheduler_addunlock(s, ghost_in, c->ghost); + scheduler_addunlock(s, c->ghost, ghost_out); + } else { + for (int k = 0; k < 8; k++) + if (c->progeny[k] != NULL) + engine_add_ghosts(e, c->progeny[k], ghost_in, ghost_out); + } +} + /** * @brief Generate the hydro hierarchical tasks for a hierarchy of cells - * i.e. all the O(Npart) tasks. @@ -185,10 +203,13 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { /* Generate the ghost tasks. */ if (is_hydro) { - c->ghost_in = scheduler_addtask(s, task_type_ghost, task_subtype_none, 0, - /* implicit = */ 1, c, NULL); - c->ghost_out = scheduler_addtask(s, task_type_ghost, task_subtype_none, 0, - /* implicit = */ 1, c, NULL); + c->ghost_in = + scheduler_addtask(s, task_type_ghost, task_subtype_none, 0, + /* implicit = */ 1, c, NULL); + c->ghost_out = + scheduler_addtask(s, task_type_ghost, task_subtype_none, 0, + /* implicit = */ 1, c, NULL); + engine_add_ghosts(e, c, c->ghost_in, c->ghost_out); } #ifdef EXTRA_HYDRO_LOOP diff --git a/src/engine.h b/src/engine.h index e62b12332d3ac1b985b8f6d7181ea66824ec4f13..67fd66ae76089d73a95c8924a558158a629f309b 100644 --- a/src/engine.h +++ b/src/engine.h @@ -82,6 +82,7 @@ extern const char *engine_policy_names[]; #define engine_redistribute_alloc_margin 1.2 #define engine_default_energy_file_name "energy" #define engine_default_timesteps_file_name "timesteps" +#define engine_max_parts_per_ghost 1000 /* The rank of the engine as a global variable (for messages). */ extern int engine_rank; diff --git a/src/scheduler.c b/src/scheduler.c index 8c273372b435edd17d2ec850e9b52cc7c49684ac..62395a1b87756c89ba744b318cdfa0c44f13038d 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -757,8 +757,8 @@ void scheduler_splittasks(struct scheduler *s) { * @param cj The second cell to interact. */ struct task *scheduler_addtask(struct scheduler *s, enum task_types type, - enum task_subtypes subtype, int flags, int implicit, - struct cell *ci, struct cell *cj) { + enum task_subtypes subtype, int flags, + int implicit, struct cell *ci, struct cell *cj) { #ifdef SWIFT_DEBUG_CHECKS if (ci == NULL && cj != NULL) diff --git a/src/scheduler.h b/src/scheduler.h index b5d2346ebfe203b73639ea8eaf06f279ec0b7eb6..f38e5fb4d849842217756b7b93713a5e1375c9c5 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -133,8 +133,8 @@ void scheduler_reset(struct scheduler *s, int nr_tasks); void scheduler_ranktasks(struct scheduler *s); void scheduler_reweight(struct scheduler *s, int verbose); struct task *scheduler_addtask(struct scheduler *s, enum task_types type, - enum task_subtypes subtype, int flags, int implicit, - struct cell *ci, struct cell *cj); + enum task_subtypes subtype, int flags, + int implicit, struct cell *ci, struct cell *cj); void scheduler_splittasks(struct scheduler *s); struct task *scheduler_done(struct scheduler *s, struct task *t); struct task *scheduler_unlock(struct scheduler *s, struct task *t); diff --git a/src/space.c b/src/space.c index cb200d399f07ab275e5d73aa76bce92527042934..d0f629d90dd56ffb621705c9b9718331cf5eff4b 100644 --- a/src/space.c +++ b/src/space.c @@ -215,6 +215,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->extra_ghost = NULL; c->ghost_in = NULL; c->ghost_out = NULL; + c->ghost = NULL; c->kick1 = NULL; c->kick2 = NULL; c->timestep = NULL;