Commit ca0eafb8 authored by Peter W. Draper's avatar Peter W. Draper
Browse files

Merge branch 'task_sub_split' into 'master'

Task sub split

This implements #175 
While at it I also removed some dead code (including #174) and cleaned up the linking of libraries in the Makefile. For some reasons we had still blas in lapack in there.

Finally I have also removed some commented-out old gravity stuff. That should make the diff for the gravity branch much easier to read when it becomes time to merge that in.

See merge request !180
parents 48ac97ea 8df32afb
......@@ -55,8 +55,8 @@ PLOT_PARAMS = {"axes.labelsize": 10,
pl.rcParams.update(PLOT_PARAMS)
# Tasks and subtypes. Indexed as in tasks.h.
TASKTYPES = ["none", "sort", "self", "pair", "sub", "init", "ghost", "drift",
"kick", "kick_fixdt", "send", "recv", "grav_pp", "grav_mm",
TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair", "init", "ghost",
"drift", "kick", "kick_fixdt", "send", "recv", "grav_pp", "grav_mm",
"grav_up", "grav_down", "grav_external", "part_sort", "gpart_sort",
"split_cell", "rewait", "count"]
......@@ -64,7 +64,8 @@ TASKCOLOURS = {"none": "black",
"sort": "lightblue",
"self": "greenyellow",
"pair": "navy",
"sub": "hotpink",
"sub_self": "greenyellow",
"sub_pair": "navy",
"init": "indigo",
"ghost": "cyan",
"drift": "maroon",
......
......@@ -61,8 +61,8 @@ PLOT_PARAMS = {"axes.labelsize": 10,
pl.rcParams.update(PLOT_PARAMS)
# Tasks and subtypes. Indexed as in tasks.h.
TASKTYPES = ["none", "sort", "self", "pair", "sub", "init", "ghost", "drift",
"kick", "kick_fixdt", "send", "recv", "grav_pp", "grav_mm",
TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair", "init", "ghost",
"drift", "kick", "kick_fixdt", "send", "recv", "grav_pp", "grav_mm",
"grav_up", "grav_down", "grav_external", "part_sort", "gpart_sort",
"split_cell", "rewait", "count"]
......@@ -70,7 +70,8 @@ TASKCOLOURS = {"none": "black",
"sort": "lightblue",
"self": "greenyellow",
"pair": "navy",
"sub": "hotpink",
"sub_self": "greenyellow",
"sub_pair": "navy",
"init": "indigo",
"ghost": "cyan",
"drift": "maroon",
......
# This file is part of SWIFT.
# Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk),
# Matthieu Schaller (matthieu.schaller@durham.ac.uk).
......@@ -17,10 +16,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Add the debug flag to the whole thing
AM_CFLAGS = -DTIMER -DCOUNTER $(HDF5_CPPFLAGS)
AM_CFLAGS = -DTIMER $(HDF5_CPPFLAGS)
# Assign a "safe" version number
AM_LDFLAGS = $(LAPACK_LIBS) $(BLAS_LIBS) $(HDF5_LDFLAGS) -version-info 0:0:0 # -fsanitize=address
AM_LDFLAGS = $(HDF5_LDFLAGS) -version-info 0:0:0
# The git command, if available.
GIT_CMD = @GIT_CMD@
......@@ -70,6 +69,7 @@ libswiftsim_la_SOURCES = $(AM_SOURCES)
# Sources and flags for MPI library
libswiftsim_mpi_la_SOURCES = $(AM_SOURCES)
libswiftsim_mpi_la_CFLAGS = $(AM_CFLAGS) -DWITH_MPI $(METIS_INCS)
libswiftsim_mpi_la_LDFLAGS = $(AM_LDFLAGS) -DWITH_MPI $(METIS_LIBS)
libswiftsim_mpi_la_SHORTNAME = mpi
......
......@@ -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;
......
......@@ -453,9 +453,9 @@ static void repart_edge_metis(int partweights, int bothweights, int nodeID,
/* Skip un-interesting tasks. */
if (t->type != task_type_self && t->type != task_type_pair &&
t->type != task_type_sub && t->type != task_type_ghost &&
t->type != task_type_drift && t->type != task_type_kick &&
t->type != task_type_init)
t->type != task_type_sub_self && t->type != task_type_sub_self &&
t->type != task_type_ghost && t->type != task_type_drift &&
t->type != task_type_kick && t->type != task_type_init)
continue;
/* Get the task weight. */
......@@ -496,7 +496,8 @@ static void repart_edge_metis(int partweights, int bothweights, int nodeID,
/* Self interaction? */
else if ((t->type == task_type_self && ci->nodeID == nodeID) ||
(t->type == task_type_sub && cj == NULL && ci->nodeID == nodeID)) {
(t->type == task_type_sub_self && cj == NULL &&
ci->nodeID == nodeID)) {
/* Self interactions add only to vertex weight. */
if (taskvweights) weights_v[cid] += w;
......@@ -504,7 +505,7 @@ static void repart_edge_metis(int partweights, int bothweights, int nodeID,
/* Pair? */
else if (t->type == task_type_pair ||
(t->type == task_type_sub && cj != NULL)) {
(t->type == task_type_sub_pair)) {
/* In-cell pair? */
if (ci == cj) {
/* Add weight to vertex for ci. */
......
......@@ -38,16 +38,6 @@
#include "const.h"
#include "error.h"
/* Counter macros. */
#ifdef COUNTER
#define COUNT(c) (__sync_add_and_fetch(&queue_counter[c], 1))
#else
#define COUNT(c)
#endif
/* The counters. */
int queue_counter[queue_counter_count];
/**
* @brief Enqueue all tasks in the incoming DEQ.
*
......
......@@ -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) {
......@@ -553,8 +550,13 @@ void runner_do_ghost(struct runner *r, struct cell *c) {
}
/* Otherwise, sub interaction? */
else if (l->t->type == task_type_sub) {
/* 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-pair interaction? */
else if (l->t->type == task_type_sub_pair) {
/* Left or right? */
if (l->t->ci == finger)
......@@ -1066,13 +1068,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_dosub_self1_density(r, ci, 1);
else if (t->subtype == task_subtype_force)
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_dosub1_density(r, ci, cj, t->flags, 1);
runner_dosub_pair1_density(r, ci, cj, t->flags, 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_pair2_force(r, ci, cj, t->flags, 1);
else
error("Unknown task subtype.");
break;
......@@ -1096,21 +1104,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,10 @@ 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:
......
......@@ -47,11 +47,11 @@
/* Task type names. */
const char *taskID_names[task_type_count] = {
"none", "sort", "self", "pair", "sub",
"init", "ghost", "drift", "kick", "kick_fixdt",
"send", "recv", "grav_pp", "grav_mm", "grav_up",
"grav_down", "grav_external", "part_sort", "gpart_sort", "split_cell",
"rewait"};
"none", "sort", "self", "pair", "sub_self",
</