1 | /* |
2 | * copy_grid_fast.hpp |
3 | * |
4 | * Created on: Nov 29, 2017 |
5 | * Author: i-bird |
6 | */ |
7 | |
8 | #ifndef OPENFPM_DATA_SRC_GRID_COPY_GRID_FAST_HPP_ |
9 | #define OPENFPM_DATA_SRC_GRID_COPY_GRID_FAST_HPP_ |
10 | |
11 | #include "Grid/iterators/grid_key_dx_iterator.hpp" |
12 | |
13 | template<unsigned int dim> |
14 | struct striding |
15 | { |
16 | size_t striding_src[dim - 1]; |
17 | size_t striding_dst[dim - 1]; |
18 | size_t n_cpy; |
19 | size_t tot_y; |
20 | }; |
21 | |
22 | //////////////////////////////////// Functor to copy 1D grid in device memory //////////// |
23 | |
24 | /*! \brief this class is a functor for "for_each" algorithm |
25 | * |
26 | * This class is a functor for "for_each" algorithm. For each |
27 | * element of the boost::vector the operator() is called. |
28 | * Is mainly used to copy one device memory into another device memory |
29 | * |
30 | * \tparam encap source |
31 | * \tparam encap dst |
32 | * |
33 | */ |
34 | template<bool lin_or_inte,typename data_type,typename S> |
35 | struct copy_fast_1d_device_memory |
36 | { |
37 | //! set of pointers |
38 | data_type & data_src; |
39 | |
40 | data_type & data_dst; |
41 | |
42 | /*! \brief constructor |
43 | * |
44 | * \param v set of pointer buffers to set |
45 | * |
46 | */ |
47 | inline copy_fast_1d_device_memory(data_type & data_src, data_type & data_dst) |
48 | :data_src(data_src),data_dst(data_dst) |
49 | {}; |
50 | |
51 | //! It call the copy function for each property |
52 | template<typename T> |
53 | inline void operator()(T& t) const |
54 | { |
55 | static_cast<S *>(boost::fusion::at_c<T::value>(data_dst).mem)->copyDeviceToDevice(*static_cast<S *>(boost::fusion::at_c<T::value>(data_src).mem)); |
56 | } |
57 | }; |
58 | |
59 | /*! \brief this class is a functor for "for_each" algorithm |
60 | * |
61 | * This class is a functor for "for_each" algorithm. For each |
62 | * element of the boost::vector the operator() is called. |
63 | * Is mainly used to copy one device memory into another device memory |
64 | * |
65 | * \tparam encap source |
66 | * \tparam encap dst |
67 | * |
68 | */ |
69 | template<typename data_type,typename S> |
70 | struct copy_fast_1d_device_memory<true,data_type,S> |
71 | { |
72 | //! set of pointers |
73 | data_type & data_src; |
74 | |
75 | data_type & data_dst; |
76 | |
77 | /*! \brief constructor |
78 | * |
79 | * \param v set of pointer buffers to set |
80 | * |
81 | */ |
82 | inline copy_fast_1d_device_memory(data_type & data_src, data_type & data_dst) |
83 | :data_src(data_src),data_dst(data_dst) |
84 | {}; |
85 | |
86 | //! It call the copy function for each property |
87 | template<typename T> |
88 | inline void operator()(T& t) const |
89 | { |
90 | if (T::value == 0) |
91 | { |
92 | static_cast<S *>(data_dst.mem)->copyDeviceToDevice(*static_cast<S *>(data_src.mem)); |
93 | } |
94 | } |
95 | }; |
96 | |
97 | /////////////////////////////////////////////////////////////////////////////////////////// |
98 | |
99 | /*! \brief This is a way to quickly copy a grid into another grid |
100 | * |
101 | * |
102 | */ |
103 | template<bool is_complex, unsigned int N, typename grid, typename ginfo> |
104 | struct copy_grid_fast |
105 | { |
106 | static void copy(ginfo & gs_src, |
107 | ginfo & gs_dst, |
108 | const Box<N,size_t> & bx_src, |
109 | const Box<N,size_t> & bx_dst, |
110 | const grid & gd_src, |
111 | grid & gd_dst, |
112 | grid_key_dx<N> (& cnt)[1] ) |
113 | { |
114 | grid_key_dx_iterator_sub<N,stencil_offset_compute<N,1>> sub_src(gs_src,bx_src.getKP1(),bx_src.getKP2(),cnt); |
115 | grid_key_dx_iterator_sub<N,stencil_offset_compute<N,1>> sub_dst(gs_dst,bx_dst.getKP1(),bx_dst.getKP2(),cnt); |
116 | |
117 | while (sub_src.isNext()) |
118 | { |
119 | // Option 1 |
120 | gd_dst.set(sub_dst.template getStencil<0>(),gd_src,sub_src.template getStencil<0>()); |
121 | |
122 | ++sub_src; |
123 | ++sub_dst; |
124 | } |
125 | } |
126 | }; |
127 | |
128 | /*! \brief This is a way to quickly copy a grid into another grid |
129 | * |
130 | * |
131 | */ |
132 | template<typename grid, typename ginfo> |
133 | struct copy_grid_fast<true,3,grid,ginfo> |
134 | { |
135 | static void copy(ginfo & gs_src, |
136 | ginfo & gs_dst, |
137 | const Box<3,size_t> & bx_src, |
138 | const Box<3,size_t> & bx_dst, |
139 | const grid & gd_src, |
140 | grid & gd_dst, |
141 | grid_key_dx<3> (& cnt)[1] ) |
142 | { |
143 | size_t lin_src = 0; |
144 | size_t lin_dst = 0; |
145 | |
146 | lin_src += bx_src.getLow(2) * gs_src.size_s(1); |
147 | lin_dst += bx_dst.getLow(2) * gs_dst.size_s(1); |
148 | for (size_t i = bx_src.getLow(2) ; i <= bx_src.getHigh(2) ; i++) |
149 | { |
150 | lin_src += bx_src.getLow(1) * gs_src.size_s(0); |
151 | lin_dst += bx_dst.getLow(1) * gs_dst.size_s(0); |
152 | for (size_t j = bx_src.getLow(1) ; j <= bx_src.getHigh(1) ; j++) |
153 | { |
154 | lin_src += bx_src.getLow(0); |
155 | lin_dst += bx_dst.getLow(0); |
156 | for (size_t k = bx_src.getLow(0) ; k <= bx_src.getHigh(0) ; k++) |
157 | { |
158 | gd_dst.set(lin_dst,gd_src,lin_src); |
159 | |
160 | lin_src++; |
161 | lin_dst++; |
162 | } |
163 | lin_src -= bx_src.getHigh(0) + 1; |
164 | lin_dst -= bx_dst.getHigh(0) + 1; |
165 | lin_src += gs_src.size_s(0); |
166 | lin_dst += gs_dst.size_s(0); |
167 | } |
168 | lin_src -= (bx_src.getHigh(1) + 1)*gs_src.size_s(0); |
169 | lin_dst -= (bx_dst.getHigh(1) + 1)*gs_dst.size_s(0); |
170 | lin_src += gs_src.size_s(1); |
171 | lin_dst += gs_dst.size_s(1); |
172 | } |
173 | } |
174 | }; |
175 | |
176 | |
177 | /*! \brief This is a way to quickly copy a grid into another grid |
178 | * |
179 | * |
180 | */ |
181 | template<typename grid, typename ginfo> |
182 | struct copy_grid_fast<true,2,grid,ginfo> |
183 | { |
184 | static void copy(ginfo & gs_src, |
185 | ginfo & gs_dst, |
186 | const Box<2,size_t> & bx_src, |
187 | const Box<2,size_t> & bx_dst, |
188 | const grid & gd_src, |
189 | grid & gd_dst, |
190 | grid_key_dx<2> (& cnt)[1] ) |
191 | { |
192 | size_t lin_src = 0; |
193 | size_t lin_dst = 0; |
194 | |
195 | |
196 | lin_src += bx_src.getLow(1) * gs_src.size_s(0); |
197 | lin_dst += bx_dst.getLow(1) * gs_dst.size_s(0); |
198 | for (size_t j = bx_src.getLow(1) ; j <= bx_src.getHigh(1) ; j++) |
199 | { |
200 | lin_src += bx_src.getLow(0); |
201 | lin_dst += bx_dst.getLow(0); |
202 | for (size_t k = bx_src.getLow(0) ; k <= bx_src.getHigh(0) ; k++) |
203 | { |
204 | gd_dst.set(lin_dst,gd_src,lin_src); |
205 | |
206 | lin_src++; |
207 | lin_dst++; |
208 | } |
209 | lin_src -= bx_src.getHigh(0) + 1; |
210 | lin_dst -= bx_dst.getHigh(0) + 1; |
211 | lin_src += gs_src.size_s(0); |
212 | lin_dst += gs_dst.size_s(0); |
213 | } |
214 | |
215 | } |
216 | }; |
217 | |
218 | |
219 | |
220 | /*! \brief This is a way to quickly copy a grid into another grid |
221 | * |
222 | * |
223 | */ |
224 | template<typename grid, typename ginfo> |
225 | struct copy_grid_fast<true,1,grid,ginfo> |
226 | { |
227 | static void copy(ginfo & gs_src, |
228 | ginfo & gs_dst, |
229 | const Box<1,size_t> & bx_src, |
230 | const Box<1,size_t> & bx_dst, |
231 | const grid & gd_src, |
232 | grid & gd_dst, |
233 | grid_key_dx<1> (& cnt)[1] ) |
234 | { |
235 | size_t lin_src = 0; |
236 | size_t lin_dst = 0; |
237 | |
238 | lin_src += bx_src.getLow(0); |
239 | lin_dst += bx_dst.getLow(0); |
240 | for (size_t k = bx_src.getLow(0) ; k <= bx_src.getHigh(0) ; k++) |
241 | { |
242 | gd_dst.set(lin_dst,gd_src,lin_src); |
243 | |
244 | lin_src++; |
245 | lin_dst++; |
246 | } |
247 | |
248 | |
249 | } |
250 | }; |
251 | |
252 | ////// In case the property is not complex |
253 | |
254 | template<unsigned int object_size> |
255 | void copy_grid_fast_longx_3(const Box<3,size_t> & bx_src, |
256 | unsigned char * ptr_dst, |
257 | unsigned char * ptr_src, |
258 | striding<3> & sr) |
259 | { |
260 | for (size_t i = bx_src.getLow(2) ; i <= bx_src.getHigh(2) ; i++) |
261 | { |
262 | for (size_t j = bx_src.getLow(1) ; j <= bx_src.getHigh(1) ; j++) |
263 | { |
264 | memcpy(ptr_dst,ptr_src,sr.n_cpy*object_size); |
265 | |
266 | ptr_dst += sr.striding_dst[0]; |
267 | ptr_src += sr.striding_src[0]; |
268 | } |
269 | ptr_dst += sr.striding_dst[1] - sr.tot_y*sr.striding_dst[0]; |
270 | ptr_src += sr.striding_src[1] - sr.tot_y*sr.striding_src[0]; |
271 | } |
272 | } |
273 | |
274 | template<unsigned int object_size, unsigned int n_cpy> |
275 | void copy_grid_fast_shortx_3(const Box<3,size_t> & bx_src, |
276 | unsigned char * ptr_dst, |
277 | unsigned char * ptr_src, |
278 | striding<3> & sr) |
279 | { |
280 | for (size_t i = bx_src.getLow(2) ; i <= bx_src.getHigh(2) ; i++) |
281 | { |
282 | for (size_t j = bx_src.getLow(1) ; j <= bx_src.getHigh(1) ; j++) |
283 | { |
284 | __builtin_memcpy(ptr_dst,ptr_src,n_cpy*object_size); |
285 | |
286 | ptr_dst += sr.striding_dst[0]; |
287 | ptr_src += sr.striding_src[0]; |
288 | } |
289 | ptr_dst += sr.striding_dst[1] - sr.tot_y*sr.striding_dst[0]; |
290 | ptr_src += sr.striding_src[1] - sr.tot_y*sr.striding_src[0]; |
291 | } |
292 | } |
293 | |
294 | |
295 | ////// In case the property is not complex |
296 | |
297 | template<unsigned int object_size> |
298 | void copy_grid_fast_longx_2(const Box<2,size_t> & bx_src, |
299 | unsigned char * ptr_dst, |
300 | unsigned char * ptr_src, |
301 | striding<2> & sr) |
302 | { |
303 | for (size_t j = bx_src.getLow(1) ; j <= bx_src.getHigh(1) ; j++) |
304 | { |
305 | memcpy(ptr_dst,ptr_src,sr.n_cpy*object_size); |
306 | |
307 | ptr_dst += sr.striding_dst[0]; |
308 | ptr_src += sr.striding_src[0]; |
309 | } |
310 | } |
311 | |
312 | template<unsigned int object_size, unsigned int n_cpy> |
313 | void copy_grid_fast_shortx_2(const Box<2,size_t> & bx_src, |
314 | unsigned char * ptr_dst, |
315 | unsigned char * ptr_src, |
316 | striding<2> & sr) |
317 | { |
318 | for (size_t j = bx_src.getLow(1) ; j <= bx_src.getHigh(1) ; j++) |
319 | { |
320 | __builtin_memcpy(ptr_dst,ptr_src,n_cpy*object_size); |
321 | |
322 | ptr_dst += sr.striding_dst[0]; |
323 | ptr_src += sr.striding_src[0]; |
324 | } |
325 | } |
326 | |
327 | template<unsigned int dim> |
328 | struct copy_ndim_fast_selector |
329 | { |
330 | template<unsigned int object_size> |
331 | static void call(unsigned char * ptr_src, |
332 | unsigned char * ptr_dst, |
333 | striding<dim> & sr, |
334 | const Box<dim,size_t> & bx_src) |
335 | { |
336 | std::cout << __FILE__ << ":" << __LINE__ << " error, wrong specialization. this case is not handled" << std::endl; |
337 | } |
338 | }; |
339 | |
340 | template<> |
341 | struct copy_ndim_fast_selector<3> |
342 | { |
343 | template<unsigned int object_size> |
344 | static void call(unsigned char * ptr_src, |
345 | unsigned char * ptr_dst, |
346 | striding<3> & sr, |
347 | const Box<3,size_t> & bx_src) |
348 | { |
349 | switch (sr.n_cpy) |
350 | { |
351 | case 1: |
352 | copy_grid_fast_shortx_3<object_size,1>(bx_src,ptr_dst,ptr_src,sr); |
353 | break; |
354 | case 2: |
355 | copy_grid_fast_shortx_3<object_size,2>(bx_src,ptr_dst,ptr_src,sr); |
356 | break; |
357 | |
358 | case 3: |
359 | copy_grid_fast_shortx_3<object_size,3>(bx_src,ptr_dst,ptr_src,sr); |
360 | break; |
361 | |
362 | case 4: |
363 | copy_grid_fast_shortx_3<object_size,4>(bx_src,ptr_dst,ptr_src,sr); |
364 | break; |
365 | case 5: |
366 | copy_grid_fast_shortx_3<object_size,5>(bx_src,ptr_dst,ptr_src,sr); |
367 | break; |
368 | case 6: |
369 | copy_grid_fast_shortx_3<object_size,6>(bx_src,ptr_dst,ptr_src,sr); |
370 | break; |
371 | |
372 | case 7: |
373 | copy_grid_fast_shortx_3<object_size,7>(bx_src,ptr_dst,ptr_src,sr); |
374 | break; |
375 | |
376 | case 8: |
377 | copy_grid_fast_shortx_3<object_size,8>(bx_src,ptr_dst,ptr_src,sr); |
378 | break; |
379 | |
380 | default: |
381 | copy_grid_fast_longx_3<object_size>(bx_src,ptr_dst,ptr_src,sr); |
382 | } |
383 | } |
384 | }; |
385 | |
386 | template<> |
387 | struct copy_ndim_fast_selector<2> |
388 | { |
389 | template<unsigned int object_size> |
390 | static void call(unsigned char * ptr_src, |
391 | unsigned char * ptr_dst, |
392 | striding<2> & sr, |
393 | const Box<2,size_t> & bx_src) |
394 | { |
395 | switch (sr.n_cpy) |
396 | { |
397 | case 1: |
398 | copy_grid_fast_shortx_2<object_size,1>(bx_src,ptr_dst,ptr_src,sr); |
399 | break; |
400 | case 2: |
401 | copy_grid_fast_shortx_2<object_size,2>(bx_src,ptr_dst,ptr_src,sr); |
402 | break; |
403 | |
404 | case 3: |
405 | copy_grid_fast_shortx_2<object_size,3>(bx_src,ptr_dst,ptr_src,sr); |
406 | break; |
407 | |
408 | case 4: |
409 | copy_grid_fast_shortx_2<object_size,4>(bx_src,ptr_dst,ptr_src,sr); |
410 | break; |
411 | case 5: |
412 | copy_grid_fast_shortx_2<object_size,5>(bx_src,ptr_dst,ptr_src,sr); |
413 | break; |
414 | case 6: |
415 | copy_grid_fast_shortx_2<object_size,6>(bx_src,ptr_dst,ptr_src,sr); |
416 | break; |
417 | |
418 | case 7: |
419 | copy_grid_fast_shortx_2<object_size,7>(bx_src,ptr_dst,ptr_src,sr); |
420 | break; |
421 | |
422 | case 8: |
423 | copy_grid_fast_shortx_2<object_size,8>(bx_src,ptr_dst,ptr_src,sr); |
424 | break; |
425 | |
426 | default: |
427 | copy_grid_fast_longx_2<object_size>(bx_src,ptr_dst,ptr_src,sr); |
428 | } |
429 | } |
430 | }; |
431 | |
432 | |
433 | template<unsigned int dim_prp, unsigned int prp,typename grid_type> |
434 | struct get_pointer |
435 | { |
436 | static unsigned char * get(const grid_type & gd, grid_key_dx<grid_type::dims> & key, unsigned int (& id)[dim_prp]) |
437 | { |
438 | return (unsigned char *)(&gd.template get_unsafe<prp>(key)); |
439 | } |
440 | }; |
441 | |
442 | template<unsigned int prp,typename grid_type> |
443 | struct get_pointer<1,prp,grid_type> |
444 | { |
445 | static unsigned char * get(const grid_type & gd, grid_key_dx<grid_type::dims> & key, unsigned int (& id)[1]) |
446 | { |
447 | return (unsigned char *)(&gd.template get_unsafe<prp>(key)[id[0]]); |
448 | } |
449 | }; |
450 | |
451 | template<unsigned int prp,typename grid_type> |
452 | struct get_pointer<2,prp,grid_type> |
453 | { |
454 | static unsigned char * get(const grid_type & gd, grid_key_dx<grid_type::dims> & key, unsigned int (& id)[2]) |
455 | { |
456 | return (unsigned char *)(&gd.template get_unsafe<prp>(key)[id[0]][id[1]]); |
457 | } |
458 | }; |
459 | |
460 | template<unsigned int dim,unsigned int dim_prp,unsigned int prp, typename grid_type> |
461 | struct get_striding |
462 | { |
463 | static striding<dim> get(const grid_type & gd_src,grid_type &gd_dst, |
464 | const Box<dim,size_t> & bx_src, unsigned int (& id)[dim_prp]) |
465 | { |
466 | striding<dim> sr; |
467 | |
468 | grid_key_dx<dim> zero; |
469 | zero.zero(); |
470 | grid_key_dx<dim> one = zero; |
471 | one.set_d(1,1); |
472 | |
473 | unsigned char * ptr_final_src = get_pointer<dim_prp,prp,grid_type>::get(gd_src,one,id); |
474 | unsigned char * ptr_start_src = get_pointer<dim_prp,prp,grid_type>::get(gd_src,zero,id); |
475 | |
476 | unsigned char * ptr_final_dst = get_pointer<dim_prp,prp,grid_type>::get(gd_dst,one,id); |
477 | unsigned char * ptr_start_dst = get_pointer<dim_prp,prp,grid_type>::get(gd_dst,zero,id); |
478 | |
479 | sr.n_cpy = bx_src.getHigh(0) - bx_src.getLow(0) + 1; |
480 | sr.tot_y = bx_src.getHigh(1) - bx_src.getLow(1) + 1; |
481 | |
482 | sr.striding_src[0] = ptr_final_src - ptr_start_src; |
483 | sr.striding_dst[0] = ptr_final_dst - ptr_start_dst; |
484 | |
485 | if (dim == 3) |
486 | { |
487 | grid_key_dx<dim> one2 = zero; |
488 | one2.set_d(2,1); |
489 | |
490 | unsigned char * ptr_final_src = get_pointer<dim_prp,prp,grid_type>::get(gd_src,one2,id); |
491 | unsigned char * ptr_start_src = get_pointer<dim_prp,prp,grid_type>::get(gd_src,zero,id); |
492 | |
493 | unsigned char * ptr_final_dst = get_pointer<dim_prp,prp,grid_type>::get(gd_dst,one2,id); |
494 | unsigned char * ptr_start_dst = get_pointer<dim_prp,prp,grid_type>::get(gd_dst,zero,id); |
495 | |
496 | sr.striding_src[1] = ptr_final_src - ptr_start_src; |
497 | sr.striding_dst[1] = ptr_final_dst - ptr_start_dst; |
498 | } |
499 | |
500 | return sr; |
501 | }; |
502 | }; |
503 | |
504 | template<unsigned int dim, typename T> |
505 | struct mp_funct_impl |
506 | { |
507 | template<unsigned int prp, typename grid> |
508 | static void process(const grid & gd_src,grid & gd_dst, |
509 | const Box<dim,size_t> & bx_src, const Box<grid::dims,size_t> & bx_dst) |
510 | { |
511 | unsigned int id[0]; |
512 | striding<dim> sr = get_striding<dim,0,prp,grid>::get(gd_src,gd_dst,bx_src,id); |
513 | |
514 | unsigned char * ptr_src = (unsigned char *)(&gd_src.template get<prp>(bx_src.getKP1())); |
515 | unsigned char * ptr_dst = (unsigned char *)(&gd_dst.template get<prp>(bx_dst.getKP1())); |
516 | |
517 | copy_ndim_fast_selector<dim>::template call<sizeof(T)>(ptr_src,ptr_dst,sr,bx_src); |
518 | } |
519 | }; |
520 | |
521 | template<unsigned int dim, typename T, unsigned int N1> |
522 | struct mp_funct_impl<dim,T[N1]> |
523 | { |
524 | template<unsigned int prp, typename grid> |
525 | static void process(const grid & gd_src,grid & gd_dst, |
526 | const Box<dim,size_t> & bx_src, const Box<grid::dims,size_t> & bx_dst) |
527 | { |
528 | unsigned int id[1]; |
529 | |
530 | for (id[0] = 0 ; id[0] < N1 ; id[0]++) |
531 | { |
532 | striding<dim> sr = get_striding<dim,1,prp,grid>::get(gd_src,gd_dst,bx_src,id); |
533 | |
534 | unsigned char * ptr_src = (unsigned char *)(&gd_src.template get<prp>(bx_src.getKP1())[id[0]]); |
535 | unsigned char * ptr_dst = (unsigned char *)(&gd_dst.template get<prp>(bx_dst.getKP1())[id[0]]); |
536 | |
537 | copy_ndim_fast_selector<dim>::template call<sizeof(T)>(ptr_src,ptr_dst,sr,bx_src); |
538 | } |
539 | } |
540 | }; |
541 | |
542 | |
543 | template<unsigned int dim, typename T, unsigned int N1, unsigned int N2> |
544 | struct mp_funct_impl<dim,T[N1][N2]> |
545 | { |
546 | template<unsigned int prp, typename grid> |
547 | static void process(const grid & gd_src,grid & gd_dst, |
548 | const Box<dim,size_t> & bx_src, const Box<grid::dims,size_t> & bx_dst) |
549 | { |
550 | unsigned int id[2]; |
551 | |
552 | for (id[1] = 0 ; id[1] < N1 ; id[1]++) |
553 | { |
554 | for (id[0] = 0 ; id[0] < N2 ; id[0]++) |
555 | { |
556 | striding<dim> sr = get_striding<dim,2,prp,grid>::get(gd_src,gd_dst,bx_src,id); |
557 | |
558 | unsigned char * ptr_src = (unsigned char *)(&gd_src.template get<prp>(bx_src.getKP1())[id[1]][id[0]]); |
559 | unsigned char * ptr_dst = (unsigned char *)(&gd_dst.template get<prp>(bx_dst.getKP1())[id[1]][id[0]]); |
560 | |
561 | copy_ndim_fast_selector<dim>::template call<sizeof(T)>(ptr_src,ptr_dst,sr,bx_src); |
562 | } |
563 | } |
564 | } |
565 | }; |
566 | |
567 | template<typename grid, typename ginfo> |
568 | class mp_funct |
569 | { |
570 | const grid & gd_src; |
571 | grid & gd_dst; |
572 | ginfo & gs_src; |
573 | ginfo & gs_dst; |
574 | |
575 | const Box<grid::dims,size_t> & bx_src; |
576 | const Box<grid::dims,size_t> & bx_dst; |
577 | |
578 | grid_key_dx<grid::dims> (& cnt)[1]; |
579 | |
580 | public: |
581 | |
582 | mp_funct(const grid & gd_src,grid & gd_dst, |
583 | ginfo & gs_src,ginfo & gs_dst, |
584 | const Box<grid::dims,size_t> & bx_src , const Box<grid::dims,size_t> & bx_dst, |
585 | grid_key_dx<grid::dims> (& cnt)[1]) |
586 | :gd_src(gd_src),gd_dst(gd_dst),gs_src(gs_src),gs_dst(gs_dst),bx_src(bx_src),bx_dst(bx_dst),cnt(cnt) |
587 | {} |
588 | |
589 | //! It call the copy function for each property |
590 | template<typename T> |
591 | inline void operator()(T& t) |
592 | { |
593 | typedef typename boost::mpl::at<typename grid::value_type::type,boost::mpl::int_<T::value>>::type prp_type; |
594 | |
595 | mp_funct_impl<grid::dims,prp_type>::template process<T::value>(gd_src,gd_dst,bx_src,bx_dst); |
596 | } |
597 | }; |
598 | |
599 | template<bool is_inte,unsigned int dim,typename grid, typename ginfo> |
600 | struct copy_grid_fast_layout_switch |
601 | { |
602 | static void copy(const ginfo & gs_src, |
603 | const ginfo & gs_dst, |
604 | const Box<dim,size_t> & bx_src, |
605 | const Box<dim,size_t> & bx_dst, |
606 | const grid & gd_src, |
607 | grid & gd_dst, |
608 | grid_key_dx<dim> (& cnt)[1]) |
609 | { |
610 | mp_funct_impl<dim,typename grid::value_type>::template process<0>(gd_src,gd_dst,bx_src,bx_dst); |
611 | |
612 | // copy_ndim_fast_selector<grid::dims>::template call<0>(gs_src,gs_dst,bx_src,bx_dst, |
613 | // gd_src,gd_dst,cnt); |
614 | } |
615 | }; |
616 | |
617 | template<unsigned int dim, typename grid, typename ginfo> |
618 | struct copy_grid_fast_layout_switch<true,dim,grid,ginfo> |
619 | { |
620 | static void copy(const ginfo & gs_src, |
621 | const ginfo & gs_dst, |
622 | const Box<dim,size_t> & bx_src, |
623 | const Box<dim,size_t> & bx_dst, |
624 | const grid & gd_src, |
625 | grid & gd_dst, |
626 | grid_key_dx<dim> (& cnt)[1]) |
627 | { |
628 | mp_funct<grid,ginfo> mpf(gd_src,gd_dst,gs_src,gs_dst,bx_src,bx_dst,cnt); |
629 | |
630 | boost::mpl::for_each_ref<boost::mpl::range_c<int,0,grid::value_type::max_prop>>(mpf); |
631 | } |
632 | }; |
633 | |
634 | /*! \brief This is a way to quickly copy a grid into another grid |
635 | * |
636 | * |
637 | */ |
638 | template<typename grid, typename ginfo> |
639 | struct copy_grid_fast<false,3,grid,ginfo> |
640 | { |
641 | static void copy(ginfo & gs_src, |
642 | ginfo & gs_dst, |
643 | const Box<3,size_t> & bx_src, |
644 | const Box<3,size_t> & bx_dst, |
645 | const grid & gd_src, |
646 | grid & gd_dst, |
647 | grid_key_dx<3> (& cnt)[1] ) |
648 | { |
649 | copy_grid_fast_layout_switch<is_layout_inte<typename grid::layout_base_>::value,3,grid,ginfo>::copy(gs_src,gs_dst,bx_src,bx_dst,gd_src,gd_dst,cnt); |
650 | } |
651 | }; |
652 | |
653 | |
654 | |
655 | |
656 | |
657 | /*! \brief This is a way to quickly copy a grid into another grid |
658 | * |
659 | * |
660 | */ |
661 | template<typename grid, typename ginfo> |
662 | struct copy_grid_fast<false,2,grid,ginfo> |
663 | { |
664 | static void copy(ginfo & gs_src, |
665 | ginfo & gs_dst, |
666 | const Box<2,size_t> & bx_src, |
667 | const Box<2,size_t> & bx_dst, |
668 | const grid & gd_src, |
669 | grid & gd_dst, |
670 | grid_key_dx<2> (& cnt)[1] ) |
671 | { |
672 | copy_grid_fast_layout_switch<is_layout_inte<typename grid::layout_base_>::value,2,grid,ginfo>::copy(gs_src,gs_dst,bx_src,bx_dst,gd_src,gd_dst,cnt); |
673 | } |
674 | }; |
675 | |
676 | //////////////////// Pack grid fast |
677 | |
678 | |
679 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
680 | * |
681 | * \tparam it type of iterator of the grid-structure |
682 | * \tparam dtype type of the structure B |
683 | * \tparam dim Dimensionality of the grid |
684 | * \tparam properties to pack |
685 | * |
686 | */ |
687 | template <bool is_complex, |
688 | unsigned int dim, |
689 | typename grid, |
690 | typename encap_src, |
691 | typename encap_dst, |
692 | typename boost_vct, |
693 | typename it, |
694 | typename dtype, |
695 | int ... prp> |
696 | struct pack_with_iterator |
697 | { |
698 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
699 | * |
700 | * \param it Grid iterator |
701 | * \param obj object to pack |
702 | * \param dest where to pack |
703 | * |
704 | */ |
705 | static void pack(grid & gr, it & sub_it, dtype & dest) |
706 | { |
707 | size_t id = 0; |
708 | |
709 | // Packing the information |
710 | while (sub_it.isNext()) |
711 | { |
712 | // Copy only the selected properties |
713 | object_si_d<encap_src,encap_dst,OBJ_ENCAP,prp...>(gr.get_o(sub_it.get()),dest.get(id)); |
714 | |
715 | ++id; |
716 | ++sub_it; |
717 | } |
718 | } |
719 | }; |
720 | |
721 | |
722 | |
723 | |
724 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
725 | * |
726 | * \tparam it type of iterator of the grid-structure |
727 | * \tparam dtype type of the structure B |
728 | * \tparam dim Dimensionality of the grid |
729 | * \tparam properties to pack |
730 | * |
731 | */ |
732 | template <typename grid, |
733 | typename encap_src, |
734 | typename encap_dst, |
735 | typename boost_vct, |
736 | typename it, |
737 | typename dtype, |
738 | int ... prp> |
739 | struct pack_with_iterator<true,3,grid,encap_src,encap_dst,boost_vct,it,dtype,prp...> |
740 | { |
741 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
742 | * |
743 | * \param it Grid iterator |
744 | * \param obj object to pack |
745 | * \param dest where to pack |
746 | * |
747 | */ |
748 | static void pack(grid & gr, it & sub_it, dtype & dest) |
749 | { |
750 | size_t id = 0; |
751 | |
752 | size_t lin_src = 0; |
753 | |
754 | auto & gs_src = gr.getGrid(); |
755 | grid_key_dx<3> start = sub_it.getStart(); |
756 | grid_key_dx<3> stop = sub_it.getStop(); |
757 | |
758 | lin_src += start.get(2) * gs_src.size_s(1); |
759 | for (long int i = start.get(2) ; i <= stop.get(2) ; i++) |
760 | { |
761 | lin_src += start.get(1) * gs_src.size_s(0); |
762 | for (long int j = start.get(1) ; j <= stop.get(1) ; j++) |
763 | { |
764 | lin_src += start.get(0); |
765 | for (long int k = start.get(0) ; k <= stop.get(0) ; k++) |
766 | { |
767 | // Copy only the selected properties |
768 | object_si_d<encap_src,encap_dst,OBJ_ENCAP,prp...>(gr.get_o(lin_src),dest.get(id)); |
769 | |
770 | ++id; |
771 | ++lin_src; |
772 | } |
773 | lin_src -= stop.get(0) + 1; |
774 | lin_src += gs_src.size_s(0); |
775 | } |
776 | lin_src -= (stop.get(1) + 1)*gs_src.size_s(0); |
777 | lin_src += gs_src.size_s(1); |
778 | } |
779 | } |
780 | }; |
781 | |
782 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
783 | * |
784 | * \tparam it type of iterator of the grid-structure |
785 | * \tparam dtype type of the structure B |
786 | * \tparam dim Dimensionality of the grid |
787 | * \tparam properties to pack |
788 | * |
789 | */ |
790 | template <typename grid, |
791 | typename encap_src, |
792 | typename encap_dst, |
793 | typename boost_vct, |
794 | typename it, |
795 | typename dtype, |
796 | int ... prp> |
797 | struct pack_with_iterator<true,2,grid,encap_src,encap_dst,boost_vct,it,dtype,prp...> |
798 | { |
799 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
800 | * |
801 | * \param it Grid iterator |
802 | * \param obj object to pack |
803 | * \param dest where to pack |
804 | * |
805 | */ |
806 | static void pack(grid & gr, it & sub_it, dtype & dest) |
807 | { |
808 | size_t id = 0; |
809 | |
810 | size_t lin_src = 0; |
811 | |
812 | auto & gs_src = gr.getGrid(); |
813 | grid_key_dx<2> start = sub_it.getStart(); |
814 | grid_key_dx<2> stop = sub_it.getStop(); |
815 | |
816 | lin_src += start.get(1) * gs_src.size_s(0); |
817 | for (long int j = start.get(1) ; j <= stop.get(1) ; j++) |
818 | { |
819 | lin_src += start.get(0); |
820 | for (long int k = start.get(0) ; k <= stop.get(0) ; k++) |
821 | { |
822 | // Copy only the selected properties |
823 | object_si_d<encap_src,encap_dst,OBJ_ENCAP,prp...>(gr.get_o(lin_src),dest.get(id)); |
824 | |
825 | ++id; |
826 | ++lin_src; |
827 | } |
828 | lin_src -= stop.get(0) + 1; |
829 | lin_src += gs_src.size_s(0); |
830 | } |
831 | |
832 | } |
833 | }; |
834 | |
835 | //////////// PACK ITERATOR LONG ///////////////////////// |
836 | |
837 | template<unsigned int dim, int obj_byte, typename git, typename grid> |
838 | struct pack_with_iterator_longx |
839 | { |
840 | static void pack(grid & gr, |
841 | git & sub_it, |
842 | unsigned char * ptr_dest, |
843 | unsigned char * ptr, |
844 | size_t stride_x, |
845 | size_t n_cpy) |
846 | { |
847 | std::cout << __FILE__ << ":" << __LINE__ << " critical error, we shoukd never be here" << std::endl; |
848 | } |
849 | }; |
850 | |
851 | template<int obj_byte, typename git, typename grid> |
852 | struct pack_with_iterator_longx<2,obj_byte,git,grid> |
853 | { |
854 | static void pack(grid & gr, |
855 | git & sub_it, |
856 | unsigned char * ptr_dest, |
857 | unsigned char * ptr, |
858 | size_t stride_x, |
859 | size_t n_cpy) |
860 | { |
861 | size_t tot_y = sub_it.getStop().get(1) - sub_it.getStart().get(1) + 1; |
862 | |
863 | for (size_t i = 0 ; i < tot_y ; i++) |
864 | { |
865 | memcpy(ptr_dest,ptr,n_cpy * obj_byte); |
866 | |
867 | ptr += stride_x; |
868 | ptr_dest += n_cpy * obj_byte; |
869 | } |
870 | } |
871 | }; |
872 | |
873 | template<int obj_byte, typename git, typename grid> |
874 | struct pack_with_iterator_longx<3,obj_byte,git,grid> |
875 | { |
876 | static void pack(grid & gr, |
877 | git & sub_it, |
878 | unsigned char * ptr_dest, |
879 | unsigned char * ptr, |
880 | size_t stride_x, |
881 | size_t n_cpy) |
882 | { |
883 | size_t tot_y = sub_it.getStop().get(1) - sub_it.getStart().get(1) + 1; |
884 | size_t tot_z = sub_it.getStop().get(2) - sub_it.getStart().get(2) + 1; |
885 | |
886 | grid_key_dx<3> zero; |
887 | zero.zero(); |
888 | grid_key_dx<3> one = zero; |
889 | one.set_d(2,1); |
890 | |
891 | unsigned char * ptr_final = (unsigned char *)&(gr.template get<0>(one)); |
892 | unsigned char * ptr_start = (unsigned char *)&(gr.template get<0>(zero)); |
893 | |
894 | size_t stride_y = ptr_final - ptr_start; |
895 | |
896 | for (size_t i = 0 ; i < tot_z ; i++) |
897 | { |
898 | for (size_t i = 0 ; i < tot_y ; i++) |
899 | { |
900 | memcpy(ptr_dest,ptr,n_cpy * obj_byte); |
901 | |
902 | ptr += stride_x; |
903 | ptr_dest += n_cpy * obj_byte; |
904 | } |
905 | ptr += stride_y - tot_y*stride_x; |
906 | } |
907 | } |
908 | }; |
909 | |
910 | ///////////////////////////////////////////////////////////////////// |
911 | |
912 | ///////////////// PACK ITERATOR SHORT /////////////////////////////// |
913 | |
914 | template<unsigned int dim, unsigned int n_cpy ,int obj_byte, typename git, typename grid> |
915 | struct pack_with_iterator_shortx |
916 | { |
917 | static void pack(grid & gr, |
918 | git & sub_it, |
919 | unsigned char * ptr_dest, |
920 | unsigned char * ptr, |
921 | size_t stride_x) |
922 | { |
923 | std::cout << __FILE__ << ":" << __LINE__ << " critical error, we shoukd never be here" << std::endl; |
924 | } |
925 | }; |
926 | |
927 | template<unsigned int n_cpy, int obj_byte, typename git, typename grid> |
928 | struct pack_with_iterator_shortx<2,n_cpy,obj_byte,git,grid> |
929 | { |
930 | static void pack(grid & gr, |
931 | git & sub_it, |
932 | unsigned char * ptr_dest, |
933 | unsigned char * ptr, |
934 | size_t stride_x) |
935 | { |
936 | size_t tot_y = sub_it.getStop().get(1) - sub_it.getStart().get(1) + 1; |
937 | |
938 | for (size_t i = 0 ; i < tot_y ; i++) |
939 | { |
940 | __builtin_memcpy(ptr_dest,ptr,n_cpy * obj_byte); |
941 | |
942 | ptr += stride_x; |
943 | ptr_dest += n_cpy * obj_byte; |
944 | } |
945 | } |
946 | }; |
947 | |
948 | template<unsigned int n_cpy, int obj_byte, typename git, typename grid> |
949 | struct pack_with_iterator_shortx<3,n_cpy,obj_byte,git,grid> |
950 | { |
951 | static void pack(grid & gr, |
952 | git & sub_it, |
953 | unsigned char * ptr_dest, |
954 | unsigned char * ptr, |
955 | size_t stride_x) |
956 | { |
957 | size_t tot_y = sub_it.getStop().get(1) - sub_it.getStart().get(1) + 1; |
958 | size_t tot_z = sub_it.getStop().get(2) - sub_it.getStart().get(2) + 1; |
959 | |
960 | grid_key_dx<3> zero; |
961 | zero.zero(); |
962 | grid_key_dx<3> one = zero; |
963 | one.set_d(2,1); |
964 | |
965 | unsigned char * ptr_final = (unsigned char *)(&gr.template get_unsafe<0>(one)); |
966 | unsigned char * ptr_start = (unsigned char *)(&gr.template get<0>(zero)); |
967 | |
968 | size_t stride_y = ptr_final - ptr_start; |
969 | |
970 | for (size_t i = 0 ; i < tot_z ; i++) |
971 | { |
972 | for (size_t i = 0 ; i < tot_y ; i++) |
973 | { |
974 | __builtin_memcpy(ptr_dest,ptr,n_cpy * obj_byte); |
975 | |
976 | ptr += stride_x; |
977 | ptr_dest += n_cpy * obj_byte; |
978 | } |
979 | ptr += stride_y - tot_y*stride_x; |
980 | } |
981 | } |
982 | }; |
983 | |
984 | /////////////////////////////////////////////////////////////////// |
985 | |
986 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
987 | * |
988 | * \tparam it type of iterator of the grid-structure |
989 | * \tparam dtype type of the structure B |
990 | * \tparam dim Dimensionality of the grid |
991 | * \tparam properties to pack |
992 | * |
993 | */ |
994 | template <unsigned int dim, |
995 | typename grid, |
996 | typename encap_src, |
997 | typename encap_dst, |
998 | typename boost_vct, |
999 | typename it, |
1000 | typename dtype, |
1001 | int ... prp> |
1002 | struct pack_with_iterator<false,dim,grid,encap_src,encap_dst,boost_vct,it,dtype,prp...> |
1003 | { |
1004 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
1005 | * |
1006 | * \param it Grid iterator |
1007 | * \param obj object to pack |
1008 | * \param dest where to pack |
1009 | * |
1010 | */ |
1011 | static void pack(grid & gr, it & sub_it, dtype & dest) |
1012 | { |
1013 | // We do not have an optimized version for dimension different from 3 and 2 |
1014 | if (dim == 1 || dim > 3) |
1015 | { |
1016 | pack_with_iterator<true,dim,grid,encap_src,encap_dst,boost_vct,it,dtype,prp...>::pack(gr,sub_it,dest); |
1017 | return; |
1018 | } |
1019 | |
1020 | // Sending property object |
1021 | typedef object<typename object_creator< |
1022 | boost_vct, |
1023 | prp...>::type |
1024 | > prp_object; |
1025 | |
1026 | |
1027 | // fast strided copy |
1028 | |
1029 | grid_key_dx<dim> zero; |
1030 | zero.zero(); |
1031 | grid_key_dx<dim> one = zero; |
1032 | one.set_d(1,1); |
1033 | |
1034 | unsigned char * ptr_final = (unsigned char *)(&gr.template get_unsafe<0>(one)); |
1035 | unsigned char * ptr_start = (unsigned char *)(&gr.template get<0>(zero)); |
1036 | |
1037 | size_t stride = ptr_final - ptr_start; |
1038 | |
1039 | size_t n_tot = 0; |
1040 | for (size_t i = 1 ; i < dim ; i++) |
1041 | {n_tot += sub_it.getStop().get(i) - sub_it.getStart().get(i) + 1;} |
1042 | |
1043 | size_t n_cpy = sub_it.getStop().get(0) - sub_it.getStart().get(0) + 1; |
1044 | unsigned char * ptr = (unsigned char *)&(gr.template get<first_variadic<prp...>::type::value>(sub_it.getStart())); |
1045 | unsigned char * ptr_dest = (unsigned char *)dest.getPointer(); |
1046 | |
1047 | switch (n_cpy) |
1048 | { |
1049 | case 1: |
1050 | pack_with_iterator_shortx<dim,1,sizeof(prp_object),it,grid>::pack(gr, |
1051 | sub_it, |
1052 | ptr_dest, |
1053 | ptr, |
1054 | stride); |
1055 | break; |
1056 | case 2: |
1057 | pack_with_iterator_shortx<dim,2,sizeof(prp_object),it,grid>::pack(gr, |
1058 | sub_it, |
1059 | ptr_dest, |
1060 | ptr, |
1061 | stride); |
1062 | break; |
1063 | case 3: |
1064 | pack_with_iterator_shortx<dim,3,sizeof(prp_object),it,grid>::pack(gr, |
1065 | sub_it, |
1066 | ptr_dest, |
1067 | ptr, |
1068 | stride); |
1069 | break; |
1070 | case 4: |
1071 | pack_with_iterator_shortx<dim,4,sizeof(prp_object),it,grid>::pack(gr, |
1072 | sub_it, |
1073 | ptr_dest, |
1074 | ptr, |
1075 | stride); |
1076 | break; |
1077 | case 5: |
1078 | pack_with_iterator_shortx<dim,5,sizeof(prp_object),it,grid>::pack(gr, |
1079 | sub_it, |
1080 | ptr_dest, |
1081 | ptr, |
1082 | stride); |
1083 | break; |
1084 | case 6: |
1085 | pack_with_iterator_shortx<dim,6,sizeof(prp_object),it,grid>::pack(gr, |
1086 | sub_it, |
1087 | ptr_dest, |
1088 | ptr, |
1089 | stride); |
1090 | break; |
1091 | case 7: |
1092 | pack_with_iterator_shortx<dim,7,sizeof(prp_object),it,grid>::pack(gr, |
1093 | sub_it, |
1094 | ptr_dest, |
1095 | ptr, |
1096 | stride); |
1097 | break; |
1098 | case 8: |
1099 | pack_with_iterator_shortx<dim,8,sizeof(prp_object),it,grid>::pack(gr, |
1100 | sub_it, |
1101 | ptr_dest, |
1102 | ptr, |
1103 | stride); |
1104 | break; |
1105 | default: |
1106 | pack_with_iterator_longx<dim,sizeof(prp_object),it,grid>::pack(gr, |
1107 | sub_it, |
1108 | ptr_dest, |
1109 | ptr, |
1110 | stride, |
1111 | n_cpy); |
1112 | |
1113 | } |
1114 | |
1115 | } |
1116 | }; |
1117 | |
1118 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
1119 | * |
1120 | * \tparam it type of iterator of the grid-structure |
1121 | * \tparam dtype type of the structure B |
1122 | * \tparam dim Dimensionality of the grid |
1123 | * \tparam properties to pack |
1124 | * |
1125 | */ |
1126 | template <typename grid, |
1127 | typename encap_src, |
1128 | typename encap_dst, |
1129 | typename boost_vct, |
1130 | typename it, |
1131 | typename dtype, |
1132 | int ... prp> |
1133 | struct pack_with_iterator<true,1,grid,encap_src,encap_dst,boost_vct,it,dtype,prp...> |
1134 | { |
1135 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
1136 | * |
1137 | * \param it Grid iterator |
1138 | * \param obj object to pack |
1139 | * \param dest where to pack |
1140 | * |
1141 | */ |
1142 | static void pack(grid & gr, it & sub_it, dtype & dest) |
1143 | { |
1144 | size_t id = 0; |
1145 | |
1146 | size_t lin_src = 0; |
1147 | |
1148 | auto & gs_src = gr.getGrid(); |
1149 | grid_key_dx<1> start = sub_it.getStart(); |
1150 | grid_key_dx<1> stop = sub_it.getStop(); |
1151 | |
1152 | |
1153 | lin_src += start.get(0); |
1154 | for (long int k = start.get(0) ; k <= stop.get(0) ; k++) |
1155 | { |
1156 | // Copy only the selected properties |
1157 | object_si_d<encap_src,encap_dst,OBJ_ENCAP,prp...>(gr.get_o(lin_src),dest.get(id)); |
1158 | |
1159 | ++id; |
1160 | ++lin_src; |
1161 | } |
1162 | lin_src -= stop.get(0) + 1; |
1163 | lin_src += gs_src.size_s(0); |
1164 | |
1165 | } |
1166 | }; |
1167 | |
1168 | //////////////////////////// Unpack grid fast //////////////////////////// |
1169 | |
1170 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
1171 | * |
1172 | * \tparam it type of iterator of the grid-structure |
1173 | * \tparam dtype type of the structure B |
1174 | * \tparam dim Dimensionality of the grid |
1175 | * \tparam properties to pack |
1176 | * |
1177 | */ |
1178 | template <unsigned int dim, |
1179 | typename grid, |
1180 | typename encap_src, |
1181 | typename encap_dst, |
1182 | typename boost_vct, |
1183 | typename it, |
1184 | typename stype, |
1185 | int ... prp> |
1186 | struct unpack_with_iterator |
1187 | { |
1188 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
1189 | * |
1190 | * \param it Grid iterator |
1191 | * \param obj object to pack |
1192 | * \param dest where to pack |
1193 | * |
1194 | */ |
1195 | static void unpack(grid & gr, it & sub_it, stype & src) |
1196 | { |
1197 | size_t id = 0; |
1198 | |
1199 | // unpacking the information |
1200 | while (sub_it.isNext()) |
1201 | { |
1202 | |
1203 | // Copy only the selected properties |
1204 | object_s_di<encap_src,encap_dst,OBJ_ENCAP,prp...>(src.get(id),gr.get_o(sub_it.get())); |
1205 | |
1206 | ++id; |
1207 | ++sub_it; |
1208 | } |
1209 | } |
1210 | }; |
1211 | |
1212 | |
1213 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
1214 | * |
1215 | * \tparam it type of iterator of the grid-structure |
1216 | * \tparam dtype type of the structure B |
1217 | * \tparam dim Dimensionality of the grid |
1218 | * \tparam properties to pack |
1219 | * |
1220 | */ |
1221 | template <typename grid, |
1222 | typename encap_src, |
1223 | typename encap_dst, |
1224 | typename boost_vct, |
1225 | typename it, |
1226 | typename stype, |
1227 | int ... prp> |
1228 | struct unpack_with_iterator<3,grid, |
1229 | encap_src, |
1230 | encap_dst, |
1231 | boost_vct, |
1232 | it, |
1233 | stype, |
1234 | prp ...> |
1235 | { |
1236 | /*! \brief Pack an N-dimensional grid into a vector like structure B given an iterator of the grid |
1237 | * |
1238 | * \param it Grid iterator |
1239 | * \param obj object to pack |
1240 | * \param dest where to pack |
1241 | * |
1242 | */ |
1243 | static void unpack(grid & gr, it & sub_it, stype & src) |
1244 | { |
1245 | size_t id = 0; |
1246 | |
1247 | size_t lin_dst = 0; |
1248 | |
1249 | auto & gs_dst = gr.getGrid(); |
1250 | grid_key_dx<3> start = sub_it.getStart(); |
1251 | grid_key_dx<3> stop = sub_it.getStop(); |
1252 | |
1253 | // unpacking the information |
1254 | |
1255 | lin_dst += start.get(2) * gs_dst.size_s(1); |
1256 | for (long int i = start.get(2) ; i <= stop.get(2) ; i++) |
1257 | { |
1258 | lin_dst += start.get(1) * gs_dst.size_s(0); |
1259 | for (long int j = start.get(1) ; j <= stop.get(1) ; j++) |
1260 | { |
1261 | lin_dst += start.get(0); |
1262 | for (long int k = start.get(0) ; k <= stop.get(0) ; k++) |
1263 | { |
1264 | // Copy only the selected properties |
1265 | object_s_di<encap_src,encap_dst,OBJ_ENCAP,prp...>(src.get(id),gr.get_o(lin_dst)); |
1266 | |
1267 | ++id; |
1268 | ++lin_dst; |
1269 | } |
1270 | lin_dst -= stop.get(0) + 1; |
1271 | lin_dst += gs_dst.size_s(0); |
1272 | } |
1273 | lin_dst -= (stop.get(1) + 1)*gs_dst.size_s(0); |
1274 | lin_dst += gs_dst.size_s(1); |
1275 | } |
1276 | } |
1277 | }; |
1278 | |
1279 | #endif /* OPENFPM_DATA_SRC_GRID_COPY_GRID_FAST_HPP_ */ |
1280 | |