From ea39843564417b2905e31c9c5f9a58f24d7692ee Mon Sep 17 00:00:00 2001 From: sjplimp <sjplimp@f3b2605a-c512-4ea7-a41b-209d697bcdaa> Date: Fri, 15 Jul 2016 23:14:13 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@15329 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/neigh_list.cpp | 26 ++++++++++ src/neigh_list.h | 10 ++++ src/neigh_shardlow.cpp | 107 ++++++++++++++++++++++++++++++----------- src/neighbor.cpp | 27 ++--------- src/neighbor.h | 8 --- 5 files changed, 117 insertions(+), 61 deletions(-) diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index 9be7c33a81..dfdd0f33a8 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -57,6 +57,14 @@ NeighList::NeighList(LAMMPS *lmp) : listcopy = NULL; listskip = NULL; + // USER-DPD package + ndxAIR_ssa = NULL; + maxbin_ssa = 0; + bins_ssa = NULL; + maxhead_ssa = 0; + binhead_ssa = NULL; + gbinhead_ssa = NULL; + maxstencil = ghostflag = 0; stencil = NULL; stencilxyz = NULL; @@ -89,6 +97,12 @@ NeighList::~NeighList() if (maxstencil) memory->destroy(stencil); if (ghostflag) memory->destroy(stencilxyz); + if (ndxAIR_ssa) memory->sfree(ndxAIR_ssa); + if (maxbin_ssa) memory->destroy(bins_ssa); + if (maxhead_ssa) { + memory->destroy(binhead_ssa); + memory->destroy(gbinhead_ssa); + } if (maxstencil_multi) { for (int i = 1; i <= atom->ntypes; i++) { @@ -148,6 +162,11 @@ void NeighList::grow(int nmax) if (dnum) firstdouble = (double **) memory->smalloc(maxatoms*sizeof(double *), "neighlist:firstdouble"); + if (ssaflag) { + if (ndxAIR_ssa) memory->sfree(ndxAIR_ssa); + ndxAIR_ssa = (uint16_t (*)[8]) memory->smalloc(sizeof(uint16_t)*8*maxatoms, + "neighlist:ndxAIR_ssa"); + } } /* ---------------------------------------------------------------------- @@ -229,6 +248,7 @@ void NeighList::print_attributes() printf(" %d = grow flag\n",growflag); printf(" %d = stencil flag\n",stencilflag); printf(" %d = ghost flag\n",ghostflag); + printf(" %d = ssa flag\n",ssaflag); printf("\n"); printf(" %d = pair\n",rq->pair); printf(" %d = fix\n",rq->fix); @@ -290,6 +310,12 @@ bigint NeighList::memory_usage() if (maxstencil) bytes += memory->usage(stencil,maxstencil); if (ghostflag) bytes += memory->usage(stencilxyz,maxstencil,3); + if (ndxAIR_ssa) bytes += sizeof(uint16_t) * 8 * maxatoms; + if (maxbin_ssa) bytes += memory->usage(bins_ssa,maxbin_ssa); + if (maxhead_ssa) { + bytes += memory->usage(binhead_ssa,maxhead_ssa); + bytes += memory->usage(gbinhead_ssa,maxhead_ssa); + } if (maxstencil_multi) { bytes += memory->usage(stencil_multi,atom->ntypes,maxstencil_multi); diff --git a/src/neigh_list.h b/src/neigh_list.h index a268dee468..d76682dfc4 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -65,6 +65,16 @@ class NeighList : protected Pointers { NeighList *listcopy; // me = copy list, point to list I copy from NeighList *listskip; // me = skip list, point to list I skip from + // USER-DPD package and Shardlow Splitting Algorithm (SSA) support + + int ssaflag; // 1 if the list has the ndxAIR_ssa array + uint16_t (*ndxAIR_ssa)[8]; // for each atom, last neighbor index of each AIR + int *bins_ssa; // index of next atom in each bin + int maxbin_ssa; // size of bins_ssa array + int *binhead_ssa; // index of 1st local atom in each bin + int *gbinhead_ssa; // index of 1st ghost atom in each bin + int maxhead_ssa; // size of binhead_ssa and gbinhead_ssa arrays + // stencils of bin indices for neighbor finding int maxstencil; // max size of stencil diff --git a/src/neigh_shardlow.cpp b/src/neigh_shardlow.cpp index 3a1246684b..1b87ab65d7 100644 --- a/src/neigh_shardlow.cpp +++ b/src/neigh_shardlow.cpp @@ -107,6 +107,20 @@ void Neighbor::stencil_half_bin_3d_ssa(NeighList *list, } } +// space for static variable ssaAIRptr so it +// can be used in qsort's compair function "cmp_ssaAIR()" +static int *ssaAIRptr; + +static int cmp_ssaAIR(const void *iptr, const void *jptr) +{ + int i = *((int *) iptr); + int j = *((int *) jptr); + if (ssaAIRptr[i] < ssaAIRptr[j]) return -1; + if (ssaAIRptr[i] > ssaAIRptr[j]) return 1; + return 0; +} + + /* ---------------------------------------------------------------------- build half list from full list for use by Shardlow Spliting Algorithm pair stored once if i,j are both owned and i < j @@ -138,6 +152,7 @@ void Neighbor::half_from_full_newton_ssa(NeighList *list) // loop over parent full list for (ii = 0; ii < inum_full; ii++) { + int AIRct[8] = { 0 }; n = 0; neighptr = ipage->vget(); @@ -153,8 +168,10 @@ void Neighbor::half_from_full_newton_ssa(NeighList *list) j = joriginal & NEIGHMASK; if (j < nlocal) { if (i > j) continue; + ++(AIRct[0]); } else { - if (ssaAIR[j] <= 0) continue; + if (ssaAIR[j] < 2) continue; // skip ghost atoms not in AIR + ++(AIRct[ssaAIR[j] - 1]); } neighptr[n++] = joriginal; } @@ -165,6 +182,16 @@ void Neighbor::half_from_full_newton_ssa(NeighList *list) ipage->vgot(n); if (ipage->status()) error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + // sort the locals+ghosts in the neighbor list by their ssaAIR number + ssaAIRptr = atom->ssaAIR; + qsort(&(neighptr[0]), n, sizeof(int), cmp_ssaAIR); + + // Do a prefix sum on the counts to turn them into indexes. + list->ndxAIR_ssa[i][0] = AIRct[0]; + for (int ndx = 1; ndx < 8; ++ndx) { + list->ndxAIR_ssa[i][ndx] = AIRct[ndx] + list->ndxAIR_ssa[i][ndx - 1]; + } } list->inum = inum; @@ -218,22 +245,22 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) exclude ghost atoms that are not in the Active Interaction Regions (AIR) ------------------------------------------------------------------------- */ - if (mbins > maxhead_ssa) { - maxhead_ssa = mbins; - memory->destroy(gbinhead_ssa); - memory->destroy(binhead_ssa); - memory->create(binhead_ssa,maxhead_ssa,"binhead_ssa"); - memory->create(gbinhead_ssa,maxhead_ssa,"gbinhead_ssa"); + if (mbins > list->maxhead_ssa) { + list->maxhead_ssa = mbins; + memory->destroy(list->gbinhead_ssa); + memory->destroy(list->binhead_ssa); + memory->create(list->binhead_ssa,list->maxhead_ssa,"binhead_ssa"); + memory->create(list->gbinhead_ssa,list->maxhead_ssa,"gbinhead_ssa"); } for (i = 0; i < mbins; i++) { - gbinhead_ssa[i] = -1; - binhead_ssa[i] = -1; + list->gbinhead_ssa[i] = -1; + list->binhead_ssa[i] = -1; } - if (maxbin > maxbin_ssa) { - maxbin_ssa = maxbin; - memory->destroy(bins_ssa); - memory->create(bins_ssa,maxbin_ssa,"bins_ssa"); + if (maxbin > list->maxbin_ssa) { + list->maxbin_ssa = maxbin; + memory->destroy(list->bins_ssa); + memory->create(list->bins_ssa,list->maxbin_ssa,"bins_ssa"); } // bin in reverse order so linked list will be in forward order @@ -241,26 +268,26 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) if (includegroup) { int bitmask = group->bitmask[includegroup]; for (i = nall-1; i >= nlocal; i--) { - if (ssaAIR[i] <= 0) continue; // skip ghost atoms not in AIR + if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR if (mask[i] & bitmask) { ibin = coord2bin(x[i]); - bins_ssa[i] = gbinhead_ssa[ibin]; - gbinhead_ssa[ibin] = i; + list->bins_ssa[i] = list->gbinhead_ssa[ibin]; + list->gbinhead_ssa[ibin] = i; } } nlocal = atom->nfirst; // This is important for the code that follows! } else { for (i = nall-1; i >= nlocal; i--) { - if (ssaAIR[i] <= 0) continue; // skip ghost atoms not in AIR + if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR ibin = coord2bin(x[i]); - bins_ssa[i] = gbinhead_ssa[ibin]; - gbinhead_ssa[ibin] = i; + list->bins_ssa[i] = list->gbinhead_ssa[ibin]; + list->gbinhead_ssa[ibin] = i; } } for (i = nlocal-1; i >= 0; i--) { ibin = coord2bin(x[i]); - bins_ssa[i] = binhead_ssa[ibin]; - binhead_ssa[ibin] = i; + list->bins_ssa[i] = list->binhead_ssa[ibin]; + list->binhead_ssa[ibin] = i; } } /* else reuse previous binning. See Neighbor::build_one comment. */ @@ -269,6 +296,7 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) // loop over owned atoms, storing half of the neighbors for (i = 0; i < nlocal; i++) { + int AIRct[8] = { 0 }; n = 0; neighptr = ipage->vget(); @@ -285,7 +313,7 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) // loop over rest of local atoms in i's bin // just store them, since j is beyond i in linked list - for (j = bins_ssa[i]; j >= 0; j = bins_ssa[j]) { + for (j = list->bins_ssa[i]; j >= 0; j = list->bins_ssa[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; @@ -316,7 +344,7 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) // loop over all local atoms in other bins in "half" stencil for (k = 0; k < nstencil; k++) { - for (j = binhead_ssa[ibin+stencil[k]]; j >= 0; j = bins_ssa[j]) { + for (j = list->binhead_ssa[ibin+stencil[k]]; j >= 0; j = list->bins_ssa[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; @@ -343,13 +371,15 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) } } } + AIRct[0] = n; // loop over AIR ghost atoms in all bins in "full" stencil // Note: the non-AIR ghost atoms have already been filtered out // That is a significant time savings because of the "full" stencil - for (k = 0; k < maxstencil; k++) { + // Note2: only non-pure locals can have ghosts as neighbors + if (ssaAIR[i] == 1) for (k = 0; k < maxstencil; k++) { if (stencil[k] > mbins) break; /* Check if ghost stencil bins are exhausted */ - for (j = gbinhead_ssa[ibin+stencil[k]]; j >= 0; j = bins_ssa[j]) { + for (j = list->gbinhead_ssa[ibin+stencil[k]]; j >= 0; j = list->bins_ssa[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; @@ -368,11 +398,20 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) onemols[imol]->nspecial[iatom], tag[j]-tagprev); else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) + if (which == 0) { neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; + ++(AIRct[ssaAIR[j] - 1]); + } else if (domain->minimum_image_check(delx,dely,delz)) { + neighptr[n++] = j; + ++(AIRct[ssaAIR[j] - 1]); + } else if (which > 0) { + neighptr[n++] = j ^ (which << SBBITS); + ++(AIRct[ssaAIR[j] - 1]); + } + } else { + neighptr[n++] = j; + ++(AIRct[ssaAIR[j] - 1]); + } } } } @@ -383,6 +422,16 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) ipage->vgot(n); if (ipage->status()) error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + // sort the ghosts in the neighbor list by their ssaAIR number + ssaAIRptr = atom->ssaAIR; + qsort(&(neighptr[AIRct[0]]), n - AIRct[0], sizeof(int), cmp_ssaAIR); + + // Do a prefix sum on the counts to turn them into indexes. + list->ndxAIR_ssa[i][0] = AIRct[0]; + for (int ndx = 1; ndx < 8; ++ndx) { + list->ndxAIR_ssa[i][ndx] = AIRct[ndx] + list->ndxAIR_ssa[i][ndx - 1]; + } } list->inum = inum; diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 307ea10dd8..5aad5bfd6f 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -104,14 +104,6 @@ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp) maxbin = 0; bins = NULL; - // USER-DPD SSA AIR binning - - maxbin_ssa = 0; - bins_ssa = NULL; - binhead_ssa = NULL; - gbinhead_ssa = NULL; - maxhead_ssa = 0; - // pair exclusion list info includegroup = 0; @@ -186,10 +178,6 @@ Neighbor::~Neighbor() memory->destroy(binhead); memory->destroy(bins); - memory->destroy(gbinhead_ssa); - memory->destroy(binhead_ssa); - memory->destroy(bins_ssa); - memory->destroy(ex1_type); memory->destroy(ex2_type); memory->destroy(ex_type); @@ -391,15 +379,6 @@ void Neighbor::init() maxbin = maxhead = 0; binhead = NULL; bins = NULL; - - // for USER-DPD Shardlow Splitting Algorithm (SSA) - memory->destroy(bins_ssa); - memory->destroy(binhead_ssa); - memory->destroy(gbinhead_ssa); - maxbin_ssa = maxhead_ssa = 0; - bins_ssa = NULL; - binhead_ssa = NULL; - gbinhead_ssa = NULL; } // 1st time allocation of xhold and bins @@ -724,6 +703,9 @@ void Neighbor::init() lists[i]->ghostflag = 0; if (requests[i]->ghost) lists[i]->ghostflag = 1; if (requests[i]->ghost && !requests[i]->occasional) anyghostlist = 1; + + lists[i]->ssaflag = 0; + if (requests[i]->ssa) lists[i]->ssaflag = 1; } else init_list_flags1_kokkos(i); } @@ -2254,9 +2236,6 @@ bigint Neighbor::memory_usage() if (style != NSQ) { bytes += memory->usage(bins,maxbin); bytes += memory->usage(binhead,maxhead); - bytes += memory->usage(bins_ssa,maxbin_ssa); - bytes += memory->usage(binhead_ssa,maxhead_ssa); - bytes += memory->usage(gbinhead_ssa,maxhead_ssa); } for (int i = 0; i < nrequest; i++) diff --git a/src/neighbor.h b/src/neighbor.h index ceec3249ef..7a098e9be2 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -176,14 +176,6 @@ class Neighbor : protected Pointers { double *zeroes; // vector of zeroes for shear history init - // USER-DPD package - - int *bins_ssa; // ptr to next atom in each bin used by SSA - int maxbin_ssa; // size of bins array used by SSA - int *binhead_ssa; // ptr to 1st atom in each bin used by SSA - int *gbinhead_ssa; // ptr to 1st ghost atom in each bin used by SSA - int maxhead_ssa; // size of binhead array used by SSA - // methods void bin_atoms(); // bin all atoms -- GitLab