PlasCom2  1.0
XPACC Multi-physics simluation application
PCPPCommUtil.C
Go to the documentation of this file.
1 #include "PCPPTypes.H"
2 #include "PCPPCommUtil.H"
3 #include "PCPPIntervalUtils.H"
4 #include "PCPPIO.H"
5 
6 namespace pcpp {
7  namespace comm {
8 
9  void ReduceTimers(double *processTimes,unsigned int nTimes,
10  std::vector<std::vector<double> > &parallelTimes,
11  pcpp::CommunicatorType &inCommunicator)
12  {
13 
14  int numProcs = 1;
15  MPI_Comm inComm(inCommunicator.GetCommunicator());
16  MPI_Comm_size(inComm,&numProcs);
17 
18  parallelTimes.resize(3);
19  parallelTimes[0].resize(nTimes);
20  parallelTimes[1].resize(nTimes);
21  parallelTimes[2].resize(nTimes);
22 
23  MPI_Reduce(processTimes,&(parallelTimes[0][0]),nTimes,MPI_DOUBLE,MPI_MIN,0,inComm);
24  MPI_Reduce(processTimes,&(parallelTimes[1][0]),nTimes,MPI_DOUBLE,MPI_MAX,0,inComm);
25  MPI_Reduce(processTimes,&(parallelTimes[2][0]),nTimes,MPI_DOUBLE,MPI_SUM,0,inComm);
26 
27  for(unsigned int iTime = 0;iTime < nTimes;iTime++){
28  parallelTimes[2][iTime] /= numProcs;
29  }
30 
31  }
32 
49  pcpp::ParallelTopologyInfoType &topologyInfo,
50  pcpp::CommunicatorType &topoCommunicator,
51  std::ostream &messageStream)
52  {
53  int &numDimensions(topologyInfo.numDimensions);
54 
55  if(numDimensions <= 0){
56  messageStream << "WARNING: No dimension configured for parallel topology, defaulting to 3.\n";
57  numDimensions = 3;
58  }
59 
60  std::ostringstream Ostr;
61  Ostr << "Dimension of parallel topology: " << numDimensions << std::endl;
62  messageStream << Ostr.str();
64 
65  std::vector<int> &dimDir(topologyInfo.dimDir);
66  std::vector<int> &cartDecomp(topologyInfo.cartDecomposition);
67  std::vector<int> &cartDirs(topologyInfo.cartDecompDirections);
68  std::vector<int> &isPeriodic(topologyInfo.isPeriodic);
69  std::vector<int> &topoCoords(topologyInfo.topoCoords);
70  std::vector<int> &cartNeighbors(topologyInfo.neighborRanks);
71 
72  dimDir.resize(numDimensions,0);
73  if(isPeriodic.size() != numDimensions)
74  isPeriodic.resize(numDimensions,0);
75  topoCoords.resize(numDimensions,0);
76 
77  int numNodes = parallelCommunicator.Size();
78  Ostr << "Total number of processes in topology: " << numNodes << std::endl;
79  messageStream << Ostr.str();
81 
82  if(!cartDecomp.empty()){
83 
84  dimDir = cartDecomp;
85  messageStream << "Using user-specified decomp map.\n";
86 
87  } else if (!cartDirs.empty()){
88 
89  messageStream << "Using user-specified directional guidance for decomp.\n";
90  int numCartDims = numDimensions;
91  std::vector<int>::iterator cartDirIt = cartDirs.begin();
92  std::vector<int>::iterator dimDirIt = dimDir.begin();
93 
94  while(dimDirIt != dimDir.end() && cartDirIt != cartDirs.end()){
95 
96  if(*cartDirIt++ == 0){
97 
98  *dimDirIt = 1;
99  numCartDims--;
100 
101  }
102  dimDirIt++;
103  }
104 
105  if(numCartDims < numDimensions){
106  if(numCartDims == 1){
107  dimDirIt = dimDir.begin();
108  while(dimDirIt != dimDir.end()){
109  if(*dimDirIt == 0)
110  *dimDirIt = parallelCommunicator.Size();
111  dimDirIt++;
112  }
113  } else if(numNodes > 1){
114 
115  // prime factorization of desired number of partitions
116  std::deque<size_t> primeFactors(pcpp::util::PrimeFactors(numNodes));
117  int numFac = primeFactors.size();
118 
119  // If the number of prime factors is larger than the
120  // number of possible dimenions, reduce by recursively
121  // combining (i.e. multiplying) the two smallest factors.
122  // Resulting deque is sorted smallest to largest
123  while(numFac > numCartDims){
124  primeFactors[1] *= primeFactors.front();
125  primeFactors.pop_front();
126  std::sort(primeFactors.begin(),primeFactors.end());
127  numFac--;
128  }
129  dimDirIt = dimDir.begin();
130  while(dimDirIt != dimDir.end() && !primeFactors.empty()){
131  if(*dimDirIt == 0){
132  if(!primeFactors.empty()){
133  *dimDirIt = primeFactors.front();
134  primeFactors.pop_front();
135  } else {
136  *dimDirIt = 1;
137  }
138  }
139  dimDirIt++;
140  }
141  }
142  }
143  }
144 
145  if(parallelCommunicator.InitializeCartesianTopology(numNodes,numDimensions,dimDir,
146  isPeriodic,true,topoCommunicator)){
147  messageStream << "Initialization of Cartesian process topology failed.\n";
148  return(1);
149  }
150  topoCoords = topoCommunicator.CartCoordinates();
151  topoCommunicator.CartNeighbors(cartNeighbors);
152  topologyInfo.rank = topoCommunicator.Rank();
153 
154  // Report to user
155  // Ostr << "Parallel topology: (";
156  // std::vector<int>::iterator dimIterator = dimDir.begin();
157  // while(dimIterator != dimDir.end()){
158  // Ostr << *dimIterator++;
159  // if(dimIterator != dimDir.end())
160  // Ostr << ", ";
161  // }
162  // Ostr << ")" << std::endl
163  // << "Cart Rank: (" << topoCommunicator.Rank() << "/"
164  // << numNodes << "), Cart Coords: (";
165  // pcpp::io::DumpContents(Ostr,topoCoords,",");
166  // Ostr << ")" << std::endl;
167  // Ostr << "Cart Neighbors: (";
168  // pcpp::io::DumpContents(Ostr,cartNeighbors,",");
169  // Ostr << ")" << std::endl;
170  // messageStream << Ostr.str();
171  // pcpp::io::RenewStream(Ostr);
172 
173  return(0);
174  };
175 
176  bool CheckResult(bool &localResult,pcpp::CommunicatorType &testComm)
177  {
178  testComm.SetExit(0);
179  if(!localResult){
180  testComm.SetExit(1);
181  }
182  if(testComm.Check()){
183  localResult = false;
184  return(false);
185  }
186  testComm.SetExit(0);
187  return(true);
188  };
189  };
190 };
std::vector< int > cartDecompDirections
Definition: PCPPCommUtil.H:22
std::vector< int > neighborRanks
Definition: PCPPCommUtil.H:26
int CartNeighbors(std::vector< int > &neighborRanks)
Definition: COMM.C:173
void RenewStream(std::ostringstream &outStream)
bool CheckResult(bool &localResult, pcpp::CommunicatorType &testComm)
Definition: PCPPCommUtil.C:176
std::vector< int > topoCoords
Definition: PCPPCommUtil.H:25
std::vector< int > cartDecomposition
Definition: PCPPCommUtil.H:23
int InitializeCartesianTopology(int numNodes, int numDims, std::vector< int > &dimDir, const std::vector< int > &isPeriodic, bool reOrder, CommunicatorObject &cartComm)
Definition: COMM.C:207
std::deque< size_t > PrimeFactors(size_t inNumber)
void ReduceTimers(double *processTimes, unsigned int nTimes, std::vector< std::vector< double > > &parallelTimes, pcpp::CommunicatorType &inCommunicator)
Definition: PCPPCommUtil.C:9
std::vector< int > isPeriodic
Definition: PCPPCommUtil.H:24
MPI_Comm GetCommunicator() const
Definition: COMM.H:85
int Check(comm::Ops op=comm::MAXOP)
Definition: COMM.C:355
Main encapsulation of MPI.
Definition: COMM.H:62
int SetupCartesianTopology(pcpp::CommunicatorType &parallelCommunicator, pcpp::ParallelTopologyInfoType &topologyInfo, pcpp::CommunicatorType &topoCommunicator, std::ostream &messageStream)
Sets up a communicator with Cartesian topology.
Definition: PCPPCommUtil.C:48
int SetExit(int errin)
Definition: COMM.H:109
std::vector< int > & CartCoordinates()
Definition: COMM.H:117