Commit d959e046 authored by James Willis's avatar James Willis
Browse files

Created a branching function for DOPAIR2 to only call the vectorised function...

Created a branching function for DOPAIR2 to only call the vectorised function when vectorisation is enabled and call the serial version when corner cells interact. Moved some debug statements inside the branching functions.
parent 778a21b7
......@@ -1884,13 +1884,8 @@ void *runner_main(void *data) {
else if (t->subtype == task_subtype_gradient)
runner_dopair1_branch_gradient(r, ci, cj);
#endif
else if (t->subtype == task_subtype_force) {
#if defined(WITH_VECTORIZATION) && defined(GADGET2_SPH)
runner_dopair2_force_vec(r, ci, cj);
#else
runner_dopair2_force(r, ci, cj);
#endif
}
else if (t->subtype == task_subtype_force)
runner_dopair2_branch_force(r, ci, cj);
else if (t->subtype == task_subtype_grav)
runner_dopair_grav(r, ci, cj, 1);
else
......
......@@ -781,37 +781,6 @@ void DOPAIR1(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
const struct entry *restrict sort_j = cj->sort[sid];
#ifdef SWIFT_DEBUG_CHECKS
/* Check that the dx_max_sort values in the cell are indeed an upper
bound on particle movement. */
for (int pid = 0; pid < ci->count; pid++) {
const struct part *p = &ci->parts[sort_i[pid].i];
const float d = p->x[0] * runner_shift[sid][0] +
p->x[1] * runner_shift[sid][1] +
p->x[2] * runner_shift[sid][2];
if (fabsf(d - sort_i[pid].d) - ci->dx_max_sort >
1.0e-4 * max(fabsf(d), ci->dx_max_sort_old))
error(
"particle shift diff exceeds dx_max_sort in cell ci. ci->nodeID=%d "
"cj->nodeID=%d d=%e sort_i[pid].d=%e ci->dx_max_sort=%e "
"ci->dx_max_sort_old=%e",
ci->nodeID, cj->nodeID, d, sort_i[pid].d, ci->dx_max_sort,
ci->dx_max_sort_old);
}
for (int pjd = 0; pjd < cj->count; pjd++) {
const struct part *p = &cj->parts[sort_j[pjd].i];
const float d = p->x[0] * runner_shift[sid][0] +
p->x[1] * runner_shift[sid][1] +
p->x[2] * runner_shift[sid][2];
if (fabsf(d - sort_j[pjd].d) - cj->dx_max_sort >
1.0e-4 * max(fabsf(d), cj->dx_max_sort_old))
error(
"particle shift diff exceeds dx_max_sort in cell cj. cj->nodeID=%d "
"ci->nodeID=%d d=%e sort_j[pjd].d=%e cj->dx_max_sort=%e "
"cj->dx_max_sort_old=%e",
cj->nodeID, ci->nodeID, d, sort_j[pjd].d, cj->dx_max_sort,
cj->dx_max_sort_old);
}
/* Some constants used to checks that the parts are in the right frame */
const float shift_threshold_x =
2. * ci->width[0] + 2. * max(ci->dx_max_part, cj->dx_max_part);
......@@ -819,7 +788,6 @@ void DOPAIR1(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
2. * ci->width[1] + 2. * max(ci->dx_max_part, cj->dx_max_part);
const float shift_threshold_z =
2. * ci->width[2] + 2. * max(ci->dx_max_part, cj->dx_max_part);
#endif /* SWIFT_DEBUG_CHECKS */
/* Get some other useful values. */
......@@ -1028,6 +996,43 @@ void DOPAIR1_BRANCH(struct runner *r, struct cell *ci, struct cell *cj) {
cj->dx_max_sort_old > space_maxreldx * cj->dmin)
error("Interacting unsorted cells.");
#ifdef SWIFT_DEBUG_CHECKS
/* Pick-out the sorted lists. */
const struct entry *restrict sort_i = ci->sort[sid];
const struct entry *restrict sort_j = cj->sort[sid];
/* Check that the dx_max_sort values in the cell are indeed an upper
bound on particle movement. */
for (int pid = 0; pid < ci->count; pid++) {
const struct part *p = &ci->parts[sort_i[pid].i];
const float d = p->x[0] * runner_shift[sid][0] +
p->x[1] * runner_shift[sid][1] +
p->x[2] * runner_shift[sid][2];
if (fabsf(d - sort_i[pid].d) - ci->dx_max_sort >
1.0e-4 * max(fabsf(d), ci->dx_max_sort_old))
error(
"particle shift diff exceeds dx_max_sort in cell ci. ci->nodeID=%d "
"cj->nodeID=%d d=%e sort_i[pid].d=%e ci->dx_max_sort=%e "
"ci->dx_max_sort_old=%e",
ci->nodeID, cj->nodeID, d, sort_i[pid].d, ci->dx_max_sort,
ci->dx_max_sort_old);
}
for (int pjd = 0; pjd < cj->count; pjd++) {
const struct part *p = &cj->parts[sort_j[pjd].i];
const float d = p->x[0] * runner_shift[sid][0] +
p->x[1] * runner_shift[sid][1] +
p->x[2] * runner_shift[sid][2];
if (fabsf(d - sort_j[pjd].d) - cj->dx_max_sort >
1.0e-4 * max(fabsf(d), cj->dx_max_sort_old))
error(
"particle shift diff exceeds dx_max_sort in cell cj. cj->nodeID=%d "
"ci->nodeID=%d d=%e sort_j[pjd].d=%e cj->dx_max_sort=%e "
"cj->dx_max_sort_old=%e",
cj->nodeID, ci->nodeID, d, sort_j[pjd].d, cj->dx_max_sort,
cj->dx_max_sort_old);
}
#endif /* SWIFT_DEBUG_CHECKS */
#if defined(WITH_VECTORIZATION) && defined(GADGET2_SPH) && \
(DOPAIR1_BRANCH == runner_dopair1_density_branch)
if (!sort_is_corner(sid))
......@@ -1046,7 +1051,8 @@ void DOPAIR1_BRANCH(struct runner *r, struct cell *ci, struct cell *cj) {
* @param ci The first #cell.
* @param cj The second #cell.
*/
void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) {
void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
const double *shift) {
struct engine *restrict e = r->e;
......@@ -1057,25 +1063,7 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) {
TIMER_TIC;
/* Anything to do here? */
if (!cell_is_active(ci, e) && !cell_is_active(cj, e)) return;
if (!cell_are_part_drifted(ci, e) || !cell_are_part_drifted(cj, e))
error("Interacting undrifted cells.");
/* Get the shift ID. */
double shift[3] = {0.0, 0.0, 0.0};
const int sid = space_getsid(e->s, &ci, &cj, shift);
/* Have the cells been sorted? */
if (!(ci->sorted & (1 << sid)) ||
ci->dx_max_sort_old > space_maxreldx * ci->dmin)
error("Interacting unsorted cells.");
if (!(cj->sorted & (1 << sid)) ||
cj->dx_max_sort_old > space_maxreldx * cj->dmin)
error("Interacting unsorted cells.");
/* Get the cutoff shift. */
/* Get the cutoff shift. */
double rshift = 0.0;
for (int k = 0; k < 3; k++) rshift += shift[k] * runner_shift[sid][k];
......@@ -1504,36 +1492,74 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) {
*/
void DOPAIR2_BRANCH(struct runner *r, struct cell *ci, struct cell *cj) {
// const struct engine *restrict e = r->e;
//
// /* Anything to do here? */
// if (!cell_is_active(ci, e) && !cell_is_active(cj, e)) return;
//
// /* Check that cells are drifted. */
// if (!cell_are_part_drifted(ci, e) || !cell_are_part_drifted(cj, e))
// error("Interacting undrifted cells.");
//
// /* Get the sort ID. */
// double shift[3] = {0.0, 0.0, 0.0};
// const int sid = space_getsid(e->s, &ci, &cj, shift);
//
// /* Have the cells been sorted? */
// if (!(ci->sorted & (1 << sid)) ||
// ci->dx_max_sort_old > space_maxreldx * ci->dmin)
// error("Interacting unsorted cells.");
// if (!(cj->sorted & (1 << sid)) ||
// cj->dx_max_sort_old > space_maxreldx * cj->dmin)
// error("Interacting unsorted cells.");
//
//#if defined(WITH_VECTORIZATION) && defined(GADGET2_SPH) && \
// (DOPAIR2_BRANCH == runner_dopair2_force_branch)
// if (!sort_is_corner(sid))
// runner_dopair2_force_vec(r, ci, cj, sid, shift);
// else
// DOPAIR2(r, ci, cj, sid, shift);
//#else
// DOPAIR2(r, ci, cj, sid, shift);
//#endif
const struct engine *restrict e = r->e;
/* Anything to do here? */
if (!cell_is_active(ci, e) && !cell_is_active(cj, e)) return;
/* Check that cells are drifted. */
if (!cell_are_part_drifted(ci, e) || !cell_are_part_drifted(cj, e))
error("Interacting undrifted cells.");
/* Get the sort ID. */
double shift[3] = {0.0, 0.0, 0.0};
const int sid = space_getsid(e->s, &ci, &cj, shift);
/* Have the cells been sorted? */
if (!(ci->sorted & (1 << sid)) ||
ci->dx_max_sort_old > space_maxreldx * ci->dmin)
error("Interacting unsorted cells.");
if (!(cj->sorted & (1 << sid)) ||
cj->dx_max_sort_old > space_maxreldx * cj->dmin)
error("Interacting unsorted cells.");
#ifdef SWIFT_DEBUG_CHECKS
/* Pick-out the sorted lists. */
const struct entry *restrict sort_i = ci->sort[sid];
const struct entry *restrict sort_j = cj->sort[sid];
/* Check that the dx_max_sort values in the cell are indeed an upper
bound on particle movement. */
for (int pid = 0; pid < ci->count; pid++) {
const struct part *p = &ci->parts[sort_i[pid].i];
const float d = p->x[0] * runner_shift[sid][0] +
p->x[1] * runner_shift[sid][1] +
p->x[2] * runner_shift[sid][2];
if (fabsf(d - sort_i[pid].d) - ci->dx_max_sort >
1.0e-4 * max(fabsf(d), ci->dx_max_sort_old))
error(
"particle shift diff exceeds dx_max_sort in cell ci. ci->nodeID=%d "
"cj->nodeID=%d d=%e sort_i[pid].d=%e ci->dx_max_sort=%e "
"ci->dx_max_sort_old=%e",
ci->nodeID, cj->nodeID, d, sort_i[pid].d, ci->dx_max_sort,
ci->dx_max_sort_old);
}
for (int pjd = 0; pjd < cj->count; pjd++) {
const struct part *p = &cj->parts[sort_j[pjd].i];
const float d = p->x[0] * runner_shift[sid][0] +
p->x[1] * runner_shift[sid][1] +
p->x[2] * runner_shift[sid][2];
if (fabsf(d - sort_j[pjd].d) - cj->dx_max_sort >
1.0e-4 * max(fabsf(d), cj->dx_max_sort_old))
error(
"particle shift diff exceeds dx_max_sort in cell cj. cj->nodeID=%d "
"ci->nodeID=%d d=%e sort_j[pjd].d=%e cj->dx_max_sort=%e "
"cj->dx_max_sort_old=%e",
cj->nodeID, ci->nodeID, d, sort_j[pjd].d, cj->dx_max_sort,
cj->dx_max_sort_old);
}
#endif /* SWIFT_DEBUG_CHECKS */
#if defined(WITH_VECTORIZATION) && defined(GADGET2_SPH) && \
(DOPAIR2_BRANCH == runner_dopair2_force_branch)
if (!sort_is_corner(sid))
runner_dopair2_force_vec(r, ci, cj, sid, shift);
else
DOPAIR2(r, ci, cj, sid, shift);
#else
DOPAIR2(r, ci, cj, sid, shift);
#endif
}
/**
......@@ -2341,11 +2367,7 @@ void DOSUB_PAIR2(struct runner *r, struct cell *ci, struct cell *cj, int sid,
error("Interacting unsorted cells.");
/* Compute the interactions. */
#if defined(WITH_VECTORIZATION) && defined(GADGET2_SPH)
runner_dopair2_force_vec(r, ci, cj);
#else
DOPAIR2(r, ci, cj);
#endif
DOPAIR2_BRANCH(r, ci, cj);
}
if (gettimer) TIMER_TOC(TIMER_DOSUB_PAIR);
......
......@@ -368,7 +368,7 @@ populate_max_index_no_cache_force(const struct cell *ci, const struct cell *cj,
const double di_max, const double dj_min,
int *max_index_i, int *max_index_j,
int *init_pi, int *init_pj,
const struct engine *e) {
const timebin_t max_active_bin) {
const struct part *restrict parts_i = ci->parts;
const struct part *restrict parts_j = cj->parts;
......@@ -383,7 +383,7 @@ populate_max_index_no_cache_force(const struct cell *ci, const struct cell *cj,
while (first_pi > 0 && sort_i[first_pi - 1].d + dx_max + max(hi_max, hj_max) > dj_min) {
first_pi--;
/* Store the index of the particle if it is active. */
if (part_is_active(&parts_i[sort_i[first_pi].i], e)) active_id = first_pi;
if (part_is_active_no_debug(&parts_i[sort_i[first_pi].i], max_active_bin)) active_id = first_pi;
}
/* Set the first active pi in range of any particle in cell j. */
......@@ -428,7 +428,7 @@ populate_max_index_no_cache_force(const struct cell *ci, const struct cell *cj,
sort_j[last_pj + 1].d - max(hj_max, hi_max) - dx_max < di_max) {
last_pj++;
/* Store the index of the particle if it is active. */
if (part_is_active(&parts_j[sort_j[last_pj].i], e)) active_id = last_pj;
if (part_is_active_no_debug(&parts_j[sort_j[last_pj].i], max_active_bin)) active_id = last_pj;
}
/* Set the last active pj in range of any particle in cell i. */
......@@ -950,38 +950,6 @@ void runner_dopair1_density_vec(struct runner *r, struct cell *ci,
const struct entry *restrict sort_i = ci->sort[sid];
const struct entry *restrict sort_j = cj->sort[sid];
#ifdef SWIFT_DEBUG_CHECKS
/* Check that the dx_max_sort values in the cell are indeed an upper
bound on particle movement. */
for (int pid = 0; pid < ci->count; pid++) {
const struct part *p = &ci->parts[sort_i[pid].i];
const float d = p->x[0] * runner_shift[sid][0] +
p->x[1] * runner_shift[sid][1] +
p->x[2] * runner_shift[sid][2];
if (fabsf(d - sort_i[pid].d) - ci->dx_max_sort >
1.0e-4 * max(fabsf(d), ci->dx_max_sort_old))
error(
"particle shift diff exceeds dx_max_sort in cell ci. ci->nodeID=%d "
"cj->nodeID=%d d=%e sort_i[pid].d=%e ci->dx_max_sort=%e "
"ci->dx_max_sort_old=%e",
ci->nodeID, cj->nodeID, d, sort_i[pid].d, ci->dx_max_sort,
ci->dx_max_sort_old);
}
for (int pjd = 0; pjd < cj->count; pjd++) {
const struct part *p = &cj->parts[sort_j[pjd].i];
const float d = p->x[0] * runner_shift[sid][0] +
p->x[1] * runner_shift[sid][1] +
p->x[2] * runner_shift[sid][2];
if (fabsf(d - sort_j[pjd].d) - cj->dx_max_sort >
1.0e-4 * max(fabsf(d), cj->dx_max_sort_old))
error(
"particle shift diff exceeds dx_max_sort in cell cj. cj->nodeID=%d "
"ci->nodeID=%d d=%e sort_j[pjd].d=%e cj->dx_max_sort=%e "
"cj->dx_max_sort_old=%e",
cj->nodeID, ci->nodeID, d, sort_j[pjd].d, cj->dx_max_sort,
cj->dx_max_sort_old);
}
#endif /* SWIFT_DEBUG_CHECKS */
/* Get some other useful values. */
const int count_i = ci->count;
......@@ -1366,34 +1334,18 @@ void runner_dopair1_density_vec(struct runner *r, struct cell *ci,
* @param cj The second #cell.
*/
void runner_dopair2_force_vec(struct runner *r, struct cell *ci,
struct cell *cj) {
struct cell *cj, const int sid,
const double *shift) {
#ifdef WITH_VECTORIZATION
const struct engine *restrict e = r->e;
const timebin_t max_active_bin = e->max_active_bin;
vector v_hi, v_vix, v_viy, v_viz, v_hig2, v_r2;
vector v_rhoi, v_grad_hi, v_pOrhoi2, v_balsara_i, v_ci;
TIMER_TIC;
/* Anything to do here? */
if (!cell_is_active(ci, e) && !cell_is_active(cj, e)) return;
if (!cell_are_part_drifted(ci, e) || !cell_are_part_drifted(cj, e))
error("Interacting undrifted cells.");
/* Get the sort ID. */
double shift[3] = {0.0, 0.0, 0.0};
const int sid = space_getsid(e->s, &ci, &cj, shift);
/* Have the cells been sorted? */
if (!(ci->sorted & (1 << sid)) ||
ci->dx_max_sort_old > space_maxreldx * ci->dmin)
error("Interacting unsorted cells.");
if (!(cj->sorted & (1 << sid)) ||
cj->dx_max_sort_old > space_maxreldx * cj->dmin)
error("Interacting unsorted cells.");
/* Get the cutoff shift. */
double rshift = 0.0;
for (int k = 0; k < 3; k++) rshift += shift[k] * runner_shift[sid][k];
......@@ -1402,38 +1354,6 @@ void runner_dopair2_force_vec(struct runner *r, struct cell *ci,
const struct entry *restrict sort_i = ci->sort[sid];
const struct entry *restrict sort_j = cj->sort[sid];
#ifdef SWIFT_DEBUG_CHECKS
/* Check that the dx_max_sort values in the cell are indeed an upper
bound on particle movement. */
for (int pid = 0; pid < ci->count; pid++) {
const struct part *p = &ci->parts[sort_i[pid].i];
const float d = p->x[0] * runner_shift[sid][0] +
p->x[1] * runner_shift[sid][1] +
p->x[2] * runner_shift[sid][2];
if (fabsf(d - sort_i[pid].d) - ci->dx_max_sort >
1.0e-4 * max(fabsf(d), ci->dx_max_sort_old))
error(
"particle shift diff exceeds dx_max_sort in cell ci. ci->nodeID=%d "
"cj->nodeID=%d d=%e sort_i[pid].d=%e ci->dx_max_sort=%e "
"ci->dx_max_sort_old=%e",
ci->nodeID, cj->nodeID, d, sort_i[pid].d, ci->dx_max_sort,
ci->dx_max_sort_old);
}
for (int pjd = 0; pjd < cj->count; pjd++) {
const struct part *p = &cj->parts[sort_j[pjd].i];
const float d = p->x[0] * runner_shift[sid][0] +
p->x[1] * runner_shift[sid][1] +
p->x[2] * runner_shift[sid][2];
if (fabsf(d - sort_j[pjd].d) - cj->dx_max_sort >
1.0e-4 * max(fabsf(d), cj->dx_max_sort_old))
error(
"particle shift diff exceeds dx_max_sort in cell cj. cj->nodeID=%d "
"ci->nodeID=%d d=%e sort_j[pjd].d=%e cj->dx_max_sort=%e "
"cj->dx_max_sort_old=%e",
cj->nodeID, ci->nodeID, d, sort_j[pjd].d, cj->dx_max_sort,
cj->dx_max_sort_old);
}
#endif /* SWIFT_DEBUG_CHECKS */
/* Get some other useful values. */
const int count_i = ci->count;
......@@ -1447,32 +1367,38 @@ void runner_dopair2_force_vec(struct runner *r, struct cell *ci,
const double di_max = sort_i[count_i - 1].d - rshift;
const double dj_min = sort_j[0].d;
const float dx_max = (ci->dx_max_sort + cj->dx_max_sort);
const int active_ci = cell_is_active(ci, e);
const int active_cj = cell_is_active(cj, e);
/* Check if any particles are active and return if there are not. */
// int numActive = 0;
// for (int pid = count_i - 1;
// pid >= 0 && sort_i[pid].d + hi_max + dx_max > dj_min; pid--) {
// struct part *restrict pi = &parts_i[sort_i[pid].i];
// if (part_is_active(pi, e)) {
// numActive++;
// break;
// }
//}
// if (!numActive) {
// for (int pjd = 0; pjd < count_j && sort_j[pjd].d - hj_max - dx_max <
// di_max;
// pjd++) {
// struct part *restrict pj = &parts_j[sort_j[pjd].i];
// if (part_is_active(pj, e)) {
// numActive++;
// break;
// }
// }
//}
// if (numActive == 0) return;
int numActive = 0;
const double h_max = max(hi_max, hj_max);
if (active_ci) {
for (int pid = count_i - 1;
pid >= 0 && sort_i[pid].d + h_max + dx_max > dj_min; pid--) {
struct part *restrict pi = &parts_i[sort_i[pid].i];
if (part_is_active(pi, e)) {
numActive++;
break;
}
}
}
if (!numActive && active_cj) {
for (int pjd = 0; pjd < count_j && sort_j[pjd].d - h_max - dx_max < di_max;
pjd++) {
struct part *restrict pj = &parts_j[sort_j[pjd].i];
if (part_is_active_no_debug(pj, max_active_bin)) {
numActive++;
break;
}
}
}
if (numActive == 0) return;
/* Get both particle caches from the runner and re-allocate
* them if they are not big enough for the cells. */
struct cache *restrict ci_cache = &r->ci_cache;
......@@ -1497,7 +1423,7 @@ void runner_dopair2_force_vec(struct runner *r, struct cell *ci,
* pj that interacts with any particle in ci. */
populate_max_index_no_cache_force(ci, cj, sort_i, sort_j, dx_max, rshift,
hi_max_raw, hj_max_raw, hi_max, hj_max, di_max, dj_min, max_index_i,
max_index_j, &first_pi, &last_pj, e);
max_index_j, &first_pi, &last_pj, max_active_bin);
/* Limits of the outer loops. */
int first_pi_loop = first_pi;
......@@ -1519,7 +1445,7 @@ void runner_dopair2_force_vec(struct runner *r, struct cell *ci,
/* Get the number of particles read into the ci cache. */
int ci_cache_count = count_i - first_pi_align;
if (cell_is_active(ci, e)) {
if (active_ci) {
/* Loop over the parts in ci until nothing is within range in cj. */
for (int pid = count_i - 1; pid >= first_pi_loop; pid--) {
......@@ -1673,7 +1599,7 @@ void runner_dopair2_force_vec(struct runner *r, struct cell *ci,
} /* loop over the parts in ci. */
}
if (cell_is_active(cj, e)) {
if (active_cj) {
/* Loop over the parts in cj until nothing is within range in ci. */
for (int pjd = 0; pjd <= last_pj_loop; pjd++) {
......
......@@ -40,6 +40,7 @@ void runner_dopair1_density_vec(struct runner *r, struct cell *restrict ci,
struct cell *restrict cj, const int sid,
const double *shift);
void runner_dopair2_force_vec(struct runner *r, struct cell *restrict ci,
struct cell *restrict cj);
struct cell *restrict cj, const int sid,
const double *shift);
#endif /* SWIFT_RUNNER_VEC_H */
......@@ -33,15 +33,18 @@
#if defined(WITH_VECTORIZATION)
#define DOSELF2 runner_doself2_force_vec
#define DOPAIR2 runner_dopair2_force_vec
#define DOPAIR2 runner_dopair2_branch_force
#define DOSELF2_NAME "runner_doself2_force_vec"
#define DOPAIR2_NAME "runner_dopair2_force_vec"
#endif
#ifndef DOSELF2
#define DOSELF2 runner_doself2_force
#define DOPAIR2 runner_dopair2_force
#define DOSELF2_NAME "runner_doself2_density"
#endif
#ifndef DOPAIR2
#define DOPAIR2 runner_dopair2_branch_force
#define DOPAIR2_NAME "runner_dopair2_force"
#endif
......@@ -447,13 +450,11 @@ void dump_particle_fields(char *fileName, struct cell *main_cell,
}
/* Just a forward declaration... */
void runner_dopair1_density(struct runner *r, struct cell *ci, struct cell *cj);
void runner_dopair1_branch_density(struct runner *r, struct cell *ci,
struct cell *cj);
void runner_doself1_density(struct runner *r, struct cell *ci);
void runner_dopair2_force(struct runner *r, struct cell *ci, struct cell *cj);
void runner_dopair2_force_vec(struct runner *r, struct cell *ci,
struct cell *cj);
void runner_dopair2_branch_force(struct runner *r, struct cell *ci,
struct cell *cj);
void runner_doself2_force(struct runner *r, struct cell *ci);
void runner_doself2_force_vec(struct runner *r, struct cell *ci);
......
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