8#ifndef SPARSEGRID_ITERATOR_BLOCK_HPP_
9#define SPARSEGRID_ITERATOR_BLOCK_HPP_
11#if !defined(__NVCC__) || defined(CUDA_ON_CPU) || defined(__HIP__)
14#define DISABLE_VECTORIZATION_OPTIMIZATION_WHEN_VCDEVEL_IS_SCALAR (Vc::float_v::Size *sizeof(float) >= sizeof(T))
18#define DISABLE_VECTORIZATION_OPTIMIZATION_WHEN_VCDEVEL_IS_SCALAR 1
24#include "Grid/iterators/grid_skin_iterator.hpp"
25#include "SparseGrid_chunk_copy.hpp"
28template<
int c,
bool is_neg = c < 0>
31 typedef boost::mpl::
int_<c> type;
35struct fix_neg_to_one<c,true>
37 typedef boost::mpl::int_<1> type;
50template<
unsigned int dim,
typename vector_blocks_ext>
66 inline void operator()(T& val)
68 k.set_d(T::value,boost::mpl::at<
typename vector_blocks_ext::type,boost::mpl::int_<T::value>>::type::value*k.get(T::value));
84template<
unsigned int dim,
typename header_type,
typename vector_blocks_ext>
85struct fill_chunk_block
90 unsigned int chunk_id;
99 inline fill_chunk_block(header_type & header,
unsigned int chunk_id)
100 :chunk_id(chunk_id),header(header)
105 inline void operator()(T& val)
107 cnk_box.
setLow(T::value,header.get(chunk_id).pos.get(T::value));
108 cnk_box.
setHigh(T::value,header.get(chunk_id).pos.get(T::value) + boost::mpl::at<typename vector_blocks_ext::type,T>::type::value - 1);
112template<
unsigned int prop,
unsigned int stencil_size,
unsigned int dim,
typename vector_blocks_exts,
typename vector_ext>
115 template<
unsigned int N1,
typename T,
typename SparseGr
idType>
116 static void loadBlock(T arr[N1], SparseGridType & sgt,
int chunk_id,
unsigned char mask[N1])
120 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,dim> >(gbs);
128 auto & data = sgt.private_get_data();
129 auto & header_mask = sgt.private_get_header_mask();
131 auto & h = header_mask.get(chunk_id);
133 auto & ref_block = data.template get<prop>(chunk_id);
135 while(it_in_block.isNext())
137 auto p = it_in_block.get();
141 for (
int i = 0 ; i < dim ; i++)
142 {arr_p.
set_d(i,p.get(i)+stencil_size);}
144 size_t id = g_block_arr.LinId(arr_p);
145 size_t idi = g_in_block.LinId(p);
147 arr[id] = ref_block[idi];
148 mask[id] = exist_sub(h,idi);
154 template<
unsigned int N1,
typename T,
typename SparseGr
idType>
155 static void loadBlock(T arr[N1], SparseGridType & sgt,
int chunk_id)
159 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,dim> >(gbs);
167 auto & data = sgt.private_get_data();
168 auto & header_mask = sgt.private_get_header_mask();
170 auto & ref_block = data.template get<prop>(chunk_id);
172 while(it_in_block.isNext())
174 auto p = it_in_block.get();
178 for (
int i = 0 ; i < dim ; i++)
179 {arr_p.
set_d(i,p.get(i)+stencil_size);}
181 arr[g_block_arr.LinId(arr_p)] = ref_block[g_in_block.LinId(p)];
187 template<
unsigned int N1,
typename T,
typename SparseGr
idType>
188 static void storeBlock(T arr[N1], SparseGridType & sgt,
int chunk_id)
192 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,dim> >(gbs);
200 auto & data = sgt.private_get_data();
201 auto & header_mask = sgt.private_get_header_mask();
203 auto & ref_block = data.template get<prop>(chunk_id);
205 while(it_in_block.isNext())
207 auto p = it_in_block.get();
209 ref_block[g_in_block.LinId(p)] = arr[g_in_block.LinId(p)];
221 template<
unsigned int N1,
typename T,
typename SparseGr
idType>
222 static void loadBorder(T arr[N1],
223 SparseGridType & sgt,
229 unsigned char mask[N1],
234 auto & data = sgt.private_get_data();
235 auto & header_mask = sgt.private_get_header_mask();
236 auto & header_inf = sgt.private_get_header_inf();
238 auto & hm = header_mask.get(chunk_id);
239 auto & hc = header_inf.get(chunk_id);
241 maps_blk.resize(block_skin.size());
243 for (
int i = 0 ; i < maps_blk.
size() ; i++)
247 for (
int j = 0 ; j < dim ; j++)
248 {p.
set_d(j,block_skin.get(i).get(j) + hc.pos.get(j) / size::data[j] - 1);}
250 maps_blk.get(i) = sgt.getChunk(p);
253 for (
int i = 0 ; i < bord.
size(); i++)
255 size_t ac = maps_blk.get(chunk_ids.get(i));
257 size_t b = bord.get(i);
258 size_t off = offsets.template get<0>(i);
260 auto & h = header_mask.get(ac);
262 arr[b] = (ac == data.size()-1)?data.template get<prop>(0)[off]:data.template get<prop>(ac)[off];
263 mask[b] = (ac == data.size()-1)?0:exist_sub(h,off);
271template<
unsigned int prop,
unsigned int stencil_size,
typename vector_blocks_exts,
typename vector_ext>
272struct loadBlock_impl<
prop,stencil_size,3,vector_blocks_exts,vector_ext>
274 template<
unsigned int N1,
typename T,
typename SparseGr
idType>
275 inline static void loadBlock(T arr[N1], SparseGridType & sgt,
int chunk_id,
unsigned char mask[N1])
277 auto & data = sgt.private_get_data();
278 auto & header_mask = sgt.private_get_header_mask();
280 auto & h = header_mask.
get(chunk_id);
284 auto & chunk = data.template get<prop>(chunk_id);
290 template<
unsigned int N1,
typename T,
typename SparseGr
idType>
291 inline static void storeBlock(T arr[N1], SparseGridType & sgt,
int chunk_id)
294 auto & data = sgt.private_get_data();
295 auto & header_mask = sgt.private_get_header_mask();
299 auto & chunk = data.template get<prop>(chunk_id);
312 template<
bool findNN,
typename NNType,
unsigned int N1,
typename T,
typename SparseGr
idType>
313 inline static void loadBorder(T arr[N1],
314 SparseGridType & sgt,
320 unsigned char mask[N1],
325 auto & data = sgt.private_get_data();
326 auto & header_mask = sgt.private_get_header_mask();
327 auto & NNlist = sgt.private_get_nnlist();
329 auto & h = header_mask.get(chunk_id);
334 typedef typename boost::mpl::at<typename vector_blocks_exts::type,boost::mpl::int_<0>>::type sz0;
335 typedef typename boost::mpl::at<typename vector_blocks_exts::type,boost::mpl::int_<1>>::type sz1;
336 typedef typename boost::mpl::at<typename vector_blocks_exts::type,boost::mpl::int_<2>>::type sz2;
345 r = sgt.getChunk(p,exist);
346 NNlist.template get<0>(chunk_id*NNType::nNN) = (exist)?r:-1;
350 r = NNlist.template get<0>(chunk_id*NNType::nNN);
355 auto & h = header_mask.get(r);
365 r = sgt.getChunk(p,exist);
366 NNlist.template get<0>(chunk_id*NNType::nNN+1) = (exist)?r:-1;
370 r = NNlist.template get<0>(chunk_id*NNType::nNN+1);
375 auto & h = header_mask.get(r);
386 r = sgt.getChunk(p,exist);
387 NNlist.template get<0>(chunk_id*NNType::nNN+2) = (exist)?r:-1;
391 r = NNlist.template get<0>(chunk_id*NNType::nNN+2);
396 auto & h = header_mask.get(r);
406 r = sgt.getChunk(p,exist);
407 NNlist.template get<0>(chunk_id*NNType::nNN+3) = (exist)?r:-1;
411 r = NNlist.template get<0>(chunk_id*NNType::nNN+3);
416 auto & h = header_mask.get(r);
427 r = sgt.getChunk(p,exist);
428 NNlist.template get<0>(chunk_id*NNType::nNN+4) = (exist)?r:-1;
432 r = NNlist.template get<0>(chunk_id*NNType::nNN+4);
437 auto & h = header_mask.get(r);
447 r = sgt.getChunk(p,exist);
448 NNlist.template get<0>(chunk_id*NNType::nNN+5) = (exist)?r:-1;
452 r = NNlist.template get<0>(chunk_id*NNType::nNN+5);
457 auto & h = header_mask.get(r);
472template<
unsigned dim,
473 unsigned int stencil_size,
474 typename SparseGridType,
475 typename vector_blocks_exts,
477class grid_key_sparse_dx_iterator_block_sub
480 SparseGridType & spg;
522 auto & header = spg.private_get_header_inf();
523 auto & header_mask = spg.private_get_header_mask();
525 while (chunk_id < header.size())
527 auto & mask = header_mask.get(chunk_id).mask;
529 fill_chunk_block<dim,
decltype(header),vector_blocks_exts> fcb(header,chunk_id);
531 boost::mpl::for_each_ref<boost::mpl::range_c<int,0,dim>>(fcb);
533 if (bx.
Intersect(fcb.cnk_box,block_it) ==
true)
535 block_it -= header.get(chunk_id).pos.toPoint();
547 typedef typename vmpl_sum_constant<2*stencil_size,typename vector_blocks_exts::type>::type stop_border_vmpl;
554 typedef vector_blocks_exts vector_blocks_exts_type;
555 typedef vector_ext vector_ext_type;
557 static const int sizeBlock = vector_blocks_exts::size::value;
566 grid_key_sparse_dx_iterator_block_sub() {};
568 grid_key_sparse_dx_iterator_block_sub(SparseGridType & spg,
571 :spg(spg),chunk_id(1),
572 start_(start),stop_(stop)
577 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,dim> >(gbs);
583 for (
int i = 0 ; i < dim ; i ++)
586 skinb.setHigh(i,gbs.
sz_tot[i]-1);
589 bc[i] = NON_PERIODIC;
599 b_map.resize(g_smb.size());
601 while (gsi_b.isNext())
603 auto p = gsi_b.
get();
607 b_map.get(g_smb.LinId(p)) = block_skin.
size() - 1;
621 bord.add(g_sm.LinId(p));
625 for (
int i = 0 ; i < dim ; i++)
628 if (p.
get(i) < stencil_size)
629 {offset += (gbs.
sz_block[i]-1)*stride;}
630 else if (p.
get(i) >= gbs.
sz_tot[i] - stencil_size)
633 {offset += (p.
get(i)-stencil_size)*stride;}
641 size_t bid = g_smb.LinId(sh);
642 chunk_shifts.add(b_map.get(bid));
647 for (
size_t i = 0 ; i < dim ; i++)
668 start_ = g_s_it.start_;
669 stop_ = g_s_it.stop_;
673 inline grid_key_sparse_dx_iterator_block_sub<dim,stencil_size,SparseGridType,vector_blocks_exts> & operator++()
675 auto & header = spg.private_get_header_inf();
679 if (chunk_id < header.size())
694 auto & header = spg.private_get_header_inf();
696 return chunk_id < header.size();
720 template<
unsigned int prop,
typename T>
721 void loadBlock(T arr[sizeBlock])
723 auto & header_mask = spg.private_get_header_mask();
724 auto & header_inf = spg.private_get_header_inf();
726 loadBlock_impl<prop,stencil_size,dim,vector_blocks_exts,vector_ext>::template loadBlock<prop>(arr,spg,chunk_id);
728 hm = &header_mask.get(chunk_id);
729 hc = &header_inf.get(chunk_id);
732 template<
unsigned int prop,
typename T>
733 void loadBlock(T arr[sizeBlock],
unsigned char mask[sizeBlock])
735 auto & header_mask = spg.private_get_header_mask();
736 auto & header_inf = spg.private_get_header_inf();
738 loadBlock_impl<prop,stencil_size,dim,vector_blocks_exts,vector_ext>::template loadBlock<prop>(arr,spg,chunk_id,mask);
740 hm = &header_mask.get(chunk_id);
741 hc = &header_inf.get(chunk_id);
744 template<
unsigned int prop,
typename T>
745 void storeBlock(T arr[sizeBlock])
747 auto & header_mask = spg.private_get_header_mask();
748 auto & header_inf = spg.private_get_header_inf();
750 loadBlock_impl<prop,stencil_size,dim,vector_blocks_exts,vector_ext>::template storeBlock<sizeBlock>(arr,spg,chunk_id);
752 hm = &header_mask.get(chunk_id);
753 hc = &header_inf.get(chunk_id);
757 template<
unsigned int prop,
typename NNtype,
bool findNN,
typename T>
758 void loadBlockBorder(T arr[sizeBlockBord],
unsigned char mask[sizeBlockBord])
760 auto & header_mask = spg.private_get_header_mask();
761 auto & header_inf = spg.private_get_header_inf();
763 loadBlock_impl<prop,stencil_size,dim,vector_blocks_exts,vector_ext>::template loadBlock<sizeBlockBord>(arr,spg,chunk_id,mask);
764 loadBlock_impl<prop,stencil_size,dim,vector_blocks_exts,vector_ext>::template loadBorder<findNN,NNtype,sizeBlockBord>(arr,spg,chunk_id,bord,block_skin,chunk_shifts,offsets,mask,maps_blk);
766 hm = &header_mask.get(chunk_id);
767 hc = &header_inf.get(chunk_id);
776 constexpr int start_b(
int i)
const
778 return block_it.
getLow(i) + stencil_size;
786 constexpr int stop_b(
int i)
const
788 return block_it.
getHigh(i) + 1 + stencil_size;
796 constexpr int start(
int i)
const
798 return block_it.
getLow(i);
806 constexpr int stop(
int i)
const
808 return block_it.
getHigh(i) + 1;
816 template<
typename a,
typename ...lT>
817 __device__ __host__
inline size_t Lin(a v,lT...t)
const
820 if (
sizeof...(t)+1 > dim)
822 std::cerr <<
"Error incorrect grid cannot linearize more index than its dimensionality" <<
"\n";
826 return v*
vmpl_reduce_prod_stop<
typename vector_blocks_exts::type,(
int)dim - (
int)
sizeof...(t) - 2>::type::value + Lin(t...);
830 template<
typename a> __device__ __host__
inline size_t Lin(a v)
const
840 template<
typename a,
typename ...lT>
841 __device__ __host__
inline size_t LinB(a v,lT...t)
const
844 if (
sizeof...(t)+1 > dim)
846 std::cerr <<
"Error incorrect grid cannot linearize more index than its dimensionality" <<
"\n";
854 template<
typename a> __device__ __host__
inline size_t LinB(a v)
const
864 template<
typename a,
typename ...lT>
865 __device__ __host__
inline size_t LinB_off(a v,lT...t)
const
868 if (
sizeof...(t)+1 > dim)
870 std::cerr <<
"Error incorrect grid cannot linearize more index than its dimensionality" <<
"\n";
874 return (v-stencil_size)*
vmpl_reduce_prod_stop<
typename vector_blocks_exts::type,(
int)dim - (
int)
sizeof...(t) - 2>::type::value + LinB_off(t...);
878 template<
typename a> __device__ __host__
inline size_t LinB_off(a v)
const
888 template<
typename ... ArgsType>
889 bool exist(ArgsType ... args)
891 size_t l = LinB_off(args ...);
893 return spg.exist_sub(*hm,l);
This class represent an N-dimensional box.
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
__device__ __host__ bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
__device__ __host__ T getHigh(int i) const
get the high interval of the box
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
grid_key_dx is the key to access any element in the grid
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
__device__ __host__ index_type get(index_type i) const
Get the i index.
Grid key sparse iterator on a sub-part of the domain.
size_t chunk_id
point to the actual chunk
Box< dim, size_t > bx
Sub-grid box.
Implementation of 1-D std::vector like structure.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
__device__ __host__ boost::mpl::at< type, boost::mpl::int_< i > >::type & get()
get the properties i
generate_array_vector_impl< T, boost::mpl::size< F >::value-1, F >::result result
generate compile-time array vector
this class is a functor for "for_each" algorithm
size_t sz_block[dim]
sizes
size_t sz_tot[dim]
sizes in point with border
size_t sz_ext_b[dim]
sizes with border block
size_t sz_ext[dim]
sizes blocks
to_variadic_const_impl< 1, N, M, exit_::value, M >::type type
generate the boost::fusion::vector apply H on each term