Commit 24e3b63a authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Merge branch 'master' into Self_gravity_BH

parents f0728bfb ca0eafb8
......@@ -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",
......
......@@ -20,7 +20,7 @@
AM_CFLAGS = -DTIMER $(HDF5_CPPFLAGS)
# Assign a "safe" version number
AM_LDFLAGS = $(HDF5_LDFLAGS) $(FFTW_LIBS) -version-info 0:0:0 # -fsanitize=address
AM_LDFLAGS = $(HDF5_LDFLAGS) $(FFTW_LIBS) -version-info 0:0:0
# The git command, if available.
GIT_CMD = @GIT_CMD@
......@@ -70,7 +70,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) $(METIS_LIBS)
libswiftsim_mpi_la_LDFLAGS = $(AM_LDFLAGS) -DWITH_MPI $(METIS_LIBS)
libswiftsim_mpi_la_SHORTNAME = mpi
......
......@@ -1246,38 +1246,25 @@ 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);
}
}
}
}
/**
* @brief Creates the dependency network for the gravity tasks of a given cell.
*
* @param sched The #scheduler.
* @param gravity The gravity task to link.
* @param c The cell.
*/
static inline void engine_make_gravity_dependencies(struct scheduler *sched,
struct task *gravity,
struct cell *c) {
/* init --> gravity --> kick */
/* grav_up --> gravity ( --> kick) */
scheduler_addunlock(sched, c->super->init, gravity);
scheduler_addunlock(sched, c->super->grav_up, gravity);
scheduler_addunlock(sched, gravity, c->super->kick);
}
/**
* @brief Creates all the task dependencies for the gravity
......@@ -1445,29 +1432,47 @@ 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);
}
}
......@@ -1646,8 +1651,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;
......@@ -1691,15 +1695,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;
......@@ -2213,7 +2216,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;
......@@ -2228,7 +2232,8 @@ void engine_init_particles(struct engine *e) {
mask |= 1 << task_type_grav_fft;
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;
submask |= 1 << task_subtype_grav;
}
......@@ -2351,7 +2356,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;
......@@ -2367,7 +2373,8 @@ void engine_step(struct engine *e) {
mask |= 1 << task_type_grav_fft;
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;
submask |= 1 << task_subtype_grav;
}
......
......@@ -23,6 +23,7 @@
#include <pthread.h>
/* Includes. */
#include "atomic.h"
#include "inline.h"
#ifdef PTHREAD_SPINLOCK
......@@ -48,14 +49,14 @@
#define lock_init(l) (*(l) = 0)
#define lock_destroy(l) 0
INLINE static int lock_lock(volatile int *l) {
while (__sync_val_compare_and_swap(l, 0, 1) != 0)
while (atomic_cas(l, 0, 1) != 0)
;
// while( *l );
return 0;
}
#define lock_trylock(l) ((*(l)) ? 1 : __sync_val_compare_and_swap(l, 0, 1))
#define lock_unlock(l) (__sync_val_compare_and_swap(l, 1, 0) != 1)
#define lock_unlock_blind(l) __sync_val_compare_and_swap(l, 1, 0)
#define lock_trylock(l) ((*(l)) ? 1 : atomic_cas(l, 0, 1))
#define lock_unlock(l) (atomic_cas(l, 1, 0) != 1)
#define lock_unlock_blind(l) atomic_cas(l, 1, 0)
#endif
#endif /* SWIFT_LOCK_H */
......@@ -35,7 +35,6 @@
/**
* @brief Mapping function to draw a specific cell (gnuplot).
*/
void map_cells_plot(struct cell *c, void *data) {
int depth = *(int *)data;
......@@ -89,20 +88,17 @@ void map_cells_plot(struct cell *c, void *data) {
/**
* @brief Mapping function for checking if each part is in its box.
*/
void map_check(struct part *p, struct cell *c, void *data) {
/* void map_check ( struct part *p , struct cell *c , void *data ) {
if ( p->x[0] < c->loc[0] || p->x[0] > c->loc[0]+c->h[0] ||
p->x[0] < c->loc[0] || p->x[0] > c->loc[0]+c->h[0] ||
p->x[0] < c->loc[0] || p->x[0] > c->loc[0]+c->h[0] )
printf( "map_check: particle %i is outside of its box.\n" , p->id );
} */
if (p->x[0] < c->loc[0] || p->x[0] > c->loc[0] + c->h[0] ||
p->x[0] < c->loc[0] || p->x[0] > c->loc[0] + c->h[0] ||
p->x[0] < c->loc[0] || p->x[0] > c->loc[0] + c->h[0])
printf("map_check: particle %lld is outside of its box.\n", p->id);
}
/**
* @brief Mapping function for neighbour count.
*/
void map_cellcheck(struct cell *c, void *data) {
int *count = (int *)data;
......@@ -142,7 +138,6 @@ void map_cellcheck(struct cell *c, void *data) {
/**
* @brief Mapping function for maxdepth cell count.
*/
void map_maxdepth(struct cell *c, void *data) {
int maxdepth = ((int *)data)[0];
......@@ -156,7 +151,6 @@ void map_maxdepth(struct cell *c, void *data) {
/**
* @brief Mapping function for neighbour count.
*/
void map_count(struct part *p, struct cell *c, void *data) {
double *wcount = (double *)data;
......@@ -165,7 +159,6 @@ void map_count(struct part *p, struct cell *c, void *data) {
*wcount += p->density.wcount;
}
void map_wcount_min(struct part *p, struct cell *c, void *data) {
struct part **p2 = (struct part **)data;
......@@ -197,7 +190,6 @@ void map_h_max(struct part *p, struct cell *c, void *data) {
/**
* @brief Mapping function for neighbour count.
*/
void map_icount(struct part *p, struct cell *c, void *data) {
// int *count = (int *)data;
......@@ -210,7 +202,6 @@ void map_icount(struct part *p, struct cell *c, void *data) {
/**
* @brief Mapping function to print the particle position.
*/
void map_dump(struct part *p, struct cell *c, void *data) {
double *shift = (double *)data;
......
......@@ -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,15 +38,11 @@
#include "const.h"
#include "error.h"
/* The counters. */
int queue_counter[queue_counter_count];
/**
* @brief Enqueue all tasks in the incoming DEQ.
*
* @param q The #queue, assumed to be locked.
*/
void queue_get_incoming(struct queue *q) {
int *tid = q->tid;
......@@ -101,7 +97,6 @@ void queue_get_incoming(struct queue *q) {
* @param q The #queue.
* @param t The #task.
*/
void queue_insert(struct queue *q, struct task *t) {
/* Get an index in the DEQ. */
const int ind = atomic_inc(&q->last_incoming) % queue_incoming_size;
......@@ -133,7 +128,6 @@ void queue_insert(struct queue *q, struct task *t) {
* @param q The #queue.
* @param tasks List of tasks to which the queue indices refer to.
*/
void queue_init(struct queue *q, struct task *tasks) {
/* Allocate the task list if needed. */
......@@ -169,7 +163,6 @@ void queue_init(struct queue *q, struct task *tasks) {
* @param prev The previous #task extracted from this #queue.
* @param blocking Block until access to the queue is granted.
*/
struct task *queue_gettask(struct queue *q, const struct task *prev,
int blocking) {
......
......@@ -558,8 +558,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)
......@@ -1077,15 +1082,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);
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;
......
This diff is collapsed.
......@@ -174,7 +174,7 @@ void scheduler_splittasks(struct scheduler *s) {
ci->gcount * ci->gcount < space_subsize)) {
/* 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;
}
......@@ -784,23 +784,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;
......@@ -967,6 +967,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:
......@@ -975,11 +976,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:
......
......@@ -123,6 +123,7 @@ void task_unlock(struct task *t) {
break;
case task_type_self:
case task_type_sub_self:
if (subtype == task_subtype_grav) {
cell_gunlocktree(ci);
} else {
......@@ -131,6 +132,7 @@ void task_unlock(struct task *t) {
break;
case task_type_pair:
case task_type_sub_pair:
if (subtype == task_subtype_grav) {
cell_gunlocktree(ci);
cell_gunlocktree(cj);
......@@ -140,15 +142,6 @@ void task_unlock(struct task *t) {
}
break;
case task_type_sub:
if (subtype == task_subtype_grav) {
cell_gunlocktree(ci);
if (cj != NULL) cell_gunlocktree(cj);
} else {
cell_unlocktree(ci);
if (cj != NULL) cell_unlocktree(cj);
}
break;
case task_type_grav_mm:
cell_gunlocktree(ci);
......@@ -198,6 +191,7 @@ int task_lock(struct task *t) {
break;
case task_type_self:
case task_type_sub_self:
if (subtype == task_subtype_grav) {
if (cell_glocktree(ci) != 0) return 0;
} else {
......@@ -206,6 +200,7 @@ int task_lock(struct task *t) {
break;
case task_type_pair:
case task_type_sub_pair:
if (subtype == task_subtype_grav) {
if (ci->ghold || cj->ghold) return 0;
if (cell_glocktree(ci) != 0) return 0;
......@@ -223,37 +218,6 @@ int task_lock(struct task *t) {
}
break;
case task_type_sub:
if (cj == NULL) { /* sub-self */
if (subtype == task_subtype_grav) {
if (cell_glocktree(ci) != 0) return 0;
} else {
if (cell_locktree(ci) != 0) return 0;
}
} else { /* Sub-pair */
if (subtype == task_subtype_grav) {
if (ci->ghold || cj->ghold) return 0;
if (cell_glocktree(ci) != 0) return 0;
if (cell_glocktree(cj) != 0) {
cell_gunlocktree(ci);
return 0;
}
} else {
if (ci->hold || cj->hold) return 0;
if (cell_locktree(ci) != 0) return 0;
if (cell_locktree(cj) != 0) {
cell_unlocktree(ci);
return 0;
}
}
}
break;
case task_type_grav_mm:
if (cell_glocktree(ci) != 0) return 0;
default: