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

Split the kick task into two different tasks

parent 563e01f9
......@@ -971,7 +971,8 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) {
if (c->ghost != NULL) scheduler_activate(s, c->ghost);
if (c->init != NULL) scheduler_activate(s, c->init);
if (c->drift != NULL) scheduler_activate(s, c->drift);
if (c->kick != NULL) scheduler_activate(s, c->kick);
if (c->kick1 != NULL) scheduler_activate(s, c->kick1);
if (c->kick2 != NULL) scheduler_activate(s, c->kick2);
if (c->cooling != NULL) scheduler_activate(s, c->cooling);
if (c->sourceterms != NULL) scheduler_activate(s, c->sourceterms);
......
......@@ -150,8 +150,11 @@ struct cell {
/*! The drift task */
struct task *drift;
/*! The kick task */
struct task *kick;
/*! The first kick task */
struct task *kick1;
/*! The second kick task */
struct task *kick2;
/*! Task constructing the multipole from the particles */
struct task *grav_up;
......
......@@ -140,8 +140,12 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) {
c->init = scheduler_addtask(s, task_type_init, task_subtype_none, 0, 0, c,
NULL, 0);
c->kick = scheduler_addtask(s, task_type_kick, task_subtype_none, 0, 0, c,
NULL, 0);
/* Add the two half kicks */
c->kick1 = scheduler_addtask(s, task_type_kick1, task_subtype_none, 0, 0,
c, NULL, 0);
c->kick2 = scheduler_addtask(s, task_type_kick2, task_subtype_none, 0, 0,
c, NULL, 0);
/* Add the drift task and dependency. */
c->drift = scheduler_addtask(s, task_type_drift, task_subtype_none, 0, 0,
......@@ -692,7 +696,7 @@ void engine_addtasks_send(struct engine *e, struct cell *ci, struct cell *cj,
#ifdef EXTRA_HYDRO_LOOP
scheduler_addunlock(s, t_gradient, ci->super->kick);
scheduler_addunlock(s, t_gradient, ci->super->kick2);
scheduler_addunlock(s, ci->super->extra_ghost, t_gradient);
......@@ -707,7 +711,7 @@ void engine_addtasks_send(struct engine *e, struct cell *ci, struct cell *cj,
#else
/* The send_rho task should unlock the super-cell's kick task. */
scheduler_addunlock(s, t_rho, ci->super->kick);
scheduler_addunlock(s, t_rho, ci->super->kick2);
/* The send_rho task depends on the cell's ghost task. */
scheduler_addunlock(s, ci->super->ghost, t_rho);
......@@ -719,7 +723,7 @@ void engine_addtasks_send(struct engine *e, struct cell *ci, struct cell *cj,
#endif
/* The super-cell's kick task should unlock the send_ti task. */
if (t_ti != NULL) scheduler_addunlock(s, ci->super->kick, t_ti);
if (t_ti != NULL) scheduler_addunlock(s, ci->super->kick2, t_ti);
}
/* Add them to the local cell. */
......@@ -1454,7 +1458,7 @@ static inline void engine_make_gravity_dependencies(struct scheduler *sched,
/* init --> gravity --> kick */
scheduler_addunlock(sched, c->super->init, gravity);
scheduler_addunlock(sched, gravity, c->super->kick);
scheduler_addunlock(sched, gravity, c->super->kick2);
/* grav_up --> gravity ( --> kick) */
scheduler_addunlock(sched, c->super->grav_up, gravity);
......@@ -1473,7 +1477,7 @@ static inline void engine_make_external_gravity_dependencies(
/* init --> external gravity --> kick */
scheduler_addunlock(sched, c->super->init, gravity);
scheduler_addunlock(sched, gravity, c->super->kick);
scheduler_addunlock(sched, gravity, c->super->kick2);
}
/**
......@@ -1512,7 +1516,7 @@ void engine_link_gravity_tasks(struct engine *e) {
/* Gather the multipoles --> mm interaction --> kick */
scheduler_addunlock(sched, gather, t);
scheduler_addunlock(sched, t, t->ci->super->kick);
scheduler_addunlock(sched, t, t->ci->super->kick2);
/* init --> mm interaction */
scheduler_addunlock(sched, t->ci->super->init, t);
......@@ -1596,14 +1600,16 @@ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched,
struct task *gradient,
struct task *force,
struct cell *c) {
/* init --> density loop --> ghost --> gradient loop --> extra_ghost */
/* extra_ghost --> force loop --> kick */
/* kick1 --> init --> density loop --> ghost --> gradient loop --> extra_ghost
*/
/* extra_ghost --> force loop --> kick2 */
scheduler_addunlock(sched, c->super->kick1, c->super->init);
scheduler_addunlock(sched, c->super->init, density);
scheduler_addunlock(sched, density, c->super->ghost);
scheduler_addunlock(sched, c->super->ghost, gradient);
scheduler_addunlock(sched, gradient, c->super->extra_ghost);
scheduler_addunlock(sched, c->super->extra_ghost, force);
scheduler_addunlock(sched, force, c->super->kick);
scheduler_addunlock(sched, force, c->super->kick2);
}
#else
......@@ -1620,11 +1626,12 @@ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched,
struct task *density,
struct task *force,
struct cell *c) {
/* init --> density loop --> ghost --> force loop --> kick */
/* kick1 --> init --> density loop --> ghost --> force loop --> kick2 */
scheduler_addunlock(sched, c->super->kick1, c->super->init);
scheduler_addunlock(sched, c->super->init, density);
scheduler_addunlock(sched, density, c->super->ghost);
scheduler_addunlock(sched, c->super->ghost, force);
scheduler_addunlock(sched, force, c->super->kick);
scheduler_addunlock(sched, force, c->super->kick2);
}
#endif
......@@ -1818,18 +1825,21 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) {
}
#endif
}
/* Cooling tasks should depend on kick and unlock sourceterms */
else if (t->type == task_type_cooling) {
scheduler_addunlock(sched, t->ci->kick, t);
}
/* source terms depend on cooling if performed, else on kick. It is the last
task */
else if (t->type == task_type_sourceterms) {
if (e->policy == engine_policy_cooling)
scheduler_addunlock(sched, t->ci->cooling, t);
else
scheduler_addunlock(sched, t->ci->kick, t);
}
/* /\* Cooling tasks should depend on kick and unlock sourceterms *\/ */
/* else if (t->type == task_type_cooling) { */
/* scheduler_addunlock(sched, t->ci->kick, t); */
/* } */
/* /\* source terms depend on cooling if performed, else on kick. It is the
* last */
/* task *\/ */
/* else if (t->type == task_type_sourceterms) { */
/* if (e->policy == engine_policy_cooling) */
/* scheduler_addunlock(sched, t->ci->cooling, t); */
/* else */
/* scheduler_addunlock(sched, t->ci->kick, t); */
/* } */
// MATTHIEU
}
}
......@@ -2121,7 +2131,11 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
}
/* Kick? */
else if (t->type == task_type_kick) {
else if (t->type == task_type_kick1) {
if (t->ci->ti_end_min <= ti_end) scheduler_activate(s, t);
}
else if (t->type == task_type_kick2) {
t->ci->updated = 0;
t->ci->g_updated = 0;
if (t->ci->ti_end_min <= ti_end) scheduler_activate(s, t);
......@@ -2353,7 +2367,7 @@ void engine_barrier(struct engine *e, int tid) {
void engine_collect_kick(struct cell *c) {
/* Skip super-cells (Their values are already set) */
if (c->kick != NULL) return;
if (c->kick2 != NULL) return;
/* Counters for the different quantities. */
int updated = 0, g_updated = 0;
......@@ -2505,9 +2519,10 @@ void engine_skip_force_and_kick(struct engine *e) {
struct task *t = &tasks[i];
/* Skip everything that updates the particles */
if (t->subtype == task_subtype_force || t->type == task_type_kick ||
t->type == task_type_cooling || t->type == task_type_sourceterms ||
t->type == task_type_drift)
if (t->subtype ==
task_subtype_force || // t->type == task_type_kick || //MATTHIEU
t->type == task_type_cooling ||
t->type == task_type_sourceterms || t->type == task_type_drift)
t->skip = 1;
}
}
......
......@@ -27,6 +27,8 @@
#include "debug.h"
#include "timeline.h"
#if 0
/**
* @brief Perform the 'kick' operation on a #gpart
*
......@@ -126,4 +128,10 @@ __attribute__((always_inline)) INLINE static void kick_part(
if (p->gpart != NULL) gravity_kick_extra(p->gpart, dt, half_dt);
}
#endif
__attribute__((always_inline)) INLINE static void kick_part(
struct part *restrict p, struct xpart *restrict xp, integertime_t ti_start,
integertime_t ti_end, integertime_t ti_current) {}
#endif /* SWIFT_KICK_H */
......@@ -823,6 +823,121 @@ void runner_do_drift_mapper(void *map_data, int num_elements,
}
}
void runner_do_kick1(struct runner *r, struct cell *c, int timer) {}
void runner_do_kick2(struct runner *r, struct cell *c, int timer) {}
/**
* @brief Kick particles in momentum space and collect statistics.
*
* @param r The runner thread.
* @param c The cell.
* @param timer Are we timing this ?
*/
void runner_do_kick(struct runner *r, struct cell *c, int timer) {
const struct engine *e = r->e;
// const double timeBase = e->timeBase;
const integertime_t ti_current = e->ti_current;
const int count = c->count;
// const int gcount = c->gcount;
struct part *restrict parts = c->parts;
struct xpart *restrict xparts = c->xparts;
// struct gpart *restrict gparts = c->gparts;
const double const_G = e->physical_constants->const_newton_G;
TIMER_TIC;
/* Anything to do here? */
if (!cell_is_active(c, e)) {
c->updated = 0;
c->g_updated = 0;
return;
}
int updated = 0, g_updated = 0;
integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0;
/* No children? */
if (!c->split) {
/* Loop over the particles and kick the active ones. */
for (int k = 0; k < count; k++) {
/* Get a handle on the part. */
struct part *restrict p = &parts[k];
struct xpart *restrict xp = &xparts[k];
/* If particle needs to be kicked */
if (part_is_active(p, e)) {
/* First, finish the force loop */
hydro_end_force(p);
if (p->gpart != NULL) gravity_end_force(p->gpart, const_G);
const integertime_t ti_step = get_integer_timestep(p->time_bin);
const integertime_t ti_begin =
get_integer_time_begin(ti_current, p->time_bin);
const integertime_t ti_end =
get_integer_time_end(ti_current, p->time_bin);
/* And finish the time-step with a second half-kick */
kick_part(p, xp, ti_begin + ti_step / 2, ti_end + ti_step, ti_current);
}
}
/* Loop over the particles and kick the active ones. */
for (int k = 0; k < count; k++) {
/* Get a handle on the part. */
struct part *restrict p = &parts[k];
struct xpart *restrict xp = &xparts[k];
/* If particle needs to be kicked */
if (part_is_active(p, e)) {
const integertime_t ti_step = get_integer_timestep(p->time_bin);
const integertime_t ti_begin =
get_integer_time_begin(ti_current, p->time_bin);
const integertime_t ti_end =
get_integer_time_end(ti_current, p->time_bin);
/* And finish the time-step with a second half-kick */
kick_part(p, xp, ti_begin, ti_end + ti_step / 2, ti_current);
}
}
}
/* Otherwise, aggregate data from children. */
else {
/* Loop over the progeny. */
for (int k = 0; k < 8; k++)
if (c->progeny[k] != NULL) {
struct cell *restrict cp = c->progeny[k];
/* Recurse */
runner_do_kick(r, cp, 0);
/* And aggregate */
updated += cp->updated;
g_updated += cp->g_updated;
ti_end_min = min(cp->ti_end_min, ti_end_min);
ti_end_max = max(cp->ti_end_max, ti_end_max);
}
}
/* Store the values. */
c->updated = updated;
c->g_updated = g_updated;
c->ti_end_min = ti_end_min;
c->ti_end_max = ti_end_max;
if (timer) TIMER_TOC(timer_kick);
}
#ifdef OLD_KICK
/**
* @brief Kick particles in momentum space and collect statistics.
*
......@@ -968,6 +1083,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) {
if (timer) TIMER_TOC(timer_kick);
}
#endif
/**
* @brief Construct the cell properties from the received particles
......@@ -1192,8 +1308,11 @@ void *runner_main(void *data) {
case task_type_drift:
runner_do_drift(r, ci, 1);
break;
case task_type_kick:
runner_do_kick(r, ci, 1);
case task_type_kick1:
runner_do_kick1(r, ci, 1);
break;
case task_type_kick2:
runner_do_kick2(r, ci, 1);
break;
#ifdef WITH_MPI
case task_type_send:
......
......@@ -132,7 +132,8 @@ static void scheduler_splittask(struct task *t, struct scheduler *s) {
/* Non-splittable task? */
if ((t->ci == NULL || (t->type == task_type_pair && t->cj == NULL)) ||
((t->type == task_type_kick) && t->ci->nodeID != s->nodeID) ||
((t->type == task_type_kick1) && t->ci->nodeID != s->nodeID) ||
((t->type == task_type_kick2) && t->ci->nodeID != s->nodeID) ||
((t->type == task_type_drift) && t->ci->nodeID != s->nodeID) ||
((t->type == task_type_init) && t->ci->nodeID != s->nodeID)) {
t->type = task_type_none;
......@@ -963,7 +964,10 @@ void scheduler_reweight(struct scheduler *s, int verbose) {
case task_type_ghost:
if (t->ci == t->ci->super) cost = wscale * t->ci->count;
break;
case task_type_kick:
case task_type_kick1:
cost = wscale * t->ci->count;
break;
case task_type_kick2:
cost = wscale * t->ci->count;
break;
case task_type_init:
......@@ -1154,7 +1158,8 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
case task_type_sub_self:
case task_type_sort:
case task_type_ghost:
case task_type_kick:
case task_type_kick1:
case task_type_kick2:
case task_type_drift:
case task_type_init:
qid = t->ci->super->owner;
......
......@@ -213,7 +213,8 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements,
c->init = NULL;
c->extra_ghost = NULL;
c->ghost = NULL;
c->kick = NULL;
c->kick1 = NULL;
c->kick2 = NULL;
c->drift = NULL;
c->cooling = NULL;
c->sourceterms = NULL;
......
......@@ -48,10 +48,10 @@
/* Task type names. */
const char *taskID_names[task_type_count] = {
"none", "sort", "self", "pair", "sub_self",
"sub_pair", "init", "ghost", "extra_ghost", "drift",
"kick", "send", "recv", "grav_gather_m", "grav_fft",
"grav_mm", "grav_up", "cooling", "sourceterms"};
"none", "sort", "self", "pair", "sub_self",
"sub_pair", "init", "ghost", "extra_ghost", "drift",
"kick1", "kick2", "send", "recv", "grav_gather_m",
"grav_fft", "grav_mm", "grav_up", "cooling", "sourceterms"};
const char *subtaskID_names[task_subtype_count] = {
"none", "density", "gradient", "force", "grav", "external_grav", "tend"};
......@@ -147,7 +147,8 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on(
break;
case task_type_init:
case task_type_kick:
case task_type_kick1:
case task_type_kick2:
case task_type_send:
case task_type_recv:
case task_type_drift:
......
......@@ -46,7 +46,8 @@ enum task_types {
task_type_ghost,
task_type_extra_ghost,
task_type_drift,
task_type_kick,
task_type_kick1,
task_type_kick2,
task_type_send,
task_type_recv,
task_type_grav_gather_m,
......
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