Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ghost communicator cleanup #3272

Merged
merged 9 commits into from
Oct 23, 2019
8 changes: 5 additions & 3 deletions src/core/cells.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,9 @@ void cells_resort_particles(int global_flag) {
#endif
}

ghost_communicator(&cell_structure.ghost_cells_comm);
ghost_communicator(&cell_structure.exchange_ghosts_comm);
ghost_communicator(&cell_structure.exchange_ghosts_comm, GHOSTTRANS_PARTNUM);
ghost_communicator(&cell_structure.exchange_ghosts_comm,
GHOSTTRANS_POSITION | GHOSTTRANS_PROPRTS);

/* Particles are now sorted, but Verlet lists are invalid
and p_old has to be reset. */
Expand Down Expand Up @@ -461,7 +462,8 @@ void cells_update_ghosts() {

} else
/* Communication step: ghost information */
ghost_communicator(&cell_structure.update_ghost_pos_comm);
ghost_communicator(&cell_structure.exchange_ghosts_comm,
GHOSTTRANS_POSITION);
}

Cell *find_current_cell(const Particle &p) {
Expand Down
4 changes: 0 additions & 4 deletions src/core/cells.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,8 @@ struct CellStructure {
/** returns the global ghost_cells */
CellPList ghost_cells() const;

/** Communicator to exchange ghost cell information. */
GhostCommunicator ghost_cells_comm;
/** Communicator to exchange ghost particles. */
GhostCommunicator exchange_ghosts_comm;
/** Communicator to update ghost positions. */
GhostCommunicator update_ghost_pos_comm;
/** Communicator to collect ghost forces. */
GhostCommunicator collect_ghost_force_comm;

Expand Down
77 changes: 22 additions & 55 deletions src/core/domain_decomposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ using Utils::get_linear_index;
#include "event.hpp"

#include <boost/mpi/collectives.hpp>
#include <boost/range/algorithm/reverse.hpp>

/** Returns pointer to the cell which corresponds to the position if the
* position is in the nodes spatial domain otherwise a nullptr pointer.
Expand Down Expand Up @@ -254,7 +255,7 @@ void dd_prepare_comm(GhostCommunicator *comm, int data_parts,
}

/* prepare communicator */
prepare_comm(comm, data_parts, num);
prepare_comm(comm, num);

/* number of cells to communicate in a direction */
n_comm_cells[0] = dd.cell_grid[1] * dd.cell_grid[2];
Expand Down Expand Up @@ -283,11 +284,8 @@ void dd_prepare_comm(GhostCommunicator *comm, int data_parts,
/* Buffer has to contain Send and Recv cells -> factor 2 */
comm->comm[cnt].part_lists.resize(2 * n_comm_cells[dir]);
/* prepare folding of ghost positions */
if ((data_parts & GHOSTTRANS_POSSHFTD) &&
local_geo.boundary()[2 * dir + lr] != 0) {
comm->comm[cnt].shift[dir] =
local_geo.boundary()[2 * dir + lr] * box_geo.length()[dir];
}
comm->comm[cnt].shift[dir] =
local_geo.boundary()[2 * dir + lr] * box_geo.length()[dir];

/* fill send comm cells */
lc[dir] = hc[dir] = 1 + lr * (dd.cell_grid[dir] - 1);
Expand All @@ -313,11 +311,8 @@ void dd_prepare_comm(GhostCommunicator *comm, int data_parts,
comm->comm[cnt].node = node_neighbors[2 * dir + lr];
comm->comm[cnt].part_lists.resize(n_comm_cells[dir]);
/* prepare folding of ghost positions */
if ((data_parts & GHOSTTRANS_POSSHFTD) &&
local_geo.boundary()[2 * dir + lr] != 0) {
comm->comm[cnt].shift[dir] =
local_geo.boundary()[2 * dir + lr] * box_geo.length()[dir];
}
comm->comm[cnt].shift[dir] =
local_geo.boundary()[2 * dir + lr] * box_geo.length()[dir];

lc[dir] = hc[dir] = 1 + lr * (dd.cell_grid[dir] - 1);

Expand Down Expand Up @@ -350,28 +345,18 @@ void dd_prepare_comm(GhostCommunicator *comm, int data_parts,
* communication types GHOST_SEND <-> GHOST_RECV.
*/
void dd_revert_comm_order(GhostCommunicator *comm) {
int i, j, nlist2;
GhostCommunication tmp;

/* revert order */
for (i = 0; i < (comm->num / 2); i++) {
tmp = comm->comm[i];
comm->comm[i] = comm->comm[comm->num - i - 1];
comm->comm[comm->num - i - 1] = tmp;
}
boost::reverse(comm->comm);

/* exchange SEND/RECV */
for (i = 0; i < comm->num; i++) {
if (comm->comm[i].type == GHOST_SEND)
comm->comm[i].type = GHOST_RECV;
else if (comm->comm[i].type == GHOST_RECV)
comm->comm[i].type = GHOST_SEND;
else if (comm->comm[i].type == GHOST_LOCL) {
nlist2 = comm->comm[i].part_lists.size() / 2;
for (j = 0; j < nlist2; j++) {
auto tmplist = comm->comm[i].part_lists[j];
comm->comm[i].part_lists[j] = comm->comm[i].part_lists[j + nlist2];
comm->comm[i].part_lists[j + nlist2] = tmplist;
}
for (auto &c : comm->comm) {
if (c.type == GHOST_SEND)
c.type = GHOST_RECV;
else if (c.type == GHOST_RECV)
c.type = GHOST_SEND;
else if (c.type == GHOST_LOCL) {
boost::reverse(c.part_lists);
}
}
}
Expand All @@ -380,22 +365,18 @@ void dd_revert_comm_order(GhostCommunicator *comm) {
* poststore
*/
void dd_assign_prefetches(GhostCommunicator *comm) {
int cnt;

for (cnt = 0; cnt < comm->num; cnt += 2) {
if (comm->comm[cnt].type == GHOST_RECV &&
comm->comm[cnt + 1].type == GHOST_SEND) {
comm->comm[cnt].type |= GHOST_PREFETCH | GHOST_PSTSTORE;
comm->comm[cnt + 1].type |= GHOST_PREFETCH | GHOST_PSTSTORE;
for (auto it = comm->comm.begin(); it != comm->comm.end(); it += 2) {
auto next = std::next(it);
if (it->type == GHOST_RECV && next->type == GHOST_SEND) {
it->type |= GHOST_PREFETCH | GHOST_PSTSTORE;
next->type |= GHOST_PREFETCH | GHOST_PSTSTORE;
}
}
}

/** update the 'shift' member of those GhostCommunicators, which use
* that value to speed up the folding process of its ghost members
* (see \ref dd_prepare_comm for the original), i.e. all which have
* GHOSTTRANS_POSSHFTD or'd into 'data_parts' upon execution of \ref
* dd_prepare_comm.
* (see \ref dd_prepare_comm for the original).
*/
void dd_update_communicators_w_boxl(const Utils::Vector3i &grid) {
int cnt = 0;
Expand All @@ -411,8 +392,6 @@ void dd_update_communicators_w_boxl(const Utils::Vector3i &grid) {
if (local_geo.boundary()[2 * dir + lr] != 0) {
cell_structure.exchange_ghosts_comm.comm[cnt].shift[dir] =
local_geo.boundary()[2 * dir + lr] * box_geo.length()[dir];
cell_structure.update_ghost_pos_comm.comm[cnt].shift[dir] =
local_geo.boundary()[2 * dir + lr] * box_geo.length()[dir];
}
cnt++;
}
Expand All @@ -427,8 +406,6 @@ void dd_update_communicators_w_boxl(const Utils::Vector3i &grid) {
if (local_geo.boundary()[2 * dir + lr] != 0) {
cell_structure.exchange_ghosts_comm.comm[cnt].shift[dir] =
local_geo.boundary()[2 * dir + lr] * box_geo.length()[dir];
cell_structure.update_ghost_pos_comm.comm[cnt].shift[dir] =
local_geo.boundary()[2 * dir + lr] * box_geo.length()[dir];
}
cnt++;
}
Expand Down Expand Up @@ -602,7 +579,6 @@ void dd_on_geometry_change(int flags, const Utils::Vector3i &grid,
void dd_topology_init(CellPList *old, const Utils::Vector3i &grid,
const double range) {
int c, p;
int exchange_data, update_data;

/* Min num cells can not be smaller than calc_processor_min_num_cells,
* but may be set to a larger value by the user for performance reasons. */
Expand All @@ -619,23 +595,16 @@ void dd_topology_init(CellPList *old, const Utils::Vector3i &grid,
dd_mark_cells();

/* create communicators */
dd_prepare_comm(&cell_structure.ghost_cells_comm, GHOSTTRANS_PARTNUM, grid);

exchange_data =
(GHOSTTRANS_PROPRTS | GHOSTTRANS_POSITION | GHOSTTRANS_POSSHFTD);
update_data = (GHOSTTRANS_POSITION | GHOSTTRANS_POSSHFTD);
const int exchange_data = (GHOSTTRANS_PROPRTS | GHOSTTRANS_POSITION);

dd_prepare_comm(&cell_structure.exchange_ghosts_comm, exchange_data, grid);
dd_prepare_comm(&cell_structure.update_ghost_pos_comm, update_data, grid);
dd_prepare_comm(&cell_structure.collect_ghost_force_comm, GHOSTTRANS_FORCE,
grid);

/* collect forces has to be done in reverted order! */
dd_revert_comm_order(&cell_structure.collect_ghost_force_comm);

dd_assign_prefetches(&cell_structure.ghost_cells_comm);
dd_assign_prefetches(&cell_structure.exchange_ghosts_comm);
dd_assign_prefetches(&cell_structure.update_ghost_pos_comm);
dd_assign_prefetches(&cell_structure.collect_ghost_force_comm);

dd_init_cell_interactions(grid);
Expand Down Expand Up @@ -663,9 +632,7 @@ void dd_topology_release() {
/* free ghost cell pointer list */
realloc_cellplist(&ghost_cells, ghost_cells.n = 0);
/* free ghost communicators */
free_comm(&cell_structure.ghost_cells_comm);
free_comm(&cell_structure.exchange_ghosts_comm);
free_comm(&cell_structure.update_ghost_pos_comm);
free_comm(&cell_structure.collect_ghost_force_comm);
}

Expand Down
6 changes: 4 additions & 2 deletions src/core/electrostatics_magnetostatics/icc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ int iccp3m_iteration(const ParticleRange &particles,

force_calc_iccp3m(particles, ghost_particles); /* Calculate electrostatic
forces (SR+LR) excluding source source interaction*/
ghost_communicator(&cell_structure.collect_ghost_force_comm);
ghost_communicator(&cell_structure.collect_ghost_force_comm,
GHOSTTRANS_FORCE);

double diff = 0;

Expand Down Expand Up @@ -172,7 +173,8 @@ int iccp3m_iteration(const ParticleRange &particles,
}
} /* cell particles */
/* Update charges on ghosts. */
ghost_communicator(&cell_structure.exchange_ghosts_comm);
ghost_communicator(&cell_structure.exchange_ghosts_comm,
GHOSTTRANS_PROPRTS);

iccp3m_cfg.citeration++;

Expand Down
3 changes: 2 additions & 1 deletion src/core/forces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ void force_calc(CellStructure &cell_structure) {
#endif

// Communication Step: ghost forces
ghost_communicator(&cell_structure.collect_ghost_force_comm);
ghost_communicator(&cell_structure.collect_ghost_force_comm,
GHOSTTRANS_FORCE);

// should be pretty late, since it needs to zero out the total force
comfixed.apply(comm_cart, particles);
Expand Down
27 changes: 8 additions & 19 deletions src/core/ghosts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,8 @@ struct BondArchiver {
bool ghosts_have_v = false;
bool ghosts_have_bonds = false;

void prepare_comm(GhostCommunicator *gcr, int data_parts, int num) {
void prepare_comm(GhostCommunicator *gcr, int num) {
assert(gcr);
gcr->data_parts = data_parts;
gcr->num = num;
gcr->comm.resize(num);
for (auto &ghost_comm : gcr->comm)
ghost_comm.shift.fill(0.0);
Expand Down Expand Up @@ -220,13 +218,11 @@ static void prepare_send_buffer(CommBuf &send_buffer,
bond_archiver << Utils::make_const_span(part.bl);
}
}
if (data_parts & GHOSTTRANS_POSSHFTD) {
if (data_parts & GHOSTTRANS_POSITION) {
/* ok, this is not nice, but perhaps fast */
auto pp = part.r;
pp.p += ghost_comm.shift;
archiver << pp;
} else if (data_parts & GHOSTTRANS_POSITION) {
archiver << part.r;
}
if (data_parts & GHOSTTRANS_MOMENTUM) {
archiver << part.m;
Expand Down Expand Up @@ -359,12 +355,11 @@ static void cell_cell_transfer(GhostCommunication &ghost_comm, int data_parts) {
part2.bl = part1.bl;
}
}
if (data_parts & GHOSTTRANS_POSSHFTD) {
if (data_parts & GHOSTTRANS_POSITION) {
/* ok, this is not nice, but perhaps fast */
part2.r = part1.r;
part2.r.p += ghost_comm.shift;
} else if (data_parts & GHOSTTRANS_POSITION)
part2.r = part1.r;
}
if (data_parts & GHOSTTRANS_MOMENTUM) {
part2.m = part1.m;
}
Expand Down Expand Up @@ -405,10 +400,6 @@ static bool is_poststorable(GhostCommunication const &ghost_comm) {
return is_recv_op(comm_type, node) && poststore;
}

void ghost_communicator(GhostCommunicator *gcr) {
ghost_communicator(gcr, gcr->data_parts);
}

void ghost_communicator(GhostCommunicator *gcr, int data_parts) {
static CommBuf send_buffer, recv_buffer;

Expand All @@ -417,8 +408,8 @@ void ghost_communicator(GhostCommunicator *gcr, int data_parts) {
if (ghosts_have_v && (data_parts & GHOSTTRANS_POSITION))
data_parts |= GHOSTTRANS_MOMENTUM;

for (int n = 0; n < gcr->num; n++) {
GhostCommunication &ghost_comm = gcr->comm[n];
for (auto it = gcr->comm.begin(); it != gcr->comm.end(); ++it) {
GhostCommunication &ghost_comm = *it;
int const comm_type = ghost_comm.type & GHOST_JOBMASK;

if (comm_type == GHOST_LOCL) {
Expand All @@ -442,8 +433,7 @@ void ghost_communicator(GhostCommunicator *gcr, int data_parts) {
} else if (prefetch) {
/* we do not send this time, let's look for a prefetch */
auto prefetch_ghost_comm =
std::find_if(std::next(gcr->comm.begin(), n + 1), gcr->comm.end(),
is_prefetchable);
std::find_if(std::next(it), gcr->comm.end(), is_prefetchable);
if (prefetch_ghost_comm != gcr->comm.end())
prepare_send_buffer(send_buffer, *prefetch_ghost_comm, data_parts);
}
Expand Down Expand Up @@ -506,8 +496,7 @@ void ghost_communicator(GhostCommunicator *gcr, int data_parts) {
* prefetch send. */
/* find previous action where we recv and which has PSTSTORE set */
auto poststore_ghost_comm = std::find_if(
std::make_reverse_iterator(std::next(gcr->comm.begin(), n)),
gcr->comm.rend(), is_poststorable);
std::make_reverse_iterator(it), gcr->comm.rend(), is_poststorable);

if (poststore_ghost_comm != gcr->comm.rend()) {
assert(recv_buffer.size() ==
Expand Down
29 changes: 5 additions & 24 deletions src/core/ghosts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,6 @@ further details.
#define GHOSTTRANS_PROPRTS 1
/// transfer \ref ParticlePosition
#define GHOSTTRANS_POSITION 2
/** flag for \ref GHOSTTRANS_POSITION, shift the positions by \ref
GhostCommunication::shift. Must be or'd together with \ref
GHOSTTRANS_POSITION */
#define GHOSTTRANS_POSSHFTD 4
/// transfer \ref ParticleMomentum
#define GHOSTTRANS_MOMENTUM 8
/// transfer \ref ParticleForce
Expand All @@ -152,30 +148,21 @@ further details.
/*@{*/

struct GhostCommunication {

/** Communication type. */
int type;
/** Node to communicate with (to use with all MPI operations). */
int node;

/** Pointer array to particle lists to communicate. */
std::vector<Cell *> part_lists;
std::vector<Cell *> part_lists = {};

/** if \ref GhostCommunicator::data_parts has \ref GHOSTTRANS_POSSHFTD, then
this is the shift vector. Normally this is an integer multiple of the box
length. The shift is done on the sender side */
Utils::Vector3d shift;
/** Position shift for ghost particles. The shift is done on the sender side.
*/
Utils::Vector3d shift = {};
};

/** Properties for a ghost communication. A ghost communication is defined */
struct GhostCommunicator {

/** Particle data parts to transfer */
int data_parts;

/** number of communication steps. */
int num;

/** List of ghost communications. */
std::vector<GhostCommunication> comm;
};
Expand All @@ -187,17 +174,11 @@ struct GhostCommunicator {
/*@{*/

/** Initialize a communicator. */
void prepare_comm(GhostCommunicator *gcr, int data_parts, int num);
void prepare_comm(GhostCommunicator *gcr, int num);

/** Free a communicator. */
void free_comm(GhostCommunicator *gcr);

/**
* @brief do a ghost communication with the data parts specified
* in the communicator.
*/
void ghost_communicator(GhostCommunicator *gcr);

/**
* @brief Do a ghost communication with caller specified data parts.
*/
Expand Down
Loading