// clang-format off /* -*- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Matt Bettencourt (NVIDIA) ------------------------------------------------------------------------- */ #include "mliap_data_kokkos.h" #include "atom_kokkos.h" #include "kokkos_type.h" #include "pair_mliap_kokkos.h" #include "atom_masks.h" #include "mliap_descriptor.h" #include "lammps.h" #include "kokkos.h" /* ---------------------------------------------------------------------- */ namespace LAMMPS_NS { template MLIAPDataKokkos::MLIAPDataKokkos(LAMMPS *lmp_in, int gradgradflag_in, int *map_in, class MLIAPModel* model_in, class MLIAPDescriptor* descriptor_in, class PairMLIAPKokkos* pairmliap_in) : MLIAPData(lmp_in, gradgradflag_in, map_in, model_in, descriptor_in, pairmliap_in), k_pairmliap(pairmliap_in), lmp(lmp_in) { execution_space = ExecutionSpaceFromDevice::space; } /* ---------------------------------------------------------------------- */ template MLIAPDataKokkos::~MLIAPDataKokkos() { memoryKK->destroy_kokkos(k_gradforce,gradforce); memoryKK->destroy_kokkos(k_betas,betas); memoryKK->destroy_kokkos(k_descriptors,descriptors); memoryKK->destroy_kokkos(k_eatoms,eatoms); memoryKK->destroy_kokkos(k_gamma_row_index,gamma_row_index); memoryKK->destroy_kokkos(k_gamma_col_index,gamma_col_index); memoryKK->destroy_kokkos(k_gamma,gamma); memoryKK->destroy_kokkos(k_iatoms,iatoms); 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); } /* ---------------------------------------------------------------------- */ template void MLIAPDataKokkos::generate_neighdata(class NeighList *list_in, int eflag_in, int vflag_in) { list = list_in; // grow nmax gradforce array if necessary if (atom->nmax > nmax) { 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(); Kokkos::deep_copy(d_gradforce, 0.); auto d_elems = k_elems.template view(); Kokkos::deep_copy(d_elems, 0.); // grow arrays if necessary nlistatoms = list->inum; if (nlistatoms_max < nlistatoms) { memoryKK->destroy_kokkos(k_betas,betas); memoryKK->create_kokkos(k_betas, betas, nlistatoms, ndescriptors, "mliap_data:betas"); memoryKK->destroy_kokkos(k_descriptors,descriptors); memoryKK->create_kokkos(k_descriptors, descriptors, nlistatoms, ndescriptors, "mliap_data:descriptors"); memoryKK->destroy_kokkos(k_eatoms,eatoms); memoryKK->create_kokkos(k_eatoms, eatoms, nlistatoms, "mliap_data:eatoms"); nlistatoms_max = nlistatoms; } // grow gamma arrays if necessary if (gradgradflag == 1) { if (natomgamma_max < nlistatoms) { memoryKK->destroy_kokkos(k_gamma_row_index,gamma_row_index); memoryKK->create_kokkos(k_gamma_row_index, gamma_row_index, nlistatoms, gamma_nnz, "mliap_data:gamma_row_index"); memoryKK->destroy_kokkos(k_gamma_col_index,gamma_col_index); memoryKK->create_kokkos(k_gamma_col_index, gamma_col_index, nlistatoms, gamma_nnz, "mliap_data:gamma_col_index"); memoryKK->destroy_kokkos(k_gamma,gamma); memoryKK->create_kokkos(k_gamma, gamma, nlistatoms, gamma_nnz, "mliap_data:"); natomgamma_max = nlistatoms; } } atomKK->sync(execution_space,X_MASK | V_MASK | F_MASK | TYPE_MASK); k_pairmliap->x = atomKK->k_x.view(); k_pairmliap->v = atomKK->k_v.view(); k_pairmliap->f = atomKK->k_f.view(); grow_neigharrays(); // Use the ielems memory for prefix scan and set it at the end to the i type auto d_iatoms = k_iatoms.template view(); auto d_ielems = k_ielems.template view(); auto d_ij = k_ij.template view(); auto d_numneighs = k_numneighs.template view(); auto d_jatoms = k_jatoms.template view(); auto d_pair_i= k_pair_i.template view(); auto d_jelems= k_jelems.template view(); auto d_rij= k_rij.template view(); NeighListKokkos* k_list = static_cast*>(list); auto d_numneigh = k_list->d_numneigh; auto d_neighbors = k_list->d_neighbors; auto d_ilist = k_list->d_ilist; auto d_cutsq=k_pairmliap->k_cutsq.template view(); AtomKokkos *atomKK = (AtomKokkos *) atom; auto x = atomKK->k_x.view(); auto type = atomKK->k_type.view(); auto map=k_pairmliap->k_map.template view(); Kokkos::parallel_scan(nlistatoms, KOKKOS_LAMBDA (int ii, int &update, const bool final) { if (final) d_ij(ii) = update; update += d_numneighs(ii); }); Kokkos::parallel_for(nlistatoms, KOKKOS_LAMBDA (int ii) { int ij = d_ij(ii); const int i = d_ilist[ii]; const double xtmp = x(i, 0); const double ytmp = x(i, 1); const double ztmp = x(i, 2); const int itype = type(i); const int ielem = map(itype); const int jnum = d_numneigh(i); for (int jj = 0; jj < jnum; jj++) { int j = d_neighbors(i,jj); j &= NEIGHMASK; const double delx = x(j,0) - xtmp; const double dely = x(j,1) - ytmp; const double delz = x(j,2) - ztmp; const double rsq = delx*delx + dely*dely + delz*delz; int jtype = type(j); 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; d_rij(ij, 2) = delz; ij++; } } d_iatoms[ii] = i; d_ielems[ii] = ielem; }); 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; } /* ---------------------------------------------------------------------- */ template void MLIAPDataKokkos::grow_neigharrays() { AtomKokkos *atomKK = (AtomKokkos *) atom; f = atom->f; f_device = atomKK->k_f.view().data(); // grow neighbor arrays if necessary if (natomneigh_max < nlistatoms) { natomneigh_max = nlistatoms; memoryKK->destroy_kokkos(k_iatoms,iatoms); memoryKK->create_kokkos(k_iatoms, iatoms, natomneigh_max, "mliap_data:iatoms"); memoryKK->destroy_kokkos(k_ielems,ielems); memoryKK->create_kokkos(k_ielems, ielems, natomneigh_max, "mliap_data:ielems"); memoryKK->destroy_kokkos(k_ij); memoryKK->create_kokkos(k_ij, natomneigh_max, "mliap_data:ij"); memoryKK->destroy_kokkos(k_numneighs,numneighs); memoryKK->create_kokkos(k_numneighs, numneighs, natomneigh_max, "mliap_data:numneighs"); } NeighListKokkos* k_list = static_cast*>(list); auto d_numneigh = k_list->d_numneigh; auto d_neighbors = k_list->d_neighbors; auto d_ilist = k_list->d_ilist; auto x = atomKK->k_x.view(); auto type = atomKK->k_type.view(); auto d_cutsq=k_pairmliap->k_cutsq.template view(); auto h_cutsq=k_pairmliap->k_cutsq.template view(); auto d_numneighs = k_numneighs.template view(); Kokkos::parallel_reduce(nlistatoms, KOKKOS_LAMBDA (int ii, int &contrib) { const int i = d_ilist[ii]; int count=0; const double xtmp = x(i, 0); const double ytmp = x(i, 1); const double ztmp = x(i, 2); const int itype = type(i); const int jnum = d_numneigh(i); for (int jj = 0; jj < jnum; jj++) { int j = d_neighbors(i,jj); j &= NEIGHMASK; const double delx = x(j,0) - xtmp; const double dely = x(j,1) - ytmp; const double delz = x(j,2) - ztmp; const double rsq = delx*delx + dely*dely + delz*delz; int jtype = type(j); if (rsq < d_cutsq(itype,jtype)) count++; } d_numneighs(ii) = count; contrib += count; }, npairs); modified(execution_space, NUMNEIGHS_MASK); if (nneigh_max < npairs) { memoryKK->destroy_kokkos(k_jatoms,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, npairs, "mliap_data:jelems"); memoryKK->destroy_kokkos(k_rij,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, npairs, ndescriptors,3, "mliap_data:graddesc"); } nneigh_max = npairs; } } /* ---------------------------------------------------------------------- */ template void MLIAPDataKokkos::modified(ExecutionSpace space, unsigned int mask, bool ignore_auto_sync) { if (space == Device) { if (mask & IATOMS_MASK ) k_iatoms .modify(); if (mask & IELEMS_MASK ) k_ielems .modify(); if (mask & JATOMS_MASK ) k_jatoms .modify(); if (mask & PAIR_I_MASK ) k_pair_i .modify(); if (mask & JELEMS_MASK ) k_jelems .modify(); if (mask & ELEMS_MASK ) k_elems .modify(); if (mask & IJ_MASK ) k_ij .modify(); if (mask & BETAS_MASK ) k_betas .modify(); if (mask & DESCRIPTORS_MASK ) k_descriptors .modify(); if (mask & EATOMS_MASK ) k_eatoms .modify(); if (mask & RIJ_MASK ) k_rij .modify(); if (mask & GRADFORCE_MASK ) k_gradforce .modify(); if (mask & GRADDESC_MASK ) k_graddesc .modify(); if (mask & NUMNEIGHS_MASK ) k_numneighs .modify(); if (mask & GAMMA_MASK_MASK ) k_gamma .modify(); if (mask & GAMMA_ROW_MASK ) k_gamma_row_index.modify(); if (mask & GAMMA_COL_MASK ) k_gamma_col_index.modify(); if (lmp->kokkos->auto_sync && !ignore_auto_sync) sync(Host, mask, true); } else { if (mask & IATOMS_MASK ) k_iatoms .modify(); if (mask & IELEMS_MASK ) k_ielems .modify(); if (mask & JATOMS_MASK ) k_jatoms .modify(); if (mask & PAIR_I_MASK ) k_pair_i .modify(); if (mask & JELEMS_MASK ) k_jelems .modify(); if (mask & ELEMS_MASK ) k_elems .modify(); if (mask & IJ_MASK ) k_ij .modify(); if (mask & BETAS_MASK ) k_betas .modify(); if (mask & DESCRIPTORS_MASK ) k_descriptors .modify(); if (mask & EATOMS_MASK ) k_eatoms .modify(); if (mask & RIJ_MASK ) k_rij .modify(); if (mask & GRADFORCE_MASK ) k_gradforce .modify(); if (mask & GRADDESC_MASK ) k_graddesc .modify(); if (mask & NUMNEIGHS_MASK ) k_numneighs .modify(); if (mask & GAMMA_MASK_MASK ) k_gamma .modify(); if (mask & GAMMA_ROW_MASK ) k_gamma_row_index.modify(); if (mask & GAMMA_COL_MASK ) k_gamma_col_index.modify(); if (lmp->kokkos->auto_sync && !ignore_auto_sync) sync(Device, mask, true); } } /* ---------------------------------------------------------------------- */ template void MLIAPDataKokkos::sync(ExecutionSpace space, unsigned int mask, bool ignore_auto_sync) { if (space == Device) { if (lmp->kokkos->auto_sync && !ignore_auto_sync) modified(Host, mask, true); if (mask & IATOMS_MASK ) k_iatoms .sync(); if (mask & IELEMS_MASK ) k_ielems .sync(); if (mask & JATOMS_MASK ) k_jatoms .sync(); if (mask & PAIR_I_MASK ) k_pair_i .sync(); if (mask & JELEMS_MASK ) k_jelems .sync(); if (mask & ELEMS_MASK ) k_elems .sync(); if (mask & IJ_MASK ) k_ij .sync(); if (mask & BETAS_MASK ) k_betas .sync(); if (mask & DESCRIPTORS_MASK ) k_descriptors .sync(); if (mask & EATOMS_MASK ) k_eatoms .sync(); if (mask & RIJ_MASK ) k_rij .sync(); if (mask & GRADFORCE_MASK ) k_gradforce .sync(); if (mask & GRADDESC_MASK ) k_graddesc .sync(); if (mask & NUMNEIGHS_MASK ) k_numneighs .sync(); if (mask & GAMMA_MASK_MASK ) k_gamma .sync(); if (mask & GAMMA_ROW_MASK ) k_gamma_row_index.sync(); if (mask & GAMMA_COL_MASK ) k_gamma_col_index.sync(); } else { if (lmp->kokkos->auto_sync && !ignore_auto_sync) modified(Device, mask, true); if (mask & IATOMS_MASK ) k_iatoms .sync(); if (mask & IELEMS_MASK ) k_ielems .sync(); if (mask & JATOMS_MASK ) k_jatoms .sync(); if (mask & PAIR_I_MASK ) k_pair_i .sync(); if (mask & JELEMS_MASK ) k_jelems .sync(); if (mask & ELEMS_MASK ) k_elems .sync(); if (mask & IJ_MASK ) k_ij .sync(); if (mask & BETAS_MASK ) k_betas .sync(); if (mask & DESCRIPTORS_MASK ) k_descriptors .sync(); if (mask & EATOMS_MASK ) k_eatoms .sync(); if (mask & RIJ_MASK ) k_rij .sync(); if (mask & GRADFORCE_MASK ) k_gradforce .sync(); if (mask & GRADDESC_MASK ) k_graddesc .sync(); if (mask & NUMNEIGHS_MASK ) k_numneighs .sync(); if (mask & GAMMA_MASK_MASK ) k_gamma .sync(); if (mask & GAMMA_ROW_MASK ) k_gamma_row_index.sync(); if (mask & GAMMA_COL_MASK ) k_gamma_col_index.sync(); } } /* ---------------------------------------------------------------------- */ template class MLIAPDataKokkos; #ifdef LMP_KOKKOS_GPU template class MLIAPDataKokkos; #endif }// namespace