diff --git a/src/cell.c b/src/cell.c index 8d72601a410a8b3a84418fd9341cb7a581db9e52..d11c99e3d0da6096256ac4a1a158effe651fd6f5 100644 --- a/src/cell.c +++ b/src/cell.c @@ -1167,19 +1167,10 @@ void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data) { */ int cell_has_tasks(struct cell *c) { #ifdef WITH_MPI - if (c->timestep != NULL || c->mpi.recv != NULL) return 1; + return (c->timestep_collect != NULL || c->mpi.recv != NULL); #else - if (c->timestep != NULL) return 1; + return (c->timestep != NULL); #endif - - if (c->split) { - int count = 0; - for (int k = 0; k < 8; ++k) - if (c->progeny[k] != NULL) count += cell_has_tasks(c->progeny[k]); - return count; - } else { - return 0; - } } /** diff --git a/src/cell.h b/src/cell.h index 9e2eda7bb79ca8a26904ddbd05cb17174bfdf217..d21be55b10fa8d2439ef81131fa5e4514d5d8a61 100644 --- a/src/cell.h +++ b/src/cell.h @@ -225,37 +225,40 @@ struct pcell { /** * @brief Cell information at the end of a time-step. */ -struct pcell_step_hydro { +struct pcell_step { - /*! Minimal integer end-of-timestep in this cell (hydro) */ - integertime_t ti_end_min; + struct { - /*! Maximal distance any #part has travelled since last rebuild */ - float dx_max_part; -}; + /*! Minimal integer end-of-timestep in this cell (hydro) */ + integertime_t ti_end_min; + + /*! Maximal distance any #part has travelled since last rebuild */ + float dx_max_part; + } hydro; -struct pcell_step_grav { + struct { - /*! Minimal integer end-of-timestep in this cell (gravity) */ - integertime_t ti_end_min; -}; + /*! Minimal integer end-of-timestep in this cell (gravity) */ + integertime_t ti_end_min; + } grav; -struct pcell_step_stars { + struct { - /*! Minimal integer end-of-timestep in this cell (stars) */ - integertime_t ti_end_min; + /*! Minimal integer end-of-timestep in this cell (stars) */ + integertime_t ti_end_min; - /*! Maximal distance any #part has travelled since last rebuild */ - float dx_max_part; -}; + /*! Maximal distance any #part has travelled since last rebuild */ + float dx_max_part; + } stars; -struct pcell_step_black_holes { + struct { - /*! Minimal integer end-of-timestep in this cell (black_holes) */ - integertime_t ti_end_min; + /*! Minimal integer end-of-timestep in this cell (black_holes) */ + integertime_t ti_end_min; - /*! Maximal distance any #part has travelled since last rebuild */ - float dx_max_part; + /*! Maximal distance any #part has travelled since last rebuild */ + float dx_max_part; + } black_holes; }; /** @@ -406,6 +409,9 @@ struct cell { * feedback */ struct task *timestep_sync; + /*! The task to recursively collect time-steps */ + struct task *timestep_collect; + #ifdef WITH_CSDS /*! The csds task */ struct task *csds; @@ -484,16 +490,8 @@ void cell_unpack_bpart_swallow(struct cell *c, const struct black_holes_bpart_data *data); int cell_pack_tags(const struct cell *c, int *tags); int cell_unpack_tags(const int *tags, struct cell *c); -int cell_pack_end_step_hydro(struct cell *c, struct pcell_step_hydro *pcell); -int cell_unpack_end_step_hydro(struct cell *c, struct pcell_step_hydro *pcell); -int cell_pack_end_step_grav(struct cell *c, struct pcell_step_grav *pcell); -int cell_unpack_end_step_grav(struct cell *c, struct pcell_step_grav *pcell); -int cell_pack_end_step_stars(struct cell *c, struct pcell_step_stars *pcell); -int cell_unpack_end_step_stars(struct cell *c, struct pcell_step_stars *pcell); -int cell_pack_end_step_black_holes(struct cell *c, - struct pcell_step_black_holes *pcell); -int cell_unpack_end_step_black_holes(struct cell *c, - struct pcell_step_black_holes *pcell); +int cell_pack_end_step(struct cell *c, struct pcell_step *pcell); +int cell_unpack_end_step(struct cell *c, struct pcell_step *pcell); void cell_pack_timebin(const struct cell *const c, timebin_t *const t); void cell_unpack_timebin(struct cell *const c, timebin_t *const t); int cell_pack_multipoles(struct cell *c, struct gravity_tensors *m); diff --git a/src/cell_pack.c b/src/cell_pack.c index 6d20dfc2be79edddc22858e183c4fc1ca14cc1c1..6305ddb6aa7c6a81f40a2422e527d596340c3ba6 100644 --- a/src/cell_pack.c +++ b/src/cell_pack.c @@ -273,6 +273,7 @@ int cell_unpack(struct pcell *restrict pc, struct cell *restrict c, temp->black_holes.dx_max_part = 0.f; temp->nodeID = c->nodeID; temp->parent = c; + temp->top = c->top; c->progeny[k] = temp; c->split = 1; count += cell_unpack(&pc[pc->progeny[k]], temp, s, with_gravity); @@ -324,121 +325,27 @@ int cell_unpack_tags(const int *tags, struct cell *restrict c) { #endif } -/** - * @brief Pack the time information of the given cell and all it's sub-cells. - * - * @param c The #cell. - * @param pcells (output) The end-of-timestep information we pack into - * - * @return The number of packed cells. - */ -int cell_pack_end_step_hydro(struct cell *restrict c, - struct pcell_step_hydro *restrict pcells) { -#ifdef WITH_MPI - - /* Pack this cell's data. */ - pcells[0].ti_end_min = c->hydro.ti_end_min; - pcells[0].dx_max_part = c->hydro.dx_max_part; - - /* Fill in the progeny, depth-first recursion. */ - int count = 1; - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) { - count += cell_pack_end_step_hydro(c->progeny[k], &pcells[count]); - } - - /* Return the number of packed values. */ - return count; - -#else - error("SWIFT was not compiled with MPI support."); - return 0; -#endif -} +int cell_pack_end_step(struct cell *c, struct pcell_step *pcells) { -/** - * @brief Unpack the time information of a given cell and its sub-cells. - * - * @param c The #cell - * @param pcells The end-of-timestep information to unpack - * - * @return The number of cells created. - */ -int cell_unpack_end_step_hydro(struct cell *restrict c, - struct pcell_step_hydro *restrict pcells) { -#ifdef WITH_MPI - - /* Unpack this cell's data. */ - c->hydro.ti_end_min = pcells[0].ti_end_min; - c->hydro.dx_max_part = pcells[0].dx_max_part; - - /* Fill in the progeny, depth-first recursion. */ - int count = 1; - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) { - count += cell_unpack_end_step_hydro(c->progeny[k], &pcells[count]); - } - - /* Return the number of packed values. */ - return count; - -#else - error("SWIFT was not compiled with MPI support."); - return 0; -#endif -} - -/** - * @brief Pack the time information of the given cell and all it's sub-cells. - * - * @param c The #cell. - * @param pcells (output) The end-of-timestep information we pack into - * - * @return The number of packed cells. - */ -int cell_pack_end_step_grav(struct cell *restrict c, - struct pcell_step_grav *restrict pcells) { #ifdef WITH_MPI /* Pack this cell's data. */ - pcells[0].ti_end_min = c->grav.ti_end_min; + pcells[0].hydro.ti_end_min = c->hydro.ti_end_min; + pcells[0].hydro.dx_max_part = c->hydro.dx_max_part; - /* Fill in the progeny, depth-first recursion. */ - int count = 1; - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) { - count += cell_pack_end_step_grav(c->progeny[k], &pcells[count]); - } + pcells[0].grav.ti_end_min = c->grav.ti_end_min; - /* Return the number of packed values. */ - return count; - -#else - error("SWIFT was not compiled with MPI support."); - return 0; -#endif -} - -/** - * @brief Unpack the time information of a given cell and its sub-cells. - * - * @param c The #cell - * @param pcells The end-of-timestep information to unpack - * - * @return The number of cells created. - */ -int cell_unpack_end_step_grav(struct cell *restrict c, - struct pcell_step_grav *restrict pcells) { -#ifdef WITH_MPI + pcells[0].stars.ti_end_min = c->stars.ti_end_min; + pcells[0].stars.dx_max_part = c->stars.dx_max_part; - /* Unpack this cell's data. */ - c->grav.ti_end_min = pcells[0].ti_end_min; + pcells[0].black_holes.ti_end_min = c->black_holes.ti_end_min; + pcells[0].black_holes.dx_max_part = c->black_holes.dx_max_part; /* Fill in the progeny, depth-first recursion. */ int count = 1; for (int k = 0; k < 8; k++) if (c->progeny[k] != NULL) { - count += cell_unpack_end_step_grav(c->progeny[k], &pcells[count]); + count += cell_pack_end_step(c->progeny[k], &pcells[count]); } /* Return the number of packed values. */ @@ -450,125 +357,27 @@ int cell_unpack_end_step_grav(struct cell *restrict c, #endif } -/** - * @brief Pack the time information of the given cell and all it's sub-cells. - * - * @param c The #cell. - * @param pcells (output) The end-of-timestep information we pack into - * - * @return The number of packed cells. - */ -int cell_pack_end_step_stars(struct cell *restrict c, - struct pcell_step_stars *restrict pcells) { -#ifdef WITH_MPI - - /* Pack this cell's data. */ - pcells[0].ti_end_min = c->stars.ti_end_min; - pcells[0].dx_max_part = c->stars.dx_max_part; - - /* Fill in the progeny, depth-first recursion. */ - int count = 1; - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) { - count += cell_pack_end_step_stars(c->progeny[k], &pcells[count]); - } - - /* Return the number of packed values. */ - return count; - -#else - error("SWIFT was not compiled with MPI support."); - return 0; -#endif -} +int cell_unpack_end_step(struct cell *c, struct pcell_step *pcells) { -/** - * @brief Unpack the time information of a given cell and its sub-cells. - * - * @param c The #cell - * @param pcells The end-of-timestep information to unpack - * - * @return The number of cells created. - */ -int cell_unpack_end_step_stars(struct cell *restrict c, - struct pcell_step_stars *restrict pcells) { #ifdef WITH_MPI /* Unpack this cell's data. */ - c->stars.ti_end_min = pcells[0].ti_end_min; - c->stars.dx_max_part = pcells[0].dx_max_part; - - /* Fill in the progeny, depth-first recursion. */ - int count = 1; - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) { - count += cell_unpack_end_step_stars(c->progeny[k], &pcells[count]); - } + c->hydro.ti_end_min = pcells[0].hydro.ti_end_min; + c->hydro.dx_max_part = pcells[0].hydro.dx_max_part; - /* Return the number of packed values. */ - return count; + c->grav.ti_end_min = pcells[0].grav.ti_end_min; -#else - error("SWIFT was not compiled with MPI support."); - return 0; -#endif -} - -/** - * @brief Pack the time information of the given cell and all it's sub-cells. - * - * @param c The #cell. - * @param pcells (output) The end-of-timestep information we pack into - * - * @return The number of packed cells. - */ -int cell_pack_end_step_black_holes( - struct cell *restrict c, struct pcell_step_black_holes *restrict pcells) { - -#ifdef WITH_MPI - - /* Pack this cell's data. */ - pcells[0].ti_end_min = c->black_holes.ti_end_min; - pcells[0].dx_max_part = c->black_holes.dx_max_part; - - /* Fill in the progeny, depth-first recursion. */ - int count = 1; - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) { - count += cell_pack_end_step_black_holes(c->progeny[k], &pcells[count]); - } - - /* Return the number of packed values. */ - return count; - -#else - error("SWIFT was not compiled with MPI support."); - return 0; -#endif -} - -/** - * @brief Unpack the time information of a given cell and its sub-cells. - * - * @param c The #cell - * @param pcells The end-of-timestep information to unpack - * - * @return The number of cells created. - */ -int cell_unpack_end_step_black_holes( - struct cell *restrict c, struct pcell_step_black_holes *restrict pcells) { - -#ifdef WITH_MPI + c->stars.ti_end_min = pcells[0].stars.ti_end_min; + c->stars.dx_max_part = pcells[0].stars.dx_max_part; - /* Unpack this cell's data. */ - c->black_holes.ti_end_min = pcells[0].ti_end_min; - c->black_holes.dx_max_part = pcells[0].dx_max_part; + c->black_holes.ti_end_min = pcells[0].black_holes.ti_end_min; + c->black_holes.dx_max_part = pcells[0].black_holes.dx_max_part; /* Fill in the progeny, depth-first recursion. */ int count = 1; for (int k = 0; k < 8; k++) if (c->progeny[k] != NULL) { - count += cell_unpack_end_step_black_holes(c->progeny[k], &pcells[count]); + count += cell_unpack_end_step(c->progeny[k], &pcells[count]); } /* Return the number of packed values. */ diff --git a/src/cell_unskip.c b/src/cell_unskip.c index 8750639b7a38f73a29a5f15f6af113140a5b6b53..dae52347ed0aae9ab2c71c4fb88a5038bfd35a3d 100644 --- a/src/cell_unskip.c +++ b/src/cell_unskip.c @@ -360,6 +360,7 @@ void cell_activate_sync_part(struct cell *c, struct scheduler *s) { error("Trying to activate un-existing c->timestep_sync"); #endif scheduler_activate(s, c->timestep_sync); + scheduler_activate(s, c->top->timestep_collect); scheduler_activate(s, c->kick1); } else { for (struct cell *parent = c->parent; @@ -374,6 +375,7 @@ void cell_activate_sync_part(struct cell *c, struct scheduler *s) { error("Trying to activate un-existing parent->timestep_sync"); #endif scheduler_activate(s, parent->timestep_sync); + scheduler_activate(s, parent->top->timestep_collect); scheduler_activate(s, parent->kick1); break; } @@ -554,6 +556,7 @@ void cell_activate_limiter(struct cell *c, struct scheduler *s) { error("Trying to activate un-existing c->timestep_limiter"); #endif scheduler_activate(s, c->timestep_limiter); + scheduler_activate(s, c->top->timestep_collect); scheduler_activate(s, c->kick1); } else { for (struct cell *parent = c->parent; @@ -569,6 +572,7 @@ void cell_activate_limiter(struct cell *c, struct scheduler *s) { error("Trying to activate un-existing parent->timestep_limiter"); #endif scheduler_activate(s, parent->timestep_limiter); + scheduler_activate(s, parent->top->timestep_collect); scheduler_activate(s, parent->kick1); break; } @@ -1653,10 +1657,6 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) { scheduler_activate_unpack(s, ci->mpi.unpack, task_subtype_limiter); } - /* If the foreign cell is active, we want its ti_end values. */ - if (ci_active) - scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_part); - /* Is the foreign cell active and will need stuff from us? */ if (ci_active) { @@ -1687,22 +1687,14 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) { ci_nodeID); } - /* If the local cell is active, send its ti_end values. */ - if (cj_active) - scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_part, - ci_nodeID); - /* Propagating new star counts? */ if (with_star_formation && with_feedback) { if (ci_active && ci->hydro.count > 0) { scheduler_activate_recv(s, ci->mpi.recv, task_subtype_sf_counts); - scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_spart); } if (cj_active && cj->hydro.count > 0) { scheduler_activate_send(s, cj->mpi.send, task_subtype_sf_counts, ci_nodeID); - scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart, - ci_nodeID); } } @@ -1726,10 +1718,6 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) { scheduler_activate_unpack(s, cj->mpi.unpack, task_subtype_limiter); } - /* If the foreign cell is active, we want its ti_end values. */ - if (cj_active) - scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_part); - /* Is the foreign cell active and will need stuff from us? */ if (cj_active) { @@ -1761,22 +1749,14 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) { cj_nodeID); } - /* If the local cell is active, send its ti_end values. */ - if (ci_active) - scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_part, - cj_nodeID); - /* Propagating new star counts? */ if (with_star_formation && with_feedback) { if (cj_active && cj->hydro.count > 0) { scheduler_activate_recv(s, cj->mpi.recv, task_subtype_sf_counts); - scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_spart); } if (ci_active && ci->hydro.count > 0) { scheduler_activate_send(s, ci->mpi.send, task_subtype_sf_counts, cj_nodeID); - scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart, - cj_nodeID); } } } @@ -1802,6 +1782,8 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) { 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->top->timestep_collect != NULL) + scheduler_activate(s, c->top->timestep_collect); if (c->hydro.end_force != NULL) scheduler_activate(s, c->hydro.end_force); if (c->hydro.cooling_in != NULL) cell_activate_cooling(c, s, e); #ifdef WITH_CSDS @@ -1877,10 +1859,6 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { if (cj_active) scheduler_activate_recv(s, ci->mpi.recv, task_subtype_gpart); - /* If the foreign cell is active, we want its ti_end values. */ - if (ci_active) - scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_gpart); - /* Is the foreign cell active and will need stuff from us? */ if (ci_active) { @@ -1893,20 +1871,11 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { cell_activate_drift_gpart(cj, s); } - /* If the local cell is active, send its ti_end values. */ - if (cj_active) - scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_gpart, - ci_nodeID); - } else if (cj_nodeID != nodeID) { /* If the local cell is active, receive data from the foreign cell. */ if (ci_active) scheduler_activate_recv(s, cj->mpi.recv, task_subtype_gpart); - /* If the foreign cell is active, we want its ti_end values. */ - if (cj_active) - scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_gpart); - /* Is the foreign cell active and will need stuff from us? */ if (cj_active) { @@ -1918,11 +1887,6 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { itself. */ cell_activate_drift_gpart(ci, s); } - - /* If the local cell is active, send its ti_end values. */ - if (ci_active) - scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_gpart, - cj_nodeID); } #endif } @@ -1960,6 +1924,8 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { 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->top->timestep_collect != NULL) + scheduler_activate(s, c->top->timestep_collect); 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.long_range != NULL) scheduler_activate(s, c->grav.long_range); @@ -2130,10 +2096,6 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s, ci_nodeID); #endif cell_activate_drift_spart(cj, s); - - /* If the local cell is active, send its ti_end values. */ - scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart, - ci_nodeID); } if (ci_active) { @@ -2141,8 +2103,6 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s, #ifdef EXTRA_STAR_LOOPS scheduler_activate_recv(s, ci->mpi.recv, task_subtype_spart_prep2); #endif - /* If the foreign cell is active, we want its ti_end values. */ - scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_spart); /* Is the foreign cell active and will need stuff from us? */ scheduler_activate_send(s, cj->mpi.send, task_subtype_xv, ci_nodeID); @@ -2172,10 +2132,6 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s, cj_nodeID); #endif cell_activate_drift_spart(ci, s); - - /* If the local cell is active, send its ti_end values. */ - scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart, - cj_nodeID); } if (cj_active) { @@ -2183,8 +2139,6 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s, #ifdef EXTRA_STAR_LOOPS scheduler_activate_recv(s, cj->mpi.recv, task_subtype_spart_prep2); #endif - /* If the foreign cell is active, we want its ti_end values. */ - scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_spart); /* Is the foreign cell active and will need stuff from us? */ scheduler_activate_send(s, ci->mpi.send, task_subtype_xv, cj_nodeID); @@ -2394,6 +2348,8 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s, 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->top->timestep_collect != NULL) + scheduler_activate(s, c->top->timestep_collect); #ifdef WITH_CSDS if (c->csds != NULL) scheduler_activate(s, c->csds); #endif @@ -2510,18 +2466,11 @@ int cell_unskip_black_holes_tasks(struct cell *c, struct scheduler *s) { /* Drift before you send */ cell_activate_drift_bpart(cj, s); - /* Send the new BH time-steps */ - scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_bpart, - ci_nodeID); - /* Receive the foreign BHs to tag particles to swallow and for feedback */ scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart_rho); scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart_feedback); - /* Receive the foreign BH time-steps */ - scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_bpart); - /* Send the local part information */ scheduler_activate_send(s, cj->mpi.send, task_subtype_rho, ci_nodeID); scheduler_activate_send(s, cj->mpi.send, task_subtype_part_swallow, @@ -2548,18 +2497,11 @@ int cell_unskip_black_holes_tasks(struct cell *c, struct scheduler *s) { /* Drift before you send */ cell_activate_drift_bpart(ci, s); - /* Send the new BH time-steps */ - scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_bpart, - cj_nodeID); - /* Receive the foreign BHs to tag particles to swallow and for feedback */ scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart_rho); scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart_feedback); - /* Receive the foreign BH time-steps */ - scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_bpart); - /* Send the local part information */ scheduler_activate_send(s, ci->mpi.send, task_subtype_rho, cj_nodeID); scheduler_activate_send(s, ci->mpi.send, task_subtype_part_swallow, @@ -2694,6 +2636,8 @@ int cell_unskip_black_holes_tasks(struct cell *c, struct scheduler *s) { 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->top->timestep_collect != NULL) + scheduler_activate(s, c->top->timestep_collect); #ifdef WITH_CSDS if (c->csds != NULL) scheduler_activate(s, c->csds); #endif @@ -2897,6 +2841,8 @@ int cell_unskip_sinks_tasks(struct cell *c, struct scheduler *s) { 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->top->timestep_collect != NULL) + scheduler_activate(s, c->top->timestep_collect); #ifdef WITH_CSDS if (c->csds != NULL) scheduler_activate(s, c->csds); #endif diff --git a/src/engine.c b/src/engine.c index 92b45dcbe20b3187d0c77d9015b74f2e4b3cb607..12582901b5ee1103ab1038be99ab11c5eca433d9 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1576,7 +1576,7 @@ void engine_skip_force_and_kick(struct engine *e) { t->type == task_type_drift_sink || t->type == task_type_kick1 || t->type == task_type_kick2 || t->type == task_type_timestep || t->type == task_type_timestep_limiter || - t->type == task_type_timestep_sync || + t->type == task_type_timestep_sync || t->type == task_type_collect || t->type == task_type_end_hydro_force || t->type == task_type_cooling || t->type == task_type_stars_in || t->type == task_type_stars_out || t->type == task_type_star_formation || @@ -1614,12 +1614,7 @@ void engine_skip_force_and_kick(struct engine *e) { t->subtype == task_subtype_sink_compute_formation || t->subtype == task_subtype_sink_merger || t->subtype == task_subtype_sink_accretion || - t->subtype == task_subtype_tend_part || - t->subtype == task_subtype_tend_gpart || - t->subtype == task_subtype_tend_spart || - t->subtype == task_subtype_tend_sink || - t->subtype == task_subtype_tend_bpart || - t->subtype == task_subtype_rho || + t->subtype == task_subtype_tend || t->subtype == task_subtype_rho || t->subtype == task_subtype_spart_density || t->subtype == task_subtype_part_prep1 || t->subtype == task_subtype_spart_prep2 || @@ -1925,16 +1920,6 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs, if (e->policy & engine_policy_rt) space_convert_rt_quantities_after_zeroth_step(e->s, e->verbose); - /* Since the time-steps may have changed because of the limiter's - * action, we need to communicate the new time-step sizes */ - if ((e->policy & engine_policy_timestep_sync) || - (e->policy & engine_policy_timestep_limiter)) { -#ifdef WITH_MPI - engine_unskip_timestep_communications(e); - engine_launch(e, "timesteps"); -#endif - } - #ifdef SWIFT_HYDRO_DENSITY_CHECKS /* Run the brute-force hydro calculation for some parts */ if (e->policy & engine_policy_hydro) @@ -2411,16 +2396,6 @@ void engine_step(struct engine *e) { e->systime_last_step = end_systime - start_systime; #endif - /* Since the time-steps may have changed because of the limiter's - * action, we need to communicate the new time-step sizes */ - if ((e->policy & engine_policy_timestep_sync) || - (e->policy & engine_policy_timestep_limiter)) { -#ifdef WITH_MPI - engine_unskip_timestep_communications(e); - engine_launch(e, "timesteps"); -#endif - } - #ifdef SWIFT_HYDRO_DENSITY_CHECKS /* Run the brute-force hydro calculation for some parts */ if (e->policy & engine_policy_hydro) diff --git a/src/engine_collect_end_of_step.c b/src/engine_collect_end_of_step.c index e0935271cb04c295e79a1058bd4a8de0aafb40c9..6a2fca510c058e33a2c96dbd777b9cefbc5798d5 100644 --- a/src/engine_collect_end_of_step.c +++ b/src/engine_collect_end_of_step.c @@ -51,272 +51,6 @@ struct end_of_step_data { float csds_file_size_gb; }; -/** - * @brief Recursive function gathering end-of-step data. - * - * We recurse until we encounter a timestep or time-step MPI recv task - * as the values will have been set at that level. We then bring these - * values upwards. - * - * @param c The #cell to recurse into. - * @param e The #engine. - */ -void engine_collect_end_of_step_recurse_hydro(struct cell *c, - const struct engine *e) { - - /* Skip super-cells (Their values are already set) */ - if (c->timestep != NULL) return; -#ifdef WITH_MPI - if (cell_get_recv(c, task_subtype_tend_part) != NULL) return; -#endif /* WITH_MPI */ - -#ifdef SWIFT_DEBUG_CHECKS - /* if (!c->split) error("Reached a leaf without finding a time-step task! - * c->depth=%d c->maxdepth=%d c->count=%d c->node=%d", */ - /* c->depth, c->maxdepth, c->hydro.count, c->nodeID); */ -#endif - - /* Counters for the different quantities. */ - size_t updated = 0; - integertime_t ti_hydro_end_min = max_nr_timesteps, ti_hydro_beg_max = 0; - - /* Collect the values from the progeny. */ - for (int k = 0; k < 8; k++) { - struct cell *cp = c->progeny[k]; - if (cp != NULL && cp->hydro.count > 0) { - - /* Recurse */ - engine_collect_end_of_step_recurse_hydro(cp, e); - - /* And update */ - ti_hydro_end_min = min(ti_hydro_end_min, cp->hydro.ti_end_min); - ti_hydro_beg_max = max(ti_hydro_beg_max, cp->hydro.ti_beg_max); - - updated += cp->hydro.updated; - - /* Collected, so clear for next time. */ - cp->hydro.updated = 0; - } - } - - /* Store the collected values in the cell. */ - c->hydro.ti_end_min = ti_hydro_end_min; - c->hydro.ti_beg_max = ti_hydro_beg_max; - c->hydro.updated = updated; -} - -/** - * @brief Recursive function gathering end-of-step data. - * - * We recurse until we encounter a timestep or time-step MPI recv task - * as the values will have been set at that level. We then bring these - * values upwards. - * - * @param c The #cell to recurse into. - * @param e The #engine. - */ -void engine_collect_end_of_step_recurse_grav(struct cell *c, - const struct engine *e) { - - /* Skip super-cells (Their values are already set) */ - if (c->timestep != NULL) return; -#ifdef WITH_MPI - if (cell_get_recv(c, task_subtype_tend_gpart) != NULL) return; -#endif /* WITH_MPI */ - -#ifdef SWIFT_DEBUG_CHECKS - // if (!c->split) error("Reached a leaf without finding a time-step - // task!"); -#endif - - /* Counters for the different quantities. */ - size_t updated = 0; - integertime_t ti_grav_end_min = max_nr_timesteps, ti_grav_beg_max = 0; - - /* Collect the values from the progeny. */ - for (int k = 0; k < 8; k++) { - struct cell *cp = c->progeny[k]; - if (cp != NULL && cp->grav.count > 0) { - - /* Recurse */ - engine_collect_end_of_step_recurse_grav(cp, e); - - /* And update */ - ti_grav_end_min = min(ti_grav_end_min, cp->grav.ti_end_min); - ti_grav_beg_max = max(ti_grav_beg_max, cp->grav.ti_beg_max); - - updated += cp->grav.updated; - - /* Collected, so clear for next time. */ - cp->grav.updated = 0; - } - } - - /* Store the collected values in the cell. */ - c->grav.ti_end_min = ti_grav_end_min; - c->grav.ti_beg_max = ti_grav_beg_max; - c->grav.updated = updated; -} - -/** - * @brief Recursive function gathering end-of-step data. - * - * We recurse until we encounter a timestep or time-step MPI recv task - * as the values will have been set at that level. We then bring these - * values upwards. - * - * @param c The #cell to recurse into. - * @param e The #engine. - */ -void engine_collect_end_of_step_recurse_stars(struct cell *c, - const struct engine *e) { - - /* Skip super-cells (Their values are already set) */ - if (c->timestep != NULL) return; -#ifdef WITH_MPI - if (cell_get_recv(c, task_subtype_tend_spart) != NULL) return; -#endif /* WITH_MPI */ - -#ifdef SWIFT_DEBUG_CHECKS - // if (!c->split) error("Reached a leaf without finding a time-step task!"); -#endif - - /* Counters for the different quantities. */ - size_t updated = 0; - integertime_t ti_stars_end_min = max_nr_timesteps, ti_stars_beg_max = 0; - - /* Collect the values from the progeny. */ - for (int k = 0; k < 8; k++) { - struct cell *cp = c->progeny[k]; - if (cp != NULL && cp->stars.count > 0) { - - /* Recurse */ - engine_collect_end_of_step_recurse_stars(cp, e); - - /* And update */ - ti_stars_end_min = min(ti_stars_end_min, cp->stars.ti_end_min); - ti_stars_beg_max = max(ti_stars_beg_max, cp->stars.ti_beg_max); - - updated += cp->stars.updated; - - /* Collected, so clear for next time. */ - cp->stars.updated = 0; - } - } - - /* Store the collected values in the cell. */ - c->stars.ti_end_min = ti_stars_end_min; - c->stars.ti_beg_max = ti_stars_beg_max; - c->stars.updated = updated; -} - -/** - * @brief Recursive function gathering end-of-step data. - * - * We recurse until we encounter a timestep or time-step MPI recv task - * as the values will have been set at that level. We then bring these - * values upwards. - * - * @param c The #cell to recurse into. - * @param e The #engine. - */ -void engine_collect_end_of_step_recurse_black_holes(struct cell *c, - const struct engine *e) { - - /* Skip super-cells (Their values are already set) */ - if (c->timestep != NULL) return; -#ifdef WITH_MPI - if (cell_get_recv(c, task_subtype_tend_bpart) != NULL) return; -#endif /* WITH_MPI */ - -#ifdef SWIFT_DEBUG_CHECKS - // if (!c->split) error("Reached a leaf without finding a time-step task!"); -#endif - - /* Counters for the different quantities. */ - size_t updated = 0; - integertime_t ti_black_holes_end_min = max_nr_timesteps, - ti_black_holes_beg_max = 0; - - /* Collect the values from the progeny. */ - for (int k = 0; k < 8; k++) { - struct cell *cp = c->progeny[k]; - if (cp != NULL && cp->black_holes.count > 0) { - - /* Recurse */ - engine_collect_end_of_step_recurse_black_holes(cp, e); - - /* And update */ - ti_black_holes_end_min = - min(ti_black_holes_end_min, cp->black_holes.ti_end_min); - ti_black_holes_beg_max = - max(ti_black_holes_beg_max, cp->black_holes.ti_beg_max); - - updated += cp->black_holes.updated; - - /* Collected, so clear for next time. */ - cp->black_holes.updated = 0; - } - } - - /* Store the collected values in the cell. */ - c->black_holes.ti_end_min = ti_black_holes_end_min; - c->black_holes.ti_beg_max = ti_black_holes_beg_max; - c->black_holes.updated = updated; -} - -/** - * @brief Recursive function gathering end-of-step data. - * - * We recurse until we encounter a timestep or time-step MPI recv task - * as the values will have been set at that level. We then bring these - * values upwards. - * - * @param c The #cell to recurse into. - * @param e The #engine. - */ -void engine_collect_end_of_step_recurse_sinks(struct cell *c, - const struct engine *e) { - - /* Skip super-cells (Their values are already set) */ - if (c->timestep != NULL) return; -#ifdef WITH_MPI - if (cell_get_recv(c, task_subtype_tend_sink) != NULL) return; -#endif /* WITH_MPI */ - -#ifdef SWIFT_DEBUG_CHECKS - // if (!c->split) error("Reached a leaf without finding a time-step task!"); -#endif - - /* Counters for the different quantities. */ - size_t updated = 0; - integertime_t ti_sinks_end_min = max_nr_timesteps, ti_sinks_beg_max = 0; - - /* Collect the values from the progeny. */ - for (int k = 0; k < 8; k++) { - struct cell *cp = c->progeny[k]; - if (cp != NULL && cp->sinks.count > 0) { - - /* Recurse */ - engine_collect_end_of_step_recurse_sinks(cp, e); - - /* And update */ - ti_sinks_end_min = min(ti_sinks_end_min, cp->sinks.ti_end_min); - ti_sinks_beg_max = max(ti_sinks_beg_max, cp->sinks.ti_beg_max); - - updated += cp->sinks.updated; - - /* Collected, so clear for next time. */ - cp->sinks.updated = 0; - } - } - - /* Store the collected values in the cell. */ - c->sinks.ti_end_min = ti_sinks_end_min; - c->sinks.ti_beg_max = ti_sinks_beg_max; - c->sinks.updated = updated; -} - /** * @brief Mapping function to collect the data from the end of the step * @@ -333,13 +67,6 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, struct end_of_step_data *data = (struct end_of_step_data *)extra_data; const struct engine *e = data->e; - const int with_hydro = (e->policy & engine_policy_hydro); - const int with_self_grav = (e->policy & engine_policy_self_gravity); - const int with_ext_grav = (e->policy & engine_policy_external_gravity); - const int with_grav = (with_self_grav || with_ext_grav); - const int with_stars = (e->policy & engine_policy_stars); - const int with_sinks = (e->policy & engine_policy_sinks); - const int with_black_holes = (e->policy & engine_policy_black_holes); struct space *s = e->s; int *local_cells = (int *)map_data; struct star_formation_history *sfh_top = &data->sfh; @@ -366,24 +93,7 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, if (c->hydro.count > 0 || c->grav.count > 0 || c->stars.count > 0 || c->black_holes.count > 0 || c->sinks.count > 0) { - /* Make the top-cells recurse */ - if (with_hydro) { - engine_collect_end_of_step_recurse_hydro(c, e); - } - if (with_grav) { - engine_collect_end_of_step_recurse_grav(c, e); - } - if (with_stars) { - engine_collect_end_of_step_recurse_stars(c, e); - } - if (with_sinks) { - engine_collect_end_of_step_recurse_sinks(c, e); - } - if (with_black_holes) { - engine_collect_end_of_step_recurse_black_holes(c, e); - } - - /* And aggregate */ + /* Aggregate data */ if (c->hydro.ti_end_min > e->ti_current) ti_hydro_end_min = min(ti_hydro_end_min, c->hydro.ti_end_min); ti_hydro_beg_max = max(ti_hydro_beg_max, c->hydro.ti_beg_max); @@ -523,8 +233,8 @@ void engine_collect_end_of_step(struct engine *e, int apply) { /* Collect information from the local top-level cells */ threadpool_map(&e->threadpool, engine_collect_end_of_step_mapper, - s->local_cells_with_tasks_top, s->nr_local_cells_with_tasks, - sizeof(int), threadpool_auto_chunk_size, &data); + s->local_cells_top, s->nr_local_cells, sizeof(int), + threadpool_auto_chunk_size, &data); /* Get the number of inhibited particles from the space-wide counters * since these have been updated atomically during the time-steps. */ diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c index a9e3095c957fa62d3197887728e4c048f2f99f5b..8e8fcf7284ad0f1a985e758af9c66f012af554f0 100644 --- a/src/engine_maketasks.c +++ b/src/engine_maketasks.c @@ -67,11 +67,9 @@ extern int engine_max_parts_per_cooling; * @param ci The sending #cell. * @param cj Dummy cell containing the nodeID of the receiving node. * @param t_grav The send_grav #task, if it has already been created. - * @param t_ti The recv_ti_end #task, if it has already been created. */ void engine_addtasks_send_gravity(struct engine *e, struct cell *ci, - struct cell *cj, struct task *t_grav, - struct task *t_ti) { + struct cell *cj, struct task *t_grav) { #ifdef WITH_MPI struct link *l = NULL; @@ -99,28 +97,22 @@ void engine_addtasks_send_gravity(struct engine *e, struct cell *ci, t_grav = scheduler_addtask(s, task_type_send, task_subtype_gpart, ci->mpi.tag, 0, ci, cj); - t_ti = scheduler_addtask(s, task_type_send, task_subtype_tend_gpart, - ci->mpi.tag, 0, ci, cj); - /* The sends should unlock the down pass. */ scheduler_addunlock(s, t_grav, ci->grav.super->grav.down); /* Drift before you send */ scheduler_addunlock(s, ci->grav.super->grav.drift, t_grav); - - scheduler_addunlock(s, ci->super->timestep, t_ti); } /* Add them to the local cell. */ engine_addlink(e, &ci->mpi.send, t_grav); - engine_addlink(e, &ci->mpi.send, t_ti); } /* Recurse? */ if (ci->split) for (int k = 0; k < 8; k++) if (ci->progeny[k] != NULL) - engine_addtasks_send_gravity(e, ci->progeny[k], cj, t_grav, t_ti); + engine_addtasks_send_gravity(e, ci->progeny[k], cj, t_grav); #else error("SWIFT was not compiled with MPI support."); @@ -136,18 +128,19 @@ void engine_addtasks_send_gravity(struct engine *e, struct cell *ci, * @param t_xv The send_xv #task, if it has already been created. * @param t_rho The send_rho #task, if it has already been created. * @param t_gradient The send_gradient #task, if already created. - * @param t_ti The send_ti_end #task, if it has already been created. * @param t_prep1 The send_prep1 #task, if it has already been created. * @param t_limiter The send_limiter #task, if it has already been created. * @param with_feedback Are we running with stellar feedback? * @param with_limiter Are we running with the time-step limiter? * @param with_sync Are we running with time-step synchronization? */ -void engine_addtasks_send_hydro( - struct engine *e, struct cell *ci, struct cell *cj, struct task *t_xv, - struct task *t_rho, struct task *t_gradient, struct task *t_ti, - struct task *t_prep1, struct task *t_limiter, struct task *t_pack_limiter, - const int with_feedback, const int with_limiter, const int with_sync) { +void engine_addtasks_send_hydro(struct engine *e, struct cell *ci, + struct cell *cj, struct task *t_xv, + struct task *t_rho, struct task *t_gradient, + struct task *t_prep1, struct task *t_limiter, + struct task *t_pack_limiter, + const int with_feedback, const int with_limiter, + const int with_sync) { #ifdef WITH_MPI struct link *l = NULL; @@ -182,9 +175,6 @@ void engine_addtasks_send_hydro( ci->mpi.tag, 0, ci, cj); #endif - t_ti = scheduler_addtask(s, task_type_send, task_subtype_tend_part, - ci->mpi.tag, 0, ci, cj); - if (with_limiter) { t_limiter = scheduler_addtask(s, task_type_send, task_subtype_limiter, ci->mpi.tag, 0, ci, cj); @@ -234,7 +224,6 @@ void engine_addtasks_send_hydro( /* Drift before you send */ scheduler_addunlock(s, ci->hydro.super->hydro.drift, t_xv); - scheduler_addunlock(s, ci->super->timestep, t_ti); if (with_limiter) scheduler_addunlock(s, ci->super->timestep, t_pack_limiter); @@ -254,7 +243,6 @@ void engine_addtasks_send_hydro( #ifdef EXTRA_HYDRO_LOOP engine_addlink(e, &ci->mpi.send, t_gradient); #endif - engine_addlink(e, &ci->mpi.send, t_ti); if (with_limiter) { engine_addlink(e, &ci->mpi.send, t_limiter); engine_addlink(e, &ci->mpi.pack, t_pack_limiter); @@ -269,8 +257,8 @@ void engine_addtasks_send_hydro( for (int k = 0; k < 8; k++) if (ci->progeny[k] != NULL) engine_addtasks_send_hydro( - e, ci->progeny[k], cj, t_xv, t_rho, t_gradient, t_ti, t_prep1, - t_limiter, t_pack_limiter, with_feedback, with_limiter, with_sync); + e, ci->progeny[k], cj, t_xv, t_rho, t_gradient, t_prep1, t_limiter, + t_pack_limiter, with_feedback, with_limiter, with_sync); #else error("SWIFT was not compiled with MPI support."); @@ -286,13 +274,11 @@ void engine_addtasks_send_hydro( * @param t_density The send_density #task, if it has already been created. * @param t_prep2 The send_prep2 #task, if it has already been created. * @param t_sf_counts The send_sf_counts, if it has been created. - * @param t_ti The recv_ti_end #task, if it has already been created. * @param with_star_formation Are we running with star formation on? */ void engine_addtasks_send_stars(struct engine *e, struct cell *ci, struct cell *cj, struct task *t_density, struct task *t_prep2, struct task *t_sf_counts, - struct task *t_ti, const int with_star_formation) { #ifdef SWIFT_DEBUG_CHECKS if (e->policy & engine_policy_sinks && e->policy & engine_policy_stars) { @@ -346,9 +332,6 @@ void engine_addtasks_send_stars(struct engine *e, struct cell *ci, ci->mpi.tag, 0, ci, cj); #endif - t_ti = scheduler_addtask(s, task_type_send, task_subtype_tend_spart, - ci->mpi.tag, 0, ci, cj); - #ifdef EXTRA_STAR_LOOPS /* The first send_stars task should unlock prep1 ghost */ scheduler_addunlock(s, t_density, ci->hydro.super->stars.prep1_ghost); @@ -371,9 +354,6 @@ void engine_addtasks_send_stars(struct engine *e, struct cell *ci, /* Drift before first send */ scheduler_addunlock(s, ci->hydro.super->stars.drift, t_density); - /* Send new time-steps after timestep tasks */ - scheduler_addunlock(s, ci->super->timestep, t_ti); - if (with_star_formation && ci->hydro.count > 0) { scheduler_addunlock(s, t_sf_counts, t_density); #ifdef EXTRA_STAR_LOOPS @@ -386,7 +366,6 @@ void engine_addtasks_send_stars(struct engine *e, struct cell *ci, #ifdef EXTRA_STAR_LOOPS engine_addlink(e, &ci->mpi.send, t_prep2); #endif - engine_addlink(e, &ci->mpi.send, t_ti); if (with_star_formation && ci->hydro.count > 0) { engine_addlink(e, &ci->mpi.send, t_sf_counts); } @@ -397,7 +376,7 @@ void engine_addtasks_send_stars(struct engine *e, struct cell *ci, for (int k = 0; k < 8; k++) if (ci->progeny[k] != NULL) engine_addtasks_send_stars(e, ci->progeny[k], cj, t_density, t_prep2, - t_sf_counts, t_ti, with_star_formation); + t_sf_counts, with_star_formation); #else error("SWIFT was not compiled with MPI support."); @@ -415,14 +394,12 @@ void engine_addtasks_send_stars(struct engine *e, struct cell *ci, * @param t_gas_swallow The gas swallow comm. task, if it has already been * created. * @param t_feedback The send_feed #task, if it has already been created. - * @param t_ti The recv_ti_end #task, if it has already been created. */ void engine_addtasks_send_black_holes(struct engine *e, struct cell *ci, struct cell *cj, struct task *t_rho, struct task *t_bh_merger, struct task *t_gas_swallow, - struct task *t_feedback, - struct task *t_ti) { + struct task *t_feedback) { #ifdef WITH_MPI @@ -461,9 +438,6 @@ void engine_addtasks_send_black_holes(struct engine *e, struct cell *ci, scheduler_addtask(s, task_type_send, task_subtype_bpart_feedback, ci->mpi.tag, 0, ci, cj); - t_ti = scheduler_addtask(s, task_type_send, task_subtype_tend_bpart, - ci->mpi.tag, 0, ci, cj); - /* The send_black_holes task should unlock the super_cell's BH exit point * task. */ scheduler_addunlock(s, t_feedback, @@ -487,15 +461,12 @@ void engine_addtasks_send_black_holes(struct engine *e, struct cell *ci, t_gas_swallow); scheduler_addunlock(s, t_gas_swallow, ci->hydro.super->black_holes.swallow_ghost_1); - - scheduler_addunlock(s, ci->super->timestep, t_ti); } engine_addlink(e, &ci->mpi.send, t_rho); engine_addlink(e, &ci->mpi.send, t_bh_merger); engine_addlink(e, &ci->mpi.send, t_gas_swallow); engine_addlink(e, &ci->mpi.send, t_feedback); - engine_addlink(e, &ci->mpi.send, t_ti); } /* Recurse? */ @@ -503,8 +474,8 @@ void engine_addtasks_send_black_holes(struct engine *e, struct cell *ci, for (int k = 0; k < 8; k++) if (ci->progeny[k] != NULL) engine_addtasks_send_black_holes(e, ci->progeny[k], cj, t_rho, - t_bh_merger, t_gas_swallow, t_feedback, - t_ti); + t_bh_merger, t_gas_swallow, + t_feedback); #else error("SWIFT was not compiled with MPI support."); @@ -519,7 +490,6 @@ void engine_addtasks_send_black_holes(struct engine *e, struct cell *ci, * @param t_xv The recv_xv #task, if it has already been created. * @param t_rho The recv_rho #task, if it has already been created. * @param t_gradient The recv_gradient #task, if it has already been created. - * @param t_ti The recv_ti_end #task, if it has already been created. * @param t_prep1 The recv_prep1 #task, if it has already been created. * @param t_limiter The recv_limiter #task, if it has already been created. * @param with_feedback Are we running with stellar feedback? @@ -527,14 +497,11 @@ void engine_addtasks_send_black_holes(struct engine *e, struct cell *ci, * @param with_limiter Are we running with the time-step limiter? * @param with_sync Are we running with time-step synchronization? */ -void engine_addtasks_recv_hydro(struct engine *e, struct cell *c, - struct task *t_xv, struct task *t_rho, - struct task *t_gradient, struct task *t_ti, - struct task *t_prep1, struct task *t_limiter, - struct task *t_unpack_limiter, - const int with_feedback, - const int with_black_holes, - const int with_limiter, const int with_sync) { +void engine_addtasks_recv_hydro( + struct engine *e, struct cell *c, struct task *t_xv, struct task *t_rho, + struct task *t_gradient, struct task *t_prep1, struct task *t_limiter, + struct task *t_unpack_limiter, struct task *tend, const int with_feedback, + const int with_black_holes, const int with_limiter, const int with_sync) { #ifdef WITH_MPI struct scheduler *s = &e->sched; @@ -563,9 +530,6 @@ void engine_addtasks_recv_hydro(struct engine *e, struct cell *c, c->mpi.tag, 0, c, NULL); #endif - t_ti = scheduler_addtask(s, task_type_recv, task_subtype_tend_part, - c->mpi.tag, 0, c, NULL); - if (with_limiter) { t_limiter = scheduler_addtask(s, task_type_recv, task_subtype_limiter, c->mpi.tag, 0, c, NULL); @@ -589,7 +553,6 @@ void engine_addtasks_recv_hydro(struct engine *e, struct cell *c, #ifdef EXTRA_HYDRO_LOOP engine_addlink(e, &c->mpi.recv, t_gradient); #endif - engine_addlink(e, &c->mpi.recv, t_ti); if (with_limiter) { engine_addlink(e, &c->mpi.recv, t_limiter); engine_addlink(e, &c->mpi.unpack, t_unpack_limiter); @@ -615,18 +578,17 @@ void engine_addtasks_recv_hydro(struct engine *e, struct cell *c, } for (struct link *l = c->hydro.force; l != NULL; l = l->next) { scheduler_addunlock(s, t_gradient, l->t); - scheduler_addunlock(s, l->t, t_ti); + scheduler_addunlock(s, l->t, tend); } #else for (struct link *l = c->hydro.force; l != NULL; l = l->next) { scheduler_addunlock(s, t_rho, l->t); - scheduler_addunlock(s, l->t, t_ti); + scheduler_addunlock(s, l->t, tend); } #endif if (with_limiter) { for (struct link *l = c->hydro.limiter; l != NULL; l = l->next) { - scheduler_addunlock(s, t_ti, l->t); scheduler_addunlock(s, t_unpack_limiter, l->t); } } @@ -669,7 +631,7 @@ void engine_addtasks_recv_hydro(struct engine *e, struct cell *c, for (int k = 0; k < 8; k++) if (c->progeny[k] != NULL) engine_addtasks_recv_hydro(e, c->progeny[k], t_xv, t_rho, t_gradient, - t_ti, t_prep1, t_limiter, t_unpack_limiter, + t_prep1, t_limiter, t_unpack_limiter, tend, with_feedback, with_black_holes, with_limiter, with_sync); @@ -686,12 +648,11 @@ void engine_addtasks_recv_hydro(struct engine *e, struct cell *c, * @param t_density The recv_density #task, if it has already been created. * @param t_prep2 The recv_prep2 #task, if it has already been created. * @param t_sf_counts The recv_sf_counts, if it has been created. - * @param t_ti The recv_ti_end #task, if it has already been created. * @param with_star_formation Are we running with star formation on? */ void engine_addtasks_recv_stars(struct engine *e, struct cell *c, struct task *t_density, struct task *t_prep2, - struct task *t_sf_counts, struct task *t_ti, + struct task *t_sf_counts, struct task *tend, const int with_star_formation) { #ifdef SWIFT_DEBUG_CHECKS if (e->policy & engine_policy_sinks && e->policy & engine_policy_stars) { @@ -733,9 +694,6 @@ void engine_addtasks_recv_stars(struct engine *e, struct cell *c, t_prep2 = scheduler_addtask(s, task_type_recv, task_subtype_spart_prep2, c->mpi.tag, 0, c, NULL); #endif - t_ti = scheduler_addtask(s, task_type_recv, task_subtype_tend_spart, - c->mpi.tag, 0, c, NULL); - if (with_star_formation && c->hydro.count > 0) { /* Receive the stars only once the counts have been received */ @@ -752,7 +710,6 @@ void engine_addtasks_recv_stars(struct engine *e, struct cell *c, #ifdef EXTRA_STAR_LOOPS engine_addlink(e, &c->mpi.recv, t_prep2); #endif - engine_addlink(e, &c->mpi.recv, t_ti); if (with_star_formation && c->hydro.count > 0) { engine_addlink(e, &c->mpi.recv, t_sf_counts); } @@ -787,13 +744,13 @@ void engine_addtasks_recv_stars(struct engine *e, struct cell *c, /* Start updating local gas only after sparts have been received */ for (struct link *l = c->stars.feedback; l != NULL; l = l->next) { scheduler_addunlock(s, t_prep2, l->t); - scheduler_addunlock(s, l->t, t_ti); + scheduler_addunlock(s, l->t, tend); } #else /* Start updating local gas only after sparts have been received */ for (struct link *l = c->stars.feedback; l != NULL; l = l->next) { scheduler_addunlock(s, t_density, l->t); - scheduler_addunlock(s, l->t, t_ti); + scheduler_addunlock(s, l->t, tend); } #endif } @@ -803,7 +760,7 @@ void engine_addtasks_recv_stars(struct engine *e, struct cell *c, for (int k = 0; k < 8; k++) if (c->progeny[k] != NULL) engine_addtasks_recv_stars(e, c->progeny[k], t_density, t_prep2, - t_sf_counts, t_ti, with_star_formation); + t_sf_counts, tend, with_star_formation); #else error("SWIFT was not compiled with MPI support."); @@ -820,14 +777,13 @@ void engine_addtasks_recv_stars(struct engine *e, struct cell *c, * @param t_gas_swallow The gas swallow comm. task, if it has already been * created. * @param t_feedback The recv_feed #task, if it has already been created. - * @param t_ti The recv_ti_end #task, if it has already been created. */ void engine_addtasks_recv_black_holes(struct engine *e, struct cell *c, struct task *t_rho, struct task *t_bh_merger, struct task *t_gas_swallow, struct task *t_feedback, - struct task *t_ti) { + struct task *tend) { #ifdef WITH_MPI struct scheduler *s = &e->sched; @@ -855,9 +811,6 @@ void engine_addtasks_recv_black_holes(struct engine *e, struct cell *c, t_feedback = scheduler_addtask( s, task_type_recv, task_subtype_bpart_feedback, c->mpi.tag, 0, c, NULL); - - t_ti = scheduler_addtask(s, task_type_recv, task_subtype_tend_bpart, - c->mpi.tag, 0, c, NULL); } if (t_rho != NULL) { @@ -865,7 +818,6 @@ void engine_addtasks_recv_black_holes(struct engine *e, struct cell *c, engine_addlink(e, &c->mpi.recv, t_bh_merger); engine_addlink(e, &c->mpi.recv, t_gas_swallow); engine_addlink(e, &c->mpi.recv, t_feedback); - engine_addlink(e, &c->mpi.recv, t_ti); #ifdef SWIFT_DEBUG_CHECKS if (c->nodeID == e->nodeID) error("Local cell!"); @@ -895,7 +847,7 @@ void engine_addtasks_recv_black_holes(struct engine *e, struct cell *c, } for (struct link *l = c->black_holes.feedback; l != NULL; l = l->next) { scheduler_addunlock(s, t_feedback, l->t); - scheduler_addunlock(s, l->t, t_ti); + scheduler_addunlock(s, l->t, tend); } } @@ -904,7 +856,7 @@ void engine_addtasks_recv_black_holes(struct engine *e, struct cell *c, for (int k = 0; k < 8; k++) if (c->progeny[k] != NULL) engine_addtasks_recv_black_holes(e, c->progeny[k], t_rho, t_bh_merger, - t_gas_swallow, t_feedback, t_ti); + t_gas_swallow, t_feedback, tend); #else error("SWIFT was not compiled with MPI support."); @@ -917,10 +869,9 @@ void engine_addtasks_recv_black_holes(struct engine *e, struct cell *c, * @param e The #engine. * @param c The foreign #cell. * @param t_grav The recv_gpart #task, if it has already been created. - * @param t_ti The recv_ti_end #task, if it has already been created. */ void engine_addtasks_recv_gravity(struct engine *e, struct cell *c, - struct task *t_grav, struct task *t_ti) { + struct task *t_grav, struct task *tend) { #ifdef WITH_MPI struct scheduler *s = &e->sched; @@ -939,19 +890,15 @@ void engine_addtasks_recv_gravity(struct engine *e, struct cell *c, /* Create the tasks. */ t_grav = scheduler_addtask(s, task_type_recv, task_subtype_gpart, c->mpi.tag, 0, c, NULL); - - t_ti = scheduler_addtask(s, task_type_recv, task_subtype_tend_gpart, - c->mpi.tag, 0, c, NULL); } /* If we have tasks, link them. */ if (t_grav != NULL) { engine_addlink(e, &c->mpi.recv, t_grav); - engine_addlink(e, &c->mpi.recv, t_ti); for (struct link *l = c->grav.grav; l != NULL; l = l->next) { scheduler_addunlock(s, t_grav, l->t); - scheduler_addunlock(s, l->t, t_ti); + scheduler_addunlock(s, l->t, tend); } } @@ -959,7 +906,7 @@ void engine_addtasks_recv_gravity(struct engine *e, struct cell *c, if (c->split) for (int k = 0; k < 8; k++) if (c->progeny[k] != NULL) - engine_addtasks_recv_gravity(e, c->progeny[k], t_grav, t_ti); + engine_addtasks_recv_gravity(e, c->progeny[k], t_grav, tend); #else error("SWIFT was not compiled with MPI support."); @@ -995,6 +942,9 @@ void engine_make_hierarchical_tasks_common(struct engine *e, struct cell *c) { /* Are we at the top-level? */ if (c->top == c && c->nodeID == e->nodeID) { + c->timestep_collect = scheduler_addtask(s, task_type_collect, + task_subtype_none, 0, 0, c, NULL); + if (with_star_formation && c->hydro.count > 0) { c->hydro.star_formation = scheduler_addtask( s, task_type_star_formation, task_subtype_none, 0, 0, c, NULL); @@ -1059,6 +1009,7 @@ void engine_make_hierarchical_tasks_common(struct engine *e, struct cell *c) { scheduler_addunlock(s, kick2_or_csds, c->timestep); scheduler_addunlock(s, c->timestep, c->kick1); + scheduler_addunlock(s, c->timestep, c->top->timestep_collect); /* Subgrid tasks: star formation */ if (with_star_formation && c->hydro.count > 0) { @@ -1082,6 +1033,7 @@ void engine_make_hierarchical_tasks_common(struct engine *e, struct cell *c) { scheduler_addunlock(s, c->timestep, c->timestep_limiter); scheduler_addunlock(s, c->timestep_limiter, c->kick1); + scheduler_addunlock(s, c->timestep_limiter, c->top->timestep_collect); } /* Time-step synchronization */ @@ -1092,6 +1044,7 @@ void engine_make_hierarchical_tasks_common(struct engine *e, struct cell *c) { scheduler_addunlock(s, c->timestep, c->timestep_sync); scheduler_addunlock(s, c->timestep_sync, c->kick1); + scheduler_addunlock(s, c->timestep_sync, c->top->timestep_collect); } if (with_timestep_limiter && with_timestep_sync) { @@ -3982,21 +3935,29 @@ void engine_addtasks_send_mapper(void *map_data, int num_elements, struct cell *cj = cell_type_pairs[k].cj; const int type = cell_type_pairs[k].type; +#ifdef WITH_MPI + /* Add the timestep exchange task */ + struct task *tend = scheduler_addtask( + &e->sched, task_type_send, task_subtype_tend, ci->mpi.tag, 0, ci, cj); + scheduler_addunlock(&e->sched, ci->timestep_collect, tend); + engine_addlink(e, &ci->mpi.send, tend); +#endif + /* Add the send tasks for the cells in the proxy that have a hydro * connection. */ if ((e->policy & engine_policy_hydro) && (type & proxy_cell_type_hydro)) engine_addtasks_send_hydro(e, ci, cj, /*t_xv=*/NULL, /*t_rho=*/NULL, /*t_gradient=*/NULL, - /*t_ti=*/NULL, /*t_prep1=*/NULL, + /*t_prep1=*/NULL, /*t_limiter=*/NULL, /*t_pack_limiter=*/NULL, with_feedback, with_limiter, with_sync); /* Add the send tasks for the cells in the proxy that have a stars * connection. */ if ((e->policy & engine_policy_feedback) && (type & proxy_cell_type_hydro)) - engine_addtasks_send_stars( - e, ci, cj, /*t_density=*/NULL, /*t_prep2=*/NULL, - /*t_sf_counts=*/NULL, /*t_ti=*/NULL, with_star_formation); + engine_addtasks_send_stars(e, ci, cj, /*t_density=*/NULL, + /*t_prep2=*/NULL, + /*t_sf_counts=*/NULL, with_star_formation); /* Add the send tasks for the cells in the proxy that have a black holes * connection. */ @@ -4005,14 +3966,13 @@ void engine_addtasks_send_mapper(void *map_data, int num_elements, engine_addtasks_send_black_holes(e, ci, cj, /*t_rho=*/NULL, /*t_swallow=*/NULL, /*t_gas_swallow=*/NULL, - /*t_feedback=*/NULL, - /*t_ti=*/NULL); + /*t_feedback=*/NULL); /* Add the send tasks for the cells in the proxy that have a gravity * connection. */ if ((e->policy & engine_policy_self_gravity) && (type & proxy_cell_type_gravity)) - engine_addtasks_send_gravity(e, ci, cj, NULL, NULL); + engine_addtasks_send_gravity(e, ci, cj, /*t_grav=*/NULL); } } @@ -4036,22 +3996,30 @@ void engine_addtasks_recv_mapper(void *map_data, int num_elements, for (int k = 0; k < num_elements; k++) { struct cell *ci = cell_type_pairs[k].ci; const int type = cell_type_pairs[k].type; + struct task *tend = NULL; + +#ifdef WITH_MPI + /* Add the timestep exchange task */ + tend = scheduler_addtask(&e->sched, task_type_recv, task_subtype_tend, + ci->mpi.tag, 0, ci, NULL); + engine_addlink(e, &ci->mpi.recv, tend); +#endif /* Add the recv tasks for the cells in the proxy that have a hydro * connection. */ if ((e->policy & engine_policy_hydro) && (type & proxy_cell_type_hydro)) engine_addtasks_recv_hydro(e, ci, /*t_xv=*/NULL, /*t_rho=*/NULL, - /*t_gradient=*/NULL, /*t_ti=*/NULL, + /*t_gradient=*/NULL, /*t_prep1=*/NULL, /*t_limiter=*/NULL, /*t_unpack_limiter=*/NULL, - with_feedback, with_black_holes, with_limiter, - with_sync); + tend, with_feedback, with_black_holes, + with_limiter, with_sync); /* Add the recv tasks for the cells in the proxy that have a stars * connection. */ if ((e->policy & engine_policy_feedback) && (type & proxy_cell_type_hydro)) engine_addtasks_recv_stars(e, ci, /*t_density=*/NULL, /*t_prep2=*/NULL, - /*t_sf_counts=*/NULL, /*t_ti=*/NULL, + /*t_sf_counts=*/NULL, tend, with_star_formation); /* Add the recv tasks for the cells in the proxy that have a black holes @@ -4061,14 +4029,13 @@ void engine_addtasks_recv_mapper(void *map_data, int num_elements, engine_addtasks_recv_black_holes(e, ci, /*t_rho=*/NULL, /*t_swallow=*/NULL, /*t_gas_swallow=*/NULL, - /*t_feedback=*/NULL, - /*t_ti=*/NULL); + /*t_feedback=*/NULL, tend); /* Add the recv tasks for the cells in the proxy that have a gravity * connection. */ if ((e->policy & engine_policy_self_gravity) && (type & proxy_cell_type_gravity)) - engine_addtasks_recv_gravity(e, ci, /*t_grav=*/NULL, /*t_ti=*/NULL); + engine_addtasks_recv_gravity(e, ci, /*t_grav=*/NULL, tend); } } diff --git a/src/engine_marktasks.c b/src/engine_marktasks.c index 258f0e16cae2dbbccbfd6656d41babbfac7bf26e..c1cc4567209b640ae5def59aba769ae174652b6f 100644 --- a/src/engine_marktasks.c +++ b/src/engine_marktasks.c @@ -938,10 +938,6 @@ void engine_marktasks_mapper(void *map_data, int num_elements, scheduler_activate_unpack(s, ci->mpi.unpack, task_subtype_limiter); } - /* If the foreign cell is active, we want its ti_end values. */ - if (ci_active_hydro) - scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_part); - /* Is the foreign cell active and will need stuff from us? */ if (ci_active_hydro) { struct link *l = scheduler_activate_send( @@ -973,23 +969,15 @@ void engine_marktasks_mapper(void *map_data, int num_elements, ci_nodeID); } - /* If the local cell is active, send its ti_end values. */ - if (cj_active_hydro) - scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_part, - ci_nodeID); - /* Propagating new star counts? */ if (with_star_formation_sink) error("TODO"); if (with_star_formation && with_feedback) { if (ci_active_hydro && ci->hydro.count > 0) { scheduler_activate_recv(s, ci->mpi.recv, task_subtype_sf_counts); - scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_spart); } if (cj_active_hydro && cj->hydro.count > 0) { scheduler_activate_send(s, cj->mpi.send, task_subtype_sf_counts, ci_nodeID); - scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart, - ci_nodeID); } } @@ -1014,10 +1002,6 @@ void engine_marktasks_mapper(void *map_data, int num_elements, scheduler_activate_unpack(s, cj->mpi.unpack, task_subtype_limiter); } - /* If the foreign cell is active, we want its ti_end values. */ - if (cj_active_hydro) - scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_part); - /* Is the foreign cell active and will need stuff from us? */ if (cj_active_hydro) { @@ -1051,23 +1035,15 @@ void engine_marktasks_mapper(void *map_data, int num_elements, cj_nodeID); } - /* If the local cell is active, send its ti_end values. */ - if (ci_active_hydro) - scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_part, - cj_nodeID); - /* Propagating new star counts? */ if (with_star_formation_sink) error("TODO"); if (with_star_formation && with_feedback) { if (cj_active_hydro && cj->hydro.count > 0) { scheduler_activate_recv(s, cj->mpi.recv, task_subtype_sf_counts); - scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_spart); } if (ci_active_hydro && ci->hydro.count > 0) { scheduler_activate_send(s, ci->mpi.send, task_subtype_sf_counts, cj_nodeID); - scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart, - cj_nodeID); } } } @@ -1100,10 +1076,6 @@ void engine_marktasks_mapper(void *map_data, int num_elements, ci_nodeID); #endif cell_activate_drift_spart(cj, s); - - /* If the local cell is active, send its ti_end values. */ - scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_spart, - ci_nodeID); } if (ci_active_stars) { @@ -1113,9 +1085,6 @@ void engine_marktasks_mapper(void *map_data, int num_elements, scheduler_activate_recv(s, ci->mpi.recv, task_subtype_spart_prep2); #endif - /* If the foreign cell is active, we want its ti_end values. */ - scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_spart); - /* Is the foreign cell active and will need stuff from us? */ scheduler_activate_send(s, cj->mpi.send, task_subtype_xv, ci_nodeID); @@ -1149,10 +1118,6 @@ void engine_marktasks_mapper(void *map_data, int num_elements, cj_nodeID); #endif cell_activate_drift_spart(ci, s); - - /* If the local cell is active, send its ti_end values. */ - scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_spart, - cj_nodeID); } if (cj_active_stars) { @@ -1162,9 +1127,6 @@ void engine_marktasks_mapper(void *map_data, int num_elements, scheduler_activate_recv(s, cj->mpi.recv, task_subtype_spart_prep2); #endif - /* If the foreign cell is active, we want its ti_end values. */ - scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_spart); - /* Is the foreign cell active and will need stuff from us? */ scheduler_activate_send(s, ci->mpi.send, task_subtype_xv, cj_nodeID); @@ -1225,18 +1187,11 @@ void engine_marktasks_mapper(void *map_data, int num_elements, /* Drift before you send */ cell_activate_drift_bpart(cj, s); - /* Send the new BH time-steps */ - scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_bpart, - ci_nodeID); - /* Receive the foreign BHs to tag particles to swallow and for * feedback */ scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart_rho); scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart_feedback); - /* Receive the foreign BH time-steps */ - scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_bpart); - /* Send the local part information */ scheduler_activate_send(s, cj->mpi.send, task_subtype_rho, ci_nodeID); scheduler_activate_send(s, cj->mpi.send, task_subtype_part_swallow, @@ -1266,18 +1221,11 @@ void engine_marktasks_mapper(void *map_data, int num_elements, /* Drift before you send */ cell_activate_drift_bpart(ci, s); - /* Send the new BH time-steps */ - scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_bpart, - cj_nodeID); - /* Receive the foreign BHs to tag particles to swallow and for * feedback */ scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart_rho); scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart_feedback); - /* Receive the foreign BH time-steps */ - scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_bpart); - /* Send the local part information */ scheduler_activate_send(s, ci->mpi.send, task_subtype_rho, cj_nodeID); scheduler_activate_send(s, ci->mpi.send, task_subtype_part_swallow, @@ -1303,10 +1251,6 @@ void engine_marktasks_mapper(void *map_data, int num_elements, if (cj_active_gravity) scheduler_activate_recv(s, ci->mpi.recv, task_subtype_gpart); - /* If the foreign cell is active, we want its ti_end values. */ - if (ci_active_gravity) - scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_gpart); - /* Is the foreign cell active and will need stuff from us? */ if (ci_active_gravity) { @@ -1319,21 +1263,12 @@ void engine_marktasks_mapper(void *map_data, int num_elements, cell_activate_drift_gpart(l->t->ci, s); } - /* If the local cell is active, send its ti_end values. */ - if (cj_active_gravity) - scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_gpart, - ci_nodeID); - } else if (cj_nodeID != nodeID) { /* If the local cell is active, receive data from the foreign cell. */ if (ci_active_gravity) scheduler_activate_recv(s, cj->mpi.recv, task_subtype_gpart); - /* If the foreign cell is active, we want its ti_end values. */ - if (cj_active_gravity) - scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_gpart); - /* Is the foreign cell active and will need stuff from us? */ if (cj_active_gravity) { @@ -1345,11 +1280,6 @@ void engine_marktasks_mapper(void *map_data, int num_elements, itself. */ cell_activate_drift_gpart(l->t->ci, s); } - - /* If the local cell is active, send its ti_end values. */ - if (ci_active_gravity) - scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_gpart, - cj_nodeID); } #endif } /* Only interested in RT tasks as of here. */ @@ -1471,8 +1401,8 @@ void engine_marktasks_mapper(void *map_data, int num_elements, if (cell_is_active_black_holes(t->ci, e)) scheduler_activate(s, t); } - /* Time-step? */ - else if (t_type == task_type_timestep) { + /* Time-step or time-step collection? */ + else if (t_type == task_type_timestep || t_type == task_type_collect) { t->ci->hydro.updated = 0; t->ci->grav.updated = 0; t->ci->stars.updated = 0; @@ -1484,6 +1414,11 @@ void engine_marktasks_mapper(void *map_data, int num_elements, scheduler_activate(s, t); } + else if ((t_type == task_type_send && t_subtype == task_subtype_tend) || + (t_type == task_type_recv && t_subtype == task_subtype_tend)) { + scheduler_activate(s, t); + } + /* Subgrid tasks: cooling */ else if (t_type == task_type_cooling || t_type == task_type_cooling_in || t_type == task_type_cooling_out) { diff --git a/src/engine_unskip.c b/src/engine_unskip.c index 37b4e224b29a14f008ed5b8e66f582701955abff..eb81c2ad42fb03b970054b2b4112fde79e4f907c 100644 --- a/src/engine_unskip.c +++ b/src/engine_unskip.c @@ -423,6 +423,12 @@ void engine_unskip(struct engine *e) { memswap(&local_cells[k], &local_cells[num_active_cells], sizeof(int)); num_active_cells += 1; } + + /* Activate the top-level timestep exchange */ +#ifdef WITH_MPI + scheduler_activate_all_subtype(&e->sched, c->mpi.send, task_subtype_tend); + scheduler_activate_all_subtype(&e->sched, c->mpi.recv, task_subtype_tend); +#endif } /* What kind of tasks do we have? */ @@ -502,60 +508,3 @@ void engine_unskip(struct engine *e) { message("took %.3f %s.", clocks_from_ticks(getticks() - tic), clocks_getunit()); } - -void engine_unskip_timestep_communications_mapper(void *map_data, - int num_elements, - void *extra_data) { - /* Unpack the data */ - struct scheduler *s = (struct scheduler *)extra_data; - struct task *const tasks = (struct task *)map_data; - const int nr_tasks = num_elements; - - /* Unskip the tasks in this part of the array */ - for (int i = 0; i < nr_tasks; ++i) { - - struct task *const t = &tasks[i]; - - if (t->type == task_type_send || t->type == task_type_recv) { - - if (t->subtype == task_subtype_tend_part || - t->subtype == task_subtype_tend_gpart) { - - scheduler_activate(s, t); - } - } - } -} - -/** - * @brief Blindly unskips all the tend communications for #part and #gpart. - * - * This function is only necessary when running with the time-step limiter - * or the time-step synchronization policy as the time-steps of inactive - * sections of the tree might have been changed by these tasks. - * - * @param e The #engine. - */ -void engine_unskip_timestep_communications(struct engine *e) { - -#ifdef WITH_MPI - - const ticks tic = getticks(); - - struct scheduler *s = &e->sched; - struct task *tasks = e->sched.tasks; - const int nr_tasks = e->sched.nr_tasks; - - /* Activate all the part and gpart ti_end tasks */ - threadpool_map(&e->threadpool, engine_unskip_timestep_communications_mapper, - tasks, nr_tasks, sizeof(struct task), - threadpool_auto_chunk_size, s); - - if (e->verbose) - message("took %.3f %s.", clocks_from_ticks(getticks() - tic), - clocks_getunit()); - -#else - error("SWIFT was not compiled with MPI support."); -#endif -} diff --git a/src/runner.h b/src/runner.h index 14bc25697b4e7ba06ae172975c2e4d2c2aa5b1a9..6f9bbe582438704153b770dad6628a8d3283808f 100644 --- a/src/runner.h +++ b/src/runner.h @@ -114,6 +114,7 @@ void runner_do_drift_bpart(struct runner *r, struct cell *c, int timer); void runner_do_kick1(struct runner *r, struct cell *c, int timer); void runner_do_kick2(struct runner *r, struct cell *c, int timer); void runner_do_timestep(struct runner *r, struct cell *c, int timer); +void runner_do_timestep_collect(struct runner *r, struct cell *c, int timer); void runner_do_end_hydro_force(struct runner *r, struct cell *c, int timer); void runner_do_end_grav_force(struct runner *r, struct cell *c, int timer); void runner_do_init(struct runner *r, struct cell *c, int timer); diff --git a/src/runner_main.c b/src/runner_main.c index 765f2ae5b0be11e54fd4557a215983df3ed72f45..52f5629c6bd9df8a6307174ede7666ad987c5cf9 100644 --- a/src/runner_main.c +++ b/src/runner_main.c @@ -507,15 +507,12 @@ void *runner_main(void *data) { case task_type_timestep_sync: runner_do_sync(r, ci, 0, 1); break; + case task_type_collect: + runner_do_timestep_collect(r, ci, 1); + break; #ifdef WITH_MPI case task_type_send: - if (t->subtype == task_subtype_tend_part) { - free(t->buff); - } else if (t->subtype == task_subtype_tend_gpart) { - free(t->buff); - } else if (t->subtype == task_subtype_tend_spart) { - free(t->buff); - } else if (t->subtype == task_subtype_tend_bpart) { + if (t->subtype == task_subtype_tend) { free(t->buff); } else if (t->subtype == task_subtype_sf_counts) { free(t->buff); @@ -528,18 +525,8 @@ void *runner_main(void *data) { } break; case task_type_recv: - if (t->subtype == task_subtype_tend_part) { - cell_unpack_end_step_hydro(ci, (struct pcell_step_hydro *)t->buff); - free(t->buff); - } else if (t->subtype == task_subtype_tend_gpart) { - cell_unpack_end_step_grav(ci, (struct pcell_step_grav *)t->buff); - free(t->buff); - } else if (t->subtype == task_subtype_tend_spart) { - cell_unpack_end_step_stars(ci, (struct pcell_step_stars *)t->buff); - free(t->buff); - } else if (t->subtype == task_subtype_tend_bpart) { - cell_unpack_end_step_black_holes( - ci, (struct pcell_step_black_holes *)t->buff); + if (t->subtype == task_subtype_tend) { + cell_unpack_end_step(ci, (struct pcell_step *)t->buff); free(t->buff); } else if (t->subtype == task_subtype_sf_counts) { cell_unpack_sf_counts(ci, (struct pcell_sf *)t->buff); diff --git a/src/runner_time_integration.c b/src/runner_time_integration.c index cfc918eb1deb066b0ff605132b46f9d2a881dbb9..e37a9a4cf28725046ae359f80185bc0c425f8f8c 100644 --- a/src/runner_time_integration.c +++ b/src/runner_time_integration.c @@ -1097,6 +1097,82 @@ void runner_do_timestep(struct runner *r, struct cell *c, const int timer) { if (timer) TIMER_TOC(timer_timestep); } +void runner_do_timestep_collect(struct runner *r, struct cell *c, + const int timer) { + + /* Early stop if we are at the super level. + * The time-step task would have set things at this level already */ + if (c->super == c) return; + + /* Counters for the different quantities. */ + size_t h_updated = 0; + size_t g_updated = 0; + size_t s_updated = 0; + size_t b_updated = 0; + size_t si_updated = 0; + integertime_t ti_hydro_end_min = max_nr_timesteps, ti_hydro_beg_max = 0; + integertime_t ti_grav_end_min = max_nr_timesteps, ti_grav_beg_max = 0; + integertime_t ti_stars_end_min = max_nr_timesteps, ti_stars_beg_max = 0; + integertime_t ti_black_holes_end_min = max_nr_timesteps, + ti_black_holes_beg_max = 0; + integertime_t ti_sinks_end_min = max_nr_timesteps, ti_sinks_beg_max = 0; + + /* Collect the values from the progeny. */ + for (int k = 0; k < 8; k++) { + struct cell *cp = c->progeny[k]; + if (cp != NULL) { + + /* Recurse */ + runner_do_timestep_collect(r, c, 0); + + /* And update */ + ti_hydro_end_min = min(ti_hydro_end_min, cp->hydro.ti_end_min); + ti_hydro_beg_max = max(ti_hydro_beg_max, cp->hydro.ti_beg_max); + ti_grav_end_min = min(ti_grav_end_min, cp->grav.ti_end_min); + ti_grav_beg_max = max(ti_grav_beg_max, cp->grav.ti_beg_max); + ti_stars_end_min = min(ti_stars_end_min, cp->stars.ti_end_min); + ti_stars_beg_max = max(ti_stars_beg_max, cp->stars.ti_beg_max); + ti_black_holes_end_min = + min(ti_black_holes_end_min, cp->black_holes.ti_end_min); + ti_black_holes_beg_max = + max(ti_black_holes_beg_max, cp->black_holes.ti_beg_max); + ti_sinks_end_min = min(ti_sinks_end_min, cp->sinks.ti_end_min); + ti_sinks_beg_max = max(ti_sinks_beg_max, cp->sinks.ti_beg_max); + + h_updated += cp->hydro.updated; + g_updated += cp->grav.updated; + s_updated += cp->stars.updated; + b_updated += cp->black_holes.updated; + si_updated += cp->sinks.updated; + + /* Collected, so clear for next time. */ + cp->hydro.updated = 0; + cp->grav.updated = 0; + cp->stars.updated = 0; + cp->black_holes.updated = 0; + cp->sinks.updated = 0; + } + } + + /* Store the collected values in the cell. */ + c->hydro.ti_end_min = ti_hydro_end_min; + c->hydro.ti_beg_max = ti_hydro_beg_max; + c->grav.ti_end_min = ti_grav_end_min; + c->grav.ti_beg_max = ti_grav_beg_max; + c->stars.ti_end_min = ti_stars_end_min; + c->stars.ti_beg_max = ti_stars_beg_max; + c->black_holes.ti_end_min = ti_black_holes_end_min; + c->black_holes.ti_beg_max = ti_black_holes_beg_max; + c->sinks.ti_end_min = ti_sinks_end_min; + c->sinks.ti_beg_max = ti_sinks_beg_max; + + c->hydro.updated = h_updated; + c->grav.updated = g_updated; + c->stars.updated = s_updated; + c->black_holes.updated = b_updated; + c->sinks.updated = si_updated; +} + /** * @brief Apply the time-step limiter to all awaken particles in a cell * hierarchy. diff --git a/src/scheduler.c b/src/scheduler.c index cddc5f12ebec7b81eaa0f70875e93696adfc2dbb..bb93cd40cece2541ece1d7102c47d4f5aa2e4437 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -2042,27 +2042,9 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) { MPI_Datatype type = MPI_BYTE; /* Type of the elements */ void *buff = NULL; /* Buffer to accept elements */ - if (t->subtype == task_subtype_tend_part) { + if (t->subtype == task_subtype_tend) { - count = size = - t->ci->mpi.pcell_size * sizeof(struct pcell_step_hydro); - buff = t->buff = malloc(count); - - } else if (t->subtype == task_subtype_tend_gpart) { - - count = size = t->ci->mpi.pcell_size * sizeof(struct pcell_step_grav); - buff = t->buff = malloc(count); - - } else if (t->subtype == task_subtype_tend_spart) { - - count = size = - t->ci->mpi.pcell_size * sizeof(struct pcell_step_stars); - buff = t->buff = malloc(count); - - } else if (t->subtype == task_subtype_tend_bpart) { - - count = size = - t->ci->mpi.pcell_size * sizeof(struct pcell_step_black_holes); + count = size = t->ci->mpi.pcell_size * sizeof(struct pcell_step); buff = t->buff = malloc(count); } else if (t->subtype == task_subtype_part_swallow) { @@ -2160,33 +2142,11 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) { MPI_Datatype type = MPI_BYTE; /* Type of the elements */ void *buff = NULL; /* Buffer to send */ - if (t->subtype == task_subtype_tend_part) { + if (t->subtype == task_subtype_tend) { - size = count = - t->ci->mpi.pcell_size * sizeof(struct pcell_step_hydro); - buff = t->buff = malloc(size); - cell_pack_end_step_hydro(t->ci, (struct pcell_step_hydro *)buff); - - } else if (t->subtype == task_subtype_tend_gpart) { - - size = count = t->ci->mpi.pcell_size * sizeof(struct pcell_step_grav); - buff = t->buff = malloc(size); - cell_pack_end_step_grav(t->ci, (struct pcell_step_grav *)buff); - - } else if (t->subtype == task_subtype_tend_spart) { - - size = count = - t->ci->mpi.pcell_size * sizeof(struct pcell_step_stars); - buff = t->buff = malloc(size); - cell_pack_end_step_stars(t->ci, (struct pcell_step_stars *)buff); - - } else if (t->subtype == task_subtype_tend_bpart) { - - size = count = - t->ci->mpi.pcell_size * sizeof(struct pcell_step_black_holes); + size = count = t->ci->mpi.pcell_size * sizeof(struct pcell_step); buff = t->buff = malloc(size); - cell_pack_end_step_black_holes(t->ci, - (struct pcell_step_black_holes *)buff); + cell_pack_end_step(t->ci, (struct pcell_step *)buff); } else if (t->subtype == task_subtype_part_swallow) { diff --git a/src/scheduler.h b/src/scheduler.h index f55f95a0bba292fd5125cbcd39c146bfb5586739..c7c9b1412458f49950087f695705e22bfd1b9582 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -143,6 +143,24 @@ __attribute__((always_inline)) INLINE static void scheduler_activate( } } +/** + * @brief Search a given linked list of task for a given subtype and activate + * it. + * + * @param s The #scheduler. + * @param link The first element in the linked list of links for the task of + * interest. + * @param subtype the task subtype to activate. + */ +__attribute__((always_inline)) INLINE static void +scheduler_activate_all_subtype(struct scheduler *s, struct link *link, + const enum task_subtypes subtype) { + + for (struct link *l = link; l != NULL; l = l->next) { + if (l->t->subtype == subtype) scheduler_activate(s, l->t); + } +} + /** * @brief Search and add an MPI send task to the list of active tasks. * @@ -156,7 +174,7 @@ __attribute__((always_inline)) INLINE static void scheduler_activate( */ __attribute__((always_inline)) INLINE static struct link * scheduler_activate_send(struct scheduler *s, struct link *link, - enum task_subtypes subtype, int nodeID) { + const enum task_subtypes subtype, const int nodeID) { struct link *l = NULL; for (l = link; l != NULL && !(l->t->cj->nodeID == nodeID && l->t->subtype == subtype); @@ -181,7 +199,7 @@ scheduler_activate_send(struct scheduler *s, struct link *link, */ __attribute__((always_inline)) INLINE static struct link * scheduler_activate_recv(struct scheduler *s, struct link *link, - enum task_subtypes subtype) { + const enum task_subtypes subtype) { struct link *l = NULL; for (l = link; l != NULL && l->t->subtype != subtype; l = l->next) ; diff --git a/src/space_recycle.c b/src/space_recycle.c index f3781167f290a09d43019e5d261b4507a3133cfc..5a0d74a5fb1c5490bc82793944e4cd8a34457162 100644 --- a/src/space_recycle.c +++ b/src/space_recycle.c @@ -158,6 +158,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->timestep = NULL; c->timestep_limiter = NULL; c->timestep_sync = NULL; + c->timestep_collect = NULL; c->hydro.end_force = NULL; c->hydro.drift = NULL; c->sinks.drift = NULL; diff --git a/src/task.c b/src/task.c index 12080542cf5e9d785a5107c40bb4928245986237..650a7f43a0a21869a7794fb867db4e764364d0bd 100644 --- a/src/task.c +++ b/src/task.c @@ -74,6 +74,7 @@ const char *taskID_names[task_type_count] = { "timestep", "timestep_limiter", "timestep_sync", + "collect", "send", "recv", "pack", @@ -131,11 +132,7 @@ const char *subtaskID_names[task_subtype_count] = { "limiter", "grav", "external_grav", - "tend_part", - "tend_gpart", - "tend_spart", - "tend_sink", - "tend_bpart", + "tend", "xv", "rho", "part_swallow", @@ -1777,6 +1774,7 @@ enum task_categories task_get_category(const struct task *t) { case task_type_kick1: case task_type_kick2: case task_type_timestep: + case task_type_collect: return task_category_time_integration; case task_type_timestep_limiter: diff --git a/src/task.h b/src/task.h index f579f152ee032e621c21b6f0778ce5013a7bd875..2725696f71dea423db2c303297015f62767515df 100644 --- a/src/task.h +++ b/src/task.h @@ -67,6 +67,7 @@ enum task_types { task_type_timestep, task_type_timestep_limiter, task_type_timestep_sync, + task_type_collect, task_type_send, task_type_recv, task_type_pack, @@ -127,11 +128,7 @@ enum task_subtypes { task_subtype_limiter, task_subtype_grav, task_subtype_external_grav, - task_subtype_tend_part, - task_subtype_tend_gpart, - task_subtype_tend_spart, - task_subtype_tend_sink, - task_subtype_tend_bpart, + task_subtype_tend, task_subtype_xv, task_subtype_rho, task_subtype_part_swallow, diff --git a/tools/task_plots/swift_hardcoded_data.py b/tools/task_plots/swift_hardcoded_data.py index 6f31bacf4d4a1e24299e20b591a7afd8ee32331c..8beb97e07a95c3f1367a62f2f51df01ac45aac72 100644 --- a/tools/task_plots/swift_hardcoded_data.py +++ b/tools/task_plots/swift_hardcoded_data.py @@ -34,6 +34,7 @@ TASKTYPES = [ "timestep", "timestep_limiter", "timestep_sync", + "collect", "send", "recv", "pack", @@ -89,11 +90,7 @@ SUBTYPES = [ "limiter", "grav", "external_grav", - "tend_part", - "tend_gpart", - "tend_spart", - "tend_sink", - "tend_bpart", + "tend", "xv", "rho", "part_swallow",