~ubuntu-branches/debian/sid/lammps/sid

« back to all changes in this revision

Viewing changes to src/KOKKOS/atom_vec_atomic_kokkos.cpp

  • Committer: Package Import Robot
  • Author(s): Anton Gladky
  • Date: 2015-04-29 23:44:49 UTC
  • mfrom: (5.1.3 experimental)
  • Revision ID: package-import@ubuntu.com-20150429234449-mbhy9utku6hp6oq8
Tags: 0~20150313.gitfa668e1-1
Upload into unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ----------------------------------------------------------------------
 
2
   LAMMPS - Large-scale AtomicKokkos/Molecular Massively Parallel Simulator
 
3
   http://lammps.sandia.gov, Sandia National Laboratories
 
4
   Steve Plimpton, sjplimp@sandia.gov
 
5
 
 
6
   Copyright (2003) Sandia Corporation.  Under the terms of Contract
 
7
   DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
 
8
   certain rights in this software.  This software is distributed under
 
9
   the GNU General Public License.
 
10
 
 
11
   See the README file in the top-level LAMMPS directory.
 
12
------------------------------------------------------------------------- */
 
13
 
 
14
#include "stdlib.h"
 
15
#include "atom_vec_atomic_kokkos.h"
 
16
#include "atom_kokkos.h"
 
17
#include "comm_kokkos.h"
 
18
#include "domain.h"
 
19
#include "modify.h"
 
20
#include "fix.h"
 
21
#include "atom_masks.h"
 
22
#include "memory.h"
 
23
#include "error.h"
 
24
 
 
25
using namespace LAMMPS_NS;
 
26
 
 
27
#define DELTA 10000
 
28
 
 
29
/* ---------------------------------------------------------------------- */
 
30
 
 
31
AtomVecAtomicKokkos::AtomVecAtomicKokkos(LAMMPS *lmp) : AtomVecKokkos(lmp)
 
32
{
 
33
  molecular = 0;
 
34
  mass_type = 1;
 
35
 
 
36
  comm_x_only = comm_f_only = 1;
 
37
  size_forward = 3;
 
38
  size_reverse = 3;
 
39
  size_border = 6;
 
40
  size_velocity = 3;
 
41
  size_data_atom = 5;
 
42
  size_data_vel = 4;
 
43
  xcol_data = 3;
 
44
 
 
45
  k_count = DAT::tdual_int_1d("atom::k_count",1);
 
46
  atomKK = (AtomKokkos *) atom;
 
47
  commKK = (CommKokkos *) comm;
 
48
}
 
49
 
 
50
/* ----------------------------------------------------------------------
 
51
   grow atom arrays
 
52
   n = 0 grows arrays by DELTA
 
53
   n > 0 allocates arrays to size n
 
54
------------------------------------------------------------------------- */
 
55
 
 
56
void AtomVecAtomicKokkos::grow(int n)
 
57
{
 
58
  if (n == 0) nmax += DELTA;
 
59
  else nmax = n;
 
60
  atomKK->nmax = nmax;
 
61
  if (nmax < 0 || nmax > MAXSMALLINT)
 
62
    error->one(FLERR,"Per-processor system is too big");
 
63
 
 
64
  sync(Device,ALL_MASK);
 
65
  modified(Device,ALL_MASK);
 
66
 
 
67
  memory->grow_kokkos(atomKK->k_tag,atomKK->tag,nmax,"atom:tag");
 
68
  memory->grow_kokkos(atomKK->k_type,atomKK->type,nmax,"atom:type");
 
69
  memory->grow_kokkos(atomKK->k_mask,atomKK->mask,nmax,"atom:mask");
 
70
  memory->grow_kokkos(atomKK->k_image,atomKK->image,nmax,"atom:image");
 
71
 
 
72
  memory->grow_kokkos(atomKK->k_x,atomKK->x,nmax,3,"atom:x");
 
73
  memory->grow_kokkos(atomKK->k_v,atomKK->v,nmax,3,"atom:v");
 
74
  memory->grow_kokkos(atomKK->k_f,atomKK->f,nmax,3,"atom:f");
 
75
 
 
76
  grow_reset();
 
77
  sync(Host,ALL_MASK);
 
78
 
 
79
  if (atom->nextra_grow)
 
80
    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
 
81
      modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 
82
}
 
83
 
 
84
/* ----------------------------------------------------------------------
 
85
   reset local array ptrs
 
86
------------------------------------------------------------------------- */
 
87
 
 
88
void AtomVecAtomicKokkos::grow_reset()
 
89
{
 
90
  tag = atomKK->tag; 
 
91
  d_tag = atomKK->k_tag.d_view; 
 
92
  h_tag = atomKK->k_tag.h_view;
 
93
 
 
94
  type = atomKK->type; 
 
95
  d_type = atomKK->k_type.d_view; 
 
96
  h_type = atomKK->k_type.h_view;
 
97
  mask = atomKK->mask; 
 
98
  d_mask = atomKK->k_mask.d_view; 
 
99
  h_mask = atomKK->k_mask.h_view;
 
100
  image = atomKK->image; 
 
101
  d_image = atomKK->k_image.d_view; 
 
102
  h_image = atomKK->k_image.h_view;
 
103
 
 
104
  x = atomKK->x; 
 
105
  d_x = atomKK->k_x.d_view; 
 
106
  h_x = atomKK->k_x.h_view;
 
107
  v = atomKK->v; 
 
108
  d_v = atomKK->k_v.d_view; 
 
109
  h_v = atomKK->k_v.h_view;
 
110
  f = atomKK->f; 
 
111
  d_f = atomKK->k_f.d_view; 
 
112
  h_f = atomKK->k_f.h_view;
 
113
}
 
114
 
 
115
/* ----------------------------------------------------------------------
 
116
   copy atom I info to atom J
 
117
------------------------------------------------------------------------- */
 
118
 
 
119
void AtomVecAtomicKokkos::copy(int i, int j, int delflag)
 
120
{
 
121
  h_tag[j] = h_tag[i];
 
122
  h_type[j] = h_type[i];
 
123
  mask[j] = mask[i];
 
124
  h_image[j] = h_image[i];
 
125
  h_x(j,0) = h_x(i,0);
 
126
  h_x(j,1) = h_x(i,1);
 
127
  h_x(j,2) = h_x(i,2);
 
128
  h_v(j,0) = h_v(i,0);
 
129
  h_v(j,1) = h_v(i,1);
 
130
  h_v(j,2) = h_v(i,2);
 
131
 
 
132
  if (atom->nextra_grow)
 
133
    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
 
134
      modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag);
 
135
}
 
136
 
 
137
/* ---------------------------------------------------------------------- */
 
138
 
 
139
template<class DeviceType,int PBC_FLAG,int TRICLINIC>
 
140
struct AtomVecAtomicKokkos_PackComm {
 
141
  typedef DeviceType device_type;
 
142
 
 
143
  typename ArrayTypes<DeviceType>::t_x_array_randomread _x;
 
144
  typename ArrayTypes<DeviceType>::t_xfloat_2d_um _buf;
 
145
  typename ArrayTypes<DeviceType>::t_int_2d_const _list;
 
146
  const int _iswap;
 
147
  X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz;
 
148
  X_FLOAT _pbc[6];
 
149
 
 
150
  AtomVecAtomicKokkos_PackComm(
 
151
      const typename DAT::tdual_x_array &x,
 
152
      const typename DAT::tdual_xfloat_2d &buf,
 
153
      const typename DAT::tdual_int_2d &list,
 
154
      const int & iswap,
 
155
      const X_FLOAT &xprd, const X_FLOAT &yprd, const X_FLOAT &zprd,
 
156
      const X_FLOAT &xy, const X_FLOAT &xz, const X_FLOAT &yz, const int* const pbc):
 
157
      _x(x.view<DeviceType>()),_list(list.view<DeviceType>()),_iswap(iswap),
 
158
      _xprd(xprd),_yprd(yprd),_zprd(zprd),
 
159
      _xy(xy),_xz(xz),_yz(yz) {
 
160
        const size_t maxsend = (buf.view<DeviceType>().dimension_0()*buf.view<DeviceType>().dimension_1())/3;
 
161
        const size_t elements = 3;
 
162
        buffer_view<DeviceType>(_buf,buf,maxsend,elements);
 
163
        _pbc[0] = pbc[0]; _pbc[1] = pbc[1]; _pbc[2] = pbc[2];
 
164
        _pbc[3] = pbc[3]; _pbc[4] = pbc[4]; _pbc[5] = pbc[5];
 
165
  };
 
166
 
 
167
  KOKKOS_INLINE_FUNCTION
 
168
  void operator() (const int& i) const {
 
169
        const int j = _list(_iswap,i);
 
170
      if (PBC_FLAG == 0) {
 
171
          _buf(i,0) = _x(j,0);
 
172
          _buf(i,1) = _x(j,1);
 
173
          _buf(i,2) = _x(j,2);
 
174
      } else {
 
175
        if (TRICLINIC == 0) {
 
176
          _buf(i,0) = _x(j,0) + _pbc[0]*_xprd;
 
177
          _buf(i,1) = _x(j,1) + _pbc[1]*_yprd;
 
178
          _buf(i,2) = _x(j,2) + _pbc[2]*_zprd;
 
179
        } else {
 
180
          _buf(i,0) = _x(j,0) + _pbc[0]*_xprd + _pbc[5]*_xy + _pbc[4]*_xz;
 
181
          _buf(i,1) = _x(j,1) + _pbc[1]*_yprd + _pbc[3]*_yz;
 
182
          _buf(i,2) = _x(j,2) + _pbc[2]*_zprd;
 
183
        }
 
184
      }
 
185
  }
 
186
};
 
