Skip to content
Permalink
Browse files

Merge pull request #2598 from KaiSzuttor/grid_refactor

Grid refactor
  • Loading branch information...
KaiSzuttor committed Mar 15, 2019
2 parents e0db0e1 + 06ea142 commit f9f0d4139f43652784a8067aedf32661cd3d3f87
Showing with 197 additions and 181 deletions.
  1. +4 −4 src/core/cells.cpp
  2. +0 −1 src/core/cluster_analysis/Cluster.cpp
  3. +2 −2 src/core/communication.cpp
  4. +0 −1 src/core/cuda_interface.cpp
  5. +29 −26 src/core/domain_decomposition.cpp
  6. +5 −4 src/core/domain_decomposition.hpp
  7. +2 −2 src/core/electrostatics_magnetostatics/fft.cpp
  8. +1 −1 src/core/electrostatics_magnetostatics/fft.hpp
  9. +7 −6 src/core/electrostatics_magnetostatics/p3m-dipolar.cpp
  10. +1 −1 src/core/electrostatics_magnetostatics/p3m-dipolar.hpp
  11. +9 −9 src/core/electrostatics_magnetostatics/p3m.cpp
  12. +2 −2 src/core/electrostatics_magnetostatics/scafacos.cpp
  13. +4 −2 src/core/global.cpp
  14. +11 −11 src/core/grid.cpp
  15. +10 −9 src/core/grid.hpp
  16. +4 −3 src/core/grid_based_algorithms/halo.cpp
  17. +2 −1 src/core/grid_based_algorithms/halo.hpp
  18. +25 −19 src/core/grid_based_algorithms/lattice.cpp
  19. +6 −3 src/core/grid_based_algorithms/lattice.hpp
  20. +13 −10 src/core/grid_based_algorithms/lb.cpp
  21. +8 −8 src/core/grid_based_algorithms/lb_interface.cpp
  22. +1 −1 src/core/grid_based_algorithms/lb_interpolation.cpp
  23. +2 −2 src/core/grid_based_algorithms/lbboundaries.cpp
  24. +1 −1 src/core/integrate.cpp
  25. +2 −0 src/core/io/writer/h5md_core.cpp
  26. +1 −4 src/core/io/writer/h5md_core.hpp
  27. +4 −4 src/core/layered.cpp
  28. +1 −1 src/core/layered.hpp
  29. +1 −2 src/core/nonbonded_interactions/nonbonded_interaction_data.cpp
  30. +0 −1 src/core/object-in-fluid/membrane_collision.hpp
  31. +0 −1 src/core/observables/CylindricalLBVelocityProfile.hpp
  32. +0 −1 src/core/pair_criteria/pair_criteria.hpp
  33. +0 −1 src/core/polymer.cpp
  34. +0 −1 src/core/rotation.cpp
  35. +0 −1 src/core/statistics.hpp
  36. +0 −1 src/core/statistics_chain.cpp
  37. +1 −1 src/core/utils/NoOp.hpp
  38. +4 −2 src/core/virtual_sites/lb_inertialess_tracers.cpp
  39. +2 −1 src/python/espressomd/analyze.pyx
  40. +2 −3 src/python/espressomd/cellsystem.pxd
  41. +2 −1 src/python/espressomd/cellsystem.pyx
  42. +2 −1 src/python/espressomd/electrostatics.pyx
  43. +2 −8 src/python/espressomd/globals.pxd
  44. +13 −6 src/python/espressomd/globals.pyx
  45. +8 −0 src/python/espressomd/grid.pxd
  46. +0 −1 src/python/espressomd/lb.pyx
  47. +1 −1 src/python/espressomd/particle_data.pyx
  48. +2 −9 src/python/espressomd/system.pyx
