OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
memory_c.hpp
1/*
2 * memory_c.hpp
3 *
4 * Created on: Aug 17, 2014
5 * Author: Pietro Incardona
6 */
7
8#include <boost/multi_array.hpp>
9#include <boost/fusion/mpl.hpp>
10#include <boost/fusion/include/mpl.hpp>
11#include <boost/mpl/vector.hpp>
12#include <array>
13#include <boost/mpl/pop_front.hpp>
14#include <boost/mpl/push_front.hpp>
15
16//#include "util/boost/boost_multi_array_openfpm.hpp"
17#include "util/multi_array_openfpm/multi_array_ref_openfpm.hpp"
18#include "util/ct_array.hpp"
19#include "memory_array.hpp"
20#include "memory/memory.hpp"
21
22#ifndef MEMORY_C_HPP_
23#define MEMORY_C_HPP_
24
25#define MEMORY_C_STANDARD 1
26#define MEMORY_C_REDUCED 2
27
28template<typename T, unsigned int impl = MEMORY_C_STANDARD, typename D = memory>
30{
31
32};
33
44template<typename T, typename D>
45class memory_c<T,MEMORY_C_STANDARD,D>
46{
52 bool manage_memory = true;
53
54 public:
55
58
60 typedef T& reference;
61
63 typedef T vtype;
64
67
70
76 void setMemory(memory & mem)
77 {
78 if (manage_memory)
79 {
80 if (this->mem != NULL)
81 {
82 this->mem->decRef();
83
84 if (this->mem->ref() == 0 && &mem != this->mem)
85 delete(this->mem);
86 }
87 mem.incRef();
88 }
89 this->mem = &mem;
90 }
91
99 {
100 mem = ref.mem;
101
102 if (manage_memory)
103 {mem->incRef();}
104
106 mem_r = ref.mem_r;
107
108 return true;
109 }
110
118 {
119 return *this->mem;
120 }
121
126 {
127 if (mem != 0)
128 {mem_r.set_pointer(mem->getDevicePointer());}
129 }
130
137 const memory& getMemory() const
138 {
139 return *this->mem;
140 }
141
145 bool allocate(const size_t sz, bool skip_initialization = false)
146 {
147 memory * mem = this->mem;
148
150 mem->resize( sz*sizeof(T) );
151
153 mem_r.initialize(mem->getPointer(),sz,mem->isInitialized() | skip_initialization);
154
155 return true;
156 }
157
159 memory_c(bool manage_memory = true)
160 :manage_memory(manage_memory),mem(NULL){}
161
164 {
165 // deinitialixe mem_r
166 if (manage_memory)
167 {
168 mem_r.deinit();
169 if (mem != NULL)
170 {
171 mem->decRef();
172
173 if (mem->ref() == 0)
174 delete(mem);
175 }
176 }
177 }
178
183 {
184 manage_memory = false;
185 }
186
192 void swap(memory_c & mem_obj)
193 {
194 // Save on temporal
195
196 void * mem_tmp = static_cast<void*>(mem);
197 mem = mem_obj.mem;
198 mem_obj.mem = static_cast<memory*>(mem_tmp);
199
200 mem_obj.mem_r.swap(mem_r);
201 }
202
208 template<typename Mem_type>
209 __host__ void swap_nomode(memory_c & mem_obj)
210 {
211 // It would be better a dynamic_cast, unfortunately nvcc
212 // does not accept it. It seems that for some reason nvcc want to
213 // produce device code out of this method. While it is true
214 // that this method is called inside a generic __device__ __host__
215 // function, tagging this method only __host__ does not stop
216 // nvcc from the intention to produce device code.
217 // The workaround is to use static_cast. Another workaround (to test)
218 // could be create a duplicate for_each function tagged only __host__ ,
219 // but I have to intention to duplicate code
220
221 Mem_type * mem_tmp = static_cast<Mem_type*>(mem);
222 mem_tmp->swap(*static_cast<Mem_type*>(mem_obj.mem));
223
224 mem_obj.mem_r.swap(mem_r);
225 }
226
227};
228
238template<typename T>
240{
241 typedef T type;
242};
243
244
250template<typename T, unsigned int N>
251struct mult
252{
253 enum { value = mult<T,N-1>::value * boost::mpl::at<T,boost::mpl::int_<N>>::type::value };
254};
255
256template <typename T>
257struct mult<T,1>
258{
259 enum { value = boost::mpl::at<T,boost::mpl::int_<1>>::type::value };
260};
261
262template<typename size_type, unsigned int dim>
263static inline std::array<size_type ,dim> zero_dims()
264{
265 std::array<size_type ,dim> dimensions;
266
267 // fill runtime, and the other dimensions
268 for (size_t i = 0 ; i < dim ; i++)
269 {dimensions[i] = 0;}
270
271 return dimensions;
272}
273
274template<unsigned int dim, typename size_type>
276{
277};
278
279template<typename size_type>
280struct array_ord<4,size_type>
281{
282 static constexpr size_type data[4] = {0,3,2,1};
283};
284
285template<typename size_type>
286struct array_ord<3,size_type>
287{
288 static constexpr size_type data[3] = {0,2,1};
289};
290
291template<typename size_type>
292struct array_ord<2,size_type>
293{
294 static constexpr size_type data[2] = {0,1};
295};
296
297template<unsigned int dim>
299{
300};
301
302template<>
303struct array_asc<4>
304{
305 static constexpr bool data[4] = {true,true,true,true};
306};
307
308template<>
309struct array_asc<3>
310{
311 static constexpr bool data[3] = {true,true,true};
312};
313
314template<>
315struct array_asc<2>
316{
317 static constexpr bool data[2] = {true,true};
318};
319
320
335template<typename T, typename D>
336class memory_c<multi_array<T>, MEMORY_C_STANDARD, D>
337{
343 bool manage_memory = true;
344
352 template<size_t index,size_t N> struct ascending
353 {
354 enum { value = true };
355 };
356
358 typedef typename boost::mpl::push_front<typename boost::mpl::pop_front<T>::type,boost::mpl::int_<-1>>::type Tv;
359
361 template<int S> using int_ = boost::mpl::int_<S>;
362
364 typedef typename boost::mpl::size<T> size_p;
365
367 template< typename S, unsigned int n> using at = boost::mpl::at<S,boost::mpl::int_<n> >;
368
369 typedef typename at<T,0>::type base;
370
372 typedef typename openfpm::multi_array_ref_openfpm<base,size_p::value,Tv>::size_type size_type;
373
374 public:
375
382 void setMemory(memory & mem)
383 {
384 if (manage_memory)
385 {
386 if (this->mem != NULL)
387 {
388 this->mem->decRef();
389
390 if (this->mem->ref() == 0 && &mem != this->mem)
391 delete(this->mem);
392 }
393 mem.incRef();
394 }
395 this->mem = &mem;
396 }
397
405 {
406 return *this->mem;
407 }
408
413 {
414 if (mem != NULL)
415 {mem_r.set_pointer(mem->getDevicePointer());}
416 }
417
418
425 bool bind_ref(const memory_c<multi_array<T>, MEMORY_C_STANDARD, D> & ref)
426 {
427 mem = ref.mem;
428 if (manage_memory)
429 {mem->incRef();}
430
432 mem_r = ref.mem_r;
433
434 return true;
435 }
436
443 bool allocate(const size_t sz, bool skip_initialization = false)
444 {
445 memory * mem = this->mem;
446
448 mem->resize( sz*mult<T,size_p::value-1>::value*sizeof(base) );
449
451 sz,
453
455 mem_r.swap(tmp);
456
457 return true;
458 }
459
462 typedef boost::multi_array<base,size_p::value> type;
463
466
469
471 memory_c(bool manage_memory = true)
472 :manage_memory(manage_memory),mem(NULL),
473 mem_r(static_cast<base *>(NULL),0,openfpm::ofp_storage_order())
474 {}
475
478 {
479 // Indicate that this memory_c does not manage the memory
480 if (manage_memory)
481 {
482 if (mem != NULL)
483 {
484 mem->decRef();
485 if (mem->ref() == 0)
486 delete(mem);
487 }
488 }
489 }
490
495 {
496 manage_memory = false;
497 }
498
500 void set_mem(memory & mem)
501 {
502 this->mem = &mem;
503 }
504
510 void swap(memory_c & mem_obj)
511 {
512 // Save on temporal
513
514 void * mem_tmp = static_cast<void*>(mem);
515 mem = mem_obj.mem;
516 mem_obj.mem = static_cast<D*>(mem_tmp);
517
518 mem_r.swap(mem_obj.mem_r);
519 }
520
521
531 template<typename Mem_type>
532 __host__ void swap_nomode(memory_c & mem_obj)
533 {
534 // It would be better a dynamic_cast, unfortunately nvcc
535 // does not accept it. It seems that for some reason nvcc want to
536 // produce device code out of this method. While it is true
537 // that this function is called inside a generic __device__ __host__
538 // function, tagging this method only __host__ does not stop
539 // nvcc from the intention to produce device code.
540 // The workaround is to use static_cast. Another workaround (to test)
541 // could be create a duplicate for_each function tagged only __host__ ,
542 // but I have to intention to duplicate code
543
544 Mem_type * mem_tmp = static_cast<Mem_type*>(mem);
545 mem_tmp->swap(*static_cast<Mem_type*>(mem_obj.mem));
546
547 mem_obj.mem_r.swap(mem_r);
548 }
549};
550
552template<typename T>
554{
555};
556
557
559template<typename T,size_t N1>
560struct array_to_vmpl<T[N1]>
561{
563 typedef boost::mpl::vector<T,boost::mpl::int_<N1>> prim_vmpl;
564};
565
566
568template<typename T,size_t N1,size_t N2>
569struct array_to_vmpl<T[N1][N2]>
570{
572 typedef boost::mpl::vector<T,boost::mpl::int_<N1>,
573 boost::mpl::int_<N2>> prim_vmpl;
574};
575
587template<typename T>
589{
590 // first we convert the type into a boost vector containing the primitive, followed by array dimension
591 typedef typename array_to_vmpl<T>::prim_vmpl prim_vmpl;
592
593 // Than we operate at compile-time the same operation memory_c<multi_array does
595 typedef typename boost::mpl::push_front<typename boost::mpl::pop_front<prim_vmpl>::type,boost::mpl::int_<-1>>::type vmpl;
596
597
598};
599
600#endif
601
Derivative second order on h (spacing)
This class give a representation to a chunk or memory.
void set_pointer(void *ptr_)
Set the internal pointer to the indicated chunk of memory.
void initialize(void *ptr, size_t sz, bool init)
Initialize the memory array.
void deinit()
Deinitialize the memory.
memory_array< T > mem_r
object that represent the memory as an array of objects T
Definition memory_c.hpp:69
bool bind_ref(const memory_c< T, MEMORY_C_STANDARD, D > &ref)
This function bind the memory_c to this memory_c as reference.
Definition memory_c.hpp:98
bool allocate(const size_t sz, bool skip_initialization=false)
This function allocate memory.
Definition memory_c.hpp:145
const memory & getMemory() const
This function get the object that allocate memory.
Definition memory_c.hpp:137
__host__ void swap_nomode(memory_c &mem_obj)
swap the memory
Definition memory_c.hpp:209
void switchToDevicePtr()
Switch the pointer to device pointer (if the memory has been already set)
Definition memory_c.hpp:125
memory_c(bool manage_memory=true)
constructor
Definition memory_c.hpp:159
memory * mem
object that allocate memory like HeapMemory or CudaMemory
Definition memory_c.hpp:66
void setMemory(memory &mem)
This function set the object that allocate memory.
Definition memory_c.hpp:76
T & reference
define a reference to T
Definition memory_c.hpp:60
void disable_manage_memory()
Disable the management of memory (it is used for toKernel views)
Definition memory_c.hpp:182
memory & getMemory()
This function get the object that allocate memory.
Definition memory_c.hpp:117
void swap(memory_c &mem_obj)
swap the memory
Definition memory_c.hpp:192
openfpm::multi_array_ref_openfpm< base, size_p::value, Tv >::size_type size_type
define size_type
Definition memory_c.hpp:372
void swap(memory_c &mem_obj)
swap the memory
Definition memory_c.hpp:510
void switchToDevicePtr()
Switch the pointer to device pointer.
Definition memory_c.hpp:412
openfpm::multi_array_ref_openfpm< base, boost::mpl::size< T >::value, Tv > mem_r
object that represent the memory as a multi-dimensional array of objects T
Definition memory_c.hpp:468
__host__ void swap_nomode(memory_c &mem_obj)
swap the memory
Definition memory_c.hpp:532
bool allocate(const size_t sz, bool skip_initialization=false)
This function allocate memory and associate the representation to mem_r.
Definition memory_c.hpp:443
boost::multi_array< base, size_p::value > type
Definition memory_c.hpp:462
void disable_manage_memory()
Disable the management of memory (it is used for toKernel views)
Definition memory_c.hpp:494
D * mem
Reference to an object to allocate memory.
Definition memory_c.hpp:465
boost::mpl::push_front< typenameboost::mpl::pop_front< T >::type, boost::mpl::int_<-1 > >::type Tv
Remove the first element.
Definition memory_c.hpp:358
boost::mpl::at< S, boost::mpl::int_< n > > at
Define "at" meta function without boost::mpl.
Definition memory_c.hpp:367
void set_mem(memory &mem)
set the device memory interface, the object that allocate memory
Definition memory_c.hpp:500
memory & getMemory()
This function get the object that allocate memory.
Definition memory_c.hpp:404
boost::mpl::int_< S > int_
define boost::mpl::int_ without boost::mpl
Definition memory_c.hpp:361
memory_c(bool manage_memory=true)
constructor
Definition memory_c.hpp:471
void setMemory(memory &mem)
This function set the object that allocate memory.
Definition memory_c.hpp:382
bool bind_ref(const memory_c< multi_array< T >, MEMORY_C_STANDARD, D > &ref)
This function bind the memory_c to this memory_c as reference.
Definition memory_c.hpp:425
boost::mpl::size< T > size_p
define the template vector size it give a number at compile time
Definition memory_c.hpp:364
virtual long int ref()=0
Return the actual reference counter.
virtual bool resize(size_t sz)=0
resize on device a buffer
virtual void * getDevicePointer()=0
Return the device pointer of the memory.
virtual bool isInitialized()=0
Return if the actual memory that is going to be allocated is already initialized.
virtual void incRef()=0
Increment the internal reference counter.
virtual void decRef()=0
Decrement the internal reference counter.
virtual void * getPointer()=0
return a data pointer
This class is a trick to indicate the compiler a specific specialization pattern.
Definition memory_c.hpp:240
convert a type into constant type
boost::mpl::vector< T, boost::mpl::int_< N1 >, boost::mpl::int_< N2 > > prim_vmpl
the internal array primitive information represented into a boost mpl vector
Definition memory_c.hpp:573
boost::mpl::vector< T, boost::mpl::int_< N1 > > prim_vmpl
the internal array primitive information represented into a boost mpl vector
Definition memory_c.hpp:563
Partial specialization for scalar N=0.
Definition memory_c.hpp:554
this class multiply all the elements in a boost::mpl::vector excluding the first element
Definition memory_c.hpp:252
OpenFPM use memory_c<multi_array<T> ..... > to implement the structure of array layout.
Definition memory_c.hpp:589
boost::mpl::push_front< typenameboost::mpl::pop_front< prim_vmpl >::type, boost::mpl::int_<-1 > >::type vmpl
Remove the first element (this is the Tv parameter of )
Definition memory_c.hpp:595