187
 
 
188
/* ---------------------------------------------------------------------- */
 
189
 
 
190
int AtomVecAtomicKokkos::pack_comm_kokkos(const int &n, 
 
191
                                          const DAT::tdual_int_2d &list, 
 
192
                                          const int & iswap,
 
193
                                          const DAT::tdual_xfloat_2d &buf,
 
194
                                          const int &pbc_flag,
 
195
                                          const int* const pbc)
 
196
{
 
197
  // Check whether to always run forward communication on the host
 
198
  // Choose correct forward PackComm kernel
 
199
 
 
200
  if(commKK->forward_comm_on_host) {
 
201
    sync(Host,X_MASK);
 
202
    if(pbc_flag) {
 
203
      if(domain->triclinic) {
 
204
        struct AtomVecAtomicKokkos_PackComm<LMPHostType,1,1> f(atomKK->k_x,buf,list,iswap,
 
205
          domain->xprd,domain->yprd,domain->zprd,
 
206
          domain->xy,domain->xz,domain->yz,pbc);
 
207
        Kokkos::parallel_for(n,f);
 
208
      } else {
 
209
        struct AtomVecAtomicKokkos_PackComm<LMPHostType,1,0> f(atomKK->k_x,buf,list,iswap,
 
210
          domain->xprd,domain->yprd,domain->zprd,
 
211
          domain->xy,domain->xz,domain->yz,pbc);
 
212
        Kokkos::parallel_for(n,f);
 
213
      }
 
214
    } else {
 
215
      if(domain->triclinic) {
 
216
        struct AtomVecAtomicKokkos_PackComm<LMPHostType,0,1> f(atomKK->k_x,buf,list,iswap,
 
217
          domain->xprd,domain->yprd,domain->zprd,
 
218
          domain->xy,domain->xz,domain->yz,pbc);
 
219
        Kokkos::parallel_for(n,f);
 
220
      } else {
 
221
        struct AtomVecAtomicKokkos_PackComm<LMPHostType,0,0> f(atomKK->k_x,buf,list,iswap,
 
222
          domain->xprd,domain->yprd,domain->zprd,
 
223
          domain->xy,domain->xz,domain->yz,pbc);
 
224
        Kokkos::parallel_for(n,f);
 
225
      }
 
226
    }
 
227
    LMPHostType::fence();
 
228
  } else {
 
229
    sync(Device,X_MASK);
 
230
    if(pbc_flag) {
 
231
      if(domain->triclinic) {
 
232
        struct AtomVecAtomicKokkos_PackComm<LMPDeviceType,1,1> f(atomKK->k_x,buf,list,iswap,
 
233
          domain->xprd,domain->yprd,domain->zprd,
 
234
          domain->xy,domain->xz,domain->yz,pbc);
 
235
        Kokkos::parallel_for(n,f);
 
236
      } else {
 
237
        struct AtomVecAtomicKokkos_PackComm<LMPDeviceType,1,0> f(atomKK->k_x,buf,list,iswap,
 
238
          domain->xprd,domain->yprd,domain->zprd,
 
239
          domain->xy,domain->xz,domain->yz,pbc);
 
240
        Kokkos::parallel_for(n,f);
 
241
      }
 
242
    } else {
 
243
      if(domain->triclinic) {
 
244
        struct AtomVecAtomicKokkos_PackComm<LMPDeviceType,0,1> f(atomKK->k_x,buf,list,iswap,
 
245
          domain->xprd,domain->yprd,domain->zprd,
 
246
          domain->xy,domain->xz,domain->yz,pbc);
 
247
        Kokkos::parallel_for(n,f);
 
248
      } else {
 
249
        struct AtomVecAtomicKokkos_PackComm<LMPDeviceType,0,0> f(atomKK->k_x,buf,list,iswap,
 
250
          domain->xprd,domain->yprd,domain->zprd,
 
251
          domain->xy,domain->xz,domain->yz,pbc);
 
252
        Kokkos::parallel_for(n,f);
 
253
      }
 
254
    }
 
255
    LMPDeviceType::fence();
 
256
  }
 
257
 
 
258
        return n*size_forward;
 
259
}
 
260
 
 
261
/* ---------------------------------------------------------------------- */
 
262
 
 
263
template<class DeviceType,int PBC_FLAG,int TRICLINIC>
 
264
struct AtomVecAtomicKokkos_PackCommSelf {
 
265
  typedef DeviceType device_type;
 
266
 
 
267
  typename ArrayTypes<DeviceType>::t_x_array_randomread _x;
 
268
  typename ArrayTypes<DeviceType>::t_x_array _xw;
 
269
  int _nfirst;
 
270
  typename ArrayTypes<DeviceType>::t_int_2d_const _list;
 
271
  const int _iswap;
 
272
  X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz;
 
273
  X_FLOAT _pbc[6];
 
274
 
 
275
  AtomVecAtomicKokkos_PackCommSelf(
 
276
      const typename DAT::tdual_x_array &x,
 
277
      const int &nfirst,
 
278
      const typename DAT::tdual_int_2d &list,
 
279
      const int & iswap,
 
280
      const X_FLOAT &xprd, const X_FLOAT &yprd, const X_FLOAT &zprd,
 
281
      const X_FLOAT &xy, const X_FLOAT &xz, const X_FLOAT &yz, const int* const pbc):
 
282
      _x(x.view<DeviceType>()),_xw(x.view<DeviceType>()),_nfirst(nfirst),_list(list.view<DeviceType>()),_iswap(iswap),
 
283
      _xprd(xprd),_yprd(yprd),_zprd(zprd),
 
284
      _xy(xy),_xz(xz),_yz(yz) {
 
285
        _pbc[0] = pbc[0]; _pbc[1] = pbc[1]; _pbc[2] = pbc[2];
 
286
        _pbc[3] = pbc[3]; _pbc[4] = pbc[4]; _pbc[5] = pbc[5];
 
287
  };
 
288
 
 
289
  KOKKOS_INLINE_FUNCTION
 
290
  void operator() (const int& i) const {
 
291
        const int j = _list(_iswap,i);
 
292
      if (PBC_FLAG == 0) {
 
293
          _xw(i+_nfirst,0) = _x(j,0);
 
294
          _xw(i+_nfirst,1) = _x(j,1);
 
295
          _xw(i+_nfirst,2) = _x(j,2);
 
296
      } else {
 
297
        if (TRICLINIC == 0) {
 
298
          _xw(i+_nfirst,0) = _x(j,0) + _pbc[0]*_xprd;
 
299
          _xw(i+_nfirst,1) = _x(j,1) + _pbc[1]*_yprd;
 
300
          _xw(i+_nfirst,2) = _x(j,2) + _pbc[2]*_zprd;
 
301
        } else {
 
302
          _xw(i+_nfirst,0) = _x(j,0) + _pbc[0]*_xprd + _pbc[5]*_xy + _pbc[4]*_xz;
 
303
          _xw(i+_nfirst,1) = _x(j,1) + _pbc[1]*_yprd + _pbc[3]*_yz;
 
304
          _xw(i+_nfirst,2) = _x(j,2) + _pbc[2]*_zprd;
 
305
        }
 
306
      }
 
307
 
 
308
  }
 
309
};
 
310
 
 
311
/* ---------------------------------------------------------------------- */
 
