Commit 4b319720 authored by Tim Mattox's avatar Tim Mattox
Browse files

USER-DPD: Rework SSA to use a new neighbor list structure, ready for Kokkos

NOTE: pair evaluation order changes, causing numerical differences!
Atom pair processing order is fully planned out in npair_half_bin_newton_ssa
Makes the SSA neighbor list structure very different. Do not use by others!
Each local is in ilist, numneigh, and firstneigh four times instead of once.

Changes LAMMPS core code that had been previously changed for USER-DPD/SSA:
Removes ssaAIR[] from class Atom as it is now unused.
Removes ndxAIR_ssa[] from class NeighList as it is now unused.
Increases length of ilist[], numneigh[], and firstneigh[] if SSA flag set.
parent ab32d136
Loading
Loading
Loading
Loading
+25 −14
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@
#include "pair_dpd_fdt.h"
#include "pair_dpd_fdt_energy.h"
#include "pair.h"
#include "npair_half_bin_newton_ssa.h"
#include "citeme.h"

using namespace LAMMPS_NS;
@@ -500,20 +501,31 @@ void FixShardlow::initial_integrate(int vflag)

  dtsqrt = sqrt(update->dt);

  ii = 0;
  NPairHalfBinNewtonSSA *np_ssa = dynamic_cast<NPairHalfBinNewtonSSA*>(list->np);
  if (!np_ssa) error->one(FLERR, "NPair wasn't a NPairHalfBinNewtonSSA object");
  int ssa_phaseCt = np_ssa->ssa_phaseCt;
  int *ssa_phaseLen = np_ssa->ssa_phaseLen;
  int **ssa_itemLoc = np_ssa->ssa_itemLoc;
  int **ssa_itemLen = np_ssa->ssa_itemLen;

  // process neighbors in the local AIR
  while (ii < inum) {
    i = ilist[ii];
    for (int subphase = 0; subphase < 4; subphase++) {
      int start = (subphase > 0) ? list->ndxAIR_ssa[i][subphase - 1] : 0;
      int len = list->ndxAIR_ssa[i][subphase] - start;
  for (int workPhase = 0; workPhase < ssa_phaseCt; ++workPhase) {
    int workItemCt = ssa_phaseLen[workPhase];

    for (int workItem = 0; workItem < workItemCt; ++workItem) {
      int ct = ssa_itemLen[workPhase][workItem];
      ii = ssa_itemLoc[workPhase][workItem];

      while (ct-- > 0) {
        int len = list->numneigh[ii];
        if (len > 0) {
        if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][start]), len);
        else ssa_update_dpd(i, &(list->firstneigh[i][start]), len);
      }
          if (useDPDE) ssa_update_dpde(ilist[ii], list->firstneigh[ii], len);
          else ssa_update_dpd(ilist[ii], list->firstneigh[ii], len);
        }
        ii++;
      }
    }
  }

  ii = inum;
  //Loop over all 13 outward directions (7 stages)
@@ -531,10 +543,9 @@ void FixShardlow::initial_integrate(int vflag)

    // process neighbors in this AIR
    while (ct-- > 0) {
      i = ilist[ii];
      int len = list->numneigh[i];
      if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][0]), len);
      else ssa_update_dpd(i, &(list->firstneigh[i][0]), len);
      int len = list->numneigh[ii];
      if (useDPDE) ssa_update_dpde(ilist[ii], list->firstneigh[ii], len);
      else ssa_update_dpd(ilist[ii], list->firstneigh[ii], len);
      ii++;
    }

+0 −20
Original line number Diff line number Diff line
@@ -30,9 +30,6 @@ using namespace LAMMPS_NS;

