OpenFPM  5.2.0
Project that contain the implementation of distributed structures
grid_base_implementation.hpp
1 /*
2  * grid_base_implementation.hpp
3  *
4  * Created on: May 2, 2016
5  * Author: i-bird
6  */
7 
8 #ifndef OPENFPM_DATA_SRC_GRID_GRID_BASE_IMPLEMENTATION_HPP_
9 #define OPENFPM_DATA_SRC_GRID_GRID_BASE_IMPLEMENTATION_HPP_
10 
11 #include "grid_base_impl_layout.hpp"
12 #include "util/cuda_util.hpp"
13 #include "cuda/cuda_grid_gpu_funcs.cuh"
14 #include "util/create_vmpl_sequence.hpp"
15 #include "util/object_si_di.hpp"
16 
17 constexpr int DATA_ON_HOST = 32;
18 constexpr int DATA_ON_DEVICE = 64;
19 constexpr int EXACT_RESIZE = 128;
20 
21 template<bool np,typename T>
22 struct skip_init
23 {
24  static bool skip_()
25  {
26  return true;
27  }
28 };
29 
30 template<typename T>
31 struct skip_init<true,T>
32 {
33  static bool skip_()
34  {
35  return T::noPointers();
36  }
37 };
38 
39 #ifdef __NVCC__
40 
41 template<bool active>
42 struct copy_ndim_grid_device_active_impl
43  {
44  template<typename grid_type1, typename grid_type2, typename ite_gpu_type>
45  static inline void copy(grid_type1 & g1, grid_type2 & g2, ite_gpu_type & ite)
46  {
47 
48  }
49 
50  template<typename grid_type1, typename grid_type2, typename ite_gpu_type>
51  static inline void copy_block(grid_type1 & g1, grid_type2 & g2, ite_gpu_type & ite)
52  {
53  }
54 };
55 
56 template<>
57 struct copy_ndim_grid_device_active_impl<true>
58 {
59  template<typename grid_type1, typename grid_type2, typename ite_gpu_type>
60  static inline void copy(grid_type1 & g1, grid_type2 & g2, ite_gpu_type & ite)
61  {
62  CUDA_LAUNCH((copy_ndim_grid_device<grid_type1::dims,decltype(g1.toKernel())>),ite,g2.toKernel(),g1.toKernel());
63  }
64 
65  template<typename grid_type1, typename grid_type2, typename ite_gpu_type>
66  static inline void copy_block(grid_type1 & g1, grid_type2 & g2, ite_gpu_type & ite)
67  {
68  CUDA_LAUNCH((copy_ndim_grid_block_device<grid_type1::dims,decltype(g1.toKernel())>),ite,g2.toKernel(),g1.toKernel());
69  }
70 };
71 
72 template<typename S,typename grid_dst_type, typename grid_src_type>
73 void copy_grid_to_grid(grid_dst_type & gdst, const grid_src_type & gsrc,
75  int blockSize)
76 {
77  if (grid_dst_type::dims <= 3)
78  {
79  auto ite = gsrc.getGPUIterator(start,stop);
80  bool has_work = has_work_gpu(ite);
81 
82  if (has_work == true)
83  {
84  if (blockSize == 1)
85  {
86  copy_ndim_grid_device_active_impl<S::isDeviceHostSame() == false>::copy(gdst,gsrc,ite);
87  }
88  else
89  {
90  move_work_to_blocks(ite);
91 
92  ite.thr.x = blockSize;
93 
94  copy_ndim_grid_device_active_impl<S::isDeviceHostSame() == false>::copy_block(gdst,gsrc,ite);
95  }
96  }
97  }
98  else
99  {
100  grid_key_dx<1> start;
101  start.set_d(0,0);
102  grid_key_dx<1> stop({});
103  stop.set_d(0,gsrc.getGrid().size());
104 
105  size_t sz[1];
106  sz[0]= gsrc.getGrid().size();
107 
108  grid_sm<1,void> g_sm_copy(sz);
109 
110  auto ite = getGPUIterator_impl<1>(g_sm_copy,start,stop);
111 
112  copy_ndim_grid_device_active_impl<S::isDeviceHostSame() == false>::copy(gdst,gsrc,ite);
113  }
114 }
115 
116 #endif
117 
118 template<typename dest_type, typename src_type, unsigned int ... prp>
119 void copy_with_openmp_prp(const dest_type & dst, const src_type & src, ite_gpu<dest_type::dims> ite)
120 {
121  #ifdef CUDIFY_USE_OPENMP
122  auto lamb = [&dst,&src,&ite] __device__ (dim3 & blockIdx, dim3 & threadIdx)
123  {
125 
126  if (dest_type::dims == 1)
127  {
128  i.set_d(0,blockIdx.x*blockDim.x + threadIdx.x + ite.start.get(0));
129  if (i.get(0) >= src.size(0)) {return;}
130  }
131  else if (dest_type::dims == 2)
132  {
133  i.set_d(0,blockIdx.x*blockDim.x + threadIdx.x + ite.start.get(0));
134  i.set_d(1,blockIdx.y*blockDim.y + threadIdx.y + ite.start.get(1));
135  if (i.get(0) >= src.size(0) || i.get(1) >= src.size(1)) {return;}
136  }
137  else if (dest_type::dims == 3)
138  {
139  i.set_d(0,blockIdx.x*blockDim.x + threadIdx.x + ite.start.get(0));
140  i.set_d(1,blockIdx.y*blockDim.y + threadIdx.y + ite.start.get(1));
141  i.set_d(2,blockIdx.z*blockDim.z + threadIdx.z + ite.start.get(2));
142  if (i.get(0) >= src.size(0) || i.get(1) >= src.size(1) || i.get(2) >= src.size(2)) {return;}
143  }
144 
145  object_si_di<decltype(src.get_o(i)),decltype(dst.get_o(i)),OBJ_ENCAP,prp ...>(src.get_o(i),dst.get_o(i));
146  };
147 
148  CUDA_LAUNCH_LAMBDA(ite,lamb);
149  #else
150  std::cout << __FILE__ << ":" << __LINE__ << " error CUDA on back end is disabled" << std::endl;
151  #endif
152 }
153 
154 
155 #ifdef CUDA_GPU
156 
157 #define GRID_ID_3_RAW(start,stop) int x[3] = {threadIdx.x + blockIdx.x * blockDim.x + start.get(0),\
158  threadIdx.y + blockIdx.y * blockDim.y + start.get(1),\
159  threadIdx.z + blockIdx.z * blockDim.z + start.get(2)};\
160  \
161  if (x[0] > stop.get(0) || x[1] > stop.get(1) || x[2] > stop.get(2))\
162  {return;}
163 
164 #define GRID_ID_3_TRAW(start,stop) int tx = threadIdx.x + blockIdx.x * blockDim.x + start.get(0);\
165  int ty = threadIdx.y + blockIdx.y * blockDim.y + start.get(1);\
166  int tz = threadIdx.z + blockIdx.z * blockDim.z + start.get(2);\
167  \
168  if (tx > stop.get(0) || ty > stop.get(1) || tz > stop.get(2))\
169  {return;}
170 
171 #define GRID_ID_3(ite_gpu) grid_key_dx<3,int> key;\
172  key.set_d(0,threadIdx.x + blockIdx.x * blockDim.x + ite_gpu.start.get(0));\
173  key.set_d(1,threadIdx.y + blockIdx.y * blockDim.y + ite_gpu.start.get(1));\
174  key.set_d(2,threadIdx.z + blockIdx.z * blockDim.z + ite_gpu.start.get(2));\
175  \
176  if (key.get(0) > ite_gpu.stop.get(0) || key.get(1) > ite_gpu.stop.get(1) || key.get(2) > ite_gpu.stop.get(2))\
177  {return;}
178 
179 #define GRID_ID_2(ite_gpu) grid_key_dx<2,int> key;\
180  key.set_d(0,threadIdx.x + blockIdx.x * blockDim.x + ite_gpu.start.get(0));\
181  key.set_d(1,threadIdx.y + blockIdx.y * blockDim.y + ite_gpu.start.get(1));\
182  \
183  if (key.get(0) > ite_gpu.stop.get(0) || key.get(1) > ite_gpu.stop.get(1))\
184  {return;}
185 
186 #ifdef __NVCC__
187 
188 
189 template<unsigned int dim, typename ids_type = int>
190 struct grid_p
191 {
192  __device__ static inline grid_key_dx<dim,ids_type> get_grid_point(const grid_sm<dim,void> & g)
193  {
195 
196  key.set_d(0,blockIdx.x * blockDim.x + threadIdx.x);
197  key.set_d(1,blockIdx.y * blockDim.y + threadIdx.y);
198 
199  unsigned int bz = blockIdx.z * blockDim.z + threadIdx.z;
200  key.set_d(2,bz % g.size(2));
201 
202  for (unsigned int i = 3 ; i < dim ; i++)
203  {
204  bz /= g.size(i);
205  key.set_d(i,bz % g.size(i));
206  }
207 
208  return key;
209  }
210 
211  __device__ static inline grid_key_dx<dim,ids_type> get_grid_point(const openfpm::array<ids_type,dim,unsigned int> & g)
212  {
214 
215  key.set_d(0,blockIdx.x * blockDim.x + threadIdx.x);
216  key.set_d(1,blockIdx.y * blockDim.y + threadIdx.y);
217 
218  unsigned int bz = blockIdx.z * blockDim.z + threadIdx.z;
219  key.set_d(2,bz % g[2]);
220 
221  for (unsigned int i = 3 ; i < dim ; i++)
222  {
223  bz /= g[i];
224  key.set_d(i,bz % g[i]);
225  }
226 
227  return key;
228  }
229 };
230 
231 template<typename ids_type>
232 struct grid_p<3,ids_type>
233 {
234  __device__ static inline grid_key_dx<3,ids_type> get_grid_point(const grid_sm<3,void> & g)
235  {
237 
238  key.set_d(0,blockIdx.x * blockDim.x + threadIdx.x);
239  key.set_d(1,blockIdx.y * blockDim.y + threadIdx.y);
240  key.set_d(2,blockIdx.z * blockDim.z + threadIdx.z);
241 
242  return key;
243  }
244 
245  __device__ static inline grid_key_dx<3,ids_type> get_grid_point(const openfpm::array<ids_type,3,unsigned int> & g)
246  {
248 
249  key.set_d(0,blockIdx.x * blockDim.x + threadIdx.x);
250  key.set_d(1,blockIdx.y * blockDim.y + threadIdx.y);
251  key.set_d(2,blockIdx.z * blockDim.z + threadIdx.z);
252 
253  return key;
254  }
255 };
256 
257 template<typename ids_type>
258 struct grid_p<2,ids_type>
259 {
260  __device__ static inline grid_key_dx<2,ids_type> get_grid_point(const grid_sm<2,void> & g)
261  {
263 
264  key.set_d(0,blockIdx.x * blockDim.x + threadIdx.x);
265  key.set_d(1,blockIdx.y * blockDim.y + threadIdx.y);
266 
267  return key;
268  }
269 
270  __device__ static inline grid_key_dx<2,ids_type> get_grid_point(const openfpm::array<ids_type,2,unsigned int> & g)
271  {
273 
274  key.set_d(0,blockIdx.x * blockDim.x + threadIdx.x);
275  key.set_d(1,blockIdx.y * blockDim.y + threadIdx.y);
276 
277  return key;
278  }
279 };
280 
281 template<typename ids_type>
282 struct grid_p<1,ids_type>
283 {
284  __device__ static inline grid_key_dx<1,unsigned int> get_grid_point(const grid_sm<1,void> & g)
285  {
287 
288  key.set_d(0,blockIdx.x * blockDim.x + threadIdx.x);
289 
290  return key;
291  }
292 };
293 
294 #endif
295 
296 
297 template<unsigned int dim>
298 void move_work_to_blocks(ite_gpu<dim> & ite)
299 {
300  if (dim == 1)
301  {
302  ite.wthr.x = ite.wthr.x * ite.thr.x;
303  ite.thr.x = 1;
304  }
305  else if(dim == 2)
306  {
307  ite.wthr.x = ite.wthr.x * ite.thr.x;
308  ite.wthr.y = ite.wthr.y * ite.thr.y;
309  ite.thr.x = 1;
310  ite.thr.y = 1;
311 
312  }
313  else
314  {
315  ite.wthr.x = ite.wthr.x * ite.thr.x;
316  ite.wthr.x = ite.wthr.y * ite.thr.y;
317  ite.wthr.x = ite.wthr.z * ite.thr.z;
318  ite.thr.x = 1;
319  ite.thr.y = 1;
320  ite.thr.z = 1;
321  }
322 }
323 
324 #endif
325 
326 #include "copy_grid_fast.hpp"
327 
328 template<typename T>
330 {
331  template<typename grid_type>
332  static void call(grid_type & gd, const grid_type & gs, const Box<grid_type::dims,size_t> & box_src, const Box<grid_type::dims,size_t> & box_dst)
333  {
334  std::cout << "Error: " << __FILE__ << ":" << __LINE__ << " copy_grid_fast_caller failure" << std::endl;
335  }
336 };
337 
338 template<int ... prp>
340 {
341  template<typename grid_type>
342  static void call(grid_type & gd, const grid_type & gs, const Box<grid_type::dims,size_t> & box_src, const Box<grid_type::dims,size_t> & box_dst)
343  {
345  cnt[0].zero();
346 
347  typedef typename std::remove_reference<decltype(gd)>::type grid_cp;
348  typedef typename std::remove_reference<decltype(gd.getGrid())>::type grid_info_cp;
349 
351 
354  grid_cp,
355  grid_info_cp>::copy(gs.getGrid(),
356  gd.getGrid(),
357  box_src,
358  box_dst,
359  gs,gd,cnt);
360  }
361 };
362 
373 template<unsigned int dim,
374  typename T,
375  typename S,
376  template<typename> class layout_base,
377  typename ord_type = grid_sm<dim,void> >
379 {
381  typedef typename layout_base<T>::type layout;
382 
383  typedef typename apply_transform<layout_base,T>::type T_;
384 
385 public:
386 
389 
391  static constexpr unsigned int dims = dim;
392 
395 
397  typedef typename T::type T_type;
398 
400  typedef layout_base<T> layout_base_;
401 
402  typedef ord_type linearizer_type;
403 
404  typedef T background_type;
405 
406 protected:
407 
410 
412  ord_type g1;
413 
414 private:
415 
417  bool is_mem_init = false;
418 
421 
422 #ifdef SE_CLASS1
423 
428  inline void check_init() const
429  {
430 #ifndef __CUDA_ARCH__
431  if (is_mem_init == false)
432  {
433  std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " you must call SetMemory before access the grid\n";
434  ACTION_ON_ERROR(GRID_ERROR_OBJECT);
435  }
436 #endif
437  }
438 
444  inline void check_bound(const grid_key_dx<dim> & v1) const
445  {
446 #ifndef __CUDA_ARCH__
447  for (long int i = 0 ; i < dim ; i++)
448  {
449  if (v1.get(i) >= (long int)getGrid().size(i))
450  {
451  std::cerr << "Error " __FILE__ << ":" << __LINE__ <<" grid overflow " << "x=[" << i << "]=" << v1.get(i) << " >= " << getGrid().size(i) << "\n";
452  ACTION_ON_ERROR(GRID_ERROR_OBJECT);
453  }
454  else if (v1.get(i) < 0)
455  {
456  std::cerr << "Error " __FILE__ << ":" << __LINE__ <<" grid overflow " << "x=[" << i << "]=" << v1.get(i) << " is negative " << "\n";
457  ACTION_ON_ERROR(GRID_ERROR_OBJECT);
458  }
459  }
460 #endif
461  }
462 
468  inline void check_bound(size_t v1) const
469  {
470 #ifndef __CUDA_ARCH__
471  if (v1 >= getGrid().size())
472  {
473  std::cerr << "Error " __FILE__ << ":" << __LINE__ <<" grid overflow " << v1<< " >= " << getGrid().size() << "\n";
474  ACTION_ON_ERROR(GRID_ERROR_OBJECT);
475  }
476 #endif
477  }
478 
487  template<typename Mem> inline void check_bound(const grid_base_impl<dim,T,Mem,layout_base, ord_type> & g,const grid_key_dx<dim> & key2) const
488  {
489 #ifndef __CUDA_ARCH__
490  for (size_t i = 0 ; i < dim ; i++)
491  {
492  if (key2.get(i) >= (long int)g.getGrid().size(i))
493  {
494  std::cerr << "Error " __FILE__ << ":" << __LINE__ <<" grid overflow " << "x=[" << i << "]=" << key2.get(i) << " >= " << g.getGrid().size(i) << "\n";
495  ACTION_ON_ERROR(GRID_ERROR_OBJECT);
496  }
497  else if (key2.get(i) < 0)
498  {
499  std::cerr << "Error " __FILE__ << ":" << __LINE__ <<" grid overflow " << "x=[" << i << "]=" << key2.get(i) << " is negative " << "\n";
500  ACTION_ON_ERROR(GRID_ERROR_OBJECT);
501  }
502  }
503 #endif
504  }
505 
514  template<typename Mem, template <typename> class layout_base2>
515  inline void check_bound(const grid_base_impl<dim,T,Mem,layout_base2,ord_type> & g,const grid_key_dx<dim> & key2) const
516  {
517 #ifndef __CUDA_ARCH__
518  for (size_t i = 0 ; i < dim ; i++)
519  {
520  if (key2.get(i) >= (long int)g.getGrid().size(i))
521  {
522  std::cerr << "Error " __FILE__ << ":" << __LINE__ <<" grid overflow " << "x=[" << i << "]=" << key2.get(i) << " >= " << g.getGrid().size(i) << "\n";
523  ACTION_ON_ERROR(GRID_ERROR_OBJECT);
524  }
525  else if (key2.get(i) < 0)
526  {
527  std::cerr << "Error " __FILE__ << ":" << __LINE__ <<" grid overflow " << "x=[" << i << "]=" << key2.get(i) << " is negative " << "\n";
528  ACTION_ON_ERROR(GRID_ERROR_OBJECT);
529  }
530  }
531 #endif
532  }
533 
542  template<typename Mem> inline void check_bound(const grid_base_impl<dim,T,Mem,layout_base> & g,const size_t & key2) const
543  {
544 #ifndef __CUDA_ARCH__
545  if (key2 >= g.getGrid().size())
546  {
547  std::cerr << "Error " __FILE__ << ":" << __LINE__ <<" grid overflow " << key2 << " >= " << getGrid().size() << "\n";
548  ACTION_ON_ERROR(GRID_ERROR_OBJECT);
549  }
550 #endif
551  }
552 
553 #endif
554 
555  void resize_impl_device(const size_t (& sz)[dim],grid_base_impl<dim,T,S,layout_base,ord_type> & grid_new, unsigned int blockSize = 1)
556  {
557 #if defined(CUDA_GPU) && defined(__NVCC__)
558 
559  // Compile time-cheking that make sense to call a GPU kernel to copy.
560 
561 
562  grid_key_dx<dim> start;
563  grid_key_dx<dim> stop;
564 
565  for (size_t i = 0 ; i < dim ; i++)
566  {
567  start.set_d(i,0);
568 
569  // take the smallest
570  if (grid_new.g1.size(i) < sz[i])
571  {stop.set_d(i,grid_new.g1.size(i)-1);}
572  else
573  {stop.set_d(i,sz[i]-1);}
574  }
575 
576  copy_grid_to_grid<S>(grid_new,*this,start,stop,blockSize);
577 
578 #else
579 
580  std::cout << __FILE__ << ":" << __LINE__ << " error: the function resize require the launch of a kernel, but it seem that this" <<
581  " file (grid_base_implementation.hpp) has not been compiled with NVCC " << std::endl;
582 
583 #endif
584  }
585 
586  void resize_impl_host(const size_t (& sz)[dim], grid_base_impl<dim,T,S,layout_base,ord_type> & grid_new)
587  {
588  size_t sz_c[dim];
589  for (size_t i = 0 ; i < dim ; i++)
590  {sz_c[i] = (g1.size(i) < sz[i])?g1.size(i):sz[i];}
591 
592  grid_sm<dim,void> g1_c(sz_c);
593 
595  grid_key_dx_iterator<dim> it(g1_c);
596 
597  while(it.isNext())
598  {
599  // get the grid key
600  grid_key_dx<dim> key = it.get();
601 
602  // create a copy element
603 
604  grid_new.get_o(key) = this->get_o(key);
605 
606  ++it;
607  }
608  }
609 
611  {
613  if (isExternal == true)
614  {
615  mem_setext<typename std::remove_reference<decltype(grid_new)>::type,S,layout_base<T>,decltype(data_)>::set(grid_new,*this,this->data_);
616  }
617  else
618  grid_new.setMemory();
619 
620 #if defined(CUDIFY_USE_SEQUENTIAL) || defined(CUDIFY_USE_OPENMP)
621 
623 
624 #endif
625  }
626 
627 public:
628 
629  // Implementation of packer and unpacker for grid
630  #include "grid_pack_unpack.ipp"
631 
633  typedef int yes_i_am_grid;
634 
637 
639  // you can access all the properties of T
641 
643  typedef T value_type;
644 
647  :g1(0),isExternal(false)
648  {
649  // Add this pointer
650  }
651 
659  :isExternal(false)
660  {
661  this->operator=(g);
662  }
663 
669  grid_base_impl(const size_t & sz) THROW
670  :g1(sz),isExternal(false)
671  {
672  // Add this pointer
673  }
674 
682  grid_base_impl(const size_t (& sz)[dim]) THROW
683  :g1(sz),isExternal(false)
684  {
685  // Add this pointer
686  }
687 
690  {
691  // delete this pointer
692  }
693 
702  {
703  swap(g.duplicate());
704 
705 #if defined(CUDIFY_USE_SEQUENTIAL) || defined(CUDIFY_USE_OPENMP)
706 
709 
710 #endif
711 
712  return *this;
713  }
714 
723  {
724  swap(g);
725 
726 #if defined(CUDIFY_USE_SEQUENTIAL) || defined(CUDIFY_USE_OPENMP)
727 
729 
730 #endif
731 
732  return *this;
733  }
734 
743  {
744  // check if the have the same size
745  if (g1 != g.g1)
746  return false;
747 
748  auto it = getIterator();
749 
750  while (it.isNext())
751  {
752  auto key = it.get();
753 
754  if (this->get_o(key) != g.get_o(key))
755  return false;
756 
757  ++it;
758  }
759 
760  return true;
761  }
762 
769  {
771 
772  grid_base_impl<dim,T,S,layout_base> grid_new(g1.getSize());
773 
775  grid_new.setMemory();
776 
777  // We know that, if it is 1D we can safely copy the memory
778 // if (dim == 1)
779 // {
781 // grid_new.data_.mem->copy(*data_.mem);
782 // }
783 // else
784 // {
786 
789 
790  while(it.isNext())
791  {
792  grid_new.set(it.get(),*this,it.get());
793 
794  ++it;
795  }
796 // }
797 
798  // copy grid_new to the base
799 
800  return grid_new;
801  }
802 
803 #ifdef CUDA_GPU
804 
811  struct ite_gpu<dim> getGPUIterator(const grid_key_dx<dim,long int> & key1, const grid_key_dx<dim,long int> & key2, size_t n_thr = default_kernel_wg_threads_) const
812  {
813  return getGPUIterator_impl<dim>(g1,key1,key2,n_thr);
814  }
815 
816 #endif
817 
821  int size(int i) const
822  {
823  return g1.size(i);
824  }
825 
834  const ord_type & getGrid() const
835  {
836  return g1;
837  }
838 
847  void setMemory()
848  {
849  mem_setm<S,layout_base<T>,decltype(this->data_),decltype(this->g1)>::setMemory(data_,g1,is_mem_init);
850 
851 #if defined(CUDIFY_USE_SEQUENTIAL) || defined(CUDIFY_USE_OPENMP)
852 
854 
855 #endif
856 
857  }
858 
866  template<unsigned int p>
867  auto getMemory() -> decltype(boost::fusion::at_c<p>(data_).getMemory())
868  {
869  return boost::fusion::at_c<p>(data_).getMemory();
870  }
871 
883  template<unsigned int p = 0> void setMemory(S & m)
884  {
886  isExternal = true;
887 
888  bool skip_ini = skip_init<has_noPointers<T>::value,T>::skip_();
889 
890  mem_setmemory<decltype(data_),S,layout_base<T>>::template setMemory<p>(data_,m,g1.size(),skip_ini);
891 
892  is_mem_init = true;
893 
894 #if defined(CUDIFY_USE_SEQUENTIAL) || defined(CUDIFY_USE_OPENMP)
895 
897 
898 #endif
899  }
900 
912  void setMemoryArray(S * m)
913  {
915  isExternal = true;
916 
917  bool skip_ini = skip_init<has_noPointers<T>::value,T>::skip_();
918 
919  mem_setmemory<decltype(data_),S,layout_base<T>>::setMemoryArray(*this,m,g1.size(),skip_ini);
920 
921  is_mem_init = true;
922 
923 #if defined(CUDIFY_USE_SEQUENTIAL) || defined(CUDIFY_USE_OPENMP)
924 
926 
927 #endif
928  }
929 
938  template<unsigned int p = 0> void * getPointer()
939  {
940  return mem_getpointer<decltype(data_),layout_base_>::template getPointer<p>(data_);
941  }
942 
951  template<unsigned int p = 0> const void * getPointer() const
952  {
953  return mem_getpointer<decltype(data_),layout_base_>::template getPointer<p>(data_);
954  }
955 
956 
964  template <unsigned int p, typename r_type=decltype(layout_base<T>::template get<p>(data_,g1,grid_key_dx<dim>()))>
965  inline r_type insert(const grid_key_dx<dim> & v1)
966  {
967 #ifdef SE_CLASS1
968  check_init();
969  check_bound(v1);
970 #endif
971  return this->get<p>(v1);
972  }
973 
974 
982  template <unsigned int p, typename r_type=decltype(layout_base<T>::template get<p>(data_,g1,grid_key_dx<dim>()))>
983  __device__ __host__ inline r_type get_usafe(const grid_key_dx<dim> & v1)
984  {
985 #ifdef SE_CLASS1
986  check_init();
987 #endif
988  return layout_base<T>::template get<p>(data_,g1,v1);
989  }
990 
996  {
997  return 1;
998  }
999 
1006  void setGPUInsertBuffer(unsigned int nb, unsigned int nt)
1007  {}
1008 
1016  template <unsigned int p, typename r_type=decltype(layout_base<T>::template get_c<p>(data_,g1,grid_key_dx<dim>()))>
1017  __device__ __host__ inline r_type get_unsafe(const grid_key_dx<dim> & v1) const
1018  {
1019 #ifdef SE_CLASS1
1020  check_init();
1021 #endif
1022  return layout_base<T>::template get_c<p>(data_,g1,v1);
1023  }
1024 
1032  template <unsigned int p, typename r_type=decltype(layout_base<T>::template get<p>(data_,g1,grid_key_dx<dim>()))>
1033  __device__ __host__ inline r_type get(const grid_key_dx<dim> & v1)
1034  {
1035 #ifdef SE_CLASS1
1036  check_init();
1037  check_bound(v1);
1038 #endif
1039  return layout_base<T>::template get<p>(data_,g1,v1);
1040  }
1041 
1049  __device__ __host__ inline unsigned char getFlag(const grid_key_dx<dim> & v1) const
1050  {
1051  return 0;
1052  }
1053 
1061  template <unsigned int p, typename r_type=decltype(layout_base<T>::template get_c<p>(data_,g1,grid_key_dx<dim>()))>
1062  __device__ __host__ inline r_type get(const grid_key_dx<dim> & v1) const
1063  {
1064 #ifdef SE_CLASS1
1065  check_init();
1066  check_bound(v1);
1067 #endif
1068  return layout_base<T>::template get_c<p>(data_,g1,v1);
1069  }
1070 
1078  template <unsigned int p, typename r_type=decltype(layout_base<T>::template get_lin<p>(data_,g1,0))>
1079  __device__ __host__ inline r_type get(const size_t lin_id)
1080  {
1081 #ifdef SE_CLASS1
1082  check_init();
1083  check_bound(lin_id);
1084 #endif
1085  return layout_base<T>::template get_lin<p>(data_,g1,lin_id);
1086  }
1087 
1095  template <unsigned int p, typename r_type=decltype(layout_base<T>::template get_lin<p>(data_,g1,0))>
1096  __device__ __host__ inline const r_type get(size_t lin_id) const
1097  {
1098 #ifdef SE_CLASS1
1099  check_init();
1100  check_bound(lin_id);
1101 #endif
1102  return layout_base<T>::get_lin_const(data_,g1,lin_id);
1103  }
1104 
1105 
1118  {
1119 #ifdef SE_CLASS1
1120  check_init();
1121  check_bound(v1);
1122 #endif
1123  return mem_geto<dim,T,layout_base<T>,decltype(this->data_),decltype(this->g1),decltype(v1)>::get(data_,g1,v1);
1124  }
1125 
1137  inline const encapc<dim,T,layout> get_o(const grid_key_dx<dim> & v1) const
1138  {
1139 #ifdef SE_CLASS1
1140  check_init();
1141  check_bound(v1);
1142 #endif
1143  return mem_geto<dim,T,layout_base<T>,decltype(this->data_),decltype(this->g1),decltype(v1)>
1144  ::get(const_cast<typename std::add_lvalue_reference<decltype(this->data_)>::type>(data_),
1145  g1,v1);
1146  }
1147 
1148 
1161  {
1162 #ifdef SE_CLASS1
1163  check_init();
1164  check_bound(v1);
1165 #endif
1166  return mem_geto<dim,T,layout_base<T>,decltype(this->data_),decltype(this->g1),decltype(v1)>::get(data_,g1,v1);
1167  }
1168 
1180  inline encapc<dim,T,layout> get_o(size_t v1)
1181  {
1182 #ifdef SE_CLASS1
1183  check_init();
1184  check_bound(v1);
1185 #endif
1186  return mem_geto<dim,T,layout_base<T>,decltype(this->data_),decltype(this->g1),decltype(v1)>::get_lin(data_,v1);
1187  }
1188 
1200  inline const encapc<dim,T,layout> get_o(size_t v1) const
1201  {
1202 #ifdef SE_CLASS1
1203  check_init();
1204  check_bound(v1);
1205 #endif
1206  return mem_geto<dim,T,layout_base<T>,decltype(this->data_),decltype(this->g1),decltype(v1)>
1207  ::get_lin(const_cast<typename std::add_lvalue_reference<decltype(this->data_)>::type>(data_),v1);
1208  }
1209 
1217  template<int prp>
1218  void fill(unsigned char fl)
1219  {
1220  if (prp != 0 || is_layout_mlin<layout_base<T>>::type::value == false)
1221  {
1222  std::cout << "Error: " << __FILE__ << ":" << __LINE__ << " unsupported fill operation " << std::endl;
1223  }
1224 
1225  memset(getPointer(),fl,size() * sizeof(T));
1226  }
1227 
1235  void remove(Box<dim,long int> & section_to_delete)
1236  {}
1237 
1244  {
1245  }
1246 
1253  {
1254  return false;
1255  }
1256 
1270  const Box<dim,long int> & box_src,
1271  const Box<dim,long int> & box_dst)
1272  {
1273  // fix box_dst
1274 
1275  Box<dim,size_t> box_src_;
1276  Box<dim,size_t> box_dst_;
1277 
1278  for (size_t i = 0 ; i < dim ; i++)
1279  {
1280  if (box_dst.getHigh(i) >= (long int)g1.size(i))
1281  {
1282  long int shift = box_dst.getHigh(i) - g1.size(i) + 1;
1283  box_dst_.setHigh(i,box_dst.getHigh(i) - shift);
1284  box_src_.setHigh(i,box_src.getHigh(i) - shift);
1285  }
1286  else
1287  {
1288  box_dst_.setHigh(i,box_dst.getHigh(i));
1289  box_src_.setHigh(i,box_src.getHigh(i));
1290  }
1291 
1292  if (box_dst.getLow(i) < 0)
1293  {
1294  long int shift = -box_dst.getLow(i);
1295  box_dst_.setLow(i,box_dst.getLow(i) - shift);
1296  box_src_.setLow(i,box_src.getLow(i) - shift);
1297  }
1298  else
1299  {
1300  box_dst_.setLow(i,box_dst.getLow(i));
1301  box_src_.setLow(i,box_src.getLow(i));
1302  }
1303  }
1304 
1305  typedef typename to_int_sequence<0,T::max_prop>::type result;
1306 
1307  copy_grid_fast_caller<result>::call(*this,grid_src,box_src_,box_dst_);
1308 
1309 /* copy_grid_fast<!is_contiguos<prp...>::type::value || has_pack_gen<typename device_grid::value_type>::value,
1310  dim,
1311  grid_cp,
1312  grid_info_cp>::copy(grid_src.getGrid(),
1313  this->getGrid(),
1314  box_src,
1315  box_dst,
1316  grid_src,*this,cnt);*/
1317 
1319  }
1320 
1331  template<unsigned int ... prp>
1333  const Box<dim,size_t> & box_src,
1334  const Box<dim,size_t> & box_dst)
1335  {
1336  typedef typename std::remove_reference<decltype(grid_src)>::type grid_cp;
1337  typedef typename std::remove_reference<decltype(grid_src.getGrid())>::type grid_info_cp;
1338 
1339  grid_key_dx<dim> cnt[1];
1340  cnt[0].zero();
1341 
1342  copy_grid_fast<!is_contiguos<prp...>::type::value || has_pack_gen<T>::value,
1343  dim,
1344  grid_cp,
1345  grid_info_cp>::copy(grid_src.getGrid(),
1346  this->getGrid(),
1347  box_src,
1348  box_dst,
1349  grid_src,*this,cnt);
1350  }
1351 
1357  void clear()
1358  {}
1359 
1370  template<template<typename,typename> class op, unsigned int ... prp>
1372  const Box<dim,size_t> & bx_src,
1373  const Box<dim,size_t> & bx_dst)
1374  {
1375  grid_key_dx_iterator_sub<dim> sub_src(gs.getGrid(),bx_src.getKP1(),bx_src.getKP2());
1376  grid_key_dx_iterator_sub<dim> sub_dst(this->getGrid(),bx_dst.getKP1(),bx_dst.getKP2());
1377 
1378  while (sub_src.isNext())
1379  {
1380  // write the object in the last element
1381  object_si_di_op<op,decltype(gs.get_o(sub_src.get())),decltype(this->get_o(sub_dst.get())),OBJ_ENCAP,prp...>(gs.get_o(sub_src.get()),this->get_o(sub_dst.get()));
1382 
1383  ++sub_src;
1384  ++sub_dst;
1385  }
1386  }
1387 
1394  {return false;}
1395 
1410  void resize(const size_t (& sz)[dim], size_t opt = DATA_ON_HOST | DATA_ON_DEVICE, unsigned int blockSize = 1)
1411  {
1413 
1415 
1416  resize_impl_memset(grid_new);
1417 
1419 
1420  if (opt & DATA_ON_HOST)
1421  {resize_impl_host(sz,grid_new);}
1422 
1423  if (opt & DATA_ON_DEVICE && S::isDeviceHostSame() == false)
1424  {resize_impl_device(sz,grid_new,blockSize);}
1425 
1426 // }
1427 
1428  // copy grid_new to the base
1429 
1430  this->swap(grid_new);
1431  }
1432 
1444  void resize_no_device(const size_t (& sz)[dim])
1445  {
1447 
1449 
1450  resize_impl_memset(grid_new);
1451  resize_impl_host(sz,grid_new);
1452 
1453  this->swap(grid_new);
1454  }
1455 
1461  void remove(size_t key)
1462  {
1463  if (dim != 1)
1464  {
1465 #ifdef SE_CLASS1
1466  std::cerr << "Error: " << __FILE__ << " " << __LINE__ << " remove work only on dimension == 1 " << "\n";
1467 #endif
1468  return;
1469  }
1470 
1471  // It is safe to do a memory copy
1472 
1473  data_.move(&this->template get<0>());
1474  }
1475 
1509  {
1510  mem_swap<T,layout_base<T>,decltype(data_),decltype(grid)>::template swap_nomode<S>(data_,grid.data_);
1511 
1512  // exchange the grid info
1513  g1.swap(grid.g1);
1514 
1515  // exchange the init status
1516  bool exg = is_mem_init;
1517  is_mem_init = grid.is_mem_init;
1518  grid.is_mem_init = exg;
1519 
1520 #if defined(CUDIFY_USE_SEQUENTIAL) || defined(CUDIFY_USE_OPENMP)
1521 
1523 
1524 #endif
1525  }
1526 
1534  {
1535  mem_swap<T,layout_base<T>,decltype(data_),decltype(grid)>::swap(data_,grid.data_);
1536 
1537  // exchange the grid info
1538  g1.swap(grid.g1);
1539 
1540  // exchange the init status
1541  bool exg = is_mem_init;
1542  is_mem_init = grid.is_mem_init;
1543  grid.is_mem_init = exg;
1544 
1545  // exchange the is external status
1546  exg = isExternal;
1547  isExternal = grid.isExternal;
1548  grid.isExternal = exg;
1549 
1550 #if defined(CUDIFY_USE_SEQUENTIAL) || defined(CUDIFY_USE_OPENMP)
1551 
1554 
1555 #endif
1556  }
1557 
1568  {
1569  swap(grid);
1570  }
1571 
1578  template<unsigned int ... prp>
1579  __device__ __host__ inline void set(const grid_key_dx<dim> & key1,const grid_base_impl & g, const grid_key_dx<dim> & key2)
1580  {
1581  auto edest = this->get_o(key1);
1582  auto esrc = g.get_o(key2);
1583 
1584  copy_cpu_encap_encap_prp<decltype(g.get_o(key2)),decltype(this->get_o(key1)),prp...> ec(esrc,edest);
1585 
1586  boost::mpl::for_each_ref<boost::mpl::range_c<int,0,sizeof...(prp)>>(ec);
1587  }
1588 
1597  template<typename Memory> inline void set(grid_key_dx<dim> dx, const encapc<1,T,Memory> & obj)
1598  {
1599 #ifdef SE_CLASS1
1600  check_init();
1601  check_bound(dx);
1602 #endif
1603 
1604  // create the object to copy the properties
1606 
1607  // copy each property
1608  boost::mpl::for_each_ref< boost::mpl::range_c<int,0,T::max_prop> >(cp);
1609  }
1610 
1620  inline void set(grid_key_dx<dim> dx, const T & obj)
1621  {
1622 #ifdef SE_CLASS1
1623  check_init();
1624  check_bound(dx);
1625 #endif
1626 
1627  this->get_o(dx) = obj;
1628  }
1629 
1630 
1639  inline void set(const grid_key_dx<dim> & key1,
1641  const grid_key_dx<dim> & key2)
1642  {
1643 #ifdef SE_CLASS1
1644  check_init();
1645  check_bound(key1);
1646  check_bound(g,key2);
1647 #endif
1648 
1649  this->get_o(key1) = g.get_o(key2);
1650  }
1651 
1660  inline void set(const size_t key1,
1662  const size_t key2)
1663  {
1664 #ifdef SE_CLASS1
1665  check_init();
1666  check_bound(key1);
1667  check_bound(g,key2);
1668 #endif
1669 
1670  this->get_o(key1) = g.get_o(key2);
1671  }
1672 
1681  template<typename Mem> inline void set(const grid_key_dx<dim> & key1,const grid_base_impl<dim,T,Mem,layout_base> & g, const grid_key_dx<dim> & key2)
1682  {
1683 #ifdef SE_CLASS1
1684  check_init();
1685  check_bound(key1);
1686  check_bound(g,key2);
1687 #endif
1688 
1689  this->get_o(key1) = g.get_o(key2);
1690  }
1691 
1700  template<typename Mem, template <typename> class layout_base2> inline void set_general(const grid_key_dx<dim> & key1,
1702  const grid_key_dx<dim> & key2)
1703  {
1704 #ifdef SE_CLASS1
1705  check_init();
1706  check_bound(key1);
1707  check_bound(g,key2);
1708 #endif
1709 
1710  this->get_o(key1) = g.get_o(key2);
1711  }
1712 
1718  inline size_t size() const
1719  {
1720  return g1.size();
1721  }
1722 
1734  {
1735  return g1.getSubIterator(start,stop);
1736  }
1737 
1748  {
1750  }
1751 
1760  {
1761  size_t sz[dim];
1762 
1763  for (int i = 0 ; i < dim ; i++)
1764  {sz[i] = g1.size(i);}
1765 
1766  grid_sm<dim,void> gvoid(sz);
1767 
1768  return grid_key_dx_iterator<dim>(gvoid);
1769  }
1770 
1775  template<unsigned int ... prp> void deviceToHost()
1776  {
1777  layout_base<T>::template deviceToHost<decltype(data_), prp ...>(data_,0,this->getGrid().size() - 1);
1778  }
1779 
1784  template<unsigned int ... prp> void deviceToHost(size_t start, size_t stop)
1785  {
1786  layout_base<T>::template deviceToHost<decltype(data_), prp ...>(data_,start,stop);
1787  }
1788 
1793  template<unsigned int ... prp> void hostToDeviceNUMA(size_t start, size_t stop)
1794  {
1795  #ifdef CUDIFY_USE_OPENMP
1796  grid_key_dx<dim> start_;
1797  grid_key_dx<dim> stop_;
1798 
1799  for (size_t i = 0 ; i < dim ; i++)
1800  {
1801  start_.set_d(i,start);
1802  stop_.set_d(i,stop);
1803  }
1804 
1805  auto ite = this->getGPUIterator(start_,stop_);
1806 
1807  // We have to carefull with openmp, numtiple thread can end up in numa
1808  copy_with_openmp_prp<decltype(this->toKernel()),typename std::remove_reference<decltype(*this)>::type,prp ...>(this->toKernel(),*this,ite);
1809  #else
1810  this->template hostToDevice<prp ...>(start,stop);
1811  #endif
1812  }
1813 
1818  template<unsigned int ... prp> void hostToDeviceNUMA()
1819  {
1820  #ifdef CUDIFY_USE_OPENMP
1821 
1822  grid_key_dx<dim> start_;
1823  grid_key_dx<dim> stop_;
1824 
1825  for (size_t i = 0 ; i < dim ; i++)
1826  {
1827  start_.set_d(i,0);
1828  stop_.set_d(i,this->g1.size() - 1);
1829  }
1830 
1831  auto ite = this->getGPUIterator(start_,stop_);
1832 
1833  // We have to carefull with openmp, numtiple thread can end up in numa
1834  copy_with_openmp_prp<decltype(this->toKernel()),typename std::remove_reference<decltype(*this)>::type,prp ...>(this->toKernel(),*this,ite);
1835  #else
1836  this->template hostToDevice<prp ...>();
1837  #endif
1838  }
1839 
1844  template<unsigned int ... prp> void hostToDevice(size_t start, size_t stop)
1845  {
1846  layout_base<T>::template hostToDevice<S, decltype(data_),prp ...>(data_,start,stop);
1847  }
1848 
1849 
1854  template<unsigned int ... prp> void hostToDevice()
1855  {
1856  layout_base<T>::template hostToDevice<S,decltype(data_),prp ...>(data_,0,this->getGrid().size() - 1);
1857  }
1858 
1859 #if defined(CUDIFY_USE_SEQUENTIAL) || defined(CUDIFY_USE_OPENMP)
1860 
1862 
1869  {
1871  }
1872 
1879  {
1881  }
1882 
1883 #else
1884 
1891  {
1893  }
1894 
1901  {
1903  }
1904 
1905 #endif
1906 
1914  template<unsigned int Np>
1916  getIteratorStencil(const grid_key_dx<dim> (& stencil_pnt)[Np]) const
1917  {
1919  }
1920 
1933  inline grid_key_dx_iterator_sub<dim> getIterator(const grid_key_dx<dim> & start, const grid_key_dx<dim> & stop, bool to_init = false) const
1934  {
1935  size_t sz[dim];
1936 
1937  for (int i = 0 ; i < dim ; i++)
1938  {sz[i] = g1.size(i);}
1939 
1940  grid_sm<dim,void> gvoid(sz);
1941 
1942  // get the starting point and the end point of the real domain
1943  return grid_key_dx_iterator_sub<dim>(gvoid,start,stop);
1944  }
1945 
1952  {
1953  return data_;
1954  }
1955 
1961  const layout & get_internal_data_() const
1962  {
1963  return data_;
1964  }
1965 
1972  {}
1973 
1981  template<unsigned int ... prp, typename context_type>
1982  void removeAddUnpackFinalize(const context_type& gpuContext, int opt)
1983  {}
1984 
1992  template<unsigned int ... prp, typename context_type>
1993  void removeCopyToFinalize(const context_type& gpuContext, int opt)
1994  {}
1995 
2000  void resetFlush()
2001  {}
2002 };
2003 
2004 
2005 #endif /* OPENFPM_DATA_SRC_GRID_GRID_BASE_IMPLEMENTATION_HPP_ */
This class represent an N-dimensional box.
Definition: Box.hpp:60
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:555
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:566
grid_key_dx< dim > getKP1() const
Get the point p1 as grid_key_dx.
Definition: Box.hpp:655
grid_key_dx< dim > getKP2() const
Get the point p12 as grid_key_dx.
Definition: Box.hpp:668
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:543
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:532
Implementation of a N-dimensional grid.
size_t size() const
return the size of the grid
layout layout_type
memory layout
void set(const grid_key_dx< dim > &key1, const grid_base_impl< dim, T, Mem, layout_base > &g, const grid_key_dx< dim > &key2)
Set an element of the grid from another element of another grid.
grid_key_dx_iterator< dim, stencil_offset_compute< dim, Np > > getIteratorStencil(const grid_key_dx< dim >(&stencil_pnt)[Np]) const
Return a grid iterator.
encapc< dim, T, layout > container
Object container for T, it is the return type of get_o it return a object type trough.
grid_base_impl< dim, T, S, layout_base > duplicate() const THROW
create a duplicated version of the grid
void remove(size_t key)
Remove one element valid only on 1D.
void hostToDeviceNUMA(size_t start, size_t stop)
Synchronize the memory buffer in the device with the memory in the host (respecting the NUMA domains)
__device__ __host__ r_type get_usafe(const grid_key_dx< dim > &v1)
Get the reference of the selected element.
void swap_nomode(grid_base_impl< dim, T, S, layout_base > &grid)
It swap the objects A become B and B become A using A.swap(B);.
bool operator==(const grid_base_impl< dim, T, S, layout_base > &g)
Compare two grids.
void set(grid_key_dx< dim > dx, const T &obj)
set an element of the grid
T::type T_type
boost::vector that describe the data type
void deviceToHost()
Synchronize the memory buffer in the device with the memory in the host.
void set(const size_t key1, const grid_base_impl< dim, T, S, layout_base > &g, const size_t key2)
Set an element of the grid from another element of another grid.
const grid_gpu_ker< dim, T_, layout_base, linearizer_type > toKernel() const
Convert the grid into a data-structure compatible for computing into GPU.
__device__ __host__ const r_type get(size_t lin_id) const
Get the const reference of the selected element.
void resetFlush()
It does nothing.
layout data_
Memory layout specification + memory chunk pointer.
void resize(const size_t(&sz)[dim], size_t opt=DATA_ON_HOST|DATA_ON_DEVICE, unsigned int blockSize=1)
Resize the grid.
grid_gpu_ker< dim, T_, layout_base, linearizer_type > toKernel()
Convert the grid into a data-structure compatible for computing into GPU.
ord_type g1
This is a structure that store all information related to the grid and how indexes are linearized.
__device__ __host__ r_type get_unsafe(const grid_key_dx< dim > &v1) const
Get the const reference of the selected element.
bool isSkipLabellingPossible()
This function check if keep geometry is possible for this grid.
void removeAddUnpackFinalize(const context_type &gpuContext, int opt)
In this case it does nothing.
const void * getPointer() const
Return a plain pointer to the internal data.
void removeCopyToFinalize(const context_type &gpuContext, int opt)
In this case it does nothing.
bool isExternal
The memory allocator is not internally created.
grid_base_impl(const grid_base_impl &g) THROW
create a grid from another grid
grid_key_dx_iterator_sub< dim > getIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop, bool to_init=false) const
Return a grid iterator over all points included between start and stop point.
__device__ __host__ r_type get(const grid_key_dx< dim > &v1) const
Get the const reference of the selected element.
auto getMemory() -> decltype(boost::fusion::at_c< p >(data_).getMemory())
Return the memory object.
r_type insert(const grid_key_dx< dim > &v1)
In this case insert is equivalent to get.
~grid_base_impl() THROW
Destructor.
void copy_to_op(const grid_base_impl< dim, T, S, layout_base > &gs, const Box< dim, size_t > &bx_src, const Box< dim, size_t > &bx_dst)
copy an external grid into a specific place into this grid
int yes_i_am_grid
it define that this data-structure is a grid
void set(const grid_key_dx< dim > &key1, const grid_base_impl< dim, T, S, layout_base > &g, const grid_key_dx< dim > &key2)
Set an element of the grid from another element of another grid.
T value_type
The object type the grid is storing.
void resize_impl_host(const size_t(&sz)[dim], grid_base_impl< dim, T, S, layout_base, ord_type > &grid_new)
__device__ __host__ void set(const grid_key_dx< dim > &key1, const grid_base_impl &g, const grid_key_dx< dim > &key2)
set only some properties
void setMemory()
Create the object that provide memory.
void hostToDevice()
Copy the memory from host to device.
int size(int i) const
Get the size if the grid in the direction i.
encapc< dim, T, layout > get_o(const grid_key_dx< dim > &v1)
Get the of the selected element as a boost::fusion::vector.
memory_traits_lin< typename T::type >::type memory_lin
Definition of the layout.
__device__ __host__ r_type get(const grid_key_dx< dim > &v1)
Get the reference of the selected element.
encapc< dim, T, layout > insert_o(const grid_key_dx< dim > &v1)
Get the of the selected element as a boost::fusion::vector.
grid_base_impl() THROW
Default constructor.
void * getPointer()
Return a plain pointer to the internal data.
grid_key_dx_iterator_sub< dim > getSubIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop) const
Return a sub-grid iterator.
const layout & get_internal_data_() const
return the internal data_
layout & get_internal_data_()
return the internal data_
void remove(Box< dim, long int > &section_to_delete)
Remove all the points in this region.
grid_base_impl< dim, T, S, layout_base > & operator=(const grid_base_impl< dim, T, S, layout_base > &g)
It copy a grid.
void copy_to_prp(const grid_base_impl< dim, T, S, layout_base > &grid_src, const Box< dim, size_t > &box_src, const Box< dim, size_t > &box_dst)
copy an external grid into a specific place into this grid
void swap(grid_base_impl< dim, T, S, layout_base, ord_type > &grid)
It swap the objects A become B and B become A using A.swap(B);.
encapc< dim, T, layout > get_o(size_t v1)
Get the of the selected element as a boost::fusion::vector.
void removeAddUnpackReset()
In this case it does nothing.
void copyRemoveReset()
Reset the queue to remove and copy section of grids.
grid_key_dx_iterator_sub< dim > getSubIterator(size_t m)
Return a sub-grid iterator.
void setMemory(S &m)
Set the object that provide memory from outside.
const ord_type & getGrid() const
Return the internal grid information.
layout_base< T > layout_base_
base layout type
grid_key_dx< dim > access_key
Access key.
void set(grid_key_dx< dim > dx, const encapc< 1, T, Memory > &obj)
set an element of the grid
grid_base_impl< dim, T, S, layout_base > & operator=(grid_base_impl< dim, T, S, layout_base > &&g)
It copy a grid.
void setGPUInsertBuffer(unsigned int nb, unsigned int nt)
No blocks here, it does nothing.
const encapc< dim, T, layout > get_o(const grid_key_dx< dim > &v1) const
Get the of the selected element as a boost::fusion::vector.
const encapc< dim, T, layout > get_o(size_t v1) const
Get the of the selected element as a boost::fusion::vector.
void set_general(const grid_key_dx< dim > &key1, const grid_base_impl< dim, T, Mem, layout_base2 > &g, const grid_key_dx< dim > &key2)
Set an element of the grid from another element of another grid.
int getBlockEdgeSize()
No blocks here, it return 1.
grid_key_dx_iterator< dim > getIterator() const
Return a grid iterator.
bool is_mem_init
Is the memory initialized.
void swap(grid_base_impl< dim, T, S, layout_base > &&grid)
It move the allocated object from one grid to another.
grid_base_impl(const size_t &sz) THROW
create a grid of size sz on each direction
void fill(unsigned char fl)
Fill the memory with the selected byte.
void clear()
It does nothing.
__device__ __host__ r_type get(const size_t lin_id)
Get the reference of the selected element.
void hostToDeviceNUMA()
Synchronize the memory buffer in the device with the memory in the host (respecting the NUMA domains)
void hostToDevice(size_t start, size_t stop)
Synchronize the memory buffer in the device with the memory in the host.
void copy_to(const grid_base_impl< dim, T, S, layout_base > &grid_src, const Box< dim, long int > &box_src, const Box< dim, long int > &box_dst)
copy an external grid into a specific place into this grid
void setMemoryArray(S *m)
Set the object that provide memory from outside.
layout_base< T >::type layout
memory layout
void resize_impl_memset(grid_base_impl< dim, T, S, layout_base, ord_type > &grid_new)
void resize_no_device(const size_t(&sz)[dim])
Resize the space.
__device__ __host__ unsigned char getFlag(const grid_key_dx< dim > &v1) const
Get the point flag (in this case just return 0)
void deviceToHost(size_t start, size_t stop)
Synchronize the memory buffer in the device with the memory in the host.
static bool is_unpack_header_supported()
Indicate that unpacking the header is supported.
static constexpr unsigned int dims
expose the dimansionality as a static const
grid_base_impl(const size_t(&sz)[dim]) THROW
Constructor.
This is a distributed grid.
static const unsigned int dims
Number of dimensions.
grid interface available when on gpu
bool isNext()
Check if there is the next element.
grid_key_dx< dim > get() const
Return the actual grid key iterator.
const grid_key_dx< dim > & get() const
Get the actual key.
bool isNext()
Check if there is the next element.
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:19
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition: grid_key.hpp:516
__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
This is a way to quickly copy a grid into another grid.
It return true if the object T require complex serialization.
Case memory_traits_lin.
Definition: Encap.hpp:926
Case memory_traits_lin.
Case memory_traits_lin.
Case memory_traits_lin.
It copy the properties from one object to another applying an operation.
It copy the properties from one object to another applying an operation.
to_variadic_impl< N+1, M, exit_::value, N >::type type
generate the boost::fusion::vector apply H on each term