312
 
 
313
int AtomVecAtomicKokkos::pack_comm_self(const int &n, const DAT::tdual_int_2d &list, const int & iswap,
 
314
                                                                                const int nfirst, const int &pbc_flag, const int* const pbc) {
 
315
  if(commKK->forward_comm_on_host) {
 
316
    sync(Host,X_MASK);
 
317
    modified(Host,X_MASK);
 
318
    if(pbc_flag) {
 
319
      if(domain->triclinic) {
 
320
      struct AtomVecAtomicKokkos_PackCommSelf<LMPHostType,1,1> f(atomKK->k_x,nfirst,list,iswap,
 
321
          domain->xprd,domain->yprd,domain->zprd,
 
322
          domain->xy,domain->xz,domain->yz,pbc);
 
323
      Kokkos::parallel_for(n,f);
 
324
      } else {
 
325
      struct AtomVecAtomicKokkos_PackCommSelf<LMPHostType,1,0> f(atomKK->k_x,nfirst,list,iswap,
 
326
          domain->xprd,domain->yprd,domain->zprd,
 
327
          domain->xy,domain->xz,domain->yz,pbc);
 
328
      Kokkos::parallel_for(n,f);
 
329
      }
 
330
    } else {
 
331
      if(domain->triclinic) {
 
332
      struct AtomVecAtomicKokkos_PackCommSelf<LMPHostType,0,1> f(atomKK->k_x,nfirst,list,iswap,
 
333
          domain->xprd,domain->yprd,domain->zprd,
 
334
          domain->xy,domain->xz,domain->yz,pbc);
 
335
      Kokkos::parallel_for(n,f);
 
336
      } else {
 
337
      struct AtomVecAtomicKokkos_PackCommSelf<LMPHostType,0,0> f(atomKK->k_x,nfirst,list,iswap,
 
338
          domain->xprd,domain->yprd,domain->zprd,
 
339
          domain->xy,domain->xz,domain->yz,pbc);
 
340
      Kokkos::parallel_for(n,f);
 
341
      }
 
342
    }
 
343
    LMPHostType::fence();
 
344
  } else {
 
345
    sync(Device,X_MASK);
 
346
    modified(Device,X_MASK);
 
347
    if(pbc_flag) {
 
348
      if(domain->triclinic) {
 
349
      struct AtomVecAtomicKokkos_PackCommSelf<LMPDeviceType,1,1> f(atomKK->k_x,nfirst,list,iswap,
 
350
          domain->xprd,domain->yprd,domain->zprd,
 
351
          domain->xy,domain->xz,domain->yz,pbc);
 
352
      Kokkos::parallel_for(n,f);
 
353
      } else {
 
354
      struct AtomVecAtomicKokkos_PackCommSelf<LMPDeviceType,1,0> f(atomKK->k_x,nfirst,list,iswap,
 
355
          domain->xprd,domain->yprd,domain->zprd,
 
356
          domain->xy,domain->xz,domain->yz,pbc);
 
357
      Kokkos::parallel_for(n,f);
 
358
      }
 
359
    } else {
 
360
      if(domain->triclinic) {
 
361
      struct AtomVecAtomicKokkos_PackCommSelf<LMPDeviceType,0,1> f(atomKK->k_x,nfirst,list,iswap,
 
362
          domain->xprd,domain->yprd,domain->zprd,
 
363
          domain->xy,domain->xz,domain->yz,pbc);
 
364
      Kokkos::parallel_for(n,f);
 
365
      } else {
 
366
      struct AtomVecAtomicKokkos_PackCommSelf<LMPDeviceType,0,0> f(atomKK->k_x,nfirst,list,iswap,
 
367
          domain->xprd,domain->yprd,domain->zprd,
 
368
          domain->xy,domain->xz,domain->yz,pbc);
 
369
      Kokkos::parallel_for(n,f);
 
370
      }
 
371
    }
 
372
    LMPDeviceType::fence();
 
373
  }
 
374
        return n*3;
 
375
}
 
376
 
 
377
/* ---------------------------------------------------------------------- */
 
378
 
 
379
template<class DeviceType>
 
380
struct AtomVecAtomicKokkos_UnpackComm {
 
381
  typedef DeviceType device_type;
 
382
 
 
383
  typename ArrayTypes<DeviceType>::t_x_array _x;
 
384
  typename ArrayTypes<DeviceType>::t_xfloat_2d_const _buf;
 
385
  int _first;
 
386
 
 
387
  AtomVecAtomicKokkos_UnpackComm(
 
388
      const typename DAT::tdual_x_array &x,
 
389
      const typename DAT::tdual_xfloat_2d &buf,
 
390
      const int& first):_x(x.view<DeviceType>()),_buf(buf.view<DeviceType>()),
 
391
                        _first(first) {};
 
392
 
 
393
  KOKKOS_INLINE_FUNCTION
 
394
  void operator() (const int& i) const {
 
395
      _x(i+_first,0) = _buf(i,0);
 
396
      _x(i+_first,1) = _buf(i,1);
 
397
      _x(i+_first,2) = _buf(i,2);
 
398
  }
 
399
};
 
400
 
 
401
/* ---------------------------------------------------------------------- */
 
402
 
 
403
void AtomVecAtomicKokkos::unpack_comm_kokkos(const int &n, const int &first,
 
404
    const DAT::tdual_xfloat_2d &buf ) {
 
405
  if(commKK->forward_comm_on_host) {
 
406
    sync(Host,X_MASK);
 
407
    modified(Host,X_MASK);
 
408
    struct AtomVecAtomicKokkos_UnpackComm<LMPHostType> f(atomKK->k_x,buf,first);
 
409
    Kokkos::parallel_for(n,f);
 
410
    LMPDeviceType::fence();
 
411
  } else {
 
412
    sync(Device,X_MASK);
 
413
    modified(Device,X_MASK);
 
414
    struct AtomVecAtomicKokkos_UnpackComm<LMPDeviceType> f(atomKK->k_x,buf,first);
 
415
    Kokkos::parallel_for(n,f);
 
416
    LMPDeviceType::fence();
 
417
  }
 
418
}
 
419
 
 
420
/* ---------------------------------------------------------------------- */
 
421
 
 
422
int AtomVecAtomicKokkos::pack_comm(int n, int *list, double *buf,
 
423
                             int pbc_flag, int *pbc)
 
424
{
 
425
  int i,j,m;
 
426
  double dx,dy,dz;
 
427
 
 
428
  m = 0;
 
429
  if (pbc_flag == 0) {
 
430
    for (i = 0; i < n; i++) {
 
431
      j = list[i];
 
432
      buf[m++] = h_x(j,0);
 
433
      buf[m++] = h_x(j,1);
 
434
      buf[m++] = h_x(j,2);
 
435
    }
 
436
  } else {
 
437
    if (domain->triclinic == 0) {
 
438
      dx = pbc[0]*domain->xprd;
 
439
      dy = pbc[1]*domain->yprd;
 
440
      dz = pbc[2]*domain->zprd;
 
441
    } else {
 
442
      dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
 
443
      dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
 
444
      dz = pbc[2]*domain->zprd;
 
445
    }
 
446
    for (i = 0; i < n; i++) {
 
447
      j = list[i];
 
448
      buf[m++] = h_x(j,0) + dx;
 
449
      buf[m++] = h_x(j,1) + dy;
 
450
      buf[m++] = h_x(j,2) + dz;
 
451
    }
 
452
  }
 
453
  return m;
 
454
}
 
455
 
 
456
/* ---------------------------------------------------------------------- */
 
457
 
 
458
int AtomVecAtomicKokkos::pack_comm_vel(int n, int *list, double *buf,
 
459
                                 int pbc_flag, int *pbc)
 
460
{
 
461
  int i,j,m;
 
462
  double dx,dy,dz,dvx,dvy,dvz;
 
463
 
 
464
  m = 0;
 
465
  if (pbc_flag == 0) {
 
466
    for (i = 0; i < n; i++) {
 
467
      j = list[i];
 
468
      buf[m++] = h_x(j,0);
 
469
      buf[m++] = h_x(j,1);
 
470
      buf[m++] = h_x(j,2);
 
471
      buf[m++] = h_v(j,0);
 
472
      buf[m++] = h_v(j,1);
 
473
      buf[m++] = h_v(j,2);
 
474
    }
 
475
  } else {
 
476
    if (domain->triclinic == 0) {
 
477
      dx = pbc[0]*domain->xprd;
 
478
      dy = pbc[1]*domain->yprd;
 
479
      dz = pbc[2]*domain->zprd;
 
480
    } else {
 
481
      dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
 
482
      dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
 
483
      dz = pbc[2]*domain->zprd;
 
484
    }
 
485
    if (!deform_vremap) {
 
486
      for (i = 0; i < n; i++) {
 
487
        j = list[i];
 
488
        buf[m++] = h_x(j,0) + dx;
 
489
        buf[m++] = h_x(j,1) + dy;
 
490
        buf[m++] = h_x(j,2) + dz;
 
491
        buf[m++] = h_v(j,0);
 
492
        buf[m++] = h_v(j,1);
 
493
        buf[m++] = h_v(j,2);
 
494
      }
 
495
    } else {
 
496
      dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
 
497
      dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
 
498
      dvz = pbc[2]*h_rate[2];
 
499
      for (i = 0; i < n; i++) {
 
500
        j = list[i];
 
501
        buf[m++] = h_x(j,0) + dx;
 
502
        buf[m++] = h_x(j,1) + dy;
 
503
        buf[m++] = h_x(j,2) + dz;
 
504
        if (mask[i] & deform_groupbit) {
 
505
          buf[m++] = h_v(j,0) + dvx;
 
506
          buf[m++] = h_v(j,1) + dvy;
 
507
          buf[m++] = h_v(j,2) + dvz;
 
508
        } else {
 
509
          buf[m++] = h_v(j,0);
 
510
          buf[m++] = h_v(j,1);
 
511
          buf[m++] = h_v(j,2);
 
512
        }
 
513
      }
 
514
    }
 
515
  }
 
516
  return m;
 
517
}
 
