Merge pull request #3035 from rbberger/kokkos_unittests

Add force style tests for Kokkos OpenMP
This commit is contained in:
Axel Kohlmeyer
2022-02-07 19:57:09 -05:00
committed by GitHub
30 changed files with 597 additions and 1733 deletions

View File

@ -1,4 +1,5 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
@ -52,10 +53,10 @@ PairHybridKokkos::~PairHybridKokkos()
/* ----------------------------------------------------------------------
call each sub-style's compute() or compute_outer() function
accumulate sub-style global/peratom energy/virial in hybrid
for global vflag = 1:
for global vflag = VIRIAL_PAIR:
each sub-style computes own virial[6]
sum sub-style virial[6] to hybrid's virial[6]
for global vflag = 2:
for global vflag = VIRIAL_FDOTR:
call sub-style with adjusted vflag to prevent it calling
virial_fdotr_compute()
hybrid calls virial_fdotr_compute() on final accumulated f
@ -65,24 +66,25 @@ void PairHybridKokkos::compute(int eflag, int vflag)
{
int i,j,m,n;
// if no_virial_fdotr_compute is set and global component of
// incoming vflag = VIRIAL_FDOTR, then
// reset vflag as if global component were VIRIAL_PAIR
// check if no_virial_fdotr_compute is set and global component of
// incoming vflag = VIRIAL_FDOTR
// if so, reset vflag as if global component were VIRIAL_PAIR
// necessary since one or more sub-styles cannot compute virial as F dot r
int neighflag = lmp->kokkos->neighflag;
if (neighflag == FULL) no_virial_fdotr_compute = 1;
if (no_virial_fdotr_compute && vflag & VIRIAL_FDOTR) vflag = VIRIAL_PAIR | (vflag & ~VIRIAL_FDOTR);
if (no_virial_fdotr_compute && (vflag & VIRIAL_FDOTR))
vflag = VIRIAL_PAIR | (vflag & ~VIRIAL_FDOTR);
ev_init(eflag,vflag);
// check if global component of incoming vflag = VIRIAL_FDOTR
// if so, reset vflag passed to substyle as if it were VIRIAL_NONE
// if so, reset vflag passed to substyle so VIRIAL_FDOTR is turned off
// necessary so substyle will not invoke virial_fdotr_compute()
int vflag_substyle;
if (vflag & VIRIAL_FDOTR) vflag_substyle = VIRIAL_NONE | (vflag & ~VIRIAL_FDOTR);
if (vflag & VIRIAL_FDOTR) vflag_substyle = vflag & ~VIRIAL_FDOTR;
else vflag_substyle = vflag;
double *saved_special = save_special();
@ -140,6 +142,30 @@ void PairHybridKokkos::compute(int eflag, int vflag)
for (j = 0; j < 6; j++)
vatom[i][j] += vatom_substyle[i][j];
}
// substyles may be CENTROID_SAME or CENTROID_AVAIL
if (cvflag_atom) {
n = atom->nlocal;
if (force->newton_pair) n += atom->nghost;
if (styles[m]->centroidstressflag == CENTROID_AVAIL) {
double **cvatom_substyle = styles[m]->cvatom;
for (i = 0; i < n; i++)
for (j = 0; j < 9; j++)
cvatom[i][j] += cvatom_substyle[i][j];
} else {
double **vatom_substyle = styles[m]->vatom;
for (i = 0; i < n; i++) {
for (j = 0; j < 6; j++) {
cvatom[i][j] += vatom_substyle[i][j];
}
for (j = 6; j < 9; j++) {
cvatom[i][j] += vatom_substyle[i][j-3];
}
}
}
}
}
delete [] saved_special;

View File

@ -13,12 +13,11 @@
------------------------------------------------------------------------- */
#include "pair_hybrid_overlay_kokkos.h"
#include <cstring>
#include <cctype>
#include "atom.h"
#include "force.h"
#include "error.h"
#include <cstring>
using namespace LAMMPS_NS;
@ -43,7 +42,7 @@ void PairHybridOverlayKokkos::coeff(int narg, char **arg)
// 4th arg = pair sub-style index if name used multiple times
// allow for "none" as valid sub-style name
int multflag;
int multflag = 0;
int m;
for (m = 0; m < nstyles; m++) {
@ -52,10 +51,7 @@ void PairHybridOverlayKokkos::coeff(int narg, char **arg)
if (multiple[m]) {
multflag = 1;
if (narg < 4) error->all(FLERR,"Incorrect args for pair coefficients");
if (!isdigit(arg[3][0]))
error->all(FLERR,"Incorrect args for pair coefficients");
int index = utils::inumeric(FLERR,arg[3],false,lmp);
if (index == multiple[m]) break;
if (multiple[m] == utils::inumeric(FLERR,arg[3],false,lmp)) break;
else continue;
} else break;
}
@ -74,9 +70,15 @@ void PairHybridOverlayKokkos::coeff(int narg, char **arg)
arg[2+multflag] = arg[1];
arg[1+multflag] = arg[0];
// ensure that one_coeff flag is honored
if (!none && styles[m]->one_coeff)
if ((strcmp(arg[0],"*") != 0) || (strcmp(arg[1],"*") != 0))
error->all(FLERR,"Incorrect args for pair coefficients");
// invoke sub-style coeff() starting with 1st remaining arg
if (!none) styles[m]->coeff(narg-1-multflag,&arg[1+multflag]);
if (!none) styles[m]->coeff(narg-1-multflag,arg+1+multflag);
// set setflag and which type pairs map to which sub-style
// if sub-style is none: set hybrid subflag, wipe out map
@ -104,3 +106,52 @@ void PairHybridOverlayKokkos::coeff(int narg, char **arg)
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
we need to handle Pair::svector special for hybrid/overlay
------------------------------------------------------------------------- */
void PairHybridOverlayKokkos::init_svector()
{
// single_extra = list all sub-style single_extra
// allocate svector
single_extra = 0;
for (int m = 0; m < nstyles; m++)
single_extra += styles[m]->single_extra;
if (single_extra) {
delete [] svector;
svector = new double[single_extra];
}
}
/* ----------------------------------------------------------------------
we need to handle Pair::svector special for hybrid/overlay
------------------------------------------------------------------------- */
void PairHybridOverlayKokkos::copy_svector(int itype, int jtype)
{
int n=0;
Pair *this_style = nullptr;
// fill svector array.
// copy data from active styles and use 0.0 for inactive ones
for (int m = 0; m < nstyles; m++) {
for (int k = 0; k < nmap[itype][jtype]; ++k) {
if (m == map[itype][jtype][k]) {
this_style = styles[m];
} else {
this_style = nullptr;
}
}
for (int l = 0; l < styles[m]->single_extra; ++l) {
if (this_style) {
svector[n++] = this_style->svector[l];
} else {
svector[n++] = 0.0;
}
}
}
}

