OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
grid_dist_id_iterator.hpp
1/*
2 * grid_dist_id_iterator_sub.hpp
3 *
4 * Created on: Feb 4, 2015
5 * Author: Pietro Incardona
6 */
7
8#ifndef GRID_DIST_ID_ITERATOR_HPP_
9#define GRID_DIST_ID_ITERATOR_HPP_
10
11#define FREE 1
12#define FIXED 2
13#define ITERATION_ISOLATION 4
14
15#include "Grid/grid_dist_key.hpp"
16#include "VCluster/VCluster.hpp"
17#include "util/GBoxes.hpp"
18
19#ifdef __NVCC__
20#include "SparseGridGpu/encap_num.hpp"
21#endif
22
23#include "Grid/cuda/grid_dist_id_kernels.cuh"
24
25template<unsigned int dim>
27{
28 template<typename ec_type, typename lambda_t,typename coord_type>
29 __device__ inline static void call(ec_type & ec,lambda_t f, coord_type coord)
30 {
31 printf("Not implemented in this direction \n");
32 }
33
34 template<typename ite_type>
35 __device__ inline static bool set_keys(grid_key_dx<3,int> & key, grid_key_dx<3,int> & keyg, ite_type & itg)
36 {
37 return false;
38 }
39};
40
41template<>
43{
44 template<typename grid_type, typename lambda_t1, typename lambda_t2,typename itd_type, typename coord_type>
45 __device__ inline static void call(grid_type & grid,
46 lambda_t1 f1, lambda_t2 f2,
47 unsigned int blockId,
48 itd_type itd,
49 coord_type & key,
50 coord_type & keyg,unsigned int offset, bool & is_block_empty,
51 bool is_in)
52 {
53#ifdef __NVCC__
54
55 bool is_active = false;
56 if (is_in == true)
57 {is_active = f1(keyg.get(0),keyg.get(1),keyg.get(2));}
58
59 if (is_active == true)
60 {is_block_empty = false;}
61
62 __syncthreads();
63
64 if (is_block_empty == false)
65 {
66 auto ec = grid.insertBlock(blockId);
67 enc_num<decltype(grid.insertBlock(blockId))> ecn(ec,offset);
68
69 if ( is_active == true)
70 {
71 f2(ecn,keyg.get(0),keyg.get(1),keyg.get(2));
72 ec.template get<grid_type::pMask>()[offset] = 1;
73 }
74 }
75
76#endif
77 }
78
79 template<typename ite_type>
80 __device__ inline static bool set_keys(grid_key_dx<3,int> & key, grid_key_dx<3,int> & keyg, ite_type & itg)
81 {
82#ifdef __NVCC__
83
84 key.set_d(0,threadIdx.x + blockIdx.x * blockDim.x + itg.start.get(0));
85 key.set_d(1,threadIdx.y + blockIdx.y * blockDim.y + itg.start.get(1));
86 key.set_d(2,threadIdx.z + blockIdx.z * blockDim.z + itg.start.get(2));
87
88 keyg.set_d(0,key.get(0) + itg.origin.get(0));
89 keyg.set_d(1,key.get(1) + itg.origin.get(1));
90 keyg.set_d(2,key.get(2) + itg.origin.get(2));
91
92 if (key.get(0) > itg.stop.get(0) || key.get(1) > itg.stop.get(1) || key.get(2) > itg.stop.get(2) ||
93 key.get(0) < itg.start_base.get(0) || key.get(1) < itg.start_base.get(1) || key.get(2) < itg.start_base.get(2))
94 {return true;}
95#endif
96 return false;
97 }
98};
99
100template<>
102{
103 template<typename grid_type, typename lambda_t1, typename lambda_t2,typename itd_type, typename coord_type>
104 __device__ inline static void call(grid_type & grid,
105 lambda_t1 f1, lambda_t2 f2,
106 unsigned int blockId,
107 itd_type itd,
108 coord_type & key,
109 coord_type & keyg,unsigned int offset, bool & is_block_empty,
110 bool is_in)
111 {
112#ifdef __NVCC__
113
114 bool is_active = false;
115 if (is_in == true)
116 {is_active = f1(keyg.get(0),keyg.get(1));}
117
118 if (is_active == true)
119 {is_block_empty = false;}
120
121 __syncthreads();
122
123 if (is_block_empty == false)
124 {
125 auto ec = grid.insertBlock(blockId);
126 enc_num<decltype(grid.insertBlock(blockId))> ecn(ec,offset);
127
128 if ( is_active == true)
129 {
130 f2(ecn,keyg.get(0),keyg.get(1));
131 ec.template get<grid_type::pMask>()[offset] = 1;
132 }
133 }
134
135#endif
136 }
137
138 template<typename ite_type>
139 __device__ inline static bool set_keys(grid_key_dx<2,int> & key, grid_key_dx<2,int> & keyg, ite_type & itg)
140 {
141#ifdef __NVCC__
142 key.set_d(0,threadIdx.x + blockIdx.x * blockDim.x + itg.start.get(0));
143 key.set_d(1,threadIdx.y + blockIdx.y * blockDim.y + itg.start.get(1));
144
145 keyg.set_d(0,key.get(0) + itg.origin.get(0));
146 keyg.set_d(1,key.get(1) + itg.origin.get(1));
147
148 if (key.get(0) > itg.stop.get(0) || key.get(1) > itg.stop.get(1) ||
149 key.get(0) < itg.start_base.get(0) || key.get(1) < itg.start_base.get(1))
150 {return true;}
151#endif
152 return false;
153 }
154};
155
157{
158 template<typename grid_type, typename ite_type, typename lambda_f1, typename lambda_f2>
159 __device__ void operator()(grid_type & grid, ite_type itg, bool & is_block_empty, lambda_f1 f1, lambda_f2 f2)
160 {
161#ifdef __NVCC__
162
165
167
168 if (threadIdx.x == 0 && threadIdx.y == 0 && threadIdx.z == 0)
169 {is_block_empty = true;}
170
171 grid.init();
172
173 int offset = 0;
175 bool out = grid.template getInsertBlockOffset<ite_type>(itg,key,blk,offset);
176
177 auto blockId = grid.getBlockLinId(blk);
178
179 launch_insert_sparse_lambda_call<grid_type::dims>::call(grid,f1,f2,blockId,itg,key,keyg,offset,is_block_empty,!not_active);
180
181 __syncthreads();
182
183 grid.flush_block_insert();
184#endif
185 }
186};
187
188template<unsigned int dim>
190{
191 template<typename grid_type, typename ite_type, typename lambda_f2>
192 __device__ void operator()(grid_type & grid, ite_type itg, lambda_f2 f2)
193 {
194#ifdef __NVCC__
195
196 printf("grid on GPU Dimension %d not implemented, yet\n",(int)dim);
197
198#endif
199 }
200};
201
202template<>
204{
205 template<typename grid_type, typename ite_type, typename lambda_f2>
206 __device__ void operator()(grid_type & grid, ite_type itg, lambda_f2 f2)
207 {
208#ifdef __NVCC__
209
210 GRID_ID_2_GLOBAL(itg);
211
212 auto obj = grid.get_o(key);
213
214 f2(obj,keyg.get(0),keyg.get(1));
215
216#endif
217 }
218};
219
220template<>
222{
223 template<typename grid_type, typename ite_type, typename lambda_f2>
224 __device__ void operator()(grid_type & grid, ite_type itg, lambda_f2 f2)
225 {
226#ifdef __NVCC__
227
228 GRID_ID_3_GLOBAL(itg);
229
230 auto obj = grid.get_o(key);
231
232 f2(obj,keyg.get(0),keyg.get(1),keyg.get(2));
233
234#endif
235 }
236};
237
238template<bool is_free>
239struct selvg
240{
241 template<typename a_it_type, typename gdb_ext_type, typename gList_type>
242 static inline void call(a_it_type & a_it, gdb_ext_type & gdb_ext, gList_type & gList, size_t & g_c)
243 {
244 if (gdb_ext.get(g_c).Dbox.isValid() == false)
245 {g_c++;}
246 else
247 {
248 a_it.reinitialize(gList.get(g_c).getIterator(gdb_ext.get(g_c).Dbox.getKP1(),gdb_ext.get(g_c).Dbox.getKP2()));
249 if (a_it.isNext() == false) {g_c++;}
250 }
251 }
252};
253
254template<>
255struct selvg<false>
256{
257 template<typename a_it_type, typename gdb_ext_type, typename gList_type>
258 static inline void call(a_it_type & a_it, gdb_ext_type & gdb_ext, gList_type & gList, size_t & g_c)
259 {
260 // Full iterator (no subset)
261 a_it.reinitialize(gList.get(g_c).getIterator());
262 if (a_it.isNext() == false) {g_c++;}
263 }
264};
265
276template<unsigned int dim, typename device_grid, typename device_sub_it, int impl, typename stencil = no_stencil >
278{
280 size_t g_c;
281
284
287
289 device_sub_it a_it;
290
293
298 {
299 do
300 {
301 if (impl == FREE)
302 {
303 // When the grid has size 0 potentially all the other informations are garbage
304 while (g_c < gList.size() && (gList.get(g_c).size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false ) ) g_c++;
305 }
306 else
307 {
308 // When the grid has size 0 potentially all the other informations are garbage
309 while (g_c < gList.size() && (gList.get(g_c).size() == 0 || gdb_ext.get(g_c).GDbox.isValid() == false) ) g_c++;
310 }
311
312 // get the next grid iterator
313 if (g_c < gList.size())
314 {
316 }
317 } while (g_c < gList.size() && a_it.isNext() == false);
318
319 }
320
321 public:
322
332 const grid_key_dx<dim> & stop)
333 :g_c(0),gList(gk),gdb_ext(gdb_ext),stop(stop)
334 {
335 // Initialize the current iterator
336 // with the first grid
338 }
339
340
352 const grid_key_dx<dim> & stop,
353 const grid_key_dx<dim> (& stencil_pnt)[stencil::nsp])
354 :g_c(0),gList(gk),gdb_ext(gdb_ext),a_it(stencil_pnt),stop(stop)
355 {
356 // Initialize the current iterator
357 // with the first grid
359 }
360
364 {}
365
369 {}
370
373 {
374 }
375
382 {
383 ++a_it;
384
385 // check if a_it is at the end
386
387 if (a_it.isNext() == true)
388 return *this;
389 else
390 {
391 // switch to the new grid
392 g_c++;
393
395 }
396
397 return *this;
398 }
399
405 inline bool isNext() const
406 {
407 // If there are no other grid stop
408
409 if (g_c >= gList.size())
410 {return false;}
411
412 return true;
413 }
414
421 {
423 }
424
433 {
434 return stop;
435 }
436
445 {
446 grid_key_dx<dim> start;
447
448 start.zero();
449
450 return start;
451 }
452
461 {
462 return gdb_ext;
463 }
464
476 {
477 // Get the sub-domain id
478 size_t sub_id = k.getSub();
479
480 auto k_glob = k.getKey();
481
482 // shift
483 auto k_glob2 = k_glob + gdb_ext.get(sub_id).origin;
484
485 return k_glob2;
486 }
487
495 template<unsigned int id> inline grid_dist_lin_dx getStencil()
496 {
497 return grid_dist_lin_dx(g_c,a_it.template getStencil<id>());
498 }
499};
500
501
502
503#endif /* GRID_DIST_ID_ITERATOR_SUB_HPP_ */
This is a distributed grid.
Distributed grid iterator.
size_t g_c
grid list counter
grid_dist_iterator(openfpm::vector< device_grid > &gk, const openfpm::vector< GBoxes< device_grid::dims > > &gdb_ext, const grid_key_dx< dim > &stop, const grid_key_dx< dim >(&stencil_pnt)[stencil::nsp])
Constructor of the distributed grid iterator with stencil support.
grid_dist_key_dx< dim, typename device_grid::base_key > get() const
Get the actual key.
grid_key_dx< dim > getStart() const
it return the start point of the iterator
device_sub_it a_it
Actual iterator.
const openfpm::vector< GBoxes< device_grid::dims > > & gdb_ext
Extension of each grid: domain and ghost + domain.
grid_key_dx< dim > getStop() const
it return the stop point of the iterator
const openfpm::vector< GBoxes< device_grid::dims > > & getGBoxes()
Get the boxes.
grid_dist_iterator(const openfpm::vector< device_grid > &gk, const openfpm::vector< GBoxes< device_grid::dims > > &gdb_ext, const grid_key_dx< dim > &stop)
Constructor of the distributed grid iterator.
grid_key_dx< dim > getGKey(const grid_dist_key_dx< dim, typename device_grid::base_key > &k)
Convert a g_dist_key_dx into a global key.
grid_dist_iterator(grid_dist_iterator< dim, device_grid, device_sub_it, impl, stencil > &&g)
Copy constructor.
grid_dist_iterator(const grid_dist_iterator< dim, device_grid, device_sub_it, impl, stencil > &g)
Copy constructor.
const openfpm::vector< device_grid > & gList
List of the grids we are going to iterate.
grid_dist_iterator< dim, device_grid, device_sub_it, impl, stencil > & operator++()
Get the next element.
void selectValidGrid()
from g_c increment g_c until you find a valid grid
grid_key_dx< dim > stop
stop point (is the grid size)
bool isNext() const
Check if there is the next element.
grid_dist_lin_dx getStencil()
Return the stencil point offset.
Grid key for a distributed grid.
Distributed linearized key.
grid_key_dx is the key to access any element in the grid
Definition grid_key.hpp:19
void zero()
Set to zero the key.
Definition grid_key.hpp:170
Implementation of 1-D std::vector like structure.
size_t size()
Stub size.
This structure store the Box that define the domain inside the Ghost + domain box.
Definition GBoxes.hpp:40