518
 
 
519
/* ---------------------------------------------------------------------- */
 
520
 
 
521
void AtomVecAtomicKokkos::unpack_comm(int n, int first, double *buf)
 
522
{
 
523
  int i,m,last;
 
524
 
 
525
  m = 0;
 
526
  last = first + n;
 
527
  for (i = first; i < last; i++) {
 
528
    h_x(i,0) = buf[m++];
 
529
    h_x(i,1) = buf[m++];
 
530
    h_x(i,2) = buf[m++];
 
531
  }
 
532
}
 
533
 
 
534
/* ---------------------------------------------------------------------- */
 
535
 
 
536
void AtomVecAtomicKokkos::unpack_comm_vel(int n, int first, double *buf)
 
537
{
 
538
  int i,m,last;
 
539
 
 
540
  m = 0;
 
541
  last = first + n;
 
542
  for (i = first; i < last; i++) {
 
543
    h_x(i,0) = buf[m++];
 
544
    h_x(i,1) = buf[m++];
 
545
    h_x(i,2) = buf[m++];
 
546
    h_v(i,0) = buf[m++];
 
547
    h_v(i,1) = buf[m++];
 
548
    h_v(i,2) = buf[m++];
 
549
  }
 
550
}
 
551
 
 
552
/* ---------------------------------------------------------------------- */
 
553
 
 
554
int AtomVecAtomicKokkos::pack_reverse(int n, int first, double *buf)
 
555
{
 
556
  if(n > 0)
 
557
    sync(Host,F_MASK);
 
558
 
 
559
  int m = 0;
 
560
  const int last = first + n;
 
561
  for (int i = first; i < last; i++) {
 
562
    buf[m++] = h_f(i,0);
 
563
    buf[m++] = h_f(i,1);
 
564
    buf[m++] = h_f(i,2);
 
565
  }
 
566
  return m;
 
567
}
 
568
 
 
569
/* ---------------------------------------------------------------------- */
 
570
 
 
571
void AtomVecAtomicKokkos::unpack_reverse(int n, int *list, double *buf)
 
572
{
 
573
  if(n > 0) {
 
574
    sync(Host,F_MASK);
 
575
    modified(Host,F_MASK);
 
576
  }
 
577
 
 
578
  int m = 0;
 
579
  for (int i = 0; i < n; i++) {
 
580
    const int j = list[i];
 
581
    h_f(j,0) += buf[m++];
 
582
    h_f(j,1) += buf[m++];
 
583
    h_f(j,2) += buf[m++];
 
584
  }
 
585
}
 
586
 
 
587
/* ---------------------------------------------------------------------- */
 
588
 
 
589
template<class DeviceType,int PBC_FLAG>
 
590
struct AtomVecAtomicKokkos_PackBorder {
 
591
  typedef DeviceType device_type;
 
592
 
 
593
  typename ArrayTypes<DeviceType>::t_xfloat_2d _buf;
 
594
  const typename ArrayTypes<DeviceType>::t_int_2d_const _list;
 
595
  const int _iswap;
 
596
  const typename ArrayTypes<DeviceType>::t_x_array_randomread _x;
 
597
  const typename ArrayTypes<DeviceType>::t_tagint_1d _tag;
 
598
  const typename ArrayTypes<DeviceType>::t_int_1d _type;
 
599
  const typename ArrayTypes<DeviceType>::t_int_1d _mask;
 
600
  X_FLOAT _dx,_dy,_dz;
 
601
 
 
602
  AtomVecAtomicKokkos_PackBorder(
 
603
      const typename ArrayTypes<DeviceType>::t_xfloat_2d &buf,
 
604
      const typename ArrayTypes<DeviceType>::t_int_2d_const &list,
 
605
      const int & iswap,
 
606
      const typename ArrayTypes<DeviceType>::t_x_array &x,
 
607
      const typename ArrayTypes<DeviceType>::t_tagint_1d &tag,
 
608
      const typename ArrayTypes<DeviceType>::t_int_1d &type,
 
609
      const typename ArrayTypes<DeviceType>::t_int_1d &mask,
 
610
      const X_FLOAT &dx, const X_FLOAT &dy, const X_FLOAT &dz):
 
611
      _buf(buf),_list(list),_iswap(iswap),
 
612
      _x(x),_tag(tag),_type(type),_mask(mask),
 
613
      _dx(dx),_dy(dy),_dz(dz) {}
 
614
 
 
615
  KOKKOS_INLINE_FUNCTION
 
616
  void operator() (const int& i) const {
 
617
      const int j = _list(_iswap,i);
 
618
      if (PBC_FLAG == 0) {
 
619
          _buf(i,0) = _x(j,0);
 
620
          _buf(i,1) = _x(j,1);
 
621
          _buf(i,2) = _x(j,2);
 
622
          _buf(i,3) = _tag(j);
 
623
          _buf(i,4) = _type(j);
 
624
          _buf(i,5) = _mask(j);
 
625
      } else {
 
626
          _buf(i,0) = _x(j,0) + _dx;
 
627
          _buf(i,1) = _x(j,1) + _dy;
 
628
          _buf(i,2) = _x(j,2) + _dz;
 
629
          _buf(i,3) = _tag(j);
 
630
          _buf(i,4) = _type(j);
 
631
          _buf(i,5) = _mask(j);
 
632
      }
 
633
  }
 
634
};
 
635
 
 
636
/* ---------------------------------------------------------------------- */
 
637
 
 
638
int AtomVecAtomicKokkos::pack_border_kokkos(int n, DAT::tdual_int_2d k_sendlist, DAT::tdual_xfloat_2d buf,int iswap,
 
639
                               int pbc_flag, int *pbc, ExecutionSpace space)
 
640
{
 
641
  X_FLOAT dx,dy,dz;
 
642
 
 
643
  if (pbc_flag != 0) {
 
644
    if (domain->triclinic == 0) {
 
645
      dx = pbc[0]*domain->xprd;
 
646
      dy = pbc[1]*domain->yprd;
 
647
      dz = pbc[2]*domain->zprd;
 
648
    } else {
 
649
      dx = pbc[0];
 
650
      dy = pbc[1];
 
651
      dz = pbc[2];
 
652
    }
 
653
    if(space==Host) {
 
654
      AtomVecAtomicKokkos_PackBorder<LMPHostType,1> f(
 
655
        buf.view<LMPHostType>(), k_sendlist.view<LMPHostType>(),
 
656
        iswap,h_x,h_tag,h_type,h_mask,dx,dy,dz);
 
657
      Kokkos::parallel_for(n,f);
 
658
      LMPHostType::fence();
 
659
    } else {
 
660
      AtomVecAtomicKokkos_PackBorder<LMPDeviceType,1> f(
 
661
        buf.view<LMPDeviceType>(), k_sendlist.view<LMPDeviceType>(),
 
662
        iswap,d_x,d_tag,d_type,d_mask,dx,dy,dz);
 
663
      Kokkos::parallel_for(n,f);
 
664
      LMPDeviceType::fence();
 
665
    }
 
666
 
 
667
  } else {
 
668
    dx = dy = dz = 0;
 
669
    if(space==Host) {
 
670
      AtomVecAtomicKokkos_PackBorder<LMPHostType,0> f(
 
671
        buf.view<LMPHostType>(), k_sendlist.view<LMPHostType>(),
 
672
        iswap,h_x,h_tag,h_type,h_mask,dx,dy,dz);
 
673
      Kokkos::parallel_for(n,f);
 
674
      LMPHostType::fence();
 
675
    } else {
 
676
      AtomVecAtomicKokkos_PackBorder<LMPDeviceType,0> f(
 
677
        buf.view<LMPDeviceType>(), k_sendlist.view<LMPDeviceType>(),
 
678
        iswap,d_x,d_tag,d_type,d_mask,dx,dy,dz);
 
679
      Kokkos::parallel_for(n,f);
 
680
      LMPDeviceType::fence();
 
681
    }
 
682
  }
 
683
  return n*6;
 
684
}
 
685
 
 
686
/* ---------------------------------------------------------------------- */
 
687
 
 
688
int AtomVecAtomicKokkos::pack_border(int n, int *list, double *buf,
 
689
                               int pbc_flag, int *pbc)
 
