1 // clang-format off
2 /* ----------------------------------------------------------------------
3    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
4    https://www.lammps.org/, Sandia National Laboratories
5    Steve Plimpton, sjplimp@sandia.gov
6 
7    Copyright (2003) Sandia Corporation.  Under the terms of Contract
8    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
9    certain rights in this software.  This software is distributed under
10    the GNU General Public License.
11 
12    See the README file in the top-level LAMMPS directory.
13 ------------------------------------------------------------------------- */
14 
15 /* ----------------------------------------------------------------------
16    Contributing author: Anders Hafreager (UiO)
17 ------------------------------------------------------------------------- */
18 
19 #include "pair_vashishta_gpu.h"
20 
21 #include "atom.h"
22 #include "comm.h"
23 #include "domain.h"
24 #include "error.h"
25 #include "force.h"
26 #include "gpu_extra.h"
27 #include "memory.h"
28 #include "neigh_list.h"
29 #include "neigh_request.h"
30 #include "neighbor.h"
31 #include "suffix.h"
32 
33 using namespace LAMMPS_NS;
34 
35 // External functions from cuda library for atom decomposition
36 
37 int vashishta_gpu_init(const int ntypes, const int inum, const int nall,
38                        const int max_nbors, const double cell_size,
39                        int &gpu_mode, FILE *screen, int* host_map,
40                        const int nelements, int*** host_elem3param,
41                        const int nparams, const double* cutsq, const double* r0,
42                        const double* gamma, const double* eta,
43                        const double* lam1inv, const double* lam4inv,
44                        const double* zizj, const double* mbigd,
45                        const double* dvrc, const double* big6w,
46                        const double* heta, const double* bigh,
47                        const double* bigw, const double* c0,
48                        const double* costheta, const double* bigb,
49                        const double* big2b, const double* bigc);
50 void vashishta_gpu_clear();
51 int ** vashishta_gpu_compute_n(const int ago, const int inum, const int nall,
52                         double **host_x, int *host_type, double *sublo,
53                         double *subhi, tagint *tag, int **nspecial,
54                         tagint **special, const bool eflag, const bool vflag,
55                         const bool eatom, const bool vatom, int &host_start,
56                         int **ilist, int **jnum,
57                         const double cpu_time, bool &success);
58 void vashishta_gpu_compute(const int ago, const int nloc, const int nall,
59                            const int ln, double **host_x, int *host_type,
60                            int *ilist, int *numj, int **firstneigh,
61                            const bool eflag, const bool vflag,
62                            const bool eatom, const bool vatom, int &host_start,
63                            const double cpu_time, bool &success);
64 double vashishta_gpu_bytes();
65 
66 /* ---------------------------------------------------------------------- */
67 
PairVashishtaGPU(LAMMPS * lmp)68 PairVashishtaGPU::PairVashishtaGPU(LAMMPS *lmp) : PairVashishta(lmp), gpu_mode(GPU_FORCE)
69 {
70   cpu_time = 0.0;
71   reinitflag = 0;
72   gpu_allocated = false;
73   suffix_flag |= Suffix::GPU;
74   GPU_EXTRA::gpu_ready(lmp->modify, lmp->error);
75 
76   cutghost = nullptr;
77   ghostneigh = 1;
78 }
79 
80 /* ----------------------------------------------------------------------
81    check if allocated, since class can be destructed when incomplete
82 ------------------------------------------------------------------------- */
83 
~PairVashishtaGPU()84 PairVashishtaGPU::~PairVashishtaGPU()
85 {
86   vashishta_gpu_clear();
87   if (allocated)
88     memory->destroy(cutghost);
89 }
90 
91 /* ---------------------------------------------------------------------- */
92 
compute(int eflag,int vflag)93 void PairVashishtaGPU::compute(int eflag, int vflag)
94 {
95   ev_init(eflag,vflag);
96 
97   int nall = atom->nlocal + atom->nghost;
98   int inum, host_start;
99 
100   bool success = true;
101   int *ilist, *numneigh, **firstneigh;
102   if (gpu_mode != GPU_FORCE) {
103     double sublo[3],subhi[3];
104     if (domain->triclinic == 0) {
105       sublo[0] = domain->sublo[0];
106       sublo[1] = domain->sublo[1];
107       sublo[2] = domain->sublo[2];
108       subhi[0] = domain->subhi[0];
109       subhi[1] = domain->subhi[1];
110       subhi[2] = domain->subhi[2];
111     } else {
112       domain->bbox(domain->sublo_lamda,domain->subhi_lamda,sublo,subhi);
113     }
114     inum = atom->nlocal;
115     firstneigh = vashishta_gpu_compute_n(neighbor->ago, inum, nall,
116                                    atom->x, atom->type, sublo,
117                                    subhi, atom->tag, atom->nspecial,
118                                    atom->special, eflag, vflag, eflag_atom,
119                                    vflag_atom, host_start,
120                                    &ilist, &numneigh, cpu_time, success);
121   } else {
122     inum = list->inum;
123     ilist = list->ilist;
124     numneigh = list->numneigh;
125     firstneigh = list->firstneigh;
126 
127     vashishta_gpu_compute(neighbor->ago, inum, nall, inum+list->gnum,
128                    atom->x, atom->type, ilist, numneigh, firstneigh, eflag,
129                    vflag, eflag_atom, vflag_atom, host_start, cpu_time,
130                    success);
131   }
132   if (!success)
133     error->one(FLERR,"Insufficient memory on accelerator");
134 }
135 
136 /* ---------------------------------------------------------------------- */
137 
allocate()138 void PairVashishtaGPU::allocate()
139 {
140   if (!allocated) {
141     PairVashishta::allocate();
142   }
143   int n = atom->ntypes;
144 
145   memory->create(cutghost,n+1,n+1,"pair:cutghost");
146   gpu_allocated = true;
147 }
148 
149 /* ----------------------------------------------------------------------
150    init specific to this pair style
151 ------------------------------------------------------------------------- */
152 
init_style()153 void PairVashishtaGPU::init_style()
154 {
155   double cell_size = cutmax + neighbor->skin;
156 
157   if (atom->tag_enable == 0)
158     error->all(FLERR,"Pair style vashishta/gpu requires atom IDs");
159   if (force->newton_pair != 0)
160     error->all(FLERR,"Pair style vashishta/gpu requires newton pair off");
161 
162   double *cutsq, *r0, *gamma, *eta;
163   double *lam1inv, *lam4inv, *zizj, *mbigd;
164   double *dvrc, *big6w, *heta, *bigh;
165   double *bigw, *c0, *costheta, *bigb;
166   double *big2b, *bigc;
167 
168   cutsq = r0 = gamma = eta = nullptr;
169   lam1inv = lam4inv = zizj = mbigd = nullptr;
170   dvrc = big6w = heta = bigh = nullptr;
171   bigw = c0 = costheta = bigb = nullptr;
172   big2b = bigc = nullptr;
173 
174   memory->create(cutsq,nparams,"pair:cutsq");
175   memory->create(r0,nparams,"pair:r0");
176   memory->create(gamma,nparams,"pair:gamma");
177   memory->create(eta,nparams,"pair:eta");
178   memory->create(lam1inv,nparams,"pair:lam1inv");
179   memory->create(lam4inv,nparams,"pair:lam4inv");
180   memory->create(zizj,nparams,"pair:zizj");
181   memory->create(mbigd,nparams,"pair:mbigd");
182   memory->create(dvrc,nparams,"pair:dvrc");
183   memory->create(big6w,nparams,"pair:big6w");
184   memory->create(heta,nparams,"pair:heta");
185   memory->create(bigh,nparams,"pair:bigh");
186   memory->create(bigw,nparams,"pair:bigw");
187   memory->create(c0,nparams,"pair:c0");
188   memory->create(costheta,nparams,"pair:costheta");
189   memory->create(bigb,nparams,"pair:bigb");
190   memory->create(big2b,nparams,"pair:big2b");
191   memory->create(bigc,nparams,"pair:bigc");
192 
193   for (int i = 0; i < nparams; i++) {
194     cutsq[i] = params[i].cutsq;
195     r0[i] = params[i].r0;
196     gamma[i] = params[i].gamma;
197     eta[i] = params[i].eta;
198     lam1inv[i] = params[i].lam1inv;
199     lam4inv[i] = params[i].lam4inv;
200     zizj[i] = params[i].zizj;
201     mbigd[i] = params[i].mbigd;
202     dvrc[i] = params[i].dvrc;
203     big6w[i] = params[i].big6w;
204     heta[i] = params[i].heta;
205     bigh[i] = params[i].bigh;
206     bigw[i] = params[i].bigw;
207     c0[i] = params[i].c0;
208     costheta[i] = params[i].costheta;
209     bigb[i] = params[i].bigb;
210     big2b[i] = params[i].big2b;
211     bigc[i] = params[i].bigc;
212   }
213   int mnf = 5e-2 * neighbor->oneatom;
214   int success = vashishta_gpu_init(atom->ntypes+1, atom->nlocal, atom->nlocal+atom->nghost, mnf,
215                             cell_size, gpu_mode, screen, map, nelements,
216                             elem3param, nparams, cutsq, r0, gamma, eta, lam1inv,
217                             lam4inv, zizj, mbigd, dvrc, big6w, heta, bigh, bigw,
218                             c0, costheta, bigb, big2b, bigc);
219   memory->destroy(cutsq);
220   memory->destroy(r0);
221   memory->destroy(gamma);
222   memory->destroy(eta);
223   memory->destroy(lam1inv);
224   memory->destroy(lam4inv);
225   memory->destroy(zizj);
226   memory->destroy(mbigd);
227   memory->destroy(dvrc);
228   memory->destroy(big6w);
229   memory->destroy(heta);
230   memory->destroy(bigh);
231   memory->destroy(bigw);
232   memory->destroy(c0);
233   memory->destroy(costheta);
234   memory->destroy(bigb);
235   memory->destroy(big2b);
236   memory->destroy(bigc);
237 
238   GPU_EXTRA::check_flag(success,error,world);
239 
240   if (gpu_mode == GPU_FORCE) {
241     int irequest = neighbor->request(this,instance_me);
242     neighbor->requests[irequest]->half = 0;
243     neighbor->requests[irequest]->full = 1;
244     neighbor->requests[irequest]->ghost = 1;
245   }
246   if (comm->cutghostuser < (2.0*cutmax + neighbor->skin)) {
247     comm->cutghostuser=2.0*cutmax + neighbor->skin;
248     if (comm->me == 0)
249        error->warning(FLERR,"Increasing communication cutoff for GPU style");
250   }
251 }
252 
253 /* ----------------------------------------------------------------------
254    init for one type pair i,j and corresponding j,i
255 ------------------------------------------------------------------------- */
256 
init_one(int i,int j)257 double PairVashishtaGPU::init_one(int i, int j)
258 {
259   if (!gpu_allocated) {
260     allocate();
261   }
262   if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
263   cutghost[i][j] = cutmax;
264   cutghost[j][i] = cutmax;
265 
266   return cutmax;
267 }
268 
269