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

First attempt at splitting the sub tasks into two categories

parent c786b757
......@@ -1200,30 +1200,22 @@ void engine_count_and_link_tasks(struct engine *e) {
t->cj->density = engine_addlink(e, t->cj->density, t);
atomic_inc(&t->cj->nr_density);
}
} else if (t->type == task_type_sub) {
} else if (t->type == task_type_sub_self) {
atomic_inc(&t->ci->nr_tasks);
if (t->cj != NULL) atomic_inc(&t->cj->nr_tasks);
if (t->subtype == task_subtype_density) {
t->ci->density = engine_addlink(e, t->ci->density, t);
atomic_inc(&t->ci->nr_density);
if (t->cj != NULL) {
t->cj->density = engine_addlink(e, t->cj->density, t);
atomic_inc(&t->cj->nr_density);
}
}
} else if (t->type == task_type_sub_pair) {
atomic_inc(&t->ci->nr_tasks);
atomic_inc(&t->cj->nr_tasks);
if (t->subtype == task_subtype_density) {
t->ci->density = engine_addlink(e, t->ci->density, t);
atomic_inc(&t->ci->nr_density);
t->cj->density = engine_addlink(e, t->cj->density, t);
atomic_inc(&t->cj->nr_density);
}
}
/* /\* Link gravity multipole tasks to the up/down tasks. *\/ */
/* if (t->type == task_type_grav_mm || */
/* (t->type == task_type_sub && t->subtype == task_subtype_grav)) { */
/* atomic_inc(&t->ci->nr_tasks); */
/* scheduler_addunlock(sched, t->ci->grav_up, t); */
/* scheduler_addunlock(sched, t, t->ci->grav_down); */
/* if (t->cj != NULL && t->ci->grav_up != t->cj->grav_up) { */
/* scheduler_addunlock(sched, t->cj->grav_up, t); */
/* scheduler_addunlock(sched, t, t->cj->grav_down); */
/* } */
/* } */
}
}
......@@ -1311,37 +1303,51 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) {
}
}
/* Otherwise, sub interaction? */
else if (t->type == task_type_sub && t->subtype == task_subtype_density) {
/* Otherwise, sub-self interaction? */
else if (t->type == task_type_sub_self &&
t->subtype == task_subtype_density) {
/* Start by constructing the task for the second hydro loop */
struct task *t2 =
scheduler_addtask(sched, task_type_sub, task_subtype_force, t->flags,
0, t->ci, t->cj, 0);
scheduler_addtask(sched, task_type_sub_self, task_subtype_force,
t->flags, 0, t->ci, t->cj, 0);
/* Add the link between the new loop and both cells */
/* Add the link between the new loop and the cell */
t->ci->force = engine_addlink(e, t->ci->force, t2);
atomic_inc(&t->ci->nr_force);
if (t->cj != NULL) {
t->cj->force = engine_addlink(e, t->cj->force, t2);
atomic_inc(&t->cj->nr_force);
/* Now, build all the dependencies for the hydro for the cells */
/* that are local and are not descendant of the same super-cells */
if (t->ci->nodeID == nodeID) {
engine_make_hydro_loops_dependencies(sched, t, t2, t->ci);
}
}
/* Otherwise, sub-pair interaction? */
else if (t->type == task_type_sub_pair &&
t->subtype == task_subtype_density) {
/* Start by constructing the task for the second hydro loop */
struct task *t2 =
scheduler_addtask(sched, task_type_sub_pair, task_subtype_force,
t->flags, 0, t->ci, t->cj, 0);
/* Add the link between the new loop and both cells */
t->ci->force = engine_addlink(e, t->ci->force, t2);
atomic_inc(&t->ci->nr_force);
t->cj->force = engine_addlink(e, t->cj->force, t2);
atomic_inc(&t->cj->nr_force);
/* Now, build all the dependencies for the hydro for the cells */
/* that are local and are not descendant of the same super-cells */
if (t->ci->nodeID == nodeID) {
engine_make_hydro_loops_dependencies(sched, t, t2, t->ci);
}
if (t->cj != NULL && t->cj->nodeID == nodeID &&
t->ci->super != t->cj->super) {
if (t->cj->nodeID == nodeID && t->ci->super != t->cj->super) {
engine_make_hydro_loops_dependencies(sched, t, t2, t->cj);
}
}
/* /\* Kick tasks should rely on the grav_down tasks of their cell. *\/ */
/* else if (t->type == task_type_kick && t->ci->grav_down != NULL) */
/* scheduler_addunlock(sched, t->ci->grav_down, t); */
/* External gravity tasks should depend on init and unlock the kick */
else if (t->type == task_type_grav_external) {
scheduler_addunlock(sched, t->ci->init, t);
......@@ -1544,8 +1550,7 @@ int engine_marktasks(struct engine *e) {
struct task *t = &tasks[ind[k]];
/* Pair? */
if (t->type == task_type_pair ||
(t->type == task_type_sub && t->cj != NULL)) {
if (t->type == task_type_pair || t->type == task_type_sub_pair) {
/* Local pointers. */
const struct cell *ci = t->ci;
......@@ -1589,15 +1594,14 @@ int engine_marktasks(struct engine *e) {
/* Single-cell task? */
else if (t->type == task_type_self || t->type == task_type_ghost ||
(t->type == task_type_sub && t->cj == NULL)) {
t->type == task_type_sub_self) {
/* Set this task's skip. */
t->skip = (t->ci->ti_end_min > ti_end);
}
/* Pair? */
else if (t->type == task_type_pair ||
(t->type == task_type_sub && t->cj != NULL)) {
else if (t->type == task_type_pair || t->type == task_type_sub_pair) {
/* Local pointers. */
const struct cell *ci = t->ci;
......@@ -2109,7 +2113,8 @@ void engine_init_particles(struct engine *e) {
mask |= 1 << task_type_self;
mask |= 1 << task_type_pair;
mask |= 1 << task_type_sub;
mask |= 1 << task_type_sub_self;
mask |= 1 << task_type_sub_pair;
mask |= 1 << task_type_ghost;
submask |= 1 << task_subtype_density;
......@@ -2238,7 +2243,8 @@ void engine_step(struct engine *e) {
mask |= 1 << task_type_self;
mask |= 1 << task_type_pair;
mask |= 1 << task_type_sub;
mask |= 1 << task_type_sub_self;
mask |= 1 << task_type_sub_pair;
mask |= 1 << task_type_ghost;
submask |= 1 << task_subtype_density;
......
......@@ -86,9 +86,6 @@ const char runner_flip[27] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
#define FUNCTION force
#include "runner_doiact.h"
/* Import the gravity loop functions. */
#include "runner_doiact_grav.h"
/**
* @brief Calculate gravity acceleration from external potential
*
......@@ -98,8 +95,8 @@ const char runner_flip[27] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
*/
void runner_do_grav_external(struct runner *r, struct cell *c, int timer) {
struct gpart *g, *gparts = c->gparts;
int i, k, gcount = c->gcount;
struct gpart *restrict gparts = c->gparts;
const int gcount = c->gcount;
const int ti_current = r->e->ti_current;
const struct external_potential *potential = r->e->external_potential;
const struct phys_const *constants = r->e->physical_constants;
......@@ -108,7 +105,7 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) {
/* Recurse? */
if (c->split) {
for (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);
return;
}
......@@ -118,10 +115,10 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) {
#endif
/* Loop over the parts in this cell. */
for (i = 0; i < gcount; i++) {
for (int i = 0; i < gcount; i++) {
/* Get a direct pointer on the part. */
g = &gparts[i];
struct gpart *const g = &gparts[i];
/* Is this part within the time step? */
if (g->ti_end <= ti_current) {
......@@ -554,7 +551,7 @@ void runner_do_ghost(struct runner *r, struct cell *c) {
}
/* Otherwise, sub interaction? */
else if (l->t->type == task_type_sub) {
else if (l->t->type == task_type_sub_pair) { // MATTHIEU
/* Left or right? */
if (l->t->ci == finger)
......@@ -1066,13 +1063,19 @@ void *runner_main(void *data) {
case task_type_sort:
runner_do_sort(r, ci, t->flags, 1);
break;
case task_type_sub:
case task_type_sub_self:
if (t->subtype == task_subtype_density)
runner_dosub1_density(r, ci, cj, t->flags, 1);
runner_dosub_self1_density(r, ci, 1);
else if (t->subtype == task_subtype_force)
runner_dosub2_force(r, ci, cj, t->flags, 1);
else if (t->subtype == task_subtype_grav)
runner_dosub_grav(r, ci, cj, 1);
runner_dosub_self2_force(r, ci, 1);
else
error("Unknown task subtype.");
break;
case task_type_sub_pair:
if (t->subtype == task_subtype_density)
runner_dosub_pair1_density(r, ci, cj, t->flags, 1);
else if (t->subtype == task_subtype_force)
runner_dosub_pair2_force(r, ci, cj, t->flags, 1);
else
error("Unknown task subtype.");
break;
......@@ -1096,21 +1099,6 @@ void *runner_main(void *data) {
case task_type_recv:
runner_do_recv_cell(r, ci, 1);
break;
case task_type_grav_pp:
if (t->cj == NULL)
runner_doself_grav(r, t->ci);
else
runner_dopair_grav(r, t->ci, t->cj);
break;
case task_type_grav_mm:
runner_dograv_mm(r, t->ci, t->cj);
break;
case task_type_grav_up:
runner_dograv_up(r, t->ci);
break;
case task_type_grav_down:
runner_dograv_down(r, t->ci);
break;
case task_type_grav_external:
runner_do_grav_external(r, t->ci, 1);
break;
......
This diff is collapsed.
......@@ -173,7 +173,7 @@ void scheduler_splittasks(struct scheduler *s) {
if (scheduler_dosub && ci->count < space_subsize / ci->count) {
/* convert to a self-subtask. */
t->type = task_type_sub;
t->type = task_type_sub_self;
}
......@@ -235,7 +235,7 @@ void scheduler_splittasks(struct scheduler *s) {
sid != 0 && sid != 2 && sid != 6 && sid != 8) {
/* Make this task a sub task. */
t->type = task_type_sub;
t->type = task_type_sub_pair;
}
......@@ -515,132 +515,6 @@ void scheduler_splittasks(struct scheduler *s) {
} /* pair interaction? */
/* Gravity interaction? */
else if (t->type == task_type_grav_mm) {
/* Get a handle on the cells involved. */
struct cell *ci = t->ci;
struct cell *cj = t->cj;
/* Self-interaction? */
if (cj == NULL) {
/* Ignore this task if the cell has no gparts. */
if (ci->gcount == 0) t->type = task_type_none;
/* If the cell is split, recurse. */
else if (ci->split) {
/* Make a single sub-task? */
if (scheduler_dosub && ci->gcount < space_subsize / ci->gcount) {
t->type = task_type_sub;
t->subtype = task_subtype_grav;
}
/* Otherwise, just split the task. */
else {
/* Split this task into tasks on its progeny. */
t->type = task_type_none;
for (int j = 0; j < 8; j++)
if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) {
if (t->type == task_type_none) {
t->type = task_type_grav_mm;
t->ci = ci->progeny[j];
t->cj = NULL;
} else
t = scheduler_addtask(s, task_type_grav_mm, task_subtype_none,
0, 0, ci->progeny[j], NULL, 0);
for (int k = j + 1; k < 8; k++)
if (ci->progeny[k] != NULL && ci->progeny[k]->gcount > 0) {
if (t->type == task_type_none) {
t->type = task_type_grav_mm;
t->ci = ci->progeny[j];
t->cj = ci->progeny[k];
} else
t = scheduler_addtask(s, task_type_grav_mm,
task_subtype_none, 0, 0,
ci->progeny[j], ci->progeny[k], 0);
}
}
redo = (t->type != task_type_none);
}
}
/* Otherwise, just make a pp task out of it. */
else
t->type = task_type_grav_pp;
}
/* Nope, pair. */
else {
/* Make a sub-task? */
if (scheduler_dosub && ci->gcount < space_subsize / cj->gcount) {
t->type = task_type_sub;
t->subtype = task_subtype_grav;
}
/* Otherwise, split the task. */
else {
/* Get the opening angle theta. */
float dx[3], theta;
for (int k = 0; k < 3; k++) {
dx[k] = fabs(ci->loc[k] - cj->loc[k]);
if (s->space->periodic && dx[k] > 0.5 * s->space->dim[k])
dx[k] = -dx[k] + s->space->dim[k];
if (dx[k] > 0.0f) dx[k] -= ci->h[k];
}
theta =
(dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) /
(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]);
/* Ignore this task if the cell has no gparts. */
if (ci->gcount == 0 || cj->gcount == 0) t->type = task_type_none;
/* Split the interaction? */
else if (theta < const_theta_max * const_theta_max) {
/* Are both ci and cj split? */
if (ci->split && cj->split) {
/* Split this task into tasks on its progeny. */
t->type = task_type_none;
for (int j = 0; j < 8; j++)
if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) {
for (int k = 0; k < 8; k++)
if (cj->progeny[k] != NULL && cj->progeny[k]->gcount > 0) {
if (t->type == task_type_none) {
t->type = task_type_grav_mm;
t->ci = ci->progeny[j];
t->cj = cj->progeny[k];
} else
t = scheduler_addtask(
s, task_type_grav_mm, task_subtype_none, 0, 0,
ci->progeny[j], cj->progeny[k], 0);
}
}
redo = (t->type != task_type_none);
}
/* Otherwise, make a pp task out of it. */
else
t->type = task_type_grav_pp;
}
}
} /* gravity pair interaction? */
} /* gravity interaction? */
} /* loop over all tasks. */
}
......@@ -899,23 +773,23 @@ void scheduler_reweight(struct scheduler *s) {
t->weight +=
2 * wscale * t->ci->count * t->cj->count * sid_scale[t->flags];
break;
case task_type_sub:
if (t->cj != NULL) {
if (t->ci->nodeID != nodeID || t->cj->nodeID != nodeID) {
if (t->flags < 0)
t->weight += 3 * wscale * t->ci->count * t->cj->count;
else
t->weight += 3 * wscale * t->ci->count * t->cj->count *
sid_scale[t->flags];
} else {
if (t->flags < 0)
t->weight += 2 * wscale * t->ci->count * t->cj->count;
else
t->weight += 2 * wscale * t->ci->count * t->cj->count *
sid_scale[t->flags];
}
} else
t->weight += 1 * wscale * t->ci->count * t->ci->count;
case task_type_sub_pair:
if (t->ci->nodeID != nodeID || t->cj->nodeID != nodeID) {
if (t->flags < 0)
t->weight += 3 * wscale * t->ci->count * t->cj->count;
else
t->weight += 3 * wscale * t->ci->count * t->cj->count *
sid_scale[t->flags];
} else {
if (t->flags < 0)
t->weight += 2 * wscale * t->ci->count * t->cj->count;
else
t->weight += 2 * wscale * t->ci->count * t->cj->count *
sid_scale[t->flags];
}
break;
case task_type_sub_self:
t->weight += 1 * wscale * t->ci->count * t->ci->count;
break;
case task_type_ghost:
if (t->ci == t->ci->super) t->weight += wscale * t->ci->count;
......@@ -1082,6 +956,7 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
any pre-processing needed. */
switch (t->type) {
case task_type_self:
case task_type_sub_self:
case task_type_sort:
case task_type_ghost:
case task_type_kick:
......@@ -1090,11 +965,9 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
qid = t->ci->super->owner;
break;
case task_type_pair:
case task_type_sub:
case task_type_sub_pair:
qid = t->ci->super->owner;
if (t->cj != NULL &&
(qid < 0 ||
s->queues[qid].count > s->queues[t->cj->super->owner].count))
if (qid < 0 || s->queues[qid].count > s->queues[t->cj->super->owner].count)
qid = t->cj->super->owner;
break;
case task_type_recv:
......
......@@ -117,13 +117,14 @@ void task_unlock(struct task *t) {
/* Act based on task type. */
switch (t->type) {
case task_type_self:
case task_type_sub_self:
case task_type_sort:
cell_unlocktree(t->ci);
break;
case task_type_pair:
case task_type_sub:
case task_type_sub_pair:
cell_unlocktree(t->ci);
if (t->cj != NULL) cell_unlocktree(t->cj);
cell_unlocktree(t->cj);
break;
case task_type_grav_pp:
case task_type_grav_mm:
......@@ -170,12 +171,12 @@ int task_lock(struct task *t) {
/* Unary lock? */
else if (type == task_type_self || type == task_type_sort ||
(type == task_type_sub && cj == NULL)) {
(type == task_type_sub_self)) {
if (cell_locktree(ci) != 0) return 0;
}
/* Otherwise, binary lock. */
else if (type == task_type_pair || (type == task_type_sub && cj != NULL)) {
else if (type == task_type_pair || (type == task_type_sub_pair)) {
if (ci->hold || cj->hold) return 0;
if (cell_locktree(ci) != 0) return 0;
if (cell_locktree(cj) != 0) {
......
......@@ -41,9 +41,12 @@ enum {
timer_dopair_force,
timer_dopair_grav,
timer_dograv_external,
timer_dosub_density,
timer_dosub_force,
timer_dosub_grav,
timer_dosub_self_density,
timer_dosub_self_force,
timer_dosub_self_grav,
timer_dosub_pair_density,
timer_dosub_pair_force,
timer_dosub_pair_grav,
timer_dopair_subset,
timer_do_ghost,
timer_dorecv_cell,
......
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