690
{
 
691
  int i,j,m;
 
692
  double dx,dy,dz;
 
693
 
 
694
  m = 0;
 
695
  if (pbc_flag == 0) {
 
696
    for (i = 0; i < n; i++) {
 
697
      j = list[i];
 
698
      buf[m++] = h_x(j,0);
 
699
      buf[m++] = h_x(j,1);
 
700
      buf[m++] = h_x(j,2);
 
701
      buf[m++] = ubuf(h_tag(j)).d;
 
702
      buf[m++] = ubuf(h_type(j)).d;
 
703
      buf[m++] = ubuf(h_mask(j)).d;
 
704
    }
 
705
  } else {
 
706
    if (domain->triclinic == 0) {
 
707
      dx = pbc[0]*domain->xprd;
 
708
      dy = pbc[1]*domain->yprd;
 
709
      dz = pbc[2]*domain->zprd;
 
710
    } else {
 
711
      dx = pbc[0];
 
712
      dy = pbc[1];
 
713
      dz = pbc[2];
 
714
    }
 
715
    for (i = 0; i < n; i++) {
 
716
      j = list[i];
 
717
      buf[m++] = h_x(j,0) + dx;
 
718
      buf[m++] = h_x(j,1) + dy;
 
719
      buf[m++] = h_x(j,2) + dz;
 
720
      buf[m++] = ubuf(h_tag(j)).d;
 
721
      buf[m++] = ubuf(h_type(j)).d;
 
722
      buf[m++] = ubuf(h_mask(j)).d;
 
723
    }
 
724
  }
 
725
 
 
726
  if (atom->nextra_border)
 
727
    for (int iextra = 0; iextra < atom->nextra_border; iextra++)
 
728
      m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]);
 
729
 
 
730
  return m;
 
731
}
 
732
 
 
733
/* ---------------------------------------------------------------------- */
 
734
 
 
735
int AtomVecAtomicKokkos::pack_border_vel(int n, int *list, double *buf,
 
736
                                   int pbc_flag, int *pbc)
 
737
{
 
738
  int i,j,m;
 
739
  double dx,dy,dz,dvx,dvy,dvz;
 
740
 
 
741
  m = 0;
 
742
  if (pbc_flag == 0) {
 
743
    for (i = 0; i < n; i++) {
 
744
      j = list[i];
 
745
      buf[m++] = h_x(j,0);
 
746
      buf[m++] = h_x(j,1);
 
747
      buf[m++] = h_x(j,2);
 
748
      buf[m++] = ubuf(h_tag(j)).d;
 
749
      buf[m++] = ubuf(h_type(j)).d;
 
750
      buf[m++] = ubuf(h_mask(j)).d;
 
751
      buf[m++] = h_v(j,0);
 
752
      buf[m++] = h_v(j,1);
 
753
      buf[m++] = h_v(j,2);
 
754
    }
 
755
  } else {
 
756
    if (domain->triclinic == 0) {
 
757
      dx = pbc[0]*domain->xprd;
 
758
      dy = pbc[1]*domain->yprd;
 
759
      dz = pbc[2]*domain->zprd;
 
760
    } else {
 
761
      dx = pbc[0];
 
762
      dy = pbc[1];
 
763
      dz = pbc[2];
 
764
    }
 
765
    if (!deform_vremap) {
 
766
      for (i = 0; i < n; i++) {
 
767
        j = list[i];
 
768
        buf[m++] = h_x(j,0) + dx;
 
769
        buf[m++] = h_x(j,1) + dy;
 
770
        buf[m++] = h_x(j,2) + dz;
 
771
        buf[m++] = ubuf(h_tag(j)).d;
 
772
        buf[m++] = ubuf(h_type(j)).d;
 
773
        buf[m++] = ubuf(h_mask(j)).d;
 
774
        buf[m++] = h_v(j,0);
 
775
        buf[m++] = h_v(j,1);
 
776
        buf[m++] = h_v(j,2);
 
777
      }
 
778
    } else {
 
779
      dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
 
780
      dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
 
781
      dvz = pbc[2]*h_rate[2];
 
782
      for (i = 0; i < n; i++) {
 
783
        j = list[i];
 
784
        buf[m++] = h_x(j,0) + dx;
 
785
        buf[m++] = h_x(j,1) + dy;
 
786
        buf[m++] = h_x(j,2) + dz;
 
787
        buf[m++] = ubuf(h_tag(j)).d;
 
788
        buf[m++] = ubuf(h_type(j)).d;
 
789
        buf[m++] = ubuf(h_mask(j)).d;
 
790
        if (mask[i] & deform_groupbit) {
 
791
          buf[m++] = h_v(j,0) + dvx;
 
792
          buf[m++] = h_v(j,1) + dvy;
 
793
          buf[m++] = h_v(j,2) + dvz;
 
794
        } else {
 
795
          buf[m++] = h_v(j,0);
 
796
          buf[m++] = h_v(j,1);
 
797
          buf[m++] = h_v(j,2);
 
798
        }
 
799
      }
 
800
    }
 
801
  }
 
802
 
 
803
  if (atom->nextra_border)
 
804
    for (int iextra = 0; iextra < atom->nextra_border; iextra++)
 
805
      m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]);
 
806
 
 
807
  return m;
 
808
}
 
809
 
 
810
/* ---------------------------------------------------------------------- */
 
811
 
 
812
template<class DeviceType>
 
813
struct AtomVecAtomicKokkos_UnpackBorder {
 
814
  typedef DeviceType device_type;
 
815
 
 
816
  const typename ArrayTypes<DeviceType>::t_xfloat_2d_const _buf;
 
817
  typename ArrayTypes<DeviceType>::t_x_array _x;
 
818
  typename ArrayTypes<DeviceType>::t_tagint_1d _tag;
 
819
  typename ArrayTypes<DeviceType>::t_int_1d _type;
 
820
  typename ArrayTypes<DeviceType>::t_int_1d _mask;
 
821
  int _first;
 
822
 
 
823
 
 
824
  AtomVecAtomicKokkos_UnpackBorder(
 
825
      const typename ArrayTypes<DeviceType>::t_xfloat_2d_const &buf,
 
826
      typename ArrayTypes<DeviceType>::t_x_array &x,
 
827
      typename ArrayTypes<DeviceType>::t_tagint_1d &tag,
 
828
      typename ArrayTypes<DeviceType>::t_int_1d &type,
 
829
      typename ArrayTypes<DeviceType>::t_int_1d &mask,
 
830
      const int& first):
 
831
      _buf(buf),_x(x),_tag(tag),_type(type),_mask(mask),_first(first){
 
832
  };
 
833
 
 
834
  KOKKOS_INLINE_FUNCTION
 
835
  void operator() (const int& i) const {
 
836
      _x(i+_first,0) = _buf(i,0);
 
837
      _x(i+_first,1) = _buf(i,1);
 
838
      _x(i+_first,2) = _buf(i,2);
 
839
      _tag(i+_first) = static_cast<int> (_buf(i,3));
 
840
      _type(i+_first) = static_cast<int>  (_buf(i,4));
 
841
      _mask(i+_first) = static_cast<int>  (_buf(i,5));
 
842
//      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));
 
843
  }
 
844
};
 
845
 
 
846
/* ---------------------------------------------------------------------- */
 
847
 
 
848
void AtomVecAtomicKokkos::unpack_border_kokkos(const int &n, const int &first,
 
849
                     const DAT::tdual_xfloat_2d &buf,ExecutionSpace space) {
 
850
  modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK);
 
851
  while (first+n >= nmax) grow(0);
 
852
  modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK);
 
853
  if(space==Host) {
 
854
    struct AtomVecAtomicKokkos_UnpackBorder<LMPHostType> f(buf.view<LMPHostType>(),h_x,h_tag,h_type,h_mask,first);
 
855
    Kokkos::parallel_for(n,f);
 
856
    LMPHostType::fence();
 
857
  } else {
 
858
    struct AtomVecAtomicKokkos_UnpackBorder<LMPDeviceType> f(buf.view<LMPDeviceType>(),d_x,d_tag,d_type,d_mask,first);
 
859
    Kokkos::parallel_for(n,f);
 
860
    LMPDeviceType::fence();
 
861
  }
 
862
}
 
863
 
 
864
/* ---------------------------------------------------------------------- */
 
865
 
 
866
void AtomVecAtomicKokkos::unpack_border(int n, int first, double *buf)
 
867
{
 
868
  int i,m,last;
 
869
 
 
870
  m = 0;
 
871
  last = first + n;
 
872
  for (i = first; i < last; i++) {
 
873
    if (i == nmax) grow(0);
 
874
    modified(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK);
 
875
    h_x(i,0) = buf[m++];
 
876
    h_x(i,1) = buf[m++];
 
877
    h_x(i,2) = buf[m++];
 
878
    h_tag(i) =  (tagint)  ubuf(buf[m++]).i;
 
879
    h_type(i) = (int) ubuf(buf[m++]).i;
 
880
    h_mask(i) = (int) ubuf(buf[m++]).i;
 
881
  }
 
882
 
 
883
  if (atom->nextra_border)
 
884
    for (int iextra = 0; iextra < atom->nextra_border; iextra++)
 
885
      m += modify->fix[atom->extra_border[iextra]]->
 
886
        unpack_border(n,first,&buf[m]);
 
887
}
 
