diff --git a/doc/src/Commands_pair.rst b/doc/src/Commands_pair.rst index 40b81a2fd1..b7baaa8581 100644 --- a/doc/src/Commands_pair.rst +++ b/doc/src/Commands_pair.rst @@ -171,7 +171,7 @@ OPT. * :doc:`lj/sdk/coul/long (go) ` * :doc:`lj/sdk/coul/msm (o) ` * :doc:`lj/sf/dipole/sf (go) ` - * :doc:`lj/smooth (o) ` + * :doc:`lj/smooth (go) ` * :doc:`lj/smooth/linear (o) ` * :doc:`lj/switch3/coulgauss/long ` * :doc:`lj96/cut (go) ` diff --git a/doc/src/pair_lj_smooth.rst b/doc/src/pair_lj_smooth.rst index 7ba12c89ba..a77eefd023 100644 --- a/doc/src/pair_lj_smooth.rst +++ b/doc/src/pair_lj_smooth.rst @@ -1,10 +1,11 @@ .. index:: pair_style lj/smooth +.. index:: pair_style lj/smooth/gpu .. index:: pair_style lj/smooth/omp pair_style lj/smooth command ============================ -Accelerator Variants: *lj/smooth/omp* +Accelerator Variants: *lj/smooth/gpu*, *lj/smooth/omp* Syntax """""" diff --git a/lib/gpu/lal_lj_smooth.cpp b/lib/gpu/lal_lj_smooth.cpp new file mode 100644 index 0000000000..42ffdabcf2 --- /dev/null +++ b/lib/gpu/lal_lj_smooth.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** + lj_smooth.cpp + ------------------- + Gurgen Melikyan (HSE University) + Class for acceleration of the lj/smooth pair style. + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + begin : + email : gkmeliyan@edu.hse.ru + ***************************************************************************/ + +#if defined(USE_OPENCL) +#include "lj_smooth_cl.h" +#elif defined(USE_CUDART) +const char *lj_smooth=0; +#else +#include "lj_smooth_cubin.h" +#endif + +#include "lal_lj_smooth.h" +#include +namespace LAMMPS_AL { +#define LJSMOOTHT LJSMOOTH + +extern Device device; + +template +LJSMOOTHT::LJSMOOTH() : BaseAtomic(), _allocated(false) { +} + +template +LJSMOOTHT::~LJSMOOTH() { + clear(); +} + +template +int LJSMOOTHT::bytes_per_atom(const int max_nbors) const { + return this->bytes_per_atom_atomic(max_nbors); +} + +template +int LJSMOOTHT::init(const int ntypes, + double **host_cutsq, double **host_lj1, + double **host_lj2, double **host_lj3, + double **host_lj4, double **host_offset, + double *host_special_lj, const int nlocal, + const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *_screen, + double **host_ljsw0, double **host_ljsw1, double **host_ljsw2, double **host_ljsw3, + double **host_ljsw4, + double **cut_inner, double **cut_inner_sq) { + const int max_shared_types=this->device->max_shared_types(); + + int onetype=0; + #ifdef USE_OPENCL + if (maxspecial==0) + for (int i=1; i0) { + if (onetype>0) + onetype=-1; + else if (onetype==0) + onetype=i*max_shared_types+j; + } + if (onetype<0) onetype=0; + #endif + + int success; + success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size,gpu_split, + _screen,lj_smooth,"k_lj_smooth",onetype); + if (success!=0) + return success; + + // If atom type constants fit in shared memory use fast kernel + int lj_types=ntypes; + shared_types=false; + if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) { + lj_types=max_shared_types; + shared_types=true; + } + _lj_types=lj_types; + + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(lj_types*lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; iucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,lj1,host_write,host_lj1,host_lj2, + host_cutsq, cut_inner_sq); + + lj3.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,lj3,host_write,host_lj3,host_lj4, + host_offset); + + ljsw.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + this->atom->type_pack4(ntypes,lj_types,ljsw,host_write,host_ljsw1,host_ljsw2, + host_ljsw3,host_ljsw4); + + ljsw0.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY); + this->atom->type_pack2(ntypes,lj_types,ljsw0,host_write,host_ljsw0,cut_inner); + + UCL_H_Vec dview; + sp_lj.alloc(4,*(this->ucl_device),UCL_READ_ONLY); + dview.view(host_special_lj,4,*(this->ucl_device)); + ucl_copy(sp_lj,dview,false); + + _allocated=true; + this->_max_bytes=lj1.row_bytes()+lj3.row_bytes()+ljsw.row_bytes()+ljsw0.row_bytes()+sp_lj.row_bytes(); + return 0; +} + +template +void LJSMOOTHT::reinit(const int ntypes, double **host_cutsq, double **host_lj1, + double **host_lj2, double **host_lj3, + double **host_lj4, double **host_offset, + double **host_ljsw0, double **host_ljsw1, double **host_ljsw2, double **host_ljsw3, + double **host_ljsw4, + double **cut_inner, double **cut_inner_sq) { + // Allocate a host write buffer for data initialization + UCL_H_Vec host_write(_lj_types*_lj_types*32,*(this->ucl_device), + UCL_WRITE_ONLY); + + for (int i=0; i<_lj_types*_lj_types; i++) + host_write[i]=0.0; + + this->atom->type_pack4(ntypes,_lj_types,lj1,host_write,host_lj1,host_lj2, + host_cutsq,cut_inner_sq); + this->atom->type_pack4(ntypes,_lj_types,lj3,host_write,host_lj3,host_lj4, + host_offset); + this->atom->type_pack4(ntypes,_lj_types,ljsw,host_write,host_ljsw1,host_ljsw2, + host_ljsw3,host_ljsw4); + this->atom->type_pack2(ntypes,_lj_types,ljsw0,host_write,host_ljsw0,cut_inner); +} + +template +void LJSMOOTHT::clear() { + if (!_allocated) + return; + _allocated=false; + + lj1.clear(); + lj3.clear(); + ljsw.clear(); + ljsw0.clear(); + sp_lj.clear(); + this->clear_atomic(); +} + +template +double LJSMOOTHT::host_memory_usage() const { + return this->host_memory_usage_atomic()+sizeof(LJSMOOTH); +} + +// --------------------------------------------------------------------------- +// Calculate energies, forces, and torques +// --------------------------------------------------------------------------- +template +int LJSMOOTHT::loop(const int eflag, const int vflag) { + // Compute the block size and grid size to keep all cores busy + const int BX=this->block_size(); + + int GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); + + int ainum=this->ans->inum(); + int nbor_pitch=this->nbor->nbor_pitch(); + this->time_pair.start(); + if (shared_types) { + this->k_pair_sel->set_size(GX,BX); + this->k_pair_sel->run(&this->atom->x, &lj1, &lj3, &ljsw, &ljsw0, &sp_lj, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &eflag, + &vflag, &ainum, &nbor_pitch, + &this->_threads_per_atom); + } else { + this->k_pair.set_size(GX,BX); + this->k_pair.run(&this->atom->x, &lj1, &lj3, &ljsw, &ljsw0, &_lj_types, &sp_lj, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->ans->force, &this->ans->engv, &eflag, &vflag, + &ainum, &nbor_pitch, &this->_threads_per_atom); + } + this->time_pair.stop(); + return GX; +} + +template class LJSMOOTH; +} diff --git a/lib/gpu/lal_lj_smooth.cu b/lib/gpu/lal_lj_smooth.cu new file mode 100644 index 0000000000..d4a99ed3a7 --- /dev/null +++ b/lib/gpu/lal_lj_smooth.cu @@ -0,0 +1,259 @@ +// ************************************************************************** +// lj_smooth.cu +// ------------------- +// Gurgen Melikyan (HSE University) +// +// Device code for acceleration of the lj/smooth pair style +// +// __________________________________________________________________________ +// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) +// __________________________________________________________________________ +// +// begin : +// email : gkmeliyan@edu.hse.ru +// *************************************************************************** + +#if defined(NV_KERNEL) || defined(USE_HIP) +#include "lal_aux_fun1.h" +#ifndef _DOUBLE_DOUBLE +_texture( pos_tex,float4); +#else +_texture_2d( pos_tex,int4); +#endif +#else +#define pos_tex x_ +#endif + +__kernel void k_lj_smooth(const __global numtyp4 *restrict x_, + const __global numtyp4 *restrict lj1, + const __global numtyp4 *restrict lj3, + const __global numtyp4 *restrict ljsw, + const __global numtyp2 *restrict ljsw0, + const int lj_types, + const __global numtyp *restrict sp_lj, + const __global int * dev_nbor, + const __global int * dev_packed, + __global acctyp4 *restrict ans, + __global acctyp *restrict engv, + const int eflag, const int vflag, const int inum, + const int nbor_pitch, const int t_per_atom) { + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + int n_stride; + local_allocate_store_pair(); + + acctyp4 f; + f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0; + acctyp energy, virial[6]; + if (EVFLAG) { + energy=(acctyp)0; + for (int i=0; i<6; i++) virial[i]=(acctyp)0; + } + + if (ii +class LJSMOOTH : public BaseAtomic { + public: + LJSMOOTH(); + ~LJSMOOTH(); + + /// Clear any previous data and set up for a new LAMMPS run + /** \param max_nbors initial number of rows in the neighbor matrix + * \param cell_size cutoff + skin + * \param gpu_split fraction of particles handled by device + * + * Returns: + * - 0 if successful + * - -1 if fix gpu not found + * - -3 if there is an out of memory error + * - -4 if the GPU library was not compiled for GPU + * - -5 Double precision is not supported on card **/ + int init(const int ntypes, double **host_cutsq, + double **host_lj1, double **host_lj2, double **host_lj3, + double **host_lj4, double **host_offset, double *host_special_lj, + const int nlocal, const int nall, const int max_nbors, + const int maxspecial, const double cell_size, + const double gpu_split, FILE *screen, + double **host_ljsw0, double **host_ljsw1, double **host_ljsw2, + double **host_ljsw3, double **host_ljsw4, + double **cut_inner, double **cut_inner_sq); + + /// Send updated coeffs from host to device (to be compatible with fix adapt) + void reinit(const int ntypes, double **host_cutsq, + double **host_lj1, double **host_lj2, double **host_lj3, + double **host_lj4, double **host_offset, + double **host_ljsw0, double **host_ljsw1, double **host_ljsw2, + double **host_ljsw3, double **host_ljsw4, + double **cut_inner, double **cut_inner_sq); + + /// Clear all host and device data + /** \note This is called at the beginning of the init() routine **/ + void clear(); + + /// Returns memory usage on device per atom + int bytes_per_atom(const int max_nbors) const; + + /// Total host memory used by library for pair style + double host_memory_usage() const; + + // --------------------------- TYPE DATA -------------------------- + + /// lj1.x = lj1, lj1.y = lj2, lj1.z = cutsq, lj1.w = cut_inner_sq + UCL_D_Vec lj1; + /// lj3.x = lj3, lj3.y = lj4, lj3.z = offset + UCL_D_Vec lj3; + /// ljsw.x = ljsw1, ljsw.y = ljsw2, ljsw.z = ljsw3, ljsw.w = ljsw4 + UCL_D_Vec ljsw; + /// ljsw0.x = ljsw0 ljsw0.y = cut_inner + UCL_D_Vec ljsw0; + /// Special LJ values + UCL_D_Vec sp_lj; + + /// If atom type constants fit in shared memory, use fast kernels + bool shared_types; + + /// Number of atom types + int _lj_types; + + private: + bool _allocated; + int loop(const int _eflag, const int _vflag); +}; + +} + +#endif diff --git a/lib/gpu/lal_lj_smooth_ext.cpp b/lib/gpu/lal_lj_smooth_ext.cpp new file mode 100644 index 0000000000..48dad74071 --- /dev/null +++ b/lib/gpu/lal_lj_smooth_ext.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + lj_smooth_ext.cpp + ------------------- + Gurgen Melikyan (HSE University) + + Functions for LAMMPS access to lj/smooth acceleration routines. + + __________________________________________________________________________ + This file is part of the LAMMPS Accelerator Library (LAMMPS_AL) + __________________________________________________________________________ + + begin : + email : gkmeliyan@edu.hse.ru + ***************************************************************************/ + +#include +#include +#include + +#include "lal_lj_smooth.h" + +using namespace std; +using namespace LAMMPS_AL; + +static LJSMOOTH LJSMTMF; + +// --------------------------------------------------------------------------- +// Allocate memory on host and device and copy constants to device +// --------------------------------------------------------------------------- +int ljsmt_gpu_init(const int ntypes, double **cutsq, double **host_lj1, + double **host_lj2, double **host_lj3, double **host_lj4, + double **offset, double *special_lj, const int inum, + const int nall, const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen, + double **host_ljsw0, double **host_ljsw1, double **host_ljsw2, double **host_ljsw3, + double **host_ljsw4, double **cut_inner, double **cut_inner_sq) { + LJSMTMF.clear(); + gpu_mode=LJSMTMF.device->gpu_mode(); + double gpu_split=LJSMTMF.device->particle_split(); + int first_gpu=LJSMTMF.device->first_device(); + int last_gpu=LJSMTMF.device->last_device(); + int world_me=LJSMTMF.device->world_me(); + int gpu_rank=LJSMTMF.device->gpu_rank(); + int procs_per_gpu=LJSMTMF.device->procs_per_gpu(); + + LJSMTMF.device->init_message(screen,"lj/smooth",first_gpu,last_gpu); + + bool message=false; + if (LJSMTMF.device->replica_me()==0 && screen) + message=true; + + if (message) { + fprintf(screen,"Initializing Device and compiling on process 0..."); + fflush(screen); + } + + int init_ok=0; + if (world_me==0) + init_ok=LJSMTMF.init(ntypes, cutsq, host_lj1, host_lj2, host_lj3, + host_lj4, offset, special_lj, inum, nall, max_nbors, + maxspecial, cell_size, gpu_split, screen, + host_ljsw0, host_ljsw1, host_ljsw2, host_ljsw3, host_ljsw4, cut_inner, cut_inner_sq); + + LJSMTMF.device->world_barrier(); + if (message) + fprintf(screen,"Done.\n"); + + for (int i=0; igpu_barrier(); + if (message) + fprintf(screen,"Done.\n"); + } + if (message) + fprintf(screen,"\n"); + + if (init_ok==0) + LJSMTMF.estimate_gpu_overhead(); + return init_ok; +} + +// --------------------------------------------------------------------------- +// Copy updated coeffs from host to device +// --------------------------------------------------------------------------- +void ljsmt_gpu_reinit(const int ntypes, double **cutsq, double **host_lj1, + double **host_lj2, double **host_lj3, double **host_lj4, + double **offset, double **host_ljsw0, double **host_ljsw1, double **host_ljsw2, double **host_ljsw3, + double **host_ljsw4, double **cut_inner, double **cut_inner_sq) { + int world_me=LJSMTMF.device->world_me(); + int gpu_rank=LJSMTMF.device->gpu_rank(); + int procs_per_gpu=LJSMTMF.device->procs_per_gpu(); + + if (world_me==0) + LJSMTMF.reinit(ntypes, cutsq, host_lj1, host_lj2, host_lj3, host_lj4, offset, host_ljsw0, host_ljsw1, host_ljsw2, host_ljsw3, host_ljsw4, cut_inner, cut_inner_sq); + LJSMTMF.device->world_barrier(); + + for (int i=0; igpu_barrier(); + } +} + +void ljsmt_gpu_clear() { + LJSMTMF.clear(); +} + +int ** ljsmt_gpu_compute_n(const int ago, const int inum_full, + const int nall, double **host_x, int *host_type, + double *sublo, double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + int **ilist, int **jnum, const double cpu_time, + bool &success) { + return LJSMTMF.compute(ago, inum_full, nall, host_x, host_type, sublo, + subhi, tag, nspecial, special, eflag, vflag, eatom, + vatom, host_start, ilist, jnum, cpu_time, success); +} + +void ljsmt_gpu_compute(const int ago, const int inum_full, const int nall, + double **host_x, int *host_type, int *ilist, int *numj, + int **firstneigh, const bool eflag, const bool vflag, + const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success) { + LJSMTMF.compute(ago,inum_full,nall,host_x,host_type,ilist,numj, + firstneigh,eflag,vflag,eatom,vatom,host_start,cpu_time,success); +} + +double ljsmt_gpu_bytes() { + return LJSMTMF.host_memory_usage(); +} diff --git a/src/GPU/Install.sh b/src/GPU/Install.sh index 49b7eeda57..8d55cd5857 100755 --- a/src/GPU/Install.sh +++ b/src/GPU/Install.sh @@ -113,6 +113,8 @@ action pair_lj_cut_coul_msm_gpu.cpp pair_lj_cut_coul_msm.cpp action pair_lj_cut_coul_msm_gpu.h pair_lj_cut_coul_msm.h action pair_lj_cut_gpu.cpp action pair_lj_cut_gpu.h +action pair_lj_smooth_gpu.cpp +action pair_lj_smooth_gpu.h action pair_lj_expand_gpu.cpp action pair_lj_expand_gpu.h action pair_lj_expand_coul_long_gpu.cpp pair_lj_expand_coul_long.cpp diff --git a/src/GPU/pair_lj_smooth_gpu.cpp b/src/GPU/pair_lj_smooth_gpu.cpp new file mode 100644 index 0000000000..1613e18fa3 --- /dev/null +++ b/src/GPU/pair_lj_smooth_gpu.cpp @@ -0,0 +1,264 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://lammps.sandia.gov/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + 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: Gurgen Melikyan (HSE University) +------------------------------------------------------------------------- */ + +#include "pair_lj_smooth_gpu.h" + +#include "atom.h" +#include "atom_vec.h" +#include "comm.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "gpu_extra.h" +#include "integrate.h" +#include "memory.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "neighbor.h" +#include "suffix.h" +#include "universe.h" +#include "update.h" + +#include +#include + +using namespace LAMMPS_NS; + +// External functions from gpu library for atom decomposition + +int ljsmt_gpu_init(const int ntypes, double **cutsq, double **host_lj1, double **host_lj2, + double **host_lj3, double **host_lj4, double **offset, double *special_lj, + const int nlocal, const int nall, const int max_nbors, const int maxspecial, + const double cell_size, int &gpu_mode, FILE *screen, double **host_ljsw0, + double **host_ljsw1, double **host_ljsw2, double **host_ljsw3, + double **host_ljsw4, double **cut_inner, double **cut_innersq); + +void ljsmt_gpu_reinit(const int ntypes, double **cutsq, double **host_lj1, double **host_lj2, + double **host_lj3, double **host_lj4, double **offset, double **host_ljsw0, + double **host_ljsw1, double **host_ljsw2, double **host_ljsw3, + double **host_ljsw4, double **cut_inner, double **cut_innersq); + +void ljsmt_gpu_clear(); +int **ljsmt_gpu_compute_n(const int ago, const int inum, const int nall, double **host_x, + int *host_type, double *sublo, double *subhi, tagint *tag, int **nspecial, + tagint **special, const bool eflag, const bool vflag, const bool eatom, + const bool vatom, int &host_start, int **ilist, int **jnum, + const double cpu_time, bool &success); +void ljsmt_gpu_compute(const int ago, const int inum, const int nall, double **host_x, + int *host_type, int *ilist, int *numj, int **firstneigh, const bool eflag, + const bool vflag, const bool eatom, const bool vatom, int &host_start, + const double cpu_time, bool &success); +double ljsmt_gpu_bytes(); + +/* ---------------------------------------------------------------------- */ + +PairLJSmoothGPU::PairLJSmoothGPU(LAMMPS *lmp) : PairLJSmooth(lmp), gpu_mode(GPU_FORCE) +{ + respa_enable = 0; + cpu_time = 0.0; + suffix_flag |= Suffix::GPU; + GPU_EXTRA::gpu_ready(lmp->modify, lmp->error); +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairLJSmoothGPU::~PairLJSmoothGPU() +{ + ljsmt_gpu_clear(); +} + +/* ---------------------------------------------------------------------- */ + +void PairLJSmoothGPU::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + int nall = atom->nlocal + atom->nghost; + int inum, host_start; + + bool success = true; + int *ilist, *numneigh, **firstneigh; + if (gpu_mode != GPU_FORCE) { + double sublo[3], subhi[3]; + if (domain->triclinic == 0) { + sublo[0] = domain->sublo[0]; + sublo[1] = domain->sublo[1]; + sublo[2] = domain->sublo[2]; + subhi[0] = domain->subhi[0]; + subhi[1] = domain->subhi[1]; + subhi[2] = domain->subhi[2]; + } else { + domain->bbox(domain->sublo_lamda, domain->subhi_lamda, sublo, subhi); + } + inum = atom->nlocal; + firstneigh = + ljsmt_gpu_compute_n(neighbor->ago, inum, nall, atom->x, atom->type, sublo, subhi, atom->tag, + atom->nspecial, atom->special, eflag, vflag, eflag_atom, vflag_atom, + host_start, &ilist, &numneigh, cpu_time, success); + } else { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + ljsmt_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, ilist, numneigh, firstneigh, + eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time, success); + } + if (!success) error->one(FLERR, "Insufficient memory on accelerator"); + + if (host_start < inum) { + cpu_time = MPI_Wtime(); + cpu_compute(host_start, inum, eflag, vflag, ilist, numneigh, firstneigh); + cpu_time = MPI_Wtime() - cpu_time; + } + //fprintf("LJ_SMOOTH_GPU"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairLJSmoothGPU::init_style() +{ + //cut_respa = nullptr; + + if (force->newton_pair) error->all(FLERR, "Cannot use newton pair with lj/smooth/gpu pair style"); + + // Repeat cutsq calculation because done after call to init_style + double maxcut = -1.0; + double cut; + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { + cut = init_one(i, j); + cut *= cut; + if (cut > maxcut) maxcut = cut; + cutsq[i][j] = cutsq[j][i] = cut; + } else + cutsq[i][j] = cutsq[j][i] = 0.0; + } + } + double cell_size = sqrt(maxcut) + neighbor->skin; + + int maxspecial = 0; + if (atom->molecular) maxspecial = atom->maxspecial; + int mnf = 5e-2 * neighbor->oneatom; + int success = + ljsmt_gpu_init(atom->ntypes + 1, cutsq, lj1, lj2, lj3, lj4, offset, force->special_lj, + atom->nlocal, atom->nlocal + atom->nghost, mnf, maxspecial, cell_size, + gpu_mode, screen, ljsw0, ljsw1, ljsw2, ljsw3, ljsw4, cut_inner, cut_inner_sq); + GPU_EXTRA::check_flag(success, error, world); + + if (gpu_mode == GPU_FORCE) { + int irequest = neighbor->request(this, instance_me); + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairLJSmoothGPU::reinit() +{ + Pair::reinit(); + + ljsmt_gpu_reinit(atom->ntypes + 1, cutsq, lj1, lj2, lj3, lj4, offset, ljsw0, ljsw1, ljsw2, ljsw3, + ljsw4, cut_inner, cut_inner_sq); +} + +/* ---------------------------------------------------------------------- */ + +double PairLJSmoothGPU::memory_usage() +{ + double bytes = Pair::memory_usage(); + return bytes + ljsmt_gpu_bytes(); +} + +/* ---------------------------------------------------------------------- */ + +void PairLJSmoothGPU::cpu_compute(int start, int inum, int eflag, int /* vflag */, int *ilist, + int *numneigh, int **firstneigh) +{ + int i, j, ii, jj, jnum, itype, jtype; + double xtmp, ytmp, ztmp, delx, dely, delz, evdwl, fpair; + double rsq, r2inv, r6inv, forcelj, factor_lj; + double r, t, tsq, fskin; + int *jlist; + + double **x = atom->x; + double **f = atom->f; + int *type = atom->type; + double *special_lj = force->special_lj; + + // loop over neighbors of my atoms + + for (ii = start; ii < inum; ii++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + r2inv = 1.0 / rsq; + if (rsq < cut_inner_sq[itype][jtype]) { + r6inv = r2inv * r2inv * r2inv; + forcelj = r6inv * (lj1[itype][jtype] * r6inv - lj2[itype][jtype]); + } else { + r = sqrt(rsq); + t = r - cut_inner[itype][jtype]; + tsq = t * t; + fskin = ljsw1[itype][jtype] + ljsw2[itype][jtype] * t + ljsw3[itype][jtype] * tsq + + ljsw4[itype][jtype] * tsq * t; + forcelj = fskin * r; + } + + fpair = factor_lj * forcelj * r2inv; + + f[i][0] += delx * fpair; + f[i][1] += dely * fpair; + f[i][2] += delz * fpair; + + if (eflag) { + if (rsq < cut_inner_sq[itype][jtype]) + evdwl = r6inv * (lj3[itype][jtype] * r6inv - lj4[itype][jtype]) - offset[itype][jtype]; + else + evdwl = ljsw0[itype][jtype] - ljsw1[itype][jtype] * t - + ljsw2[itype][jtype] * tsq / 2.0 - ljsw3[itype][jtype] * tsq * t / 3.0 - + ljsw4[itype][jtype] * tsq * tsq / 4.0 - offset[itype][jtype]; + evdwl *= factor_lj; + } + + if (evflag) ev_tally_full(i, evdwl, 0.0, fpair, delx, dely, delz); + } + } + } +} diff --git a/src/GPU/pair_lj_smooth_gpu.h b/src/GPU/pair_lj_smooth_gpu.h new file mode 100644 index 0000000000..2b7f978f0c --- /dev/null +++ b/src/GPU/pair_lj_smooth_gpu.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(lj/smooth/gpu, PairLJSmoothGPU); +// clang-format on +#else + +#ifndef LMP_PAIR_LJ_SMOOTH_GPU_H +#define LMP_PAIR_LJ_SMOOTH_GPU_H + +#include "pair_lj_smooth.h" + +namespace LAMMPS_NS { + +class PairLJSmoothGPU : public PairLJSmooth { + public: + PairLJSmoothGPU(LAMMPS *lmp); + ~PairLJSmoothGPU(); + void cpu_compute(int, int, int, int, int *, int *, int **); + void compute(int, int); + void init_style(); + void reinit(); + double memory_usage(); + + enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; + + private: + int gpu_mode; + double cpu_time; +}; + +} // namespace LAMMPS_NS +#endif +#endif + +/* ERROR/WARNING messages: + +E: Insufficient memory on accelerator + +There is insufficient memory on one of the devices specified for the gpu +package + +E: Cannot use newton pair with lj/smooth/gpu pair style + +Self-explanatory. + +*/ diff --git a/src/MOLECULE/bond_fene_expand.h b/src/MOLECULE/bond_fene_expand.h index 6c79b1cfd0..49a8b8ab8e 100644 --- a/src/MOLECULE/bond_fene_expand.h +++ b/src/MOLECULE/bond_fene_expand.h @@ -13,7 +13,7 @@ #ifdef BOND_CLASS -BondStyle(fene / expand, BondFENEExpand) +BondStyle(fene/expand, BondFENEExpand) #else