C++ mpi module for stochmagnet_main Package
MPI_CartEnvironment.h
1 #ifndef MPI_CartEnvironment_H
2 #define MPI_CartEnvironment_H
3 
4 //inherited class object
5 #include "MPI_DirectionalGridEnvironment.h"
6 
29 template<tUCInt N,tUCInt D=1>
31 
32  //attributes
33 private :
34 
37 
38 
39 protected:
40  // CONSTRUCTORS
41 
45  this->getWorld()=MPI_COMM_NULL;
46  }
47 
60  MPI_CartEnvironment(int& argc,char * argv[],const tBoolean& isOpenMPEnabled) : SuperClass(argc,argv,isOpenMPEnabled) {
61 
62  }
63 
64 
65 
66  // DESTRUCTORS
69  virtual ~MPI_CartEnvironment(void) {
70 
71 
72  }
73 
74 public:
75 
76 
77 
78  //New methods
79  //===========
80 
89  inline static CORE_UniquePointer<SelfClass> New(const std::array<tMPICoreId,N>& nCoresPerDirection,
90  const std::array<tBoolean,N>& isPeriodicPerDirection,
91  int& argc,char * argv[],const tBoolean& isOpenMPEnabled) {
92 
93  CORE_UniquePointer<SelfClass> p(new SelfClass(argc,argv,isOpenMPEnabled),
95 
96  //std::cout<<" world:"<<parent.getWorld()<<" N:"<<((int)N)<<" nCoresPerDirection:"<<core_arrays::toString(nCoresPerDirection)<<" Periodicity:"<<core_arrays::toString(isPeriodicPerDirection)<<"\n";
97 
98  MPI_Cart_create(MPI_COMM_WORLD,
99  (int) N,nCoresPerDirection.data(),isPeriodicPerDirection.data(),
100  true,
101  &p->getWorld());
102 
103  if (p->getWorld()==MPI_COMM_NULL) {
104  //process can not be added in the grid environement
105  p.reset();
106  return p;
107  }
108  p->initialize();
109  return p;
110 
111  };
117  inline static CORE_UniquePointer<SelfClass> New(const MPI_Environment& parent,
118  const std::array<tMPICoreId,N>& nCoresPerDirection) {
119  //no periodicity
120  std::array<tMPIBoolean,N> periodicity;
121  for(auto& Vi:periodicity) Vi=0;
122 
123  return New(parent,nCoresPerDirection,periodicity,true);
124 
125  };
133  inline static CORE_UniquePointer<SelfClass> New(const MPI_Environment& parent,
134  const std::array<tMPICoreId,N>& nCoresPerDirection,
135  const std::array<tBoolean,N>& isPeriodicPerDirection,
136  const int& canCoreIdBeChanged) {
137  std::array<int,N> periods;
138  int k=0;
139  for(auto& Pk:periods) {
140  Pk=isPeriodicPerDirection[k];
141  k++;
142  }
143  return New(parent,nCoresPerDirection,periods,canCoreIdBeChanged);
144  }
152  inline static CORE_UniquePointer<MPI_CartEnvironment<N>> New(const MPI_Environment& parent,
153  const std::array<tMPICoreId,N>& nCoresPerDirection,
154  const std::array<tMPIBoolean,N>& isPeriodicPerDirection,
155  const int& canCoreIdBeChanged) {
156  CORE_UniquePointer<SelfClass> p(new SelfClass(),
158 
159  //std::cout<<" world:"<<parent.getWorld()<<" N:"<<((int)N)<<" nCoresPerDirection:"<<core_arrays::toString(nCoresPerDirection)<<" Periodicity:"<<core_arrays::toString(isPeriodicPerDirection)<<"\n";
160 
161  MPI_Cart_create(parent.getWorld(),
162  (int) N,nCoresPerDirection.data(),isPeriodicPerDirection.data(),
163  canCoreIdBeChanged,
164  &p->getWorld());
165 
166  if (p->getWorld()==MPI_COMM_NULL) {
167  //process can not be added in the grid environement
168  p.reset();
169  return p;
170  }
171  p->initialize();
172  return p;
173  };
174 
180  inline static CORE_UniquePointer<SelfClass> New(const MPI_CartEnvironment<N+1,D>& parent,
181  const tUCInt& dir) {
182  CORE_UniquePointer<SelfClass> p(new SelfClass(),
184  //create the selected directions to keep
185  std::array<int,N+1> dims;
186  for(auto& Dk:dims) Dk=1;
187  dims[dir]=0;
188  MPI_Cart_sub(parent.getWorld(),&dims[0],&p->getWorld());
189  if (p->getWorld()==MPI_COMM_NULL) {
190  //process can not be added in the grid environement
191  p.reset();
192  return p;
193  }
194  p->initialize();
195  return p;
196  }
197 
198 
199  //memory management
200  //=================
203  virtual tMemSize getMemorySize() const {
204  return sizeof(*this)+this->getContentsMemorySize();
205  }
206 
207 
208 
209 
210 protected :
217  virtual void initialize() {
218 
220 
221 
222  //build the neighbor cores list
224  }
225 
226 
232  inline void buildNeighborCoresList(const std::array<tMPICoreId,N>& nGrids,const std::array<tMPICoreId,N>& indices,
233  const std::array<tBoolean,N>& periodicity ) {
234 
235 
236 
237  //initialize the neighbor grids per direction
238 
239  std::map<tUCInt,tMPICoreId> neighbors;
240 
241  //ietaror on periodc
242  const tBoolean *iPeriod=null;
243 
244  //index of direction
245  tUCInt index=0;
246 
247  //neighbor core id
248  tMPICoreId nextCoreId;
249 
250  std::array<tCInt,N> dir;
251  tCInt *iDir=null;//itertor on dir
252 
253  //neighbor is inside bounds
254  tBoolean isInsideBounds;
255 
256  //neighbor indices
257  std::array<tMPICoreId,N> neighborIndices;
258  tMPICoreId *iNeighborIndices;//iterator on neighbor indices
259  const tMPICoreId *iNk=nGrids.data();//iterator on grid size
260  while (index<=this->GetMaximumDirectionalNeighborsNumber()) {
261 
262  //get the direction of the neighbor grid at index
263  this->GetDirection(index,dir);
264 
265  //set the indices of the neighbor from current indices of this core
266  iDir=dir.data();
267 
268  //periodicity
269  iPeriod=periodicity.data();
270 
271  //size of grids
272  iNk=nGrids.data();
273 
274  //neighbor in domain indicator
275  isInsideBounds=true;
276 
277  iNeighborIndices=neighborIndices.data();
278  for(const auto& i:indices) {
279  //neighbor indices initialitze to indices of this
280  (*iNeighborIndices)=i;
281  //translation to direction
282  (*iNeighborIndices)+=(*iDir);
283 
284  if (*iPeriod) {//periodic case
285  (*iNeighborIndices)+=(*iNk);
286  (*iNeighborIndices)%=(*iNk);
287  }
288 
289  isInsideBounds=isInsideBounds && ((*iNeighborIndices)>=0) && ((*iNeighborIndices)<(*iNk));
290 
291  //iterator at next coordinate
292  iDir++;
293  iPeriod++;
294  iNk++;
295  iNeighborIndices++;
296  }
297  //get the core Id of the neighbor
298  nextCoreId=NULL_CORE;
299  if (isInsideBounds) {
300 
301  //get the index of the neighbor core at dierction neighborIndices
302  MPI_Cart_rank(this->getWorld(),neighborIndices.data(),&nextCoreId);
303  //std::cout<<"MPI_Cart_rank(indices="<<core_functions::toString(indices)<<" dir="<<core_functions::toString<int,tCInt>(dir)<<" neighborIndices="<<core_functions::toString(neighborIndices)<<",size="<<core_functions::toString(nGrids)<<" ) nextCoreId="<<nextCoreId<<"\n";
304  }
305 
306  //register the neighbor core id
307  if (nextCoreId!=NULL_CORE) neighbors[index]=nextCoreId;
308 
309 
310 
311  //index of next neighbor grid
312  index++;
313 
314  }//end loop on directional
315 
316  //erase neighbor for null displacement
317  memset(dir.data(),0,sizeof(tCInt)*N);
318  std::map<tUCInt,tMPICoreId>::iterator iNeighbors=neighbors.find(this->GetDirectionIndex(dir));
319  if (iNeighbors!=neighbors.end()) neighbors.erase(iNeighbors);
320 
321 
322  //set the dierctional neighbors
323  this->setDirectionalNeighbors(neighbors);
324 
325  //set to null core for the null directiopn
326 
327  //std::cout<<"coreId:"<<this->getCoreId()<<" neighbors:"<<core_functions::toString<tInt,tInt>(neighbors)<<"\n";
328 
329 
330  }
331 
332 
333 
334 
335  //accessor methods
336  //================
337 
338 
339 
340 
341 
342 
343 
344 
345 
346 };
347 
348 
349 #endif
class Free introduced for deleting a smart pointer
Definition: CORE_Object.h:113
This class is a cart Environment of templated dimension N.
Definition: MPI_CartEnvironment.h:30
virtual void initialize()
initialize the environment
Definition: MPI_CartEnvironment.h:217
void buildNeighborCoresList(const std::array< tMPICoreId, N > &nGrids, const std::array< tMPICoreId, N > &indices, const std::array< tBoolean, N > &periodicity)
build the neighbors with depth D
Definition: MPI_CartEnvironment.h:232
virtual tMemSize getMemorySize() const
return the memory size of the class
Definition: MPI_CartEnvironment.h:203
static CORE_UniquePointer< SelfClass > New(const MPI_Environment &parent, const std::array< tMPICoreId, N > &nCoresPerDirection)
create a new cart environment
Definition: MPI_CartEnvironment.h:117
virtual ~MPI_CartEnvironment(void)
destroy
Definition: MPI_CartEnvironment.h:69
static CORE_UniquePointer< SelfClass > New(const std::array< tMPICoreId, N > &nCoresPerDirection, const std::array< tBoolean, N > &isPeriodicPerDirection, int &argc, char *argv[], const tBoolean &isOpenMPEnabled)
create a new cart environment
Definition: MPI_CartEnvironment.h:89
static CORE_UniquePointer< MPI_CartEnvironment< N > > New(const MPI_Environment &parent, const std::array< tMPICoreId, N > &nCoresPerDirection, const std::array< tMPIBoolean, N > &isPeriodicPerDirection, const int &canCoreIdBeChanged)
create a new cart grid environment
Definition: MPI_CartEnvironment.h:152
static CORE_UniquePointer< SelfClass > New(const MPI_Environment &parent, const std::array< tMPICoreId, N > &nCoresPerDirection, const std::array< tBoolean, N > &isPeriodicPerDirection, const int &canCoreIdBeChanged)
create a new cart grid environment
Definition: MPI_CartEnvironment.h:133
MPI_CartEnvironment(int &argc, char *argv[], const tBoolean &isOpenMPEnabled)
create a root environment
Definition: MPI_CartEnvironment.h:60
static CORE_UniquePointer< SelfClass > New(const MPI_CartEnvironment< N+1, D > &parent, const tUCInt &dir)
create a hyper plan of the grids perpendicular to dir
Definition: MPI_CartEnvironment.h:180
MPI_CartEnvironment()
create a root environment
Definition: MPI_CartEnvironment.h:44
This class is a grid Environment of templated dimension N=1,2,3.
Definition: MPI_DirectionalGridEnvironment.h:30
virtual tMemSize getContentsMemorySize() const override
return the memory size of the included associations
Definition: MPI_DirectionalGridEnvironment.h:105
static tUCInt GetMaximumDirectionalNeighborsNumber()
get the maximum direction number : (2*D+1)^N when D is the neighbor Depth (D=0,1,2)
Definition: MPI_DirectionalGridEnvironment.h:191
static tUCInt GetDirectionIndex(const std::array< tCInt, N > &dir)
get the direction index from dir index=dir[0]+1+3*(dir[1]+1+3*(dir[2]+1)) in {0,27}
Definition: MPI_DirectionalGridEnvironment.h:287
virtual void initialize()
initialize the environment
Definition: MPI_DirectionalGridEnvironment.h:303
void setDirectionalNeighbors(const std::map< tUCInt, tMPICoreId > &neighbors)
set neighbors grids per face
Definition: MPI_DirectionalGridEnvironment.h:267
static void GetDirection(const tUCInt &index, std::array< tCInt, N > &dir)
get the direction dir from index: index=dir[0]+1+D*(dir[1]+1+3*(dir[2]+1)) in {0,27}
Definition: MPI_DirectionalGridEnvironment.h:279
This class is a Environment class to define MPI world.
Definition: MPI_Environment.h:36
const tMPIComm & getWorld() const
get the world of the environment for reading
Definition: MPI_Environment.h:165
const std::array< tMPICoreId, N > & getGridSize() const
get the grids number
Definition: MPI_GridEnvironment.h:200
const std::array< tBoolean, N > & getGridPeriodicity() const
return the periodicity of the grid
Definition: MPI_GridEnvironment.h:356
const std::array< tMPICoreId, N > & getIndices() const
get the indices of the current core within the grid environment
Definition: MPI_GridEnvironment.h:219