888
 
 
889
/* ---------------------------------------------------------------------- */
 
890
 
 
891
void AtomVecAtomicKokkos::unpack_border_vel(int n, int first, double *buf)
 
892
{
 
893
  int i,m,last;
 
894
 
 
895
  m = 0;
 
896
  last = first + n;
 
897
  for (i = first; i < last; i++) {
 
898
    if (i == nmax) grow(0);
 
899
    h_x(i,0) = buf[m++];
 
900
    h_x(i,1) = buf[m++];
 
901
    h_x(i,2) = buf[m++];
 
902
    h_tag(i) =  (tagint)  ubuf(buf[m++]).i;
 
903
    h_type(i) = (int) ubuf(buf[m++]).i;
 
904
    h_mask(i) = (int) ubuf(buf[m++]).i;
 
905
    h_v(i,0) = buf[m++];
 
906
    h_v(i,1) = buf[m++];
 
907
    h_v(i,2) = buf[m++];
 
908
  }
 
909
 
 
910
  if (atom->nextra_border)
 
911
    for (int iextra = 0; iextra < atom->nextra_border; iextra++)
 
912
      m += modify->fix[atom->extra_border[iextra]]->
 
913
        unpack_border(n,first,&buf[m]);
 
914
}
 
915
 
 
916
/* ---------------------------------------------------------------------- */
 
917
 
 
918
template<class DeviceType>
 
919
struct AtomVecAtomicKokkos_PackExchangeFunctor {
 
920
  typedef DeviceType device_type;
 
921
  typedef ArrayTypes<DeviceType> AT;
 
922
  typename AT::t_x_array_randomread _x;
 
923
  typename AT::t_v_array_randomread _v;
 
924
  typename AT::t_tagint_1d_randomread _tag;
 
925
  typename AT::t_int_1d_randomread _type;
 
926
  typename AT::t_int_1d_randomread _mask;
 
927
  typename AT::t_imageint_1d_randomread _image;
 
928
  typename AT::t_x_array _xw;
 
929
  typename AT::t_v_array _vw;
 
930
  typename AT::t_tagint_1d _tagw;
 
931
  typename AT::t_int_1d _typew;
 
932
  typename AT::t_int_1d _maskw;
 
933
  typename AT::t_imageint_1d _imagew;
 
934
 
 
935
  typename AT::t_xfloat_2d_um _buf;
 
936
  typename AT::t_int_1d_const _sendlist;
 
937
  typename AT::t_int_1d_const _copylist;
 
938
  int _nlocal,_dim;
 
939
  X_FLOAT _lo,_hi;
 
940
 
 
941
  AtomVecAtomicKokkos_PackExchangeFunctor(
 
942
      const AtomKokkos* atom,
 
943
      const typename AT::tdual_xfloat_2d buf,
 
944
      typename AT::tdual_int_1d sendlist,
 
945
      typename AT::tdual_int_1d copylist,int nlocal, int dim,
 
946
                X_FLOAT lo, X_FLOAT hi):
 
947
                _x(atom->k_x.view<DeviceType>()),
 
948
                _v(atom->k_v.view<DeviceType>()),
 
949
                _tag(atom->k_tag.view<DeviceType>()),
 
950
                _type(atom->k_type.view<DeviceType>()),
 
951
                _mask(atom->k_mask.view<DeviceType>()),
 
952
                _image(atom->k_image.view<DeviceType>()),
 
953
                _xw(atom->k_x.view<DeviceType>()),
 
954
                _vw(atom->k_v.view<DeviceType>()),
 
955
                _tagw(atom->k_tag.view<DeviceType>()),
 
956
                _typew(atom->k_type.view<DeviceType>()),
 
957
                _maskw(atom->k_mask.view<DeviceType>()),
 
958
                _imagew(atom->k_image.view<DeviceType>()),
 
959
                _sendlist(sendlist.template view<DeviceType>()),
 
960
                _copylist(copylist.template view<DeviceType>()),
 
961
                _nlocal(nlocal),_dim(dim),
 
962
                _lo(lo),_hi(hi){
 
963
    const size_t elements = 11;
 
964
    const int maxsendlist = (buf.template view<DeviceType>().dimension_0()*buf.template view<DeviceType>().dimension_1())/elements;
 
965
 
 
966
    buffer_view<DeviceType>(_buf,buf,maxsendlist,elements);
 
967
  }
 
968
 
 
969
  KOKKOS_INLINE_FUNCTION
 
970
  void operator() (const int &mysend) const {
 
971
    const int i = _sendlist(mysend);
 
972
    _buf(mysend,0) = 11;
 
973
    _buf(mysend,1) = _x(i,0);
 
974
    _buf(mysend,2) = _x(i,1);
 
975
    _buf(mysend,3) = _x(i,2);
 
976
    _buf(mysend,4) = _v(i,0);
 
977
    _buf(mysend,5) = _v(i,1);
 
978
    _buf(mysend,6) = _v(i,2);
 
979
    _buf(mysend,7) = _tag[i];
 
980
    _buf(mysend,8) = _type[i];
 
981
    _buf(mysend,9) = _mask[i];
 
982
    _buf(mysend,10) = _image[i];
 
983
    const int j = _copylist(mysend);
 
984
 
 
985
    if(j>-1) {
 
986
    _xw(i,0) = _x(j,0);
 
987
    _xw(i,1) = _x(j,1);
 
988
    _xw(i,2) = _x(j,2);
 
989
    _vw(i,0) = _v(j,0);
 
990
    _vw(i,1) = _v(j,1);
 
991
    _vw(i,2) = _v(j,2);
 
992
    _tagw[i] = _tag(j);
 
993
    _typew[i] = _type(j);
 
994
    _maskw[i] = _mask(j);
 
995
    _imagew[i] = _image(j);
 
996
    }
 
997
  }
 
998
};
 
999
 
 
1000
/* ---------------------------------------------------------------------- */
 
1001
 
 
1002
int AtomVecAtomicKokkos::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 )
 
1003
{
 
1004
  if(nsend > (int) (k_buf.view<LMPHostType>().dimension_0()*k_buf.view<LMPHostType>().dimension_1())/11) {
 
1005
    int newsize = nsend*11/k_buf.view<LMPHostType>().dimension_1()+1;
 
1006
    k_buf.resize(newsize,k_buf.view<LMPHostType>().dimension_1());
 
1007
  }
 
1008
  if(space == Host) {
 
1009
    AtomVecAtomicKokkos_PackExchangeFunctor<LMPHostType> f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi);
 
1010
    Kokkos::parallel_for(nsend,f);
 
1011
    LMPHostType::fence();
 
1012
    return nsend*11;
 
1013
  } else {
 
1014
    AtomVecAtomicKokkos_PackExchangeFunctor<LMPDeviceType> f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi);
 
1015
    Kokkos::parallel_for(nsend,f);
 
1016
    LMPDeviceType::fence();
 
1017
    return nsend*11;
 
1018
  }
 
1019
}
 
1020
 
 
1021
/* ---------------------------------------------------------------------- */
 
1022
 
 
1023
int AtomVecAtomicKokkos::pack_exchange(int i, double *buf)
 
1024
{
 
1025
  int m = 1;
 
1026
  buf[m++] = h_x(i,0);
 
1027
  buf[m++] = h_x(i,1);
 
1028
  buf[m++] = h_x(i,2);
 
1029
  buf[m++] = h_v(i,0);
 
1030
  buf[m++] = h_v(i,1);
 
1031
  buf[m++] = h_v(i,2);
 
1032
  buf[m++] = ubuf(h_tag(i)).d;
 
1033
  buf[m++] = ubuf(h_type(i)).d;
 
1034
  buf[m++] = ubuf(h_mask(i)).d;
 
1035
  buf[m++] = ubuf(h_image(i)).d;
 
1036
 
 
1037
  if (atom->nextra_grow)
 
1038
    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
 
1039
      m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
1040
 
 
1041
  buf[0] = m;
 
1042
  return m;
 
1043
}
 
1044
 
 
1045
/* ---------------------------------------------------------------------- */
 
1046
 
 
1047
template<class DeviceType>
 
