From e91c62df2e596dbd200577896955a8d0a7ee174c Mon Sep 17 00:00:00 2001 From: Alexei Borissov <ab325@st-andrews.ac.uk> Date: Fri, 14 Dec 2018 23:09:44 +0000 Subject: [PATCH] Feedback task --- src/cell.c | 8 +- src/cell.h | 29 +++++- src/engine_maketasks.c | 155 ++++++++++++++++++++---------- src/engine_marktasks.c | 31 +++++- src/runner.c | 8 ++ src/space.c | 3 +- src/task.c | 48 ++++++++- src/task.h | 1 + tools/analyse_runtime.py | 1 + tools/task_plots/analyse_tasks.py | 1 + tools/task_plots/plot_tasks.py | 5 + 11 files changed, 227 insertions(+), 63 deletions(-) diff --git a/src/cell.c b/src/cell.c index ed54163a00..a5b371f5ed 100644 --- a/src/cell.c +++ b/src/cell.c @@ -2771,7 +2771,7 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) { /* Check whether there was too much particle motion, i.e. the cell neighbour conditions were violated. */ - if (cell_need_rebuild_for_pair(ci, cj)) rebuild = 1; + if (cell_need_rebuild_for_hydro_pair(ci, cj)) rebuild = 1; #ifdef WITH_MPI /* Activate the send/recv tasks. */ @@ -3125,7 +3125,7 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) { /* Check whether there was too much particle motion, i.e. the cell neighbour conditions were violated. */ - if (cell_need_rebuild_for_pair(ci, cj)) rebuild = 1; + if (cell_need_rebuild_for_stars_pair(ci, cj)) rebuild = 1; #ifdef WITH_MPI error("MPI with stars not implemented"); @@ -3212,6 +3212,10 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) { /* Unskip all the other task types. */ if (c->nodeID == nodeID && cell_is_active_stars(c, e)) { + /* Un-skip the feedback tasks involved with this cell. */ + for (struct link *l = c->stars.feedback; l != NULL; l = l->next) + scheduler_activate(s, l->t); + if (c->stars.ghost_in != NULL) scheduler_activate(s, c->stars.ghost_in); if (c->stars.ghost_out != NULL) scheduler_activate(s, c->stars.ghost_out); if (c->stars.ghost != NULL) scheduler_activate(s, c->stars.ghost); diff --git a/src/cell.h b/src/cell.h index 7178698c42..9452accbab 100644 --- a/src/cell.h +++ b/src/cell.h @@ -469,6 +469,9 @@ struct cell { /*! Linked list of the tasks computing this cell's star density. */ struct link *density; + /*! Linked list of the tasks computing this cell's star feedback. */ + struct link *feedback; + /*! The task computing this cell's sorts. */ struct task *sorts; @@ -952,14 +955,15 @@ cell_can_split_self_gravity_task(const struct cell *c) { } /** - * @brief Have particles in a pair of cells moved too much and require a rebuild + * @brief Have gas particles in a pair of cells moved too much and require a + * rebuild * ? * * @param ci The first #cell. * @param cj The second #cell. */ -__attribute__((always_inline)) INLINE static int cell_need_rebuild_for_pair( - const struct cell *ci, const struct cell *cj) { +__attribute__((always_inline)) INLINE static int +cell_need_rebuild_for_hydro_pair(const struct cell *ci, const struct cell *cj) { /* Is the cut-off radius plus the max distance the parts in both cells have */ /* moved larger than the cell size ? */ @@ -969,6 +973,25 @@ __attribute__((always_inline)) INLINE static int cell_need_rebuild_for_pair( cj->dmin); } +/** + * @brief Have star particles in a pair of cells moved too much and require a + * rebuild + * ? + * + * @param ci The first #cell. + * @param cj The second #cell. + */ +__attribute__((always_inline)) INLINE static int +cell_need_rebuild_for_stars_pair(const struct cell *ci, const struct cell *cj) { + + /* Is the cut-off radius plus the max distance the parts in both cells have */ + /* moved larger than the cell size ? */ + /* Note ci->dmin == cj->dmin */ + return (kernel_gamma * max(ci->stars.h_max, cj->stars.h_max) + + ci->stars.dx_max_part + cj->stars.dx_max_part > + cj->dmin); +} + /** * @brief Add a unique tag to a cell, mostly for MPI communications. * diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c index 2c9fe3cb70..7d77e8c6c7 100644 --- a/src/engine_maketasks.c +++ b/src/engine_maketasks.c @@ -1015,6 +1015,8 @@ void engine_count_and_link_tasks_mapper(void *map_data, int num_elements, engine_addlink(e, &ci->grav.grav, t); } else if (t->subtype == task_subtype_stars_density) { engine_addlink(e, &ci->stars.density, t); + } else if (t->subtype == task_subtype_stars_feedback) { + engine_addlink(e, &ci->stars.feedback, t); } /* Link pair tasks to cells. */ @@ -1031,6 +1033,9 @@ void engine_count_and_link_tasks_mapper(void *map_data, int num_elements, } else if (t->subtype == task_subtype_stars_density) { engine_addlink(e, &ci->stars.density, t); engine_addlink(e, &cj->stars.density, t); + } else if (t->subtype == task_subtype_stars_feedback) { + engine_addlink(e, &ci->stars.feedback, t); + engine_addlink(e, &cj->stars.feedback, t); } #ifdef SWIFT_DEBUG_CHECKS else if (t_subtype == task_subtype_external_grav) { @@ -1050,6 +1055,8 @@ void engine_count_and_link_tasks_mapper(void *map_data, int num_elements, engine_addlink(e, &ci->grav.grav, t); } else if (t->subtype == task_subtype_stars_density) { engine_addlink(e, &ci->stars.density, t); + } else if (t->subtype == task_subtype_stars_feedback) { + engine_addlink(e, &ci->stars.feedback, t); } /* Link sub-pair tasks to cells. */ @@ -1066,6 +1073,9 @@ void engine_count_and_link_tasks_mapper(void *map_data, int num_elements, } else if (t->subtype == task_subtype_stars_density) { engine_addlink(e, &ci->stars.density, t); engine_addlink(e, &cj->stars.density, t); + } else if (t->subtype == task_subtype_stars_feedback) { + engine_addlink(e, &ci->stars.feedback, t); + engine_addlink(e, &cj->stars.feedback, t); } #ifdef SWIFT_DEBUG_CHECKS else if (t_subtype == task_subtype_external_grav) { @@ -1305,9 +1315,11 @@ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched, */ static inline void engine_make_stars_loops_dependencies(struct scheduler *sched, struct task *density, + struct task *feedback, struct cell *c) { - /* density loop --> ghost */ + /* density loop --> ghost --> feedback loop*/ scheduler_addunlock(sched, density, c->super->stars.ghost_in); + scheduler_addunlock(sched, c->super->stars.ghost_out, feedback); } /** @@ -1563,14 +1575,17 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, } /** - * @brief Creates all the task dependencies for the stars + * @brief Duplicates the first stars loop and construct all the + * dependencies for the stars part * - * @param map_data The tasks - * @param num_elements number of tasks - * @param extra_data The #engine + * This is done by looping over all the previously constructed tasks + * and adding another task involving the same cells but this time + * corresponding to the second stars loop over neighbours. + * With all the relevant tasks for a given cell available, we construct + * all the dependencies for that cell. */ -void engine_link_stars_tasks_mapper(void *map_data, int num_elements, - void *extra_data) { +void engine_make_extra_starsloop_tasks_mapper(void *map_data, int num_elements, + void *extra_data) { struct engine *e = (struct engine *)extra_data; struct scheduler *sched = &e->sched; @@ -1579,88 +1594,114 @@ void engine_link_stars_tasks_mapper(void *map_data, int num_elements, for (int ind = 0; ind < num_elements; ind++) { struct task *t = &((struct task *)map_data)[ind]; - /* Sort tasks depend on the drift of the cell. */ + /* Sort tasks depend on the drift and gravity drift of the cell. */ if (t->type == task_type_stars_sort && t->ci->nodeID == engine_rank) { + scheduler_addunlock(sched, t->ci->hydro.super->hydro.drift, t); scheduler_addunlock(sched, t->ci->super->grav.drift, t); } /* Self-interaction? */ - if (t->type == task_type_self && t->subtype == task_subtype_stars_density) { - - /* Make the self-density tasks depend on the drifts. */ - scheduler_addunlock(sched, t->ci->super->hydro.drift, t); + else if (t->type == task_type_self && + t->subtype == task_subtype_stars_density) { + /* Make the self-density tasks depend on the drift and gravity drift. */ + scheduler_addunlock(sched, t->ci->hydro.super->hydro.drift, t); scheduler_addunlock(sched, t->ci->super->grav.drift, t); + /* Start by constructing the task for the second stars loop */ + struct task *t2 = + scheduler_addtask(sched, task_type_self, task_subtype_stars_feedback, + 0, 0, t->ci, NULL); + + /* Add the link between the new loop and the cell */ + engine_addlink(e, &t->ci->stars.feedback, t2); + /* Now, build all the dependencies for the stars */ - engine_make_stars_loops_dependencies(sched, t, t->ci); - if (t->ci == t->ci->super) - scheduler_addunlock(sched, t->ci->super->stars.ghost_out, - t->ci->super->end_force); + engine_make_stars_loops_dependencies(sched, t, t2, t->ci); + + /* end_force depends on feedback tasks */ + scheduler_addunlock(sched, t2, t->ci->super->end_force); } /* Otherwise, pair interaction? */ else if (t->type == task_type_pair && t->subtype == task_subtype_stars_density) { - /* Make all density tasks depend on the drift and the sorts. */ - if (t->cj->nodeID == engine_rank) - scheduler_addunlock(sched, t->cj->super->hydro.drift, t); - scheduler_addunlock(sched, t->cj->super->hydro.sorts, t); - + /* Make all stars density tasks depend on the hydro drift and sorts, + * gravity drift and star sorts. */ + if (t->ci->nodeID == engine_rank) + scheduler_addunlock(sched, t->ci->super->hydro.drift, t); + scheduler_addunlock(sched, t->ci->super->hydro.sorts, t); if (t->cj->nodeID == engine_rank) scheduler_addunlock(sched, t->cj->super->grav.drift, t); scheduler_addunlock(sched, t->ci->super->stars.sorts, t); if (t->ci->super != t->cj->super) { - if (t->ci->nodeID == engine_rank) - scheduler_addunlock(sched, t->ci->super->hydro.drift, t); - scheduler_addunlock(sched, t->ci->super->hydro.sorts, t); - + if (t->cj->nodeID == engine_rank) + scheduler_addunlock(sched, t->cj->super->hydro.drift, t); + scheduler_addunlock(sched, t->cj->super->hydro.sorts, t); if (t->ci->nodeID == engine_rank) scheduler_addunlock(sched, t->ci->super->grav.drift, t); scheduler_addunlock(sched, t->cj->super->stars.sorts, t); } + /* Start by constructing the task for the second stars loop */ + struct task *t2 = + scheduler_addtask(sched, task_type_pair, task_subtype_stars_feedback, + 0, 0, t->ci, t->cj); + + /* Add the link between the new loop and both cells */ + engine_addlink(e, &t->ci->stars.feedback, t2); + engine_addlink(e, &t->cj->stars.feedback, t2); + /* Now, build all the dependencies for the stars for the cells */ - /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_stars_loops_dependencies(sched, t, t->ci); + engine_make_stars_loops_dependencies(sched, t, t2, t->ci); + scheduler_addunlock(sched, t2, t->ci->super->end_force); } if (t->cj->nodeID == nodeID) { if (t->ci->super != t->cj->super) - engine_make_stars_loops_dependencies(sched, t, t->cj); + engine_make_stars_loops_dependencies(sched, t, t2, t->cj); + if (t->ci->super != t->cj->super) + scheduler_addunlock(sched, t2, t->cj->super->end_force); } - } /* Otherwise, sub-self interaction? */ else if (t->type == task_type_sub_self && t->subtype == task_subtype_stars_density) { - /* Make all density tasks depend on the drift and sorts. */ + /* Make all stars density tasks depend on the hydro drift and sorts, + * gravity drift and star sorts. */ scheduler_addunlock(sched, t->ci->super->hydro.drift, t); scheduler_addunlock(sched, t->ci->super->hydro.sorts, t); scheduler_addunlock(sched, t->ci->super->grav.drift, t); scheduler_addunlock(sched, t->ci->super->stars.sorts, t); + /* Start by constructing the task for the second stars loop */ + struct task *t2 = scheduler_addtask(sched, task_type_sub_self, + task_subtype_stars_feedback, t->flags, + 0, t->ci, t->cj); + + /* Add the link between the new loop and the cell */ + engine_addlink(e, &t->ci->stars.feedback, t2); + /* Now, build all the dependencies for the stars for the cells */ - /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_stars_loops_dependencies(sched, t, t->ci); - } else - error("oo"); + engine_make_stars_loops_dependencies(sched, t, t2, t->ci); + scheduler_addunlock(sched, t2, t->ci->super->end_force); + } } /* Otherwise, sub-pair interaction? */ else if (t->type == task_type_sub_pair && t->subtype == task_subtype_stars_density) { - /* Make all density tasks depend on the drift. */ + /* Make all stars density tasks depend on the hydro drift and sorts, + * gravity drift and star sorts. */ if (t->cj->nodeID == engine_rank) scheduler_addunlock(sched, t->cj->super->hydro.drift, t); scheduler_addunlock(sched, t->cj->super->hydro.sorts, t); - if (t->cj->nodeID == engine_rank) scheduler_addunlock(sched, t->cj->super->grav.drift, t); scheduler_addunlock(sched, t->ci->super->stars.sorts, t); @@ -1669,20 +1710,30 @@ void engine_link_stars_tasks_mapper(void *map_data, int num_elements, if (t->ci->nodeID == engine_rank) scheduler_addunlock(sched, t->ci->super->hydro.drift, t); scheduler_addunlock(sched, t->ci->super->hydro.sorts, t); - if (t->ci->nodeID == engine_rank) scheduler_addunlock(sched, t->ci->super->grav.drift, t); scheduler_addunlock(sched, t->cj->super->stars.sorts, t); } + /* Start by constructing the task for the second stars loop */ + struct task *t2 = scheduler_addtask(sched, task_type_sub_pair, + task_subtype_stars_feedback, t->flags, + 0, t->ci, t->cj); + + /* Add the link between the new loop and both cells */ + engine_addlink(e, &t->ci->stars.feedback, t2); + engine_addlink(e, &t->cj->stars.feedback, t2); + /* Now, build all the dependencies for the stars for the cells */ - /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_stars_loops_dependencies(sched, t, t->ci); + engine_make_stars_loops_dependencies(sched, t, t2, t->ci); + scheduler_addunlock(sched, t2, t->ci->super->end_force); } if (t->cj->nodeID == nodeID) { if (t->ci->super != t->cj->super) - engine_make_stars_loops_dependencies(sched, t, t->cj); + engine_make_stars_loops_dependencies(sched, t, t2, t->cj); + if (t->ci->super != t->cj->super) + scheduler_addunlock(sched, t2, t->cj->super->end_force); } } } @@ -1729,9 +1780,10 @@ void engine_make_starsloop_tasks_mapper(void *map_data, int num_elements, if (ci->stars.count == 0 && ci->hydro.count == 0) continue; /* If the cells is local build a self-interaction */ - if (ci->nodeID == nodeID) + if (ci->nodeID == nodeID) { scheduler_addtask(sched, task_type_self, task_subtype_stars_density, 0, 0, ci, NULL); + } /* Now loop over all the neighbours of this cell */ for (int ii = -1; ii < 2; ii++) { @@ -2104,24 +2156,29 @@ void engine_maketasks(struct engine *e) { tic2 = getticks(); - /* Add the dependencies for the gravity stuff */ - if (e->policy & (engine_policy_self_gravity | engine_policy_external_gravity)) - engine_link_gravity_tasks(e); + /* Run through the tasks and make stars feedback tasks for each stars density + task. Each stars feedback task depends on the stars ghosts and unlocks the + kick task of its super-cell. */ + if (e->policy & engine_policy_stars) + threadpool_map(&e->threadpool, engine_make_extra_starsloop_tasks_mapper, + sched->tasks, sched->nr_tasks, sizeof(struct task), 0, e); if (e->verbose) - message("Linking gravity tasks took %.3f %s.", + message("Making extra starsloop tasks took %.3f %s.", clocks_from_ticks(getticks() - tic2), clocks_getunit()); tic2 = getticks(); - if (e->policy & engine_policy_stars) - threadpool_map(&e->threadpool, engine_link_stars_tasks_mapper, sched->tasks, - sched->nr_tasks, sizeof(struct task), 0, e); + /* Add the dependencies for the gravity stuff */ + if (e->policy & (engine_policy_self_gravity | engine_policy_external_gravity)) + engine_link_gravity_tasks(e); if (e->verbose) - message("Linking stars tasks took %.3f %s.", + message("Linking gravity tasks took %.3f %s.", clocks_from_ticks(getticks() - tic2), clocks_getunit()); + tic2 = getticks(); + #ifdef WITH_MPI if (e->policy & engine_policy_feedback) error("Cannot run stellar feedback with MPI (yet)."); diff --git a/src/engine_marktasks.c b/src/engine_marktasks.c index ad36c532da..9c7a783c25 100644 --- a/src/engine_marktasks.c +++ b/src/engine_marktasks.c @@ -141,6 +141,23 @@ void engine_marktasks_mapper(void *map_data, int num_elements, } } + /* Activate the star feedback */ + else if (t_type == task_type_self && + t_subtype == task_subtype_stars_feedback) { + if (cell_is_active_stars(ci, e)) { + scheduler_activate(s, t); + } + } + + /* Store current values of dx_max and h_max. */ + else if (t_type == task_type_sub_self && + t_subtype == task_subtype_stars_feedback) { + if (cell_is_active_stars(ci, e)) { + scheduler_activate(s, t); + cell_activate_subcell_stars_tasks(ci, NULL, s); + } + } + /* Activate the gravity drift */ else if (t_type == task_type_self && t_subtype == task_subtype_grav) { if (cell_is_active_gravity(ci, e)) { @@ -222,7 +239,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements, } } - /* Stars */ + /* Stars density */ if (t_subtype == task_subtype_stars_density && ((ci_active_stars && ci->nodeID == engine_rank) || (cj_active_stars && cj->nodeID == engine_rank))) { @@ -279,6 +296,14 @@ void engine_marktasks_mapper(void *map_data, int num_elements, } } + /* Stars feedback */ + if (t_subtype == task_subtype_stars_feedback && + ((ci_active_stars && ci->nodeID == engine_rank) || + (cj_active_stars && cj->nodeID == engine_rank))) { + + scheduler_activate(s, t); + } + /* Gravity */ if ((t_subtype == task_subtype_grav) && ((ci_active_gravity && ci_nodeID == nodeID) || @@ -303,7 +328,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements, if (t_subtype == task_subtype_density) { /* Too much particle movement? */ - if (cell_need_rebuild_for_pair(ci, cj)) *rebuild_space = 1; + if (cell_need_rebuild_for_hydro_pair(ci, cj)) *rebuild_space = 1; #ifdef WITH_MPI /* Activate the send/recv tasks. */ @@ -399,7 +424,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements, if (t->subtype == task_subtype_stars_density) { /* Too much particle movement? */ - if (cell_need_rebuild_for_pair(ci, cj)) *rebuild_space = 1; + if (cell_need_rebuild_for_stars_pair(ci, cj)) *rebuild_space = 1; // LOIC: Need implementing MPI case } diff --git a/src/runner.c b/src/runner.c index 018e35c582..13e87b09f2 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2732,6 +2732,8 @@ void *runner_main(void *data) { runner_do_grav_external(r, ci, 1); else if (t->subtype == task_subtype_stars_density) runner_doself_stars_density(r, ci, 1); + else if (t->subtype == task_subtype_stars_feedback) + runner_doself_stars_feedback(r, ci, 1); else error("Unknown/invalid task subtype (%d).", t->subtype); break; @@ -2749,6 +2751,8 @@ void *runner_main(void *data) { runner_dopair_recursive_grav(r, ci, cj, 1); else if (t->subtype == task_subtype_stars_density) runner_dopair_stars_density(r, ci, cj, 1); + else if (t->subtype == task_subtype_stars_feedback) + runner_dopair_stars_feedback(r, ci, cj, 1); else error("Unknown/invalid task subtype (%d).", t->subtype); break; @@ -2764,6 +2768,8 @@ void *runner_main(void *data) { runner_dosub_self2_force(r, ci, 1); else if (t->subtype == task_subtype_stars_density) runner_dosub_self_stars_density(r, ci, 1); + else if (t->subtype == task_subtype_stars_feedback) + runner_dosub_self_stars_feedback(r, ci, 1); else error("Unknown/invalid task subtype (%d).", t->subtype); break; @@ -2779,6 +2785,8 @@ void *runner_main(void *data) { runner_dosub_pair2_force(r, ci, cj, t->flags, 1); else if (t->subtype == task_subtype_stars_density) runner_dosub_pair_stars_density(r, ci, cj, t->flags, 1); + else if (t->subtype == task_subtype_stars_feedback) + runner_dosub_pair_stars_feedback(r, ci, cj, t->flags, 1); else error("Unknown/invalid task subtype (%d).", t->subtype); break; diff --git a/src/space.c b/src/space.c index 85e1147a90..b00a473cfe 100644 --- a/src/space.c +++ b/src/space.c @@ -218,6 +218,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->stars.ghost_out = NULL; c->stars.ghost = NULL; c->stars.density = NULL; + c->stars.feedback = NULL; c->kick1 = NULL; c->kick2 = NULL; c->timestep = NULL; @@ -2712,7 +2713,7 @@ void space_split_recursive(struct space *s, struct cell *c, /* Update the cell-wide properties */ h_max = max(h_max, cp->hydro.h_max); - stars_h_max = max(h_max, cp->stars.h_max); + stars_h_max = max(stars_h_max, cp->stars.h_max); ti_hydro_end_min = min(ti_hydro_end_min, cp->hydro.ti_end_min); ti_hydro_end_max = max(ti_hydro_end_max, cp->hydro.ti_end_max); ti_hydro_beg_max = max(ti_hydro_beg_max, cp->hydro.ti_beg_max); diff --git a/src/task.c b/src/task.c index f68d10f7cf..83db236450 100644 --- a/src/task.c +++ b/src/task.c @@ -83,9 +83,10 @@ const char *taskID_names[task_type_count] = {"none", /* Sub-task type names. */ const char *subtaskID_names[task_subtype_count] = { - "none", "density", "gradient", "force", "grav", - "external_grav", "tend", "xv", "rho", "gpart", - "multipole", "spart", "stars_density"}; + "none", "density", "gradient", "force", + "grav", "external_grav", "tend", "xv", + "rho", "gpart", "multipole", "spart", + "stars_density", "stars_feedback"}; #ifdef WITH_MPI /* MPI communicators for the subtypes. */ @@ -164,6 +165,7 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on( break; case task_subtype_stars_density: + case task_subtype_stars_feedback: return task_action_all; break; @@ -354,6 +356,9 @@ void task_unlock(struct task *t) { cell_munlocktree(ci); } else if (subtype == task_subtype_stars_density) { cell_sunlocktree(ci); + } else if (subtype == task_subtype_stars_feedback) { + cell_sunlocktree(ci); + cell_unlocktree(ci); } else { cell_unlocktree(ci); } @@ -369,6 +374,11 @@ void task_unlock(struct task *t) { } else if (subtype == task_subtype_stars_density) { cell_sunlocktree(ci); cell_sunlocktree(cj); + } else if (subtype == task_subtype_stars_feedback) { + cell_sunlocktree(ci); + cell_sunlocktree(cj); + cell_unlocktree(ci); + cell_unlocktree(cj); } else { cell_unlocktree(ci); cell_unlocktree(cj); @@ -481,7 +491,15 @@ int task_lock(struct task *t) { } else if (subtype == task_subtype_stars_density) { if (ci->stars.hold) return 0; if (cell_slocktree(ci) != 0) return 0; - } else { + } else if (subtype == task_subtype_stars_feedback) { + if (ci->stars.hold) return 0; + if (ci->hydro.hold) return 0; + if (cell_slocktree(ci) != 0) return 0; + if (cell_locktree(ci) != 0) { + cell_sunlocktree(ci); + return 0; + } + } else { /* subtype == hydro */ if (ci->hydro.hold) return 0; if (cell_locktree(ci) != 0) return 0; } @@ -513,7 +531,27 @@ int task_lock(struct task *t) { cell_sunlocktree(ci); return 0; } - } else { + } else if (subtype == task_subtype_stars_feedback) { + /* Lock the stars and the gas particles in both cells */ + if (ci->stars.hold || cj->stars.hold) return 0; + if (ci->hydro.hold || cj->hydro.hold) return 0; + if (cell_slocktree(ci) != 0) return 0; + if (cell_slocktree(cj) != 0) { + cell_sunlocktree(ci); + return 0; + } + if (cell_locktree(ci) != 0) { + cell_sunlocktree(ci); + cell_sunlocktree(cj); + return 0; + } + if (cell_locktree(cj) != 0) { + cell_sunlocktree(ci); + cell_sunlocktree(cj); + cell_unlocktree(ci); + return 0; + } + } else { /* subtype == hydro */ /* Lock the parts in both cells */ if (ci->hydro.hold || cj->hydro.hold) return 0; if (cell_locktree(ci) != 0) return 0; diff --git a/src/task.h b/src/task.h index 5bce55d6a2..e432a051f5 100644 --- a/src/task.h +++ b/src/task.h @@ -92,6 +92,7 @@ enum task_subtypes { task_subtype_multipole, task_subtype_spart, task_subtype_stars_density, + task_subtype_stars_feedback, task_subtype_count } __attribute__((packed)); diff --git a/tools/analyse_runtime.py b/tools/analyse_runtime.py index e1b09a9903..a4b08d5d0f 100755 --- a/tools/analyse_runtime.py +++ b/tools/analyse_runtime.py @@ -67,6 +67,7 @@ labels = [ "Counting and linking tasks", "Setting super-pointers", "Making extra hydroloop tasks", + "Making extra starsloop tasks", "Linking gravity tasks", "Creating send tasks", "Exchanging cell tags", diff --git a/tools/task_plots/analyse_tasks.py b/tools/task_plots/analyse_tasks.py index f79a0090b0..5738ca068c 100755 --- a/tools/task_plots/analyse_tasks.py +++ b/tools/task_plots/analyse_tasks.py @@ -113,6 +113,7 @@ SUBTYPES = [ "multipole", "spart", "stars_density", + "stars_feedback", "count", ] diff --git a/tools/task_plots/plot_tasks.py b/tools/task_plots/plot_tasks.py index 1ff722a607..82dc882bec 100755 --- a/tools/task_plots/plot_tasks.py +++ b/tools/task_plots/plot_tasks.py @@ -198,6 +198,7 @@ SUBTYPES = [ "multipole", "spart", "stars_density", + "stars_feedback", "count", ] @@ -225,6 +226,10 @@ FULLTYPES = [ "pair/stars_density", "sub_self/stars_density", "sub_pair/stars_density", + "self/stars_feedback", + "pair/stars_feedback", + "sub_self/stars_feedback", + "sub_pair/stars_feedback", ] # A number of colours for the various types. Recycled when there are -- GitLab