Commit bd44fc03 authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Make sure all hierarchical task timers are updated even when recursing in daughter cells

parent ae123a6e
...@@ -132,16 +132,16 @@ void runner_do_sourceterms(struct runner *r, struct cell *c, int timer) { ...@@ -132,16 +132,16 @@ void runner_do_sourceterms(struct runner *r, struct cell *c, int timer) {
if (c->split) { if (c->split) {
for (int k = 0; k < 8; k++) for (int k = 0; k < 8; k++)
if (c->progeny[k] != NULL) runner_do_sourceterms(r, c->progeny[k], 0); if (c->progeny[k] != NULL) runner_do_sourceterms(r, c->progeny[k], 0);
return; } else {
}
if (count > 0) { if (count > 0) {
/* do sourceterms in this cell? */ /* do sourceterms in this cell? */
const int incell = const int incell =
sourceterms_test_cell(cell_min, cell_width, sourceterms, dimen); sourceterms_test_cell(cell_min, cell_width, sourceterms, dimen);
if (incell == 1) { if (incell == 1) {
sourceterms_apply(r, sourceterms, c); sourceterms_apply(r, sourceterms, c);
}
} }
} }
...@@ -173,23 +173,23 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) { ...@@ -173,23 +173,23 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) {
if (c->split) { if (c->split) {
for (int k = 0; k < 8; k++) for (int k = 0; k < 8; k++)
if (c->progeny[k] != NULL) runner_do_grav_external(r, c->progeny[k], 0); if (c->progeny[k] != NULL) runner_do_grav_external(r, c->progeny[k], 0);
return; } else {
}
#ifdef TASK_VERBOSE #ifdef TASK_VERBOSE
OUT; OUT;
#endif #endif
/* Loop over the gparts in this cell. */ /* Loop over the gparts in this cell. */
for (int i = 0; i < gcount; i++) { for (int i = 0; i < gcount; i++) {
/* Get a direct pointer on the part. */ /* Get a direct pointer on the part. */
struct gpart *restrict gp = &gparts[i]; struct gpart *restrict gp = &gparts[i];
/* Is this part within the time step? */ /* Is this part within the time step? */
if (gp->ti_end <= ti_current) { if (gp->ti_end <= ti_current) {
external_gravity_acceleration(time, potential, constants, gp); external_gravity_acceleration(time, potential, constants, gp);
}
} }
} }
...@@ -221,26 +221,26 @@ void runner_do_cooling(struct runner *r, struct cell *c, int timer) { ...@@ -221,26 +221,26 @@ void runner_do_cooling(struct runner *r, struct cell *c, int timer) {
if (c->split) { if (c->split) {
for (int k = 0; k < 8; k++) for (int k = 0; k < 8; k++)
if (c->progeny[k] != NULL) runner_do_cooling(r, c->progeny[k], 0); if (c->progeny[k] != NULL) runner_do_cooling(r, c->progeny[k], 0);
return; } else {
}
#ifdef TASK_VERBOSE #ifdef TASK_VERBOSE
OUT; OUT;
#endif #endif
/* Loop over the parts in this cell. */ /* Loop over the parts in this cell. */
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
/* Get a direct pointer on the part. */ /* Get a direct pointer on the part. */
struct part *restrict p = &parts[i]; struct part *restrict p = &parts[i];
struct xpart *restrict xp = &xparts[i]; struct xpart *restrict xp = &xparts[i];
/* Kick has already updated ti_end, so need to check ti_begin */ /* Kick has already updated ti_end, so need to check ti_begin */
if (p->ti_begin == ti_current) { if (p->ti_begin == ti_current) {
const double dt = (p->ti_end - p->ti_begin) * timeBase; const double dt = (p->ti_end - p->ti_begin) * timeBase;
cooling_cool_part(constants, us, cooling_func, p, xp, dt); cooling_cool_part(constants, us, cooling_func, p, xp, dt);
}
} }
} }
...@@ -503,7 +503,6 @@ void runner_do_init(struct runner *r, struct cell *c, int timer) { ...@@ -503,7 +503,6 @@ void runner_do_init(struct runner *r, struct cell *c, int timer) {
if (c->split) { if (c->split) {
for (int k = 0; k < 8; k++) for (int k = 0; k < 8; k++)
if (c->progeny[k] != NULL) runner_do_init(r, c->progeny[k], 0); if (c->progeny[k] != NULL) runner_do_init(r, c->progeny[k], 0);
return;
} else { } else {
/* Loop over the parts in this cell. */ /* Loop over the parts in this cell. */
...@@ -542,8 +541,9 @@ void runner_do_init(struct runner *r, struct cell *c, int timer) { ...@@ -542,8 +541,9 @@ void runner_do_init(struct runner *r, struct cell *c, int timer) {
* *
* @param r The runner thread. * @param r The runner thread.
* @param c The cell. * @param c The cell.
* @param timer Are we timing this ?
*/ */
void runner_do_extra_ghost(struct runner *r, struct cell *c) { void runner_do_extra_ghost(struct runner *r, struct cell *c, int timer) {
#ifdef EXTRA_HYDRO_LOOP #ifdef EXTRA_HYDRO_LOOP
...@@ -551,14 +551,15 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c) { ...@@ -551,14 +551,15 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c) {
const int count = c->count; const int count = c->count;
const int ti_current = r->e->ti_current; const int ti_current = r->e->ti_current;
TIMER_TIC;
/* Anything to do here? */ /* Anything to do here? */
if (c->ti_end_min > ti_current) return; if (c->ti_end_min > ti_current) return;
/* Recurse? */ /* Recurse? */
if (c->split) { if (c->split) {
for (int k = 0; k < 8; k++) for (int k = 0; k < 8; k++)
if (c->progeny[k] != NULL) runner_do_extra_ghost(r, c->progeny[k]); if (c->progeny[k] != NULL) runner_do_extra_ghost(r, c->progeny[k], 0);
return;
} else { } else {
/* Loop over the parts in this cell. */ /* Loop over the parts in this cell. */
...@@ -575,6 +576,8 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c) { ...@@ -575,6 +576,8 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c) {
} }
} }
if (timer) TIMER_TOC(timer_do_extra_ghost);
#else #else
error("SWIFT was not compiled with the extra hydro loop activated."); error("SWIFT was not compiled with the extra hydro loop activated.");
#endif #endif
...@@ -586,8 +589,9 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c) { ...@@ -586,8 +589,9 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c) {
* *
* @param r The runner thread. * @param r The runner thread.
* @param c The cell. * @param c The cell.
* @param timer Are we timing this ?
*/ */
void runner_do_ghost(struct runner *r, struct cell *c) { void runner_do_ghost(struct runner *r, struct cell *c, int timer) {
struct part *restrict parts = c->parts; struct part *restrict parts = c->parts;
struct xpart *restrict xparts = c->xparts; struct xpart *restrict xparts = c->xparts;
...@@ -610,140 +614,141 @@ void runner_do_ghost(struct runner *r, struct cell *c) { ...@@ -610,140 +614,141 @@ void runner_do_ghost(struct runner *r, struct cell *c) {
/* Recurse? */ /* Recurse? */
if (c->split) { if (c->split) {
for (int k = 0; k < 8; k++) for (int k = 0; k < 8; k++)
if (c->progeny[k] != NULL) runner_do_ghost(r, c->progeny[k]); if (c->progeny[k] != NULL) runner_do_ghost(r, c->progeny[k], 0);
return; } else {
}
/* Init the IDs that have to be updated. */ /* Init the IDs that have to be updated. */
int *pid = NULL; int *pid = NULL;
if ((pid = malloc(sizeof(int) * count)) == NULL) if ((pid = malloc(sizeof(int) * count)) == NULL)
error("Can't allocate memory for pid."); error("Can't allocate memory for pid.");
for (int k = 0; k < count; k++) pid[k] = k; for (int k = 0; k < count; k++) pid[k] = k;
/* While there are particles that need to be updated... */ /* While there are particles that need to be updated... */
for (int num_reruns = 0; count > 0 && num_reruns < max_smoothing_iter; for (int num_reruns = 0; count > 0 && num_reruns < max_smoothing_iter;
num_reruns++) { num_reruns++) {
/* Reset the redo-count. */ /* Reset the redo-count. */
redo = 0; redo = 0;
/* Loop over the parts in this cell. */ /* Loop over the parts in this cell. */
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
/* Get a direct pointer on the part. */ /* Get a direct pointer on the part. */
struct part *restrict p = &parts[pid[i]]; struct part *restrict p = &parts[pid[i]];
struct xpart *restrict xp = &xparts[pid[i]]; struct xpart *restrict xp = &xparts[pid[i]];
/* Is this part within the timestep? */ /* Is this part within the timestep? */
if (p->ti_end <= ti_current) { if (p->ti_end <= ti_current) {
/* Finish the density calculation */ /* Finish the density calculation */
hydro_end_density(p, ti_current); hydro_end_density(p, ti_current);
float h_corr = 0.f; float h_corr = 0.f;
/* If no derivative, double the smoothing length. */ /* If no derivative, double the smoothing length. */
if (p->density.wcount_dh == 0.0f) h_corr = p->h; if (p->density.wcount_dh == 0.0f) h_corr = p->h;
/* Otherwise, compute the smoothing length update (Newton step). */ /* Otherwise, compute the smoothing length update (Newton step). */
else { else {
h_corr = (target_wcount - p->density.wcount) / p->density.wcount_dh; h_corr = (target_wcount - p->density.wcount) / p->density.wcount_dh;
/* Truncate to the range [ -p->h/2 , p->h ]. */ /* Truncate to the range [ -p->h/2 , p->h ]. */
h_corr = (h_corr < p->h) ? h_corr : p->h; h_corr = (h_corr < p->h) ? h_corr : p->h;
h_corr = (h_corr > -0.5f * p->h) ? h_corr : -0.5f * p->h; h_corr = (h_corr > -0.5f * p->h) ? h_corr : -0.5f * p->h;
} }
/* Did we get the right number density? */ /* Did we get the right number density? */
if (p->density.wcount > max_wcount || p->density.wcount < min_wcount) { if (p->density.wcount > max_wcount ||
p->density.wcount < min_wcount) {
/* Ok, correct then */ /* Ok, correct then */
p->h += h_corr; p->h += h_corr;
/* Flag for another round of fun */ /* Flag for another round of fun */
pid[redo] = pid[i]; pid[redo] = pid[i];
redo += 1; redo += 1;
/* Re-initialise everything */ /* Re-initialise everything */
hydro_init_part(p); hydro_init_part(p);
/* Off we go ! */ /* Off we go ! */
continue; continue;
} }
/* We now have a particle whose smoothing length has converged */ /* We now have a particle whose smoothing length has converged */
/* As of here, particle force variables will be set. */ /* As of here, particle force variables will be set. */
/* Compute variables required for the force loop */ /* Compute variables required for the force loop */
hydro_prepare_force(p, xp, ti_current, timeBase); hydro_prepare_force(p, xp, ti_current, timeBase);
/* The particle force values are now set. Do _NOT_ /* The particle force values are now set. Do _NOT_
try to read any particle density variables! */ try to read any particle density variables! */
/* Prepare the particle for the force loop over neighbours */ /* Prepare the particle for the force loop over neighbours */
hydro_reset_acceleration(p); hydro_reset_acceleration(p);
}
} }
}
/* We now need to treat the particles whose smoothing length had not /* We now need to treat the particles whose smoothing length had not
* converged again */ * converged again */
/* Re-set the counter for the next loop (potentially). */ /* Re-set the counter for the next loop (potentially). */
count = redo; count = redo;
if (count > 0) { if (count > 0) {
/* Climb up the cell hierarchy. */ /* Climb up the cell hierarchy. */
for (struct cell *finger = c; finger != NULL; finger = finger->parent) { for (struct cell *finger = c; finger != NULL; finger = finger->parent) {
/* Run through this cell's density interactions. */ /* Run through this cell's density interactions. */
for (struct link *l = finger->density; l != NULL; l = l->next) { for (struct link *l = finger->density; l != NULL; l = l->next) {
/* Self-interaction? */ /* Self-interaction? */
if (l->t->type == task_type_self) if (l->t->type == task_type_self)
runner_doself_subset_density(r, finger, parts, pid, count); runner_doself_subset_density(r, finger, parts, pid, count);
/* Otherwise, pair interaction? */ /* Otherwise, pair interaction? */
else if (l->t->type == task_type_pair) { else if (l->t->type == task_type_pair) {
/* Left or right? */ /* Left or right? */
if (l->t->ci == finger) if (l->t->ci == finger)
runner_dopair_subset_density(r, finger, parts, pid, count, runner_dopair_subset_density(r, finger, parts, pid, count,
l->t->cj); l->t->cj);
else else
runner_dopair_subset_density(r, finger, parts, pid, count, runner_dopair_subset_density(r, finger, parts, pid, count,
l->t->ci); l->t->ci);
} }
/* Otherwise, sub-self interaction? */
else if (l->t->type == task_type_sub_self)
runner_dosub_subset_density(r, finger, parts, pid, count, NULL,
-1, 1);
/* Otherwise, sub-self interaction? */ /* Otherwise, sub-pair interaction? */
else if (l->t->type == task_type_sub_self) else if (l->t->type == task_type_sub_pair) {
runner_dosub_subset_density(r, finger, parts, pid, count, NULL, -1,
1); /* Left or right? */
if (l->t->ci == finger)
/* Otherwise, sub-pair interaction? */ runner_dosub_subset_density(r, finger, parts, pid, count,
else if (l->t->type == task_type_sub_pair) { l->t->cj, -1, 1);
else
/* Left or right? */ runner_dosub_subset_density(r, finger, parts, pid, count,
if (l->t->ci == finger) l->t->ci, -1, 1);
runner_dosub_subset_density(r, finger, parts, pid, count, }
l->t->cj, -1, 1);
else
runner_dosub_subset_density(r, finger, parts, pid, count,
l->t->ci, -1, 1);
} }
} }
} }
} }
}
if (count) if (count)
message("Smoothing length failed to converge on %i particles.", count); message("Smoothing length failed to converge on %i particles.", count);
/* Be clean */ /* Be clean */
free(pid); free(pid);
}
TIMER_TOC(timer_do_ghost); if (timer) TIMER_TOC(timer_do_ghost);
} }
/** /**
...@@ -1224,11 +1229,11 @@ void *runner_main(void *data) { ...@@ -1224,11 +1229,11 @@ void *runner_main(void *data) {
runner_do_init(r, ci, 1); runner_do_init(r, ci, 1);
break; break;
case task_type_ghost: case task_type_ghost:
runner_do_ghost(r, ci); runner_do_ghost(r, ci, 1);
break; break;
#ifdef EXTRA_HYDRO_LOOP #ifdef EXTRA_HYDRO_LOOP
case task_type_extra_ghost: case task_type_extra_ghost:
runner_do_extra_ghost(r, ci); runner_do_extra_ghost(r, ci, 1);
break; break;
#endif #endif
case task_type_kick: case task_type_kick:
......
...@@ -48,11 +48,13 @@ struct runner { ...@@ -48,11 +48,13 @@ struct runner {
}; };
/* Function prototypes. */ /* Function prototypes. */
void runner_do_ghost(struct runner *r, struct cell *c); void runner_do_ghost(struct runner *r, struct cell *c, int timer);
void runner_do_extra_ghost(struct runner *r, struct cell *c, int timer);
void runner_do_sort(struct runner *r, struct cell *c, int flag, int clock); void runner_do_sort(struct runner *r, struct cell *c, int flag, int clock);
void runner_do_kick(struct runner *r, struct cell *c, int timer); void runner_do_kick(struct runner *r, struct cell *c, int timer);
void runner_do_init(struct runner *r, struct cell *c, int timer); void runner_do_init(struct runner *r, struct cell *c, int timer);
void runner_do_cooling(struct runner *r, struct cell *c, int timer); void runner_do_cooling(struct runner *r, struct cell *c, int timer);
void runner_do_grav_external(struct runner *r, struct cell *c, int timer);
void *runner_main(void *data); void *runner_main(void *data);
void runner_do_drift_mapper(void *map_data, int num_elements, void *extra_data); void runner_do_drift_mapper(void *map_data, int num_elements, void *extra_data);
......
...@@ -56,6 +56,7 @@ enum { ...@@ -56,6 +56,7 @@ enum {
timer_dosub_pair_grav, timer_dosub_pair_grav,
timer_dopair_subset, timer_dopair_subset,
timer_do_ghost, timer_do_ghost,
timer_do_extra_ghost,
timer_dorecv_cell, timer_dorecv_cell,
timer_gettask, timer_gettask,
timer_qget, timer_qget,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment