diff --git a/configure.ac b/configure.ac index 9ec78c8b8b8168191df002a01ed5de6fb1580243..5851324ec76a466aa52f0cbecf972cf32d4a256f 100644 --- a/configure.ac +++ b/configure.ac @@ -226,6 +226,18 @@ if test "$enable_debugging_checks" = "yes"; then AC_DEFINE([SWIFT_DEBUG_CHECKS],1,[Enable expensive debugging]) fi +# Check whether we want to default to naive cell interactions +AC_ARG_ENABLE([naive-interactions], + [AS_HELP_STRING([--enable-naive-interactions], + [Activate use of naive cell interaction functions @<:@yes/no@:>@] + )], + [enable_naive_interactions="$enableval"], + [enable_naive_interactions="no"] +) +if test "$enable_naive_interactions" = "yes"; then + AC_DEFINE([SWIFT_USE_NAIVE_INTERACTIONS],1,[Enable use of naive cell interaction functions]) +fi + # Check if gravity force checks are on for some particles. AC_ARG_ENABLE([gravity-force-checks], [AS_HELP_STRING([--enable-gravity-force-checks], @@ -919,6 +931,7 @@ AC_MSG_RESULT([ Task debugging : $enable_task_debugging Threadpool debugging : $enable_threadpool_debugging Debugging checks : $enable_debugging_checks + Naive interactions : $enable_naive_interactions Gravity checks : $gravity_force_checks ------------------------]) diff --git a/examples/main.c b/examples/main.c index 56f463940d51cc1c30904c2472334768fa3d58d1..0d87ea350793e0d089b41d3bd05a68cd97753ef9 100644 --- a/examples/main.c +++ b/examples/main.c @@ -361,6 +361,13 @@ int main(int argc, char *argv[]) { message("WARNING: Debugging checks activated. Code will be slower !"); #endif +/* Do we have debugging checks ? */ +#ifdef SWIFT_USE_NAIVE_INTERACTIONS + if (myrank == 0) + message( + "WARNING: Naive cell interactions activated. Code will be slower !"); +#endif + /* Do we have gravity accuracy checks ? */ #ifdef SWIFT_GRAVITY_FORCE_CHECKS if (myrank == 0) diff --git a/src/runner_doiact.h b/src/runner_doiact.h index 473c0604ee60d755f8aef87a96a37bef30ca6279..bcbd0b7425747ea5e9cf0bcccb1d653d8b8d8126 100644 --- a/src/runner_doiact.h +++ b/src/runner_doiact.h @@ -50,6 +50,9 @@ #define _DOPAIR2_NAIVE(f) PASTE(runner_dopair2_naive, f) #define DOPAIR2_NAIVE _DOPAIR2_NAIVE(FUNCTION) +#define _DOSELF1_NAIVE(f) PASTE(runner_doself1_naive, f) +#define DOSELF1_NAIVE _DOSELF1_NAIVE(FUNCTION) + #define _DOSELF2_NAIVE(f) PASTE(runner_doself2_naive, f) #define DOSELF2_NAIVE _DOSELF2_NAIVE(FUNCTION) @@ -121,10 +124,6 @@ void DOPAIR1_NAIVE(struct runner *r, struct cell *restrict ci, const struct engine *e = r->e; -#ifndef SWIFT_DEBUG_CHECKS - error("Don't use in actual runs ! Slow code !"); -#endif - TIMER_TIC; /* Anything to do here? */ @@ -171,6 +170,14 @@ void DOPAIR1_NAIVE(struct runner *r, struct cell *restrict ci, float dx[3] = {pix[0] - pjx[0], pix[1] - pjx[1], pix[2] - pjx[2]}; const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hig2 && pi_active) { @@ -205,10 +212,6 @@ void DOPAIR2_NAIVE(struct runner *r, struct cell *restrict ci, const struct engine *e = r->e; -#ifndef SWIFT_DEBUG_CHECKS - error("Don't use in actual runs ! Slow code !"); -#endif - TIMER_TIC; /* Anything to do here? */ @@ -255,6 +258,14 @@ void DOPAIR2_NAIVE(struct runner *r, struct cell *restrict ci, float dx[3] = {pix[0] - pjx[0], pix[1] - pjx[1], pix[2] - pjx[2]}; const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hig2 || r2 < hjg2) { @@ -280,21 +291,17 @@ void DOPAIR2_NAIVE(struct runner *r, struct cell *restrict ci, } /** - * @brief Compute the interactions within a cell (symmetric case). + * @brief Compute the interactions within a cell (non-symmetric case). * * Inefficient version using a brute-force algorithm. * * @param r The #runner. * @param c The #cell. */ -void DOSELF2_NAIVE(struct runner *r, struct cell *restrict c) { +void DOSELF1_NAIVE(struct runner *r, struct cell *restrict c) { const struct engine *e = r->e; -#ifndef SWIFT_DEBUG_CHECKS - error("Don't use in actual runs ! Slow code !"); -#endif - TIMER_TIC; /* Anything to do here? */ @@ -308,10 +315,11 @@ void DOSELF2_NAIVE(struct runner *r, struct cell *restrict c) { /* Get a hold of the ith part in ci. */ struct part *restrict pi = &parts[pid]; - const double pix[3] = {pi->x[0], pi->x[1], pi->x[2]}; + const int pi_active = part_is_active(pi, e); const float hi = pi->h; const float hig2 = hi * hi * kernel_gamma2; - const int pi_active = part_is_active(pi, e); + const float pix[3] = {pi->x[0] - c->loc[0], pi->x[1] - c->loc[1], + pi->x[2] - c->loc[2]}; /* Loop over the parts in cj. */ for (int pjd = pid + 1; pjd < count; pjd++) { @@ -319,39 +327,121 @@ void DOSELF2_NAIVE(struct runner *r, struct cell *restrict c) { /* Get a pointer to the jth particle. */ struct part *restrict pj = &parts[pjd]; const float hj = pj->h; + const float hjg2 = hj * hj * kernel_gamma2; const int pj_active = part_is_active(pj, e); /* Compute the pairwise distance. */ - float r2 = 0.0f; - float dx[3]; - for (int k = 0; k < 3; k++) { - dx[k] = pix[k] - pj->x[k]; - r2 += dx[k] * dx[k]; + const float pjx[3] = {pj->x[0] - c->loc[0], pj->x[1] - c->loc[1], + pj->x[2] - c->loc[2]}; + float dx[3] = {pix[0] - pjx[0], pix[1] - pjx[1], pix[2] - pjx[2]}; + const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + + const int doi = pi_active && (r2 < hig2); + const int doj = pj_active && (r2 < hjg2); + +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + + /* Hit or miss? */ + if (doi && doj) { + + IACT(r2, dx, hi, hj, pi, pj); + } else if (doi) { + + IACT_NONSYM(r2, dx, hi, hj, pi, pj); + } else if (doj) { + + dx[0] = -dx[0]; + dx[1] = -dx[1]; + dx[2] = -dx[2]; + + IACT_NONSYM(r2, dx, hj, hi, pj, pi); } + } /* loop over the parts in cj. */ + } /* loop over the parts in ci. */ + + TIMER_TOC(TIMER_DOSELF); +} + +/** + * @brief Compute the interactions within a cell (symmetric case). + * + * Inefficient version using a brute-force algorithm. + * + * @param r The #runner. + * @param c The #cell. + */ +void DOSELF2_NAIVE(struct runner *r, struct cell *restrict c) { + + const struct engine *e = r->e; + + TIMER_TIC; + + /* Anything to do here? */ + if (!cell_is_active(c, e)) return; + + const int count = c->count; + struct part *restrict parts = c->parts; + + /* Loop over the parts in ci. */ + for (int pid = 0; pid < count; pid++) { + + /* Get a hold of the ith part in ci. */ + struct part *restrict pi = &parts[pid]; + const int pi_active = part_is_active(pi, e); + const float hi = pi->h; + const float hig2 = hi * hi * kernel_gamma2; + const float pix[3] = {pi->x[0] - c->loc[0], pi->x[1] - c->loc[1], + pi->x[2] - c->loc[2]}; + + /* Loop over the parts in cj. */ + for (int pjd = pid + 1; pjd < count; pjd++) { + + /* Get a pointer to the jth particle. */ + struct part *restrict pj = &parts[pjd]; + const float hj = pj->h; const float hjg2 = hj * hj * kernel_gamma2; + const int pj_active = part_is_active(pj, e); - /* Hit or miss? */ - if (r2 < hig2 || r2 < hjg2) { + /* Compute the pairwise distance. */ + const float pjx[3] = {pj->x[0] - c->loc[0], pj->x[1] - c->loc[1], + pj->x[2] - c->loc[2]}; + float dx[3] = {pix[0] - pjx[0], pix[1] - pjx[1], pix[2] - pjx[2]}; + const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; - if (pi_active && pj_active) { + const int doi = pi_active && ((r2 < hig2) || (r2 < hjg2)); + const int doj = pj_active && ((r2 < hig2) || (r2 < hjg2)); - IACT(r2, dx, hi, hj, pi, pj); - } else if (pi_active) { +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif - IACT_NONSYM(r2, dx, hi, hj, pi, pj); - } else if (pj_active) { + /* Hit or miss? */ + if (doi && doj) { - dx[0] = -dx[0]; - dx[1] = -dx[1]; - dx[2] = -dx[2]; + IACT(r2, dx, hi, hj, pi, pj); + } else if (doi) { - IACT_NONSYM(r2, dx, hj, hi, pj, pi); - } - } + IACT_NONSYM(r2, dx, hi, hj, pi, pj); + } else if (doj) { - } /* loop over the parts in cj. */ + dx[0] = -dx[0]; + dx[1] = -dx[1]; + dx[2] = -dx[2]; - } /* loop over the parts in ci. */ + IACT_NONSYM(r2, dx, hj, hi, pj, pi); + } + } /* loop over the parts in cj. */ + } /* loop over the parts in ci. */ TIMER_TOC(TIMER_DOSELF); } @@ -375,10 +465,6 @@ void DOPAIR_SUBSET_NAIVE(struct runner *r, struct cell *restrict ci, const struct engine *e = r->e; -#ifndef SWIFT_DEBUG_CHECKS - error("Don't use in actual runs ! Slow code !"); -#endif - TIMER_TIC; const int count_j = cj->count; @@ -459,6 +545,11 @@ void DOPAIR_SUBSET(struct runner *r, struct cell *restrict ci, const struct engine *e = r->e; +#ifdef SWIFT_USE_NAIVE_INTERACTIONS + DOPAIR_SUBSET_NAIVE(r, ci, parts_i, ind, count, cj); + return; +#endif + TIMER_TIC; const int count_j = cj->count; @@ -523,6 +614,14 @@ void DOPAIR_SUBSET(struct runner *r, struct cell *restrict ci, float dx[3] = {pix - pjx, piy - pjy, piz - pjz}; const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hig2) { @@ -562,6 +661,14 @@ void DOPAIR_SUBSET(struct runner *r, struct cell *restrict ci, float dx[3] = {pix - pjx, piy - pjy, piz - pjz}; const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hig2) { @@ -622,6 +729,14 @@ void DOSELF_SUBSET(struct runner *r, struct cell *restrict ci, float dx[3] = {pix[0] - pjx[0], pix[1] - pjx[1], pix[2] - pjx[2]}; const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 > 0.f && r2 < hig2) { @@ -647,8 +762,10 @@ void DOPAIR1(struct runner *r, struct cell *ci, struct cell *cj, const int sid, const struct engine *restrict e = r->e; - // DOPAIR1_NAIVE(r, ci, cj); - // return; +#ifdef SWIFT_USE_NAIVE_INTERACTIONS + DOPAIR1_NAIVE(r, ci, cj); + return; +#endif TIMER_TIC; @@ -869,8 +986,10 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) { struct engine *restrict e = r->e; - // DOPAIR2_NAIVE(r, ci, cj); - // return; +#ifdef SWIFT_USE_NAIVE_INTERACTIONS + DOPAIR2_NAIVE(r, ci, cj); + return; +#endif TIMER_TIC; @@ -1207,6 +1326,11 @@ void DOSELF1(struct runner *r, struct cell *restrict c) { const struct engine *e = r->e; +#ifdef SWIFT_USE_NAIVE_INTERACTIONS + DOSELF1_NAIVE(r, c); + return; +#endif + TIMER_TIC; if (!cell_is_active(c, e)) return; @@ -1339,6 +1463,11 @@ void DOSELF2(struct runner *r, struct cell *restrict c) { const struct engine *e = r->e; +#ifdef SWIFT_USE_NAIVE_INTERACTIONS + DOSELF2_NAIVE(r, c); + return; +#endif + TIMER_TIC; if (!cell_is_active(c, e)) return;