From 2fd327d05738ce6a87521f658256a81851947e88 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Tue, 9 Jul 2019 16:17:54 -0600 Subject: [PATCH 1/5] more robust version of atom exchange size --- src/BODY/body_nparticle.cpp | 1 + src/BODY/body_rounded_polygon.cpp | 1 + src/BODY/body_rounded_polyhedron.cpp | 1 + src/atom_vec.cpp | 2 ++ src/atom_vec.h | 2 ++ src/body.h | 2 ++ src/comm.cpp | 40 ++++++++++++++++++++++++++-- src/comm.h | 15 +++++++---- src/comm_brick.cpp | 30 +++++++++------------ src/comm_brick.h | 1 - src/comm_tiled.cpp | 30 +++++++++------------ src/comm_tiled.h | 1 - src/fix.cpp | 2 ++ src/fix.h | 2 ++ src/fix_neigh_history.cpp | 16 +++++------ src/fix_store.cpp | 1 + 16 files changed, 93 insertions(+), 54 deletions(-) diff --git a/src/BODY/body_nparticle.cpp b/src/BODY/body_nparticle.cpp index 10529ad3af..1a85531a31 100644 --- a/src/BODY/body_nparticle.cpp +++ b/src/BODY/body_nparticle.cpp @@ -44,6 +44,7 @@ BodyNparticle::BodyNparticle(LAMMPS *lmp, int narg, char **arg) : icp = new MyPoolChunk(1,1); dcp = new MyPoolChunk(3*nmin,3*nmax); + maxexchange = 1 + 3*nmax; // icp max + dcp max memory->create(imflag,nmax,"body/nparticle:imflag"); memory->create(imdata,nmax,4,"body/nparticle:imdata"); diff --git a/src/BODY/body_rounded_polygon.cpp b/src/BODY/body_rounded_polygon.cpp index d352c789d7..f4d9cede18 100644 --- a/src/BODY/body_rounded_polygon.cpp +++ b/src/BODY/body_rounded_polygon.cpp @@ -61,6 +61,7 @@ BodyRoundedPolygon::BodyRoundedPolygon(LAMMPS *lmp, int narg, char **arg) : icp = new MyPoolChunk(1,1); dcp = new MyPoolChunk(3*nmin+2*nmin+1+1,3*nmax+2*nmax+1+1); + maxexchange = 1 + 3*nmax+2*nmax+1+1; // icp max + dcp max memory->create(imflag,nmax,"body/rounded/polygon:imflag"); memory->create(imdata,nmax,7,"body/nparticle:imdata"); diff --git a/src/BODY/body_rounded_polyhedron.cpp b/src/BODY/body_rounded_polyhedron.cpp index 99a380a932..6d5824ecc5 100644 --- a/src/BODY/body_rounded_polyhedron.cpp +++ b/src/BODY/body_rounded_polyhedron.cpp @@ -61,6 +61,7 @@ BodyRoundedPolyhedron::BodyRoundedPolyhedron(LAMMPS *lmp, int narg, char **arg) icp = new MyPoolChunk(1,3); dcp = new MyPoolChunk(3*nmin+2+1+1, 3*nmax+2*nmax+MAX_FACE_SIZE*nmax+1+1); + maxexchange = 3 + 3*nmax+2*nmax+MAX_FACE_SIZE*nmax+1+1; // icp max + dcp max memory->create(imflag,2*nmax,"body/rounded/polyhedron:imflag"); memory->create(imdata,2*nmax,7,"body/polyhedron:imdata"); diff --git a/src/atom_vec.cpp b/src/atom_vec.cpp index d4bea15d0b..93433c6bea 100644 --- a/src/atom_vec.cpp +++ b/src/atom_vec.cpp @@ -34,6 +34,8 @@ AtomVec::AtomVec(LAMMPS *lmp) : Pointers(lmp) mass_type = dipole_type = 0; forceclearflag = 0; size_data_bonus = 0; + maxexchange = 0; + kokkosable = 0; nargcopy = 0; diff --git a/src/atom_vec.h b/src/atom_vec.h index 87fb35d9c7..e4e8014cd5 100644 --- a/src/atom_vec.h +++ b/src/atom_vec.h @@ -39,6 +39,8 @@ class AtomVec : protected Pointers { int size_data_vel; // number of values in Velocity line int size_data_bonus; // number of values in Bonus line int xcol_data; // column (1-N) where x is in Atom line + int maxexchange; // max size of exchanged atom + // only needs to be set if size > BUFEXTRA class Molecule **onemols; // list of molecules for style template int nset; // # of molecules in list diff --git a/src/body.h b/src/body.h index 59001620f8..7da08733c5 100644 --- a/src/body.h +++ b/src/body.h @@ -28,6 +28,8 @@ class Body : protected Pointers { char *style; int size_forward; // max extra values packed for comm int size_border; // max extra values packed for border comm + int maxexchange; // max size of exchanged atom + AtomVecBody *avec; // ptr to class that stores body bonus info Body(class LAMMPS *, int, char **); diff --git a/src/comm.cpp b/src/comm.cpp index 052de93793..0356f88be7 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -39,7 +39,7 @@ using namespace LAMMPS_NS; -#define BUFMIN 1000 // also in comm styles +#define BUFEXTRA 1024 enum{ONELEVEL,TWOLEVEL,NUMA,CUSTOM}; enum{CART,CARTREORDER,XYZ}; @@ -65,7 +65,10 @@ Comm::Comm(LAMMPS *lmp) : Pointers(lmp) outfile = NULL; recv_from_partition = send_to_partition = -1; otherflag = 0; - maxexchange_atom = maxexchange_fix = 0; + + maxexchange = maxexchange_atom = maxexchange_fix = 0; + maxexchange_fix_dynamic = 0; + bufextra = BUFEXTRA; grid2proc = NULL; xsplit = ysplit = zsplit = NULL; @@ -225,6 +228,39 @@ void Comm::init() if (force->newton == 0) maxreverse = 0; if (force->pair) maxreverse = MAX(maxreverse,force->pair->comm_reverse_off); + + // maxexchange_atom = size of an exchanged atom, set by AtomVec + // only needs to be set if size > BUFEXTRA + // maxexchange_fix_dynamic = 1 if any fix sets its maxexchange dynamically + + maxexchange_atom = atom->avec->maxexchange; + + int nfix = modify->nfix; + Fix **fix = modify->fix; + + maxexchange_fix_dynamic = 0; + for (int i = 0; i < nfix; i++) + if (fix[i]->maxexchange_dynamic) maxexchange_fix_dynamic = 1; +} + +/* ---------------------------------------------------------------------- + set maxexchange based on AtomVec and fixes +------------------------------------------------------------------------- */ + +void Comm::init_exchange() +{ + int nfix = modify->nfix; + Fix **fix = modify->fix; + + int onefix; + maxexchange_fix = 0; + for (int i = 0; i < nfix; i++) { + onefix = fix[i]->maxexchange; + maxexchange_fix = MAX(maxexchange_fix,onefix); + } + + maxexchange = maxexchange_atom + maxexchange_fix; + bufextra = maxexchange + BUFEXTRA; } /* ---------------------------------------------------------------------- diff --git a/src/comm.h b/src/comm.h index 30360b1059..3367051e3c 100644 --- a/src/comm.h +++ b/src/comm.h @@ -38,9 +38,8 @@ class Comm : protected Pointers { // -1 if no recv or send int other_partition_style; // 0 = recv layout dims must be multiple of // my layout dims - int maxexchange_atom; // max contribution to exchange from AtomVec - int maxexchange_fix; // max contribution to exchange from Fixes - int nthreads; // OpenMP threads per MPI process + + int nthreads; // OpenMP threads per MPI process // public settings specific to layout = UNIFORM, NONUNIFORM @@ -130,8 +129,13 @@ class Comm : protected Pointers { int size_reverse; // # of datums in reverse comm int size_border; // # of datums in forward border comm - int maxforward,maxreverse; // max # of datums in forward/reverse comm - int maxexchange; // max # of datums/atom in exchange comm + int maxforward,maxreverse; // max # of datums in forward/reverse comm + int maxexchange; // max size of one exchanged atom + int maxexchange_atom; // contribution to maxexchange from AtomVec + int maxexchange_fix; // static contribution to maxexchange from Fixes + int maxexchange_fix_dynamic; // 1 if a fix has a dynamic contribution + int bufextra; // augment size of send buf for an exchange atom + int gridflag; // option for creating 3d grid int mapflag; // option for mapping procs to 3d grid @@ -147,6 +151,7 @@ class Comm : protected Pointers { int coregrid[3]; // 3d grid of cores within a node int user_coregrid[3]; // user request for cores in each dim + void init_exchange(); int rendezvous_irregular(int, char *, int, int, int *, int (*)(int, char *, int &, int *&, char *&, void *), int, char *&, int, void *, int); diff --git a/src/comm_brick.cpp b/src/comm_brick.cpp index 330551aaed..97114e5734 100644 --- a/src/comm_brick.cpp +++ b/src/comm_brick.cpp @@ -42,8 +42,7 @@ using namespace LAMMPS_NS; #define BUFFACTOR 1.5 -#define BUFMIN 1000 -#define BUFEXTRA 1000 +#define BUFMIN 1024 #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ @@ -110,14 +109,6 @@ void CommBrick::init_buffers() multilo = multihi = NULL; cutghostmulti = NULL; - // bufextra = max size of one exchanged atom - // = allowed overflow of sendbuf in exchange() - // atomvec, fix reset these 2 maxexchange values if needed - // only necessary if their size > BUFEXTRA - - maxexchange = maxexchange_atom + maxexchange_fix; - bufextra = maxexchange + BUFEXTRA; - maxsend = BUFMIN; memory->create(buf_send,maxsend+bufextra,"comm:buf_send"); maxrecv = BUFMIN; @@ -141,6 +132,10 @@ void CommBrick::init() { Comm::init(); + int bufextra_old = bufextra; + init_exchange(); + if (bufextra > bufextra_old) grow_send(maxsend+bufextra,0); + // memory for multi-style communication if (mode == Comm::MULTI && multilo == NULL) { @@ -603,15 +598,14 @@ void CommBrick::exchange() atom->nghost = 0; atom->avec->clear_bonus(); - // insure send buf is large enough for single atom - // bufextra = max size of one atom = allowed overflow of sendbuf - // fixes can change per-atom size requirement on-the-fly + // insure send buf has extra space for a single atom + // only need to reset if a fix can dynamically add to size of single atom - int bufextra_old = bufextra; - maxexchange = maxexchange_atom + maxexchange_fix; - bufextra = maxexchange + BUFEXTRA; - if (bufextra > bufextra_old) - grow_send(maxsend+bufextra,1); + if (maxexchange_fix_dynamic) { + int bufextra_old = bufextra; + init_exchange(); + if (bufextra > bufextra_old) grow_send(maxsend+bufextra,0); + } // subbox bounds for orthogonal or triclinic diff --git a/src/comm_brick.h b/src/comm_brick.h index b3a3a7e094..05268da63e 100644 --- a/src/comm_brick.h +++ b/src/comm_brick.h @@ -74,7 +74,6 @@ class CommBrick : public Comm { double *buf_send; // send buffer for all comm double *buf_recv; // recv buffer for all comm int maxsend,maxrecv; // current size of send/recv buffer - int bufextra; // extra space beyond maxsend in send buffer int smax,rmax; // max size in atoms of single borders send/recv // NOTE: init_buffers is called from a constructor and must not be made virtual diff --git a/src/comm_tiled.cpp b/src/comm_tiled.cpp index d1d625445a..c9f1a63fbc 100644 --- a/src/comm_tiled.cpp +++ b/src/comm_tiled.cpp @@ -32,8 +32,7 @@ using namespace LAMMPS_NS; #define BUFFACTOR 1.5 #define BUFFACTOR 1.5 -#define BUFMIN 1000 -#define BUFEXTRA 1000 +#define BUFMIN 1024 #define EPSILON 1.0e-6 #define DELTA_PROCS 16 @@ -80,14 +79,6 @@ CommTiled::~CommTiled() void CommTiled::init_buffers() { - // bufextra = max size of one exchanged atom - // = allowed overflow of sendbuf in exchange() - // atomvec, fix reset these 2 maxexchange values if needed - // only necessary if their size > BUFEXTRA - - maxexchange = maxexchange_atom + maxexchange_fix; - bufextra = maxexchange + BUFEXTRA; - maxsend = BUFMIN; memory->create(buf_send,maxsend+bufextra,"comm:buf_send"); maxrecv = BUFMIN; @@ -108,6 +99,10 @@ void CommTiled::init() { Comm::init(); + int bufextra_old = bufextra; + init_exchange(); + if (bufextra > bufextra_old) grow_send(maxsend+bufextra,0); + // temporary restrictions if (triclinic) @@ -644,15 +639,14 @@ void CommTiled::exchange() atom->nghost = 0; atom->avec->clear_bonus(); - // insure send buf is large enough for single atom - // bufextra = max size of one atom = allowed overflow of sendbuf - // fixes can change per-atom size requirement on-the-fly + // insure send buf has extra space for a single atom + // only need to reset if a fix can dynamically add to size of single atom - int bufextra_old = bufextra; - maxexchange = maxexchange_atom + maxexchange_fix; - bufextra = maxexchange + BUFEXTRA; - if (bufextra > bufextra_old) - memory->grow(buf_send,maxsend+bufextra,"comm:buf_send"); + if (maxexchange_fix_dynamic) { + int bufextra_old = bufextra; + init_exchange(); + if (bufextra > bufextra_old) grow_send(maxsend+bufextra,1); + } // domain properties used in exchange method and methods it calls // subbox bounds for orthogonal or triclinic diff --git a/src/comm_tiled.h b/src/comm_tiled.h index 13ecbc4b01..679be195aa 100644 --- a/src/comm_tiled.h +++ b/src/comm_tiled.h @@ -87,7 +87,6 @@ class CommTiled : public Comm { double *buf_send; // send buffer for all comm double *buf_recv; // recv buffer for all comm int maxsend,maxrecv; // current size of send/recv buffer - int bufextra; // extra space beyond maxsend in send buffer int smaxone,rmaxone; // max size in atoms of single borders send/recv int smaxall,rmaxall; // max size in atoms of any borders send/recv // for comm to all procs in one swap diff --git a/src/fix.cpp b/src/fix.cpp index 634bc2393d..2a94340842 100644 --- a/src/fix.cpp +++ b/src/fix.cpp @@ -78,6 +78,8 @@ Fix::Fix(LAMMPS *lmp, int /*narg*/, char **arg) : enforce2d_flag = 0; respa_level_support = 0; respa_level = -1; + maxexchange = 0; + maxexchange_dynamic = 0; scalar_flag = vector_flag = array_flag = 0; peratom_flag = local_flag = 0; diff --git a/src/fix.h b/src/fix.h index 7eaff38bd3..f4bf7f9c01 100644 --- a/src/fix.h +++ b/src/fix.h @@ -56,6 +56,8 @@ class Fix : protected Pointers { int enforce2d_flag; // 1 if has enforce2d method int respa_level_support; // 1 if fix supports fix_modify respa int respa_level; // which respa level to apply fix (1-Nrespa) + int maxexchange; // max # of per-atom values for Comm::exchange() + int maxexchange_dynamic; // 1 if fix sets maxexchange dynamically int scalar_flag; // 0/1 if compute_scalar() function exists int vector_flag; // 0/1 if compute_vector() function exists diff --git a/src/fix_neigh_history.cpp b/src/fix_neigh_history.cpp index 207c409596..7405b6d81f 100644 --- a/src/fix_neigh_history.cpp +++ b/src/fix_neigh_history.cpp @@ -42,6 +42,7 @@ FixNeighHistory::FixNeighHistory(LAMMPS *lmp, int narg, char **arg) : restart_peratom = 1; create_attribute = 1; + maxexchange_dynamic = 1; newton_pair = force->newton_pair; @@ -296,11 +297,11 @@ void FixNeighHistory::pre_exchange_onesided() } // set maxpartner = max # of partners of any owned atom - // bump up comm->maxexchange_fix if necessary + // maxexchange = max # of values for any Comm::exchange() atom maxpartner = 0; for (i = 0; i < nlocal_neigh; i++) maxpartner = MAX(maxpartner,npartner[i]); - comm->maxexchange_fix = MAX(comm->maxexchange_fix,(dnum+1)*maxpartner+1); + maxexchange = (dnum+1)*maxpartner + 1; // zero npartner values from previous nlocal_neigh to current nlocal @@ -424,11 +425,11 @@ void FixNeighHistory::pre_exchange_newton() comm->reverse_comm_fix_variable(this); // set maxpartner = max # of partners of any owned atom - // bump up comm->maxexchange_fix if necessary + // maxexchange = max # of values for any Comm::exchange() atom maxpartner = 0; for (i = 0; i < nlocal_neigh; i++) maxpartner = MAX(maxpartner,npartner[i]); - comm->maxexchange_fix = MAX(comm->maxexchange_fix,(dnum+1)*maxpartner+1); + maxexchange = (dnum+1)*maxpartner + 1; // zero npartner values from previous nlocal_neigh to current nlocal @@ -531,11 +532,11 @@ void FixNeighHistory::pre_exchange_no_newton() } // set maxpartner = max # of partners of any owned atom - // bump up comm->maxexchange_fix if necessary + // maxexchange = max # of values for any Comm::exchange() atom maxpartner = 0; for (i = 0; i < nlocal_neigh; i++) maxpartner = MAX(maxpartner,npartner[i]); - comm->maxexchange_fix = MAX(comm->maxexchange_fix,(dnum+1)*maxpartner+1); + maxexchange = (dnum+1)*maxpartner + 1; // zero npartner values from previous nlocal_neigh to current nlocal @@ -796,9 +797,6 @@ void FixNeighHistory::unpack_reverse_comm(int n, int *list, double *buf) int FixNeighHistory::pack_exchange(int i, double *buf) { - // NOTE: how do I know comm buf is big enough if extreme # of touching neighs - // Comm::BUFEXTRA may need to be increased - int m = 0; buf[m++] = npartner[i]; for (int n = 0; n < npartner[i]; n++) { diff --git a/src/fix_store.cpp b/src/fix_store.cpp index 9db65d0987..941132a837 100644 --- a/src/fix_store.cpp +++ b/src/fix_store.cpp @@ -106,6 +106,7 @@ vstore(NULL), astore(NULL), rbuf(NULL) for (int i = 0; i < nlocal; i++) for (int j = 0; j < nvalues; j++) astore[i][j] = 0.0; + maxexchange = nvalues; } } From 89af88bd10343585de91b695c0348252f109f04e Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 10 Jul 2019 08:41:27 -0600 Subject: [PATCH 2/5] more changes to robustify comm buf_send length --- src/atom_vec_hybrid.cpp | 3 ++ src/comm.h | 2 +- src/comm_brick.cpp | 27 ++++++++++------- src/comm_tiled.cpp | 23 +++++++++------ src/irregular.cpp | 64 ++++++++++++++++++++++++++++++++--------- src/irregular.h | 2 ++ 6 files changed, 87 insertions(+), 34 deletions(-) diff --git a/src/atom_vec_hybrid.cpp b/src/atom_vec_hybrid.cpp index a7816efbed..d0e8ed62ed 100644 --- a/src/atom_vec_hybrid.cpp +++ b/src/atom_vec_hybrid.cpp @@ -95,6 +95,7 @@ void AtomVecHybrid::process_args(int narg, char **arg) size_data_atom = 5; size_data_vel = 4; xcol_data = 3; + maxexchange = 0; for (int k = 0; k < nstyles; k++) { if ((styles[k]->molecular == 1 && molecular == 2) || @@ -120,6 +121,8 @@ void AtomVecHybrid::process_args(int narg, char **arg) size_border += styles[k]->size_border - 6; size_data_atom += styles[k]->size_data_atom - 5; size_data_vel += styles[k]->size_data_vel - 4; + + maxexchange += styles[k]->maxexchange; } size_velocity = 3; diff --git a/src/comm.h b/src/comm.h index 3367051e3c..967af0a014 100644 --- a/src/comm.h +++ b/src/comm.h @@ -134,7 +134,7 @@ class Comm : protected Pointers { int maxexchange_atom; // contribution to maxexchange from AtomVec int maxexchange_fix; // static contribution to maxexchange from Fixes int maxexchange_fix_dynamic; // 1 if a fix has a dynamic contribution - int bufextra; // augment size of send buf for an exchange atom + int bufextra; // augment send buf size for an exchange atom int gridflag; // option for creating 3d grid diff --git a/src/comm_brick.cpp b/src/comm_brick.cpp index 97114e5734..5c5fec47c0 100644 --- a/src/comm_brick.cpp +++ b/src/comm_brick.cpp @@ -109,9 +109,9 @@ void CommBrick::init_buffers() multilo = multihi = NULL; cutghostmulti = NULL; - maxsend = BUFMIN; - memory->create(buf_send,maxsend+bufextra,"comm:buf_send"); - maxrecv = BUFMIN; + buf_send = buf_recv = NULL; + maxsend = maxrecv = BUFMIN; + grow_send(maxsend,2); memory->create(buf_recv,maxrecv,"comm:buf_recv"); nswap = 0; @@ -134,7 +134,7 @@ void CommBrick::init() int bufextra_old = bufextra; init_exchange(); - if (bufextra > bufextra_old) grow_send(maxsend+bufextra,0); + if (bufextra > bufextra_old) grow_send(maxsend+bufextra,2); // memory for multi-style communication @@ -604,7 +604,7 @@ void CommBrick::exchange() if (maxexchange_fix_dynamic) { int bufextra_old = bufextra; init_exchange(); - if (bufextra > bufextra_old) grow_send(maxsend+bufextra,0); + if (bufextra > bufextra_old) grow_send(maxsend+bufextra,2); } // subbox bounds for orthogonal or triclinic @@ -1346,18 +1346,23 @@ int CommBrick::exchange_variable(int n, double *inbuf, double *&outbuf) /* ---------------------------------------------------------------------- realloc the size of the send buffer as needed with BUFFACTOR and bufextra - if flag = 1, realloc - if flag = 0, don't need to realloc with copy, just free/malloc + flag = 0, don't need to realloc with copy, just free/malloc w/ BUFFACTOR + flag = 1, realloc with BUFFACTOR + flag = 2, free/malloc w/out BUFFACTOR ------------------------------------------------------------------------- */ void CommBrick::grow_send(int n, int flag) { - maxsend = static_cast (BUFFACTOR * n); - if (flag) - memory->grow(buf_send,maxsend+bufextra,"comm:buf_send"); - else { + if (flag == 0) { + maxsend = static_cast (BUFFACTOR * n); memory->destroy(buf_send); memory->create(buf_send,maxsend+bufextra,"comm:buf_send"); + } else if (flag == 1) { + maxsend = static_cast (BUFFACTOR * n); + memory->grow(buf_send,maxsend+bufextra,"comm:buf_send"); + } else { + memory->destroy(buf_send); + memory->grow(buf_send,maxsend+bufextra,"comm:buf_send"); } } diff --git a/src/comm_tiled.cpp b/src/comm_tiled.cpp index c9f1a63fbc..2e04aa2978 100644 --- a/src/comm_tiled.cpp +++ b/src/comm_tiled.cpp @@ -79,9 +79,9 @@ CommTiled::~CommTiled() void CommTiled::init_buffers() { - maxsend = BUFMIN; - memory->create(buf_send,maxsend+bufextra,"comm:buf_send"); - maxrecv = BUFMIN; + buf_send = buf_recv = NULL; + maxsend = maxrecv = BUFMIN; + grow_send(maxsend,2); memory->create(buf_recv,maxrecv,"comm:buf_recv"); maxoverlap = 0; @@ -1804,18 +1804,23 @@ int CommTiled::coord2proc(double *x, int &igx, int &igy, int &igz) /* ---------------------------------------------------------------------- realloc the size of the send buffer as needed with BUFFACTOR and bufextra - if flag = 1, realloc - if flag = 0, don't need to realloc with copy, just free/malloc + flag = 0, don't need to realloc with copy, just free/malloc w/ BUFFACTOR + flag = 1, realloc with BUFFACTOR + flag = 2, free/malloc w/out BUFFACTOR ------------------------------------------------------------------------- */ void CommTiled::grow_send(int n, int flag) { - maxsend = static_cast (BUFFACTOR * n); - if (flag) - memory->grow(buf_send,maxsend+bufextra,"comm:buf_send"); - else { + if (flag == 0) { + maxsend = static_cast (BUFFACTOR * n); memory->destroy(buf_send); memory->create(buf_send,maxsend+bufextra,"comm:buf_send"); + } else if (flag == 1) { + maxsend = static_cast (BUFFACTOR * n); + memory->grow(buf_send,maxsend+bufextra,"comm:buf_send"); + } else { + memory->destroy(buf_send); + memory->grow(buf_send,maxsend+bufextra,"comm:buf_send"); } } diff --git a/src/irregular.cpp b/src/irregular.cpp index 1865f9cbf6..9851770612 100644 --- a/src/irregular.cpp +++ b/src/irregular.cpp @@ -19,6 +19,8 @@ #include "atom_vec.h" #include "domain.h" #include "comm.h" +#include "modify.h" +#include "fix.h" #include "memory.h" using namespace LAMMPS_NS; @@ -35,8 +37,8 @@ static int compare_standalone(const int, const int, void *); #endif #define BUFFACTOR 1.5 -#define BUFMIN 1000 -#define BUFEXTRA 1000 +#define BUFMIN 1024 +#define BUFEXTRA 1024 /* ---------------------------------------------------------------------- */ @@ -69,9 +71,10 @@ Irregular::Irregular(LAMMPS *lmp) : Pointers(lmp) // initialize buffers for migrate atoms, not used for datum comm // these can persist for multiple irregular operations - maxsend = BUFMIN; - memory->create(buf_send,maxsend+BUFEXTRA,"comm:buf_send"); - maxrecv = BUFMIN; + buf_send = buf_recv = NULL; + maxsend = maxrecv = BUFMIN; + bufextra = BUFEXTRA; + grow_send(maxsend,2); memory->create(buf_recv,maxrecv,"comm:buf_recv"); } @@ -103,6 +106,13 @@ Irregular::~Irregular() void Irregular::migrate_atoms(int sortflag, int preassign, int *procassign) { + // check if buf_send needs to be extended due to atom style or per-atom fixes + // same as in Comm::exchange() + + int bufextra_old = bufextra; + init_exchange(); + if (bufextra > bufextra_old) grow_send(maxsend+bufextra,2); + // clear global->local map since atoms move to new procs // clear old ghosts so map_set() at end will operate only on local atoms // exchange() doesn't need to clear ghosts b/c borders() @@ -983,24 +993,52 @@ void Irregular::destroy_data() } /* ---------------------------------------------------------------------- - realloc the size of the send buffer as needed with BUFFACTOR & BUFEXTRA - if flag = 1, realloc - if flag = 0, don't need to realloc with copy, just free/malloc + set bufextra based on AtomVec and fixes + similar to Comm::init_exchange() +------------------------------------------------------------------------- */ + +void Irregular::init_exchange() +{ + int nfix = modify->nfix; + Fix **fix = modify->fix; + + int onefix; + int maxexchange_fix = 0; + for (int i = 0; i < nfix; i++) { + onefix = fix[i]->maxexchange; + maxexchange_fix = MAX(maxexchange_fix,onefix); + } + + int maxexchange = atom->avec->maxexchange + maxexchange_fix; + bufextra = maxexchange + BUFEXTRA; +} + +/* ---------------------------------------------------------------------- + realloc the size of the send buffer as needed with BUFFACTOR and bufextra + flag = 0, don't need to realloc with copy, just free/malloc w/ BUFFACTOR + flag = 1, realloc with BUFFACTOR + flag = 2, free/malloc w/out BUFFACTOR + same as Comm::grow_send() ------------------------------------------------------------------------- */ void Irregular::grow_send(int n, int flag) { - maxsend = static_cast (BUFFACTOR * n); - if (flag) - memory->grow(buf_send,maxsend+BUFEXTRA,"comm:buf_send"); - else { + if (flag == 0) { + maxsend = static_cast (BUFFACTOR * n); memory->destroy(buf_send); - memory->create(buf_send,maxsend+BUFEXTRA,"comm:buf_send"); + memory->create(buf_send,maxsend+bufextra,"comm:buf_send"); + } else if (flag == 1) { + maxsend = static_cast (BUFFACTOR * n); + memory->grow(buf_send,maxsend+bufextra,"comm:buf_send"); + } else { + memory->destroy(buf_send); + memory->grow(buf_send,maxsend+bufextra,"comm:buf_send"); } } /* ---------------------------------------------------------------------- free/malloc the size of the recv buffer as needed with BUFFACTOR + same as Comm::grow_recv() ------------------------------------------------------------------------- */ void Irregular::grow_recv(int n) diff --git a/src/irregular.h b/src/irregular.h index d56bcb253d..01fe40c46b 100644 --- a/src/irregular.h +++ b/src/irregular.h @@ -43,6 +43,7 @@ class Irregular : protected Pointers { int triclinic; int map_style; + int bufextra; // augment send buf size for a migrating atom int maxsend,maxrecv; // size of buf send/recv in # of doubles double *buf_send,*buf_recv; // bufs used in migrate_atoms int maxdbuf; // size of double buf in bytes @@ -91,6 +92,7 @@ class Irregular : protected Pointers { int binary(double, int, double *); + void init_exchange(); // reset bufxtra void grow_send(int,int); // reallocate send buffer void grow_recv(int); // free/allocate recv buffer }; From 941607595aff199660cc3e5a1fc682e29a213a5c Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 10 Jul 2019 08:48:33 -0600 Subject: [PATCH 3/5] one more change --- src/comm_tiled.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/comm_tiled.cpp b/src/comm_tiled.cpp index 2e04aa2978..652bb7add9 100644 --- a/src/comm_tiled.cpp +++ b/src/comm_tiled.cpp @@ -101,7 +101,7 @@ void CommTiled::init() int bufextra_old = bufextra; init_exchange(); - if (bufextra > bufextra_old) grow_send(maxsend+bufextra,0); + if (bufextra > bufextra_old) grow_send(maxsend+bufextra,2); // temporary restrictions @@ -645,7 +645,7 @@ void CommTiled::exchange() if (maxexchange_fix_dynamic) { int bufextra_old = bufextra; init_exchange(); - if (bufextra > bufextra_old) grow_send(maxsend+bufextra,1); + if (bufextra > bufextra_old) grow_send(maxsend+bufextra,2); } // domain properties used in exchange method and methods it calls From eaf2b59b1b4b586f279d4a958293a343e1cea906 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 24 Jul 2019 16:53:03 -0400 Subject: [PATCH 4/5] adapt fix neigh/history/omp to changes for dynamic exchange buffer size --- src/USER-OMP/fix_neigh_history_omp.cpp | 11 ++++++++--- src/fix.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/USER-OMP/fix_neigh_history_omp.cpp b/src/USER-OMP/fix_neigh_history_omp.cpp index efa7f5a3f1..c44d122981 100644 --- a/src/USER-OMP/fix_neigh_history_omp.cpp +++ b/src/USER-OMP/fix_neigh_history_omp.cpp @@ -175,6 +175,8 @@ void FixNeighHistoryOMP::pre_exchange_onesided() } // set maxpartner = max # of partners of any owned atom + // maxexchange = max # of values for any Comm::exchange() atom + maxpartner = m = 0; for (i = lfrom; i < lto; i++) m = MAX(m,npartner[i]); @@ -184,7 +186,7 @@ void FixNeighHistoryOMP::pre_exchange_onesided() #endif { maxpartner = MAX(m,maxpartner); - comm->maxexchange_fix =MAX(comm->maxexchange_fix,(dnum+1)*maxpartner+1); + maxexchange = (dnum+1)*maxpartner+1; } } @@ -347,6 +349,7 @@ void FixNeighHistoryOMP::pre_exchange_newton() } // set maxpartner = max # of partners of any owned atom + // maxexchange = max # of values for any Comm::exchange() atom m = 0; for (i = lfrom; i < lto; i++) m = MAX(m,npartner[i]); @@ -356,7 +359,7 @@ void FixNeighHistoryOMP::pre_exchange_newton() #endif { maxpartner = MAX(m,maxpartner); - comm->maxexchange_fix = MAX(comm->maxexchange_fix,(dnum+1)*maxpartner+1); + maxexchange = (dnum+1)*maxpartner+1; } } @@ -485,6 +488,8 @@ void FixNeighHistoryOMP::pre_exchange_no_newton() } // set maxpartner = max # of partners of any owned atom + // maxexchange = max # of values for any Comm::exchange() atom + m = 0; for (i = lfrom; i < lto; i++) m = MAX(m,npartner[i]); @@ -494,7 +499,7 @@ void FixNeighHistoryOMP::pre_exchange_no_newton() #endif { maxpartner = MAX(m,maxpartner); - comm->maxexchange_fix = MAX(comm->maxexchange_fix,(dnum+1)*maxpartner+1); + maxexchange = (dnum+1)*maxpartner+1; } } } diff --git a/src/fix.h b/src/fix.h index f4bf7f9c01..be99fe7cff 100644 --- a/src/fix.h +++ b/src/fix.h @@ -57,7 +57,7 @@ class Fix : protected Pointers { int respa_level_support; // 1 if fix supports fix_modify respa int respa_level; // which respa level to apply fix (1-Nrespa) int maxexchange; // max # of per-atom values for Comm::exchange() - int maxexchange_dynamic; // 1 if fix sets maxexchange dynamically + int maxexchange_dynamic; // 1 if fix sets maxexchange dynamically int scalar_flag; // 0/1 if compute_scalar() function exists int vector_flag; // 0/1 if compute_vector() function exists From 354855147983862c1830af93970db678e3c2dc09 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 30 Jul 2019 08:49:58 -0600 Subject: [PATCH 5/5] Fix Kokkos package compile error --- src/KOKKOS/fix_neigh_history_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/fix_neigh_history_kokkos.cpp b/src/KOKKOS/fix_neigh_history_kokkos.cpp index 5f53950fe6..8cfe7111dd 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.cpp +++ b/src/KOKKOS/fix_neigh_history_kokkos.cpp @@ -99,7 +99,7 @@ void FixNeighHistoryKokkos::pre_exchange() copymode = 0; - comm->maxexchange_fix = MAX(comm->maxexchange_fix,(dnum+1)*maxpartner+1); + maxexchange = (dnum+1)*maxpartner+1; } /* ---------------------------------------------------------------------- */