View File

@ -29,6 +29,9 @@ class PairHybridOverlayKokkos : public PairHybridKokkos {
public:
PairHybridOverlayKokkos(class LAMMPS *);
void coeff(int, char **) override;
void init_svector() override;
void copy_svector(int, int) override;
};
}

View File

@ -61,6 +61,8 @@ PairLJGromacsKokkos<DeviceType>::~PairLJGromacsKokkos()
memoryKK->destroy_kokkos(k_eatom,eatom);
memoryKK->destroy_kokkos(k_vatom,vatom);
memoryKK->destroy_kokkos(k_cutsq,cutsq);
memoryKK->destroy_kokkos(k_cut_inner,cut_inner);
memoryKK->destroy_kokkos(k_cut_inner_sq,cut_inner_sq);
}
}

View File

@ -171,7 +171,7 @@ void PairTersoffKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom");
d_eatom = k_eatom.view<DeviceType>();
}
if (vflag_atom) {
if (vflag_either) {
memoryKK->destroy_kokkos(k_vatom,vatom);
memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"pair:vatom");
d_vatom = k_vatom.view<DeviceType>();
@ -271,7 +271,7 @@ void PairTersoffKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
k_eatom.template sync<LMPHostType>();
}
if (vflag_atom) {
if (vflag_either) {
if (need_dup)
Kokkos::Experimental::contribute(d_vatom, dup_vatom);
k_vatom.template modify<DeviceType>();
@ -480,7 +480,7 @@ void PairTersoffKokkos<DeviceType>::operator()(TagPairTersoffComputeHalf<NEIGHFL
a_f(k,1) += fk[1];
a_f(k,2) += fk[2];
if (vflag_atom) {
if (vflag_either) {
F_FLOAT delrij[3], delrik[3];
delrij[0] = -delx1; delrij[1] = -dely1; delrij[2] = -delz1;
delrik[0] = -delx2; delrik[1] = -dely2; delrik[2] = -delz2;
@ -639,7 +639,7 @@ void PairTersoffKokkos<DeviceType>::operator()(TagPairTersoffComputeFullA<NEIGHF
f_y += fi[1];
f_z += fi[2];
if (vflag_atom) {
if (vflag_either) {
F_FLOAT delrij[3], delrik[3];
delrij[0] = -delx1; delrij[1] = -dely1; delrij[2] = -delz1;
delrik[0] = -delx2; delrik[1] = -dely2; delrik[2] = -delz2;
@ -764,7 +764,7 @@ void PairTersoffKokkos<DeviceType>::operator()(TagPairTersoffComputeFullB<NEIGHF
f_y += fj[1];
f_z += fj[2];
if (vflag_atom) {
if (vflag_either) {
F_FLOAT delrji[3], delrjk[3];
delrji[0] = -delx1; delrji[1] = -dely1; delrji[2] = -delz1;
delrjk[0] = -delx2; delrjk[1] = -dely2; delrjk[2] = -delz2;
@ -1216,12 +1216,12 @@ void PairTersoffKokkos<DeviceType>::v_tally3(EV_FLOAT &ev, const int &i, const i
F_FLOAT v[6];
v[0] = THIRD * (drij[0]*fj[0] + drik[0]*fk[0]);
v[1] = THIRD * (drij[1]*fj[1] + drik[1]*fk[1]);
v[2] = THIRD * (drij[2]*fj[2] + drik[2]*fk[2]);
v[3] = THIRD * (drij[0]*fj[1] + drik[0]*fk[1]);
v[4] = THIRD * (drij[0]*fj[2] + drik[0]*fk[2]);
v[5] = THIRD * (drij[1]*fj[2] + drik[1]*fk[2]);
v[0] = (drij[0]*fj[0] + drik[0]*fk[0]);
v[1] = (drij[1]*fj[1] + drik[1]*fk[1]);
v[2] = (drij[2]*fj[2] + drik[2]*fk[2]);
v[3] = (drij[0]*fj[1] + drik[0]*fk[1]);
v[4] = (drij[0]*fj[2] + drik[0]*fk[2]);
v[5] = (drij[1]*fj[2] + drik[1]*fk[2]);
if (vflag_global) {
ev.v[0] += v[0];
@ -1233,6 +1233,13 @@ void PairTersoffKokkos<DeviceType>::v_tally3(EV_FLOAT &ev, const int &i, const i
}
if (vflag_atom) {
v[0] *= THIRD;
v[1] *= THIRD;
v[2] *= THIRD;
v[3] *= THIRD;
v[4] *= THIRD;
v[5] *= THIRD;
a_vatom(i,0) += v[0]; a_vatom(i,1) += v[1]; a_vatom(i,2) += v[2];
a_vatom(i,3) += v[3]; a_vatom(i,4) += v[4]; a_vatom(i,5) += v[5];
if (NEIGHFLAG != FULL) {

View File

@ -171,7 +171,7 @@ void PairTersoffMODKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom");
d_eatom = k_eatom.view<DeviceType>();
}
if (vflag_atom) {
if (vflag_either) {
memoryKK->destroy_kokkos(k_vatom,vatom);
memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"pair:vatom");
d_vatom = k_vatom.view<DeviceType>();
@ -271,7 +271,7 @@ void PairTersoffMODKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
k_eatom.template sync<LMPHostType>();
}
if (vflag_atom) {
if (vflag_either) {
if (need_dup)
Kokkos::Experimental::contribute(d_vatom, dup_vatom);
k_vatom.template modify<DeviceType>();
@ -480,7 +480,7 @@ void PairTersoffMODKokkos<DeviceType>::operator()(TagPairTersoffMODComputeHalf<N
a_f(k,1) += fk[1];
a_f(k,2) += fk[2];
if (vflag_atom) {
if (vflag_either) {
F_FLOAT delrij[3], delrik[3];
delrij[0] = -delx1; delrij[1] = -dely1; delrij[2] = -delz1;
delrik[0] = -delx2; delrik[1] = -dely2; delrik[2] = -delz2;
@ -639,7 +639,7 @@ void PairTersoffMODKokkos<DeviceType>::operator()(TagPairTersoffMODComputeFullA<
f_y += fi[1];
f_z += fi[2];
if (vflag_atom) {
if (vflag_either) {
F_FLOAT delrij[3], delrik[3];
delrij[0] = -delx1; delrij[1] = -dely1; delrij[2] = -delz1;
delrik[0] = -delx2; delrik[1] = -dely2; delrik[2] = -delz2;
@ -764,7 +764,7 @@ void PairTersoffMODKokkos<DeviceType>::operator()(TagPairTersoffMODComputeFullB<
f_y += fj[1];
f_z += fj[2];
if (vflag_atom) {
if (vflag_either) {
F_FLOAT delrji[3], delrjk[3];
delrji[0] = -delx1; delrji[1] = -dely1; delrji[2] = -delz1;
delrjk[0] = -delx2; delrjk[1] = -dely2; delrjk[2] = -delz2;
@ -1219,12 +1219,12 @@ void PairTersoffMODKokkos<DeviceType>::v_tally3(EV_FLOAT &ev, const int &i, cons
F_FLOAT v[6];
v[0] = THIRD * (drij[0]*fj[0] + drik[0]*fk[0]);
v[1] = THIRD * (drij[1]*fj[1] + drik[1]*fk[1]);
v[2] = THIRD * (drij[2]*fj[2] + drik[2]*fk[2]);
v[3] = THIRD * (drij[0]*fj[1] + drik[0]*fk[1]);
v[4] = THIRD * (drij[0]*fj[2] + drik[0]*fk[2]);
v[5] = THIRD * (drij[1]*fj[2] + drik[1]*fk[2]);
v[0] = (drij[0]*fj[0] + drik[0]*fk[0]);
v[1] = (drij[1]*fj[1] + drik[1]*fk[1]);
v[2] = (drij[2]*fj[2] + drik[2]*fk[2]);
v[3] = (drij[0]*fj[1] + drik[0]*fk[1]);
v[4] = (drij[0]*fj[2] + drik[0]*fk[2]);
v[5] = (drij[1]*fj[2] + drik[1]*fk[2]);
if (vflag_global) {
ev.v[0] += v[0];
@ -1236,6 +1236,13 @@ void PairTersoffMODKokkos<DeviceType>::v_tally3(EV_FLOAT &ev, const int &i, cons
}
if (vflag_atom) {
v[0] *= THIRD;
v[1] *= THIRD;
v[2] *= THIRD;
v[3] *= THIRD;
v[4] *= THIRD;
v[5] *= THIRD;
a_vatom(i,0) += v[0]; a_vatom(i,1) += v[1]; a_vatom(i,2) += v[2];
a_vatom(i,3) += v[3]; a_vatom(i,4) += v[4]; a_vatom(i,5) += v[5];
if (NEIGHFLAG != FULL) {

View File

@ -31,6 +31,7 @@
#include "memory_kokkos.h"
#include "error.h"
#include "atom_masks.h"
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
@ -44,6 +45,7 @@ template<class DeviceType>
PairTersoffZBLKokkos<DeviceType>::PairTersoffZBLKokkos(LAMMPS *lmp) : PairTersoffZBL(lmp)
{
respa_enable = 0;
suffix_flag |= Suffix::KOKKOS;
kokkosable = 1;
atomKK = (AtomKokkos *) atom;
@ -185,7 +187,7 @@ void PairTersoffZBLKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom");
d_eatom = k_eatom.view<DeviceType>();
}
if (vflag_atom) {
if (vflag_either) {
memoryKK->destroy_kokkos(k_vatom,vatom);
memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"pair:vatom");
d_vatom = k_vatom.view<DeviceType>();
@ -285,7 +287,7 @@ void PairTersoffZBLKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
k_eatom.template sync<LMPHostType>();
}
if (vflag_atom) {
if (vflag_either) {
if (need_dup)
Kokkos::Experimental::contribute(d_vatom, dup_vatom);
k_vatom.template modify<DeviceType>();
@ -524,7 +526,7 @@ void PairTersoffZBLKokkos<DeviceType>::operator()(TagPairTersoffZBLComputeHalf<N
a_f(k,1) += fk[1];
a_f(k,2) += fk[2];
if (vflag_atom) {
if (vflag_either) {
F_FLOAT delrij[3], delrik[3];
delrij[0] = -delx1; delrij[1] = -dely1; delrij[2] = -delz1;
delrik[0] = -delx2; delrik[1] = -dely2; delrik[2] = -delz2;
@ -713,7 +715,7 @@ void PairTersoffZBLKokkos<DeviceType>::operator()(TagPairTersoffZBLComputeFullA<
f_y += fi[1];
f_z += fi[2];
if (vflag_atom) {
if (vflag_either) {
F_FLOAT delrij[3], delrik[3];
delrij[0] = -delx1; delrij[1] = -dely1; delrij[2] = -delz1;
delrik[0] = -delx2; delrik[1] = -dely2; delrik[2] = -delz2;
@ -838,7 +840,7 @@ void PairTersoffZBLKokkos<DeviceType>::operator()(TagPairTersoffZBLComputeFullB<
f_y += fj[1];
f_z += fj[2];
if (vflag_atom) {
if (vflag_either) {
F_FLOAT delrji[3], delrjk[3];
delrji[0] = -delx1; delrji[1] = -dely1; delrji[2] = -delz1;
delrjk[0] = -delx2; delrjk[1] = -dely2; delrjk[2] = -delz2;
@ -1313,12 +1315,12 @@ void PairTersoffZBLKokkos<DeviceType>::v_tally3(EV_FLOAT &ev, const int &i, cons
F_FLOAT v[6];
v[0] = THIRD * (drij[0]*fj[0] + drik[0]*fk[0]);
v[1] = THIRD * (drij[1]*fj[1] + drik[1]*fk[1]);
v[2] = THIRD * (drij[2]*fj[2] + drik[2]*fk[2]);
v[3] = THIRD * (drij[0]*fj[1] + drik[0]*fk[1]);
v[4] = THIRD * (drij[0]*fj[2] + drik[0]*fk[2]);
v[5] = THIRD * (drij[1]*fj[2] + drik[1]*fk[2]);
v[0] = (drij[0]*fj[0] + drik[0]*fk[0]);
v[1] = (drij[1]*fj[1] + drik[1]*fk[1]);
v[2] = (drij[2]*fj[2] + drik[2]*fk[2]);
v[3] = (drij[0]*fj[1] + drik[0]*fk[1]);
v[4] = (drij[0]*fj[2] + drik[0]*fk[2]);
v[5] = (drij[1]*fj[2] + drik[1]*fk[2]);
if (vflag_global) {
ev.v[0] += v[0];
@ -1330,6 +1332,13 @@ void PairTersoffZBLKokkos<DeviceType>::v_tally3(EV_FLOAT &ev, const int &i, cons
}
if (vflag_atom) {
v[0] *= THIRD;
v[1] *= THIRD;
v[2] *= THIRD;
v[3] *= THIRD;
v[4] *= THIRD;
v[5] *= THIRD;
a_vatom(i,0) += v[0]; a_vatom(i,1) += v[1]; a_vatom(i,2) += v[2];
a_vatom(i,3) += v[3]; a_vatom(i,4) += v[4]; a_vatom(i,5) += v[5];
if (NEIGHFLAG != FULL) {

View File

@ -277,19 +277,19 @@ namespace platform {
int mkdir(const std::string &path);
/*! Delete a directory
*
* \param path directory path
* \return -1 if unsuccessful, otherwise >= 0 */
int rmdir(const std::string &path);
/*! Delete a directory and its contents
*
* Unlike the the ``rmdir()`` or ``_rmdir()`` function of the
* C library, this function will check for the contents of the
* folder and recurse into any sub-folders, if necessary and
* delete all contained folders and their contents before
* deleting the folder *path*.
*
* \param path directory path
* \return -1 if unsuccessful, otherwise >= 0 */
int rmdir(const std::string &path);
/*! Delete a file
*
* \param path path to file to be deleted
* \return 0 on success, -1 on error */