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 #include "atom_vec_dpd_kokkos.h"
16 
17 #include "atom_kokkos.h"
18 #include "atom_masks.h"
19 #include "comm_kokkos.h"
20 #include "domain.h"
21 #include "error.h"
22 #include "fix.h"
23 #include "memory_kokkos.h"
24 #include "modify.h"
25 
26 using namespace LAMMPS_NS;
27 
28 /* ---------------------------------------------------------------------- */
29 
AtomVecDPDKokkos(LAMMPS * lmp)30 AtomVecDPDKokkos::AtomVecDPDKokkos(LAMMPS *lmp) : AtomVecKokkos(lmp)
31 {
32   molecular = Atom::ATOMIC;
33   mass_type = PER_TYPE;
34 
35   comm_x_only = comm_f_only = 0;
36   size_forward = 7;
37   size_reverse = 3;
38   size_border = 12;
39   size_velocity = 3;
40   size_data_atom = 6;
41   size_data_vel = 4;
42   xcol_data = 4;
43 
44   atom->rho_flag = 1;
45   atom->dpd_flag = 1;
46 
47   k_count = DAT::tdual_int_1d("atom::k_count",1);
48   atomKK = (AtomKokkos *) atom;
49   commKK = (CommKokkos *) comm;
50 
51   no_comm_vel_flag = 1;
52 }
53 
54 /* ----------------------------------------------------------------------
55    grow atom arrays
56    n = 0 grows arrays by DELTA
57    n > 0 allocates arrays to size n
58 ------------------------------------------------------------------------- */
59 
grow(int n)60 void AtomVecDPDKokkos::grow(int n)
61 {
62   auto DELTA = LMP_KOKKOS_AV_DELTA;
63   int step = MAX(DELTA,nmax*0.01);
64   if (n == 0) nmax += step;
65   else nmax = n;
66   atomKK->nmax = nmax;
67   if (nmax < 0 || nmax > MAXSMALLINT)
68     error->one(FLERR,"Per-processor system is too big");
69 
70   atomKK->sync(Device,ALL_MASK);
71   atomKK->modified(Device,ALL_MASK);
72 
73   memoryKK->grow_kokkos(atomKK->k_tag,atomKK->tag,nmax,"atom:tag");
74   memoryKK->grow_kokkos(atomKK->k_type,atomKK->type,nmax,"atom:type");
75   memoryKK->grow_kokkos(atomKK->k_mask,atomKK->mask,nmax,"atom:mask");
76   memoryKK->grow_kokkos(atomKK->k_image,atomKK->image,nmax,"atom:image");
77 
78   memoryKK->grow_kokkos(atomKK->k_x,atomKK->x,nmax,"atom:x");
79   memoryKK->grow_kokkos(atomKK->k_v,atomKK->v,nmax,"atom:v");
80   memoryKK->grow_kokkos(atomKK->k_f,atomKK->f,nmax,"atom:f");
81 
82 
83   memoryKK->grow_kokkos(atomKK->k_rho,atomKK->rho,nmax,"atom:rho");
84   memoryKK->grow_kokkos(atomKK->k_dpdTheta,atomKK->dpdTheta,nmax,"atom:dpdTheta");
85   memoryKK->grow_kokkos(atomKK->k_uCond,atomKK->uCond,nmax,"atom:uCond");
86   memoryKK->grow_kokkos(atomKK->k_uMech,atomKK->uMech,nmax,"atom:uMech");
87   memoryKK->grow_kokkos(atomKK->k_uChem,atomKK->uChem,nmax,"atom:uChem");
88   memoryKK->grow_kokkos(atomKK->k_uCG,atomKK->uCG,nmax,"atom:uCG");
89   memoryKK->grow_kokkos(atomKK->k_uCGnew,atomKK->uCGnew,nmax,"atom:uCGnew");
90   memoryKK->grow_kokkos(atomKK->k_duChem,atomKK->duChem,nmax,"atom:duChem");
91 
92   if (atom->nextra_grow)
93     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
94       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
95 
96   grow_pointers();
97   atomKK->sync(Host,ALL_MASK);
98 }
99 
100 /* ----------------------------------------------------------------------
101    reset local array ptrs
102 ------------------------------------------------------------------------- */
103 
grow_pointers()104 void AtomVecDPDKokkos::grow_pointers()
105 {
106   tag = atomKK->tag;
107   d_tag = atomKK->k_tag.d_view;
108   h_tag = atomKK->k_tag.h_view;
109 
110   type = atomKK->type;
111   d_type = atomKK->k_type.d_view;
112   h_type = atomKK->k_type.h_view;
113   mask = atomKK->mask;
114   d_mask = atomKK->k_mask.d_view;
115   h_mask = atomKK->k_mask.h_view;
116   image = atomKK->image;
117   d_image = atomKK->k_image.d_view;
118   h_image = atomKK->k_image.h_view;
119 
120   x = atomKK->x;
121   d_x = atomKK->k_x.d_view;
122   h_x = atomKK->k_x.h_view;
123   v = atomKK->v;
124   d_v = atomKK->k_v.d_view;
125   h_v = atomKK->k_v.h_view;
126   f = atomKK->f;
127   d_f = atomKK->k_f.d_view;
128   h_f = atomKK->k_f.h_view;
129 
130   rho = atomKK->rho;
131   d_rho = atomKK->k_rho.d_view;
132   h_rho = atomKK->k_rho.h_view;
133   dpdTheta = atomKK->dpdTheta;
134   d_dpdTheta = atomKK->k_dpdTheta.d_view;
135   h_dpdTheta = atomKK->k_dpdTheta.h_view;
136   uCond = atomKK->uCond;
137   d_uCond = atomKK->k_uCond.d_view;;
138   h_uCond = atomKK->k_uCond.h_view;
139   uMech = atomKK->uMech;
140   d_uMech = atomKK->k_uMech.d_view;;
141   h_uMech = atomKK->k_uMech.h_view;
142   uChem = atomKK->uChem;
143   d_uChem = atomKK->k_uChem.d_view;;
144   h_uChem = atomKK->k_uChem.h_view;
145   uCG = atomKK->uCG;
146   d_uCG = atomKK->k_uCG.d_view;;
147   h_uCG = atomKK->k_uCG.h_view;
148   uCGnew = atomKK->uCGnew;
149   d_uCGnew = atomKK->k_uCGnew.d_view;;
150   h_uCGnew = atomKK->k_uCGnew.h_view;
151   duChem = atomKK->duChem;
152   d_duChem = atomKK->k_duChem.d_view;;
153   h_duChem = atomKK->k_duChem.h_view;
154 }
155 
156 /* ----------------------------------------------------------------------
157    copy atom I info to atom J
158 ------------------------------------------------------------------------- */
159 
copy(int i,int j,int delflag)160 void AtomVecDPDKokkos::copy(int i, int j, int delflag)
161 {
162   atomKK->sync(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK |
163             MASK_MASK | IMAGE_MASK | DPDTHETA_MASK |
164             UCG_MASK | UCGNEW_MASK |
165             UCOND_MASK | UMECH_MASK | UCHEM_MASK | DVECTOR_MASK);
166 
167   h_tag[j] = h_tag[i];
168   h_type[j] = h_type[i];
169   mask[j] = mask[i];
170   h_image[j] = h_image[i];
171   h_x(j,0) = h_x(i,0);
172   h_x(j,1) = h_x(i,1);
173   h_x(j,2) = h_x(i,2);
174   h_v(j,0) = h_v(i,0);
175   h_v(j,1) = h_v(i,1);
176   h_v(j,2) = h_v(i,2);
177   h_dpdTheta[j] = h_dpdTheta[i];
178   h_uCond[j] = h_uCond[i];
179   h_uMech[j] = h_uMech[i];
180   h_uChem[j] = h_uChem[i];
181   h_uCG[j] = h_uCG[i];
182   h_uCGnew[j] = h_uCGnew[i];
183 
184   if (atom->nextra_grow)
185     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
186       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag);
187 
188   atomKK->modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK |
189                 MASK_MASK | IMAGE_MASK | DPDTHETA_MASK |
190                 UCG_MASK | UCGNEW_MASK |
191                 UCOND_MASK | UMECH_MASK | UCHEM_MASK | DVECTOR_MASK);
192 }
193 
194 /* ---------------------------------------------------------------------- */
195 
196 template<class DeviceType,int PBC_FLAG,int TRICLINIC>
197 struct AtomVecDPDKokkos_PackComm {
198   typedef DeviceType device_type;
199 
200   typename ArrayTypes<DeviceType>::t_x_array_randomread _x;
201   typename ArrayTypes<DeviceType>::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem;
202   typename ArrayTypes<DeviceType>::t_xfloat_2d_um _buf;
203   typename ArrayTypes<DeviceType>::t_int_2d_const _list;
204   const int _iswap;
205   X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz;
206   X_FLOAT _pbc[6];
207 
AtomVecDPDKokkos_PackCommAtomVecDPDKokkos_PackComm208   AtomVecDPDKokkos_PackComm(
209       const typename DAT::tdual_x_array &x,
210       const typename DAT::tdual_efloat_1d &dpdTheta,
211       const typename DAT::tdual_efloat_1d &uCond,
212       const typename DAT::tdual_efloat_1d &uMech,
213       const typename DAT::tdual_efloat_1d &uChem,
214       const typename DAT::tdual_xfloat_2d &buf,
215       const typename DAT::tdual_int_2d &list,
216       const int & iswap,
217       const X_FLOAT &xprd, const X_FLOAT &yprd, const X_FLOAT &zprd,
218       const X_FLOAT &xy, const X_FLOAT &xz, const X_FLOAT &yz, const int* const pbc):
219       _x(x.view<DeviceType>()),
220       _dpdTheta(dpdTheta.view<DeviceType>()),
221       _uCond(uCond.view<DeviceType>()),
222       _uMech(uMech.view<DeviceType>()),
223       _uChem(uChem.view<DeviceType>()),
224       _list(list.view<DeviceType>()),_iswap(iswap),
225       _xprd(xprd),_yprd(yprd),_zprd(zprd),
226       _xy(xy),_xz(xz),_yz(yz) {
227         const size_t maxsend = (buf.view<DeviceType>().extent(0)*buf.view<DeviceType>().extent(1))/3;
228         const size_t elements = 3;
229         buffer_view<DeviceType>(_buf,buf,maxsend,elements);
230         _pbc[0] = pbc[0]; _pbc[1] = pbc[1]; _pbc[2] = pbc[2];
231         _pbc[3] = pbc[3]; _pbc[4] = pbc[4]; _pbc[5] = pbc[5];
232   };
233 
234   KOKKOS_INLINE_FUNCTION
operator ()AtomVecDPDKokkos_PackComm235   void operator() (const int& i) const {
236       const int j = _list(_iswap,i);
237       if (PBC_FLAG == 0) {
238           _buf(i,0) = _x(j,0);
239           _buf(i,1) = _x(j,1);
240           _buf(i,2) = _x(j,2);
241       } else {
242         if (TRICLINIC == 0) {
243           _buf(i,0) = _x(j,0) + _pbc[0]*_xprd;
244           _buf(i,1) = _x(j,1) + _pbc[1]*_yprd;
245           _buf(i,2) = _x(j,2) + _pbc[2]*_zprd;
246         } else {
247           _buf(i,0) = _x(j,0) + _pbc[0]*_xprd + _pbc[5]*_xy + _pbc[4]*_xz;
248           _buf(i,1) = _x(j,1) + _pbc[1]*_yprd + _pbc[3]*_yz;
249           _buf(i,2) = _x(j,2) + _pbc[2]*_zprd;
250         }
251       }
252       _buf(i,3) = _dpdTheta(j);
253       _buf(i,4) = _uCond(j);
254       _buf(i,5) = _uMech(j);
255       _buf(i,6) = _uChem(j);
256   }
257 };
258 
259 /* ---------------------------------------------------------------------- */
260 
pack_comm_kokkos(const int & n,const DAT::tdual_int_2d & list,const int & iswap,const DAT::tdual_xfloat_2d & buf,const int & pbc_flag,const int * const pbc)261 int AtomVecDPDKokkos::pack_comm_kokkos(const int &n,
262                                           const DAT::tdual_int_2d &list,
263                                           const int & iswap,
264                                           const DAT::tdual_xfloat_2d &buf,
265                                           const int &pbc_flag,
266                                           const int* const pbc)
267 {
268   // Check whether to always run forward communication on the host
269   // Choose correct forward PackComm kernel
270 
271   if (commKK->forward_comm_on_host) {
272     atomKK->sync(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
273     if (pbc_flag) {
274       if (domain->triclinic) {
275         struct AtomVecDPDKokkos_PackComm<LMPHostType,1,1> f(atomKK->k_x,
276           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
277           buf,list,iswap,
278           domain->xprd,domain->yprd,domain->zprd,
279           domain->xy,domain->xz,domain->yz,pbc);
280         Kokkos::parallel_for(n,f);
281       } else {
282         struct AtomVecDPDKokkos_PackComm<LMPHostType,1,0> f(atomKK->k_x,
283           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
284           buf,list,iswap,
285           domain->xprd,domain->yprd,domain->zprd,
286           domain->xy,domain->xz,domain->yz,pbc);
287         Kokkos::parallel_for(n,f);
288       }
289     } else {
290       if (domain->triclinic) {
291         struct AtomVecDPDKokkos_PackComm<LMPHostType,0,1> f(atomKK->k_x,
292           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
293           buf,list,iswap,
294           domain->xprd,domain->yprd,domain->zprd,
295           domain->xy,domain->xz,domain->yz,pbc);
296         Kokkos::parallel_for(n,f);
297       } else {
298         struct AtomVecDPDKokkos_PackComm<LMPHostType,0,0> f(atomKK->k_x,
299           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
300           buf,list,iswap,
301           domain->xprd,domain->yprd,domain->zprd,
302           domain->xy,domain->xz,domain->yz,pbc);
303         Kokkos::parallel_for(n,f);
304       }
305     }
306   } else {
307     atomKK->sync(Device,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
308     if (pbc_flag) {
309       if (domain->triclinic) {
310         struct AtomVecDPDKokkos_PackComm<LMPDeviceType,1,1> f(atomKK->k_x,
311           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
312           buf,list,iswap,
313           domain->xprd,domain->yprd,domain->zprd,
314           domain->xy,domain->xz,domain->yz,pbc);
315         Kokkos::parallel_for(n,f);
316       } else {
317         struct AtomVecDPDKokkos_PackComm<LMPDeviceType,1,0> f(atomKK->k_x,
318           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
319           buf,list,iswap,
320           domain->xprd,domain->yprd,domain->zprd,
321           domain->xy,domain->xz,domain->yz,pbc);
322         Kokkos::parallel_for(n,f);
323       }
324     } else {
325       if (domain->triclinic) {
326         struct AtomVecDPDKokkos_PackComm<LMPDeviceType,0,1> f(atomKK->k_x,
327           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
328           buf,list,iswap,
329           domain->xprd,domain->yprd,domain->zprd,
330           domain->xy,domain->xz,domain->yz,pbc);
331         Kokkos::parallel_for(n,f);
332       } else {
333         struct AtomVecDPDKokkos_PackComm<LMPDeviceType,0,0> f(atomKK->k_x,
334           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
335           buf,list,iswap,
336           domain->xprd,domain->yprd,domain->zprd,
337           domain->xy,domain->xz,domain->yz,pbc);
338         Kokkos::parallel_for(n,f);
339       }
340     }
341   }
342 
343         return n*size_forward;
344 }
345 
346 /* ---------------------------------------------------------------------- */
347 
348 template<class DeviceType,int PBC_FLAG,int TRICLINIC>
349 struct AtomVecDPDKokkos_PackCommSelf {
350   typedef DeviceType device_type;
351 
352   typename ArrayTypes<DeviceType>::t_x_array_randomread _x;
353   typename ArrayTypes<DeviceType>::t_x_array _xw;
354   typename ArrayTypes<DeviceType>::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem;
355   int _nfirst;
356   typename ArrayTypes<DeviceType>::t_int_2d_const _list;
357   const int _iswap;
358   X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz;
359   X_FLOAT _pbc[6];
360 
AtomVecDPDKokkos_PackCommSelfAtomVecDPDKokkos_PackCommSelf361   AtomVecDPDKokkos_PackCommSelf(
362       const typename DAT::tdual_x_array &x,
363       const typename DAT::tdual_efloat_1d &dpdTheta,
364       const typename DAT::tdual_efloat_1d &uCond,
365       const typename DAT::tdual_efloat_1d &uMech,
366       const typename DAT::tdual_efloat_1d &uChem,
367       const int &nfirst,
368       const typename DAT::tdual_int_2d &list,
369       const int & iswap,
370       const X_FLOAT &xprd, const X_FLOAT &yprd, const X_FLOAT &zprd,
371       const X_FLOAT &xy, const X_FLOAT &xz, const X_FLOAT &yz, const int* const pbc):
372       _x(x.view<DeviceType>()),_xw(x.view<DeviceType>()),
373       _dpdTheta(dpdTheta.view<DeviceType>()),
374       _uCond(uCond.view<DeviceType>()),
375       _uMech(uMech.view<DeviceType>()),
376       _uChem(uChem.view<DeviceType>()),
377       _nfirst(nfirst),_list(list.view<DeviceType>()),_iswap(iswap),
378       _xprd(xprd),_yprd(yprd),_zprd(zprd),
379       _xy(xy),_xz(xz),_yz(yz) {
380         _pbc[0] = pbc[0]; _pbc[1] = pbc[1]; _pbc[2] = pbc[2];
381         _pbc[3] = pbc[3]; _pbc[4] = pbc[4]; _pbc[5] = pbc[5];
382   };
383 
384   KOKKOS_INLINE_FUNCTION
operator ()AtomVecDPDKokkos_PackCommSelf385   void operator() (const int& i) const {
386         const int j = _list(_iswap,i);
387       if (PBC_FLAG == 0) {
388           _xw(i+_nfirst,0) = _x(j,0);
389           _xw(i+_nfirst,1) = _x(j,1);
390           _xw(i+_nfirst,2) = _x(j,2);
391       } else {
392         if (TRICLINIC == 0) {
393           _xw(i+_nfirst,0) = _x(j,0) + _pbc[0]*_xprd;
394           _xw(i+_nfirst,1) = _x(j,1) + _pbc[1]*_yprd;
395           _xw(i+_nfirst,2) = _x(j,2) + _pbc[2]*_zprd;
396         } else {
397           _xw(i+_nfirst,0) = _x(j,0) + _pbc[0]*_xprd + _pbc[5]*_xy + _pbc[4]*_xz;
398           _xw(i+_nfirst,1) = _x(j,1) + _pbc[1]*_yprd + _pbc[3]*_yz;
399           _xw(i+_nfirst,2) = _x(j,2) + _pbc[2]*_zprd;
400         }
401       }
402       _dpdTheta(i+_nfirst) = _dpdTheta(j);
403       _uCond(i+_nfirst) = _uCond(j);
404       _uMech(i+_nfirst) = _uMech(j);
405       _uChem(i+_nfirst) = _uChem(j);
406   }
407 };
408 
409 /* ---------------------------------------------------------------------- */
410 
pack_comm_self(const int & n,const DAT::tdual_int_2d & list,const int & iswap,const int nfirst,const int & pbc_flag,const int * const pbc)411 int AtomVecDPDKokkos::pack_comm_self(const int &n, const DAT::tdual_int_2d &list, const int & iswap,
412                                                                                 const int nfirst, const int &pbc_flag, const int* const pbc) {
413   if (commKK->forward_comm_on_host) {
414     atomKK->sync(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
415     atomKK->modified(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
416     if (pbc_flag) {
417       if (domain->triclinic) {
418       struct AtomVecDPDKokkos_PackCommSelf<LMPHostType,1,1> f(atomKK->k_x,
419           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
420           nfirst,list,iswap,
421           domain->xprd,domain->yprd,domain->zprd,
422           domain->xy,domain->xz,domain->yz,pbc);
423       Kokkos::parallel_for(n,f);
424       } else {
425       struct AtomVecDPDKokkos_PackCommSelf<LMPHostType,1,0> f(atomKK->k_x,
426           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
427           nfirst,list,iswap,
428           domain->xprd,domain->yprd,domain->zprd,
429           domain->xy,domain->xz,domain->yz,pbc);
430       Kokkos::parallel_for(n,f);
431       }
432     } else {
433       if (domain->triclinic) {
434       struct AtomVecDPDKokkos_PackCommSelf<LMPHostType,0,1> f(atomKK->k_x,
435           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
436           nfirst,list,iswap,
437           domain->xprd,domain->yprd,domain->zprd,
438           domain->xy,domain->xz,domain->yz,pbc);
439       Kokkos::parallel_for(n,f);
440       } else {
441       struct AtomVecDPDKokkos_PackCommSelf<LMPHostType,0,0> f(atomKK->k_x,
442           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
443           nfirst,list,iswap,
444           domain->xprd,domain->yprd,domain->zprd,
445           domain->xy,domain->xz,domain->yz,pbc);
446       Kokkos::parallel_for(n,f);
447       }
448     }
449   } else {
450     atomKK->sync(Device,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
451     atomKK->modified(Device,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
452     if (pbc_flag) {
453       if (domain->triclinic) {
454       struct AtomVecDPDKokkos_PackCommSelf<LMPDeviceType,1,1> f(atomKK->k_x,
455           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
456           nfirst,list,iswap,
457           domain->xprd,domain->yprd,domain->zprd,
458           domain->xy,domain->xz,domain->yz,pbc);
459       Kokkos::parallel_for(n,f);
460       } else {
461       struct AtomVecDPDKokkos_PackCommSelf<LMPDeviceType,1,0> f(atomKK->k_x,
462           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
463           nfirst,list,iswap,
464           domain->xprd,domain->yprd,domain->zprd,
465           domain->xy,domain->xz,domain->yz,pbc);
466       Kokkos::parallel_for(n,f);
467       }
468     } else {
469       if (domain->triclinic) {
470       struct AtomVecDPDKokkos_PackCommSelf<LMPDeviceType,0,1> f(atomKK->k_x,
471           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
472           nfirst,list,iswap,
473           domain->xprd,domain->yprd,domain->zprd,
474           domain->xy,domain->xz,domain->yz,pbc);
475       Kokkos::parallel_for(n,f);
476       } else {
477       struct AtomVecDPDKokkos_PackCommSelf<LMPDeviceType,0,0> f(atomKK->k_x,
478           atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
479           nfirst,list,iswap,
480           domain->xprd,domain->yprd,domain->zprd,
481           domain->xy,domain->xz,domain->yz,pbc);
482       Kokkos::parallel_for(n,f);
483       }
484     }
485   }
486         return n*3;
487 }
488 
489 /* ---------------------------------------------------------------------- */
490 
491 template<class DeviceType>
492 struct AtomVecDPDKokkos_UnpackComm {
493   typedef DeviceType device_type;
494 
495   typename ArrayTypes<DeviceType>::t_x_array _x;
496   typename ArrayTypes<DeviceType>::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem;
497   typename ArrayTypes<DeviceType>::t_xfloat_2d_const _buf;
498   int _first;
499 
AtomVecDPDKokkos_UnpackCommAtomVecDPDKokkos_UnpackComm500   AtomVecDPDKokkos_UnpackComm(
501       const typename DAT::tdual_x_array &x,
502       const typename DAT::tdual_efloat_1d &dpdTheta,
503       const typename DAT::tdual_efloat_1d &uCond,
504       const typename DAT::tdual_efloat_1d &uMech,
505       const typename DAT::tdual_efloat_1d &uChem,
506       const typename DAT::tdual_xfloat_2d &buf,
507       const int& first):_x(x.view<DeviceType>()),
508                         _dpdTheta(dpdTheta.view<DeviceType>()),
509                         _uCond(uCond.view<DeviceType>()),
510                         _uMech(uMech.view<DeviceType>()),
511                         _uChem(uChem.view<DeviceType>()),
512                         _buf(buf.view<DeviceType>()),
513                         _first(first) {};
514 
515   KOKKOS_INLINE_FUNCTION
operator ()AtomVecDPDKokkos_UnpackComm516   void operator() (const int& i) const {
517       _x(i+_first,0) = _buf(i,0);
518       _x(i+_first,1) = _buf(i,1);
519       _x(i+_first,2) = _buf(i,2);
520       _dpdTheta(i+_first) = _buf(i,3);
521       _uCond(i+_first) = _buf(i,4);
522       _uMech(i+_first) = _buf(i,5);
523       _uChem(i+_first) = _buf(i,6);
524   }
525 };
526 
527 /* ---------------------------------------------------------------------- */
528 
unpack_comm_kokkos(const int & n,const int & first,const DAT::tdual_xfloat_2d & buf)529 void AtomVecDPDKokkos::unpack_comm_kokkos(const int &n, const int &first,
530     const DAT::tdual_xfloat_2d &buf) {
531   if (commKK->forward_comm_on_host) {
532     atomKK->sync(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
533     atomKK->modified(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
534     struct AtomVecDPDKokkos_UnpackComm<LMPHostType> f(atomKK->k_x,
535     atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
536     buf,first);
537     Kokkos::parallel_for(n,f);
538   } else {
539     atomKK->sync(Device,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
540     atomKK->modified(Device,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
541     struct AtomVecDPDKokkos_UnpackComm<LMPDeviceType> f(atomKK->k_x,
542     atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem,
543     buf,first);
544     Kokkos::parallel_for(n,f);
545   }
546 }
547 
548 /* ---------------------------------------------------------------------- */
549 
pack_comm(int n,int * list,double * buf,int pbc_flag,int * pbc)550 int AtomVecDPDKokkos::pack_comm(int n, int *list, double *buf,
551                              int pbc_flag, int *pbc)
552 {
553   int i,j,m;
554   double dx,dy,dz;
555 
556   atomKK->sync(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
557 
558   m = 0;
559   if (pbc_flag == 0) {
560     for (i = 0; i < n; i++) {
561       j = list[i];
562       buf[m++] = h_x(j,0);
563       buf[m++] = h_x(j,1);
564       buf[m++] = h_x(j,2);
565       buf[m++] = h_dpdTheta[j];
566       buf[m++] = h_uCond[j];
567       buf[m++] = h_uMech[j];
568       buf[m++] = h_uChem[j];
569     }
570   } else {
571     if (domain->triclinic == 0) {
572       dx = pbc[0]*domain->xprd;
573       dy = pbc[1]*domain->yprd;
574       dz = pbc[2]*domain->zprd;
575     } else {
576       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
577       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
578       dz = pbc[2]*domain->zprd;
579     }
580     for (i = 0; i < n; i++) {
581       j = list[i];
582       buf[m++] = h_x(j,0) + dx;
583       buf[m++] = h_x(j,1) + dy;
584       buf[m++] = h_x(j,2) + dz;
585       buf[m++] = h_dpdTheta[j];
586       buf[m++] = h_uCond[j];
587       buf[m++] = h_uMech[j];
588       buf[m++] = h_uChem[j];
589     }
590   }
591   return m;
592 }
593 
594 /* ---------------------------------------------------------------------- */
595 
pack_comm_vel(int n,int * list,double * buf,int pbc_flag,int * pbc)596 int AtomVecDPDKokkos::pack_comm_vel(int n, int *list, double *buf,
597                                  int pbc_flag, int *pbc)
598 {
599   int i,j,m;
600   double dx,dy,dz,dvx,dvy,dvz;
601 
602   atomKK->sync(Host,X_MASK|V_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
603 
604   m = 0;
605   if (pbc_flag == 0) {
606     for (i = 0; i < n; i++) {
607       j = list[i];
608       buf[m++] = h_x(j,0);
609       buf[m++] = h_x(j,1);
610       buf[m++] = h_x(j,2);
611       buf[m++] = h_v(j,0);
612       buf[m++] = h_v(j,1);
613       buf[m++] = h_v(j,2);
614       buf[m++] = h_dpdTheta[j];
615       buf[m++] = h_uCond[j];
616       buf[m++] = h_uMech[j];
617       buf[m++] = h_uChem[j];
618     }
619   } else {
620     if (domain->triclinic == 0) {
621       dx = pbc[0]*domain->xprd;
622       dy = pbc[1]*domain->yprd;
623       dz = pbc[2]*domain->zprd;
624     } else {
625       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
626       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
627       dz = pbc[2]*domain->zprd;
628     }
629     if (!deform_vremap) {
630       for (i = 0; i < n; i++) {
631         j = list[i];
632         buf[m++] = h_x(j,0) + dx;
633         buf[m++] = h_x(j,1) + dy;
634         buf[m++] = h_x(j,2) + dz;
635         buf[m++] = h_v(j,0);
636         buf[m++] = h_v(j,1);
637         buf[m++] = h_v(j,2);
638         buf[m++] = h_dpdTheta[j];
639         buf[m++] = h_uCond[j];
640         buf[m++] = h_uMech[j];
641         buf[m++] = h_uChem[j];
642       }
643     } else {
644       dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
645       dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
646       dvz = pbc[2]*h_rate[2];
647       for (i = 0; i < n; i++) {
648         j = list[i];
649         buf[m++] = h_x(j,0) + dx;
650         buf[m++] = h_x(j,1) + dy;
651         buf[m++] = h_x(j,2) + dz;
652         if (mask[i] & deform_groupbit) {
653           buf[m++] = h_v(j,0) + dvx;
654           buf[m++] = h_v(j,1) + dvy;
655           buf[m++] = h_v(j,2) + dvz;
656         } else {
657           buf[m++] = h_v(j,0);
658           buf[m++] = h_v(j,1);
659           buf[m++] = h_v(j,2);
660         }
661         buf[m++] = h_dpdTheta(j);
662         buf[m++] = h_uCond(j);
663         buf[m++] = h_uMech(j);
664         buf[m++] = h_uChem(j);
665       }
666     }
667   }
668   return m;
669 }
670 
671 /* ---------------------------------------------------------------------- */
672 
unpack_comm(int n,int first,double * buf)673 void AtomVecDPDKokkos::unpack_comm(int n, int first, double *buf)
674 {
675   int i,m,last;
676 
677   m = 0;
678   last = first + n;
679   for (i = first; i < last; i++) {
680     h_x(i,0) = buf[m++];
681     h_x(i,1) = buf[m++];
682     h_x(i,2) = buf[m++];
683     h_dpdTheta[i] = buf[m++];
684     h_uCond[i] = buf[m++];
685     h_uMech[i] = buf[m++];
686     h_uChem[i] = buf[m++];
687   }
688 
689   atomKK->modified(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
690 }
691 
692 /* ---------------------------------------------------------------------- */
693 
unpack_comm_vel(int n,int first,double * buf)694 void AtomVecDPDKokkos::unpack_comm_vel(int n, int first, double *buf)
695 {
696   int i,m,last;
697 
698   m = 0;
699   last = first + n;
700   for (i = first; i < last; i++) {
701     h_x(i,0) = buf[m++];
702     h_x(i,1) = buf[m++];
703     h_x(i,2) = buf[m++];
704     h_v(i,0) = buf[m++];
705     h_v(i,1) = buf[m++];
706     h_v(i,2) = buf[m++];
707     h_dpdTheta[i] = buf[m++];
708     h_uCond[i] = buf[m++];
709     h_uMech[i] = buf[m++];
710     h_uChem[i] = buf[m++];
711   }
712 
713   atomKK->modified(Host,X_MASK|V_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK);
714 }
715 
716 /* ---------------------------------------------------------------------- */
717 
pack_reverse(int n,int first,double * buf)718 int AtomVecDPDKokkos::pack_reverse(int n, int first, double *buf)
719 {
720   if (n > 0)
721     atomKK->sync(Host,F_MASK);
722 
723   int m = 0;
724   const int last = first + n;
725   for (int i = first; i < last; i++) {
726     buf[m++] = h_f(i,0);
727     buf[m++] = h_f(i,1);
728     buf[m++] = h_f(i,2);
729   }
730   return m;
731 }
732 
733 /* ---------------------------------------------------------------------- */
734 
unpack_reverse(int n,int * list,double * buf)735 void AtomVecDPDKokkos::unpack_reverse(int n, int *list, double *buf)
736 {
737   if (n > 0) {
738     atomKK->sync(Host,F_MASK);
739     atomKK->modified(Host,F_MASK);
740   }
741 
742   int m = 0;
743   for (int i = 0; i < n; i++) {
744     const int j = list[i];
745     h_f(j,0) += buf[m++];
746     h_f(j,1) += buf[m++];
747     h_f(j,2) += buf[m++];
748   }
749 }
750 
751 /* ---------------------------------------------------------------------- */
752 
753 template<class DeviceType,int PBC_FLAG>
754 struct AtomVecDPDKokkos_PackBorder {
755   typedef DeviceType device_type;
756 
757   typename ArrayTypes<DeviceType>::t_xfloat_2d _buf;
758   const typename ArrayTypes<DeviceType>::t_int_2d_const _list;
759   const int _iswap;
760   const typename ArrayTypes<DeviceType>::t_x_array_randomread _x;
761   const typename ArrayTypes<DeviceType>::t_tagint_1d _tag;
762   const typename ArrayTypes<DeviceType>::t_int_1d _type;
763   const typename ArrayTypes<DeviceType>::t_int_1d _mask;
764   typename ArrayTypes<DeviceType>::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew;
765   X_FLOAT _dx,_dy,_dz;
766 
AtomVecDPDKokkos_PackBorderAtomVecDPDKokkos_PackBorder767   AtomVecDPDKokkos_PackBorder(
768       const typename ArrayTypes<DeviceType>::t_xfloat_2d &buf,
769       const typename ArrayTypes<DeviceType>::t_int_2d_const &list,
770       const int & iswap,
771       const typename ArrayTypes<DeviceType>::t_x_array &x,
772       const typename ArrayTypes<DeviceType>::t_tagint_1d &tag,
773       const typename ArrayTypes<DeviceType>::t_int_1d &type,
774       const typename ArrayTypes<DeviceType>::t_int_1d &mask,
775       const typename ArrayTypes<DeviceType>::t_efloat_1d &dpdTheta,
776       const typename ArrayTypes<DeviceType>::t_efloat_1d &uCond,
777       const typename ArrayTypes<DeviceType>::t_efloat_1d &uMech,
778       const typename ArrayTypes<DeviceType>::t_efloat_1d &uChem,
779       const typename ArrayTypes<DeviceType>::t_efloat_1d &uCG,
780       const typename ArrayTypes<DeviceType>::t_efloat_1d &uCGnew,
781       const X_FLOAT &dx, const X_FLOAT &dy, const X_FLOAT &dz):
782       _buf(buf),_list(list),_iswap(iswap),
783       _x(x),_tag(tag),_type(type),_mask(mask),
784       _dpdTheta(dpdTheta),
785       _uCond(uCond),
786       _uMech(uMech),
787       _uChem(uChem),
788       _uCG(uCG),
789       _uCGnew(uCGnew),
790       _dx(dx),_dy(dy),_dz(dz) {}
791 
792   KOKKOS_INLINE_FUNCTION
operator ()AtomVecDPDKokkos_PackBorder793   void operator() (const int& i) const {
794       const int j = _list(_iswap,i);
795       if (PBC_FLAG == 0) {
796           _buf(i,0) = _x(j,0);
797           _buf(i,1) = _x(j,1);
798           _buf(i,2) = _x(j,2);
799       } else {
800           _buf(i,0) = _x(j,0) + _dx;
801           _buf(i,1) = _x(j,1) + _dy;
802           _buf(i,2) = _x(j,2) + _dz;
803       }
804       _buf(i,3) = _tag(j);
805       _buf(i,4) = _type(j);
806       _buf(i,5) = _mask(j);
807       _buf(i,6) = _dpdTheta(j);
808       _buf(i,7) = _uCond(j);
809       _buf(i,8) = _uMech(j);
810       _buf(i,9) = _uChem(j);
811       _buf(i,10) = _uCG(j);
812       _buf(i,11) = _uCGnew(j);
813   }
814 };
815 
816 /* ---------------------------------------------------------------------- */
817 
pack_border_kokkos(int n,DAT::tdual_int_2d k_sendlist,DAT::tdual_xfloat_2d buf,int iswap,int pbc_flag,int * pbc,ExecutionSpace space)818 int AtomVecDPDKokkos::pack_border_kokkos(int n, DAT::tdual_int_2d k_sendlist, DAT::tdual_xfloat_2d buf,int iswap,
819                                int pbc_flag, int *pbc, ExecutionSpace space)
820 {
821   X_FLOAT dx,dy,dz;
822 
823   atomKK->sync(space,ALL_MASK);
824 
825   if (pbc_flag != 0) {
826     if (domain->triclinic == 0) {
827       dx = pbc[0]*domain->xprd;
828       dy = pbc[1]*domain->yprd;
829       dz = pbc[2]*domain->zprd;
830     } else {
831       dx = pbc[0];
832       dy = pbc[1];
833       dz = pbc[2];
834     }
835     if (space==Host) {
836       AtomVecDPDKokkos_PackBorder<LMPHostType,1> f(
837         buf.view<LMPHostType>(), k_sendlist.view<LMPHostType>(),
838         iswap,h_x,h_tag,h_type,h_mask,
839         h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew,
840         dx,dy,dz);
841       Kokkos::parallel_for(n,f);
842     } else {
843       AtomVecDPDKokkos_PackBorder<LMPDeviceType,1> f(
844         buf.view<LMPDeviceType>(), k_sendlist.view<LMPDeviceType>(),
845         iswap,d_x,d_tag,d_type,d_mask,
846         d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew,
847         dx,dy,dz);
848       Kokkos::parallel_for(n,f);
849     }
850 
851   } else {
852     dx = dy = dz = 0;
853     if (space==Host) {
854       AtomVecDPDKokkos_PackBorder<LMPHostType,0> f(
855         buf.view<LMPHostType>(), k_sendlist.view<LMPHostType>(),
856         iswap,h_x,h_tag,h_type,h_mask,
857         h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew,
858         dx,dy,dz);
859       Kokkos::parallel_for(n,f);
860     } else {
861       AtomVecDPDKokkos_PackBorder<LMPDeviceType,0> f(
862         buf.view<LMPDeviceType>(), k_sendlist.view<LMPDeviceType>(),
863         iswap,d_x,d_tag,d_type,d_mask,
864         d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew,
865         dx,dy,dz);
866       Kokkos::parallel_for(n,f);
867     }
868   }
869   return n*6;
870 }
871 
872 /* ---------------------------------------------------------------------- */
873 
pack_border(int n,int * list,double * buf,int pbc_flag,int * pbc)874 int AtomVecDPDKokkos::pack_border(int n, int *list, double *buf,
875                                int pbc_flag, int *pbc)
876 {
877   int i,j,m;
878   double dx,dy,dz;
879 
880   atomKK->sync(Host,ALL_MASK);
881 
882   m = 0;
883   if (pbc_flag == 0) {
884     for (i = 0; i < n; i++) {
885       j = list[i];
886       buf[m++] = h_x(j,0);
887       buf[m++] = h_x(j,1);
888       buf[m++] = h_x(j,2);
889       buf[m++] = ubuf(h_tag(j)).d;
890       buf[m++] = ubuf(h_type(j)).d;
891       buf[m++] = ubuf(h_mask(j)).d;
892       buf[m++] = h_dpdTheta(j);
893       buf[m++] = h_uCond(j);
894       buf[m++] = h_uMech(j);
895       buf[m++] = h_uChem(j);
896       buf[m++] = h_uCG(j);
897       buf[m++] = h_uCGnew(j);
898     }
899   } else {
900     if (domain->triclinic == 0) {
901       dx = pbc[0]*domain->xprd;
902       dy = pbc[1]*domain->yprd;
903       dz = pbc[2]*domain->zprd;
904     } else {
905       dx = pbc[0];
906       dy = pbc[1];
907       dz = pbc[2];
908     }
909     for (i = 0; i < n; i++) {
910       j = list[i];
911       buf[m++] = h_x(j,0) + dx;
912       buf[m++] = h_x(j,1) + dy;
913       buf[m++] = h_x(j,2) + dz;
914       buf[m++] = ubuf(h_tag(j)).d;
915       buf[m++] = ubuf(h_type(j)).d;
916       buf[m++] = ubuf(h_mask(j)).d;
917       buf[m++] = h_dpdTheta(j);
918       buf[m++] = h_uCond(j);
919       buf[m++] = h_uMech(j);
920       buf[m++] = h_uChem(j);
921       buf[m++] = h_uCG(j);
922       buf[m++] = h_uCGnew(j);
923     }
924   }
925 
926   if (atom->nextra_border)
927     for (int iextra = 0; iextra < atom->nextra_border; iextra++)
928       m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]);
929 
930   return m;
931 }
932 
933 /* ---------------------------------------------------------------------- */
934 
pack_border_vel(int n,int * list,double * buf,int pbc_flag,int * pbc)935 int AtomVecDPDKokkos::pack_border_vel(int n, int *list, double *buf,
936                                    int pbc_flag, int *pbc)
937 {
938   int i,j,m;
939   double dx,dy,dz,dvx,dvy,dvz;
940 
941   atomKK->sync(Host,ALL_MASK);
942 
943   m = 0;
944   if (pbc_flag == 0) {
945     for (i = 0; i < n; i++) {
946       j = list[i];
947       buf[m++] = h_x(j,0);
948       buf[m++] = h_x(j,1);
949       buf[m++] = h_x(j,2);
950       buf[m++] = ubuf(h_tag(j)).d;
951       buf[m++] = ubuf(h_type(j)).d;
952       buf[m++] = ubuf(h_mask(j)).d;
953       buf[m++] = h_v(j,0);
954       buf[m++] = h_v(j,1);
955       buf[m++] = h_v(j,2);
956       buf[m++] = h_dpdTheta(j);
957       buf[m++] = h_uCond(j);
958       buf[m++] = h_uMech(j);
959       buf[m++] = h_uChem(j);
960       buf[m++] = h_uCG(j);
961       buf[m++] = h_uCGnew(j);
962     }
963   } else {
964     if (domain->triclinic == 0) {
965       dx = pbc[0]*domain->xprd;
966       dy = pbc[1]*domain->yprd;
967       dz = pbc[2]*domain->zprd;
968     } else {
969       dx = pbc[0];
970       dy = pbc[1];
971       dz = pbc[2];
972     }
973     if (!deform_vremap) {
974       for (i = 0; i < n; i++) {
975         j = list[i];
976         buf[m++] = h_x(j,0) + dx;
977         buf[m++] = h_x(j,1) + dy;
978         buf[m++] = h_x(j,2) + dz;
979         buf[m++] = ubuf(h_tag(j)).d;
980         buf[m++] = ubuf(h_type(j)).d;
981         buf[m++] = ubuf(h_mask(j)).d;
982         buf[m++] = h_v(j,0);
983         buf[m++] = h_v(j,1);
984         buf[m++] = h_v(j,2);
985         buf[m++] = h_dpdTheta(j);
986         buf[m++] = h_uCond(j);
987         buf[m++] = h_uMech(j);
988         buf[m++] = h_uChem(j);
989         buf[m++] = h_uCG(j);
990         buf[m++] = h_uCGnew(j);
991       }
992     } else {
993       dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
994       dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
995       dvz = pbc[2]*h_rate[2];
996       for (i = 0; i < n; i++) {
997         j = list[i];
998         buf[m++] = h_x(j,0) + dx;
999         buf[m++] = h_x(j,1) + dy;
1000         buf[m++] = h_x(j,2) + dz;
1001         buf[m++] = ubuf(h_tag(j)).d;
1002         buf[m++] = ubuf(h_type(j)).d;
1003         buf[m++] = ubuf(h_mask(j)).d;
1004         if (mask[i] & deform_groupbit) {
1005           buf[m++] = h_v(j,0) + dvx;
1006           buf[m++] = h_v(j,1) + dvy;
1007           buf[m++] = h_v(j,2) + dvz;
1008         } else {
1009           buf[m++] = h_v(j,0);
1010           buf[m++] = h_v(j,1);
1011           buf[m++] = h_v(j,2);
1012         }
1013         buf[m++] = h_dpdTheta(j);
1014         buf[m++] = h_uCond(j);
1015         buf[m++] = h_uMech(j);
1016         buf[m++] = h_uChem(j);
1017         buf[m++] = h_uCG(j);
1018         buf[m++] = h_uCGnew(j);
1019       }
1020     }
1021   }
1022 
1023   if (atom->nextra_border)
1024     for (int iextra = 0; iextra < atom->nextra_border; iextra++)
1025       m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]);
1026 
1027   return m;
1028 }
1029 
1030 /* ---------------------------------------------------------------------- */
1031 
pack_comm_hybrid(int n,int * list,double * buf)1032 int AtomVecDPDKokkos::pack_comm_hybrid(int n, int *list, double *buf)
1033 {
1034   int i,j,m;
1035 
1036   atomKK->sync(Host,DPDTHETA_MASK | UCOND_MASK |
1037             UMECH_MASK | UCHEM_MASK);
1038 
1039   m = 0;
1040   for (i = 0; i < n; i++) {
1041     j = list[i];
1042     buf[m++] = h_dpdTheta[j];
1043     buf[m++] = h_uCond[j];
1044     buf[m++] = h_uMech[j];
1045     buf[m++] = h_uChem[j];
1046   }
1047   return m;
1048 }
1049 
1050 /* ---------------------------------------------------------------------- */
1051 
pack_border_hybrid(int n,int * list,double * buf)1052 int AtomVecDPDKokkos::pack_border_hybrid(int n, int *list, double *buf)
1053 {
1054   int i,j,m;
1055 
1056   atomKK->sync(Host,DPDTHETA_MASK | UCOND_MASK |
1057             UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK);
1058 
1059   m = 0;
1060   for (i = 0; i < n; i++) {
1061     j = list[i];
1062     buf[m++] = h_dpdTheta[j];
1063     buf[m++] = h_uCond[j];
1064     buf[m++] = h_uMech[j];
1065     buf[m++] = h_uChem[j];
1066     buf[m++] = h_uCG[j];
1067     buf[m++] = h_uCGnew[j];
1068   }
1069   return m;
1070 }
1071 
1072 /* ---------------------------------------------------------------------- */
1073 
1074 template<class DeviceType>
1075 struct AtomVecDPDKokkos_UnpackBorder {
1076   typedef DeviceType device_type;
1077 
1078   const typename ArrayTypes<DeviceType>::t_xfloat_2d_const _buf;
1079   typename ArrayTypes<DeviceType>::t_x_array _x;
1080   typename ArrayTypes<DeviceType>::t_tagint_1d _tag;
1081   typename ArrayTypes<DeviceType>::t_int_1d _type;
1082   typename ArrayTypes<DeviceType>::t_int_1d _mask;
1083   typename ArrayTypes<DeviceType>::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew;
1084   int _first;
1085 
1086 
AtomVecDPDKokkos_UnpackBorderAtomVecDPDKokkos_UnpackBorder1087   AtomVecDPDKokkos_UnpackBorder(
1088       const typename ArrayTypes<DeviceType>::t_xfloat_2d_const &buf,
1089       typename ArrayTypes<DeviceType>::t_x_array &x,
1090       typename ArrayTypes<DeviceType>::t_tagint_1d &tag,
1091       typename ArrayTypes<DeviceType>::t_int_1d &type,
1092       typename ArrayTypes<DeviceType>::t_int_1d &mask,
1093       const typename ArrayTypes<DeviceType>::t_efloat_1d &dpdTheta,
1094       const typename ArrayTypes<DeviceType>::t_efloat_1d &uCond,
1095       const typename ArrayTypes<DeviceType>::t_efloat_1d &uMech,
1096       const typename ArrayTypes<DeviceType>::t_efloat_1d &uChem,
1097       const typename ArrayTypes<DeviceType>::t_efloat_1d &uCG,
1098       const typename ArrayTypes<DeviceType>::t_efloat_1d &uCGnew,
1099       const int& first):
1100       _buf(buf),_x(x),_tag(tag),_type(type),_mask(mask),
1101       _dpdTheta(dpdTheta),
1102       _uCond(uCond),
1103       _uMech(uMech),
1104       _uChem(uChem),
1105       _uCG(uCG),
1106       _uCGnew(uCGnew),
1107       _first(first) {};
1108 
1109   KOKKOS_INLINE_FUNCTION
operator ()AtomVecDPDKokkos_UnpackBorder1110   void operator() (const int& i) const {
1111       _x(i+_first,0) = _buf(i,0);
1112       _x(i+_first,1) = _buf(i,1);
1113       _x(i+_first,2) = _buf(i,2);
1114       _tag(i+_first) = static_cast<int> (_buf(i,3));
1115       _type(i+_first) = static_cast<int>  (_buf(i,4));
1116       _mask(i+_first) = static_cast<int>  (_buf(i,5));
1117       _dpdTheta(i+_first) = _buf(i,6);
1118       _uCond(i+_first) = _buf(i,7);
1119       _uMech(i+_first) = _buf(i,8);
1120       _uChem(i+_first) = _buf(i,9);
1121       _uCG(i+_first) = _buf(i,10);
1122       _uCGnew(i+_first) = _buf(i,11);
1123 //      printf("%i %i %lf %lf %lf %i BORDER\n",_tag(i+_first),i+_first,_x(i+_first,0),_x(i+_first,1),_x(i+_first,2),_type(i+_first));
1124   }
1125 };
1126 
1127 /* ---------------------------------------------------------------------- */
1128 
unpack_border_kokkos(const int & n,const int & first,const DAT::tdual_xfloat_2d & buf,ExecutionSpace space)1129 void AtomVecDPDKokkos::unpack_border_kokkos(const int &n, const int &first,
1130                      const DAT::tdual_xfloat_2d &buf,ExecutionSpace space) {
1131   atomKK->modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK|
1132                  DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK|
1133                  UCG_MASK|UCGNEW_MASK);
1134   while (first+n >= nmax) grow(0);
1135   atomKK->modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK|
1136                  DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK|
1137                  UCG_MASK|UCGNEW_MASK|DVECTOR_MASK);
1138   if (space==Host) {
1139     struct AtomVecDPDKokkos_UnpackBorder<LMPHostType> f(buf.view<LMPHostType>(),
1140       h_x,h_tag,h_type,h_mask,
1141       h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew,
1142       first);
1143     Kokkos::parallel_for(n,f);
1144   } else {
1145     struct AtomVecDPDKokkos_UnpackBorder<LMPDeviceType> f(buf.view<LMPDeviceType>(),
1146       d_x,d_tag,d_type,d_mask,
1147       d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew,
1148       first);
1149     Kokkos::parallel_for(n,f);
1150   }
1151 }
1152 
1153 /* ---------------------------------------------------------------------- */
1154 
unpack_border(int n,int first,double * buf)1155 void AtomVecDPDKokkos::unpack_border(int n, int first, double *buf)
1156 {
1157   int i,m,last;
1158 
1159   m = 0;
1160   last = first + n;
1161   while (last > nmax) grow(0);
1162 
1163   for (i = first; i < last; i++) {
1164     h_x(i,0) = buf[m++];
1165     h_x(i,1) = buf[m++];
1166     h_x(i,2) = buf[m++];
1167     h_tag(i) =  (tagint)  ubuf(buf[m++]).i;
1168     h_type(i) = (int) ubuf(buf[m++]).i;
1169     h_mask(i) = (int) ubuf(buf[m++]).i;
1170     h_dpdTheta(i) = buf[m++];
1171     h_uCond(i) = buf[m++];
1172     h_uMech(i) = buf[m++];
1173     h_uChem(i) = buf[m++];
1174     h_uCG(i) = buf[m++];
1175     h_uCGnew(i) = buf[m++];
1176   }
1177 
1178   if (atom->nextra_border)
1179     for (int iextra = 0; iextra < atom->nextra_border; iextra++)
1180       m += modify->fix[atom->extra_border[iextra]]->
1181         unpack_border(n,first,&buf[m]);
1182 
1183   atomKK->modified(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK|
1184                 DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK|
1185                 UCG_MASK|UCGNEW_MASK|DVECTOR_MASK);
1186 }
1187 
1188 /* ---------------------------------------------------------------------- */
1189 
unpack_border_vel(int n,int first,double * buf)1190 void AtomVecDPDKokkos::unpack_border_vel(int n, int first, double *buf)
1191 {
1192   int i,m,last;
1193 
1194   m = 0;
1195   last = first + n;
1196   while (last > nmax) grow(0);
1197 
1198   for (i = first; i < last; i++) {
1199     h_x(i,0) = buf[m++];
1200     h_x(i,1) = buf[m++];
1201     h_x(i,2) = buf[m++];
1202     h_tag(i) =  (tagint)  ubuf(buf[m++]).i;
1203     h_type(i) = (int) ubuf(buf[m++]).i;
1204     h_mask(i) = (int) ubuf(buf[m++]).i;
1205     h_v(i,0) = buf[m++];
1206     h_v(i,1) = buf[m++];
1207     h_v(i,2) = buf[m++];
1208     h_dpdTheta(i) = buf[m++];
1209     h_uCond(i) = buf[m++];
1210     h_uMech(i) = buf[m++];
1211     h_uChem(i) = buf[m++];
1212     h_uCG(i) = buf[m++];
1213     h_uCGnew(i) = buf[m++];
1214   }
1215 
1216   if (atom->nextra_border)
1217     for (int iextra = 0; iextra < atom->nextra_border; iextra++)
1218       m += modify->fix[atom->extra_border[iextra]]->
1219         unpack_border(n,first,&buf[m]);
1220 
1221   atomKK->modified(Host,X_MASK|V_MASK|TAG_MASK|TYPE_MASK|MASK_MASK|
1222                 DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK|
1223                 UCG_MASK|UCGNEW_MASK|DVECTOR_MASK);
1224 }
1225 
1226 /* ---------------------------------------------------------------------- */
1227 
unpack_comm_hybrid(int n,int first,double * buf)1228 int AtomVecDPDKokkos::unpack_comm_hybrid(int n, int first, double *buf)
1229 {
1230   int i,m,last;
1231 
1232   m = 0;
1233   last = first + n;
1234   for (i = first; i < last; i++) {
1235     h_dpdTheta(i) = buf[m++];
1236     h_uCond(i) = buf[m++];
1237     h_uMech(i) = buf[m++];
1238     h_uChem(i) = buf[m++];
1239   }
1240 
1241   atomKK->modified(Host,DPDTHETA_MASK | UCOND_MASK |
1242                 UMECH_MASK | UCHEM_MASK );
1243 
1244   return m;
1245 }
1246 
1247 /* ---------------------------------------------------------------------- */
1248 
unpack_border_hybrid(int n,int first,double * buf)1249 int AtomVecDPDKokkos::unpack_border_hybrid(int n, int first, double *buf)
1250 {
1251   int i,m,last;
1252 
1253   m = 0;
1254   last = first + n;
1255   for (i = first; i < last; i++) {
1256     h_dpdTheta(i) = buf[m++];
1257     h_uCond(i) = buf[m++];
1258     h_uMech(i) = buf[m++];
1259     h_uChem(i) = buf[m++];
1260     h_uCG(i) = buf[m++];
1261     h_uCGnew(i) = buf[m++];
1262   }
1263 
1264   atomKK->modified(Host,DPDTHETA_MASK | UCOND_MASK |
1265                 UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK);
1266 
1267   return m;
1268 }
1269 
1270 /* ---------------------------------------------------------------------- */
1271 
1272 template<class DeviceType>
1273 struct AtomVecDPDKokkos_PackExchangeFunctor {
1274   typedef DeviceType device_type;
1275   typedef ArrayTypes<DeviceType> AT;
1276   typename AT::t_x_array_randomread _x;
1277   typename AT::t_v_array_randomread _v;
1278   typename AT::t_tagint_1d_randomread _tag;
1279   typename AT::t_int_1d_randomread _type;
1280   typename AT::t_int_1d_randomread _mask;
1281   typename AT::t_imageint_1d_randomread _image;
1282   typename AT::t_efloat_1d_randomread _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew;
1283   typename AT::t_x_array _xw;
1284   typename AT::t_v_array _vw;
1285   typename AT::t_tagint_1d _tagw;
1286   typename AT::t_int_1d _typew;
1287   typename AT::t_int_1d _maskw;
1288   typename AT::t_imageint_1d _imagew;
1289   typename AT::t_efloat_1d _dpdThetaw,_uCondw,_uMechw,_uChemw,_uCGw,_uCGneww;
1290 
1291   typename AT::t_xfloat_2d_um _buf;
1292   typename AT::t_int_1d_const _sendlist;
1293   typename AT::t_int_1d_const _copylist;
1294   int _nlocal,_dim;
1295   X_FLOAT _lo,_hi;
1296 
AtomVecDPDKokkos_PackExchangeFunctorAtomVecDPDKokkos_PackExchangeFunctor1297   AtomVecDPDKokkos_PackExchangeFunctor(
1298       const AtomKokkos* atom,
1299       const typename AT::tdual_xfloat_2d buf,
1300       typename AT::tdual_int_1d sendlist,
1301       typename AT::tdual_int_1d copylist,int nlocal, int dim,
1302                 X_FLOAT lo, X_FLOAT hi):
1303                 _x(atom->k_x.view<DeviceType>()),
1304                 _v(atom->k_v.view<DeviceType>()),
1305                 _tag(atom->k_tag.view<DeviceType>()),
1306                 _type(atom->k_type.view<DeviceType>()),
1307                 _mask(atom->k_mask.view<DeviceType>()),
1308                 _image(atom->k_image.view<DeviceType>()),
1309                 _dpdTheta(atom->k_dpdTheta.view<DeviceType>()),
1310                 _uCond(atom->k_uCond.view<DeviceType>()),
1311                 _uMech(atom->k_uMech.view<DeviceType>()),
1312                 _uChem(atom->k_uChem.view<DeviceType>()),
1313                 _uCG(atom->k_uCG.view<DeviceType>()),
1314                 _uCGnew(atom->k_uCGnew.view<DeviceType>()),
1315                 _xw(atom->k_x.view<DeviceType>()),
1316                 _vw(atom->k_v.view<DeviceType>()),
1317                 _tagw(atom->k_tag.view<DeviceType>()),
1318                 _typew(atom->k_type.view<DeviceType>()),
1319                 _maskw(atom->k_mask.view<DeviceType>()),
1320                 _imagew(atom->k_image.view<DeviceType>()),
1321                 _dpdThetaw(atom->k_dpdTheta.view<DeviceType>()),
1322                 _uCondw(atom->k_uCond.view<DeviceType>()),
1323                 _uMechw(atom->k_uMech.view<DeviceType>()),
1324                 _uChemw(atom->k_uChem.view<DeviceType>()),
1325                 _uCGw(atom->k_uCG.view<DeviceType>()),
1326                 _uCGneww(atom->k_uCGnew.view<DeviceType>()),
1327                 _sendlist(sendlist.template view<DeviceType>()),
1328                 _copylist(copylist.template view<DeviceType>()),
1329                 _nlocal(nlocal),_dim(dim),
1330                 _lo(lo),_hi(hi) {
1331     const size_t elements = 17;
1332     const int maxsendlist = (buf.template view<DeviceType>().extent(0)*buf.template view<DeviceType>().extent(1))/elements;
1333 
1334     buffer_view<DeviceType>(_buf,buf,maxsendlist,elements);
1335   }
1336 
1337   KOKKOS_INLINE_FUNCTION
operator ()AtomVecDPDKokkos_PackExchangeFunctor1338   void operator() (const int &mysend) const {
1339     const int i = _sendlist(mysend);
1340     _buf(mysend,0) = 17;
1341     _buf(mysend,1) = _x(i,0);
1342     _buf(mysend,2) = _x(i,1);
1343     _buf(mysend,3) = _x(i,2);
1344     _buf(mysend,4) = _v(i,0);
1345     _buf(mysend,5) = _v(i,1);
1346     _buf(mysend,6) = _v(i,2);
1347     _buf(mysend,7) = _tag[i];
1348     _buf(mysend,8) = _type[i];
1349     _buf(mysend,9) = _mask[i];
1350     _buf(mysend,10) = _image[i];
1351     _buf(mysend,11) = _dpdTheta[i];
1352     _buf(mysend,12) = _uCond[i];
1353     _buf(mysend,13) = _uMech[i];
1354     _buf(mysend,14) = _uChem[i];
1355     _buf(mysend,15) = _uCG[i];
1356     _buf(mysend,16) = _uCGnew[i];
1357     const int j = _copylist(mysend);
1358 
1359     if (j>-1) {
1360     _xw(i,0) = _x(j,0);
1361     _xw(i,1) = _x(j,1);
1362     _xw(i,2) = _x(j,2);
1363     _vw(i,0) = _v(j,0);
1364     _vw(i,1) = _v(j,1);
1365     _vw(i,2) = _v(j,2);
1366     _tagw[i] = _tag(j);
1367     _typew[i] = _type(j);
1368     _maskw[i] = _mask(j);
1369     _imagew[i] = _image(j);
1370     _dpdThetaw[i] = _dpdTheta(j);
1371     _uCondw[i] = _uCond(j);
1372     _uMechw[i] = _uMech(j);
1373     _uChemw[i] = _uChem(j);
1374     _uCGw[i] = _uCG(j);
1375     _uCGneww[i] = _uCGnew(j);
1376     }
1377   }
1378 };
1379 
1380 /* ---------------------------------------------------------------------- */
1381 
pack_exchange_kokkos(const int & nsend,DAT::tdual_xfloat_2d & k_buf,DAT::tdual_int_1d k_sendlist,DAT::tdual_int_1d k_copylist,ExecutionSpace space,int dim,X_FLOAT lo,X_FLOAT hi)1382 int AtomVecDPDKokkos::pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d &k_buf, DAT::tdual_int_1d k_sendlist,DAT::tdual_int_1d k_copylist,ExecutionSpace space,int dim,X_FLOAT lo,X_FLOAT hi )
1383 {
1384   if (nsend > (int) (k_buf.view<LMPHostType>().extent(0)*k_buf.view<LMPHostType>().extent(1))/17) {
1385     int newsize = nsend*17/k_buf.view<LMPHostType>().extent(1)+1;
1386     k_buf.resize(newsize,k_buf.view<LMPHostType>().extent(1));
1387   }
1388   atomKK->sync(space,X_MASK | V_MASK | TAG_MASK | TYPE_MASK |
1389              MASK_MASK | IMAGE_MASK| DPDTHETA_MASK | UCOND_MASK |
1390              UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK |
1391              DVECTOR_MASK);
1392   if (space == Host) {
1393     AtomVecDPDKokkos_PackExchangeFunctor<LMPHostType> f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi);
1394     Kokkos::parallel_for(nsend,f);
1395   } else {
1396     AtomVecDPDKokkos_PackExchangeFunctor<LMPDeviceType> f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi);
1397     Kokkos::parallel_for(nsend,f);
1398   }
1399   return nsend*17;
1400 }
1401 
1402 /* ---------------------------------------------------------------------- */
1403 
pack_exchange(int i,double * buf)1404 int AtomVecDPDKokkos::pack_exchange(int i, double *buf)
1405 {
1406   atomKK->sync(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK |
1407             MASK_MASK | IMAGE_MASK| DPDTHETA_MASK | UCOND_MASK |
1408             UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK |
1409             DVECTOR_MASK);
1410 
1411   int m = 1;
1412   buf[m++] = h_x(i,0);
1413   buf[m++] = h_x(i,1);
1414   buf[m++] = h_x(i,2);
1415   buf[m++] = h_v(i,0);
1416   buf[m++] = h_v(i,1);
1417   buf[m++] = h_v(i,2);
1418   buf[m++] = ubuf(h_tag(i)).d;
1419   buf[m++] = ubuf(h_type(i)).d;
1420   buf[m++] = ubuf(h_mask(i)).d;
1421   buf[m++] = ubuf(h_image(i)).d;
1422   buf[m++] = h_dpdTheta[i];
1423   buf[m++] = h_uCond[i];
1424   buf[m++] = h_uMech[i];
1425   buf[m++] = h_uChem[i];
1426   buf[m++] = h_uCG[i];
1427   buf[m++] = h_uCGnew[i];
1428 
1429   if (atom->nextra_grow)
1430     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
1431       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
1432 
1433   buf[0] = m;
1434   return m;
1435 }
1436 
1437 /* ---------------------------------------------------------------------- */
1438 
1439 template<class DeviceType>
1440 struct AtomVecDPDKokkos_UnpackExchangeFunctor {
1441   typedef DeviceType device_type;
1442   typedef ArrayTypes<DeviceType> AT;
1443   typename AT::t_x_array _x;
1444   typename AT::t_v_array _v;
1445   typename AT::t_tagint_1d _tag;
1446   typename AT::t_int_1d _type;
1447   typename AT::t_int_1d _mask;
1448   typename AT::t_imageint_1d _image;
1449   typename AT::t_efloat_1d _dpdTheta;
1450   typename AT::t_efloat_1d _uCond;
1451   typename AT::t_efloat_1d _uMech;
1452   typename AT::t_efloat_1d _uChem;
1453   typename AT::t_efloat_1d _uCG;
1454   typename AT::t_efloat_1d _uCGnew;
1455 
1456   typename AT::t_xfloat_2d_um _buf;
1457   typename AT::t_int_1d _nlocal;
1458   int _dim;
1459   X_FLOAT _lo,_hi;
1460 
AtomVecDPDKokkos_UnpackExchangeFunctorAtomVecDPDKokkos_UnpackExchangeFunctor1461   AtomVecDPDKokkos_UnpackExchangeFunctor(
1462       const AtomKokkos* atom,
1463       const typename AT::tdual_xfloat_2d buf,
1464       typename AT::tdual_int_1d nlocal,
1465       int dim, X_FLOAT lo, X_FLOAT hi):
1466                 _x(atom->k_x.view<DeviceType>()),
1467                 _v(atom->k_v.view<DeviceType>()),
1468                 _tag(atom->k_tag.view<DeviceType>()),
1469                 _type(atom->k_type.view<DeviceType>()),
1470                 _mask(atom->k_mask.view<DeviceType>()),
1471                 _image(atom->k_image.view<DeviceType>()),
1472                 _nlocal(nlocal.template view<DeviceType>()),_dim(dim),
1473                 _lo(lo),_hi(hi) {
1474     const size_t elements = 17;
1475     const int maxsendlist = (buf.template view<DeviceType>().extent(0)*buf.template view<DeviceType>().extent(1))/elements;
1476 
1477     buffer_view<DeviceType>(_buf,buf,maxsendlist,elements);
1478   }
1479 
1480   KOKKOS_INLINE_FUNCTION
operator ()AtomVecDPDKokkos_UnpackExchangeFunctor1481   void operator() (const int &myrecv) const {
1482     X_FLOAT x = _buf(myrecv,_dim+1);
1483     if (x >= _lo && x < _hi) {
1484       int i = Kokkos::atomic_fetch_add(&_nlocal(0),1);
1485       _x(i,0) = _buf(myrecv,1);
1486       _x(i,1) = _buf(myrecv,2);
1487       _x(i,2) = _buf(myrecv,3);
1488       _v(i,0) = _buf(myrecv,4);
1489       _v(i,1) = _buf(myrecv,5);
1490       _v(i,2) = _buf(myrecv,6);
1491       _tag[i] = _buf(myrecv,7);
1492       _type[i] = _buf(myrecv,8);
1493       _mask[i] = _buf(myrecv,9);
1494       _image[i] = _buf(myrecv,10);
1495       _dpdTheta[i] = _buf(myrecv,11);
1496       _uCond[i] = _buf(myrecv,12);
1497       _uMech[i] = _buf(myrecv,13);
1498       _uChem[i] = _buf(myrecv,14);
1499       _uCG[i] = _buf(myrecv,15);
1500       _uCGnew[i] = _buf(myrecv,16);
1501     }
1502   }
1503 };
1504 
1505 /* ---------------------------------------------------------------------- */
1506 
unpack_exchange_kokkos(DAT::tdual_xfloat_2d & k_buf,int nrecv,int nlocal,int dim,X_FLOAT lo,X_FLOAT hi,ExecutionSpace space)1507 int AtomVecDPDKokkos::unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,int nrecv,int nlocal,int dim,X_FLOAT lo,X_FLOAT hi,ExecutionSpace space) {
1508   if (space == Host) {
1509     k_count.h_view(0) = nlocal;
1510     AtomVecDPDKokkos_UnpackExchangeFunctor<LMPHostType> f(atomKK,k_buf,k_count,dim,lo,hi);
1511     Kokkos::parallel_for(nrecv/17,f);
1512   } else {
1513     k_count.h_view(0) = nlocal;
1514     k_count.modify<LMPHostType>();
1515     k_count.sync<LMPDeviceType>();
1516     AtomVecDPDKokkos_UnpackExchangeFunctor<LMPDeviceType> f(atomKK,k_buf,k_count,dim,lo,hi);
1517     Kokkos::parallel_for(nrecv/17,f);
1518     k_count.modify<LMPDeviceType>();
1519     k_count.sync<LMPHostType>();
1520   }
1521 
1522   atomKK->modified(space,X_MASK | V_MASK | TAG_MASK | TYPE_MASK |
1523                  MASK_MASK | IMAGE_MASK| DPDTHETA_MASK | UCOND_MASK |
1524                  UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK |
1525                  DVECTOR_MASK);
1526 
1527   return k_count.h_view(0);
1528 }
1529 
1530 /* ---------------------------------------------------------------------- */
1531 
unpack_exchange(double * buf)1532 int AtomVecDPDKokkos::unpack_exchange(double *buf)
1533 {
1534   int nlocal = atom->nlocal;
1535   if (nlocal == nmax) grow(0);
1536 
1537   int m = 1;
1538   h_x(nlocal,0) = buf[m++];
1539   h_x(nlocal,1) = buf[m++];
1540   h_x(nlocal,2) = buf[m++];
1541   h_v(nlocal,0) = buf[m++];
1542   h_v(nlocal,1) = buf[m++];
1543   h_v(nlocal,2) = buf[m++];
1544   h_tag(nlocal) = (tagint) ubuf(buf[m++]).i;
1545   h_type(nlocal) = (int) ubuf(buf[m++]).i;
1546   h_mask(nlocal) = (int) ubuf(buf[m++]).i;
1547   h_image(nlocal) = (imageint) ubuf(buf[m++]).i;
1548   h_dpdTheta[nlocal] = buf[m++];
1549   h_uCond[nlocal] = buf[m++];
1550   h_uMech[nlocal] = buf[m++];
1551   h_uChem[nlocal] = buf[m++];
1552   h_uCG[nlocal] = buf[m++];
1553   h_uCGnew[nlocal] = buf[m++];
1554 
1555   if (atom->nextra_grow)
1556     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
1557       m += modify->fix[atom->extra_grow[iextra]]->
1558         unpack_exchange(nlocal,&buf[m]);
1559 
1560   atomKK->modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK |
1561            MASK_MASK | IMAGE_MASK| DPDTHETA_MASK | UCOND_MASK |
1562            UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK |
1563            DVECTOR_MASK);
1564 
1565   atom->nlocal++;
1566   return m;
1567 }
1568 
1569 /* ----------------------------------------------------------------------
1570    size of restart data for all atoms owned by this proc
1571    include extra data stored by fixes
1572 ------------------------------------------------------------------------- */
1573 
size_restart()1574 int AtomVecDPDKokkos::size_restart()
1575 {
1576   int i;
1577 
1578   int nlocal = atom->nlocal;
1579   int n = 15 * nlocal; // 11 + dpdTheta + uCond + uMech + uChem
1580 
1581   if (atom->nextra_restart)
1582     for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
1583       for (i = 0; i < nlocal; i++)
1584         n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
1585 
1586   return n;
1587 }
1588 
1589 /* ----------------------------------------------------------------------
1590    pack atom I's data for restart file including extra quantities
1591    xyz must be 1st 3 values, so that read_restart can test on them
1592    molecular types may be negative, but write as positive
1593 ------------------------------------------------------------------------- */
1594 
pack_restart(int i,double * buf)1595 int AtomVecDPDKokkos::pack_restart(int i, double *buf)
1596 {
1597   atomKK->sync(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK |
1598             MASK_MASK | IMAGE_MASK | DPDTHETA_MASK |
1599             UCOND_MASK | UMECH_MASK | UCHEM_MASK | DVECTOR_MASK);
1600 
1601   int m = 1;
1602   buf[m++] = h_x(i,0);
1603   buf[m++] = h_x(i,1);
1604   buf[m++] = h_x(i,2);
1605   buf[m++] = ubuf(h_tag(i)).d;
1606   buf[m++] = ubuf(h_type(i)).d;
1607   buf[m++] = ubuf(h_mask(i)).d;
1608   buf[m++] = ubuf(h_image(i)).d;
1609   buf[m++] = h_v(i,0);
1610   buf[m++] = h_v(i,1);
1611   buf[m++] = h_v(i,2);
1612   buf[m++] = h_dpdTheta[i];
1613   buf[m++] = h_uCond[i];
1614   buf[m++] = h_uMech[i];
1615   buf[m++] = h_uChem[i];
1616 
1617   if (atom->nextra_restart)
1618     for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
1619       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
1620 
1621   buf[0] = m;
1622   return m;
1623 }
1624 
1625 /* ----------------------------------------------------------------------
1626    unpack data for one atom from restart file including extra quantities
1627 ------------------------------------------------------------------------- */
1628 
unpack_restart(double * buf)1629 int AtomVecDPDKokkos::unpack_restart(double *buf)
1630 {
1631   int nlocal = atom->nlocal;
1632   if (nlocal == nmax) {
1633     grow(0);
1634     if (atom->nextra_store)
1635       memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra");
1636   }
1637 
1638   int m = 1;
1639   h_x(nlocal,0) = buf[m++];
1640   h_x(nlocal,1) = buf[m++];
1641   h_x(nlocal,2) = buf[m++];
1642   h_tag(nlocal) = (tagint) ubuf(buf[m++]).i;
1643   h_type(nlocal) = (int) ubuf(buf[m++]).i;
1644   h_mask(nlocal) = (int) ubuf(buf[m++]).i;
1645   h_image(nlocal) = (imageint) ubuf(buf[m++]).i;
1646   h_v(nlocal,0) = buf[m++];
1647   h_v(nlocal,1) = buf[m++];
1648   h_v(nlocal,2) = buf[m++];
1649   h_dpdTheta[nlocal] = buf[m++];
1650   h_uCond[nlocal] = buf[m++];
1651   h_uMech[nlocal] = buf[m++];
1652   h_uChem[nlocal] = buf[m++];
1653   h_uCG[nlocal] = 0.0;
1654   h_uCGnew[nlocal] = 0.0;
1655 
1656   double **extra = atom->extra;
1657   if (atom->nextra_store) {
1658     int size = static_cast<int> (buf[0]) - m;
1659     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
1660   }
1661 
1662   atomKK->modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK |
1663                 MASK_MASK | IMAGE_MASK | DPDTHETA_MASK |
1664                 UCG_MASK | UCGNEW_MASK |
1665                 UCOND_MASK | UMECH_MASK | UCHEM_MASK | DVECTOR_MASK);
1666 
1667   atom->nlocal++;
1668   return m;
1669 }
1670 
1671 /* ----------------------------------------------------------------------
1672    create one atom of itype at coord
1673    set other values to defaults
1674 ------------------------------------------------------------------------- */
1675 
create_atom(int itype,double * coord)1676 void AtomVecDPDKokkos::create_atom(int itype, double *coord)
1677 {
1678   int nlocal = atom->nlocal;
1679   if (nlocal == nmax) {
1680     //if(nlocal>2) printf("typeA: %i %i\n",type[0],type[1]);
1681     atomKK->modified(Host,ALL_MASK);
1682     grow(0);
1683     //if(nlocal>2) printf("typeB: %i %i\n",type[0],type[1]);
1684   }
1685   atomKK->modified(Host,ALL_MASK);
1686 
1687   tag[nlocal] = 0;
1688   type[nlocal] = itype;
1689   h_x(nlocal,0) = coord[0];
1690   h_x(nlocal,1) = coord[1];
1691   h_x(nlocal,2) = coord[2];
1692   h_mask[nlocal] = 1;
1693   h_image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
1694     ((tagint) IMGMAX << IMGBITS) | IMGMAX;
1695   h_v(nlocal,0) = 0.0;
1696   h_v(nlocal,1) = 0.0;
1697   h_v(nlocal,2) = 0.0;
1698   h_rho[nlocal] = 0.0;
1699   h_dpdTheta[nlocal] = 0.0;
1700   h_uCond[nlocal] = 0.0;
1701   h_uMech[nlocal] = 0.0;
1702   h_uChem[nlocal] = 0.0;
1703   h_uCG[nlocal] = 0.0;
1704   h_uCGnew[nlocal] = 0.0;
1705   h_duChem[nlocal] = 0.0;
1706 
1707   //atomKK->modified(Host,TAG_MASK|TYPE_MASK|DPDTHETA_MASK|X_MASK|IMAGE_MASK|
1708   //                      MASK_MASK|V_MASK|DPDRHO_MASK|UCOND_MASK|UMECH_MASK|
1709   //                      UCHEM_MASK|UCG_MASK|UCGNEW_MASK);
1710 
1711   atom->nlocal++;
1712 }
1713 
1714 /* ----------------------------------------------------------------------
1715    unpack one line from Atoms section of data file
1716    initialize other atom quantities
1717 ------------------------------------------------------------------------- */
1718 
data_atom(double * coord,tagint imagetmp,char ** values)1719 void AtomVecDPDKokkos::data_atom(double *coord, tagint imagetmp,
1720                                     char **values)
1721 {
1722   int nlocal = atom->nlocal;
1723   if (nlocal == nmax) grow(0);
1724 
1725   h_tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp);
1726   h_type[nlocal] = utils::inumeric(FLERR,values[1],true,lmp);
1727   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
1728     error->one(FLERR,"Invalid atom type in Atoms section of data file");
1729 
1730   h_dpdTheta[nlocal] = utils::numeric(FLERR,values[2],true,lmp);
1731   if (h_dpdTheta[nlocal] <= 0)
1732     error->one(FLERR,"Internal temperature in Atoms section of date file must be > zero");
1733 
1734   h_x(nlocal,0) = coord[0];
1735   h_x(nlocal,1) = coord[1];
1736   h_x(nlocal,2) = coord[2];
1737 
1738   h_image[nlocal] = imagetmp;
1739 
1740   h_mask[nlocal] = 1;
1741   h_v(nlocal,0) = 0.0;
1742   h_v(nlocal,1) = 0.0;
1743   h_v(nlocal,2) = 0.0;
1744 
1745   h_rho[nlocal] = 0.0;
1746   h_uCond[nlocal] = 0.0;
1747   h_uMech[nlocal] = 0.0;
1748   h_uChem[nlocal] = 0.0;
1749   h_uCG[nlocal] = 0.0;
1750   h_uCGnew[nlocal] = 0.0;
1751 
1752   atomKK->modified(Host,ALL_MASK);
1753 
1754   atom->nlocal++;
1755 }
1756 
1757 /* ----------------------------------------------------------------------
1758    unpack hybrid quantities from one line in Atoms section of data file
1759    initialize other atom quantities for this sub-style
1760 ------------------------------------------------------------------------- */
1761 
data_atom_hybrid(int nlocal,char ** values)1762 int AtomVecDPDKokkos::data_atom_hybrid(int nlocal, char **values)
1763 {
1764   h_dpdTheta(nlocal) = utils::numeric(FLERR,values[0],true,lmp);
1765 
1766   atomKK->modified(Host,DPDTHETA_MASK);
1767 
1768   return 1;
1769 }
1770 
1771 /* ----------------------------------------------------------------------
1772    pack atom info for data file including 3 image flags
1773 ------------------------------------------------------------------------- */
1774 
pack_data(double ** buf)1775 void AtomVecDPDKokkos::pack_data(double **buf)
1776 {
1777   atomKK->sync(Host,TAG_MASK|TYPE_MASK|DPDTHETA_MASK|X_MASK|IMAGE_MASK);
1778 
1779   int nlocal = atom->nlocal;
1780   for (int i = 0; i < nlocal; i++) {
1781     buf[i][0] = ubuf(h_tag(i)).d;
1782     buf[i][1] = ubuf(h_type(i)).d;
1783     buf[i][2] = h_dpdTheta(i);
1784     buf[i][3] = h_x(i,0);
1785     buf[i][4] = h_x(i,1);
1786     buf[i][5] = h_x(i,2);
1787     buf[i][6] = (h_image[i] & IMGMASK) - IMGMAX;
1788     buf[i][7] = (h_image[i] >> IMGBITS & IMGMASK) - IMGMAX;
1789     buf[i][8] = (h_image[i] >> IMG2BITS) - IMGMAX;
1790   }
1791 }
1792 
1793 /* ----------------------------------------------------------------------
1794    pack hybrid atom info for data file
1795 ------------------------------------------------------------------------- */
1796 
pack_data_hybrid(int i,double * buf)1797 int AtomVecDPDKokkos::pack_data_hybrid(int i, double *buf)
1798 {
1799   atomKK->sync(Host,DPDTHETA_MASK);
1800 
1801   buf[0] = h_dpdTheta(i);
1802   return 1;
1803 }
1804 
1805 /* ----------------------------------------------------------------------
1806    write atom info to data file including 3 image flags
1807 ------------------------------------------------------------------------- */
1808 
write_data(FILE * fp,int n,double ** buf)1809 void AtomVecDPDKokkos::write_data(FILE *fp, int n, double **buf)
1810 {
1811   for (int i = 0; i < n; i++)
1812     fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
1813             (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
1814             buf[i][2],buf[i][3],buf[i][4],buf[i][5],
1815             (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i,
1816             (int) ubuf(buf[i][8]).i);
1817 }
1818 
1819 /* ----------------------------------------------------------------------
1820    write hybrid atom info to data file
1821 ------------------------------------------------------------------------- */
1822 
write_data_hybrid(FILE * fp,double * buf)1823 int AtomVecDPDKokkos::write_data_hybrid(FILE *fp, double *buf)
1824 {
1825   fprintf(fp," %-1.16e",buf[0]);
1826   return 1;
1827 }
1828 
1829 /* ----------------------------------------------------------------------
1830    return # of bytes of allocated memory
1831 ------------------------------------------------------------------------- */
1832 
memory_usage()1833 double AtomVecDPDKokkos::memory_usage()
1834 {
1835   double bytes = 0;
1836 
1837   if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
1838   if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
1839   if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
1840   if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
1841   if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
1842   if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
1843   if (atom->memcheck("f")) bytes += memory->usage(f,nmax*commKK->nthreads,3);
1844   if (atom->memcheck("rho")) bytes += memory->usage(rho,nmax);
1845   if (atom->memcheck("dpdTheta")) bytes += memory->usage(dpdTheta,nmax);
1846   if (atom->memcheck("uCond")) bytes += memory->usage(uCond,nmax);
1847   if (atom->memcheck("uMech")) bytes += memory->usage(uMech,nmax);
1848   if (atom->memcheck("uChem")) bytes += memory->usage(uChem,nmax);
1849   if (atom->memcheck("uCG")) bytes += memory->usage(uCG,nmax);
1850   if (atom->memcheck("uCGnew")) bytes += memory->usage(uCGnew,nmax);
1851   if (atom->memcheck("duChem")) bytes += memory->usage(duChem,nmax);
1852 
1853   return bytes;
1854 }
1855 
1856 /* ---------------------------------------------------------------------- */
1857 
sync(ExecutionSpace space,unsigned int mask)1858 void AtomVecDPDKokkos::sync(ExecutionSpace space, unsigned int mask)
1859 {
1860   if (space == Device) {
1861     if (mask & X_MASK) atomKK->k_x.sync<LMPDeviceType>();
1862     if (mask & V_MASK) atomKK->k_v.sync<LMPDeviceType>();
1863     if (mask & F_MASK) atomKK->k_f.sync<LMPDeviceType>();
1864     if (mask & TAG_MASK) atomKK->k_tag.sync<LMPDeviceType>();
1865     if (mask & TYPE_MASK) atomKK->k_type.sync<LMPDeviceType>();
1866     if (mask & MASK_MASK) atomKK->k_mask.sync<LMPDeviceType>();
1867     if (mask & IMAGE_MASK) atomKK->k_image.sync<LMPDeviceType>();
1868     if (mask & DPDRHO_MASK) atomKK->k_rho.sync<LMPDeviceType>();
1869     if (mask & DPDTHETA_MASK) atomKK->k_dpdTheta.sync<LMPDeviceType>();
1870     if (mask & UCOND_MASK) atomKK->k_uCond.sync<LMPDeviceType>();
1871     if (mask & UMECH_MASK) atomKK->k_uMech.sync<LMPDeviceType>();
1872     if (mask & UCHEM_MASK) atomKK->k_uChem.sync<LMPDeviceType>();
1873     if (mask & UCG_MASK) atomKK->k_uCG.sync<LMPDeviceType>();
1874     if (mask & UCGNEW_MASK) atomKK->k_uCGnew.sync<LMPDeviceType>();
1875     if (mask & DUCHEM_MASK) atomKK->k_duChem.sync<LMPDeviceType>();
1876     if (mask & DVECTOR_MASK) atomKK->k_dvector.sync<LMPDeviceType>();
1877   } else {
1878     if (mask & X_MASK) atomKK->k_x.sync<LMPHostType>();
1879     if (mask & V_MASK) atomKK->k_v.sync<LMPHostType>();
1880     if (mask & F_MASK) atomKK->k_f.sync<LMPHostType>();
1881     if (mask & TAG_MASK) atomKK->k_tag.sync<LMPHostType>();
1882     if (mask & TYPE_MASK) atomKK->k_type.sync<LMPHostType>();
1883     if (mask & MASK_MASK) atomKK->k_mask.sync<LMPHostType>();
1884     if (mask & IMAGE_MASK) atomKK->k_image.sync<LMPHostType>();
1885     if (mask & DPDRHO_MASK) atomKK->k_rho.sync<LMPHostType>();
1886     if (mask & DPDTHETA_MASK) atomKK->k_dpdTheta.sync<LMPHostType>();
1887     if (mask & UCOND_MASK) atomKK->k_uCond.sync<LMPHostType>();
1888     if (mask & UMECH_MASK) atomKK->k_uMech.sync<LMPHostType>();
1889     if (mask & UCHEM_MASK) atomKK->k_uChem.sync<LMPHostType>();
1890     if (mask & UCG_MASK) atomKK->k_uCG.sync<LMPHostType>();
1891     if (mask & UCGNEW_MASK) atomKK->k_uCGnew.sync<LMPHostType>();
1892     if (mask & DUCHEM_MASK) atomKK->k_duChem.sync<LMPHostType>();
1893     if (mask & DVECTOR_MASK) atomKK->k_dvector.sync<LMPHostType>();
1894   }
1895 }
1896 
1897 /* ---------------------------------------------------------------------- */
1898 
sync_overlapping_device(ExecutionSpace space,unsigned int mask)1899 void AtomVecDPDKokkos::sync_overlapping_device(ExecutionSpace space, unsigned int mask)
1900 {
1901   if (space == Device) {
1902     if ((mask & X_MASK) && atomKK->k_x.need_sync<LMPDeviceType>())
1903       perform_async_copy<DAT::tdual_x_array>(atomKK->k_x,space);
1904     if ((mask & V_MASK) && atomKK->k_v.need_sync<LMPDeviceType>())
1905       perform_async_copy<DAT::tdual_v_array>(atomKK->k_v,space);
1906     if ((mask & F_MASK) && atomKK->k_f.need_sync<LMPDeviceType>())
1907       perform_async_copy<DAT::tdual_f_array>(atomKK->k_f,space);
1908     if ((mask & TAG_MASK) && atomKK->k_tag.need_sync<LMPDeviceType>())
1909       perform_async_copy<DAT::tdual_tagint_1d>(atomKK->k_tag,space);
1910     if ((mask & TYPE_MASK) && atomKK->k_type.need_sync<LMPDeviceType>())
1911       perform_async_copy<DAT::tdual_int_1d>(atomKK->k_type,space);
1912     if ((mask & MASK_MASK) && atomKK->k_mask.need_sync<LMPDeviceType>())
1913       perform_async_copy<DAT::tdual_int_1d>(atomKK->k_mask,space);
1914     if ((mask & IMAGE_MASK) && atomKK->k_image.need_sync<LMPDeviceType>())
1915       perform_async_copy<DAT::tdual_imageint_1d>(atomKK->k_image,space);
1916     if ((mask & DPDRHO_MASK) && atomKK->k_rho.need_sync<LMPDeviceType>())
1917       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_rho,space);
1918     if ((mask & DPDTHETA_MASK) && atomKK->k_dpdTheta.need_sync<LMPDeviceType>())
1919       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_dpdTheta,space);
1920     if ((mask & UCOND_MASK) && atomKK->k_uCond.need_sync<LMPDeviceType>())
1921       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_uCond,space);
1922     if ((mask & UMECH_MASK) && atomKK->k_uMech.need_sync<LMPDeviceType>())
1923       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_uMech,space);
1924     if ((mask & UCHEM_MASK) && atomKK->k_uChem.need_sync<LMPDeviceType>())
1925       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_uChem,space);
1926     if ((mask & UCG_MASK) && atomKK->k_uCG.need_sync<LMPDeviceType>())
1927       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_uCG,space);
1928     if ((mask & UCGNEW_MASK) && atomKK->k_uCGnew.need_sync<LMPDeviceType>())
1929       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_uCGnew,space);
1930     if ((mask & DUCHEM_MASK) && atomKK->k_duChem.need_sync<LMPDeviceType>())
1931       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_duChem,space);
1932     if ((mask & DVECTOR_MASK) && atomKK->k_dvector.need_sync<LMPDeviceType>())
1933       perform_async_copy<DAT::tdual_float_2d>(atomKK->k_dvector,space);
1934   } else {
1935     if ((mask & X_MASK) && atomKK->k_x.need_sync<LMPHostType>())
1936       perform_async_copy<DAT::tdual_x_array>(atomKK->k_x,space);
1937     if ((mask & V_MASK) && atomKK->k_v.need_sync<LMPHostType>())
1938       perform_async_copy<DAT::tdual_v_array>(atomKK->k_v,space);
1939     if ((mask & F_MASK) && atomKK->k_f.need_sync<LMPHostType>())
1940       perform_async_copy<DAT::tdual_f_array>(atomKK->k_f,space);
1941     if ((mask & TAG_MASK) && atomKK->k_tag.need_sync<LMPHostType>())
1942       perform_async_copy<DAT::tdual_tagint_1d>(atomKK->k_tag,space);
1943     if ((mask & TYPE_MASK) && atomKK->k_type.need_sync<LMPHostType>())
1944       perform_async_copy<DAT::tdual_int_1d>(atomKK->k_type,space);
1945     if ((mask & MASK_MASK) && atomKK->k_mask.need_sync<LMPHostType>())
1946       perform_async_copy<DAT::tdual_int_1d>(atomKK->k_mask,space);
1947     if ((mask & IMAGE_MASK) && atomKK->k_image.need_sync<LMPHostType>())
1948       perform_async_copy<DAT::tdual_imageint_1d>(atomKK->k_image,space);
1949     if ((mask & DPDRHO_MASK) && atomKK->k_rho.need_sync<LMPHostType>())
1950       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_rho,space);
1951     if ((mask & DPDTHETA_MASK) && atomKK->k_dpdTheta.need_sync<LMPHostType>())
1952       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_dpdTheta,space);
1953     if ((mask & UCOND_MASK) && atomKK->k_uCond.need_sync<LMPHostType>())
1954       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_uCond,space);
1955     if ((mask & UMECH_MASK) && atomKK->k_uMech.need_sync<LMPHostType>())
1956       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_uMech,space);
1957     if ((mask & UCHEM_MASK) && atomKK->k_uChem.need_sync<LMPHostType>())
1958       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_uChem,space);
1959     if ((mask & UCG_MASK) && atomKK->k_uCG.need_sync<LMPHostType>())
1960       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_uCG,space);
1961     if ((mask & UCGNEW_MASK) && atomKK->k_uCGnew.need_sync<LMPHostType>())
1962       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_uCGnew,space);
1963     if ((mask & DUCHEM_MASK) && atomKK->k_duChem.need_sync<LMPHostType>())
1964       perform_async_copy<DAT::tdual_efloat_1d>(atomKK->k_duChem,space);
1965     if ((mask & DVECTOR_MASK) && atomKK->k_dvector.need_sync<LMPHostType>())
1966       perform_async_copy<DAT::tdual_float_2d>(atomKK->k_dvector,space);
1967   }
1968 }
1969 
1970 /* ---------------------------------------------------------------------- */
1971 
modified(ExecutionSpace space,unsigned int mask)1972 void AtomVecDPDKokkos::modified(ExecutionSpace space, unsigned int mask)
1973 {
1974   if (space == Device) {
1975     if (mask & X_MASK) atomKK->k_x.modify<LMPDeviceType>();
1976     if (mask & V_MASK) atomKK->k_v.modify<LMPDeviceType>();
1977     if (mask & F_MASK) atomKK->k_f.modify<LMPDeviceType>();
1978     if (mask & TAG_MASK) atomKK->k_tag.modify<LMPDeviceType>();
1979     if (mask & TYPE_MASK) atomKK->k_type.modify<LMPDeviceType>();
1980     if (mask & MASK_MASK) atomKK->k_mask.modify<LMPDeviceType>();
1981     if (mask & IMAGE_MASK) atomKK->k_image.modify<LMPDeviceType>();
1982     if (mask & DPDRHO_MASK) atomKK->k_rho.modify<LMPDeviceType>();
1983     if (mask & DPDTHETA_MASK) atomKK->k_dpdTheta.modify<LMPDeviceType>();
1984     if (mask & UCOND_MASK) atomKK->k_uCond.modify<LMPDeviceType>();
1985     if (mask & UMECH_MASK) atomKK->k_uMech.modify<LMPDeviceType>();
1986     if (mask & UCHEM_MASK) atomKK->k_uChem.modify<LMPDeviceType>();
1987     if (mask & UCG_MASK) atomKK->k_uCG.modify<LMPDeviceType>();
1988     if (mask & UCGNEW_MASK) atomKK->k_uCGnew.modify<LMPDeviceType>();
1989     if (mask & DUCHEM_MASK) atomKK->k_duChem.modify<LMPDeviceType>();
1990     if (mask & DVECTOR_MASK) atomKK->k_dvector.modify<LMPDeviceType>();
1991   } else {
1992     if (mask & X_MASK) atomKK->k_x.modify<LMPHostType>();
1993     if (mask & V_MASK) atomKK->k_v.modify<LMPHostType>();
1994     if (mask & F_MASK) atomKK->k_f.modify<LMPHostType>();
1995     if (mask & TAG_MASK) atomKK->k_tag.modify<LMPHostType>();
1996     if (mask & TYPE_MASK) atomKK->k_type.modify<LMPHostType>();
1997     if (mask & MASK_MASK) atomKK->k_mask.modify<LMPHostType>();
1998     if (mask & IMAGE_MASK) atomKK->k_image.modify<LMPHostType>();
1999     if (mask & DPDRHO_MASK) atomKK->k_rho.modify<LMPHostType>();
2000     if (mask & DPDTHETA_MASK) atomKK->k_dpdTheta.modify<LMPHostType>();
2001     if (mask & UCOND_MASK) atomKK->k_uCond.modify<LMPHostType>();
2002     if (mask & UMECH_MASK) atomKK->k_uMech.modify<LMPHostType>();
2003     if (mask & UCHEM_MASK) atomKK->k_uChem.modify<LMPHostType>();
2004     if (mask & UCG_MASK) atomKK->k_uCG.modify<LMPHostType>();
2005     if (mask & UCGNEW_MASK) atomKK->k_uCGnew.modify<LMPHostType>();
2006     if (mask & DUCHEM_MASK) atomKK->k_duChem.modify<LMPHostType>();
2007     if (mask & DVECTOR_MASK) atomKK->k_dvector.modify<LMPHostType>();
2008   }
2009 }
2010 
2011