1/*
2 * grid_base_impl_layout.hpp
3 *
4 * Created on: May 2, 2016
5 * Author: i-bird
6 */
7
8#ifndef OPENFPM_DATA_SRC_GRID_GRID_BASE_IMPL_LAYOUT_HPP_
9#define OPENFPM_DATA_SRC_GRID_GRID_BASE_IMPL_LAYOUT_HPP_
10
11#include <boost/fusion/include/mpl.hpp>
12#include "memory_ly/memory_conf.hpp"
13#include <boost/fusion/include/for_each.hpp>
14#include "memory_ly/Encap.hpp"
15#include "Space/Shape/Box.hpp"
16
17/*! \brief this class is a functor for "for_each" algorithm
18 *
19 * This class is a functor for "for_each" algorithm. For each
20 * element of the boost::vector the operator() is called
21 *
22 * \param T Type of memory allocator
23 *
24 */
25
26template<typename S>
27struct allocate
28{
29 //! size to allocate
30 size_t sz;
31
32 //! constructor it fix the size
33 allocate(size_t sz)
34 :sz(sz){};
35
36 //! It call the allocate function for each member
37 template<typename T>
38 void operator()(T& t) const
39 {
40 //! Create and set the memory allocator
41 t.setMemory(*new S());
42
43 //! Allocate the memory and create the reppresentation
44 if (sz != 0) t.allocate(sz);
45 }
46};
47
48
49/*! \brief this class is a functor for "for_each" algorithm
50 *
51 * This class is a functor for "for_each" algorithm. For each
52 * element of the boost::vector the operator() is called
53 *
54 * \param T Type of memory allocator
55 *
56 */
57
58template<typename s_m>
59struct frswap
60{
61 s_m & swap_src;
62 s_m & swap_dst;
63
64 //! constructor
65 frswap(s_m & swap_dst, s_m & swap_src)
66 :swap_src(swap_src),swap_dst(swap_dst)
67 {};
68
69 //! It call the allocate function for each member
70 template<typename T>
71 void operator()(T& t) const
72 {
73 boost::fusion::at_c<T::value>(swap_dst).swap(boost::fusion::at_c<T::value>(swap_src));
74 }
75};
76
77
78/*! \brief this class is a functor for "for_each" algorithm
79 *
80 * This class is a functor for "for_each" algorithm. For each
81 * element of the boost::vector the operator() is called
82 *
83 * \param T Type of memory allocator
84 * \param Mem_type Memory type
85 *
86 */
87
88template<typename s_m, typename Mem_type>
89struct frswap_nomode
90{
91 s_m & swap_src;
92 s_m & swap_dst;
93
94 //! constructor
95 frswap_nomode(s_m & swap_dst, s_m & swap_src)
96 :swap_src(swap_src),swap_dst(swap_dst)
97 {};
98
99 //! It call the allocate function for each member
100 template<typename T>
101 void operator()(T& t) const
102 {
103 boost::fusion::at_c<T::value>(swap_dst).template swap_nomode<Mem_type>(boost::fusion::at_c<T::value>(swap_src));
104 }
105};
106
107//! Case memory_traits_lin
108template<typename S, typename layout, typename data_type, typename g1_type, unsigned int sel = 2*is_layout_mlin<layout>::value + is_layout_inte<layout>::value >
109struct mem_setm
110{
111 static inline void setMemory(data_type & data_, const g1_type & g1, bool & is_mem_init)
112 {
113 S * mem = new S();
114
115 //! Create and set the memory allocator
116 data_.setMemory(*mem);
117
118 //! Allocate the memory and create the representation
119 if (g1.size() != 0) data_.allocate(g1.size());
120
121 is_mem_init = true;
122 }
123};
124
125//! Case memory_traits_inte
126template<typename S, typename layout, typename data_type, typename g1_type>
127struct mem_setm<S,layout,data_type,g1_type,1>
128{
129 static inline void setMemory(data_type & data_, const g1_type & g1, bool & is_mem_init)
130 {
131 //! Create an allocate object
132 allocate<S> all(g1.size());
133
134 //! for each element in the vector allocate the buffer
135 boost::fusion::for_each(data_,all);
136
137 is_mem_init = true;
138 }
139};
140
141
142//! Case memory_traits_lin
143template<typename grid_type, typename S , typename layout, typename data_type, unsigned int sel = 2*is_layout_mlin<layout>::value + is_layout_inte<layout>::value >
144struct mem_setext
145{
146 static inline void set(grid_type & grid_new, grid_type & old, data_type & data_)
147 {
148 grid_new.setMemory(static_cast<S&>(data_.getMemory()));
149
150 // Create an empty memory allocator for the actual structure
151
152 old.setMemory();
153 }
154};
155
156/*! \brief this class is a functor for "for_each" algorithm
157 *
158 * This class is a functor for "for_each" algorithm. For each
159 * element of the boost::vector the operator() is called.
160 * Is mainly used to set each property with external memory
161 *
162 *
163 */
164template<typename grid_type, typename data_type, typename S>
165struct mem_setext_prp
166{
167 grid_type & grid_new;
168
169 grid_type & old;
170
171 data_type & data_;
172
173 /*! \brief constructor
174 *
175 *
176 *
177 */
178 inline mem_setext_prp(grid_type & g_new, grid_type & old, data_type & data_)
179 :grid_new(g_new),old(old),data_(data_)
180 {};
181
182 //! It call the copy function for each property
183 template<typename T>
184 inline void operator()(T& t)
185 {
186 grid_new.template setMemory<T::value>(static_cast<S&>(boost::fusion::at_c<T::value>(data_).getMemory()));
187
188
189 }
190};
191
192
193/*! \brief this class is a functor for "for_each" algorithm
194 *
195 * This class is a functor for "for_each" algorithm. For each
196 * element of the boost::vector the operator() is called.
197 * Is mainly used to set an external memory for each
198 *
199 *
200 */
201template<typename grid_type, typename Memory>
202struct mem_setarray
203{
204 grid_type & grid_new;
205
206 Memory * mem;
207
208 size_t sz;
209
210 bool np;
211
212 /*! \brief constructor
213 *
214 *
215 *
216 */
217 inline mem_setarray(grid_type & g_new, Memory * mem, size_t sz, bool np)
218 :grid_new(g_new),mem(mem),sz(sz),np(np)
219 {};
220
221 //! It call the copy function for each property
222 template<typename T>
223 inline void operator()(T& t)
224 {
225 grid_new.template setMemory<T::value>(mem[T::value]);
226
227 //! Allocate the memory and create the reppresentation
228 if (sz != 0) boost::fusion::at_c<T::value>(grid_new.get_internal_data_()).allocate(sz,np);
229 }
230};
231
232//! Case memory_traits_inte
233template<typename grid_type, typename S , typename layout, typename data_type>
234struct mem_setext<grid_type,S,layout,data_type,1>
235{
236 static inline void set(grid_type & grid_new, grid_type & old, data_type & data_)
237 {
238// std::cerr << __FILE__ << ":" << "__LINE__" << " Error, " << demangle(typeid(grid_type).name()) << " this structure does not support setting from external memory" << std::endl;
239 mem_setext_prp<grid_type,data_type,S> mst(grid_new,old,data_);
240
241 // Create an empty memory allocator for the actual structure
242 boost::mpl::for_each_ref<boost::mpl::range_c<int,0,grid_type::value_type::max_prop>>(mst);
243
244 old.setMemory();
245 }
246};
247
248
249//! Case memory_traits_lin
250template<typename T , typename layout, typename data_type, typename grid_type, unsigned int sel = 2*is_layout_mlin<layout>::value + is_layout_inte<layout>::value >
251struct mem_swap
252{
253 static inline void swap(data_type & data_dst, data_type & data_src)
254 {
255 // move the data
256 data_dst.swap(data_src);
257 }
258
259 template<typename Mem_type>
260 static inline void swap_nomode(data_type & data_dst, data_type & data_src)
261 {
262 // move the data
263 data_dst.swap_nomode(data_src);
264 }
265};
266
267//! Case memory_traits_inte
268template<typename T , typename layout, typename data_type, typename grid_type>
269struct mem_swap<T,layout,data_type,grid_type,1>
270{
271 static inline void swap(data_type & data_dst, data_type & data_src)
272 {
273 // swap the data for each property
274 frswap<decltype(data_dst)> sw(data_dst,data_src);
275
276 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,T::max_prop> >(sw);
277 }
278
279 template<typename Mem_type>
280 static inline void swap_nomode(data_type & data_dst, data_type & data_src)
281 {
282 // swap the data for each property
283 frswap_nomode<decltype(data_dst),Mem_type> sw(data_dst,data_src);
284
285 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,T::max_prop> >(sw);
286 }
287};
288
289template<typename data_type, typename layout, unsigned int sel = 2*is_layout_mlin<layout>::value + is_layout_inte<layout>::value>
290struct mem_getpointer
291{
292 template<unsigned int d> __device__ __host__ static void * getPointer(data_type & data_)
293 {
294 return data_.mem_r.get_pointer();
295 }
296
297 template<unsigned int d> __device__ __host__ static void * getPointer(const data_type & data_)
298 {
299 return data_.mem_r.get_pointer();
300 }
301};
302
303template<typename data_type, typename layout>
304struct mem_getpointer<data_type,layout,1>
305{
306 template<unsigned int p> __device__ __host__ static void * getPointer(data_type & data_)
307 {
308 return boost::fusion::at_c<p>(data_).mem_r.get_pointer();
309 }
310
311 template<unsigned int p> __device__ __host__ static const void * getPointer(const data_type & data_)
312 {
313 return boost::fusion::at_c<p>(data_).mem_r.get_pointer();
314 }
315};
316
317template<typename data_type, typename Mem_type, typename layout, unsigned int sel = 2*is_layout_mlin<layout>::value + is_layout_inte<layout>::value>
318struct mem_setmemory
319{
320 template<unsigned int d> static void setMemory(data_type & data_, Mem_type & m, size_t sz, bool np)
321 {
322 //! Create and set the memory allocator
323 data_.setMemory(m);
324
325 //! Allocate the memory and create the reppresentation
326 if (sz != 0) data_.allocate(sz,np);
327 }
328
329 static void setMemoryArray(data_type & data_, Mem_type * m, size_t sz, bool np)
330 {
331 //! Create and set the memory allocator
332 data_.setMemory(m[0]);
333
334 //! Allocate the memory and create the reppresentation
335 if (sz != 0) data_.allocate(sz,np);
336 }
337};
338
339template<typename data_type, typename Mem_type, typename layout>
340struct mem_setmemory<data_type,Mem_type,layout,1>
341{
342 template<unsigned int p> static void setMemory(data_type & data_, Mem_type & m, size_t sz,bool np)
343 {
344 //! Create and set the memory allocator
345 boost::fusion::at_c<p>(data_).setMemory(m);
346
347 //! Allocate the memory and create the reppresentation
348 if (sz != 0) boost::fusion::at_c<p>(data_).allocate(sz,np);
349 }
350
351 template<typename grid_type> static void setMemoryArray(grid_type & grid, Mem_type * m, size_t sz,bool np)
352 {
353 mem_setarray<grid_type,Mem_type> ma(grid,m,sz,np);
354
355 // Create an empty memory allocator for the actual structure
356 boost::mpl::for_each_ref<boost::mpl::range_c<int,0,grid_type::value_type::max_prop>>(ma);
357 }
358};
359
360
361#endif /* OPENFPM_DATA_SRC_GRID_GRID_BASE_IMPL_LAYOUT_HPP_ */
362