1048
struct AtomVecAtomicKokkos_UnpackExchangeFunctor {
 
1049
  typedef DeviceType device_type;
 
1050
  typedef ArrayTypes<DeviceType> AT;
 
1051
  typename AT::t_x_array _x;
 
1052
  typename AT::t_v_array _v;
 
1053
  typename AT::t_tagint_1d _tag;
 
1054
  typename AT::t_int_1d _type;
 
1055
  typename AT::t_int_1d _mask;
 
1056
  typename AT::t_imageint_1d _image;
 
1057
 
 
1058
  typename AT::t_xfloat_2d_um _buf;
 
1059
  typename AT::t_int_1d _nlocal;
 
1060
  int _dim;
 
1061
  X_FLOAT _lo,_hi;
 
1062
 
 
1063
  AtomVecAtomicKokkos_UnpackExchangeFunctor(
 
1064
      const AtomKokkos* atom,
 
1065
      const typename AT::tdual_xfloat_2d buf,
 
1066
      typename AT::tdual_int_1d nlocal,
 
1067
      int dim, X_FLOAT lo, X_FLOAT hi):
 
1068
                _x(atom->k_x.view<DeviceType>()),
 
1069
                _v(atom->k_v.view<DeviceType>()),
 
1070
                _tag(atom->k_tag.view<DeviceType>()),
 
1071
                _type(atom->k_type.view<DeviceType>()),
 
1072
                _mask(atom->k_mask.view<DeviceType>()),
 
1073
                _image(atom->k_image.view<DeviceType>()),
 
1074
                _nlocal(nlocal.template view<DeviceType>()),_dim(dim),
 
1075
                _lo(lo),_hi(hi){
 
1076
    const size_t elements = 11;
 
1077
    const int maxsendlist = (buf.template view<DeviceType>().dimension_0()*buf.template view<DeviceType>().dimension_1())/elements;
 
1078
 
 
1079
    buffer_view<DeviceType>(_buf,buf,maxsendlist,elements);
 
1080
  }
 
1081
 
 
1082
  KOKKOS_INLINE_FUNCTION
 
1083
  void operator() (const int &myrecv) const {
 
1084
    X_FLOAT x = _buf(myrecv,_dim+1);
 
1085
    if (x >= _lo && x < _hi) {
 
1086
      int i = Kokkos::atomic_fetch_add(&_nlocal(0),1);
 
1087
      _x(i,0) = _buf(myrecv,1);
 
1088
      _x(i,1) = _buf(myrecv,2);
 
1089
      _x(i,2) = _buf(myrecv,3);
 
1090
      _v(i,0) = _buf(myrecv,4);
 
1091
      _v(i,1) = _buf(myrecv,5);
 
1092
      _v(i,2) = _buf(myrecv,6);
 
1093
      _tag[i] = _buf(myrecv,7);
 
1094
      _type[i] = _buf(myrecv,8);
 
1095
      _mask[i] = _buf(myrecv,9);
 
1096
      _image[i] = _buf(myrecv,10);
 
1097
    }
 
1098
  }
 
1099
};
 
1100
 
 
1101
/* ---------------------------------------------------------------------- */
 
1102
 
 
1103
int AtomVecAtomicKokkos::unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,int nrecv,int nlocal,int dim,X_FLOAT lo,X_FLOAT hi,ExecutionSpace space) {
 
1104
  if(space == Host) {
 
1105
    k_count.h_view(0) = nlocal;
 
1106
    AtomVecAtomicKokkos_UnpackExchangeFunctor<LMPHostType> f(atomKK,k_buf,k_count,dim,lo,hi);
 
1107
    Kokkos::parallel_for(nrecv/11,f);
 
1108
    LMPHostType::fence();
 
1109
    return k_count.h_view(0);
 
1110
  } else {
 
1111
    k_count.h_view(0) = nlocal;
 
1112
    k_count.modify<LMPHostType>();
 
1113
    k_count.sync<LMPDeviceType>();
 
1114
    AtomVecAtomicKokkos_UnpackExchangeFunctor<LMPDeviceType> f(atomKK,k_buf,k_count,dim,lo,hi);
 
1115
    Kokkos::parallel_for(nrecv/11,f);
 
1116
    LMPDeviceType::fence();
 
1117
    k_count.modify<LMPDeviceType>();
 
1118
    k_count.sync<LMPHostType>();
 
1119
 
 
1120
    return k_count.h_view(0);
 
1121
  }
 
1122
}
 
1123
 
 
1124
/* ---------------------------------------------------------------------- */
 
1125
 
 
1126
int AtomVecAtomicKokkos::unpack_exchange(double *buf)
 
1127
{
 
1128
  int nlocal = atom->nlocal;
 
1129
  if (nlocal == nmax) grow(0);
 
1130
  modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | 
 
1131
           MASK_MASK | IMAGE_MASK);
 
1132
 
 
1133
  int m = 1;
 
1134
  h_x(nlocal,0) = buf[m++];
 
1135
  h_x(nlocal,1) = buf[m++];
 
1136
  h_x(nlocal,2) = buf[m++];
 
1137
  h_v(nlocal,0) = buf[m++];
 
1138
  h_v(nlocal,1) = buf[m++];
 
1139
  h_v(nlocal,2) = buf[m++];
 
1140
  h_tag(nlocal) = (tagint) ubuf(buf[m++]).i;
 
1141
  h_type(nlocal) = (int) ubuf(buf[m++]).i;
 
1142
  h_mask(nlocal) = (int) ubuf(buf[m++]).i;
 
1143
  h_image(nlocal) = (imageint) ubuf(buf[m++]).i;
 
1144
 
 
1145
  if (atom->nextra_grow)
 
1146
    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
 
1147
      m += modify->fix[atom->extra_grow[iextra]]->
 
1148
        unpack_exchange(nlocal,&buf[m]);
 
1149
 
 
1150
  atom->nlocal++;
 
1151
  return m;
 
1152
}
 
1153
 
 
1154
/* ----------------------------------------------------------------------
 
1155
   size of restart data for all atoms owned by this proc
 
1156
   include extra data stored by fixes
 
1157
------------------------------------------------------------------------- */
 
1158
 
 
1159
int AtomVecAtomicKokkos::size_restart()
 
1160
{
 
1161
  int i;
 
1162
 
 
1163
  int nlocal = atom->nlocal;
 
1164
  int n = 11 * nlocal;
 
1165
 
 
1166
  if (atom->nextra_restart)
 
1167
    for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
 
1168
      for (i = 0; i < nlocal; i++)
 
1169
        n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
1170
 
 
1171
  return n;
 
1172
}
 
1173
 
 
1174
/* ----------------------------------------------------------------------
 
1175
   pack atom I's data for restart file including extra quantities
 
1176
   xyz must be 1st 3 values, so that read_restart can test on them
 
1177
   molecular types may be negative, but write as positive
 
1178
------------------------------------------------------------------------- */
 
1179
 
 
1180
int AtomVecAtomicKokkos::pack_restart(int i, double *buf)
 
1181
{
 
1182
  int m = 1;
 
1183
  buf[m++] = h_x(i,0);
 
1184
  buf[m++] = h_x(i,1);
 
1185
  buf[m++] = h_x(i,2);
 
1186
  buf[m++] = ubuf(h_tag(i)).d;
 
1187
  buf[m++] = ubuf(h_type(i)).d;
 
1188
  buf[m++] = ubuf(h_mask(i)).d;
 
1189
  buf[m++] = ubuf(h_image(i)).d;
 
1190
  buf[m++] = h_v(i,0);
 
1191
  buf[m++] = h_v(i,1);
 
1192
  buf[m++] = h_v(i,2);
 
1193
 
 
1194
  if (atom->nextra_restart)
 
1195
    for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
 
1196
      m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
1197
 
 
1198
  buf[0] = m;
 
1199
  return m;
 
1200
}
 
1201
 
 
1202
/* ----------------------------------------------------------------------
 
1203
   unpack data for one atom from restart file including extra quantities
 
1204
------------------------------------------------------------------------- */
 
1205
 
 
1206
int AtomVecAtomicKokkos::unpack_restart(double *buf)
 
1207
{
 
1208
  int nlocal = atom->nlocal;
 
1209
  if (nlocal == nmax) {
 
1210
    grow(0);
 
1211
    if (atom->nextra_store)
 
1212
      memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra");
 
1213
  }
 
1214
 
 
1215
  int m = 1;
 
1216
  h_x(nlocal,0) = buf[m++];
 
1217
  h_x(nlocal,1) = buf[m++];
 
1218
  h_x(nlocal,2) = buf[m++];
 
1219
  h_tag(nlocal) = (tagint) ubuf(buf[m++]).i;
 
1220
  h_type(nlocal) = (int) ubuf(buf[m++]).i;
 
1221
  h_mask(nlocal) = (int) ubuf(buf[m++]).i;
 
1222
  h_image(nlocal) = (imageint) ubuf(buf[m++]).i;
 
1223
  h_v(nlocal,0) = buf[m++];
 
1224
  h_v(nlocal,1) = buf[m++];
 
1225
  h_v(nlocal,2) = buf[m++];
 
1226
 
 
1227
  double **extra = atom->extra;
 
1228
  if (atom->nextra_store) {
 
1229
    int size = static_cast<int> (ubuf(buf[m++]).i) - m;
 
1230
    for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
 
1231
  }
 
1232
 
 
1233
  atom->nlocal++;
 
1234
  return m;
 
1235
}
 