@@ -196,13 +196,13 @@ void topology_init(int cs, CellPList *local) {
topology_init(cell_structure.type, local);
break;
case CELL_STRUCTURE_DOMDEC:
dd_topology_init(local);
dd_topology_init(local, node_grid);
break;
case CELL_STRUCTURE_NSQUARE:
nsq_topology_init(local);
break;
case CELL_STRUCTURE_LAYERED:
layered_topology_init(local);
layered_topology_init(local, node_grid);
break;
default:
fprintf(stderr,
@@ -369,7 +369,7 @@ void cells_resort_particles(int global_flag) {
nsq_balance_particles(global_flag);
break;
case CELL_STRUCTURE_DOMDEC:
dd_exchange_and_sort_particles(global_flag, &displaced_parts);
dd_exchange_and_sort_particles(global_flag, &displaced_parts, node_grid);
break;
}

@@ -418,7 +418,7 @@ void cells_on_geometry_change(int flags) {

switch (cell_structure.type) {
case CELL_STRUCTURE_DOMDEC:
dd_on_geometry_change(flags);
dd_on_geometry_change(flags, node_grid);
break;
case CELL_STRUCTURE_LAYERED:
/* there is no fast version, always redo everything. */
@@ -16,7 +16,6 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "grid.hpp"
#include "partCfg_global.hpp"
#include "particle_data.hpp"
#ifdef GSL
@@ -257,11 +257,11 @@ void mpi_init() {
#endif

MPI_Comm_size(MPI_COMM_WORLD, &n_nodes);
MPI_Dims_create(n_nodes, 3, node_grid);
MPI_Dims_create(n_nodes, 3, node_grid.data());

mpi_reshape_communicator({{node_grid[0], node_grid[1], node_grid[2]}},
/* periodicity */ {{1, 1, 1}});
MPI_Cart_coords(comm_cart, this_node, 3, node_pos);
MPI_Cart_coords(comm_cart, this_node, 3, node_pos.data());

Communication::m_callbacks =
Utils::make_unique<Communication::MpiCallbacks>(comm_cart);
@@ -25,7 +25,6 @@
#include "config.hpp"
#include "debug.hpp"
#include "energy.hpp"
#include "grid.hpp"
#include "nonbonded_interactions/nonbonded_interaction_data.hpp"
#include "serialization/CUDA_particle_data.hpp"

@@ -275,7 +275,8 @@ int dd_fill_comm_cell_lists(Cell **part_lists, int lc[3], int hc[3]) {
/** Create communicators for cell structure domain decomposition. (see \ref
* GhostCommunicator)
*/
void dd_prepare_comm(GhostCommunicator *comm, int data_parts) {
void dd_prepare_comm(GhostCommunicator *comm, int data_parts,
const Vector3i &grid) {
int dir, lr, i, cnt, num, n_comm_cells[3];
int lc[3], hc[3], done[3] = {0, 0, 0};

@@ -285,7 +286,7 @@ void dd_prepare_comm(GhostCommunicator *comm, int data_parts) {
for (lr = 0; lr < 2; lr++) {
/* No communication for border of non periodic direction */
if (PERIODIC(dir) || (boundary[2 * dir + lr] == 0)) {
if (node_grid[dir] == 1)
if (grid[dir] == 1)
num++;
else
num += 2;
@@ -316,7 +317,7 @@ void dd_prepare_comm(GhostCommunicator *comm, int data_parts) {
communication, simply by taking the lr loop only over one
value */
for (lr = 0; lr < 2; lr++) {
if (node_grid[dir] == 1) {
if (grid[dir] == 1) {
/* just copy cells on a single node */
if (PERIODIC(dir) || (boundary[2 * dir + lr] == 0)) {
comm->comm[cnt].type = GHOST_LOCL;
@@ -461,14 +462,14 @@ void dd_assign_prefetches(GhostCommunicator *comm) {
* GHOSTTRANS_POSSHFTD or'd into 'data_parts' upon execution of \ref
* dd_prepare_comm.
*/
void dd_update_communicators_w_boxl() {
void dd_update_communicators_w_boxl(const Vector3i &grid) {
int cnt = 0;

/* direction loop: x, y, z */
for (int dir = 0; dir < 3; dir++) {
/* lr loop: left right */
for (int lr = 0; lr < 2; lr++) {
if (node_grid[dir] == 1) {
if (grid[dir] == 1) {
if (PERIODIC(dir) || (boundary[2 * dir + lr] == 0)) {
/* prepare folding of ghost positions */
if (boundary[2 * dir + lr] != 0) {
@@ -508,11 +509,11 @@ void dd_update_communicators_w_boxl() {
* created list of interacting neighbor cells is used by the Verlet
* algorithm (see verlet.cpp) to build the verlet lists.
*/
void dd_init_cell_interactions() {
void dd_init_cell_interactions(const Vector3i &grid) {
int m, n, o, p, q, r, ind1, ind2;

for (int i = 0; i < 3; i++) {
if (dd.fully_connected[i] == true and node_grid[i] != 1) {
if (dd.fully_connected[i] == true and grid[i] != 1) {
runtimeErrorMsg()
<< "Node grid not compatible with fully_connected property";
}
@@ -597,7 +598,7 @@ Cell *dd_save_position_to_cell(const Vector3d &pos) {
/* Public Functions */
/************************************************************/

void dd_on_geometry_change(int flags) {
void dd_on_geometry_change(int flags, const Vector3i &grid) {
/* check that the CPU domains are still sufficiently large. */
for (int i = 0; i < 3; i++)
if (local_box_l[i] < max_range) {
@@ -612,7 +613,7 @@ void dd_on_geometry_change(int flags) {
fprintf(stderr, "%d: dd_on_geometry_change full redo\n", this_node));

/* Reset min num cells to default */
min_num_cells = calc_processor_min_num_cells();
min_num_cells = calc_processor_min_num_cells(grid);

cells_re_init(CELL_STRUCTURE_CURRENT);
return;
@@ -658,11 +659,11 @@ void dd_on_geometry_change(int flags) {
return;
}
}
dd_update_communicators_w_boxl();
dd_update_communicators_w_boxl(grid);
}

/************************************************************/
void dd_topology_init(CellPList *old) {
void dd_topology_init(CellPList *old, const Vector3i &grid) {
int c, p;
int exchange_data, update_data;

@@ -672,7 +673,7 @@ void dd_topology_init(CellPList *old) {

/* 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. */
min_num_cells = std::max(min_num_cells, calc_processor_min_num_cells());
min_num_cells = std::max(min_num_cells, calc_processor_min_num_cells(grid));

cell_structure.type = CELL_STRUCTURE_DOMDEC;
cell_structure.position_to_node = map_position_node_array;
@@ -684,15 +685,16 @@ void dd_topology_init(CellPList *old) {
dd_mark_cells();

/* create communicators */
dd_prepare_comm(&cell_structure.ghost_cells_comm, GHOSTTRANS_PARTNUM);
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);

dd_prepare_comm(&cell_structure.exchange_ghosts_comm, exchange_data);
dd_prepare_comm(&cell_structure.update_ghost_pos_comm, update_data);
dd_prepare_comm(&cell_structure.collect_ghost_force_comm, GHOSTTRANS_FORCE);
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);
@@ -702,7 +704,7 @@ void dd_topology_init(CellPList *old) {
dd_assign_prefetches(&cell_structure.update_ghost_pos_comm);
dd_assign_prefetches(&cell_structure.collect_ghost_force_comm);

dd_init_cell_interactions();
dd_init_cell_interactions(grid);

/* copy particles */
for (c = 0; c < old->n; c++) {
@@ -805,14 +807,14 @@ void move_left_or_right(ParticleList &src, ParticleList &left,
}
}

void exchange_neighbors(ParticleList *pl) {
void exchange_neighbors(ParticleList *pl, const Vector3i &grid) {
for (int dir = 0; dir < 3; dir++) {
/* Single node direction, no action needed. */
if (node_grid[dir] == 1) {
if (grid[dir] == 1) {
continue;
/* In this (common) case left and right neighbors are
the same, and we need only one communication */
} else if (node_grid[dir] == 2) {
} else if (grid[dir] == 2) {
ParticleList send_buf, recv_buf;
move_left_or_right(*pl, send_buf, send_buf, dir);

@@ -849,14 +851,15 @@ void exchange_neighbors(ParticleList *pl) {
}
} // namespace

void dd_exchange_and_sort_particles(int global, ParticleList *pl) {
void dd_exchange_and_sort_particles(int global, ParticleList *pl,
const Vector3i &grid) {
if (global) {
/* Worst case we need node_grid - 1 rounds per direction.
* This correctly implies that if there is only one node,
* no action should be taken. */
int rounds_left = node_grid[0] + node_grid[1] + node_grid[2] - 3;
int rounds_left = grid[0] + grid[1] + grid[2] - 3;
for (; rounds_left > 0; rounds_left--) {
exchange_neighbors(pl);
exchange_neighbors(pl, grid);

auto left_over =
boost::mpi::all_reduce(comm_cart, pl->n, std::plus<int>());
@@ -866,13 +869,13 @@ void dd_exchange_and_sort_particles(int global, ParticleList *pl) {
}
}
} else {
exchange_neighbors(pl);
exchange_neighbors(pl, grid);
}
}

/*************************************************/

int calc_processor_min_num_cells() {
int calc_processor_min_num_cells(const Vector3i &grid) {
int i, min = 1;
/* the minimal number of cells can be lower if there are at least two nodes
serving a direction,
@@ -881,7 +884,7 @@ int calc_processor_min_num_cells() {
only one processor for a direction, there have to be at least two cells for
this direction. */
for (i = 0; i < 3; i++)
if (node_grid[i] == 1)
if (grid[i] == 1)
min *= 2;
return min;
}
@@ -124,7 +124,7 @@ extern int min_num_cells;
* CELL_FLAG_GRIDCHANGED, see documentation of \ref
* cells_on_geometry_change.
*/
void dd_on_geometry_change(int flags);
void dd_on_geometry_change(int flags, const Vector3i &grid);

/** Initialize the topology. The argument is a list of cell pointers,
* containing particles that have to be sorted into new cells. The
@@ -135,7 +135,7 @@ void dd_on_geometry_change(int flags);
* @param cl List of cell pointers with particles to be stored in the
* new cell system.
*/
void dd_topology_init(CellPList *cl);
void dd_topology_init(CellPList *cl, const Vector3i &grid);

/** Called when the current cell structure is invalidated because for
* example the box length has changed. This procedure may NOT destroy
@@ -156,10 +156,11 @@ void dd_topology_release();
* particle moves)
* @param pl List of particles
*/
void dd_exchange_and_sort_particles(int global, ParticleList *pl);
void dd_exchange_and_sort_particles(int global, ParticleList *pl,
const Vector3i &grid);

/** calculate physical (processor) minimal number of cells */
int calc_processor_min_num_cells();
int calc_processor_min_num_cells(const Vector3i &grid);

/** Fill a communication cell pointer list. Fill the cell pointers of
* all cells which are inside a rectangular subgrid of the 3D cell
@@ -58,7 +58,7 @@ static void fft_back_grid_comm(fft_forw_plan plan_f, fft_back_plan plan_b,

int fft_init(double **data, int *ca_mesh_dim, int *ca_mesh_margin,
int *global_mesh_dim, double *global_mesh_off, int *ks_pnum,
fft_data_struct &fft) {
fft_data_struct &fft, const Vector3i &grid) {
int i, j;
/* helpers */
int mult[3];
@@ -80,7 +80,7 @@ int fft_init(double **data, int *ca_mesh_dim, int *ca_mesh_margin,
/* === node grids === */
/* real space node grid (n_grid[0]) */
for (i = 0; i < 3; i++) {
n_grid[0][i] = node_grid[i];
n_grid[0][i] = grid[i];
my_pos[0][i] = node_pos[i];
}
for (i = 0; i < n_nodes; i++) {
@@ -63,7 +63,7 @@
*/
int fft_init(double **data, int *ca_mesh_dim, int *ca_mesh_margin,
int *global_mesh_dim, double *global_mesh_off, int *ks_pnum,
fft_data_struct &fft);
fft_data_struct &fft, const Vector3i &grid);

/** perform the forward 3D FFT.
The assigned charges are in \a data. The result is also stored in \a data.
@@ -346,7 +346,7 @@ void dp3m_init() {
} else {
P3M_TRACE(fprintf(stderr, "%d: dp3m_init:\n", this_node));

if (dp3m_sanity_checks())
if (dp3m_sanity_checks(node_grid))
return;

P3M_TRACE(fprintf(stderr, "%d: dp3m_init: starting\n", this_node));
@@ -402,9 +402,10 @@ void dp3m_init() {
P3M_TRACE(fprintf(stderr, "%d: dp3m.rs_mesh ADR=%p\n", this_node,
(void *)dp3m.rs_mesh));

int ca_mesh_size = fft_init(&dp3m.rs_mesh, dp3m.local_mesh.dim,
dp3m.local_mesh.margin, dp3m.params.mesh,
dp3m.params.mesh_off, &dp3m.ks_pnum, dp3m.fft);
int ca_mesh_size =
fft_init(&dp3m.rs_mesh, dp3m.local_mesh.dim, dp3m.local_mesh.margin,
dp3m.params.mesh, dp3m.params.mesh_off, &dp3m.ks_pnum,
dp3m.fft, node_grid);
dp3m.ks_mesh = Utils::realloc(dp3m.ks_mesh, ca_mesh_size * sizeof(double));

for (n = 0; n < 3; n++)
@@ -2422,7 +2423,7 @@ bool dp3m_sanity_checks_boxl() {

/*****************************************************************************/

bool dp3m_sanity_checks() {
bool dp3m_sanity_checks(const Vector3i &grid) {
bool ret = false;

if (!PERIODIC(0) || !PERIODIC(1) || !PERIODIC(2)) {
@@ -2462,7 +2463,7 @@ bool dp3m_sanity_checks() {
runtimeErrorMsg() << "dipolar P3M_init: cao is not yet set";
ret = true;
}
if (node_grid[0] < node_grid[1] || node_grid[1] < node_grid[2]) {
if (grid[0] < grid[1] || grid[1] < grid[2]) {
runtimeErrorMsg()
<< "dipolar P3M_init: node grid must be sorted, largest first";
ret = true;
@@ -137,7 +137,7 @@ void dp3m_init(void);
void dp3m_scaleby_box_l();

/** Sanity checks */
bool dp3m_sanity_checks();
bool dp3m_sanity_checks(const Vector3i &grid);

/** Assign the physical dipoles using the tabulated assignment function.
* If Dstore_ca_frac is true, then the charge fractions are buffered in
Oops, something went wrong.

0 comments on commit f9f0d41

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.