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

several bug fixes.


Former-commit-id: d0161ae876e742cd8a08b6af01a461704a3cfb59
parent 095461aa
...@@ -38,7 +38,7 @@ struct cell { ...@@ -38,7 +38,7 @@ struct cell {
double h[3]; double h[3];
/* Max radii in this cell. */ /* Max radii in this cell. */
double r_max; double h_max;
/* The depth of this cell in the tree. */ /* The depth of this cell in the tree. */
int depth, split; int depth, split;
......
...@@ -55,6 +55,10 @@ ...@@ -55,6 +55,10 @@
* @brief Sort the tasks in topological order over all queues. * @brief Sort the tasks in topological order over all queues.
* *
* @param e The #engine. * @param e The #engine.
*
* TODO: Return the indices tid as these are the tasks sorted according
* to their ranks. They can then be dropped into the queues in order
* of these indices.
*/ */
void engine_ranktasks ( struct engine *e ) { void engine_ranktasks ( struct engine *e ) {
......
...@@ -485,6 +485,9 @@ void runner_doghost ( struct runner *r , struct cell *c ) { ...@@ -485,6 +485,9 @@ void runner_doghost ( struct runner *r , struct cell *c ) {
printf( "runner_doghost: particle %i has bad wcount=%f.\n" , p->id , p->wcount + kernel_root ); printf( "runner_doghost: particle %i has bad wcount=%f.\n" , p->id , p->wcount + kernel_root );
pid[redo] = pid[i]; pid[redo] = pid[i];
redo += 1; redo += 1;
p->wcount = 0.0;
p->rho = 0.0;
p->rho_dh = 0.0;
continue; continue;
} }
......
...@@ -99,7 +99,7 @@ void DOPAIR_NAIVE ( struct runner *r , struct cell *ci , struct cell *cj ) { ...@@ -99,7 +99,7 @@ void DOPAIR_NAIVE ( struct runner *r , struct cell *ci , struct cell *cj ) {
pj = &parts_j[ pjd ]; pj = &parts_j[ pjd ];
/* Compute the pairwise distance. */ /* Compute the pairwise distance. */
r2 = 0.0; r2 = 0.0f;
for ( k = 0 ; k < 3 ; k++ ) { for ( k = 0 ; k < 3 ; k++ ) {
dx[k] = pix[k] - pj->x[k]; dx[k] = pix[k] - pj->x[k];
r2 += dx[k]*dx[k]; r2 += dx[k]*dx[k];
...@@ -117,7 +117,7 @@ void DOPAIR_NAIVE ( struct runner *r , struct cell *ci , struct cell *cj ) { ...@@ -117,7 +117,7 @@ void DOPAIR_NAIVE ( struct runner *r , struct cell *ci , struct cell *cj ) {
} /* loop over the parts in ci. */ } /* loop over the parts in ci. */
#ifdef TIMER_VERBOSE #ifdef TIMER_VERBOSE
printf( "runner_dopair_naive[%02i]: %i/%i parts at depth %i (r_max=%.3f/%.3f) took %.3f ms.\n" , r->id , count_i , count_j , ci->depth , ci->r_max , cj->r_max , ((double)TIMER_TOC(TIMER_DOPAIR)) / CPU_TPS * 1000 ); printf( "runner_dopair_naive[%02i]: %i/%i parts at depth %i (r_max=%.3f/%.3f) took %.3f ms.\n" , r->id , count_i , count_j , ci->depth , ci->h_max , cj->h_max , ((double)TIMER_TOC(TIMER_DOPAIR)) / CPU_TPS * 1000 );
#else #else
TIMER_TOC(TIMER_DOPAIR); TIMER_TOC(TIMER_DOPAIR);
#endif #endif
...@@ -144,7 +144,8 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) { ...@@ -144,7 +144,8 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) {
struct part *pi, *pj, *parts_i, *parts_j; struct part *pi, *pj, *parts_i, *parts_j;
double pix[3], pjx[3], di, dj; double pix[3], pjx[3], di, dj;
float dx[3], hi, hi2, hj, hj2, r2; float dx[3], hi, hi2, hj, hj2, r2;
double hi_max, hj_max, di_max, dj_min; double hi_max, hj_max;
double di_max, dj_min;
int count_i, count_j; int count_i, count_j;
TIMER_TIC TIMER_TIC
...@@ -172,9 +173,17 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) { ...@@ -172,9 +173,17 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) {
for ( rshift = 0.0 , k = 0 ; k < 3 ; k++ ) for ( rshift = 0.0 , k = 0 ; k < 3 ; k++ )
rshift += shift[k]*runner_shift[ 3*sid + k ]; rshift += shift[k]*runner_shift[ 3*sid + k ];
/* printf( "runner_dopair: doing pair [ %g %g %g ]/[ %g %g %g ] with %i/%i parts and shift = [ %g %g %g ].\n" , /* for ( k = 0 ; k < ci->count ; k++ )
ci->loc[0] , ci->loc[1] , ci->loc[2] , cj->loc[0] , cj->loc[1] , cj->loc[2] , if ( ci->parts[k].id == 561590 )
ci->count , cj->count , shift[0] , shift[1] , shift[2] ); fflush(stdout); */ break;
if ( k == ci->count )
for ( k = 0 ; k < cj->count ; k++ )
if ( cj->parts[k].id == 561590 )
break;
if ( k < cj->count )
printf( "runner_dopair: doing pair [ %g %g %g ]/[ %g %g %g ] with %i/%i parts, h_max=%g/%g, and shift = [ %g %g %g ] (rshift=%g).\n" ,
ci->loc[0] , ci->loc[1] , ci->loc[2] , cj->loc[0] , cj->loc[1] , cj->loc[2] ,
ci->count , cj->count , ci->h_max , cj->h_max , shift[0] , shift[1] , shift[2] , rshift ); fflush(stdout); */
/* for ( hi = 0 , k = 0 ; k < ci->count ; k++ ) /* for ( hi = 0 , k = 0 ; k < ci->count ; k++ )
hi += ci->parts[k].r; hi += ci->parts[k].r;
for ( hj = 0 , k = 0 ; k < cj->count ; k++ ) for ( hj = 0 , k = 0 ; k < cj->count ; k++ )
...@@ -186,7 +195,7 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) { ...@@ -186,7 +195,7 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) {
sort_j = &cj->sort[ sid*(cj->count + 1) ]; sort_j = &cj->sort[ sid*(cj->count + 1) ];
/* Get some other useful values. */ /* Get some other useful values. */
hi_max = ci->r_max - rshift; hj_max = cj->r_max - rshift; hi_max = ci->h_max - rshift; hj_max = cj->h_max;
count_i = ci->count; count_j = cj->count; count_i = ci->count; count_j = cj->count;
parts_i = ci->parts; parts_j = cj->parts; parts_i = ci->parts; parts_j = cj->parts;
di_max = sort_i[count_i-1].d - rshift; di_max = sort_i[count_i-1].d - rshift;
...@@ -216,7 +225,7 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) { ...@@ -216,7 +225,7 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) {
pj = &parts_j[ sort_j[pjd].i ]; pj = &parts_j[ sort_j[pjd].i ];
/* Compute the pairwise distance. */ /* Compute the pairwise distance. */
r2 = 0.0; r2 = 0.0f;
for ( k = 0 ; k < 3 ; k++ ) { for ( k = 0 ; k < 3 ; k++ ) {
dx[k] = pix[k] - pj->x[k]; dx[k] = pix[k] - pj->x[k];
r2 += dx[k]*dx[k]; r2 += dx[k]*dx[k];
...@@ -237,7 +246,7 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) { ...@@ -237,7 +246,7 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) {
tic = getticks(); */ tic = getticks(); */
/* Loop over the parts in cj. */ /* Loop over the parts in cj. */
for ( pjd = 0 ; pjd < count_j && sort_j[pjd].d - hj_max < di_max ; pjd++ ) { for ( pjd = 0 ; pjd < count_j && ( 1 || sort_j[pjd].d - hj_max < di_max ) ; pjd++ ) {
/* Get a hold of the jth part in cj. */ /* Get a hold of the jth part in cj. */
pj = &parts_j[ sort_j[ pjd ].i ]; pj = &parts_j[ sort_j[ pjd ].i ];
...@@ -257,7 +266,7 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) { ...@@ -257,7 +266,7 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) {
pi = &parts_i[ sort_i[pid].i ]; pi = &parts_i[ sort_i[pid].i ];
/* Compute the pairwise distance. */ /* Compute the pairwise distance. */
r2 = 0.0; r2 = 0.0f;
for ( k = 0 ; k < 3 ; k++ ) { for ( k = 0 ; k < 3 ; k++ ) {
dx[k] = pi->x[k] - pjx[k]; dx[k] = pi->x[k] - pjx[k];
r2 += dx[k]*dx[k]; r2 += dx[k]*dx[k];
...@@ -275,7 +284,7 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) { ...@@ -275,7 +284,7 @@ void DOPAIR ( struct runner *r , struct cell *ci , struct cell *cj ) {
} /* loop over the parts in ci. */ } /* loop over the parts in ci. */
#ifdef TIMER_VERBOSE #ifdef TIMER_VERBOSE
printf( "runner_dopair[%02i]: %i/%i parts at depth %i (r_max=%.3f/%.3f, h=%.3f) took %.3f ms.\n" , r->id , count_i , count_j , ci->depth , ci->r_max , cj->r_max , fmax(ci->h[0],fmax(ci->h[1],ci->h[2])) , ((double)(TIMER_TOC(TIMER_DOPAIR))) / CPU_TPS * 1000 ); printf( "runner_dopair[%02i]: %i/%i parts at depth %i (r_max=%.3f/%.3f, h=%.3f) took %.3f ms.\n" , r->id , count_i , count_j , ci->depth , ci->h_max , cj->h_max , fmax(ci->h[0],fmax(ci->h[1],ci->h[2])) , ((double)(TIMER_TOC(TIMER_DOPAIR))) / CPU_TPS * 1000 );
#else #else
TIMER_TOC(TIMER_DOPAIR); TIMER_TOC(TIMER_DOPAIR);
#endif #endif
...@@ -320,7 +329,7 @@ void DOSELF ( struct runner *r , struct cell *c ) { ...@@ -320,7 +329,7 @@ void DOSELF ( struct runner *r , struct cell *c ) {
pj = &parts[pjd]; pj = &parts[pjd];
/* Compute the pairwise distance. */ /* Compute the pairwise distance. */
r2 = 0.0; r2 = 0.0f;
for ( k = 0 ; k < 3 ; k++ ) { for ( k = 0 ; k < 3 ; k++ ) {
dx[k] = pix[k] - pj->x[k]; dx[k] = pix[k] - pj->x[k];
r2 += dx[k]*dx[k]; r2 += dx[k]*dx[k];
...@@ -330,7 +339,7 @@ void DOSELF ( struct runner *r , struct cell *c ) { ...@@ -330,7 +339,7 @@ void DOSELF ( struct runner *r , struct cell *c ) {
if ( r2 < hi2 || r2 < pj->h*pj->h ) { if ( r2 < hi2 || r2 < pj->h*pj->h ) {
IACT( r2 , dx , hi , pj->h , pi , pj ); IACT( r2 , dx , hi , pj->h , pi , pj );
} }
} /* loop over all other particles. */ } /* loop over all other particles. */
......
...@@ -41,9 +41,6 @@ ...@@ -41,9 +41,6 @@
/* Error macro. */ /* Error macro. */
#define error(s) { printf( "%s:%s:%i: %s\n" , __FILE__ , __FUNCTION__ , __LINE__ , s ); abort(); } #define error(s) { printf( "%s:%s:%i: %s\n" , __FILE__ , __FUNCTION__ , __LINE__ , s ); abort(); }
/* Convert cell location to ID. */
#define cell_getid( cdim , i , j , k ) ( (int)(k) + (cdim)[2]*( (int)(j) + (cdim)[1]*(int)(i) ) )
/* Split size. */ /* Split size. */
int space_splitsize = space_splitsize_default; int space_splitsize = space_splitsize_default;
...@@ -95,6 +92,10 @@ void space_map_clearsort ( struct cell *c , void *data ) { ...@@ -95,6 +92,10 @@ void space_map_clearsort ( struct cell *c , void *data ) {
/** /**
* @brief Mapping function to append a ghost task to each cell. * @brief Mapping function to append a ghost task to each cell.
*
* Looks for the super cell, e.g. the highest-level cell above each
* cell for which a pair is defined. All ghosts below this cell will
* depend on the ghost of their parents (sounds spooky, but it isn't).
*/ */
void space_map_mkghosts ( struct cell *c , void *data ) { void space_map_mkghosts ( struct cell *c , void *data ) {
...@@ -109,7 +110,7 @@ void space_map_mkghosts ( struct cell *c , void *data ) { ...@@ -109,7 +110,7 @@ void space_map_mkghosts ( struct cell *c , void *data ) {
if ( finger->nr_tasks > 0 ) if ( finger->nr_tasks > 0 )
c->super = finger; c->super = finger;
/* Make the ghost task, if needed. */ /* Make the ghost task */
if ( c->super != c || c->nr_tasks > 0 ) if ( c->super != c || c->nr_tasks > 0 )
c->ghost = space_addtask( s , task_type_ghost , task_subtype_none , 0 , 0 , c , NULL , NULL , 0 , NULL , 0 ); c->ghost = space_addtask( s , task_type_ghost , task_subtype_none , 0 , 0 , c , NULL , NULL , 0 , NULL , 0 );
...@@ -359,7 +360,7 @@ void space_splittasks ( struct space *s ) { ...@@ -359,7 +360,7 @@ void space_splittasks ( struct space *s ) {
hj = fmax( cj->h[0] , fmax( cj->h[1] , cj->h[2] ) ); hj = fmax( cj->h[0] , fmax( cj->h[1] , cj->h[2] ) );
/* Should this task be split-up? */ /* Should this task be split-up? */
if ( ci->split && cj->split && ci->r_max < hi/2 && cj->r_max < hj/2 ) { if ( ci->split && cj->split && ci->h_max < hi/2 && cj->h_max < hj/2 ) {
/* Get the relative distance between the pairs, wrapping. */ /* Get the relative distance between the pairs, wrapping. */
for ( k = 0 ; k < 3 ; k++ ) { for ( k = 0 ; k < 3 ; k++ ) {
...@@ -800,7 +801,7 @@ void space_maketasks ( struct space *s , int do_sort ) { ...@@ -800,7 +801,7 @@ void space_maketasks ( struct space *s , int do_sort ) {
int i, j, k, ii, jj, kk, iii, jjj, kkk, cid, cjd; int i, j, k, ii, jj, kk, iii, jjj, kkk, cid, cjd;
int *cdim = s->cdim; int *cdim = s->cdim;
int nr_tasks_old = s->nr_tasks; int nr_tasks_old = s->nr_tasks;
struct task *t, *t2; struct task *t , *t2;
int pts[7][8] = { { -1 , 12 , 10 , 9 , 4 , 3 , 1 , 0 } , int pts[7][8] = { { -1 , 12 , 10 , 9 , 4 , 3 , 1 , 0 } ,
{ -1 , -1 , 11 , 10 , 5 , 4 , 2 , 1 } , { -1 , -1 , 11 , 10 , 5 , 4 , 2 , 1 } ,
{ -1 , -1 , -1 , 12 , 7 , 6 , 4 , 3 } , { -1 , -1 , -1 , 12 , 7 , 6 , 4 , 3 } ,
...@@ -968,7 +969,7 @@ void space_maketasks ( struct space *s , int do_sort ) { ...@@ -968,7 +969,7 @@ void space_maketasks ( struct space *s , int do_sort ) {
if ( t->flags & ( 1 << i ) ) { if ( t->flags & ( 1 << i ) ) {
for ( j = 0 ; j < 8 ; j++ ) for ( j = 0 ; j < 8 ; j++ )
if ( t->ci->progeny[j] != NULL ) if ( t->ci->progeny[j] != NULL )
task_rmunlock( t->ci->progeny[j]->sorts[i] , t ); task_rmunlock_blind( t->ci->progeny[j]->sorts[i] , t );
t->ci->sorts[i] = NULL; t->ci->sorts[i] = NULL;
} }
t->type = task_type_none; t->type = task_type_none;
...@@ -976,7 +977,7 @@ void space_maketasks ( struct space *s , int do_sort ) { ...@@ -976,7 +977,7 @@ void space_maketasks ( struct space *s , int do_sort ) {
} }
/* Count the number of tasks associated with each cell. */ /* Count the number of tasks associated with each cell. */
space_map_cells( s , 1 , &space_map_mkghosts , NULL ); space_map_cells( s , 1 , &space_map_clearnrtasks , NULL );
for ( k = 0 ; k < s->nr_tasks ; k++ ) { for ( k = 0 ; k < s->nr_tasks ; k++ ) {
t = &s->tasks[k]; t = &s->tasks[k];
if ( t->type == task_type_self ) if ( t->type == task_type_self )
...@@ -1010,8 +1011,6 @@ void space_maketasks ( struct space *s , int do_sort ) { ...@@ -1010,8 +1011,6 @@ void space_maketasks ( struct space *s , int do_sort ) {
/* Otherwise, pair interaction? */ /* Otherwise, pair interaction? */
else if ( t->type == task_type_pair && t->subtype == task_subtype_density ) { else if ( t->type == task_type_pair && t->subtype == task_subtype_density ) {
if ( t->ci->ghost == NULL )
printf( "space_maketasks: cell at %lx has no ghost!\n" , (unsigned long int)t->ci );
task_addunlock( t , t->ci->super->ghost ); task_addunlock( t , t->ci->super->ghost );
task_addunlock( t , t->cj->super->ghost ); task_addunlock( t , t->cj->super->ghost );
t2 = space_addtask( s , task_type_pair , task_subtype_force , 0 , 0 , t->ci , t->cj , NULL , 0 , NULL , 0 ); t2 = space_addtask( s , task_type_pair , task_subtype_force , 0 , 0 , t->ci , t->cj , NULL , 0 , NULL , 0 );
...@@ -1069,7 +1068,7 @@ void space_maketasks ( struct space *s , int do_sort ) { ...@@ -1069,7 +1068,7 @@ void space_maketasks ( struct space *s , int do_sort ) {
void space_split ( struct space *s , struct cell *c ) { void space_split ( struct space *s , struct cell *c ) {
int k, count; int k, count;
double h, h_limit, r_max = 0.0; double h, h_limit, h_max = 0.0;
struct cell *temp; struct cell *temp;
/* Check the depth. */ /* Check the depth. */
...@@ -1084,10 +1083,10 @@ void space_split ( struct space *s , struct cell *c ) { ...@@ -1084,10 +1083,10 @@ void space_split ( struct space *s , struct cell *c ) {
h = c->parts[k].h; h = c->parts[k].h;
if ( h <= h_limit ) if ( h <= h_limit )
count += 1; count += 1;
if ( h > r_max ) if ( h > h_max )
r_max = h; h_max = h;
} }
c->r_max = r_max; c->h_max = h_max;
/* Split or let it be? */ /* Split or let it be? */
if ( count > c->count*space_splitratio && c->count > space_splitsize ) { if ( count > c->count*space_splitratio && c->count > space_splitsize ) {
...@@ -1113,7 +1112,7 @@ void space_split ( struct space *s , struct cell *c ) { ...@@ -1113,7 +1112,7 @@ void space_split ( struct space *s , struct cell *c ) {
temp->loc[2] += temp->h[2]; temp->loc[2] += temp->h[2];
temp->depth = c->depth + 1; temp->depth = c->depth + 1;
temp->split = 0; temp->split = 0;
temp->r_max = 0.0; temp->h_max = 0.0;
temp->parent = c; temp->parent = c;
c->progeny[k] = temp; c->progeny[k] = temp;
} }
...@@ -1237,7 +1236,7 @@ void space_init ( struct space *s , double dim[3] , struct part *parts , int N , ...@@ -1237,7 +1236,7 @@ void space_init ( struct space *s , double dim[3] , struct part *parts , int N ,
if ( h_cells < h_max ) if ( h_cells < h_max )
h_cells = h_max; h_cells = h_max;
for ( k = 0 ; k < 3 ; k++ ) { for ( k = 0 ; k < 3 ; k++ ) {
cdim[k] = ceil( dim[k] / h_cells ); cdim[k] = floor( dim[k] / h_cells );
h[k] = dim[k] / cdim[k]; h[k] = dim[k] / cdim[k];
ih[k] = 1.0 / h[k]; ih[k] = 1.0 / h[k];
} }
......
...@@ -24,10 +24,13 @@ ...@@ -24,10 +24,13 @@
#define space_maxdepth 10 #define space_maxdepth 10
#define space_cellallocchunk 1000 #define space_cellallocchunk 1000
#define space_splitratio 0.875 #define space_splitratio 0.875
#define space_splitsize_default 800 #define space_splitsize_default 400
#define space_dosub 1 #define space_dosub 1
/* Convert cell location to ID. */
#define cell_getid( cdim , i , j , k ) ( (int)(k) + (cdim)[2]*( (int)(j) + (cdim)[1]*(int)(i) ) )
/* Split size. */ /* Split size. */
extern int space_splitsize; extern int space_splitsize;
......
...@@ -66,6 +66,30 @@ void task_rmunlock( struct task *ta , struct task *tb ) { ...@@ -66,6 +66,30 @@ void task_rmunlock( struct task *ta , struct task *tb ) {
} }
/**
* @brief Remove an unlock_task from the given task.
*
* @param ta The unlocking #task.
* @param tb The #task that will be unlocked.
*
* Differs from #task_rmunlock in that it will not fail if
* the task @c tb is not in the unlocks of @c ta.
*/
void task_rmunlock_blind( struct task *ta , struct task *tb ) {
int k;
for ( k = 0 ; k < ta->nr_unlock_tasks ; k++ )
if ( ta->unlock_tasks[k] == tb ) {
ta->nr_unlock_tasks -= 1;
ta->unlock_tasks[k] = ta->unlock_tasks[ ta->nr_unlock_tasks ];
return;
}
}
/** /**
* @brief Add an unlock_task to the given task. * @brief Add an unlock_task to the given task.
* *
......
...@@ -62,4 +62,5 @@ struct task { ...@@ -62,4 +62,5 @@ struct task {
/* Function prototypes. */ /* Function prototypes. */
void task_rmunlock( struct task *ta , struct task *tb ); void task_rmunlock( struct task *ta , struct task *tb );
void task_rmunlock_blind( struct task *ta , struct task *tb );
void task_addunlock( struct task *ta , struct task *tb ); void task_addunlock( struct task *ta , struct task *tb );
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