diff --git a/src/cell.c b/src/cell.c index 900389f7f59e5de8ff7f842b2949c4b020c71e5d..6807e2da3721ddf317d0f9371ed18fd06860a9db 100644 --- a/src/cell.c +++ b/src/cell.c @@ -2017,48 +2017,6 @@ void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj, } /* Otherwise, pair interation */ } -/** - * @brief Drift the multipoles that will be used in a M-M task. - * - * @param ci The first #cell we update. - * @param cj The second #cell we update. - * @param s The task #scheduler. - */ -void cell_activate_grav_mm_task(struct cell *ci, struct cell *cj, - struct scheduler *s) { - /* Some constants */ - const struct engine *e = s->space->e; - // const integertime_t ti_current = e->ti_current; - - /* Anything to do here? */ - if (!cell_is_active_gravity_mm(ci, e) && !cell_is_active_gravity_mm(cj, e)) - error("Inactive MM task being activated"); - - /* /\* Atomically drift the multipoles in the progenies of ci *\/ */ - /* for (int i = 0; i < 8; i++) { */ - /* struct cell *cpi = ci->progeny[i]; */ - /* if (cpi != NULL) { */ - /* lock_lock(&cpi->mlock); */ - /* if (cpi->ti_old_multipole < ti_current) cell_drift_multipole(cpi, e); - */ - /* if (lock_unlock(&cpi->mlock) != 0) error("Impossible to unlock - * m-pole"); */ - /* } */ - /* } */ - - /* /\* Atomically drift the multipoles in the progenies of cj *\/ */ - /* for (int j = 0; j < 8; j++) { */ - /* struct cell *cpj = cj->progeny[j]; */ - /* if (cpj != NULL) { */ - /* lock_lock(&cpj->mlock); */ - /* if (cpj->ti_old_multipole < ti_current) cell_drift_multipole(cpj, e); - */ - /* if (lock_unlock(&cpj->mlock) != 0) error("Impossible to unlock - * m-pole"); */ - /* } */ - /* } */ -} - /** * @brief Traverse a sub-cell task and activate the gravity drift tasks that * are required by a self gravity task. @@ -2523,9 +2481,6 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { (cj_active && cj_nodeID == nodeID)) { scheduler_activate(s, t); - - /* Drift the multipoles */ - cell_activate_grav_mm_task(ci, cj, s); } } diff --git a/src/runner.c b/src/runner.c index fc22bd8014edc49612a50fc4ee84d948eaff2205..259343b34008f852fbafd35909d888d28daf7fc1 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2273,7 +2273,7 @@ void *runner_main(void *data) { runner_do_grav_long_range(r, t->ci, 1); break; case task_type_grav_mm: - runner_dopair_grav_mm_progenies(r, t->ci, t->cj); + runner_dopair_grav_mm_progenies(r, t->flags, t->ci, t->cj); break; case task_type_cooling: runner_do_cooling(r, t->ci, 1); diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index ed8f935872496adc538a0bde9cca9c3db10070bf..26e3cfdca0dc37449c90e1c85fa9fb0597ff68a8 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -1308,13 +1308,21 @@ static INLINE void runner_dopair_grav_mm(struct runner *r, runner_dopair_grav_mm_nonsym(r, cj, ci); } +/** + * @brief Computes all the M-M interactions between all the well-separated (at + * rebuild) pairs of progenies of the two cells. + * + * @param r The #runner thread. + * @param flags The task flag containing the list of well-separated pairs as a + * bit-field. + * @param ci The first #cell. + * @param cj The second #cell. + */ static INLINE void runner_dopair_grav_mm_progenies(struct runner *r, + const long long flags, struct cell *restrict ci, struct cell *restrict cj) { - const struct engine *e = r->e; - const struct space *s = e->s; - /* Loop over all pairs of progenies */ for (int i = 0; i < 8; i++) { if (ci->progeny[i] != NULL) { @@ -1324,11 +1332,10 @@ static INLINE void runner_dopair_grav_mm_progenies(struct runner *r, struct cell *cpi = ci->progeny[i]; struct cell *cpj = cj->progeny[j]; - /* Did we agree to use an M-M interaction here at the last rebuild? */ - if (cell_can_use_pair_mm_rebuild(cpi, cpj, e, s)) { + const int flag = i * 8 + j; - runner_dopair_grav_mm(r, cpi, cpj); - } + /* Did we agree to use an M-M interaction here at the last rebuild? */ + if (flags & (1LL << flag)) runner_dopair_grav_mm(r, cpi, cpj); } } } diff --git a/src/scheduler.c b/src/scheduler.c index a5da777f45f8075c7c577988eaa5dfbd7d1ca5ed..c0e4175ebd398c8e3a475216bfa73240ff001115 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -906,6 +906,7 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) { * progeny pairs */ t->type = task_type_grav_mm; t->subtype = task_subtype_none; + t->flags = 0; /* Make a task for every other pair of progeny */ for (int i = 0; i < 8; i++) { @@ -913,11 +914,22 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) { for (int j = 0; j < 8; j++) { if (cj->progeny[j] != NULL) { - /* But only for pairs that cannot be replaced by a M-M - * interaction */ - if (!cell_can_use_pair_mm_rebuild(ci->progeny[i], - cj->progeny[j], e, sp)) { + /* Can we use a M-M interaction here? */ + if (cell_can_use_pair_mm_rebuild(ci->progeny[i], + cj->progeny[j], e, sp)) { + /* Flag this pair as being treated by the M-M task */ + /* We use the 64 bits in the task->flags field to store */ + /* this information. The corresponding taks will unpack the + */ + /* information and operate according to the choices made + * here. */ + const int flag = i * 8 + j; + t->flags |= (1LL << flag); + + } else { + + /* Ok, we actually have to create a task */ scheduler_splittask_gravity( scheduler_addtask(s, task_type_pair, task_subtype_grav, 0, 0, ci->progeny[i], cj->progeny[j]), @@ -927,6 +939,16 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) { } } } + + /* Can none of the progenies use M-M calculations? */ + if (t->flags == 0) { + t->type = task_type_none; + t->subtype = task_subtype_none; + t->ci = NULL; + t->cj = NULL; + t->skip = 1; + } + } /* Split the pair */ } } /* pair interaction? */ diff --git a/src/task.c b/src/task.c index 10f2ddf5cec885ec23c4f65db5cdea50f0e5097b..018a09b5c74f8dc72093f411d24e31abd767b3d0 100644 --- a/src/task.c +++ b/src/task.c @@ -366,7 +366,7 @@ int task_lock(struct task *t) { char buff[MPI_MAX_ERROR_STRING]; int len; MPI_Error_string(err, buff, &len); - error("Failed to test request on send/recv task (tag=%i, %s).", + error("Failed to test request on send/recv task (tag=%lld, %s).", t->flags, buff); } return res; diff --git a/src/task.h b/src/task.h index 58ea3a8cbb93b38b47ab7b6a243c3ee6c85d40b7..b66fe87d353bab589ab4023e749e17f62f16d3af 100644 --- a/src/task.h +++ b/src/task.h @@ -128,6 +128,9 @@ struct task { /*! List of tasks unlocked by this one */ struct task **unlock_tasks; + /*! Flags used to carry additional information (e.g. sort directions) */ + long long flags; + #ifdef WITH_MPI /*! Buffer for this task's communications */ @@ -138,9 +141,6 @@ struct task { #endif - /*! Flags used to carry additional information (e.g. sort directions) */ - int flags; - /*! Rank of a task in the order */ int rank;