OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
map_grid_cuda_ker.cuh
1/*
2 * map_grid_cuda_ker.hpp
3 *
4 * Created on: Jun 28, 2018
5 * Author: i-bird
6 */
7
8#ifndef MAP_GRID_CUDA_KER_HPP_
9#define MAP_GRID_CUDA_KER_HPP_
10
11#include "config.h"
12#include "Grid/grid_base_impl_layout.hpp"
13#include "util/tokernel_transformation.hpp"
14#ifdef CUDA_GPU
15#include "memory/CudaMemory.cuh"
16#endif
17#ifdef HAVE_OPENMP
18#include <omp.h>
19#endif
20
32template<typename T_type_src,typename T_type_dst>
34{
36 const T_type_src & src;
38 T_type_dst & dst;
39
40
47 inline copy_switch_memory_c_no_cpy(const T_type_src & src,
48 T_type_dst & dst)
49 :src(src),dst(dst)
50 {
51 };
52
53
55 template<typename T>
56 inline void operator()(T& t)
57 {
58 boost::fusion::at_c<T::value>(dst).disable_manage_memory();
59
60 boost::fusion::at_c<T::value>(dst).mem = boost::fusion::at_c<T::value>(src).mem;
61
62 boost::fusion::at_c<T::value>(dst).mem_r.bind_ref(boost::fusion::at_c<T::value>(src).mem_r);
63 boost::fusion::at_c<T::value>(dst).switchToDevicePtr();
64 }
65};
66
67template<bool inte_or_lin,typename T>
69{
70 template<typename ggk_type> static inline void construct(const ggk_type & cpy,ggk_type & this_)
71 {
72 copy_switch_memory_c_no_cpy<decltype(cpy.get_data_()),decltype(this_.get_data_())> bp_mc(cpy.get_data_(),this_.get_data_());
73
74 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,T::max_prop> >(bp_mc);
75 }
76};
77
78template<typename T>
80{
81 template<typename ggk_type> static inline void construct(const ggk_type & cpy,ggk_type & this_)
82 {
83 this_.get_data_().disable_manage_memory();
84 this_.get_data_().mem = cpy.get_data_().mem;
85
86 this_.get_data_().mem_r.bind_ref(cpy.get_data_().mem_r);
87 this_.get_data_().switchToDevicePtr();
88 }
89};
90
91template<unsigned int dim, int prp, typename ids_type>
92__device__ void fill_grid_error_array_overflow(const void * sptr,grid_key_dx<dim,ids_type> key)
93{
94#ifdef CUDA_GPU
95
96 int * ptr = (int *)&global_cuda_error_array[0];
97
98 ptr[0] = 1;
99 ptr[1] = ((size_t)sptr) & 0xFFFFFFFF;
100 ptr[2] = (((size_t)sptr) & 0xFFFFFFFF00000000) >> 32;
101 ptr[3] = prp;
102 ptr[4] = dim;
103
104 for (int i = 0 ; i < dim ; i++)
105 {ptr[i+5] = key.get(i);}
106
107#ifdef __NVCC__
108
109 ptr[5+dim] = blockIdx.x;
110 ptr[6+dim] = blockIdx.y;
111 ptr[7+dim] = blockIdx.z;
112
113 ptr[8+dim] = blockDim.x;
114 ptr[9+dim] = blockDim.y;
115 ptr[10+dim] = blockDim.z;
116
117 ptr[11+dim] = threadIdx.x;
118 ptr[12+dim] = threadIdx.y;
119 ptr[13+dim] = threadIdx.z;
120
121#endif
122
123#endif
124}
125
126template<unsigned int dim>
127__device__ void fill_grid_error_array(size_t lin_id)
128{
129#ifdef CUDA_GPU
130
131 int * ptr = (int *)&global_cuda_error_array[0];
132
133 ptr[0] = 1;
134 ptr[1] = 1;
135 ptr[2] = lin_id;
136
137#endif
138}
139
140template<unsigned int dim, typename T, template <typename> class layout_base, typename linearizer>
141class grid_gpu_ker_ref;
142
148template<unsigned int dim, typename T, template <typename> class layout_base, typename linearizer>
150{
152 typedef typename apply_transform<layout_base,T>::type T_;
153
155 linearizer g1;
156
158 typedef typename layout_base<T_>::type layout;
159
161 mutable layout data_;
162
163
164
172 template<typename ids_type> __device__ __host__ inline bool check_bound(const grid_key_dx<dim,ids_type> & v1) const
173 {
174 for (long int i = 0 ; i < dim ; i++)
175 {
176 if (v1.get(i) >= (long int)getGrid().size(i))
177 {return false;}
178 else if (v1.get(i) < 0)
179 {return false;}
180 }
181 return true;
182 }
183
191 __device__ __host__ inline bool check_bound(size_t v1) const
192 {
193 return v1 < getGrid().size();
194 }
195
196public:
197
199 typedef int yes_i_am_grid;
200
202 typedef T value_type;
203
204 __device__ __host__ grid_gpu_ker()
205 {}
206
207 __device__ __host__ grid_gpu_ker(const linearizer & g1)
208 :g1(g1)
209 {
210 }
211
212 __device__ __host__ grid_gpu_ker(const grid_gpu_ker & cpy)
213 :g1(cpy.g1)
214 {
216 }
217
218 __device__ __host__ void constructor_impl(const grid_gpu_ker & cpy)
219 {
220 g1 = cpy.g1;
222 }
223
224 __device__ __host__ void constructor_impl(const grid_gpu_ker_ref<dim,T,layout_base,linearizer> & cpy)
225 {
226 g1 = cpy.ggk.g1;
227 grid_gpu_ker_constructor_impl<is_layout_inte<layout_base<T_>>::value,T_>::construct(cpy.ggk,*this);
228 }
229
237 __device__ __host__ const grid_sm<dim,void> & getGrid() const
238 {
239 return g1;
240 }
241
249 template <unsigned int p, typename ids_type,typename r_type=decltype(layout_base<T_>::template get<p>(data_,g1,grid_key_dx<dim>()))>
250 __device__ __host__ inline r_type get(const grid_key_dx<dim,ids_type> & v1)
251 {
252#ifdef SE_CLASS1
253 if (check_bound(v1) == false)
254 {fill_grid_error_array_overflow<dim,p>(this->template getPointer<p>(),v1);}
255#endif
256
257 return layout_base<T_>::template get<p>(data_,g1,v1);
258 }
259
267 template <unsigned int p, typename ids_type, typename r_type=decltype(layout_base<T_>::template get<p>(data_,g1,grid_key_dx<dim>()))>
268 __device__ __host__ inline r_type get_debug(const grid_key_dx<dim,ids_type> & v1) const
269 {
270#ifdef SE_CLASS1
271 if (check_bound(v1) == false)
272 {fill_grid_error_array_overflow<dim,p>(this->template getPointer<p>(),v1);}
273#endif
274
275 return layout_base<T_>::template get<p>(data_,g1,v1);
276 }
277
285 template <unsigned int p, typename ids_type, typename r_type=decltype(layout_base<T_>::template get<p>(data_,g1,grid_key_dx<dim>()))>
286 __device__ __host__ inline r_type get(const grid_key_dx<dim,ids_type> & v1) const
287 {
288#ifdef SE_CLASS1
289 if (check_bound(v1) == false)
290 {fill_grid_error_array_overflow<dim,p>(this->template getPointer<p>(),v1);}
291#endif
292 return layout_base<T_>::template get<p>(data_,g1,v1);
293 }
294
302 template <unsigned int p, typename r_type=decltype(layout_base<T_>::template get_lin<p>(data_,g1,0))>
303 __device__ __host__ inline r_type get(const size_t lin_id)
304 {
305#ifdef SE_CLASS1
306 if (check_bound(lin_id) == false)
307 {fill_grid_error_array_overflow<p>(this->getPointer(),lin_id);}
308#endif
309 return layout_base<T_>::template get_lin<p>(data_,g1,lin_id);
310 }
311
319 template <unsigned int p, typename r_type=decltype(layout_base<T_>::template get_lin<p>(data_,g1,0))>
320 __device__ __host__ inline const r_type get(size_t lin_id) const
321 {
322#ifdef SE_CLASS1
323 if (check_bound(lin_id) == false)
324 {fill_grid_error_array_overflow<p>(this->getPointer(),lin_id);}
325#endif
326 return layout_base<T_>::template get_lin<p>(data_,g1,lin_id);
327 }
328
340 template<typename Tk>
341 __device__ inline encapc<dim,T_,layout> get_o(const grid_key_dx<dim,Tk> & v1)
342 {
343#ifdef SE_CLASS1
344 if (check_bound(v1) == false)
345 {fill_grid_error_array_overflow<dim,-1>(this->template getPointer<0>(),v1);}
346#endif
347 return mem_geto<dim,T_,layout_base<T_>,decltype(this->data_),decltype(this->g1),decltype(v1)>::get(data_,g1,v1);
348 }
349
361 template<typename Tk>
362 __device__ inline const encapc<dim,T_,layout> get_o(const grid_key_dx<dim,Tk> & v1) const
363 {
364#ifdef SE_CLASS1
365 if (check_bound(v1) == false)
366 {fill_grid_error_array_overflow<dim,-1>(this->template getPointer<0>(),v1);}
367#endif
368 return mem_geto<dim,T,layout_base<T_>,decltype(this->data_),decltype(this->g1),decltype(v1)>::get(const_cast<decltype(this->data_) &>(data_),g1,v1);
369 }
370
371
372 __device__ inline void set(const grid_key_dx<dim> & key1,const grid_gpu_ker<dim,T_,layout_base, linearizer> & g, const grid_key_dx<dim> & key2)
373 {
374#ifdef SE_CLASS1
375 if (check_bound(key1) == false)
376 {fill_grid_error_array_overflow<dim,-1>(this->template getPointer<0>(),key1);}
377
378 if (g.check_bound(key2) == false)
379 {fill_grid_error_array_overflow<dim,-1>(g.template getPointer<0>(),key2);}
380
381#endif
382
383 this->get_o(key1) = g.get_o(key2);
384 }
385
386 template<unsigned int ... prp> __device__ inline void set(const grid_key_dx<dim> & key1,const grid_gpu_ker<dim,T_,layout_base, linearizer> & g, const grid_key_dx<dim> & key2)
387 {
388#ifdef SE_CLASS1
389 if (check_bound(key1) == false)
390 {fill_grid_error_array_overflow<dim,-1>(this->template getPointer<0>(),key1);}
391
392 if (g.check_bound(key2) == false)
393 {fill_grid_error_array_overflow<dim,-1>(g.template getPointer<0>(),key2);}
394
395#endif
396
397 auto edest = this->get_o(key1);
398 auto esrc = g.get_o(key2);
399
400 copy_cpu_encap_encap_prp<decltype(g.get_o(key2)),decltype(this->get_o(key1)),prp...> ec(esrc,edest);
401
402 boost::mpl::for_each_ref<boost::mpl::range_c<int,0,sizeof...(prp)>>(ec);
403 }
404
413 template<typename Memory> __device__ inline void set(grid_key_dx<dim> key1, const encapc<1,T,Memory> & obj)
414 {
415#ifdef SE_CLASS1
416 if (check_bound(key1) == false)
417 {fill_grid_error_array_overflow<dim,-1>(this->template getPointer<0>(),key1);}
418#endif
419
420 this->get_o(key1) = obj;
421 }
422
428 template<unsigned int p> __device__ __host__ void * getPointer()
429 {
430 return mem_getpointer<decltype(data_),layout_base<T>>::template getPointer<p>(data_);
431 }
432
438 template<unsigned int p> __device__ __host__ const void * getPointer() const
439 {
440 return mem_getpointer<decltype(data_),layout_base<T>>::template getPointer<p>(data_);
441 }
442
449 {
450 g1 = g.g1;
451
453
454 return *this;
455 }
456
463 struct ite_gpu<dim> getGPUIterator(grid_key_dx<dim> & key1, grid_key_dx<dim> & key2, size_t n_thr = default_kernel_wg_threads_) const
464 {
465 return getGPUIterator_impl<dim>(g1,key1,key2,n_thr);
466 }
467
473 __device__ __host__ inline layout & get_data_()
474 {
475 return data_;
476 }
477
483 __device__ __host__ inline const layout & get_data_() const
484 {
485 return data_;
486 }
487};
488
489// This is an abstraction for reference type. It exist because the compiler by C++ starndard even if we return a reference deduce
490// as value. To force as reference we have to create an object grid_gpu_ker_ref that emulate the reference concept
491
492template<unsigned int dim, typename T, template <typename> class layout_base, typename linearizer>
494{
496
497 typedef typename apply_transform<layout_base,T>::type T_;
498
499 typedef typename layout_base<T_>::type layout;
500
501public:
502
504 typedef int yes_i_am_grid;
505
507 typedef T value_type;
508
510 static constexpr unsigned int dims = dim;
511
512 __device__ __host__ grid_gpu_ker_ref()
513 {}
514
516 :ggk(ggk)
517 {}
518
519
520 __device__ __host__ const grid_sm<dim,void> & getGrid() const
521 {
522 return ggk.getGrid();
523 }
524
525 __device__ __host__ size_t size() const
526 {
527 return ggk.getGrid().size();
528 }
529
530 template <unsigned int p, typename ids_type>
531 __device__ __host__ inline auto get(const grid_key_dx<dim,ids_type> & v1) -> decltype(ggk.template get<p>(v1))
532 {
533 return ggk.template get<p>(v1);
534 }
535
536 template <unsigned int p, typename ids_type>
537 __device__ __host__ inline auto get(const grid_key_dx<dim,ids_type> & v1) const -> decltype(ggk.template get<p>(v1))
538 {
539 return ggk.template get<p>(v1);
540 }
541
542 template <unsigned int p>
543 __device__ __host__ inline auto get(const size_t lin_id) -> decltype(ggk.template get<p>(lin_id))
544 {
545 return ggk.template get<p>(lin_id);
546 }
547
548 template <unsigned int p>
549 __device__ __host__ inline auto get(size_t lin_id) const -> decltype(ggk.template get<p>(lin_id))
550 {
551 return ggk.template get<p>(lin_id);
552 }
553
554 template<typename Tk>
555 __device__ inline auto get_o(const grid_key_dx<dim,Tk> & v1) -> decltype(ggk.get_o(v1))
556 {
557 return ggk.get_o(v1);
558 }
559
560 template<typename Tk>
561 __device__ inline auto get_o(const grid_key_dx<dim,Tk> & v1) const -> decltype(ggk.get_o(v1))
562 {
563 return ggk.get_o(v1);
564 }
565
566
567 __device__ inline void set(const grid_key_dx<dim> & key1,const grid_gpu_ker<dim,T_,layout_base, linearizer> & g, const grid_key_dx<dim> & key2)
568 {
569 ggk.set(key1,g,key2);
570 }
571
572 template<unsigned int ... prp> __device__ inline void set(const grid_key_dx<dim> & key1,const grid_gpu_ker<dim,T_,layout_base, linearizer> & g, const grid_key_dx<dim> & key2)
573 {
574 ggk.template set<prp ...>(key1,g,key2);
575 }
576
577 template<typename Memory> __device__ inline void set(grid_key_dx<dim> key1, const encapc<1,T,Memory> & obj)
578 {
579 ggk.set(key1,obj);
580 }
581
582 template<unsigned int p> __device__ __host__ void * getPointer()
583 {
584 return ggk.template getPointer<p>();
585 }
586
587 template<unsigned int p> __device__ __host__ const void * getPointer() const
588 {
589 return ggk.template getPointer<p>();
590 }
591
593 {
594 ggk.operator=(g);
595
596 return *this;
597 }
598
599 struct ite_gpu<dim> getGPUIterator(grid_key_dx<dim> & key1, grid_key_dx<dim> & key2, size_t n_thr = default_kernel_wg_threads_) const
600 {
601 return ggk.getGPUIterator(key1,key2,n_thr);
602 }
603
604 __device__ __host__ inline layout & get_data_()
605 {
606 return ggk.get_data_();
607 }
608
609 __device__ __host__ inline const layout & get_data_() const
610 {
611 return ggk.get_data_();
612 }
613
614 const grid_gpu_ker_ref & toKernel() const
615 {
616 return *this;
617 }
618
619 friend class grid_gpu_ker<dim,T,layout_base,linearizer>;
620};
621
622#endif /* MAP_GRID_CUDA_KER_HPP_ */
T value_type
Type of the value the vector is storing.
int yes_i_am_grid
it define that it is a grid
static constexpr unsigned int dims
expose the dimansionality as a static const
grid interface available when on gpu
__device__ __host__ bool check_bound(size_t v1) const
Check that the key is inside the grid.
__device__ __host__ r_type get(const size_t lin_id)
Get the reference of the selected element.
__device__ __host__ const layout & get_data_() const
Get the internal data_ structure.
grid_gpu_ker< dim, T_, layout_base, linearizer > & operator=(const grid_gpu_ker< dim, T_, layout_base, linearizer > &g)
operator= this operator absorb the pointers, consider that this object wrap device pointers
__device__ __host__ bool check_bound(const grid_key_dx< dim, ids_type > &v1) const
Check that the key is inside the grid.
__device__ __host__ r_type get(const grid_key_dx< dim, ids_type > &v1)
Get the reference of the selected element.
__device__ __host__ const grid_sm< dim, void > & getGrid() const
Return the internal grid information.
apply_transform< layout_base, T >::type T_
Type T.
int yes_i_am_grid
it define that it is a grid
__device__ __host__ void * getPointer()
Get the pointer for the property p.
layout data_
layout data
__device__ __host__ layout & get_data_()
Get the internal data_ structure.
__device__ __host__ const r_type get(size_t lin_id) const
Get the const reference of the selected element.
__device__ void set(grid_key_dx< dim > key1, const encapc< 1, T, Memory > &obj)
set an element of the grid
__device__ __host__ r_type get_debug(const grid_key_dx< dim, ids_type > &v1) const
Get the const reference of the selected element.
__device__ encapc< dim, T_, layout > get_o(const grid_key_dx< dim, Tk > &v1)
Get the of the selected element as a boost::fusion::vector.
__device__ __host__ r_type get(const grid_key_dx< dim, ids_type > &v1) const
Get the const reference of the selected element.
struct ite_gpu< dim > getGPUIterator(grid_key_dx< dim > &key1, grid_key_dx< dim > &key2, size_t n_thr=default_kernel_wg_threads_) const
Get an iterator for the GPU.
layout_base< T_ >::type layout
type of layout of the structure
T value_type
Type of the value the vector is storing.
__device__ const encapc< dim, T_, layout > get_o(const grid_key_dx< dim, Tk > &v1) const
Get the of the selected element as a boost::fusion::vector.
linearizer g1
grid information
__device__ __host__ const void * getPointer() const
Get the pointer for the property p.
grid_key_dx is the key to access any element in the grid
Definition grid_key.hpp:19
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition grid_key.hpp:503
Declaration grid_sm.
Definition grid_sm.hpp:167
__device__ __host__ size_t size() const
Return the size of the grid.
Definition grid_sm.hpp:657
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
this class is a functor for "for_each" algorithm
Definition Encap.hpp:33
this class is a functor for "for_each" algorithm
copy_switch_memory_c_no_cpy(const T_type_src &src, T_type_dst &dst)
constructor
const T_type_src & src
encapsulated source object
void operator()(T &t)
It call the copy function for each property.
T_type_dst & dst
encapsulated destination object
Case memory_traits_lin.
Definition Encap.hpp:926