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: Trung Dac Nguyen (ndactrung@gmail.com)
17 ------------------------------------------------------------------------- */
18
19 #include "pair_tersoff_mod_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 tersoff_mod_gpu_init(const int ntypes, const int inum, const int nall,
38 const int max_nbors, const double cell_size, int &gpu_mode, FILE *screen,
39 int* host_map, const int nelements, int*** host_elem3param, const int nparams,
40 const double* ts_lam1, const double* ts_lam2, const double* ts_lam3,
41 const double* ts_powermint, const double* ts_biga, const double* ts_bigb,
42 const double* ts_bigr, const double* ts_bigd, const double* ts_c1,
43 const double* ts_c2, const double* ts_c3, const double* ts_c4,
44 const double* ts_c5, const double* ts_h, const double* ts_beta,
45 const double* ts_powern, const double* ts_powern_del,
46 const double* ts_ca1, const double* ts_cutsq);
47 void tersoff_mod_gpu_clear();
48 int ** tersoff_mod_gpu_compute_n(const int ago, const int inum_full,
49 const int nall, double **host_x, int *host_type,
50 double *sublo, double *subhi, tagint *tag, int **nspecial,
51 tagint **special, const bool eflag, const bool vflag,
52 const bool eatom, const bool vatom, int &host_start,
53 int **ilist, int **jnum, const double cpu_time,
54 bool &success);
55 void tersoff_mod_gpu_compute(const int ago, const int nlocal, const int nall,
56 const int nlist, double **host_x, int *host_type,
57 int *ilist, int *numj, int **firstneigh, const bool eflag,
58 const bool vflag, const bool eatom, const bool vatom,
59 int &host_start, const double cpu_time, bool &success);
60 double tersoff_mod_gpu_bytes();
61
62 /* ---------------------------------------------------------------------- */
63
PairTersoffMODGPU(LAMMPS * lmp)64 PairTersoffMODGPU::PairTersoffMODGPU(LAMMPS *lmp) : PairTersoffMOD(lmp),
65 gpu_mode(GPU_FORCE)
66 {
67 cpu_time = 0.0;
68 suffix_flag |= Suffix::GPU;
69 GPU_EXTRA::gpu_ready(lmp->modify, lmp->error);
70
71 cutghost = nullptr;
72 ghostneigh = 1;
73 }
74
75 /* ----------------------------------------------------------------------
76 check if allocated, since class can be destructed when incomplete
77 ------------------------------------------------------------------------- */
78
~PairTersoffMODGPU()79 PairTersoffMODGPU::~PairTersoffMODGPU()
80 {
81 tersoff_mod_gpu_clear();
82 if (allocated)
83 memory->destroy(cutghost);
84 }
85
86 /* ---------------------------------------------------------------------- */
87
compute(int eflag,int vflag)88 void PairTersoffMODGPU::compute(int eflag, int vflag)
89 {
90 ev_init(eflag,vflag);
91
92 int nall = atom->nlocal + atom->nghost;
93 int inum, host_start;
94
95 bool success = true;
96 int *ilist, *numneigh, **firstneigh;
97 if (gpu_mode != GPU_FORCE) {
98 double sublo[3],subhi[3];
99 if (domain->triclinic == 0) {
100 sublo[0] = domain->sublo[0];
101 sublo[1] = domain->sublo[1];
102 sublo[2] = domain->sublo[2];
103 subhi[0] = domain->subhi[0];
104 subhi[1] = domain->subhi[1];
105 subhi[2] = domain->subhi[2];
106 } else {
107 domain->bbox(domain->sublo_lamda,domain->subhi_lamda,sublo,subhi);
108 }
109 inum = atom->nlocal;
110 firstneigh = tersoff_mod_gpu_compute_n(neighbor->ago, inum, nall,
111 atom->x, atom->type, sublo,
112 subhi, atom->tag, atom->nspecial,
113 atom->special, eflag, vflag, eflag_atom,
114 vflag_atom, host_start,
115 &ilist, &numneigh, cpu_time, success);
116 } else {
117 inum = list->inum;
118 ilist = list->ilist;
119 numneigh = list->numneigh;
120 firstneigh = list->firstneigh;
121
122 tersoff_mod_gpu_compute(neighbor->ago, inum, nall, inum+list->gnum,
123 atom->x, atom->type, ilist, numneigh, firstneigh, eflag,
124 vflag, eflag_atom, vflag_atom, host_start, cpu_time,
125 success);
126 }
127 if (!success)
128 error->one(FLERR,"Insufficient memory on accelerator");
129 }
130
131 /* ---------------------------------------------------------------------- */
132
allocate()133 void PairTersoffMODGPU::allocate()
134 {
135 PairTersoffMOD::allocate();
136 int n = atom->ntypes;
137
138 memory->create(cutghost,n+1,n+1,"pair:cutghost");
139 }
140
141 /* ----------------------------------------------------------------------
142 init specific to this pair style
143 ------------------------------------------------------------------------- */
144
init_style()145 void PairTersoffMODGPU::init_style()
146 {
147 double cell_size = cutmax + neighbor->skin;
148
149 if (atom->tag_enable == 0)
150 error->all(FLERR,"Pair style tersoff/mod/gpu requires atom IDs");
151 if (force->newton_pair != 0)
152 error->all(FLERR,"Pair style tersoff/mod/gpu requires newton pair off");
153
154 double *lam1, *lam2, *lam3, *powermint;
155 double *biga, *bigb, *bigr, *bigd;
156 double *c1, *c2, *c3, *c4, *c5, *h;
157 double *beta, *powern, *ca1, *powern_del, *_cutsq;
158 lam1 = lam2 = lam3 = powermint = nullptr;
159 biga = bigb = bigr = bigd = nullptr;
160 powern_del = ca1 = nullptr;
161 c1 = c2 = c3 = c4 = c5 = h = nullptr;
162 beta = powern = _cutsq = nullptr;
163
164 memory->create(lam1,nparams,"pair:lam1");
165 memory->create(lam2,nparams,"pair:lam2");
166 memory->create(lam3,nparams,"pair:lam3");
167 memory->create(powermint,nparams,"pair:powermint");
168 memory->create(biga,nparams,"pair:biga");
169 memory->create(bigb,nparams,"pair:bigb");
170 memory->create(bigr,nparams,"pair:bigr");
171 memory->create(bigd,nparams,"pair:bigd");
172 memory->create(c1,nparams,"pair:c1");
173 memory->create(c2,nparams,"pair:c2");
174 memory->create(c3,nparams,"pair:c3");
175 memory->create(c4,nparams,"pair:c4");
176 memory->create(c5,nparams,"pair:c5");
177 memory->create(h,nparams,"pair:h");
178 memory->create(beta,nparams,"pair:beta");
179 memory->create(powern,nparams,"pair:powern");
180 memory->create(powern_del,nparams,"pair:powern_del");
181 memory->create(ca1,nparams,"pair:ca1");
182 memory->create(_cutsq,nparams,"pair:_cutsq");
183
184 for (int i = 0; i < nparams; i++) {
185 lam1[i] = params[i].lam1;
186 lam2[i] = params[i].lam2;
187 lam3[i] = params[i].lam3;
188 powermint[i] = params[i].powermint;
189 biga[i] = params[i].biga;
190 bigb[i] = params[i].bigb;
191 bigr[i] = params[i].bigr;
192 bigd[i] = params[i].bigd;
193 c1[i] = params[i].c1;
194 c2[i] = params[i].c2;
195 c3[i] = params[i].c3;
196 c4[i] = params[i].c4;
197 c5[i] = params[i].c5;
198 h[i] = params[i].h;
199 beta[i] = params[i].beta;
200 powern[i] = params[i].powern;
201 powern_del[i] = params[i].powern_del;
202 ca1[i] = params[i].ca1;
203 _cutsq[i] = params[i].cutsq;
204 }
205
206 int mnf = 5e-2 * neighbor->oneatom;
207 int success = tersoff_mod_gpu_init(atom->ntypes+1, atom->nlocal,
208 atom->nlocal+atom->nghost, mnf,
209 cell_size, gpu_mode, screen, map, nelements,
210 elem3param, nparams, lam1, lam2, lam3,
211 powermint, biga, bigb, bigr, bigd,
212 c1, c2, c3, c4, c5, h, beta, powern,
213 powern_del, ca1, _cutsq);
214
215 memory->destroy(lam1);
216 memory->destroy(lam2);
217 memory->destroy(lam3);
218 memory->destroy(powermint);
219 memory->destroy(biga);
220 memory->destroy(bigb);
221 memory->destroy(bigr);
222 memory->destroy(bigd);
223 memory->destroy(c1);
224 memory->destroy(c2);
225 memory->destroy(c3);
226 memory->destroy(c4);
227 memory->destroy(c5);
228 memory->destroy(h);
229 memory->destroy(beta);
230 memory->destroy(powern);
231 memory->destroy(ca1);
232 memory->destroy(powern_del);
233 memory->destroy(_cutsq);
234
235 GPU_EXTRA::check_flag(success,error,world);
236
237 if (gpu_mode == GPU_FORCE) {
238 int irequest = neighbor->request(this);
239 neighbor->requests[irequest]->half = 0;
240 neighbor->requests[irequest]->full = 1;
241 neighbor->requests[irequest]->ghost = 1;
242 }
243 if (comm->cutghostuser < (2.0*cutmax + neighbor->skin)) {
244 comm->cutghostuser = 2.0*cutmax + neighbor->skin;
245 if (comm->me == 0)
246 error->warning(FLERR,"Increasing communication cutoff for GPU style");
247 }
248 }
249
250 /* ----------------------------------------------------------------------
251 init for one type pair i,j and corresponding j,i
252 ------------------------------------------------------------------------- */
253
init_one(int i,int j)254 double PairTersoffMODGPU::init_one(int i, int j)
255 {
256 if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
257 cutghost[i][j] = cutmax;
258 cutghost[j][i] = cutmax;
259
260 return cutmax;
261 }
262
263