NBinSSA::NBinSSA(LAMMPS *lmp) : NBinStandard(lmp)
{
  maxbin_ssa = 0;
  binlist_ssa = NULL;
  binct_ssa = NULL;
  for (int i = 0; i < 8; i++) {
    gairhead_ssa[i] = -1;
  }
@@ -40,8 +37,6 @@ NBinSSA::NBinSSA(LAMMPS *lmp) : NBinStandard(lmp)

NBinSSA::~NBinSSA()
{
  memory->destroy(binlist_ssa);
  memory->destroy(binct_ssa);
}

/* ----------------------------------------------------------------------
@@ -72,8 +67,6 @@ void NBinSSA::bin_atoms()

  for (i = 0; i < mbins; i++) {
    binhead[i] = -1;
    binlist_ssa[i] = -1;
    binct_ssa[i] = 0;
  }

  // bin in reverse order so linked list will be in forward order
@@ -108,7 +101,6 @@ void NBinSSA::bin_atoms()
    if (zbin >= lbinzhi) lbinzhi = zbin + 1;
    bins[i] = binhead[ibin];
    binhead[ibin] = i;
    ++(binct_ssa[ibin]);
  }

}
@@ -119,14 +111,6 @@ void NBinSSA::bin_atoms_setup(int nall)
{
  NBinStandard::bin_atoms_setup(nall); // Setup the parent class's data too

  if (mbins > maxbin_ssa) {
    maxbin_ssa = mbins;
    memory->destroy(binlist_ssa);
    memory->destroy(binct_ssa);
    memory->create(binlist_ssa,maxbin_ssa,"binlist_ssa");
    memory->create(binct_ssa,maxbin_ssa,"binct_ssa");
  }

  // Clear the local bin extent bounding box.
  lbinxlo = mbinx - 1; // Safe to = stencil->sx + 1
  lbinylo = mbiny - 1; // Safe to = stencil->sy + 1
@@ -142,10 +126,6 @@ bigint NBinSSA::memory_usage()
{
  bigint bytes = NBinStandard::memory_usage(); // Count the parent's usage too

  if (maxbin_ssa) {
    bytes += memory->usage(binlist_ssa,maxbin_ssa);
    bytes += memory->usage(binct_ssa,maxbin_ssa);
  }
  return bytes;
}

+0 −3
Original line number Diff line number Diff line
@@ -29,10 +29,7 @@ namespace LAMMPS_NS {
class NBinSSA : public NBinStandard {
 public:

  int *binlist_ssa;          // index in neighlist of 1st local atom in each bin
  int *binct_ssa;            // count of local atoms in each bin
  int gairhead_ssa[8];       // index of 1st ghost atom in each AIR
  int maxbin_ssa;            // size of binlist_ssa and binct_ssa arrays

  // Bounds of the local atoms in the binhead array
  int lbinxlo;               // lowest local bin x-dim coordinate
+134 −72
Original line number Diff line number Diff line
@@ -34,7 +34,27 @@ using namespace LAMMPS_NS;

/* ---------------------------------------------------------------------- */

NPairHalfBinNewtonSSA::NPairHalfBinNewtonSSA(LAMMPS *lmp) : NPair(lmp) {}
NPairHalfBinNewtonSSA::NPairHalfBinNewtonSSA(LAMMPS *lmp) : NPair(lmp)
{
  ssa_maxPhaseCt = 0;
  ssa_maxPhaseLen = 0;
  ssa_phaseCt = 0;
  ssa_phaseLen = NULL;
  ssa_itemLoc = NULL;
  ssa_itemLen = NULL;
}

/* ---------------------------------------------------------------------- */

NPairHalfBinNewtonSSA::~NPairHalfBinNewtonSSA()
{
  ssa_maxPhaseCt = 0;
  ssa_maxPhaseLen = 0;
  ssa_phaseCt = 0;
  memory->destroy(ssa_phaseLen);
  memory->destroy(ssa_itemLoc);
  memory->destroy(ssa_itemLen);
}

/* ----------------------------------------------------------------------
   binned neighbor list construction with full Newton's 3rd law
@@ -81,8 +101,6 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
  if (!nb_ssa) error->one(FLERR, "NBin wasn't a NBinSSA object");
  int *bins = nb_ssa->bins;
  int *binhead = nb_ssa->binhead;
  int *binlist_ssa = nb_ssa->binlist_ssa;
  int *binct_ssa = nb_ssa->binct_ssa;
  int *gairhead_ssa = &(nb_ssa->gairhead_ssa[0]);

  int inum = 0;
@@ -96,18 +114,63 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
  int lbinzlo = nb_ssa->lbinzlo;
  int lbinzhi = nb_ssa->lbinzhi;

  int sx1 = ns_ssa->sx + 1;
  int sy1 = ns_ssa->sy + 1;
  int sz1 = ns_ssa->sz + 1;

  ssa_phaseCt = sz1*sy1*sx1;

  xbin = (lbinxhi - lbinxlo + sx1 - 1) / sx1 + 1;
  ybin = (lbinyhi - lbinylo + sy1 - 1) / sy1 + 1;
  zbin = (lbinzhi - lbinzlo + sz1 - 1) / sz1 + 1;

  int phaseLenEstimate = xbin*ybin*zbin;

  if (ssa_phaseCt > ssa_maxPhaseCt) {
    ssa_maxPhaseCt = ssa_phaseCt;
    ssa_maxPhaseLen = 0;
    memory->destroy(ssa_phaseLen);
    memory->destroy(ssa_itemLoc);
    memory->destroy(ssa_itemLen);
    memory->create(ssa_phaseLen,ssa_maxPhaseCt,"NPairHalfBinNewtonSSA:ssa_phaseLen");
  }

  if (phaseLenEstimate > ssa_maxPhaseLen) {
    ssa_maxPhaseLen = phaseLenEstimate;
    memory->destroy(ssa_itemLoc);
    memory->destroy(ssa_itemLen);
    memory->create(ssa_itemLoc,ssa_maxPhaseCt,ssa_maxPhaseLen,"NPairHalfBinNewtonSSA:ssa_itemLoc");
    memory->create(ssa_itemLen,ssa_maxPhaseCt,ssa_maxPhaseLen,"NPairHalfBinNewtonSSA:ssa_itemLen");
  }

  ipage->reset();

  int workPhase = 0;
  // loop over bins with local atoms, storing half of the neighbors
  for (zbin = lbinzlo; zbin < lbinzhi; zbin++) {
  for (ybin = lbinylo; ybin < lbinyhi; ybin++) {
  for (xbin = lbinxlo; xbin < lbinxhi; xbin++) {
  ibin = zbin*mbiny*mbinx + ybin*mbinx + xbin;
  binlist_ssa[ibin] = inum; // record where ibin starts in ilist
  for (int zoff = ns_ssa->sz; zoff >= 0; --zoff) {
  for (int yoff = ns_ssa->sy; yoff >= 0; --yoff) {
  for (int xoff = ns_ssa->sx; xoff >= 0; --xoff) {
    int workItem = 0;
  for (zbin = lbinzlo + zoff; zbin < lbinzhi; zbin += sz1) {
  for (ybin = lbinylo + yoff - ns_ssa->sy; ybin < lbinyhi; ybin += sy1) {
  for (xbin = lbinxlo + xoff - ns_ssa->sx; xbin < lbinxhi; xbin += sz1) {
    if (workItem >= phaseLenEstimate) error->one(FLERR,"phaseLenEstimate was too small");
    ssa_itemLoc[workPhase][workItem] = inum; // record where workItem starts in ilist

    for (int subphase = 0; subphase < 4; subphase++) {
      int s_ybin = ybin + ((subphase & 0x2) ? ns_ssa->sy : 0);
      int s_xbin = xbin + ((subphase & 0x1) ? ns_ssa->sx : 0);
      int ibin, ct;

      if ((s_ybin < lbinylo) || (s_ybin >= lbinyhi)) continue;
      if ((s_xbin < lbinxlo) || (s_xbin >= lbinxhi)) continue;
      ibin = zbin*nb_ssa->mbiny*nb_ssa->mbinx
           + s_ybin*nb_ssa->mbinx
           + s_xbin;

      for (i = binhead[ibin]; i >= 0; i = bins[i]) {
        n = 0;
        neighptr = ipage->vget();

        itype = type[i];
        xtmp = x[i][0];
        ytmp = x[i][1];
@@ -117,20 +180,15 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
          iatom = molatom[i];
          tagprev = tag[i] - iatom - 1;
        }

    // loop over rest of local atoms in i's bin
        // loop over rest of local atoms in i's bin if this is subphase 0
        // just store them, since j is beyond i in linked list

    for (j = bins[i]; j >= 0; j = bins[j]) {

        if (subphase == 0) for (j = bins[i]; j >= 0; j = bins[j]) {
          jtype = type[j];
          if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;

          delx = xtmp - x[j][0];
          dely = ytmp - x[j][1];
          delz = ztmp - x[j][2];
          rsq = delx*delx + dely*dely + delz*delz;

          if (rsq <= cutneighsq[itype][jtype]) {
            if (molecular) {
              if (!moltemplate)
@@ -148,22 +206,16 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
          }
        }

    // loop over all local atoms in other bins in "half" stencil

    k = 0;
    for (int subphase = 0; subphase < 4; subphase++) {
        // loop over all local atoms in other bins in "subphase" of stencil
        k = (subphase > 0) ? nstencil_ssa[subphase - 1] : 0;
        for (; k < nstencil_ssa[subphase]; k++) {
        for (j = binhead[ibin+stencil[k]]; j >= 0;
             j = bins[j]) {

          for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
            jtype = type[j];
            if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;

            delx = xtmp - x[j][0];
            dely = ytmp - x[j][1];
            delz = ztmp - x[j][2];
            rsq = delx*delx + dely*dely + delz*delz;

            if (rsq <= cutneighsq[itype][jtype]) {
              if (molecular) {
                if (!moltemplate)
@@ -181,21 +233,31 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
            }
          }
        }
      list->ndxAIR_ssa[i][subphase] = n; // record end of this subphase
    }

        if (n > 0) {
          firstneigh[inum] = neighptr;
          numneigh[inum] = n;
          ilist[inum++] = i;
        }
    firstneigh[i] = neighptr;
    numneigh[i] = n;
        ipage->vgot(n);
        if (ipage->status())
          error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
      }
    }
    // record where workItem ends in ilist
    ssa_itemLen[workPhase][workItem] = inum - ssa_itemLoc[workPhase][workItem];
    if (ssa_itemLen[workPhase][workItem] > 0) workItem++;
  }
  }
  }

    // record where workPhase ends
    ssa_phaseLen[workPhase++] = workItem;
  }
  }
  }

  if (ssa_phaseCt != workPhase) error->one(FLERR,"ssa_phaseCt was wrong");

  list->AIRct_ssa[0] = list->inum = inum;

@@ -258,11 +320,11 @@ void NPairHalfBinNewtonSSA::build(NeighList *list)
      }

      if (n > 0) {
        firstneigh[inum + gnum] = neighptr;
        numneigh[inum + gnum] = n;
        ilist[inum + (gnum++)] = i;
        ++locAIRct;
      }
      firstneigh[i] = neighptr;
      numneigh[i] = n;
      ipage->vgot(n);
      if (ipage->status())
        error->one(FLERR,"Neighbor (ghost) list overflow, boost neigh_modify one");
+10 −1
Original line number Diff line number Diff line
@@ -28,9 +28,18 @@ namespace LAMMPS_NS {

class NPairHalfBinNewtonSSA : public NPair {
 public:
  // SSA Work plan data structures
  int ssa_phaseCt;
  int *ssa_phaseLen;
  int **ssa_itemLoc;
  int **ssa_itemLen;

  NPairHalfBinNewtonSSA(class LAMMPS *);
  ~NPairHalfBinNewtonSSA() {}
  ~NPairHalfBinNewtonSSA();
  void build(class NeighList *);
 private:
  int ssa_maxPhaseCt;
  int ssa_maxPhaseLen;
};

}
Loading