Commit b48cf575 authored by Pedro Gonnet's avatar Pedro Gonnet
Browse files

Merge remote-tracking branch 'origin' into tasks_cleanup

Conflicts:
	src/engine.c
	src/scheduler.c
	src/space.c
	src/task.c
parents 98f8fde9 35b13d49
......@@ -19,11 +19,6 @@
#ifndef SWIFT_RUNNER_DOIACT_GRAV_H
#define SWIFT_RUNNER_DOIACT_GRAV_H
/* Includes. */
#include "cell.h"
#include "clocks.h"
#include "part.h"
/**
* @brief Compute the sorted gravity interactions between a cell pair.
*
......@@ -60,8 +55,8 @@ void runner_dopair_grav_new(struct runner *r, struct cell *ci,
sid = space_getsid(e->s, &ci, &cj, shift);
/* Make sure the cells are sorted. */
runner_do_gsort(r, ci, (1 << sid), 0);
runner_do_gsort(r, cj, (1 << sid), 0);
// runner_do_gsort(r, ci, (1 << sid), 0);
// runner_do_gsort(r, cj, (1 << sid), 0);
/* Have the cells been sorted? */
if (!(ci->gsorted & (1 << sid)) || !(cj->gsorted & (1 << sid)))
......@@ -69,7 +64,7 @@ void runner_dopair_grav_new(struct runner *r, struct cell *ci,
/* Get the cutoff shift. */
for (rshift = 0.0, k = 0; k < 3; k++)
rshift += shift[k] * runner_shift[3 * sid + k];
rshift += shift[k] * runner_shift[sid][k];
/* Pick-out the sorted lists. */
sort_i = &ci->gsort[sid * (ci->count + 1)];
......
......@@ -44,6 +44,9 @@
#include "error.h"
#include "intrinsics.h"
#include "kernel_hydro.h"
#include "queue.h"
#include "space.h"
#include "task.h"
#include "timers.h"
/**
......@@ -65,8 +68,8 @@ void scheduler_addunlock(struct scheduler *s, struct task *ta,
struct task **unlocks_new;
int *unlock_ind_new;
const int size_unlocks_new = s->size_unlocks * 2;
if ((unlocks_new = (struct task **)malloc(
sizeof(struct task *) *size_unlocks_new)) == NULL ||
if ((unlocks_new = (struct task **)malloc(sizeof(struct task *) *
size_unlocks_new)) == NULL ||
(unlock_ind_new = (int *)malloc(sizeof(int) * size_unlocks_new)) ==
NULL)
error("Failed to re-allocate unlocks.");
......@@ -107,12 +110,10 @@ void scheduler_splittasks_mapper(void *map_data, int num_elements,
void *extra_data) {
/* Static constants. */
const static int pts[7][8] = {{-1, 12, 10, 9, 4, 3, 1, 0},
{-1, -1, 11, 10, 5, 4, 2, 1},
{-1, -1, -1, 12, 7, 6, 4, 3},
{-1, -1, -1, -1, 8, 7, 5, 4},
{-1, -1, -1, -1, -1, 12, 10, 9},
{-1, -1, -1, -1, -1, -1, 11, 10},
const static int pts[7][8] = {
{-1, 12, 10, 9, 4, 3, 1, 0}, {-1, -1, 11, 10, 5, 4, 2, 1},
{-1, -1, -1, 12, 7, 6, 4, 3}, {-1, -1, -1, -1, 8, 7, 5, 4},
{-1, -1, -1, -1, -1, 12, 10, 9}, {-1, -1, -1, -1, -1, -1, 11, 10},
{-1, -1, -1, -1, -1, -1, -1, 12}};
const static float sid_scale[13] = {0.1897, 0.4025, 0.1897, 0.4025, 0.5788,
0.4025, 0.1897, 0.4025, 0.1897, 0.4025,
......@@ -161,7 +162,7 @@ void scheduler_splittasks_mapper(void *map_data, int num_elements,
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;
/* Otherwise, make tasks explicitly. */
} else {
......@@ -224,7 +225,7 @@ void scheduler_splittasks_mapper(void *map_data, int num_elements,
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;
/* Otherwise, split it. */
} else {
......@@ -791,7 +792,8 @@ void scheduler_ranktasks(struct scheduler *s) {
const int nr_tasks = s->nr_tasks;
/* Run through the tasks and get all the waits right. */
/* threadpool_map(s->threadpool, scheduler_simple_rewait_mapper, tasks, nr_tasks,
/* threadpool_map(s->threadpool, scheduler_simple_rewait_mapper, tasks,
nr_tasks,
sizeof(struct task), 1000, NULL); */
for (int i = 0; i < nr_tasks; i++) {
struct task *t = &tasks[i];
......@@ -837,10 +839,12 @@ void scheduler_ranktasks(struct scheduler *s) {
j = left_old;
}
#ifdef SWIFT_DEBUG_CHECKS
/* Verify that the tasks were ranked correctly. */
/* for (int k = 1; k < s->nr_tasks; k++)
for (int k = 1; k < s->nr_tasks; k++)
if (tasks[tid[k - 1]].rank > tasks[tid[k - 1]].rank)
error("Task ranking failed."); */
error("Task ranking failed.");
#endif
}
/**
......@@ -860,7 +864,8 @@ void scheduler_reset(struct scheduler *s, int size) {
if (s->tasks_ind != NULL) free(s->tasks_ind);
/* Allocate the new lists. */
if ((s->tasks = (struct task *)malloc(sizeof(struct task) *size)) == NULL ||
if ((s->tasks = (struct task *)malloc(sizeof(struct task) * size)) ==
NULL ||
(s->tasks_ind = (int *)malloc(sizeof(int) * size)) == NULL)
error("Failed to allocate task lists.");
}
......@@ -925,8 +930,7 @@ 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) {
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;
......@@ -940,7 +944,8 @@ void scheduler_reweight(struct scheduler *s) {
t->weight += 2 * wscale * t->ci->count * t->cj->count *
sid_scale[t->flags];
}
} else
break;
case task_type_sub_self:
t->weight += 1 * wscale * t->ci->count * t->ci->count;
break;
case task_type_ghost:
......@@ -1097,6 +1102,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:
......@@ -1105,11 +1111,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:
......@@ -1269,7 +1274,7 @@ struct task *scheduler_gettask(struct scheduler *s, int qid,
tries++) {
/* Try to get a task from the suggested queue. */
if (s->queues[qid].count > 0) {
if (s->queues[qid].count > 0 || s->queues[qid].count_incoming > 0) {
TIMER_TIC
res = queue_gettask(&s->queues[qid], prev, 0);
TIMER_TOC(timer_qget);
......@@ -1280,7 +1285,9 @@ struct task *scheduler_gettask(struct scheduler *s, int qid,
if (s->flags & scheduler_flag_steal) {
int count = 0, qids[nr_queues];
for (int k = 0; k < nr_queues; k++)
if (s->queues[k].count > 0) qids[count++] = k;
if (s->queues[k].count > 0 || s->queues[k].count_incoming > 0) {
qids[count++] = k;
}
for (int k = 0; k < scheduler_maxsteal && count > 0; k++) {
const int ind = rand_r(&seed) % count;
TIMER_TIC
......@@ -1353,7 +1360,7 @@ void scheduler_init(struct scheduler *s, struct space *space, int nr_tasks,
/* Init the unlocks. */
if ((s->unlocks = (struct task **)malloc(
sizeof(struct task *) *scheduler_init_nr_unlocks)) == NULL ||
sizeof(struct task *) * scheduler_init_nr_unlocks)) == NULL ||
(s->unlock_ind =
(int *)malloc(sizeof(int) * scheduler_init_nr_unlocks)) == NULL)
error("Failed to allocate unlocks.");
......
......@@ -35,7 +35,6 @@
#include "cell.h"
#include "lock.h"
#include "queue.h"
#include "space.h"
#include "task.h"
#include "threadpool.h"
......
......@@ -26,22 +26,22 @@
/* Some standard headers. */
#include <hdf5.h>
#include <math.h>
#include <mpi.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* MPI headers. */
#ifdef WITH_MPI
#include <mpi.h>
#endif
/* This object's header. */
#include "serial_io.h"
/* Local includes. */
#include "common_io.h"
#include "engine.h"
#include "error.h"
#include "kernel_hydro.h"
#include "part.h"
#include "units.h"
/*-----------------------------------------------------------------------------
* Routines reading an IC file
......
......@@ -19,6 +19,9 @@
#ifndef SWIFT_SERIAL_IO_H
#define SWIFT_SERIAL_IO_H
/* Config parameters. */
#include "../config.h"
/* MPI headers. */
#ifdef WITH_MPI
#include <mpi.h>
......
......@@ -36,8 +36,11 @@
/* Local includes. */
#include "common_io.h"
#include "const.h"
#include "engine.h"
#include "error.h"
#include "kernel_hydro.h"
#include "part.h"
#include "units.h"
/*-----------------------------------------------------------------------------
* Routines reading an IC file
......
......@@ -19,6 +19,9 @@
#ifndef SWIFT_SINGLE_IO_H
#define SWIFT_SINGLE_IO_H
/* Config parameters. */
#include "../config.h"
/* Includes. */
#include "engine.h"
#include "part.h"
......
......@@ -429,6 +429,7 @@ void space_rebuild(struct space *s, double cell_max, int verbose) {
// clocks_from_ticks(getticks() - tic), clocks_getunit());
#ifdef WITH_MPI
/* Move non-local parts to the end of the list. */
const int local_nodeID = s->e->nodeID;
for (size_t k = 0; k < nr_parts;) {
......@@ -456,8 +457,9 @@ void space_rebuild(struct space *s, double cell_max, int verbose) {
}
}
#ifdef SWIFT_DEBUG_CHECKS
/* Check that all parts are in the correct places. */
/* for (size_t k = 0; k < nr_parts; k++) {
for (size_t k = 0; k < nr_parts; k++) {
if (cells[ind[k]].nodeID != local_nodeID) {
error("Failed to move all non-local parts to send list");
}
......@@ -466,7 +468,8 @@ void space_rebuild(struct space *s, double cell_max, int verbose) {
if (cells[ind[k]].nodeID == local_nodeID) {
error("Failed to remove local parts from send list");
}
}*/
}
#endif
/* Move non-local gparts to the end of the list. */
for (int k = 0; k < nr_gparts;) {
......@@ -491,8 +494,8 @@ void space_rebuild(struct space *s, double cell_max, int verbose) {
}
}
#ifdef SWIFT_DEBUG_CHECKS
/* Check that all gparts are in the correct place (untested). */
/*
for (size_t k = 0; k < nr_gparts; k++) {
if (cells[gind[k]].nodeID != local_nodeID) {
error("Failed to move all non-local gparts to send list");
......@@ -502,7 +505,8 @@ void space_rebuild(struct space *s, double cell_max, int verbose) {
if (cells[gind[k]].nodeID == local_nodeID) {
error("Failed to remove local gparts from send list");
}
}*/
}
#endif
/* Exchange the strays, note that this potentially re-allocates
the parts arrays. */
......@@ -531,12 +535,15 @@ void space_rebuild(struct space *s, double cell_max, int verbose) {
ind[k] =
cell_getid(cdim, p->x[0] * ih[0], p->x[1] * ih[1], p->x[2] * ih[2]);
cells[ind[k]].count += 1;
/* if ( cells[ ind[k] ].nodeID != nodeID )
error( "Received part that does not belong to me (nodeID=%i)." , cells[
ind[k] ].nodeID ); */
#ifdef SWIFT_DEBUG_CHECKS
if (cells[ind[k]].nodeID != local_nodeID)
error("Received part that does not belong to me (nodeID=%i).",
cells[ind[k]].nodeID);
#endif
}
nr_parts = s->nr_parts;
#endif
#endif /* WITH_MPI */
/* Sort the parts according to their cells. */
space_parts_sort(s, ind, nr_parts, 0, s->nr_cells - 1, verbose);
......@@ -545,15 +552,18 @@ void space_rebuild(struct space *s, double cell_max, int verbose) {
for (size_t k = 0; k < nr_parts; k++)
if (s->parts[k].gpart != NULL) s->parts[k].gpart->part = &s->parts[k];
/* Verify sort_struct. */
/* for ( k = 1 ; k < nr_parts ; k++ ) {
if ( ind[k-1] > ind[k] ) {
error( "Sort failed!" );
#ifdef SWIFT_DEBUG_CHECKS
/* Verify space_sort_struct. */
for (size_t k = 1; k < nr_parts; k++) {
if (ind[k - 1] > ind[k]) {
error("Sort failed!");
} else if (ind[k] != cell_getid(cdim, s->parts[k].x[0] * ih[0],
s->parts[k].x[1] * ih[1],
s->parts[k].x[2] * ih[2])) {
error("Incorrect indices!");
}
}
else if ( ind[k] != cell_getid( cdim , parts[k].x[0]*ih[0] ,
parts[k].x[1]*ih[1] , parts[k].x[2]*ih[2] ) )
error( "Incorrect indices!" );
} */
#endif
/* We no longer need the indices as of here. */
free(ind);
......@@ -594,8 +604,8 @@ void space_rebuild(struct space *s, double cell_max, int verbose) {
/* We no longer need the indices as of here. */
free(gind);
#ifdef SWIFT_DEBUG_CHECKS
/* Verify that the links are correct */
/* MATTHIEU: To be commented out once we are happy */
for (size_t k = 0; k < nr_gparts; ++k) {
if (s->gparts[k].id > 0) {
......@@ -615,6 +625,7 @@ void space_rebuild(struct space *s, double cell_max, int verbose) {
if (s->parts[k].gpart->part != &s->parts[k]) error("Linking problem !");
}
}
#endif
/* Hook the cells up to the parts. */
// tic = getticks();
......@@ -705,13 +716,14 @@ void space_parts_sort(struct space *s, int *ind, size_t N, int min, int max,
threadpool_map(&s->e->threadpool, space_parts_sort_mapper, &sort_struct,
s->e->threadpool.num_threads, 0, 1, NULL);
/* Verify sort_struct. */
/* for (int i = 1; i < N; i++)
#ifdef SWIFT_DEBUG_CHECKS
/* Verify space_sort_struct. */
for (int i = 1; i < N; i++)
if (ind[i - 1] > ind[i])
error("Sorting failed (ind[%i]=%i,ind[%i]=%i), min=%i, max=%i.", i - 1,
ind[i - 1], i,
ind[i], min, max);
message("Sorting succeeded."); */
ind[i - 1], i, ind[i], min, max);
message("Sorting succeeded.");
#endif
/* Clean up. */
free(sort_struct.stack);
......@@ -721,7 +733,8 @@ void space_parts_sort(struct space *s, int *ind, size_t N, int min, int max,
clocks_getunit());
}
void space_parts_sort_mapper(void *map_data, int num_elements, void *extra_data) {
void space_parts_sort_mapper(void *map_data, int num_elements,
void *extra_data) {
/* Unpack the mapping data. */
struct parallel_sort *sort_struct = (struct parallel_sort *)map_data;
......@@ -775,19 +788,21 @@ void space_parts_sort_mapper(void *map_data, int num_elements, void *extra_data)
}
}
/* Verify sort_struct. */
/* for (int k = i; k <= jj; k++)
#ifdef SWIFT_DEBUG_CHECKS
/* Verify space_sort_struct. */
for (int k = i; k <= jj; k++)
if (ind[k] > pivot) {
message("sorting failed at k=%i, ind[k]=%i, pivot=%i, i=%i, j=%i.", k,
ind[k], pivot, i, j);
message("sorting failed at k=%i, ind[k]=%i, pivot=%i, i=%li, j=%li.",
k, ind[k], pivot, i, j);
error("Partition failed (<=pivot).");
}
for (int k = jj + 1; k <= j; k++)
if (ind[k] <= pivot) {
message("sorting failed at k=%i, ind[k]=%i, pivot=%i, i=%i, j=%i.", k,
ind[k], pivot, i, j);
message("sorting failed at k=%i, ind[k]=%i, pivot=%i, i=%li, j=%li.",
k, ind[k], pivot, i, j);
error("Partition failed (>pivot).");
} */
}
#endif
/* Split-off largest interval. */
if (jj - i > j - jj + 1) {
......@@ -886,13 +901,14 @@ void space_gparts_sort(struct space *s, int *ind, size_t N, int min, int max,
threadpool_map(&s->e->threadpool, space_gparts_sort_mapper, &sort_struct,
s->e->threadpool.num_threads, 0, 1, NULL);
/* Verify sort_struct. */
/* for (int i = 1; i < N; i++)
#ifdef SWIFT_DEBUG_CHECKS
/* Verify space_sort_struct. */
for (int i = 1; i < N; i++)
if (ind[i - 1] > ind[i])
error("Sorting failed (ind[%i]=%i,ind[%i]=%i), min=%i, max=%i.", i - 1,
ind[i - 1], i,
ind[i], min, max);
message("Sorting succeeded."); */
ind[i - 1], i, ind[i], min, max);
message("Sorting succeeded.");
#endif
/* Clean up. */
free(sort_struct.stack);
......@@ -902,7 +918,8 @@ void space_gparts_sort(struct space *s, int *ind, size_t N, int min, int max,
clocks_getunit());
}
void space_gparts_sort_mapper(void *map_data, int num_elements, void *extra_data) {
void space_gparts_sort_mapper(void *map_data, int num_elements,
void *extra_data) {
/* Unpack the mapping data. */
struct parallel_sort *sort_struct = (struct parallel_sort *)map_data;
......@@ -952,19 +969,21 @@ void space_gparts_sort_mapper(void *map_data, int num_elements, void *extra_data
}
}
/* Verify sort_struct. */
/* for (int k = i; k <= jj; k++)
#ifdef SWIFT_DEBUG_CHECKS
/* Verify space_sort_struct. */
for (int k = i; k <= jj; k++)
if (ind[k] > pivot) {
message("sorting failed at k=%i, ind[k]=%i, pivot=%i, i=%i, j=%i.", k,
ind[k], pivot, i, j);
message("sorting failed at k=%i, ind[k]=%i, pivot=%i, i=%li, j=%li.",
k, ind[k], pivot, i, j);
error("Partition failed (<=pivot).");
}
for (int k = jj + 1; k <= j; k++)
if (ind[k] <= pivot) {
message("sorting failed at k=%i, ind[k]=%i, pivot=%i, i=%i, j=%i.", k,
ind[k], pivot, i, j);
message("sorting failed at k=%i, ind[k]=%i, pivot=%i, i=%li, j=%li.",
k, ind[k], pivot, i, j);
error("Partition failed (>pivot).");
} */
}
#endif
/* Split-off largest interval. */
if (jj - i > j - jj + 1) {
......
......@@ -23,16 +23,18 @@
#ifndef SWIFT_SPACE_H
#define SWIFT_SPACE_H
/* Includes. */
/* Config parameters. */
#include "../config.h"
/* Some standard headers. */
#include <stddef.h>
/* Local includes. */
/* Includes. */
#include "cell.h"
#include "lock.h"
#include "parser.h"
#include "part.h"
/* Forward-declare the engine to avoid cyclic includes. */
struct engine;
#include "space.h"
/* Some constants. */
#define space_maxdepth 10
......@@ -150,8 +152,10 @@ void space_map_parts_xparts(struct space *s,
struct cell *c));
void space_map_cells_post(struct space *s, int full,
void (*fun)(struct cell *c, void *data), void *data);
void space_parts_sort_mapper(void *map_data, int num_elements, void *extra_data);
void space_gparts_sort_mapper(void *map_data, int num_elements, void *extra_data);
void space_parts_sort_mapper(void *map_data, int num_elements,
void *extra_data);
void space_gparts_sort_mapper(void *map_data, int num_elements,
void *extra_data);
void space_rebuild(struct space *s, double h_max, int verbose);
void space_recycle(struct space *s, struct cell *c);
void space_split(struct space *s, struct cell *cells, int verbose);
......@@ -159,4 +163,5 @@ void space_split_mapper(void *map_data, int num_elements, void *extra_data);
void space_do_parts_sort();
void space_do_gparts_sort();
void space_link_cleanup(struct space *s);
#endif /* SWIFT_SPACE_H */
......@@ -52,8 +52,8 @@ const char *taskID_names[task_type_count] = {
"send", "recv", "grav_pp", "grav_mm", "grav_up",
"grav_down", "grav_external", "comm_root"};
const char *subtaskID_names[task_type_count] = {"none", "density",
"force", "grav"};
const char *subtaskID_names[task_type_count] = {"none", "density", "force",
"grav"};
/**
* @brief Computes the overlap between the parts array of two given cells.
......@@ -112,13 +112,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:
......@@ -139,38 +140,57 @@ void task_unlock(struct task *t) {
int task_lock(struct task *t) {
int type = t->type;
const int type = t->type;
const int subtype = t->subtype;
struct cell *ci = t->ci, *cj = t->cj;
#ifdef WITH_MPI
int res = 0, err = 0;
MPI_Status stat;
#endif
/* Communication task? */
if (type == task_type_recv || type == task_type_send) {
switch (type) {
/* Communication task? */
case task_type_recv:
case task_type_send:
#ifdef WITH_MPI
/* Check the status of the MPI request. */
int res = 0, err = 0;
MPI_Status stat;
if ((err = MPI_Test(&t->req, &res, &stat)) != MPI_SUCCESS) {
char buff[MPI_MAX_ERROR_STRING];
int len;
MPI_Error_string(err, buff, &len);
error("Failed to test request on send/recv task (tag=%i, %s).", t->flags,
buff);
error("Failed to test request on send/recv task (tag=%i, %s).",
t->flags, buff);
}
return res;
#else
error("SWIFT was not compiled with MPI support.");
#endif
break;
}
case task_type_sort:
if (cell_locktree(ci) != 0) return 0;
break;
/* Unary lock? */
else if (type == task_type_self || type == task_type_sort ||
(type == task_type_sub && cj == NULL)) {
case task_type_self:
case task_type_sub_self:
if (subtype == task_subtype_grav) {
if (cell_glocktree(ci) != 0) return 0;
} else {
if (cell_locktree(ci) != 0) return 0;
}
break;
/* Otherwise, binary lock. */
else if (type == task_type_pair || (type == task_type_sub && cj != NULL)) {
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;
if (cell_glocktree(cj) != 0) {
cell_gunlocktree(ci);
return 0;
}
} else {