OpenFPM  5.2.0
Project that contain the implementation of distributed structures
vector_dist_operators_cuda.cuh
1 /*
2  * vector_dist_operators_cuda.cuh
3  *
4  * Created on: May 31, 2019
5  * Author: i-bird
6  */
7 
8 #ifndef VECTOR_DIST_OPERATORS_CUDA_CUH_
9 #define VECTOR_DIST_OPERATORS_CUDA_CUH_
10 
11 #include "Space/Shape/Point.hpp"
12 #include "util/cuda_util.hpp"
13 #include <utility>
14 
15 #ifdef SE_CLASS1
16 template<bool is_subset>
17 struct SubsetSelector_impl{
18  template<typename particle_type,typename subset_type>
19  static void check(particle_type &particles,subset_type &particle_subset)
20  {
21  }
22 };
23 
24 template<>
25 struct SubsetSelector_impl<true>
26 {
27  template<typename particle_type,typename subset_type>
28  static void check(particle_type &particles,subset_type &particle_subset){
29  //This getMapCtr needs to be created or fixed for cuda!
30  /* if(particles.getMapCtr()!=particle_subset.getUpdateCtr())
31  {
32  std::cerr<<__FILE__<<":"<<__LINE__<<" Error: You forgot a subset update after map."<<std::endl;
33  }*/
34  }
35 };
36 #endif
37 
45 template <typename vector, unsigned int prp>
47 {
48  typedef typename boost::mpl::at<typename vector::value_type::type, boost::mpl::int_<prp>>::type property_act;
49 
51  __device__ __host__ static inline auto value(vector & v, const vect_dist_key_dx & k) -> decltype(v.template getProp<prp>(k))
52  {
53  return v.template getProp<prp>(k);
54  }
55 
57  __device__ __host__ static inline auto value_type(vector && v, const vect_dist_key_dx & k) -> decltype(v.template getProp<prp>(k))
58  {
59  return v.template getProp<prp>(k);
60  }
61 };
62 
70 template <typename vector, unsigned int prp>
72 {
74  __device__ static inline auto value(vector & v, const unsigned int & k) -> decltype(v.template getProp<prp>(k))
75  {
76  return v.template getProp<prp>(k);
77  }
78 };
79 
80 
88 template <typename vector>
89 struct pos_or_propL<vector,POS_PROP>
90 {
91  typedef typename Point<vector::dims,typename vector::stype>::type_native property_act;
92 
93 #ifdef SE_CLASS3
94 
96  static inline auto value(vector & v, const vect_dist_key_dx & k) -> decltype(getExprL(v.getPos(k).getReference()))
97  {
98  return getExprL(v.getPos(k).getReference());
99  }
100 
101 #else
102 
104  __device__ __host__ static inline auto value(vector & v, const vect_dist_key_dx & k) -> decltype(ger<vector::dims,typename vector::stype>::getExprL(v.getPos(k)))
105  {
107  }
108 
110  static inline auto value_type(vector && v, const vect_dist_key_dx & k) -> decltype(v.getPos(k))
111  {
112  return v.getPos(k);
113  }
114 
115 #endif
116 };
117 
125 template <typename vector>
126 struct pos_or_propL_ker<vector,POS_PROP>
127 {
128 #ifdef SE_CLASS3
129 
131  static inline auto value(vector & v, const vect_dist_key_dx & k) -> decltype(getExprL(v.getPos(k).getReference()))
132  {
133  return getExprL(v.getPos(k).getReference());
134  }
135 
136 #else
137 
139  __device__ static inline auto value(vector & v, const unsigned int & k) -> decltype(ger<vector::dims,typename vector::stype>::getExprL(v.getPos(k)))
140  {
142  }
143 
144 #endif
145 };
146 
154 template <typename vector, unsigned int prp>
156 {
158  __device__ __host__ static inline auto value(vector & v, const vect_dist_key_dx & k) -> decltype(v.template getProp<prp>(k))
159  {
160  return v.template getProp<prp>(k);
161  }
162 
164  __device__ __host__ static inline auto value(vector & v, const unsigned int & k) -> decltype(v.template getProp<prp>(k))
165  {
166  return v.template getProp<prp>(k);
167  }
168 };
169 
170 
178 template <typename vector>
179 struct pos_or_propR<vector,POS_PROP>
180 {
182  __device__ __host__ static inline auto value(vector & v, const vect_dist_key_dx & k) -> decltype(ger<vector::dims,typename vector::stype>::getExprR(v.getPos(k)))
183  {
185  }
186 
188  __device__ __host__ static inline auto value(vector & v, const unsigned int & k) -> decltype(ger<vector::dims,typename vector::stype>::getExprR(v.getPos(k)))
189  {
191  }
192 };
193 
194 template<unsigned int prp, int impl>
196 {
197  template<typename vector, typename expr>
198  static void compute_expr(vector & v,expr & v_exp)
199  {}
200 
201  template<unsigned int n, typename vector, typename expr>
202  static void compute_expr_slice(vector & v,expr & v_exp, int (& comp)[n])
203  {}
204 
205  template<typename vector>
206  static void compute_const(vector & v,double d)
207  {}
208 };
209 
211 
212 template<unsigned int, bool is_valid>
214 {
215  template<typename exp_type>
216  __device__ __host__ inline static auto get(exp_type & o1, const vect_dist_key_dx & key) -> decltype(o1.value(vect_dist_key_dx(0)))
217  {
218  return o1.value(key);
219  }
220 
221  template<unsigned int prop, typename exp_type, typename vector_type>
222  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key)
223  {
225  }
226 
227  template<unsigned int prop, typename exp_type, typename vector_type>
228  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key)
229  {
231  }
232 
233  template<unsigned int prop, typename vector_type>
234  inline static void assign_double(double d, vector_type & v, const vect_dist_key_dx & key)
235  {
237  }
238 };
239 
240 template<>
242 {
243  template<typename exp_type>
244  __device__ __host__ static int get(exp_type & o1, const vect_dist_key_dx & key, const int (& comp)[1])
245  {
246  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
247  return 0;
248  }
249 
250  template<unsigned int prop, typename exp_type, typename vector_type>
251  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[1])
252  {
253  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
254  }
255 
256  template<unsigned int prop, typename exp_type, typename vector_type>
257  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const int (& comp)[1])
258  {
259  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
260  }
261 
262  template<unsigned int prop,typename exp_type, typename vector_type>
263  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const Point<1,int> & comp)
264  {
265  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
266  }
267 
268  template<unsigned int prop,typename exp_type, typename vector_type>
269  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const Point<1,int> & comp)
270  {
271  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
272  }
273 
274  template<unsigned int prop, typename vector_type>
275  inline static void assign_double(double d, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[1])
276  {
277  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
278  }
279 };
280 
281 template<>
283 {
284  template<typename exp_type>
285  __device__ __host__ static int get(exp_type & o1, const vect_dist_key_dx & key, const int (& comp)[2])
286  {
287  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
288  return 0;
289  }
290 
291  template<unsigned int prop, typename exp_type, typename vector_type>
292  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[2])
293  {
294  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
295  }
296 
297  template<unsigned int prop, typename exp_type, typename vector_type>
298  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const int (& comp)[2])
299  {
300  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
301  }
302 
303  template<unsigned int prop,typename exp_type, typename vector_type>
304  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const Point<2,int> & comp)
305  {
306  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
307  }
308 
309  template<unsigned int prop,typename exp_type, typename vector_type>
310  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const Point<2,int> & comp)
311  {
312  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
313  }
314 
315  template<unsigned int prop, typename vector_type>
316  inline static void assign_double(double d, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[2])
317  {
318  printf("ERROR: Slicer, the expression is incorrect, please check it\n");
319  }
320 };
321 
322 template<>
324 {
325  template<typename exp_type>
326  __device__ __host__ static auto get(exp_type & o1, const vect_dist_key_dx & key, const int (& comp)[1]) -> decltype(o1.value(vect_dist_key_dx(0))[0])
327  {
328  return o1.value(key)[comp[0]];
329  }
330 
331  template<unsigned int prop,typename exp_type, typename vector_type>
332  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[1])
333  {
334  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]] = o1.value(key);
335  }
336 
337  template<unsigned int prop,typename exp_type, typename vector_type>
338  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const int (& comp)[1])
339  {
340  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]] = o1.value(key);
341  }
342 
343  template<unsigned int prop,typename exp_type, typename vector_type>
344  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const Point<1,int> & comp)
345  {
346  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]] = o1.value(key);
347  }
348 
349  template<unsigned int prop,typename exp_type, typename vector_type>
350  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const Point<1,int> & comp)
351  {
352  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]] = o1.value(key);
353  }
354 
355  template<unsigned int prop, typename vector_type>
356  inline static void assign_double(double d, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[1])
357  {
358  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]] = d;
359  }
360 };
361 
362 template<>
364 {
365  template<typename exp_type>
366  __device__ __host__ static auto get(exp_type & o1, const vect_dist_key_dx & key, const int (& comp)[2]) -> decltype(o1.value(vect_dist_key_dx(0))[0][0])
367  {
368  return o1.value(key)[comp[0]][comp[1]];
369  }
370 
371  template<unsigned int prop,typename exp_type, typename vector_type>
372  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[2])
373  {
374  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]] = o1.value(key);
375  }
376 
377  template<unsigned int prop,typename exp_type, typename vector_type>
378  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const Point<2,int> & comp)
379  {
380  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]] = o1.value(key);
381  }
382 
383  template<unsigned int prop,typename exp_type, typename vector_type>
384  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const int (& comp)[2])
385  {
386  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]] = o1.value(key);
387  }
388 
389  template<unsigned int prop,typename exp_type, typename vector_type>
390  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const Point<2,int> & comp)
391  {
392  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]] = o1.value(key);
393  }
394 
395  template<unsigned int prop, typename vector_type>
396  inline static void assign_double(double d, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[2])
397  {
398  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]] = d;
399  }
400 };
401 
402 template<>
404 {
405  template<typename exp_type>
406  __device__ __host__ static auto get(exp_type & o1, const vect_dist_key_dx & key, const int (& comp)[3]) -> decltype(o1.value(vect_dist_key_dx(0))[0][0][0])
407  {
408  return o1.value(key)[comp[0]][comp[1]][comp[2]];
409  }
410 
411  template<unsigned int prop,typename exp_type, typename vector_type>
412  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[3])
413  {
414  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]][comp[2]] = o1.value(key);
415  }
416 
417  template<unsigned int prop,typename exp_type, typename vector_type>
418  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const Point<3,int> & comp)
419  {
420  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]][comp[2]] = o1.value(key);
421  }
422 
423  template<unsigned int prop,typename exp_type, typename vector_type>
424  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const int (& comp)[3])
425  {
426  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]][comp[2]] = o1.value(key);
427  }
428 
429  template<unsigned int prop,typename exp_type, typename vector_type>
430  __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const Point<3,int> & comp)
431  {
432  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]][comp[2]] = o1.value(key);
433  }
434 
435  template<unsigned int prop, typename vector_type>
436  inline static void assign_double(double d, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[3])
437  {
438  pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]][comp[2]] = d;
439  }
440 };
441 
443 
444 template<unsigned int prp>
445 struct vector_dist_op_compute_op<prp,comp_host>
446 {
447  template<typename vector, typename expr>
448  static void compute_expr(vector & v,expr & v_exp)
449  {
450  v_exp.init();
451 
452  auto it = v.getDomainIterator();
453 
454  while (it.isNext())
455  {
456  auto key = it.get();
457 
458  pos_or_propL<vector,prp>::value(v,key) = v_exp.value(key);
459 
460  ++it;
461  }
462  }
463 
464  template<unsigned int n, typename vector, typename expr>
465  static void compute_expr_slice(vector & v,expr & v_exp, int (& comp)[n])
466  {
467  typedef typename pos_or_propL<vector,prp>::property_act property_act;
468 
469  v_exp.init();
470 
471 #ifdef SE_CLASS1
472  auto &v2=v_exp.getVector();
473 
474  SubsetSelector_impl<std::remove_reference<decltype(v)>::type::is_it_a_subset::value>::check(v2,v);
475 #endif
476 
477  auto it = v.getDomainIterator();
478 
479  while (it.isNext())
480  {
481  auto key = it.get();
482 
483  get_vector_dist_expression_op<n,n == rank_gen<property_act>::type::value>::template assign<prp>(v_exp,v,key,comp);
484 
485  ++it;
486  }
487  }
488 
489  template<typename vector>
490  static void compute_const(vector & v,double d)
491  {
492  auto it = v.getDomainIterator();
493 
494  while (it.isNext())
495  {
496  auto key = it.get();
497 
499 
500  ++it;
501 
502  }
503  }
504 };
505 
506 #define NVCC
507 #ifdef __NVCC__
508 
509 template<unsigned int prp, unsigned int dim ,typename vector, typename expr>
510 __global__ void compute_expr_ker_vv(vector vd, expr v_exp)
511 {
512  unsigned int p = threadIdx.x + blockIdx.x * blockDim.x;
513 
514  if (p >= vd.size()) {return;}
515 
516  for (unsigned int i = 0 ; i < dim ; i++)
517  {
518  vd.template get<prp>(p)[i] = v_exp.value(p).get(i);
519  }
520 }
521 
522 template<unsigned int prp, typename vector, typename expr>
523 __global__ void compute_expr_ker_v(vector vd, expr v_exp)
524 {
525  unsigned int p = threadIdx.x + blockIdx.x * blockDim.x;
526 
527  if (p >= vd.size()) {return;}
528 
529  vd.template get<prp>(p) = v_exp.value(p);
530 }
531 
532 template<unsigned int prp, typename vector, typename expr>
533 __global__ void compute_expr_ker(vector vd, expr v_exp)
534 {
535  unsigned int p = threadIdx.x + blockIdx.x * blockDim.x;
536 
537  if (p >= vd.size_local()) {return;}
538 
539  pos_or_propL_ker<vector,prp>::value(vd,p) = v_exp.value(p);
540 }
541 
542 namespace openfpm
543 {
544 
545  template<typename _Tp, typename _Up = _Tp&&>
546  __device__ __host__ _Up
547  __declval(int);
548 
549  template<typename _Tp>
550  __device__ __host__ _Tp
551  __declval(long);
552 
553  template<typename _Tp>
554  __device__ __host__ auto declval() noexcept -> decltype(__declval<_Tp>(0))
555  {
556  return __declval<_Tp>(0);
557  }
558 }
559 
560 template<unsigned int prp, unsigned int n, typename vector, typename expr>
561 __global__ void compute_expr_ker_slice(vector vd, expr v_exp, Point<n,int> comp)
562 {
563  typedef typename std::remove_const<typename std::remove_reference<decltype(pos_or_propL<vector,prp>::value_type(openfpm::declval<vector>(),vect_dist_key_dx(0)))>::type>::type property_act;
564 
565  unsigned int p = threadIdx.x + blockIdx.x * blockDim.x;
566 
567  if (p >= vd.size_local()) {return;}
568 
569  get_vector_dist_expression_op<n,n == rank_gen<property_act>::type::value>::template assign<prp>(v_exp,vd,p,comp);
570 }
571 
572 template<unsigned int prp, typename vector>
573 __global__ void compute_double_ker(vector vd, double d)
574 {
575  unsigned int p = threadIdx.x + blockIdx.x * blockDim.x;
576 
577  if (p >= vd.size_local()) {return;}
578 
580 }
581 
582 template<unsigned int prp>
583 struct vector_dist_op_compute_op<prp,comp_dev>
584 {
585  template<typename vector, typename expr>
586  static void compute_expr(vector & v,expr & v_exp)
587  {
588  v_exp.init();
589 
590  auto ite = v.getDomainIteratorGPU(256);
591 
592  CUDA_LAUNCH((compute_expr_ker<prp>),ite,v,v_exp);
593  }
594 
595  template<unsigned int n, typename vector, typename expr>
596  static void compute_expr_slice(vector & v,expr & v_exp, int (& comp)[n])
597  {
598  v_exp.init();
599 
600  auto ite = v.getDomainIteratorGPU(256);
601 
602  Point<n,int> comp_;
603  for (int i = 0 ; i < n ; i++) {comp_[i] = comp[i];}
604 
605  CUDA_LAUNCH((compute_expr_ker_slice<prp,n>),ite,v,v_exp,comp_);
606  }
607 
608  template<typename vector, typename expr>
609  static void compute_expr_v(vector & v,expr & v_exp)
610  {
611  v_exp.init();
612 
613  auto ite = v.getGPUIterator(256);
614 
615  CUDA_LAUNCH((compute_expr_ker_v<prp>),ite,v,v_exp);
616  }
617 
618  template<unsigned int dim, typename vector, typename expr>
619  static void compute_expr_vv(vector & v,expr & v_exp)
620  {
621  v_exp.init();
622 
623  auto ite = v.getGPUIterator(256);
624 
625  CUDA_LAUNCH((compute_expr_ker_vv<prp,dim>),ite,v,v_exp);
626  }
627 
628  template<typename vector>
629  static void compute_const(vector & v,double d)
630  {
631  auto ite = v.getDomainIteratorGPU(256);
632 
633  CUDA_LAUNCH((compute_double_ker<prp>),ite,v,d);
634  }
635 };
636 
637 #endif
638 
639 
640 #endif /* VECTOR_DIST_OPERATORS_CUDA_CUH_ */
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:28
Grid key for a distributed grid.
Distributed vector.
convert a type into constant type
Definition: aggregate.hpp:302
__device__ static __host__ auto value(vector &v, const vect_dist_key_dx &k) -> decltype(ger< vector::dims, typename vector::stype >::getExprL(v.getPos(k)))
return the value (position or property) of the particle k in the vector v
static auto value_type(vector &&v, const vect_dist_key_dx &k) -> decltype(v.getPos(k))
return the value (position or property) of the particle k in the vector v
static __device__ auto value(vector &v, const unsigned int &k) -> decltype(ger< vector::dims, typename vector::stype >::getExprL(v.getPos(k)))
return the value (position or property) of the particle k in the vector v
selector for position or properties left side expression
static __device__ auto value(vector &v, const unsigned int &k) -> decltype(v.template getProp< prp >(k))
return the value (position or property) of the particle k in the vector v
selector for position or properties left side expression
__device__ static __host__ auto value(vector &v, const vect_dist_key_dx &k) -> decltype(v.template getProp< prp >(k))
return the value (position or property) of the particle k in the vector v
__device__ static __host__ auto value_type(vector &&v, const vect_dist_key_dx &k) -> decltype(v.template getProp< prp >(k))
return the value (position or property) of the particle k in the vector v
__device__ static __host__ auto value(vector &v, const unsigned int &k) -> decltype(ger< vector::dims, typename vector::stype >::getExprR(v.getPos(k)))
return the value (position or property) of the particle k in the vector v
__device__ static __host__ auto value(vector &v, const vect_dist_key_dx &k) -> decltype(ger< vector::dims, typename vector::stype >::getExprR(v.getPos(k)))
return the value (position or property) of the particle k in the vector v
selector for position or properties right side position
__device__ static __host__ auto value(vector &v, const unsigned int &k) -> decltype(v.template getProp< prp >(k))
return the value (position or property) of the particle k in the vector v
__device__ static __host__ auto value(vector &v, const vect_dist_key_dx &k) -> decltype(v.template getProp< prp >(k))
return the value (position or property) of the particle k in the vector v