OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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_launch.hpp"
13#include <utility>
14
15#ifdef SE_CLASS1
16template<bool is_subset>
17struct 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
24template<>
25struct 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
38constexpr unsigned int PROP_POS =(unsigned int)-1;
39
47template <typename vector, unsigned int prp>
49{
50 typedef typename boost::mpl::at<typename vector::value_type::type, boost::mpl::int_<prp>>::type property_act;
51
53 __device__ __host__ static inline auto value(vector & v, const vect_dist_key_dx & k) -> decltype(v.template getProp<prp>(k))
54 {
55 return v.template getProp<prp>(k);
56 }
57
59 __device__ __host__ static inline auto value_type(vector && v, const vect_dist_key_dx & k) -> decltype(v.template getProp<prp>(k))
60 {
61 return v.template getProp<prp>(k);
62 }
63};
64
72template <typename vector, unsigned int prp>
74{
76 __device__ static inline auto value(vector & v, const unsigned int & k) -> decltype(v.template getProp<prp>(k))
77 {
78 return v.template getProp<prp>(k);
79 }
80};
81
82
90template <typename vector>
91struct pos_or_propL<vector,PROP_POS>
92{
93 typedef typename Point<vector::dims,typename vector::stype>::type_native property_act;
94
95#ifdef SE_CLASS3
96
98 static inline auto value(vector & v, const vect_dist_key_dx & k) -> decltype(getExprL(v.getPos(k).getReference()))
99 {
100 return getExprL(v.getPos(k).getReference());
101 }
102
103#else
104
106 __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)))
107 {
109 }
110
112 static inline auto value_type(vector && v, const vect_dist_key_dx & k) -> decltype(v.getPos(k))
113 {
114 return v.getPos(k);
115 }
116
117#endif
118};
119
127template <typename vector>
128struct pos_or_propL_ker<vector,PROP_POS>
129{
130#ifdef SE_CLASS3
131
133 static inline auto value(vector & v, const vect_dist_key_dx & k) -> decltype(getExprL(v.getPos(k).getReference()))
134 {
135 return getExprL(v.getPos(k).getReference());
136 }
137
138#else
139
141 __device__ static inline auto value(vector & v, const unsigned int & k) -> decltype(ger<vector::dims,typename vector::stype>::getExprL(v.getPos(k)))
142 {
144 }
145
146#endif
147};
148
156template <typename vector, unsigned int prp>
158{
160 __device__ __host__ static inline auto value(vector & v, const vect_dist_key_dx & k) -> decltype(v.template getProp<prp>(k))
161 {
162 return v.template getProp<prp>(k);
163 }
164
166 __device__ __host__ static inline auto value(vector & v, const unsigned int & k) -> decltype(v.template getProp<prp>(k))
167 {
168 return v.template getProp<prp>(k);
169 }
170};
171
172
180template <typename vector>
181struct pos_or_propR<vector,PROP_POS>
182{
184 __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)))
185 {
187 }
188
190 __device__ __host__ static inline auto value(vector & v, const unsigned int & k) -> decltype(ger<vector::dims,typename vector::stype>::getExprR(v.getPos(k)))
191 {
193 }
194};
195
196template<unsigned int prp ,bool is_sort, int impl>
198{
199 template<typename vector, typename expr>
200 static void compute_expr(vector & v,expr & v_exp)
201 {}
202
203 template<unsigned int n, typename vector, typename expr>
204 static void compute_expr_slice(vector & v,expr & v_exp, int (& comp)[n])
205 {}
206
207 template<typename vector>
208 static void compute_const(vector & v,double d)
209 {}
210};
211
213
214template<unsigned int, bool is_valid>
216{
217 template<typename exp_type>
218 __device__ __host__ inline static auto get(exp_type & o1, const vect_dist_key_dx & key) -> decltype(o1.value(vect_dist_key_dx(0)))
219 {
220 return o1.value(key);
221 }
222
223 template<unsigned int prop, typename exp_type, typename vector_type>
224 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const vect_dist_key_dx & key_orig)
225 {
226 pos_or_propL<vector_type,exp_type::prop>::value(v,key) = o1.value(key_orig);
227 }
228
229 template<unsigned int prop, typename exp_type, typename vector_type>
230 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const unsigned int & key_orig)
231 {
232 pos_or_propL<vector_type,exp_type::prop>::value(v,key) = o1.value(key_orig);
233 }
234
235 template<unsigned int prop, typename vector_type>
236 inline static void assign_double(double d, vector_type & v, const vect_dist_key_dx & key)
237 {
239 }
240};
241
242template<>
244{
245 template<typename exp_type>
246 __device__ __host__ static int get(exp_type & o1, const vect_dist_key_dx & key, const int (& comp)[1])
247 {
248 printf("ERROR: Slicer, the expression is incorrect, please check it\n");
249 return 0;
250 }
251
252 template<unsigned int prop, typename exp_type, typename vector_type>
253 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const vect_dist_key_dx & key_orig, const int (& comp)[1])
254 {
255 printf("ERROR: Slicer, the expression is incorrect, please check it\n");
256 }
257
258 template<unsigned int prop, typename exp_type, typename vector_type>
259 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const vect_dist_key_dx & key_orig, const int (& comp)[1])
260 {
261 printf("ERROR: Slicer, the expression is incorrect, please check it\n");
262 }
263
264 template<unsigned int prop,typename exp_type, typename vector_type>
265 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const vect_dist_key_dx & key_orig, const Point<1,int> & comp)
266 {
267 printf("ERROR: Slicer, the expression is incorrect, please check it\n");
268 }
269
270 template<unsigned int prop,typename exp_type, typename vector_type>
271 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const unsigned int & key_orig, const Point<1,int> & comp)
272 {
273 printf("ERROR: Slicer, the expression is incorrect, please check it\n");
274 }
275
276 template<unsigned int prop, typename vector_type>
277 inline static void assign_double(double d, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[1])
278 {
279 printf("ERROR: Slicer, the expression is incorrect, please check it\n");
280 }
281};
282
283template<>
285{
286 template<typename exp_type>
287 __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])
288 {
289 return o1.value(key)[comp[0]];
290 }
291
292 template<unsigned int prop,typename exp_type, typename vector_type>
293 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const vect_dist_key_dx & key_orig, const int (& comp)[1])
294 {
295 pos_or_propL<vector_type,prop>::value(v,key)[comp[0]] = o1.value(key_orig);
296 }
297
298 template<unsigned int prop,typename exp_type, typename vector_type>
299 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const unsigned int & key_orig, const int (& comp)[1])
300 {
301 pos_or_propL<vector_type,prop>::value(v,key)[comp[0]] = o1.value(key_orig);
302 }
303
304 template<unsigned int prop,typename exp_type, typename vector_type>
305 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const vect_dist_key_dx & key_orig, const Point<1,int> & comp)
306 {
307 pos_or_propL<vector_type,prop>::value(v,key)[comp[0]] = o1.value(key_orig);
308 }
309
310 template<unsigned int prop,typename exp_type, typename vector_type>
311 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const unsigned int & key_orig, const Point<1,int> & comp)
312 {
313 pos_or_propL<vector_type,prop>::value(v,key)[comp[0]] = o1.value(key_orig);
314 }
315
316 template<unsigned int prop, typename vector_type>
317 inline static void assign_double(double d, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[1])
318 {
319 pos_or_propL<vector_type,prop>::value(v,key)[comp[0]] = d;
320 }
321};
322
323template<>
325{
326 template<typename exp_type>
327 __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])
328 {
329 return o1.value(key)[comp[0]][comp[1]];
330 }
331
332 template<unsigned int prop,typename exp_type, typename vector_type>
333 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const vect_dist_key_dx & key_orig, const int (& comp)[2])
334 {
335 pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]] = o1.value(key_orig);
336 }
337
338 template<unsigned int prop,typename exp_type, typename vector_type>
339 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const vect_dist_key_dx & key, const vect_dist_key_dx & key_orig, const Point<2,int> & comp)
340 {
341 pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]] = o1.value(key_orig);
342 }
343
344 template<unsigned int prop,typename exp_type, typename vector_type>
345 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const unsigned int & key_orig, const int (& comp)[2])
346 {
347 pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]] = o1.value(key_orig);
348 }
349
350 template<unsigned int prop,typename exp_type, typename vector_type>
351 __device__ __host__ inline static void assign(exp_type & o1, vector_type & v, const unsigned int & key, const unsigned int & key_orig, const Point<2,int> & comp)
352 {
353 pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]] = o1.value(key_orig);
354 }
355
356 template<unsigned int prop, typename vector_type>
357 inline static void assign_double(double d, vector_type & v, const vect_dist_key_dx & key, const int (& comp)[2])
358 {
359 pos_or_propL<vector_type,prop>::value(v,key)[comp[0]][comp[1]] = d;
360 }
361};
362
364
365template<unsigned int prp>
366struct vector_dist_op_compute_op<prp,false,comp_host>
367{
368 template<typename vector, typename expr>
369 static void compute_expr(vector & v,expr & v_exp)
370 {
371 v_exp.init();
372
373 auto it = v.getDomainIterator();
374
375 while (it.isNext())
376 {
377 auto key = it.get();
378 auto key_orig = v.getOriginKey(key);
379
380 pos_or_propL<vector,prp>::value(v,key) = v_exp.value(key_orig);
381
382 ++it;
383 }
384 }
385
386 template<unsigned int n, typename vector, typename expr>
387 static void compute_expr_slice(vector & v,expr & v_exp, int (& comp)[n])
388 {
389 typedef typename pos_or_propL<vector,prp>::property_act property_act;
390
391 v_exp.init();
392
393#ifdef SE_CLASS1
394 auto &v2=v_exp.getVector();
395
396 SubsetSelector_impl<std::remove_reference<decltype(v)>::type::is_it_a_subset::value>::check(v2,v);
397#endif
398
399 auto it = v.getDomainIterator();
400
401 while (it.isNext())
402 {
403 auto key = it.get();
404 auto key_orig = v.getOriginKey(key);
405
406 get_vector_dist_expression_op<n,n == rank_gen<property_act>::type::value>::template assign<prp>(v_exp,v,key,key_orig,comp);
407
408 ++it;
409 }
410 }
411
412 template<typename vector>
413 static void compute_const(vector & v,double d)
414 {
415 auto it = v.getDomainIterator();
416
417 while (it.isNext())
418 {
419 auto key = it.get();
420 auto key_orig = v.getOriginKey(key);
421
423
424 ++it;
425
426 }
427 }
428};
429
430#define NVCC
431#ifdef __NVCC__
432
433template<unsigned int prp, unsigned int dim ,typename vector, typename expr>
434__global__ void compute_expr_ker_vv(vector vd, expr v_exp)
435{
436 unsigned int p = threadIdx.x + blockIdx.x * blockDim.x;
437
438 if (p >= vd.size()) {return;}
439
440 for (unsigned int i = 0 ; i < dim ; i++)
441 {
442 vd.template get<prp>(p)[i] = v_exp.value(p).get(i);
443 }
444}
445
446template<unsigned int prp, typename vector, typename expr>
447__global__ void compute_expr_ker_v(vector vd, expr v_exp)
448{
449 unsigned int p = threadIdx.x + blockIdx.x * blockDim.x;
450
451 if (p >= vd.size()) {return;}
452
453 vd.template get<prp>(p) = v_exp.value(p);
454}
455
456template<unsigned int prp, typename vector, typename expr>
457__global__ void compute_expr_ker(vector vd, expr v_exp)
458{
459 unsigned int p = threadIdx.x + blockIdx.x * blockDim.x;
460
461 if (p >= vd.size_local()) {return;}
462
463 pos_or_propL_ker<vector,prp>::value(vd,p) = v_exp.value(p);
464}
465
466namespace openfpm
467{
468
469 template<typename _Tp, typename _Up = _Tp&&>
470 __device__ __host__ _Up
471 __declval(int);
472
473 template<typename _Tp>
474 __device__ __host__ _Tp
475 __declval(long);
476
477 template<typename _Tp>
478 __device__ __host__ auto declval() noexcept -> decltype(__declval<_Tp>(0))
479 {
480 return __declval<_Tp>(0);
481 }
482}
483
484template<unsigned int prp, unsigned int n, typename vector, typename expr>
485__global__ void compute_expr_ker_slice(vector vd, expr v_exp, Point<n,int> comp)
486{
487 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;
488
489 unsigned int p = threadIdx.x + blockIdx.x * blockDim.x;
490
491 if (p >= vd.size_local()) {return;}
492
493 get_vector_dist_expression_op<n,n == rank_gen<property_act>::type::value>::template assign<prp>(v_exp,vd,p,p,comp);
494}
495
496template<unsigned int prp, typename vector>
497__global__ void compute_double_ker(vector vd, double d)
498{
499 unsigned int p = threadIdx.x + blockIdx.x * blockDim.x;
500
501 if (p >= vd.size_local()) {return;}
502
504}
505
507
508template<unsigned int prp, unsigned int dim ,typename vector, typename NN_type, typename expr>
509__global__ void compute_expr_ker_sort_vv(vector vd, NN_type NN, expr v_exp)
510{
511 unsigned int p;
512
513 GET_PARTICLE_SORT(p,NN);
514
515 for (unsigned int i = 0 ; i < dim ; i++)
516 {
517 vd.template get<prp>(p)[i] = v_exp.value(p).get(i);
518 }
519}
520
521template<unsigned int prp, typename vector, typename NN_type, typename expr>
522__global__ void compute_expr_ker_sort_v(vector vd, NN_type NN, expr v_exp)
523{
524 unsigned int p;
525
526 GET_PARTICLE_SORT(p,NN);
527
528 vd.template get<prp>(p) = v_exp.value(p);
529}
530
531template<unsigned int prp, typename vector, typename expr, typename NN_type>
532__global__ void compute_expr_ker_sort(vector vd, NN_type NN, expr v_exp)
533{
534 unsigned int p;
535
536 GET_PARTICLE_SORT(p,NN);
537
538 pos_or_propL_ker<vector,prp>::value(vd,p) = v_exp.value(p);
539}
540
541
543
544template<unsigned int prp>
545struct vector_dist_op_compute_op<prp,false,comp_dev>
546{
547 template<typename vector, typename expr>
548 static void compute_expr(vector & v,expr & v_exp)
549 {
550 v_exp.init();
551
552 auto ite = v.getDomainIteratorGPU(256);
553
554 CUDA_LAUNCH((compute_expr_ker<prp>),ite,v,v_exp);
555 }
556
557 template<unsigned int n, typename vector, typename expr>
558 static void compute_expr_slice(vector & v,expr & v_exp, int (& comp)[n])
559 {
560 v_exp.init();
561
562 auto ite = v.getDomainIteratorGPU(256);
563
564 Point<n,int> comp_;
565 for (int i = 0 ; i < n ; i++) {comp_[i] = comp[i];}
566
567 CUDA_LAUNCH((compute_expr_ker_slice<prp,n>),ite,v,v_exp,comp);
568 }
569
570 template<typename vector, typename expr>
571 static void compute_expr_v(vector & v,expr & v_exp)
572 {
573 v_exp.init();
574
575 auto ite = v.getGPUIterator(256);
576
577 CUDA_LAUNCH((compute_expr_ker_v<prp>),ite,v,v_exp);
578 }
579
580 template<unsigned int dim, typename vector, typename expr>
581 static void compute_expr_vv(vector & v,expr & v_exp)
582 {
583 v_exp.init();
584
585 auto ite = v.getGPUIterator(256);
586
587 CUDA_LAUNCH((compute_expr_ker_vv<prp,dim>),ite,v,v_exp);
588 }
589
590 template<typename vector>
591 static void compute_const(vector & v,double d)
592 {
593 auto ite = v.getDomainIteratorGPU(256);
594
595 CUDA_LAUNCH((compute_double_ker<prp>),ite,v,d);
596 }
597};
598
599template<unsigned int prp>
600struct vector_dist_op_compute_op<prp,true,comp_dev>
601{
602 template<typename vector, typename expr>
603 static void compute_expr(vector & v,expr & v_exp)
604 {
605 v_exp.init();
606
607 auto ite = v.getDomainIteratorGPU(256);
608
609 auto NN = v_exp.getNN();
610
611 CUDA_LAUNCH((compute_expr_ker_sort<prp>),ite,v,*NN,v_exp);
612 }
613
614 template<typename vector, typename expr>
615 static void compute_expr_v(vector & v,expr & v_exp)
616 {
617 v_exp.init();
618
619 auto ite = v.getGPUIterator(256);
620
621 auto NN = v_exp.getNN();
622
623 CUDA_LAUNCH((compute_expr_ker_sort_v<prp>),ite,v,*NN,v_exp);
624 }
625
626 template<unsigned int dim, typename vector, typename expr>
627 static void compute_expr_vv(vector & v,expr & v_exp)
628 {
629 v_exp.init();
630
631 auto ite = v.getGPUIterator(256);
632
633 auto NN = v_exp.getNN();
634
635 CUDA_LAUNCH((compute_expr_ker_sort_vv<prp,dim>),ite,v,*NN,v_exp);
636 }
637};
638
639#endif
640
641
642#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.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
convert a type into constant type
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
__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 __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 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
__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
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