OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
Packer.hpp
1 /*
2  * Packer_cls.hpp
3  *
4  * Created on: Jul 15, 2015
5  * Author: i-bird
6  */
7 
8 #ifndef SRC_PACKER_HPP_
9 #define SRC_PACKER_HPP_
10 
11 
12 #include "util/cudify/cudify.hpp"
13 
14 #include "util/object_util.hpp"
15 //#include "Grid/util.hpp"
16 #include "Vector/util.hpp"
17 #include "memory/ExtPreAlloc.hpp"
18 #include "util/util_debug.hpp"
19 
20 #include "Grid/grid_sm.hpp"
21 #include "util/Pack_stat.hpp"
22 #include "Pack_selector.hpp"
23 #include "has_pack_encap.hpp"
24 #include "Packer_util.hpp"
25 
26 
27 template <typename> struct Debug;
28 
48 template<typename T, typename Mem, int pack_type >
49 class Packer
50 {
51 public:
52 
56  static void pack(ExtPreAlloc<Mem> , const T & obj)
57  {
58 #ifndef DISABLE_ALL_RTTI
59  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " packing for the type " << demangle(typeid(T).name()) << " is not implemented\n";
60 #endif
61  }
62 
66  static size_t packRequest(const T & obj, size_t & req)
67  {
68 #ifndef DISABLE_ALL_RTTI
69  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " packing for the type " << demangle(typeid(T).name()) << " is not implemented\n";
70 #endif
71  return 0;
72  }
73 };
74 
81 template<typename T, typename Mem>
82 class Packer<T,Mem,PACKER_PRIMITIVE>
83 {
84 public:
85 
93  inline static void pack(ExtPreAlloc<Mem> & ext, const T & obj, Pack_stat & sts)
94  {
95  ext.allocate(sizeof(T));
96  *(typename std::remove_const<T>::type *)ext.getPointer() = obj;
97 
98  // update statistic
99  sts.incReq();
100  }
101 
107  static void packRequest(const T & obj, size_t & req)
108  {
109  req += sizeof(T);
110  }
111 
117  static void packRequest(size_t & req)
118  {
119  req += sizeof(T);
120  }
121 };
122 
131 template<typename T, typename Mem>
132 class Packer<T,Mem,PACKER_ARRAY_PRIMITIVE>
133 {
134 public:
135 
143  inline static void pack(ExtPreAlloc<Mem> & ext, const T & obj, Pack_stat & sts, size_t n)
144  {
145  //Pack the size of a vector
146  Packer<size_t, Mem>::pack(ext,obj.size(),sts);
147 
148  //Pack a vector
149  ext.allocate(sizeof(typename T::value_type)*n);
150  memcpy(ext.getPointer(),obj.getPointer(),sizeof(typename T::value_type)*n);
151 
152  // update statistic
153  sts.incReq();
154  }
155 
161  static void packRequest(T & obj,size_t & req)
162  {
163  req += sizeof(typename T::value_type)*obj.size();
164  }
165 };
166 
167 
168 template<typename T, typename Mem>
169 class Packer<T,Mem,PACKER_ARRAY_CP_PRIMITIVE>
170 {
171 public:
172 
180  inline static void pack(ExtPreAlloc<Mem> & ext, const T & obj, Pack_stat & sts)
181  {
182  typedef typename std::remove_extent<T>::type prim_type;
183 
184  //Pack a vector
185  ext.allocate(sizeof(T));
186 
187  meta_copy<T>::meta_copy_(obj,(prim_type *)ext.getPointer());
188 
189  // update statistic
190  sts.incReq();
191  }
192 
200  template<typename tp, long unsigned int dim, typename vmpl>
201  inline static void pack(ExtPreAlloc<Mem> & ext,
203  Pack_stat & sts)
204  {
205  typedef typename std::remove_extent<T>::type prim_type;
206 
207  //Pack a vector
208  ext.allocate(sizeof(T));
209 
210  meta_copy<T>::meta_copy_(obj,(prim_type *)ext.getPointer());
211 
212  // update statistic
213  sts.incReq();
214  }
215 
221  static void packRequest(T & obj,size_t & req)
222  {
223  req += sizeof(T);
224  }
225 
231  template<typename tp, long unsigned int dim, typename vmpl>
233  size_t & req)
234  {
235  req += sizeof(T);
236  }
237 };
238 
245 template<typename T, typename Mem>
246 class Packer<T,Mem,PACKER_OBJECTS_WITH_WARNING_POINTERS>
247 {
248 public:
249 
257  static void pack(ExtPreAlloc<Mem> & ext, const T & obj, Pack_stat & sts)
258  {
259 #ifdef SE_CLASS1
260  if (ext.ref() == 0)
261  std::cerr << "Error : " << __FILE__ << ":" << __LINE__ << " the reference counter of mem should never be zero when packing \n";
262 
263  if (!(std::is_array<T>::value == true && std::is_fundamental<typename std::remove_all_extents<T>::type>::value == true))
264  std::cerr << "Warning: " << __FILE__ << ":" << __LINE__ << " impossible to check the type " << demangle(typeid(T).name()) << " please consider to add a static method like \"static bool noPointers() {return true;}\" \n" ;
265 #endif
266  ext.allocate(sizeof(T));
267  memcpy((typename std::remove_reference<T>::type *)ext.getPointer(),&obj,sizeof(T));
268 
269  // update statistic
270  sts.incReq();
271  }
272 
278  static void packRequest(const T & obj,size_t & req)
279  {
280  req += sizeof(T);
281  }
282 
288  static void packRequest(size_t & req)
289  {
290  req += sizeof(T);
291  }
292 };
293 
300 template<typename T, typename Mem>
301 class Packer<T,Mem,PACKER_OBJECTS_WITH_POINTER_CHECK>
302 {
303 public:
304 
312  static void pack(ExtPreAlloc<Mem> & ext, const T & obj, Pack_stat & sts)
313  {
314 #ifdef SE_CLASS1
315  if (ext.ref() == 0)
316  std::cerr << "Error : " << __FILE__ << ":" << __LINE__ << " the reference counter of mem should never be zero when packing \n";
317 
318  if (obj.noPointers() == false)
319  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " the type " << demangle(typeid(T).name()) << " has pointers inside, sending pointers values has no sense\n";
320 #endif
321  ext.allocate(sizeof(T));
322  memcpy((typename std::remove_const<T>::type *)ext.getPointer(),&obj,sizeof(T));
323 
324  // Update statistic
325  sts.incReq();
326  }
327 
333  static void packRequest(const T & obj,size_t & req)
334  {
335  req += sizeof(T);
336  }
337 
343  static void packRequest(size_t & req)
344  {
345  req += sizeof(T);
346  }
347 };
348 
355 template<typename T, typename Mem>
356 class Packer<T,Mem,PACKER_GENERAL>
357 {
358 public:
359 
360  template<int ... prp> static void packRequest(const T & obj, size_t & req)
361  {
362  obj.template packRequest<prp...>(req);
363  }
364 
365  template<int ... prp> static void pack(ExtPreAlloc<Mem> & mem, const T & obj, Pack_stat & sts)
366  {
367  obj.template pack<prp...>(mem, sts);
368  }
369 };
370 
377 template<typename T, typename Mem>
378 class Packer<T,Mem,PACKER_GRID>
379 {
380 public:
381 
382  template<int ... prp> static void packRequest(const T & obj, size_t & req)
383  {
384  obj.template packRequest<prp...>(req);
385  }
386 
387  template<typename grid_sub_it_type, int ... prp> static void packRequest(T & obj, grid_sub_it_type & sub, size_t & req)
388  {
389  obj.template packRequest<prp...>(sub, req);
390  }
391 
392  template<int ... prp> static void pack(ExtPreAlloc<Mem> & mem, const T & obj, Pack_stat & sts)
393  {
394  obj.template pack<prp...>(mem, sts);
395  }
396 
397  template<typename grid_sub_it_type, int ... prp> static void pack(ExtPreAlloc<Mem> & mem, T & obj, grid_sub_it_type & sub_it, Pack_stat & sts)
398  {
399  obj.template pack<prp...>(mem, sub_it, sts);
400  }
401 };
402 
403 template<typename T, typename Mem>
404 class Packer<T,Mem,PACKER_ENCAP_OBJECTS>
405 {
406 public:
407 
412  template<int ... prp> static void pack(ExtPreAlloc<Mem> & mem, const T & eobj, Pack_stat & sts)
413  {
414 #ifdef SE_CLASS1
415  if (mem.ref() == 0)
416  std::cerr << "Error : " << __FILE__ << ":" << __LINE__ << " the reference counter of mem should never be zero when packing \n";
417 #endif
418 
421  else
422  {
423  if (sizeof...(prp) == 0)
424  {
425  mem.allocate(sizeof(typename T::T_type));
426  encapc<1,typename T::T_type,typename memory_traits_lin< typename T::T_type >::type> enc(*static_cast<typename T::T_type::type *>(mem.getPointer()));
427  enc = eobj;
428  }
429  else
430  {
431  typedef object<typename object_creator<typename T::type,prp...>::type> prp_object;
432  mem.allocate(sizeof(prp_object));
433  encapc<1,prp_object,typename memory_traits_lin< prp_object >::type> enc(*static_cast<typename prp_object::type *>(mem.getPointer()));
434  object_si_d<T,decltype(enc),OBJ_ENCAP,prp ... >(eobj,enc);
435  }
436  }
437 
438  // update statistic
439  sts.incReq();
440  }
441 
446  template<int ... prp> void packRequest(T & eobj,size_t & req)
447  {
448  if (has_pack_encap<T>::value == true)
450  else
451  {
452  if (sizeof...(prp) == 0)
453  return;
454 
455  typedef object<typename object_creator<typename T::type,prp...>::type> prp_object;
456 
457  req += sizeof(prp_object);
458  }
459  }
460 };
461 
463 
464 template<typename Timpl>
466 {
467  template<typename T, typename e_src, typename e_dst>
468  static inline void call(const e_src & src, size_t sub_id, e_dst & dst)
469  {
470  // Remove the reference from the type to copy
471  typedef typename boost::remove_reference<decltype(dst.template get< T::value >())>::type copy_rtype;
472 
473  meta_copy<copy_rtype>::meta_copy_(src.template get< T::value >()[sub_id],dst.template get< T::value >());
474  }
475 };
476 
477 template<unsigned int N1, typename Timpl>
478 struct copy_packer_chunk_arr_impl<Timpl[N1]>
479 {
480  template<typename T, typename e_src, typename e_dst>
481  static inline void call(const e_src & src, size_t sub_id, e_dst & dst)
482  {
483  // Remove the reference from the type to copy
484  typedef typename boost::remove_reference<decltype(dst.template get< T::value >()[0])>::type copy_rtype;
485 
486  for (int i = 0 ; i < N1 ; i++)
487  {meta_copy<copy_rtype>::meta_copy_(src.template get< T::value >()[i][sub_id],dst.template get< T::value >()[i]);}
488  }
489 };
490 
492 template<typename e_src, typename e_dst>
494 {
496  const e_src & src;
498  e_dst & dst;
499 
501  size_t sub_id;
502 
510  inline copy_packer_chunk(const e_src & src, size_t sub_id, e_dst & dst)
511  :src(src),dst(dst),sub_id(sub_id)
512  {};
513 
514 
515 
517  template<typename T>
518  inline void operator()(T& t) const
519  {
520  // Remove the reference from the type to copy
521  typedef typename boost::remove_reference<decltype(dst.template get< T::value >())>::type copy_rtype;
522 
523  // meta_copy<copy_rtype>::meta_copy_(src.template get< T::value >()[sub_id],dst.template get< T::value >());
524 
526  }
527 };
528 
529 template <typename> struct Debug;
530 
531 template<bool is_not_zero, typename T, typename T_nc, int ... prp>
533 {
534  template<typename Mem> static inline void select(ExtPreAlloc<Mem> & mem, const T & eobj, size_t sub_id)
535  {
536  mem.allocate(sizeof(T_nc));
537  encapc<1,T_nc,typename memory_traits_lin< T_nc >::type> enc(*static_cast<typename T_nc::type *>(mem.getPointer()));
538  copy_packer_chunk<decltype(eobj),
540  boost::mpl::for_each_ref<boost::mpl::range_c<int,0,T::T_type::max_prop>>(cp);
541  //enc = eobj[sub_id];
542  }
543 };
544 
545 template<typename T, typename T_nc, int ... prp>
546 struct selector_chunking_prp_has_zero_size<true,T,T_nc,prp...>
547 {
548  template<typename Mem> static inline void select(ExtPreAlloc<Mem> & mem, const T & eobj, size_t sub_id)
549  {
550  // Here we create an encap without array extent
551  typedef object<typename object_creator_chunking<typename T::type,prp...>::type> prp_object;
552  mem.allocate(sizeof(prp_object));
553  encapc<1,prp_object,typename memory_traits_lin< prp_object>::type> enc(*static_cast<typename prp_object::type *>(mem.getPointer()));
554  object_si_d<T,decltype(enc),OBJ_ENCAP_CHUNKING,prp ... >(eobj,sub_id,enc);
555  }
556 };
557 
558 template<typename T, typename Mem>
559 class Packer<T,Mem,PACKER_ENCAP_OBJECTS_CHUNKING>
560 {
561 public:
562 
568  template<typename T_nc, int ... prp> static void pack(ExtPreAlloc<Mem> & mem, const T & eobj, size_t sub_id, Pack_stat & sts)
569  {
570 #ifdef SE_CLASS1
571  if (mem.ref() == 0)
572  std::cerr << "Error : " << __FILE__ << ":" << __LINE__ << " the reference counter of mem should never be zero when packing \n";
573 #endif
574 
577  else
578  {
579  selector_chunking_prp_has_zero_size<sizeof...(prp) != 0,T, T_nc, prp ...>::select(mem,eobj,sub_id);
580  }
581 
582  // update statistic
583  sts.incReq();
584  }
585 
590  template<int ... prp> void packRequest(T & eobj,size_t & req)
591  {
592  if (has_pack_encap<T>::value == true)
594  else
595  {
596  if (sizeof...(prp) == 0)
597  return;
598 
599  typedef object<typename object_creator<typename T::type,prp...>::type> prp_object;
600 
601  req += sizeof(prp_object);
602  }
603  }
604 };
605 
606 #endif /* SRC_PACKER_HPP_ */
static void packRequest(T &obj, size_t &req)
It add a request to pack a C++ primitive.
Definition: Packer.hpp:221
static void packRequest(const T &obj, size_t &req)
it add a request to pack an object
Definition: Packer.hpp:333
It copy one element of the chunk for each property.
Definition: Packer.hpp:493
virtual size_t size() const
Get the size of the LAST allocated memory.
__device__ static __host__ void meta_copy_(const T &src, T &dst)
copy and object from src to dst
Definition: meta_copy.hpp:60
static void packRequest(size_t &req)
It add a request to pack a C++ primitive.
Definition: Packer.hpp:117
const e_src & src
encapsulated object source
Definition: Packer.hpp:496
static void pack(ExtPreAlloc< Mem > &ext, const T &obj, Pack_stat &sts)
It pack any C++ primitives.
Definition: Packer.hpp:93
copy_packer_chunk(const e_src &src, size_t sub_id, e_dst &dst)
constructor
Definition: Packer.hpp:510
static void packRequest(const T &obj, size_t &req)
It add a request to pack a C++ primitive.
Definition: Packer.hpp:107
virtual void * getPointer()
Return the pointer of the last allocation.
e_dst & dst
encapsulated object destination
Definition: Packer.hpp:498
static void pack(ExtPreAlloc< Mem > &ext, const T &obj, Pack_stat &sts)
It packs arrays of C++ primitives.
Definition: Packer.hpp:180
static void packRequest(T &obj, size_t &req)
It add a request to pack a C++ primitive.
Definition: Packer.hpp:161
static void packRequest(size_t &req)
it add a request to pack an object
Definition: Packer.hpp:343
virtual bool allocate(size_t sz)
Allocate a chunk of memory.
Definition: Packer.hpp:27
virtual long int ref()
Return the reference counter.
static size_t packRequest(const T &obj, size_t &req)
Error, no implementation.
Definition: Packer.hpp:66
void incReq()
Increment the request pointer.
Definition: Pack_stat.hpp:79
Packing class.
Definition: Packer.hpp:49
static void packRequest(const T &obj, size_t &req)
it add a request to pack an object
Definition: Packer.hpp:278
static void pack(ExtPreAlloc< Mem > &mem, const T &eobj, size_t sub_id, Pack_stat &sts)
Pack the encapsulkated object.
Definition: Packer.hpp:568
static void pack(ExtPreAlloc< Mem > &ext, const T &obj, Pack_stat &sts)
It pack any object checking that the object does not have pointers inside.
Definition: Packer.hpp:312
size_t sub_id
element to copy
Definition: Packer.hpp:501
void operator()(T &t) const
It call the copy function for each property.
Definition: Packer.hpp:518
It create a boost::fusion vector with the selected properties.
static void pack(ExtPreAlloc< Mem > &ext, const openfpm::detail::multi_array::sub_array_openfpm< tp, dim, vmpl > &obj, Pack_stat &sts)
It packs arrays of C++ primitives.
Definition: Packer.hpp:201
static void pack(ExtPreAlloc< Mem > &ext, const T &obj, Pack_stat &sts, size_t n)
It packs arrays of C++ primitives.
Definition: Packer.hpp:143
static void packRequest(size_t &req)
it add a request to pack an object
Definition: Packer.hpp:288
Packing status object.
Definition: Pack_stat.hpp:60
static void pack(ExtPreAlloc< Mem >, const T &obj)
Error, no implementation.
Definition: Packer.hpp:56
static void packRequest(const openfpm::detail::multi_array::sub_array_openfpm< tp, dim, vmpl > &obj, size_t &req)
It add a request to pack a C++ primitive.
Definition: Packer.hpp:232
static void pack(ExtPreAlloc< Mem > &ext, const T &obj, Pack_stat &sts)
It pack an object.
Definition: Packer.hpp:257
It copy the properties from one object to another.
static void call_packRequest(encap &obj, size_t &req)
pack/serialize
Definition: Packer_util.hpp:71