OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
grid_sm.hpp
1 #ifndef GRID_HPP
2 #define GRID_HPP
3 
4 #include "config.h"
5 #include <boost/shared_array.hpp>
6 #include <vector>
7 #include <initializer_list>
8 #include <array>
9 #include "memory/memory.hpp"
10 #include "Space/Shape/Box.hpp"
11 #include "grid_key.hpp"
12 #include <iostream>
13 #include "util/mathutil.hpp"
14 #include "iterators/stencil_type.hpp"
15 
16 #define PERIODIC 1
17 #define NON_PERIODIC 0
18 
19 // Box need the definition of grid_key_dx_r
20 #define HARDWARE 1
21 
28 class NoCheck
29 {
30 public:
39  static bool valid(size_t v_id, size_t sz)
40  {
41  return true;
42  }
43 };
44 
52 {
53 public:
64  static bool valid(size_t v_id, size_t sz)
65  {
66  return v_id < sz;
67  }
68 };
69 
71 template<unsigned int N, typename T> class grid_sm;
72 
74 template <unsigned int dim> class print_warning_on_adjustment;
75 
77 template<unsigned int dim,typename stencil=no_stencil,typename warn=print_warning_on_adjustment<dim>> class grid_key_dx_iterator_sub;
78 
86 template<unsigned int N, typename T>
87 class grid_sm
88 {
91 
93  size_t size_tot;
94 
96  size_t sz[N];
97 
99  size_t sz_s[N];
100 
110  inline void Initialize(const size_t sz)
111  {
113  sz_s[0] = sz;
114  this->sz[0] = sz;
115 
116  // set the box
117  box.setHigh(0,sz);
118  box.setLow(0,0);
119 
120  for (size_t i = 1 ; i < N ; i++)
121  {
122  /* coverity[dead_error_begin] */
123  sz_s[i] = sz*sz_s[i-1];
124  this->sz[i] = sz;
125 
126  // set the box
127  box.setHigh(i,sz);
128  box.setLow(i,0);
129  }
130  }
131 
141  inline void Initialize(const size_t (& sz)[N])
142  {
144  sz_s[0] = sz[0];
145  this->sz[0] = sz[0];
146 
147  // set the box
148  box.setHigh(0,sz[0]);
149  box.setLow(0,0);
150 
151  for (size_t i = 1 ; i < N ; i++)
152  {
153  /* coverity[dead_error_begin] */
154  sz_s[i] = sz[i]*sz_s[i-1];
155  this->sz[i] = sz[i];
156 
157  // set the box
158  box.setHigh(i,sz[i]);
159  box.setLow(i,0);
160  }
161  }
162 
169  inline void Initialize()
170  {
172  sz_s[0] = 0;
173  this->sz[0] = 0;
174 
175  // set the box
176  box.setHigh(0,0);
177  box.setLow(0,0);
178 
179  for (size_t i = 1 ; i < N ; i++)
180  {
181  /* coverity[dead_error_begin] */
182  sz_s[i] = sz[i]*sz_s[i-1];
183 
184  // set the box
185  box.setHigh(i,sz[i]);
186  box.setLow(i,0);
187  }
188  }
189 
190 public:
191 
197  inline const Box<N,size_t> & getBox() const
198  {
199  return box;
200  }
201 
211  inline const Box<N,size_t> getBoxKey() const
212  {
213  Box<N,size_t> bx;
214 
215  for (size_t i = 0 ; i < N ; i++)
216  {
217  bx.setLow(i,box.getLow(i));
218  bx.setHigh(i,box.getHigh(i) - 1);
219  }
220 
221  return bx;
222  }
223 
229  inline void setDimensions(const size_t (& dims)[N])
230  {
231  Initialize(dims);
232  size_tot = totalSize(dims);
233  }
234 
241  inline grid_sm()
242  :size_tot(0)
243  {
244  // Initialize sz
245  for (size_t i = 0 ; i < N ; i++)
246  {sz[i] = 0;}
247 
248  Initialize();
249  }
250 
259  template<typename S> inline grid_sm(const grid_sm<N,S> & g)
260  {
261  box = g.box;
262  size_tot = g.size_tot;
263 
264  for (size_t i = 0 ; i < N ; i++)
265  {
266  sz[i] = g.sz[i];
267  sz_s[i] = g.sz_s[i];
268  }
269  }
270 
271  // Static element to calculate total size
272 
273  inline size_t totalSize(const size_t sz)
274  {
275  size_t tSz = 1;
276 
277  for (size_t i = 0 ; i < N ; i++)
278  {
279  tSz *= sz;
280  }
281 
282  return tSz;
283  }
284 
285  // Static element to calculate total size
286 
287  inline size_t totalSize(const size_t (& sz)[N])
288  {
289  size_t tSz = 1;
290 
291  for (size_t i = 0 ; i < N ; i++)
292  {
293  tSz *= sz[i];
294  }
295 
296  return tSz;
297  }
298 
299 
308  inline grid_sm(const size_t & sz)
309  : size_tot(totalSize(sz))
310  {
311  Initialize(sz);
312  }
313 
322  inline grid_sm(const size_t (& sz)[N])
323  : size_tot(totalSize(sz))
324  {
325  Initialize(sz);
326  }
327 
337  template<typename check=NoCheck> inline mem_id LinId(const grid_key_dx<N> & gk, const char sum_id[N]) const
338  {
339  mem_id lid;
340 
341  // Check the sum produce a valid key
342 
343  if (check::valid(gk.get(0) + sum_id[0],sz[0]) == false)
344  return -1;
345 
346  lid = gk.get(0) + sum_id[0];
347 
348 
349  for (mem_id i = 1 ; i < N ; i++)
350  {
351  // Check the sum produce a valid key
352 
353  if (check::valid(gk.get(i) + sum_id[i],sz[i]) == false)
354  return -1;
355 
356  lid += (gk.get(i) + sum_id[i]) * sz_s[i-1];
357  }
358 
359  return lid;
360  }
361 
372  template<typename check=NoCheck> inline mem_id LinId(const grid_key_dx<N> & gk, const char sum_id[N], const size_t (&bc)[N]) const
373  {
374  mem_id lid;
375 
376  // Check the sum produce a valid key
377 
378  if (bc[0] == NON_PERIODIC)
379  {
380  if (check::valid(gk.get(0) + sum_id[0],sz[0]) == false)
381  return -1;
382 
383  lid = gk.get(0) + sum_id[0];
384  }
385  else
386  {
387  lid = openfpm::math::positive_modulo(gk.get(0) + sum_id[0],sz[0]);
388  }
389 
390  for (mem_id i = 1 ; i < N ; i++)
391  {
392  // Check the sum produce a valid key
393 
394  /* coverity[dead_error_line] */
395  if (bc[i] == NON_PERIODIC)
396  {
397  if (check::valid(gk.get(i) + sum_id[i],sz[i]) == false)
398  return -1;
399 
400  lid += (gk.get(i) + sum_id[i]) * sz_s[i-1];
401  }
402  else
403  {
404  lid += (openfpm::math::positive_modulo(gk.get(i) + sum_id[i],sz[i])) * sz_s[i-1];
405  }
406  }
407 
408  return lid;
409  }
410 
419  inline mem_id LinIdPtr(size_t * k) const
420  {
421  mem_id lid = k[0];
422  for (mem_id i = 1 ; i < N ; i++)
423  {
424  lid += k[i] * sz_s[i-1];
425  }
426 
427  return lid;
428  }
429 
439  inline mem_id LinId(const size_t (& k)[N]) const
440  {
441  mem_id lid = k[0];
442  for (mem_id i = 1 ; i < N ; i++)
443  {
444  /* coverity[dead_error_line] */
445  lid += k[i] * sz_s[i-1];
446  }
447 
448  return lid;
449  }
450 
460  inline mem_id LinId(const grid_key_dx<N> & gk) const
461  {
462  mem_id lid = gk.get(0);
463  for (mem_id i = 1 ; i < N ; i++)
464  {
465  /* coverity[dead_error_begin */
466  lid += gk.get(i) * sz_s[i-1];
467  }
468 
469  return lid;
470  }
471 
477  template<typename a, typename ...lT> inline mem_id Lin(a v,lT...t) const
478  {
479 #ifdef DEBUG
480  if (sizeof...(t)+1 > N)
481  {
482  std::cerr << "Error incorrect grid cannot linearize more index than its dimensionality" << "\n";
483  }
484 #endif
485 
486  return v*sz_s[sizeof...(t)-1] + Lin(t...);
487  }
488 
490  template<typename a> inline mem_id Lin(a v) const
491  {
492  return v;
493  }
494 
496 
503  inline grid_key_dx<N> InvLinId(mem_id id) const
504  {
505  // Inversion of linearize
506 
507  grid_key_dx<N> gk;
508 
509  for (mem_id i = 0 ; i < N ; i++)
510  {
511  gk.set_d(i,id % sz[i]);
512  id /= sz[i];
513  }
514 
515  return gk;
516  }
517 
528  //#pragma openfpm layout(get)
529  template<unsigned int dim, unsigned int p> inline mem_id LinId(const grid_key_d<dim,p> & gk) const
530  {
531  mem_id lid = gk.k[0];
532  for (mem_id i = 1 ; i < dim ; i++)
533  {
534  lid += gk.k[i] * sz_s[i-1];
535  }
536 
537  return lid;
538  }
539 
549  //#pragma openfpm layout(get)
550  inline mem_id LinId(mem_id * id) const
551  {
552  mem_id lid = 0;
553  lid += id[0];
554  for (mem_id i = 1 ; i < N ; i++)
555  {
556  lid += id[i] * sz_s[i-1];
557  }
558 
559  return lid;
560  }
561 
563  ~grid_sm() {};
564 
572  inline size_t size() const
573  {
574  return size_tot;
575  };
576 
583  inline grid_sm<N,T> & operator=(const grid_sm<N,T> & g)
584  {
585  box = g.box;
586  size_tot = g.size_tot;
587 
588  for (size_t i = 0 ; i < N ; i++)
589  {
590  sz[i] = g.sz[i];
591  sz_s[i] = g.sz_s[i];
592  }
593 
594  return *this;
595  }
596 
605  inline bool operator==(const grid_sm<N,T> & g)
606  {
607  for (size_t i = 0 ; i < N ; i++)
608  {
609  if (sz[i] != g.sz[i])
610  return false;
611  }
612 
613  if (box != g.box)
614  return false;
615 
616 #ifdef SE_CLASS1
617 
618  if (size_tot != g.size_tot)
619  return false;
620 
621  for (size_t i = 0 ; i < N ; i++)
622  {
623  if (sz_s[i] != g.sz_s[i])
624  return false;
625  }
626 
627 #endif
628  return true;
629  }
630 
637  inline bool operator!=(const grid_sm<N,T> & g)
638  {
639  return ! this->operator==(g);
640  }
641 
653  inline size_t size_s(unsigned int i) const
654  {
655  return sz_s[i];
656  }
657 
667  inline size_t size(unsigned int i) const
668  {
669  return sz[i];
670  }
671 
677  inline const size_t (& getSize() const)[N]
678  {
679  return sz;
680  }
681 
691  {
692  return grid_key_dx_iterator_sub<N>(*this,start,stop);
693  }
694 
700  inline void swap(grid_sm<N,T> & g)
701  {
702  Box<N,size_t> box_t = box;
703  box = g.box;
704  g.box = box_t;
705 
706  size_t tmp = size_tot;
707  size_tot = g.size_tot;
708  g.size_tot = tmp;
709 
710  for (size_t i = 0 ; i < N ; i++)
711  {
712  tmp = sz[i];
713  sz[i] = g.sz[i];
714  g.sz[i] = tmp;
715 
716  tmp = sz_s[i];
717  sz_s[i] = g.sz_s[i];
718  g.sz_s[i] = tmp;
719  }
720  }
721 
727  std::string toString() const
728  {
729  std::stringstream str;
730 
731  for (size_t i = 0 ; i < N ; i++)
732  str << "sz[" << i << "]=" << size(i) << " ";
733 
734  return str.str();
735  }
736 
738  template <unsigned int,typename> friend class grid_sm;
739 };
740 
741 
742 
743 
751 {
752  size_t dim;
753 
754 public:
755 
762  size_t getDim()
763  {
764  return dim;
765  }
766 
773  :dim(key.dim)
774  {
775  // Allocate the key
776  k = new mem_id[dim];
777 
778  // Copy the key
779  for(unsigned int i = 0 ; i < dim ; i++)
780  {
781  k[i] = key.k[i];
782  }
783  }
784 
792  grid_key_dx_r(size_t dim)
793  :dim(dim)
794  {
795  // Allocate the key
796  k = new mem_id[dim];
797  }
798 
799  ~grid_key_dx_r()
800  {
801  delete [] k;
802  }
803 
805  template<typename a, typename ...T>void set(a v, T...t)
806  {
807  k[dim-1] = v;
808  invert_assign(t...);
809  }
810 
820  mem_id get(size_t i)
821  {
822  return k[i];
823  }
824 
833  void set_d(size_t i, mem_id id)
834  {
835  k[i] = id;
836  }
837 
839  mem_id * k;
840 
841 private:
842 
848  template<typename a, typename ...T>void invert_assign(a v,T...t)
849  {
850  k[sizeof...(T)] = v;
851  invert_assign(t...);
852  }
853 
854  template<typename a, typename ...T>void invert_assign(a v)
855  {
856  k[0] = v;
857  }
858 
859  void invert_assign()
860  {
861  }
862 
863 };
864 
865 
874 {
875  size_t dim;
876 
878  size_t sz;
879 
880  // Actual grid_key position
881  grid_key_dx_r gk;
882 
883 public:
884 
891  size_t getDim()
892  {
893  return dim;
894  }
895 
903  Iterator_g_const(size_t n, size_t sz)
904  :dim(n),sz(sz),gk(n)
905  {
906  // fill gk with the first grid element that satisfied the constrain: 0,1,2,3... dim
907 
908  for (size_t i = 0 ; i < dim ; i++)
909  {
910  gk.set_d(i,dim-i-1);
911  }
912  }
913 
923  {
925 
926  gk.set_d(0,gk.get(0)+1);
927 
929 
930  unsigned int i = 0;
931  for ( ; i < dim-1 ; i++)
932  {
933  size_t id = gk.get(i);
934  if (id >= sz)
935  {
936  // ! overflow, increment the next index
937 
938  id = gk.get(i+1);
939  if (id+i+2 >= sz)
940  {
941  // there is no-way to produce a valid key
942  // there is not need to check the previous index
943  // overflow i+1
944 
945  gk.set_d(i+1,sz);
946  }
947  else
948  {
949 
950  // reinitialize the previous index
951 
952  for (unsigned int s = 0 ; s <= i+1 ; s++)
953  {
954  gk.set_d(i+1-s,id+1+s);
955  }
956  }
957  }
958  else
959  {
960  break;
961  }
962  }
963 
964  return *this;
965  }
966 
975  bool isNext()
976  {
977  // If dimensionless return immediately
978  if (dim == 0)
979  return false;
980 
981  if (gk.get(dim-1) < static_cast<mem_id>(sz-dim+1))
982  {
984 
985  return true;
986  }
987 
989  return false;
990  }
991 
1001  {
1002  return gk;
1003  }
1004 };
1005 
1006 #endif
Declaration print_warning_on_adjustment.
Definition: grid_sm.hpp:74
grid_sm()
Default constructor.
Definition: grid_sm.hpp:241
mem_id LinId(const grid_key_dx< N > &gk, const char sum_id[N]) const
Linearization of the grid_key_dx with a specified shift.
Definition: grid_sm.hpp:337
size_t sz_s[N]
size of the grid on each stride (used for linearization)
Definition: grid_sm.hpp:99
mem_id Lin(a v) const
Linearize a set of index.
Definition: grid_sm.hpp:490
Iterator_g_const(size_t n, size_t sz)
Constructor.
Definition: grid_sm.hpp:903
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:479
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
const Box< N, size_t > getBoxKey() const
Return the box enclosing the grid.
Definition: grid_sm.hpp:211
void set_d(size_t i, mem_id id)
Set the i index.
Definition: grid_sm.hpp:833
grid_key_dx_r(size_t dim)
constructor
Definition: grid_sm.hpp:792
size_t size_s(unsigned int i) const
Definition: grid_sm.hpp:653
void set(a v, T...t)
set the grid key from a list of numbers
Definition: grid_sm.hpp:805
mem_id LinIdPtr(size_t *k) const
Linearization of the set of indexes.
Definition: grid_sm.hpp:419
size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:572
Emulate grid_key_dx with runtime dimensionality.
Definition: grid_sm.hpp:750
size_t size_tot
total number of the elements in the grid
Definition: grid_sm.hpp:93
const Box< N, size_t > & getBox() const
Return the box enclosing the grid.
Definition: grid_sm.hpp:197
Box< N, size_t > box
Box enclosing the grid.
Definition: grid_sm.hpp:90
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:490
static bool valid(size_t v_id, size_t sz)
Check if vertex exist.
Definition: grid_sm.hpp:64
void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:467
mem_id LinId(const grid_key_d< dim, p > &gk) const
Linearization of the grid_key_d.
Definition: grid_sm.hpp:529
grid_key_dx_r(grid_key_dx_r &key)
constructor from another key
Definition: grid_sm.hpp:772
size_t sz[N]
size of the grid
Definition: grid_sm.hpp:96
bool operator==(const grid_sm< N, T > &g)
Check if the two grid_sm are the same.
Definition: grid_sm.hpp:605
bool operator!=(const grid_sm< N, T > &g)
Check if the two grid_sm are the same.
Definition: grid_sm.hpp:637
grid_key_dx< N > InvLinId(mem_id id) const
Construct.
Definition: grid_sm.hpp:503
mem_id LinId(const size_t(&k)[N]) const
Linearization of the grid_key_dx.
Definition: grid_sm.hpp:439
void invert_assign(a v, T...t)
Recursively invert the assignment.
Definition: grid_sm.hpp:848
mem_id get(size_t i) const
Get the i index.
Definition: grid_key.hpp:394
void Initialize()
Initialize the basic structure.
Definition: grid_sm.hpp:169
grid_sm(const size_t &sz)
Construct a grid of a specified size.
Definition: grid_sm.hpp:308
~grid_sm()
Destructor.
Definition: grid_sm.hpp:563
static bool valid(size_t v_id, size_t sz)
No check is performed.
Definition: grid_sm.hpp:39
void swap(grid_sm< N, T > &g)
swap the grid_sm informations
Definition: grid_sm.hpp:700
grid_sm(const grid_sm< N, S > &g)
construct a grid from another grid
Definition: grid_sm.hpp:259
grid_sm< N, T > & operator=(const grid_sm< N, T > &g)
Copy the grid from another grid.
Definition: grid_sm.hpp:583
size_t sz
size of the grid (the grid is assumed a square so equal on each dimension)
Definition: grid_sm.hpp:878
size_t getDim()
Get the dimensionality of the iterator.
Definition: grid_sm.hpp:891
const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition: grid_sm.hpp:677
void Initialize(const size_t(&sz)[N])
Initialize the basic structure.
Definition: grid_sm.hpp:141
mem_id Lin(a v, lT...t) const
linearize an arbitrary set of index
Definition: grid_sm.hpp:477
void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:456
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
Iterator_g_const & operator++()
Get the next element.
Definition: grid_sm.hpp:922
mem_id LinId(const grid_key_dx< N > &gk) const
Linearization of the grid_key_dx.
Definition: grid_sm.hpp:460
Declaration grid_sm.
Definition: grid_sm.hpp:71
grid_key_d is the key to access any element in the grid
Definition: grid_key.hpp:465
Declaration grid_key_dx_iterator_sub.
Definition: grid_sm.hpp:77
size_t size(unsigned int i) const
Definition: grid_sm.hpp:667
Class to check if the edge can be created or not.
Definition: grid_sm.hpp:28
bool isNext()
Check if there is the next element.
Definition: grid_sm.hpp:975
mem_id LinId(mem_id *id) const
Linearization of an array of mem_id (long int)
Definition: grid_sm.hpp:550
std::string toString() const
Produce a string from the object.
Definition: grid_sm.hpp:727
Definition: ids.hpp:168
void set_d(size_t i, mem_id id)
Set the i index.
Definition: grid_key.hpp:407
mem_id * k
structure that store all the index
Definition: grid_sm.hpp:839
grid_key_dx_iterator_sub< N > getSubIterator(grid_key_dx< N > &start, grid_key_dx< N > &stop) const
Return a sub-grid iterator.
Definition: grid_sm.hpp:690
Class to check if the edge can be created or not.
Definition: grid_sm.hpp:51
mem_id LinId(const grid_key_dx< N > &gk, const char sum_id[N], const size_t(&bc)[N]) const
Linearization of the grid_key_dx with a specified shift.
Definition: grid_sm.hpp:372
void Initialize(const size_t sz)
Initialize the basic structure.
Definition: grid_sm.hpp:110
void setDimensions(const size_t(&dims)[N])
Reset the dimension of the grid.
Definition: grid_sm.hpp:229
size_t getDim()
Get the dimensionality of the key.
Definition: grid_sm.hpp:762
grid_sm(const size_t(&sz)[N])
Construct a grid of a specified size.
Definition: grid_sm.hpp:322