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