37 #include <lifev/multiscale/framework/MultiscaleCommunicatorsManager.hpp> 57 #ifdef HAVE_LIFEV_DEBUG 58 debugStream ( 8005 ) <<
"MultiscaleCommunicatorsManager::MultiscaleCommunicatorsManager() \n";
70 #ifdef HAVE_LIFEV_DEBUG 71 debugStream ( 8005 ) <<
"MultiscaleCommunicatorsManager::splitCommunicator() \n";
75 Int myPID = M_comm->MyPID();
76 Int numberOfProcesses = M_comm->NumProc();
77 MPI_Comm comm = ( std::dynamic_pointer_cast< Epetra_MpiComm > ( M_comm ) )->Comm();
81 MPI_Comm_group ( comm, &commGroup );
84 M_serialProcesses.resize ( M_serialModelsID.size(), std::vector< Int > ( 1, 0 ) );
85 for ( Int i (0) ; i <
static_cast <Int> ( M_serialProcesses.size() ) ; ++i )
87 M_serialProcesses[i][0] = i % numberOfProcesses;
91 Int serialMembers[1] = { myPID };
92 MPI_Group serialCommGroup;
93 MPI_Group_incl ( commGroup, 1, serialMembers, &serialCommGroup );
96 MPI_Comm_create ( comm, serialCommGroup, &serialComm );
98 for ( Int i (0) ; i <
static_cast <Int> ( M_serialProcesses.size() ) ; ++i )
99 if ( M_serialProcesses[i][0] == myPID )
101 M_commContainer[M_serialModelsID[i]].reset (
new Epetra_MpiComm ( serialComm ) );
105 std::vector<Real> localNumberOfProcesses ( M_parallelModelsID.size(), 0 );
106 parallelProcessesDistribution ( localNumberOfProcesses, numberOfProcesses );
109 parallelProcessesAssignment ( M_parallelProcesses, localNumberOfProcesses, numberOfProcesses );
112 for ( UInt i (0) ; i < M_parallelModelsID.size() ; ++i )
115 bool myComm (
false );
116 Int* parallelMembers =
new Int[M_parallelProcesses[i].size()];
119 for ( UInt j (0) ; j < M_parallelProcesses[i].size() ; ++j )
121 parallelMembers[j] = M_parallelProcesses[i][j];
122 if ( parallelMembers[j] == myPID )
129 MPI_Group parallelCommGroup;
130 MPI_Group_incl ( commGroup, M_parallelProcesses[i].size(), parallelMembers, ¶llelCommGroup );
133 MPI_Comm localParallelComm;
134 MPI_Comm_create ( comm, parallelCommGroup, &localParallelComm );
139 M_commContainer[M_parallelModelsID[i]].reset (
new Epetra_MpiComm ( localParallelComm ) );
142 delete[] parallelMembers;
149 if ( M_commContainer.find ( modelID ) != M_commContainer.end() )
162 if ( M_comm->MyPID() == 0 )
164 std::cout <<
"Serial models number = " << M_serialModelsID.size() << std::endl;
165 std::cout <<
"Serial models list = ";
166 for ( UInt i ( 0 ) ; i < M_serialModelsID.size() ; ++i )
168 std::cout << M_serialModelsID[i] <<
" ";
170 std::cout << std::endl;
171 std::cout <<
"Serial models processes = ";
172 for ( UInt i ( 0 ) ; i < M_serialModelsID.size() ; ++i )
174 std::cout << M_serialProcesses[i][0] <<
" ";
176 std::cout << std::endl << std::endl;
178 std::cout <<
"Parallel models number = " << M_parallelModelsID.size() << std::endl;
179 for ( UInt i ( 0 ) ; i < M_parallelModelsID.size() ; ++i )
181 std::cout <<
"Model " << M_parallelModelsID[i]
182 <<
", load " << M_parallelModelsLoad[i]
184 for ( UInt j (0) ; j < M_parallelProcesses[i].size() ; ++j )
186 std::cout << M_parallelProcesses[i][j] <<
" ";
188 std::cout << std::endl;
190 std::cout << std::endl << std::endl << std::endl;
202 M_serialModelsID.insert ( M_serialModelsID.end(), modelsID.begin(), modelsID.end() );
209 for ( ; modelsIDIterator != M_parallelModelsID.end() ; ++modelsIDIterator, ++modelsLoadIterator )
210 if ( load < *modelsLoadIterator )
215 M_parallelModelsID.insert ( modelsIDIterator, modelsID.begin(), modelsID.end() );
218 M_parallelModelsLoad.insert ( modelsLoadIterator, loadVector.begin(), loadVector.end() );
229 #ifdef HAVE_LIFEV_DEBUG 230 debugStream ( 8005 ) <<
"MultiscaleCommunicatorsManager::parallelProcessesDistribution() \n";
234 for ( UInt i (0) ; i < M_parallelModelsID.size() ; ++i )
236 localNumberOfProcesses[i] = numberOfProcesses * ( M_parallelModelsLoad[i] / 100 );
248 Real availableResource ( 0 );
249 bool optimize (
false );
252 std::vector<
bool> unoptimized ( M_parallelModelsID.size(),
true );
255 for ( UInt i (0) ; i < M_parallelModelsID.size() ; ++i )
257 if ( localNumberOfProcesses[i] < 1 )
259 availableResource -= 1 - localNumberOfProcesses[i];
260 localNumberOfProcesses[i] = 1;
262 unoptimized[i] =
false;
264 optimize |= unoptimized[i];
277 Int totalResources (0);
278 Real optimizationResources (0);
279 Real resourcesToBelow (0);
280 Real resourcesToAbove (0);
281 std::vector<Real> delta ( M_parallelModelsID.size(), 0 );
292 for ( UInt i (0) ; i < M_parallelModelsID.size() ; ++i )
293 if ( unoptimized[i] )
295 if ( std::floor ( localNumberOfProcesses[i] / multiscaleCoresPerNode ) > 0 )
297 resourcesToBelow = std::fmod ( localNumberOfProcesses[i], multiscaleCoresPerNode );
298 resourcesToAbove = resourcesToBelow - multiscaleCoresPerNode;
302 resourcesToBelow = std::fmod ( localNumberOfProcesses[i], 1 );
303 resourcesToAbove = resourcesToBelow - 1;
311 if ( std::fabs ( resourcesToBelow ) >= std::fabs ( resourcesToAbove ) )
313 delta[i] += resourcesToAbove;
317 delta[i] += resourcesToBelow;
319 optimizationResources += delta[i];
325 totalResources =
roundToInteger ( availableResource + optimizationResources
);
326 if ( totalResources >= 0 )
331 for ( UInt i (0) ; i < M_parallelModelsID.size() ; ++i )
332 if ( unoptimized[i] )
334 localNumberOfProcesses[i] -= delta[i];
336 if ( totalResources > 0 )
338 Int availableSlot = multiscaleCoresPerNode - std::fmod ( localNumberOfProcesses[i], multiscaleCoresPerNode );
339 for ( ; ( availableSlot > 0 && totalResources > 0 ) ; ++localNumberOfProcesses[i], --totalResources )
345 unoptimized[i] =
false;
354 for ( UInt i (0) ; i < M_parallelModelsID.size() ; ++i )
355 if ( unoptimized[i] && ( delta[i] < optimizationResources ) )
358 optimizationResources = delta[ID];
361 if ( optimizationResources >= 0 )
363 availableResource += optimizationResources;
364 localNumberOfProcesses[ID] -= optimizationResources;
368 if ( std::floor ( localNumberOfProcesses[ID] / multiscaleCoresPerNode ) > 0 )
371 localNumberOfProcesses[ID] -= multiscaleCoresPerNode + optimizationResources;
375 availableResource += 1 + optimizationResources;
376 localNumberOfProcesses[ID] -= 1 + optimizationResources;
379 unoptimized[ID] =
false;
383 optimizationResources = 0;
384 delta.assign ( M_parallelModelsID.size(), 0 );
388 for ( UInt i (0) ; i < M_parallelModelsID.size() ; ++i )
390 optimize |= unoptimized[i];
406 #ifdef HAVE_LIFEV_DEBUG 407 debugStream ( 8005 ) <<
"MultiscaleCommunicatorsManager::parallelProcessesAssignment() \n";
411 parallelProcesses.resize ( M_parallelModelsID.size() );
412 for ( UInt i (0) ; i < parallelProcesses.size() ; ++i )
414 parallelProcesses[i] = std::vector< Int > ( localNumberOfProcesses[i], 0 );
419 for (
Int i ( parallelProcesses.size() - 1 ) ; i > -1; --i )
421 for ( UInt j (0) ; j < localNumberOfProcesses[i] ; ++j, ++processID )
423 parallelProcesses[i][j] = processID % numberOfProcesses;
void parallelProcessesAssignment(std::vector< std::vector< Int > > ¶llelProcesses, const std::vector< Real > &localNumberOfProcesses, const Int &numberOfProcesses)
modelsID_Type M_parallelModelsID
modelsCommunicatorContainer_Type M_commContainer
int32_type Int
Generic integer data.
void updateInverseJacobian(const UInt &iQuadPt)
modelsLoad_Type::iterator modelsLoadIterator_Type
modelsProcessesList_Type M_serialProcesses
modelsLoad_Type M_parallelModelsLoad
void showMe()
Display some information about the communicators.
UInt multiscaleCoresPerNode
void addGroup(const Real &load, const modelsID_Type &modelsID)
Add a group of models.
modelsProcessesList_Type M_parallelProcesses
multiscaleCommPtr_Type M_comm
void parallelProcessesDistribution(std::vector< Real > &localNumberOfProcesses, const Int &numberOfProcesses)
std::vector< Real > modelsLoad_Type
Int roundToInteger(const Real &value) const
Round a real number to the closest integer.
double Real
Generic real data.
modelsID_Type M_serialModelsID
bool myModel(const UInt &modelID) const
Determine if the model is owned by the process.
modelsID_Type::iterator modelsIDIterator_Type
void splitCommunicator()
Split the communicator among the models.
MultiscaleCommunicatorsManager()
Constructor.
MultiscaleCommunicatorsManager - The Multiscale Communicators Manager.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
std::vector< UInt > modelsID_Type