1236
 
 
1237
/* ----------------------------------------------------------------------
 
1238
   create one atom of itype at coord
 
1239
   set other values to defaults
 
1240
------------------------------------------------------------------------- */
 
1241
 
 
1242
void AtomVecAtomicKokkos::create_atom(int itype, double *coord)
 
1243
{
 
1244
  int nlocal = atom->nlocal;
 
1245
  if (nlocal == nmax) {
 
1246
    //if(nlocal>2) printf("typeA: %i %i\n",type[0],type[1]);
 
1247
    atomKK->modified(Host,ALL_MASK);
 
1248
    grow(0);
 
1249
    //if(nlocal>2) printf("typeB: %i %i\n",type[0],type[1]);
 
1250
  }
 
1251
  atomKK->modified(Host,ALL_MASK);
 
1252
 
 
1253
  tag[nlocal] = 0;
 
1254
  type[nlocal] = itype;
 
1255
  h_x(nlocal,0) = coord[0];
 
1256
  h_x(nlocal,1) = coord[1];
 
1257
  h_x(nlocal,2) = coord[2];
 
1258
  h_mask[nlocal] = 1;
 
1259
  h_image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
 
1260
    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
 
1261
  h_v(nlocal,0) = 0.0;
 
1262
  h_v(nlocal,1) = 0.0;
 
1263
  h_v(nlocal,2) = 0.0;
 
1264
 
 
1265
  atom->nlocal++;
 
1266
}
 
1267
 
 
1268
/* ----------------------------------------------------------------------
 
1269
   unpack one line from Atoms section of data file
 
1270
   initialize other atom quantities
 
1271
------------------------------------------------------------------------- */
 
1272
 
 
1273
void AtomVecAtomicKokkos::data_atom(double *coord, tagint imagetmp, 
 
1274
                                    char **values)
 
1275
{
 
1276
  int nlocal = atom->nlocal;
 
1277
  if (nlocal == nmax) grow(0);
 
1278
 
 
1279
  h_tag[nlocal] = atoi(values[0]);
 
1280
  h_type[nlocal] = atoi(values[1]);
 
1281
  if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
 
1282
    error->one(FLERR,"Invalid atom type in Atoms section of data file");
 
1283
 
 
1284
  h_x(nlocal,0) = coord[0];
 
1285
  h_x(nlocal,1) = coord[1];
 
1286
  h_x(nlocal,2) = coord[2];
 
1287
 
 
1288
  h_image[nlocal] = imagetmp;
 
1289
 
 
1290
  h_mask[nlocal] = 1;
 
1291
  h_v(nlocal,0) = 0.0;
 
1292
  h_v(nlocal,1) = 0.0;
 
1293
  h_v(nlocal,2) = 0.0;
 
1294
 
 
1295
  atom->nlocal++;
 
1296
}
 
1297
 
 
1298
/* ----------------------------------------------------------------------
 
1299
   pack atom info for data file including 3 image flags
 
1300
------------------------------------------------------------------------- */
 
1301
 
 
1302
void AtomVecAtomicKokkos::pack_data(double **buf)
 
1303
{
 
1304
  int nlocal = atom->nlocal;
 
1305
  for (int i = 0; i < nlocal; i++) {
 
1306
    buf[i][0] = h_tag[i];
 
1307
    buf[i][1] = h_type[i];
 
1308
    buf[i][2] = h_x(i,0);
 
1309
    buf[i][3] = h_x(i,1);
 
1310
    buf[i][4] = h_x(i,2);
 
1311
    buf[i][5] = (h_image[i] & IMGMASK) - IMGMAX;
 
1312
    buf[i][6] = (h_image[i] >> IMGBITS & IMGMASK) - IMGMAX;
 
1313
    buf[i][7] = (h_image[i] >> IMG2BITS) - IMGMAX;
 
1314
  }
 
1315
}
 
1316
 
 
1317
/* ----------------------------------------------------------------------
 
1318
   write atom info to data file including 3 image flags
 
1319
------------------------------------------------------------------------- */
 
1320
 
 
1321
void AtomVecAtomicKokkos::write_data(FILE *fp, int n, double **buf)
 
1322
{
 
1323
  for (int i = 0; i < n; i++)
 
1324
    fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %d %d %d\n",
 
1325
            (int) buf[i][0],(int) buf[i][1],buf[i][2],buf[i][3],buf[i][4],
 
1326
            (int) buf[i][5],(int) buf[i][6],(int) buf[i][7]);
 
1327
}
 
1328
 
 
1329
/* ----------------------------------------------------------------------
 
1330
   return # of bytes of allocated memory
 
1331
------------------------------------------------------------------------- */
 
1332
 
 
1333
bigint AtomVecAtomicKokkos::memory_usage()
 
1334
{
 
1335
  bigint bytes = 0;
 
1336
 
 
1337
  if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
 
1338
  if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
 
1339
  if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
 
1340
  if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
 
1341
  if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
 
1342
  if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
 
1343
  if (atom->memcheck("f")) bytes += memory->usage(f,nmax*commKK->nthreads,3);
 
1344
 
 
1345
  return bytes;
 
1346
}
 
1347
 
 
1348
/* ---------------------------------------------------------------------- */
 
1349
 
 
1350
void AtomVecAtomicKokkos::sync(ExecutionSpace space, unsigned int mask)
 
1351
{
 
1352
  if (space == Device) {
 
1353
    if (mask & X_MASK) atomKK->k_x.sync<LMPDeviceType>();
 
1354
    if (mask & V_MASK) atomKK->k_v.sync<LMPDeviceType>();
 
1355
    if (mask & F_MASK) atomKK->k_f.sync<LMPDeviceType>();
 
1356
    if (mask & TAG_MASK) atomKK->k_tag.sync<LMPDeviceType>();
 
1357
    if (mask & TYPE_MASK) atomKK->k_type.sync<LMPDeviceType>();
 
1358
    if (mask & MASK_MASK) atomKK->k_mask.sync<LMPDeviceType>();
 
1359
    if (mask & IMAGE_MASK) atomKK->k_image.sync<LMPDeviceType>();
 
1360
  } else {
 
1361
    if (mask & X_MASK) atomKK->k_x.sync<LMPHostType>();
 
1362
    if (mask & V_MASK) atomKK->k_v.sync<LMPHostType>();
 
1363
    if (mask & F_MASK) atomKK->k_f.sync<LMPHostType>();
 
1364
    if (mask & TAG_MASK) atomKK->k_tag.sync<LMPHostType>();
 
1365
    if (mask & TYPE_MASK) atomKK->k_type.sync<LMPHostType>();
 
1366
    if (mask & MASK_MASK) atomKK->k_mask.sync<LMPHostType>();
 
1367
    if (mask & IMAGE_MASK) atomKK->k_image.sync<LMPHostType>();
 
1368
  }
 
1369
}
 
1370
 
 
1371
/* ---------------------------------------------------------------------- */
 
1372
 
 
1373
void AtomVecAtomicKokkos::modified(ExecutionSpace space, unsigned int mask)
 
1374
{
 
1375
  if (space == Device) {
 
1376
    if (mask & X_MASK) atomKK->k_x.modify<LMPDeviceType>();
 
1377
    if (mask & V_MASK) atomKK->k_v.modify<LMPDeviceType>();
 
1378
    if (mask & F_MASK) atomKK->k_f.modify<LMPDeviceType>();
 
1379
    if (mask & TAG_MASK) atomKK->k_tag.modify<LMPDeviceType>();
 
1380
    if (mask & TYPE_MASK) atomKK->k_type.modify<LMPDeviceType>();
 
1381
    if (mask & MASK_MASK) atomKK->k_mask.modify<LMPDeviceType>();
 
1382
    if (mask & IMAGE_MASK) atomKK->k_image.modify<LMPDeviceType>();
 
1383
  } else {
 
1384
    if (mask & X_MASK) atomKK->k_x.modify<LMPHostType>();
 
1385
    if (mask & V_MASK) atomKK->k_v.modify<LMPHostType>();
 
1386
    if (mask & F_MASK) atomKK->k_f.modify<LMPHostType>();
 
1387
    if (mask & TAG_MASK) atomKK->k_tag.modify<LMPHostType>();
 
1388
    if (mask & TYPE_MASK) atomKK->k_type.modify<LMPHostType>();
 
1389
    if (mask & MASK_MASK) atomKK->k_mask.modify<LMPHostType>();
 
1390
    if (mask & IMAGE_MASK) atomKK->k_image.modify<LMPHostType>();
 
1391
  }
 
1392
}