Merge pull request #3606 from bathmatt/kokkos-mliap-unified
Add MLIAP-KOKKOS version of the Unified model/descriptor
This commit is contained in:
@ -144,6 +144,7 @@ if(PKG_ML-IAP)
|
||||
${KOKKOS_PKG_SOURCES_DIR}/mliap_descriptor_so3_kokkos.cpp
|
||||
${KOKKOS_PKG_SOURCES_DIR}/mliap_model_linear_kokkos.cpp
|
||||
${KOKKOS_PKG_SOURCES_DIR}/mliap_model_python_kokkos.cpp
|
||||
${KOKKOS_PKG_SOURCES_DIR}/mliap_unified_kokkos.cpp
|
||||
${KOKKOS_PKG_SOURCES_DIR}/mliap_so3_kokkos.cpp)
|
||||
|
||||
# Add KOKKOS version of ML-IAP Python coupling if non-KOKKOS version is included
|
||||
|
||||
@ -32,7 +32,7 @@ if not pylib.Py_IsInitialized():
|
||||
else:
|
||||
from .loader import load_model, load_unified, activate_mliappy
|
||||
try:
|
||||
from .loader import load_model_kokkos, activate_mliappy_kokkos
|
||||
from .loader import load_model_kokkos, load_unified_kokkos, activate_mliappy_kokkos
|
||||
except Exception as ee:
|
||||
# ignore import error, it means that the KOKKOS package was not included in LAMMPS
|
||||
pass
|
||||
|
||||
@ -75,7 +75,7 @@ def activate_mliappy(lmp):
|
||||
def activate_mliappy_kokkos(lmp):
|
||||
try:
|
||||
library = lmp.lib
|
||||
module_names = ["mliap_model_python_couple_kokkos"]
|
||||
module_names = ["mliap_model_python_couple_kokkos", "mliap_unified_couple_kokkos"]
|
||||
api_version = library.lammps_python_api_version()
|
||||
|
||||
for module_name in module_names:
|
||||
@ -118,3 +118,12 @@ def load_unified(model):
|
||||
) from ie
|
||||
mliap_unified_couple.load_from_python(model)
|
||||
|
||||
def load_unified_kokkos(model):
|
||||
try:
|
||||
import mliap_unified_couple_kokkos
|
||||
except ImportError as ie:
|
||||
raise ImportError("ML-IAP python module must be activated before loading\n"
|
||||
"the pair style. Call lammps.mliap.activate_mliappy(lmp)."
|
||||
) from ie
|
||||
mliap_unified_couple_kokkos.load_from_python(model)
|
||||
|
||||
|
||||
@ -204,6 +204,8 @@ action mliap_model_linear_kokkos.h mliap_model_linear.h
|
||||
action mliap_model_python_kokkos.cpp mliap_model_linear.cpp
|
||||
action mliap_model_python_kokkos.h mliap_model_linear.h
|
||||
action mliap_model_kokkos.h mliap_model.h
|
||||
action mliap_unified_kokkos.cpp mliap_unified.cpp
|
||||
action mliap_unified_kokkos.h mliap_unified.h
|
||||
action mliap_so3_kokkos.cpp mliap_so3.cpp
|
||||
action mliap_so3_kokkos.h mliap_so3.h
|
||||
action modify_kokkos.cpp
|
||||
@ -365,6 +367,7 @@ action verlet_kokkos.h
|
||||
|
||||
# Install cython pyx file only if non-KOKKOS version is present
|
||||
action mliap_model_python_couple_kokkos.pyx mliap_model_python_couple.pyx
|
||||
action mliap_unified_couple_kokkos.pyx mliap_unified_couple.pyx
|
||||
|
||||
# edit 2 Makefile.package files to include/exclude package info
|
||||
|
||||
@ -423,15 +426,19 @@ fi
|
||||
if (test $1 = 1) then
|
||||
if (type cythonize > /dev/null 2>&1 && test -e ../python_impl.cpp) then
|
||||
cythonize -3 ../mliap_model_python_couple_kokkos.pyx
|
||||
cythonize -3 ../mliap_unified_couple_kokkos.pyx
|
||||
fi
|
||||
|
||||
elif (test $1 = 0) then
|
||||
rm -f ../mliap_model_python_couple_kokkos.cpp ../mliap_model_python_couple_kokkos.h
|
||||
rm -f ../mliap_unified_couple_kokkos.cpp ../mliap_unified_couple_kokkos.h
|
||||
|
||||
elif (test $1 = 2) then
|
||||
if (type cythonize > /dev/null 2>&1 && test -e ../python_impl.cpp) then
|
||||
cythonize -3 ../mliap_model_python_couple_kokkos.pyx
|
||||
cythonize -3 ../mliap_unified_couple_kokkos.pyx
|
||||
else
|
||||
rm -f ../mliap_model_python_couple_kokkos.cpp ../mliap_model_python_couple_kokkos.h
|
||||
rm -f ../mliap_unified_couple_kokkos.cpp ../mliap_unified_couple_kokkos.h
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -56,7 +56,9 @@ MLIAPDataKokkos<DeviceType>::~MLIAPDataKokkos() {
|
||||
memoryKK->destroy_kokkos(k_ielems,ielems);
|
||||
memoryKK->destroy_kokkos(k_numneighs,numneighs);
|
||||
memoryKK->destroy_kokkos(k_jatoms,jatoms);
|
||||
memoryKK->destroy_kokkos(k_pair_i,pair_i);
|
||||
memoryKK->destroy_kokkos(k_jelems,jelems);
|
||||
memoryKK->destroy_kokkos(k_elems,elems);
|
||||
memoryKK->destroy_kokkos(k_ij);
|
||||
memoryKK->destroy_kokkos(k_rij,rij);
|
||||
memoryKK->destroy_kokkos(k_graddesc,graddesc);
|
||||
@ -75,13 +77,17 @@ void MLIAPDataKokkos<DeviceType>::generate_neighdata(class NeighList *list_in, i
|
||||
nmax = atom->nmax;
|
||||
memoryKK->destroy_kokkos(k_gradforce,gradforce);
|
||||
memoryKK->create_kokkos(k_gradforce, gradforce, nmax, size_gradforce, "mliap_data:gradforce");
|
||||
}
|
||||
memoryKK->destroy_kokkos(k_elems,elems);
|
||||
memoryKK->create_kokkos(k_elems, elems, nmax, "mliap_data:elems"); }
|
||||
|
||||
// clear gradforce array
|
||||
|
||||
int nall = atom->nlocal + atom->nghost;
|
||||
ntotal = nall;
|
||||
auto d_gradforce = k_gradforce.template view<DeviceType>();
|
||||
Kokkos::deep_copy(d_gradforce, 0.);
|
||||
|
||||
auto d_elems = k_elems.template view<DeviceType>();
|
||||
Kokkos::deep_copy(d_elems, 0.);
|
||||
// grow arrays if necessary
|
||||
|
||||
nlistatoms = list->inum;
|
||||
@ -122,6 +128,7 @@ void MLIAPDataKokkos<DeviceType>::generate_neighdata(class NeighList *list_in, i
|
||||
auto d_ij = k_ij.template view<DeviceType>();
|
||||
auto d_numneighs = k_numneighs.template view<DeviceType>();
|
||||
auto d_jatoms = k_jatoms.template view<DeviceType>();
|
||||
auto d_pair_i= k_pair_i.template view<DeviceType>();
|
||||
auto d_jelems= k_jelems.template view<DeviceType>();
|
||||
auto d_rij= k_rij.template view<DeviceType>();
|
||||
|
||||
@ -162,6 +169,7 @@ void MLIAPDataKokkos<DeviceType>::generate_neighdata(class NeighList *list_in, i
|
||||
const int jelem = map(jtype);
|
||||
if (rsq < d_cutsq(itype,jtype)) {
|
||||
d_jatoms(ij) = j;
|
||||
d_pair_i(ij) = i;
|
||||
d_jelems(ij) = jelem;
|
||||
d_rij(ij, 0) = delx;
|
||||
d_rij(ij, 1) = dely;
|
||||
@ -172,8 +180,11 @@ void MLIAPDataKokkos<DeviceType>::generate_neighdata(class NeighList *list_in, i
|
||||
d_iatoms[ii] = i;
|
||||
d_ielems[ii] = ielem;
|
||||
});
|
||||
|
||||
modified(execution_space, NUMNEIGHS_MASK | IATOMS_MASK | IELEMS_MASK | JATOMS_MASK | JELEMS_MASK | RIJ_MASK | IJ_MASK );
|
||||
Kokkos::parallel_for(nmax, KOKKOS_LAMBDA (int i) {
|
||||
const int itype = type(i);
|
||||
d_elems(i) = map(itype);
|
||||
});
|
||||
modified(execution_space, NUMNEIGHS_MASK | IATOMS_MASK | IELEMS_MASK | ELEMS_MASK | JATOMS_MASK | PAIR_I_MASK | JELEMS_MASK | RIJ_MASK | IJ_MASK );
|
||||
eflag = eflag_in;
|
||||
vflag = vflag_in;
|
||||
}
|
||||
@ -183,7 +194,8 @@ void MLIAPDataKokkos<DeviceType>::generate_neighdata(class NeighList *list_in, i
|
||||
template<class DeviceType>
|
||||
void MLIAPDataKokkos<DeviceType>::grow_neigharrays() {
|
||||
AtomKokkos *atomKK = (AtomKokkos *) atom;
|
||||
|
||||
f = atom->f;
|
||||
f_device = atomKK->k_f.view<DeviceType>().data();
|
||||
// grow neighbor arrays if necessary
|
||||
|
||||
if (natomneigh_max < nlistatoms) {
|
||||
@ -207,6 +219,7 @@ void MLIAPDataKokkos<DeviceType>::grow_neigharrays() {
|
||||
auto x = atomKK->k_x.view<DeviceType>();
|
||||
auto type = atomKK->k_type.view<DeviceType>();
|
||||
auto d_cutsq=k_pairmliap->k_cutsq.template view<DeviceType>();
|
||||
auto h_cutsq=k_pairmliap->k_cutsq.template view<LMPHostType>();
|
||||
auto d_numneighs = k_numneighs.template view<DeviceType>();
|
||||
Kokkos::parallel_reduce(nlistatoms, KOKKOS_LAMBDA (int ii, int &contrib) {
|
||||
const int i = d_ilist[ii];
|
||||
@ -229,22 +242,24 @@ void MLIAPDataKokkos<DeviceType>::grow_neigharrays() {
|
||||
}
|
||||
d_numneighs(ii) = count;
|
||||
contrib += count;
|
||||
}, nij_total);
|
||||
}, npairs);
|
||||
modified(execution_space, NUMNEIGHS_MASK);
|
||||
|
||||
if (nneigh_max < nij_total) {
|
||||
if (nneigh_max < npairs) {
|
||||
memoryKK->destroy_kokkos(k_jatoms,jatoms);
|
||||
memoryKK->create_kokkos(k_jatoms, jatoms, nij_total, "mliap_data:jatoms");
|
||||
memoryKK->create_kokkos(k_jatoms, jatoms, npairs, "mliap_data:jatoms");
|
||||
memoryKK->destroy_kokkos(k_pair_i,pair_i);
|
||||
memoryKK->create_kokkos(k_pair_i, pair_i, npairs, "mliap_data:pair_i");
|
||||
memoryKK->destroy_kokkos(k_jelems,jelems);
|
||||
memoryKK->create_kokkos(k_jelems, jelems, nij_total, "mliap_data:jelems");
|
||||
memoryKK->create_kokkos(k_jelems, jelems, npairs, "mliap_data:jelems");
|
||||
memoryKK->destroy_kokkos(k_rij,rij);
|
||||
memoryKK->create_kokkos(k_rij, rij, nij_total, 3, "mliap_data:rij");
|
||||
memoryKK->create_kokkos(k_rij, rij, npairs, 3, "mliap_data:rij");
|
||||
|
||||
if (gradgradflag == 0){
|
||||
memoryKK->destroy_kokkos(k_graddesc,graddesc);
|
||||
memoryKK->create_kokkos(k_graddesc, graddesc, nij_total, ndescriptors,3, "mliap_data:graddesc");
|
||||
memoryKK->create_kokkos(k_graddesc, graddesc, npairs, ndescriptors,3, "mliap_data:graddesc");
|
||||
}
|
||||
nneigh_max = nij_total;
|
||||
nneigh_max = npairs;
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,7 +271,9 @@ void MLIAPDataKokkos<DeviceType>::modified(ExecutionSpace space, unsigned int ma
|
||||
if (mask & IATOMS_MASK ) k_iatoms .modify<LMPDeviceType>();
|
||||
if (mask & IELEMS_MASK ) k_ielems .modify<LMPDeviceType>();
|
||||
if (mask & JATOMS_MASK ) k_jatoms .modify<LMPDeviceType>();
|
||||
if (mask & PAIR_I_MASK ) k_pair_i .modify<LMPDeviceType>();
|
||||
if (mask & JELEMS_MASK ) k_jelems .modify<LMPDeviceType>();
|
||||
if (mask & ELEMS_MASK ) k_elems .modify<LMPDeviceType>();
|
||||
if (mask & IJ_MASK ) k_ij .modify<LMPDeviceType>();
|
||||
if (mask & BETAS_MASK ) k_betas .modify<LMPDeviceType>();
|
||||
if (mask & DESCRIPTORS_MASK ) k_descriptors .modify<LMPDeviceType>();
|
||||
@ -274,7 +291,9 @@ void MLIAPDataKokkos<DeviceType>::modified(ExecutionSpace space, unsigned int ma
|
||||
if (mask & IATOMS_MASK ) k_iatoms .modify<LMPHostType>();
|
||||
if (mask & IELEMS_MASK ) k_ielems .modify<LMPHostType>();
|
||||
if (mask & JATOMS_MASK ) k_jatoms .modify<LMPHostType>();
|
||||
if (mask & PAIR_I_MASK ) k_pair_i .modify<LMPHostType>();
|
||||
if (mask & JELEMS_MASK ) k_jelems .modify<LMPHostType>();
|
||||
if (mask & ELEMS_MASK ) k_elems .modify<LMPHostType>();
|
||||
if (mask & IJ_MASK ) k_ij .modify<LMPHostType>();
|
||||
if (mask & BETAS_MASK ) k_betas .modify<LMPHostType>();
|
||||
if (mask & DESCRIPTORS_MASK ) k_descriptors .modify<LMPHostType>();
|
||||
@ -300,7 +319,9 @@ void MLIAPDataKokkos<DeviceType>::sync(ExecutionSpace space, unsigned int mask,
|
||||
if (mask & IATOMS_MASK ) k_iatoms .sync<LMPDeviceType>();
|
||||
if (mask & IELEMS_MASK ) k_ielems .sync<LMPDeviceType>();
|
||||
if (mask & JATOMS_MASK ) k_jatoms .sync<LMPDeviceType>();
|
||||
if (mask & PAIR_I_MASK ) k_pair_i .sync<LMPDeviceType>();
|
||||
if (mask & JELEMS_MASK ) k_jelems .sync<LMPDeviceType>();
|
||||
if (mask & ELEMS_MASK ) k_elems .sync<LMPDeviceType>();
|
||||
if (mask & IJ_MASK ) k_ij .sync<LMPDeviceType>();
|
||||
if (mask & BETAS_MASK ) k_betas .sync<LMPDeviceType>();
|
||||
if (mask & DESCRIPTORS_MASK ) k_descriptors .sync<LMPDeviceType>();
|
||||
@ -317,7 +338,9 @@ void MLIAPDataKokkos<DeviceType>::sync(ExecutionSpace space, unsigned int mask,
|
||||
if (mask & IATOMS_MASK ) k_iatoms .sync<LMPHostType>();
|
||||
if (mask & IELEMS_MASK ) k_ielems .sync<LMPHostType>();
|
||||
if (mask & JATOMS_MASK ) k_jatoms .sync<LMPHostType>();
|
||||
if (mask & PAIR_I_MASK ) k_pair_i .sync<LMPHostType>();
|
||||
if (mask & JELEMS_MASK ) k_jelems .sync<LMPHostType>();
|
||||
if (mask & ELEMS_MASK ) k_elems .sync<LMPHostType>();
|
||||
if (mask & IJ_MASK ) k_ij .sync<LMPHostType>();
|
||||
if (mask & BETAS_MASK ) k_betas .sync<LMPHostType>();
|
||||
if (mask & DESCRIPTORS_MASK ) k_descriptors .sync<LMPHostType>();
|
||||
|
||||
@ -43,6 +43,8 @@ enum {
|
||||
GAMMA_MASK_MASK = 0x00001000,
|
||||
GAMMA_ROW_MASK = 0x00002000,
|
||||
GAMMA_COL_MASK = 0x00004000,
|
||||
PAIR_I_MASK = 0x00008000,
|
||||
ELEMS_MASK = 0x00010000,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@ -65,6 +67,8 @@ template <class DeviceType> class MLIAPDataKokkos : public MLIAPData {
|
||||
DAT::tdual_int_1d k_iatoms; // index of each atom
|
||||
DAT::tdual_int_1d k_ielems; // element of each atom
|
||||
DAT::tdual_int_1d k_jatoms; // index of each neighbor
|
||||
DAT::tdual_int_1d k_elems; // element of each atom in or not in the neighborlist
|
||||
DAT::tdual_int_1d k_pair_i; // index of each i atom for each ij pair
|
||||
DAT::tdual_int_1d k_jelems; // element of each neighbor
|
||||
DAT::tdual_int_1d k_ij; // Start location for each particle
|
||||
DAT::tdual_float_2d k_betas; // betas for all atoms in list
|
||||
@ -78,10 +82,123 @@ template <class DeviceType> class MLIAPDataKokkos : public MLIAPData {
|
||||
DAT::tdual_int_2d k_gamma_row_index; // row (parameter) index
|
||||
DAT::tdual_int_2d k_gamma_col_index; // column (descriptor) index
|
||||
|
||||
int nij_total;
|
||||
// Just cached for python interface
|
||||
double *f_device;
|
||||
|
||||
protected:
|
||||
class LAMMPS *lmp;
|
||||
};
|
||||
|
||||
// Now we need a specific device version for communication with python
|
||||
class MLIAPDataKokkosDevice {
|
||||
public:
|
||||
|
||||
MLIAPDataKokkosDevice(MLIAPDataKokkos<LMPDeviceType> &base) :
|
||||
size_array_rows(base.size_array_rows),
|
||||
size_array_cols(base.size_array_cols),
|
||||
natoms(base.natoms),
|
||||
yoffset(base.yoffset),
|
||||
zoffset(base.zoffset),
|
||||
ndims_force(base.ndims_force),
|
||||
ndims_virial(base.ndims_virial),
|
||||
size_gradforce(base.size_gradforce),
|
||||
f(base.f_device),
|
||||
gradforce(base.k_gradforce.d_view.data()),
|
||||
betas(base.k_betas.d_view.data()),
|
||||
descriptors(base.k_descriptors.d_view.data()),
|
||||
eatoms(base.k_eatoms.d_view.data()),
|
||||
energy(&base.energy),
|
||||
ndescriptors(base.ndescriptors),
|
||||
nparams(base.nparams),
|
||||
nelements(base.nelements),
|
||||
gamma_nnz(base.gamma_nnz),
|
||||
gamma(base.k_gamma.d_view.data()),
|
||||
gamma_row_index(base.k_gamma_row_index.d_view.data()),
|
||||
gamma_col_index(base.k_gamma_col_index.d_view.data()),
|
||||
egradient(nullptr),
|
||||
ntotal(base.ntotal),
|
||||
nlistatoms(base.nlistatoms),
|
||||
natomneigh(base.natomneigh),
|
||||
numneighs(base.numneighs),
|
||||
iatoms(base.k_iatoms.d_view.data()),
|
||||
pair_i(base.k_pair_i.d_view.data()),
|
||||
ielems(base.k_ielems.d_view.data()),
|
||||
nneigh_max(base.nneigh_max),
|
||||
npairs(base.npairs),
|
||||
jatoms(base.k_jatoms.d_view.data()),
|
||||
jelems(base.k_jelems.d_view.data()),
|
||||
elems(base.k_elems.d_view.data()),
|
||||
rij(base.k_rij.d_view.data()),
|
||||
graddesc(base.k_graddesc.d_view.data()),
|
||||
eflag(base.eflag),
|
||||
vflag(base.vflag),
|
||||
pairmliap(dynamic_cast<PairMLIAPKokkos<LMPDeviceType> *>(base.pairmliap)),
|
||||
#if defined(KOKKOS_ENABLE_CUDA)
|
||||
dev(1)
|
||||
#else
|
||||
dev(0)
|
||||
#endif
|
||||
{ }
|
||||
int size_array_rows;
|
||||
int size_array_cols;
|
||||
int natoms;
|
||||
int yoffset;
|
||||
int zoffset;
|
||||
int ndims_force;
|
||||
int ndims_virial;
|
||||
int size_gradforce;
|
||||
|
||||
//Write only
|
||||
double *f;
|
||||
double *gradforce;
|
||||
double *betas;
|
||||
double *descriptors;
|
||||
double *eatoms;
|
||||
double *energy;
|
||||
|
||||
// sizing
|
||||
const int ndescriptors;
|
||||
const int nparams;
|
||||
const int nelements;
|
||||
|
||||
//Ignored for now
|
||||
int gamma_nnz;
|
||||
double *gamma;
|
||||
int *gamma_row_index;
|
||||
int *gamma_col_index;
|
||||
double *egradient;
|
||||
|
||||
// Neighborlist stuff
|
||||
const int ntotal;
|
||||
const int nlistatoms;
|
||||
const int natomneigh;
|
||||
int *numneighs;
|
||||
int *iatoms;
|
||||
int *pair_i;
|
||||
int *ielems;
|
||||
const int nneigh_max;
|
||||
const int npairs;
|
||||
int *jatoms;
|
||||
int *jelems;
|
||||
int *elems;
|
||||
double *rij;
|
||||
double *graddesc;
|
||||
int eflag;
|
||||
int vflag;
|
||||
|
||||
class PairMLIAPKokkos<LMPDeviceType> *pairmliap; // access to pair tally functions
|
||||
|
||||
int dev;
|
||||
|
||||
#ifdef LMP_KOKKOS_GPU
|
||||
MLIAPDataKokkosDevice(MLIAPDataKokkos<LMPHostType> &base) : ndescriptors(-1),nparams(-1),nelements(-1),ntotal(-1),nlistatoms(-1),natomneigh(-1),
|
||||
nneigh_max(-1),npairs(-1)
|
||||
{
|
||||
// It cannot get here, but needed for compilation
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
} // namespace LAMMPS_NS
|
||||
#endif
|
||||
|
||||
@ -58,7 +58,7 @@ void MLIAPDescriptorSO3Kokkos<DeviceType>::compute_descriptors(class MLIAPData *
|
||||
{
|
||||
auto data = static_cast<MLIAPDataKokkos<DeviceType>*>(data_);
|
||||
so3ptr_kokkos->spectrum(data->nlistatoms, data->k_numneighs, data->k_jelems, this->k_wjelem, data->k_rij, data->k_ij,
|
||||
nmax, lmax, rcutfac, alpha, data->nij_total, data->ndescriptors);
|
||||
nmax, lmax, rcutfac, alpha, data->npairs, data->ndescriptors);
|
||||
|
||||
Kokkos::deep_copy(data->k_descriptors.template view<DeviceType>(), so3ptr_kokkos->m_plist_r);
|
||||
Kokkos::deep_copy(data->k_descriptors.h_view, so3ptr_kokkos->m_plist_r);
|
||||
@ -70,7 +70,7 @@ template <class DeviceType>
|
||||
void MLIAPDescriptorSO3Kokkos<DeviceType>::compute_forces(class MLIAPData *data_)
|
||||
{
|
||||
auto data = static_cast<MLIAPDataKokkos<DeviceType>*>(data_);
|
||||
int npairs = data->nij_total;
|
||||
int npairs = data->npairs;
|
||||
auto d_numneighs = data->k_numneighs.template view<DeviceType>();
|
||||
so3ptr_kokkos->spectrum_dxdr(data->nlistatoms, data->k_numneighs, data->k_jelems, this->k_wjelem, data->k_rij, data->k_ij,
|
||||
nmax, lmax, rcutfac, alpha, npairs, data->ndescriptors);
|
||||
@ -186,7 +186,7 @@ void MLIAPDescriptorSO3Kokkos<DeviceType>::compute_force_gradients(class MLIAPDa
|
||||
error->all(FLERR,"This has not been tested in cuda/kokkos");
|
||||
|
||||
auto data = static_cast<MLIAPDataKokkos<DeviceType>*>(data_);
|
||||
int npairs = data->nij_total;
|
||||
int npairs = data->npairs;
|
||||
so3ptr_kokkos->spectrum_dxdr(data->nlistatoms, data->k_numneighs, data->k_jelems, this->k_wjelem, data->k_rij, data->k_ij,
|
||||
nmax, lmax, rcutfac, alpha, npairs, data->ndescriptors);
|
||||
auto d_dplist_r = so3ptr_kokkos->k_dplist_r;
|
||||
@ -239,7 +239,7 @@ template <class DeviceType>
|
||||
void MLIAPDescriptorSO3Kokkos<DeviceType>::compute_descriptor_gradients(class MLIAPData *data_)
|
||||
{
|
||||
auto data = static_cast<MLIAPDataKokkos<DeviceType>*>(data_);
|
||||
bigint npairs = data->nij_total;
|
||||
bigint npairs = data->npairs;
|
||||
so3ptr_kokkos->spectrum_dxdr(data->nlistatoms, data->k_numneighs, data->k_jelems, this->k_wjelem, data->k_rij, data->k_ij,
|
||||
nmax, lmax, rcutfac, alpha, npairs, data->ndescriptors);
|
||||
auto graddesc = data->k_graddesc.template view<DeviceType>();
|
||||
|
||||
@ -36,51 +36,11 @@ class MLIAPModelPythonKokkos : public MLIAPModelPython, public MLIAPModelKokkos<
|
||||
void compute_force_gradients(class MLIAPData *) override;
|
||||
void connect_param_counts();
|
||||
};
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
|
||||
|
||||
|
||||
#include "mliap_data_kokkos.h"
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
class MLIAPModelPythonKokkosDevice: public MLIAPModelPythonKokkos<LMPDeviceType> {
|
||||
};
|
||||
|
||||
class MLIAPDataKokkosDevice {
|
||||
public:
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
MLIAPDataKokkosDevice(MLIAPDataKokkos<LMPDeviceType> &base) :
|
||||
ndescriptors(base.ndescriptors),
|
||||
nlistatoms(base.nlistatoms),
|
||||
ielems(base.k_ielems.d_view.data()),
|
||||
descriptors(base.k_descriptors.d_view.data()),
|
||||
betas(base.k_betas.d_view.data()),
|
||||
eatoms(base.k_eatoms.d_view.data()),
|
||||
energy(&base.energy),
|
||||
#if defined(KOKKOS_ENABLE_CUDA)
|
||||
dev(1)
|
||||
#else
|
||||
dev(0)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
const int ndescriptors;
|
||||
const int nlistatoms;
|
||||
int *ielems;
|
||||
double *descriptors;
|
||||
double *betas;
|
||||
double *eatoms;
|
||||
double *energy;
|
||||
int dev;
|
||||
|
||||
#ifdef LMP_KOKKOS_GPU
|
||||
MLIAPDataKokkosDevice(MLIAPDataKokkos<LMPHostType> &base) : ndescriptors(-1),nlistatoms(-1)
|
||||
{
|
||||
// It cannot get here, but needed for compilation
|
||||
}
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
445
src/KOKKOS/mliap_unified_couple_kokkos.pyx
Normal file
445
src/KOKKOS/mliap_unified_couple_kokkos.pyx
Normal file
@ -0,0 +1,445 @@
|
||||
# cython: language_level=3
|
||||
# distutils: language = c++
|
||||
|
||||
import pickle
|
||||
import numpy as np
|
||||
import lammps.mliap
|
||||
try:
|
||||
import cupy
|
||||
except ImportError:
|
||||
pass
|
||||
from libc.stdint cimport uintptr_t
|
||||
|
||||
cimport cython
|
||||
from cpython.ref cimport PyObject
|
||||
from libc.stdlib cimport malloc, free
|
||||
|
||||
|
||||
cdef extern from "lammps.h" namespace "LAMMPS_NS":
|
||||
cdef cppclass LAMMPS:
|
||||
pass
|
||||
|
||||
|
||||
cdef extern from "mliap_data_kokkos.h" namespace "LAMMPS_NS":
|
||||
cdef cppclass MLIAPDataKokkosDevice:
|
||||
# ----- may not need -----
|
||||
int size_array_rows
|
||||
int size_array_cols
|
||||
int natoms
|
||||
int yoffset
|
||||
int zoffset
|
||||
int ndims_force
|
||||
int ndims_virial
|
||||
# -END- may not need -END-
|
||||
int size_gradforce
|
||||
# ----- write only -----
|
||||
double * f
|
||||
double * gradforce
|
||||
double * betas # betas for all atoms in list
|
||||
double * descriptors # descriptors for all atoms in list
|
||||
double * eatoms # energies for all atoms in list
|
||||
double * energy
|
||||
# -END- write only -END-
|
||||
int ndescriptors # number of descriptors
|
||||
int nparams # number of model parameters per element
|
||||
int nelements # number of elements
|
||||
|
||||
# data structures for grad-grad list (gamma)
|
||||
|
||||
# ----- ignore for now -----
|
||||
int gamma_nnz # number of non-zero entries in gamma
|
||||
double * gamma # gamma element
|
||||
int * gamma_row_index # row (parameter) index
|
||||
int * gamma_col_index # column (descriptor) index
|
||||
double * egradient # energy gradient w.r.t. parameters
|
||||
# -END- ignore for now -END-
|
||||
|
||||
# data structures for mliap neighbor list
|
||||
# only neighbors strictly inside descriptor cutoff
|
||||
|
||||
int ntotal # total number of owned and ghost atoms on this proc
|
||||
int nlistatoms # current number of atoms in local atom lists
|
||||
int natomneigh # current number of atoms and ghosts in atom neighbor arrays
|
||||
int * numneighs # neighbors count for each atom
|
||||
int * iatoms # index of each atom
|
||||
int * pair_i # index of each i atom for each ij pair
|
||||
int * ielems # element of each atom
|
||||
int nneigh_max # number of ij neighbors allocated
|
||||
int npairs # number of ij neighbor pairs
|
||||
int * jatoms # index of each neighbor
|
||||
int * jelems # element of each neighbor
|
||||
int * elems # element of each atom in or not in the neighborlist
|
||||
double * rij # distance vector of each neighbor
|
||||
# ----- write only -----
|
||||
double * graddesc # descriptor gradient w.r.t. each neighbor
|
||||
# -END- write only -END-
|
||||
int eflag # indicates if energy is needed
|
||||
int vflag # indicates if virial is needed
|
||||
void * pairmliap # pointer to base class
|
||||
int dev
|
||||
|
||||
cdef extern from "mliap_unified_kokkos.h" namespace "LAMMPS_NS":
|
||||
cdef cppclass MLIAPDummyDescriptor:
|
||||
MLIAPDummyDescriptor(PyObject *, LAMMPS *) except +
|
||||
int ndescriptors # number of descriptors
|
||||
int nelements # # of unique elements
|
||||
char *elements # names of unique elements
|
||||
double cutmax # maximum cutoff needed
|
||||
double rcutfac
|
||||
double *radelem # element radii
|
||||
|
||||
void compute_descriptors(MLIAPDataKokkosDevice *)
|
||||
void compute_forces(MLIAPDataKokkosDevice *)
|
||||
void set_elements(char **, int)
|
||||
|
||||
cdef cppclass MLIAPDummyModel:
|
||||
MLIAPDummyModel(PyObject *, LAMMPS *, char * = NULL) except +
|
||||
int ndescriptors # number of descriptors
|
||||
int nparams # number of parameters per element
|
||||
int nelements; # # of unique elements
|
||||
|
||||
void compute_gradients(MLIAPDataKokkosDevice *)
|
||||
|
||||
cdef void update_pair_energy(MLIAPDataKokkosDevice *, double *) except +
|
||||
cdef void update_pair_forces(MLIAPDataKokkosDevice *, double *) except +
|
||||
|
||||
|
||||
LOADED_MODEL = None
|
||||
|
||||
|
||||
# @property sans getter
|
||||
def write_only_property(fset):
|
||||
return property(fget=None, fset=fset)
|
||||
|
||||
cdef create_array(device, void *pointer, shape,is_int):
|
||||
size=1
|
||||
for i in shape:
|
||||
size = size*i
|
||||
|
||||
if ( device == 1):
|
||||
mem = cupy.cuda.UnownedMemory(ptr=int( <uintptr_t> pointer), owner=None, size=size)
|
||||
memptr = cupy.cuda.MemoryPointer(mem, 0)
|
||||
type=cupy.double
|
||||
if (is_int):
|
||||
type=cupy.int32
|
||||
return cupy.ndarray(shape, type, memptr=memptr)
|
||||
else:
|
||||
if (len(shape) == 1 ):
|
||||
if (is_int):
|
||||
return np.asarray(<int[:shape[0]]>pointer)
|
||||
else:
|
||||
return np.asarray(<double[:shape[0]]>pointer)
|
||||
else:
|
||||
if (is_int):
|
||||
return np.asarray(<int[:shape[0],:shape[1]]>pointer)
|
||||
else:
|
||||
return np.asarray(<double[:shape[0],:shape[1]]>pointer)
|
||||
|
||||
|
||||
|
||||
# Cython implementation of MLIAPData
|
||||
# Automatically converts between C arrays and numpy when needed
|
||||
cdef class MLIAPDataPy:
|
||||
cdef MLIAPDataKokkosDevice * data
|
||||
|
||||
def __cinit__(self):
|
||||
self.data = NULL
|
||||
|
||||
def update_pair_energy_cpu(self, eij):
|
||||
cdef double[:] eij_arr = eij
|
||||
update_pair_energy(self.data, &eij_arr[0])
|
||||
def update_pair_energy_gpu(self, eij):
|
||||
cdef uintptr_t ptr = eij.data.ptr
|
||||
update_pair_energy(self.data, <double*>ptr)
|
||||
def update_pair_energy(self, eij):
|
||||
if self.data.dev==0:
|
||||
self.update_pair_energy_cpu(eij)
|
||||
else:
|
||||
self.update_pair_energy_gpu(eij)
|
||||
|
||||
def update_pair_forces_cpu(self, fij):
|
||||
cdef double[:, ::1] fij_arr = fij
|
||||
update_pair_forces(self.data, &fij_arr[0][0])
|
||||
def update_pair_forces_gpu(self, fij):
|
||||
cdef uintptr_t ptr = fij.data.ptr
|
||||
update_pair_forces(self.data, <double*>ptr)
|
||||
def update_pair_forces(self, fij):
|
||||
if self.data.dev==0:
|
||||
self.update_pair_forces_cpu(fij)
|
||||
else:
|
||||
self.update_pair_forces_gpu(fij)
|
||||
@property
|
||||
def f(self):
|
||||
if self.data.f is NULL:
|
||||
return None
|
||||
return cupy.asarray(<double[:self.ntotal, :3]> self.data.f)
|
||||
|
||||
@property
|
||||
def size_gradforce(self):
|
||||
return self.data.size_gradforce
|
||||
|
||||
@write_only_property
|
||||
def gradforce(self, value):
|
||||
if self.data.gradforce is NULL:
|
||||
raise ValueError("attempt to set NULL gradforce")
|
||||
cdef double[:, :] gradforce_view = <double[:self.ntotal, :self.size_gradforce]> &self.data.gradforce[0]
|
||||
cdef double[:, :] value_view = value
|
||||
gradforce_view[:] = value_view
|
||||
print("This code has not been tested or optimized for the GPU, if you are getting this warning optimize gradforce")
|
||||
|
||||
@write_only_property
|
||||
def betas(self, value):
|
||||
if self.data.betas is NULL:
|
||||
raise ValueError("attempt to set NULL betas")
|
||||
cdef double[:, :] betas_view = <double[:self.nlistatoms, :self.ndescriptors]> &self.data.betas[0]
|
||||
cdef double[:, :] value_view = value
|
||||
betas_view[:] = value_view
|
||||
print("This code has not been tested or optimized for the GPU, if you are getting this warning optimize ")
|
||||
|
||||
@write_only_property
|
||||
def descriptors(self, value):
|
||||
if self.data.descriptors is NULL:
|
||||
raise ValueError("attempt to set NULL descriptors")
|
||||
cdef double[:, :] descriptors_view = <double[:self.nlistatoms, :self.ndescriptors]> &self.data.descriptors[0]
|
||||
cdef double[:, :] value_view = value
|
||||
descriptors_view[:] = value_view
|
||||
print("This code has not been tested or optimized for the GPU, if you are getting this warning optimize descriptors")
|
||||
|
||||
@write_only_property
|
||||
def eatoms(self, value):
|
||||
if self.data.eatoms is NULL:
|
||||
raise ValueError("attempt to set NULL eatoms")
|
||||
cdef double[:] eatoms_view = <double[:self.nlistatoms]> &self.data.eatoms[0]
|
||||
cdef double[:] value_view = value
|
||||
eatoms_view[:] = value_view
|
||||
print("This code has not been tested or optimized for the GPU, if you are getting this warning optimize eatoms")
|
||||
|
||||
|
||||
@write_only_property
|
||||
def energy(self, value):
|
||||
self.data.energy[0] = <double>value
|
||||
|
||||
@property
|
||||
def ndescriptors(self):
|
||||
return self.data.ndescriptors
|
||||
|
||||
@property
|
||||
def nparams(self):
|
||||
return self.data.nparams
|
||||
|
||||
@property
|
||||
def nelements(self):
|
||||
return self.data.nelements
|
||||
|
||||
# data structures for grad-grad list (gamma)
|
||||
|
||||
@property
|
||||
def gamma_nnz(self):
|
||||
return self.data.gamma_nnz
|
||||
|
||||
@property
|
||||
def gamma(self):
|
||||
if self.data.gamma is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.gamma, [self.nlistatoms, self.gama_nnz],False)
|
||||
|
||||
@property
|
||||
def gamma_row_index(self):
|
||||
if self.data.gamma_row_index is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.gamma_row_index, [self.nlistatoms, self.gamma_nnz],True)
|
||||
|
||||
@property
|
||||
def gamma_col_index(self):
|
||||
if self.data.gamma_col_index is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.gamma_col_index, [self.nlistatoms, self.gamma_nnz],True)
|
||||
|
||||
@property
|
||||
def egradient(self):
|
||||
if self.data.egradient is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.egradient, [self.nelements*self.nparams],False)
|
||||
|
||||
# data structures for mliap neighbor list
|
||||
# only neighbors strictly inside descriptor cutoff
|
||||
|
||||
@property
|
||||
def ntotal(self):
|
||||
return self.data.ntotal
|
||||
|
||||
@property
|
||||
def elems(self):
|
||||
if self.data.elems is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.elems, [self.ntotal],True)
|
||||
|
||||
@property
|
||||
def nlistatoms(self):
|
||||
return self.data.nlistatoms
|
||||
|
||||
@property
|
||||
def natomneigh(self):
|
||||
return self.data.natomneigh
|
||||
|
||||
@property
|
||||
def numneighs(self):
|
||||
if self.data.numneighs is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.numneighs, [self.natomneigh],False)
|
||||
|
||||
@property
|
||||
def iatoms(self):
|
||||
if self.data.iatoms is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.iatoms, [self.natomneigh],True)
|
||||
|
||||
@property
|
||||
def ielems(self):
|
||||
if self.data.ielems is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.ielems, [self.natomneigh],True)
|
||||
|
||||
@property
|
||||
def npairs(self):
|
||||
return self.data.npairs
|
||||
|
||||
@property
|
||||
def pair_i(self):
|
||||
if self.data.pair_i is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.pair_i, [self.npairs],True)
|
||||
|
||||
@property
|
||||
def pair_j(self):
|
||||
return self.jatoms
|
||||
|
||||
@property
|
||||
def jatoms(self):
|
||||
if self.data.jatoms is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.jatoms, [self.npairs],True)
|
||||
|
||||
@property
|
||||
def jelems(self):
|
||||
if self.data.jelems is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.jelems, [self.npairs],True)
|
||||
|
||||
|
||||
@property
|
||||
def rij(self):
|
||||
if self.data.rij is NULL:
|
||||
return None
|
||||
return create_array(self.data.dev, self.data.rij, [self.npairs,3],False)
|
||||
|
||||
@write_only_property
|
||||
def graddesc(self, value):
|
||||
if self.data.graddesc is NULL:
|
||||
raise ValueError("attempt to set NULL graddesc")
|
||||
cdef double[:, :, :] graddesc_view = <double[:self.npairs, :self.ndescriptors, :3]> &self.data.graddesc[0]
|
||||
cdef double[:, :, :] value_view = value
|
||||
graddesc_view[:] = value_view
|
||||
|
||||
@property
|
||||
def eflag(self):
|
||||
return self.data.eflag
|
||||
|
||||
@property
|
||||
def vflag(self):
|
||||
return self.data.vflag
|
||||
|
||||
|
||||
# Interface between C and Python compute functions
|
||||
cdef class MLIAPUnifiedInterface:
|
||||
cdef MLIAPDummyModel * model
|
||||
cdef MLIAPDummyDescriptor * descriptor
|
||||
cdef unified_impl
|
||||
|
||||
def __init__(self, unified_impl):
|
||||
self.model = NULL
|
||||
self.descriptor = NULL
|
||||
self.unified_impl = unified_impl
|
||||
|
||||
def compute_gradients(self, data):
|
||||
self.unified_impl.compute_gradients(data)
|
||||
|
||||
def compute_descriptors(self, data):
|
||||
self.unified_impl.compute_descriptors(data)
|
||||
|
||||
def compute_forces(self, data):
|
||||
self.unified_impl.compute_forces(data)
|
||||
|
||||
|
||||
cdef public void compute_gradients_python_kokkos(unified_int, MLIAPDataKokkosDevice *data) except * with gil:
|
||||
pydata = MLIAPDataPy()
|
||||
pydata.data = data
|
||||
unified_int.compute_gradients(pydata)
|
||||
|
||||
|
||||
cdef public void compute_descriptors_python_kokkos(unified_int, MLIAPDataKokkosDevice *data) except * with gil:
|
||||
pydata = MLIAPDataPy()
|
||||
pydata.data = data
|
||||
unified_int.compute_descriptors(pydata)
|
||||
|
||||
|
||||
cdef public void compute_forces_python_kokkos(unified_int, MLIAPDataKokkosDevice *data) except * with gil:
|
||||
pydata = MLIAPDataPy()
|
||||
pydata.data = data
|
||||
unified_int.compute_forces(pydata)
|
||||
|
||||
|
||||
# Create a MLIAPUnifiedInterface and connect it to the dummy model, descriptor
|
||||
cdef public object mliap_unified_connect_kokkos(char *fname, MLIAPDummyModel * model,
|
||||
MLIAPDummyDescriptor * descriptor) with gil:
|
||||
str_fname = fname.decode('utf-8')
|
||||
if str_fname == 'EXISTS':
|
||||
if LOADED_MODEL is None:
|
||||
raise ValueError("No unified model loaded")
|
||||
unified = LOADED_MODEL
|
||||
elif str_fname.endswith(".pt") or str_fname.endswith('.pth'):
|
||||
import torch
|
||||
unified = torch.load(str_fname)
|
||||
else:
|
||||
with open(str_fname, 'rb') as pfile:
|
||||
unified = pickle.load(pfile)
|
||||
|
||||
unified_int = MLIAPUnifiedInterface(unified)
|
||||
unified_int.model = model
|
||||
unified_int.descriptor = descriptor
|
||||
|
||||
unified.interface = unified_int
|
||||
|
||||
if unified.ndescriptors is None:
|
||||
raise ValueError("no descriptors set")
|
||||
|
||||
unified_int.descriptor.ndescriptors = <int>unified.ndescriptors
|
||||
unified_int.descriptor.rcutfac = <double>unified.rcutfac
|
||||
unified_int.model.ndescriptors = <int>unified.ndescriptors
|
||||
unified_int.model.nparams = <int>unified.nparams
|
||||
|
||||
if unified.element_types is None:
|
||||
raise ValueError("no element type set")
|
||||
|
||||
cdef int nelements = <int>len(unified.element_types)
|
||||
cdef char **elements = <char**>malloc(nelements * sizeof(char*))
|
||||
|
||||
if not elements:
|
||||
raise MemoryError("failed to allocate memory for element names")
|
||||
|
||||
cdef char *elem_name
|
||||
for i, elem in enumerate(unified.element_types):
|
||||
elem_name_bytes = elem.encode('UTF-8')
|
||||
elem_name = elem_name_bytes
|
||||
elements[i] = &elem_name[0]
|
||||
unified_int.descriptor.set_elements(elements, nelements)
|
||||
unified_int.model.nelements = nelements
|
||||
|
||||
free(elements)
|
||||
return unified_int
|
||||
|
||||
|
||||
# For pre-loading a Python model
|
||||
def load_from_python(unified):
|
||||
global LOADED_MODEL
|
||||
LOADED_MODEL = unified
|
||||
388
src/KOKKOS/mliap_unified_kokkos.cpp
Normal file
388
src/KOKKOS/mliap_unified_kokkos.cpp
Normal file
@ -0,0 +1,388 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
https://www.lammps.org/, Sandia National Laboratories
|
||||
LAMMPS development team: developers@lammps.org
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing author: Matt Bettencourt (NVIDIA)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef MLIAP_PYTHON
|
||||
|
||||
#include "mliap_unified_kokkos.h"
|
||||
#include <Python.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "lmppython.h"
|
||||
#include "memory.h"
|
||||
#include "mliap_data.h"
|
||||
#include "mliap_unified_couple_kokkos.h"
|
||||
#include "pair_mliap.h"
|
||||
#include "python_compat.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
template <class DeviceType>
|
||||
MLIAPDummyDescriptorKokkos<DeviceType>::MLIAPDummyDescriptorKokkos(LAMMPS *_lmp) :
|
||||
Pointers(_lmp), MLIAPDummyDescriptor(_lmp), MLIAPDescriptorKokkos<DeviceType>(lmp, this) {}
|
||||
|
||||
template <class DeviceType>
|
||||
MLIAPDummyDescriptorKokkos<DeviceType>::~MLIAPDummyDescriptorKokkos()
|
||||
{
|
||||
// done in base class
|
||||
// Py_DECREF(unified_interface);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
invoke compute_descriptors from Cython interface
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
template <class DeviceType>
|
||||
void MLIAPDummyDescriptorKokkos<DeviceType>::compute_descriptors(class MLIAPData *data)
|
||||
{
|
||||
PyGILState_STATE gstate = PyGILState_Ensure();
|
||||
auto *kokkos_data = dynamic_cast<MLIAPDataKokkos<DeviceType>*>(data);
|
||||
MLIAPDataKokkosDevice raw_data(*kokkos_data);
|
||||
compute_descriptors_python_kokkos(unified_interface, &raw_data);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
PyGILState_Release(gstate);
|
||||
lmp->error->all(FLERR, "Running mliappy unified compute_descriptors failure.");
|
||||
}
|
||||
PyGILState_Release(gstate);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
invoke compute_forces from Cython interface
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
template <class DeviceType>
|
||||
void MLIAPDummyDescriptorKokkos<DeviceType>::compute_forces(class MLIAPData *data)
|
||||
{
|
||||
PyGILState_STATE gstate = PyGILState_Ensure();
|
||||
auto *kokkos_data = dynamic_cast<MLIAPDataKokkos<DeviceType>*>(data);
|
||||
MLIAPDataKokkosDevice raw_data(*kokkos_data);
|
||||
compute_forces_python_kokkos(unified_interface, &raw_data);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
PyGILState_Release(gstate);
|
||||
lmp->error->all(FLERR, "Running mliappy unified compute_forces failure.");
|
||||
}
|
||||
PyGILState_Release(gstate);
|
||||
}
|
||||
|
||||
// not implemented
|
||||
template <class DeviceType>
|
||||
void MLIAPDummyDescriptorKokkos<DeviceType>::compute_force_gradients(class MLIAPData *)
|
||||
{
|
||||
error->all(FLERR, "compute_force_gradients not implemented");
|
||||
}
|
||||
|
||||
// not implemented
|
||||
template <class DeviceType>
|
||||
void MLIAPDummyDescriptorKokkos<DeviceType>::compute_descriptor_gradients(class MLIAPData *)
|
||||
{
|
||||
error->all(FLERR, "compute_descriptor_gradients not implemented");
|
||||
}
|
||||
|
||||
template <class DeviceType>
|
||||
void MLIAPDummyDescriptorKokkos<DeviceType>::init()
|
||||
{
|
||||
memory->create(radelem, nelements, "mliap_dummy_descriptor:radelem");
|
||||
for (int ielem = 0; ielem < nelements; ielem++) { radelem[ielem] = 1; }
|
||||
|
||||
double cut;
|
||||
cutmax = 0.0;
|
||||
memory->create(cutsq, nelements, nelements, "mliap/descriptor/dummy:cutsq");
|
||||
memory->create(cutghost, nelements, nelements, "mliap/descriptor/dummy:cutghost");
|
||||
for (int ielem = 0; ielem < nelements; ielem++) {
|
||||
// rcutfac set from python, is global cutoff for all elements
|
||||
cut = 2.0 * radelem[ielem] * rcutfac;
|
||||
if (cut > cutmax) cutmax = cut;
|
||||
cutsq[ielem][ielem] = cut * cut;
|
||||
cutghost[ielem][ielem] = cut * cut;
|
||||
for (int jelem = ielem + 1; jelem < nelements; jelem++) {
|
||||
cut = (radelem[ielem] + radelem[jelem]) * rcutfac;
|
||||
cutsq[ielem][jelem] = cutsq[jelem][ielem] = cut * cut;
|
||||
cutghost[ielem][jelem] = cutghost[jelem][ielem] = cut * cut;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class DeviceType>
|
||||
void MLIAPDummyDescriptorKokkos<DeviceType>::set_elements(char **elems, int nelems)
|
||||
{
|
||||
nelements = nelems;
|
||||
elements = new char *[nelems];
|
||||
for (int i = 0; i < nelems; i++) { elements[i] = utils::strdup(elems[i]); }
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
template <class DeviceType>
|
||||
MLIAPDummyModelKokkos<DeviceType>::MLIAPDummyModelKokkos(LAMMPS *lmp, char *coefffilename) :
|
||||
MLIAPDummyModel(lmp,coefffilename),
|
||||
MLIAPModelKokkos<DeviceType>(lmp, this)
|
||||
{
|
||||
nonlinearflag = 1;
|
||||
}
|
||||
|
||||
template <class DeviceType>
|
||||
MLIAPDummyModelKokkos<DeviceType>::~MLIAPDummyModelKokkos()
|
||||
{
|
||||
// manually decrement borrowed reference from Python
|
||||
Py_DECREF(unified_interface);
|
||||
}
|
||||
|
||||
template <class DeviceType>
|
||||
int MLIAPDummyModelKokkos<DeviceType>::get_nparams()
|
||||
{
|
||||
return nparams;
|
||||
}
|
||||
|
||||
template <class DeviceType>
|
||||
int MLIAPDummyModelKokkos<DeviceType>::get_gamma_nnz(class MLIAPData *)
|
||||
{
|
||||
// TODO: get_gamma_nnz
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
invoke compute_gradients from Cython interface
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
template <class DeviceType>
|
||||
void MLIAPDummyModelKokkos<DeviceType>::compute_gradients(class MLIAPData *data)
|
||||
{
|
||||
PyGILState_STATE gstate = PyGILState_Ensure();
|
||||
auto *kokkos_data = dynamic_cast<MLIAPDataKokkos<DeviceType>*>(data);
|
||||
MLIAPDataKokkosDevice raw_data(*kokkos_data);
|
||||
compute_gradients_python_kokkos(unified_interface, &raw_data);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
PyGILState_Release(gstate);
|
||||
MLIAPModelKokkos<DeviceType>::error->all(FLERR, "Running mliappy unified compute_gradients failure.");
|
||||
}
|
||||
PyGILState_Release(gstate);
|
||||
}
|
||||
|
||||
// not implemented
|
||||
template <class DeviceType>
|
||||
void MLIAPDummyModelKokkos<DeviceType>::compute_gradgrads(class MLIAPData *)
|
||||
{
|
||||
MLIAPModelKokkos<DeviceType>::error->all(FLERR, "compute_gradgrads not implemented");
|
||||
}
|
||||
|
||||
// not implemented
|
||||
template <class DeviceType>
|
||||
void MLIAPDummyModelKokkos<DeviceType>::compute_force_gradients(class MLIAPData *)
|
||||
{
|
||||
MLIAPModelKokkos<DeviceType>::error->all(FLERR, "compute_force_gradients not implemented");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
memory usage unclear due to Cython/Python implementation
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
template <class DeviceType>
|
||||
double MLIAPDummyModelKokkos<DeviceType>::memory_usage()
|
||||
{
|
||||
// TODO: implement memory usage in Cython(?)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// not implemented
|
||||
template <class DeviceType>
|
||||
void MLIAPDummyModelKokkos<DeviceType>::read_coeffs(char *)
|
||||
{
|
||||
MLIAPModelKokkos<DeviceType>::error->all(FLERR, "read_coeffs not implemented");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
build the unified interface object, connect to dummy model and descriptor
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
template <class DeviceType>
|
||||
MLIAPBuildUnifiedKokkos_t<DeviceType> LAMMPS_NS::build_unified(char *unified_fname, MLIAPDataKokkos<DeviceType> *data, LAMMPS *lmp,
|
||||
char *coefffilename)
|
||||
{
|
||||
lmp->python->init();
|
||||
PyGILState_STATE gstate = PyGILState_Ensure();
|
||||
|
||||
PyObject *pyMain = PyImport_AddModule("__main__");
|
||||
|
||||
if (!pyMain) {
|
||||
PyGILState_Release(gstate);
|
||||
lmp->error->all(FLERR, "Could not initialize embedded Python");
|
||||
}
|
||||
|
||||
PyImport_ImportModule("mliap_unified_couple_kokkos");
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
PyGILState_Release(gstate);
|
||||
lmp->error->all(FLERR, "Loading mliappy unified module failure.");
|
||||
}
|
||||
|
||||
// Connect dummy model, dummy descriptor, data to Python unified
|
||||
MLIAPDummyModelKokkos<DeviceType> *model = new MLIAPDummyModelKokkos<DeviceType>(lmp, coefffilename);
|
||||
MLIAPDummyDescriptorKokkos<DeviceType> *descriptor = new MLIAPDummyDescriptorKokkos<DeviceType>(lmp);
|
||||
|
||||
PyObject *unified_interface = mliap_unified_connect_kokkos(unified_fname, model, descriptor);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
PyGILState_Release(gstate);
|
||||
lmp->error->all(FLERR, "Running mliappy unified module failure.");
|
||||
}
|
||||
|
||||
// Borrowed references must be manually incremented
|
||||
model->unified_interface = unified_interface;
|
||||
Py_INCREF(unified_interface);
|
||||
descriptor->unified_interface = unified_interface;
|
||||
Py_INCREF(unified_interface);
|
||||
|
||||
PyGILState_Release(gstate);
|
||||
|
||||
MLIAPBuildUnifiedKokkos_t<DeviceType> build = {data, descriptor, model};
|
||||
return build;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
set energy for ij atom pairs
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
void LAMMPS_NS::update_pair_energy(MLIAPDataKokkosDevice *data, double *eij)
|
||||
{
|
||||
double e_total = 0.0;
|
||||
auto d_eatoms = data->eatoms;
|
||||
auto d_pair_i= data->pair_i;
|
||||
const auto nlistatoms = data->nlistatoms;
|
||||
Kokkos::parallel_for(nlistatoms, KOKKOS_LAMBDA(int ii){
|
||||
d_eatoms[ii] = 0;
|
||||
});
|
||||
|
||||
Kokkos::parallel_reduce(data->npairs, KOKKOS_LAMBDA(int ii, double &local_sum){
|
||||
int i = d_pair_i[ii];
|
||||
double e = 0.5 * eij[ii];
|
||||
|
||||
// must not count any contribution where i is not a local atom
|
||||
if (i < nlistatoms) {
|
||||
Kokkos::atomic_add(&d_eatoms[i], e);
|
||||
local_sum += e;
|
||||
}
|
||||
},*data->energy);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
set forces for ij atom pairs
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
void LAMMPS_NS::update_pair_forces(MLIAPDataKokkosDevice *data, double *fij)
|
||||
{
|
||||
const auto nlistatoms = data->nlistatoms;
|
||||
auto *f = data->f;
|
||||
auto pair_i = data->pair_i;
|
||||
auto j_atoms = data->jatoms;
|
||||
auto vflag = data->vflag;
|
||||
auto rij = data->rij;
|
||||
int vflag_either=data->pairmliap->vflag_either, vflag_global=data->pairmliap->vflag_global, vflag_atom=data->pairmliap->vflag_atom;
|
||||
auto d_vatom = data->pairmliap->k_vatom.template view<LMPDeviceType>();
|
||||
Kokkos::View<double[6], LMPDeviceType> virial("virial");
|
||||
|
||||
Kokkos::parallel_for(data->npairs,KOKKOS_LAMBDA (int ii) {
|
||||
|
||||
int ii3 = ii * 3;
|
||||
int i = pair_i[ii];
|
||||
int j = j_atoms[ii];
|
||||
|
||||
// must not count any contribution where i is not a local atom
|
||||
if (i < nlistatoms) {
|
||||
Kokkos::atomic_add(&f[i*3+0], fij[ii3+0]);
|
||||
Kokkos::atomic_add(&f[i*3+1], fij[ii3+1]);
|
||||
Kokkos::atomic_add(&f[i*3+2], fij[ii3+2]);
|
||||
Kokkos::atomic_add(&f[j*3+0],-fij[ii3+0]);
|
||||
Kokkos::atomic_add(&f[j*3+1],-fij[ii3+1]);
|
||||
Kokkos::atomic_add(&f[j*3+2],-fij[ii3+2]);
|
||||
if (vflag) {
|
||||
double v[6];
|
||||
v[0] = -rij[ii3+0]*fij[ii3+0];
|
||||
v[1] = -rij[ii3+1]*fij[ii3+1];
|
||||
v[2] = -rij[ii3+2]*fij[ii3+2];
|
||||
v[3] = -rij[ii3+0]*fij[ii3+1];
|
||||
v[4] = -rij[ii3+0]*fij[ii3+2];
|
||||
v[5] = -rij[ii3+1]*fij[ii3+2];
|
||||
if (vflag_global) {
|
||||
Kokkos::atomic_add(&virial[0], v[0]);
|
||||
Kokkos::atomic_add(&virial[1], v[1]);
|
||||
Kokkos::atomic_add(&virial[2], v[2]);
|
||||
Kokkos::atomic_add(&virial[3], v[3]);
|
||||
Kokkos::atomic_add(&virial[4], v[4]);
|
||||
Kokkos::atomic_add(&virial[5], v[5]);
|
||||
}
|
||||
if (vflag_atom) {
|
||||
Kokkos::atomic_add(&d_vatom(i,0), 0.5*v[0]);
|
||||
Kokkos::atomic_add(&d_vatom(i,1), 0.5*v[1]);
|
||||
Kokkos::atomic_add(&d_vatom(i,2), 0.5*v[2]);
|
||||
Kokkos::atomic_add(&d_vatom(i,3), 0.5*v[3]);
|
||||
Kokkos::atomic_add(&d_vatom(i,4), 0.5*v[4]);
|
||||
Kokkos::atomic_add(&d_vatom(i,5), 0.5*v[5]);
|
||||
|
||||
Kokkos::atomic_add(&d_vatom(j,0), 0.5*v[0]);
|
||||
Kokkos::atomic_add(&d_vatom(j,1), 0.5*v[1]);
|
||||
Kokkos::atomic_add(&d_vatom(j,2), 0.5*v[2]);
|
||||
Kokkos::atomic_add(&d_vatom(j,3), 0.5*v[3]);
|
||||
Kokkos::atomic_add(&d_vatom(j,4), 0.5*v[4]);
|
||||
Kokkos::atomic_add(&d_vatom(j,5), 0.5*v[5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (vflag) {
|
||||
if (vflag_global) {
|
||||
Kokkos::View<double[6], LMPHostType> h_virial("h_virial");
|
||||
Kokkos::deep_copy(h_virial,virial);
|
||||
for (int i=0;i<6;++i)
|
||||
data->pairmliap->virial[i]+=h_virial[i];
|
||||
}
|
||||
if (vflag_atom) {
|
||||
data->pairmliap->k_vatom.template modify<LMPDeviceType>();
|
||||
data->pairmliap->k_vatom.template sync<LMPHostType>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
template class MLIAPDummyModelKokkos<LMPDeviceType>;
|
||||
template class MLIAPDummyDescriptorKokkos<LMPDeviceType>;
|
||||
template MLIAPBuildUnifiedKokkos_t<LMPDeviceType> LAMMPS_NS::build_unified(char *unified_fname, MLIAPDataKokkos<LMPDeviceType> *data, LAMMPS *lmp,
|
||||
char *coefffilename);
|
||||
//template void LAMMPS_NS::update_pair_energy(MLIAPDataKokkos<LMPDeviceType> *data, double *eij);
|
||||
//template void LAMMPS_NS::update_pair_forces(MLIAPDataKokkos<LMPDeviceType> *data, double *fij);
|
||||
#ifdef LMP_KOKKOS_GPU
|
||||
template class MLIAPDummyModelKokkos<LMPHostType>;
|
||||
template class MLIAPDummyDescriptorKokkos<LMPHostType>;
|
||||
template MLIAPBuildUnifiedKokkos_t<LMPHostType> LAMMPS_NS::build_unified(char *unified_fname, MLIAPDataKokkos<LMPHostType> *data, LAMMPS *lmp,
|
||||
char *coefffilename);
|
||||
//template void LAMMPS_NS::update_pair_energy(MLIAPDataKokkos<LMPHostType> *data, double *eij);
|
||||
//template void LAMMPS_NS::update_pair_forces(MLIAPDataKokkos<LMPHostType> *data, double *fij);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
66
src/KOKKOS/mliap_unified_kokkos.h
Normal file
66
src/KOKKOS/mliap_unified_kokkos.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* -*- c++ -*- ----------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
https://www.lammps.org/, Sandia National Laboratories
|
||||
LAMMPS development team: developers@lammps.org
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LMP_MLIAP_UNIFIED_KOKKOS_H
|
||||
#define LMP_MLIAP_UNIFIED_KOKKOS_H
|
||||
|
||||
#include "mliap_unified.h"
|
||||
#include "mliap_descriptor_kokkos.h"
|
||||
#include "mliap_model_kokkos.h"
|
||||
#include "mliap_data_kokkos.h"
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
template <class DeviceType>
|
||||
class MLIAPDummyDescriptorKokkos : public MLIAPDummyDescriptor, public MLIAPDescriptorKokkos<DeviceType>{
|
||||
public:
|
||||
MLIAPDummyDescriptorKokkos(LAMMPS *);
|
||||
~MLIAPDummyDescriptorKokkos() override;
|
||||
void compute_descriptors(class MLIAPData *) override;
|
||||
void compute_forces(class MLIAPData *) override;
|
||||
void compute_force_gradients(class MLIAPData *) override;
|
||||
void compute_descriptor_gradients(class MLIAPData *) override;
|
||||
void init() override;
|
||||
void set_elements(char **, int);
|
||||
};
|
||||
template <class DeviceType>
|
||||
class MLIAPDummyModelKokkos : public MLIAPDummyModel, public MLIAPModelKokkos<DeviceType> {
|
||||
public:
|
||||
MLIAPDummyModelKokkos(LAMMPS *, char * = nullptr);
|
||||
~MLIAPDummyModelKokkos() override;
|
||||
int get_nparams() override;
|
||||
int get_gamma_nnz(class MLIAPData *) override;
|
||||
void compute_gradients(class MLIAPData *) override;
|
||||
void compute_gradgrads(class MLIAPData *) override;
|
||||
void compute_force_gradients(class MLIAPData *) override;
|
||||
double memory_usage() override;
|
||||
|
||||
protected:
|
||||
void read_coeffs(char *) override;
|
||||
};
|
||||
|
||||
template <class DeviceType>
|
||||
struct MLIAPBuildUnifiedKokkos_t {
|
||||
MLIAPDataKokkos<DeviceType> *data;
|
||||
MLIAPDummyDescriptorKokkos<DeviceType> *descriptor;
|
||||
MLIAPDummyModelKokkos<DeviceType> *model;
|
||||
};
|
||||
template <class DeviceType>
|
||||
MLIAPBuildUnifiedKokkos_t<DeviceType> build_unified(char *, MLIAPDataKokkos<DeviceType> *, LAMMPS *, char * = NULL);
|
||||
void update_pair_energy(MLIAPDataKokkosDevice *, double *);
|
||||
void update_pair_forces(MLIAPDataKokkosDevice *, double *);
|
||||
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
#endif
|
||||
@ -24,6 +24,7 @@
|
||||
#include "mliap_model_linear_kokkos.h"
|
||||
#ifdef MLIAP_PYTHON
|
||||
#include "mliap_model_python_kokkos.h"
|
||||
#include "mliap_unified_kokkos.h"
|
||||
#endif
|
||||
#include "error.h"
|
||||
#include "neigh_request.h"
|
||||
@ -66,7 +67,6 @@ PairMLIAPKokkos<DeviceType>::~PairMLIAPKokkos()
|
||||
template<class DeviceType>
|
||||
void PairMLIAPKokkos<DeviceType>::compute(int eflag, int vflag)
|
||||
{
|
||||
atomKK->sync(Host,F_MASK | ENERGY_MASK | VIRIAL_MASK);
|
||||
atomKK->sync(execution_space,X_MASK | TYPE_MASK );
|
||||
MLIAPDataKokkos<DeviceType> *k_data = (MLIAPDataKokkos<DeviceType>*)(data);
|
||||
|
||||
@ -97,7 +97,7 @@ void PairMLIAPKokkos<DeviceType>::compute(int eflag, int vflag)
|
||||
|
||||
// compute descriptors, if needed
|
||||
if (model->nonlinearflag || eflag) {
|
||||
k_data->sync(descriptor_space, NUMNEIGHS_MASK | IATOMS_MASK | IELEMS_MASK | JATOMS_MASK | JELEMS_MASK | RIJ_MASK );
|
||||
k_data->sync(descriptor_space, NUMNEIGHS_MASK | IATOMS_MASK | IELEMS_MASK | ELEMS_MASK | JATOMS_MASK | PAIR_I_MASK | JELEMS_MASK | RIJ_MASK );
|
||||
descriptor->compute_descriptors(data);
|
||||
if (!is_kokkos_descriptor)
|
||||
k_data->modified(descriptor_space, DESCRIPTORS_MASK);
|
||||
@ -109,12 +109,13 @@ void PairMLIAPKokkos<DeviceType>::compute(int eflag, int vflag)
|
||||
k_data->modified(model_space, BETAS_MASK);
|
||||
if (eflag_atom)
|
||||
k_data->modified(model_space, EATOMS_MASK);
|
||||
e_tally(data);
|
||||
|
||||
// calculate force contributions beta_i*dB_i/dR_j
|
||||
k_data->sync(descriptor_space, NUMNEIGHS_MASK | IATOMS_MASK | IELEMS_MASK | BETAS_MASK | JATOMS_MASK | JELEMS_MASK | RIJ_MASK );
|
||||
k_data->sync(descriptor_space, NUMNEIGHS_MASK | IATOMS_MASK | IELEMS_MASK | ELEMS_MASK | BETAS_MASK | JATOMS_MASK | PAIR_I_MASK | JELEMS_MASK | RIJ_MASK );
|
||||
descriptor->compute_forces(data);
|
||||
|
||||
e_tally(data);
|
||||
|
||||
if (evflag) {
|
||||
atomKK->modified(descriptor_space,F_MASK | ENERGY_MASK | VIRIAL_MASK);
|
||||
atomKK->sync(execution_space,F_MASK | ENERGY_MASK | VIRIAL_MASK);
|
||||
@ -181,6 +182,25 @@ void PairMLIAPKokkos<DeviceType>::settings(int narg, char ** arg)
|
||||
iarg += 3;
|
||||
} else
|
||||
new_args.push_back(arg[iarg++]);
|
||||
} else if (strcmp(arg[iarg], "unified") == 0) {
|
||||
#ifdef MLIAP_PYTHON
|
||||
printf("IN SETUP UNIFIED\n");
|
||||
if (model != nullptr) error->all(FLERR,"Illegal multiple pair_style mliap model definitions");
|
||||
if (descriptor != nullptr) error->all(FLERR,"Illegal multiple pair_style mliap descriptor definitions");
|
||||
if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "pair_style mliap unified", error);
|
||||
MLIAPBuildUnifiedKokkos_t<DeviceType> build = build_unified(arg[iarg+1], dynamic_cast<MLIAPDataKokkos<DeviceType>*>(data), lmp);
|
||||
if (iarg+3 > narg) {
|
||||
ghostneigh = 0;
|
||||
} else {
|
||||
ghostneigh = utils::logical(FLERR, arg[iarg+2], false, lmp);
|
||||
}
|
||||
|
||||
iarg += 3;
|
||||
model = build.model;
|
||||
descriptor = build.descriptor;
|
||||
#else
|
||||
error->all(FLERR,"Using pair_style mliap unified requires ML-IAP with python support");
|
||||
#endif
|
||||
} else
|
||||
new_args.push_back(arg[iarg++]);
|
||||
}
|
||||
@ -226,13 +246,6 @@ void PairMLIAPKokkos<DeviceType>::coeff(int narg, char **arg) {
|
||||
k_map.modify<LMPHostType>();
|
||||
k_map.sync<LMPDeviceType>();
|
||||
|
||||
auto h_cutsq=k_cutsq.template view<LMPHostType>();
|
||||
for (int itype=1; itype <= atom->ntypes; ++itype)
|
||||
for (int jtype=1; jtype <= atom->ntypes; ++jtype)
|
||||
h_cutsq(itype,jtype) = descriptor->cutsq[map[itype]][map[jtype]];
|
||||
k_cutsq.modify<LMPHostType>();
|
||||
k_cutsq.sync<DeviceType>();
|
||||
|
||||
// clear setflag since coeff() called once with I,J = * *
|
||||
|
||||
int n = atom->ntypes;
|
||||
@ -257,6 +270,13 @@ void PairMLIAPKokkos<DeviceType>::coeff(int narg, char **arg) {
|
||||
// set up model, descriptor, and mliap data structures
|
||||
model->init();
|
||||
descriptor->init();
|
||||
|
||||
auto h_cutsq=k_cutsq.template view<LMPHostType>();
|
||||
for (int itype=1; itype <= atom->ntypes; ++itype)
|
||||
for (int jtype=1; jtype <= atom->ntypes; ++jtype)
|
||||
h_cutsq(itype,jtype) = descriptor->cutsq[map[itype]][map[jtype]];
|
||||
k_cutsq.modify<LMPHostType>();
|
||||
k_cutsq.sync<DeviceType>();
|
||||
int gradgradflag = -1;
|
||||
delete data;
|
||||
data = new MLIAPDataKokkos<DeviceType>(lmp, gradgradflag, map, model, descriptor, this);
|
||||
|
||||
@ -83,7 +83,6 @@ void PairMLIAP::compute(int eflag, int vflag)
|
||||
{
|
||||
|
||||
// consistency checks
|
||||
|
||||
if (data->ndescriptors != model->ndescriptors)
|
||||
error->all(FLERR, "Inconsistent model and descriptor descriptor count: {} vs {}",
|
||||
model->ndescriptors, data->ndescriptors);
|
||||
@ -134,10 +133,10 @@ void PairMLIAP::allocate()
|
||||
|
||||
void PairMLIAP::settings(int narg, char ** arg)
|
||||
{
|
||||
if (narg < 2) utils::missing_cmd_args(FLERR, "pair_style mliap", error);
|
||||
|
||||
// This is needed because the unit test calls settings twice
|
||||
if (!is_child) {
|
||||
if (narg < 2) utils::missing_cmd_args(FLERR, "pair_style mliap", error);
|
||||
delete model;
|
||||
model = nullptr;
|
||||
delete descriptor;
|
||||
|
||||
Reference in New Issue
Block a user