Line data Source code
1 : // Copyright (C) 2015 Technische Universitaet Muenchen
2 : // This file is part of the Mamico project. For conditions of distribution
3 : // and use, please see the copyright notice in Mamico's main folder, or at
4 : // www5.in.tum.de/mamico
5 :
6 : template <unsigned int dim>
7 68 : tarch::utils::MultiMDService<dim>::MultiMDService(const tarch::la::Vector<dim, unsigned int>& numberProcessesPerMDSimulation,
8 : const unsigned int& totalNumberMDSimulations
9 : #if (TARCH_PARALLEL == TARCH_YES)
10 : ,
11 : MPI_Comm globalComm
12 : #endif
13 : )
14 : : // initialise all values, either immediately consistent for single and
15 : // parallel mode, or for single mode only (and overwrite the setting
16 : // afterwards in constructor body)
17 68 : _numberProcessesPerMDSimulation(numberProcessesPerMDSimulation), _numberLocalComms(1), _totalNumberMDSimulations(totalNumberMDSimulations),
18 68 : _avgNumberMDSimulationsPerLocalComm(totalNumberMDSimulations), _thisNumberMDSimulations(totalNumberMDSimulations), _globalSize(1), _globalRank(0),
19 68 : _localSize(1), _localRank(0) {
20 : #if (TARCH_PARALLEL == TARCH_YES)
21 :
22 68 : _globalComm = globalComm;
23 :
24 68 : MPI_Comm_size(getGlobalCommunicator(), &_globalSize);
25 68 : MPI_Comm_rank(getGlobalCommunicator(), &_globalRank);
26 :
27 : /* Resilience TODOs
28 : * Allow idle processes?
29 : * - allow any number of processes or only useful numbers?
30 : */
31 :
32 : // test process distribution
33 68 : _localSize = numberProcessesPerMDSimulation[0];
34 204 : for (unsigned int d = 1; d < dim; d++) {
35 136 : _localSize *= numberProcessesPerMDSimulation[d];
36 : }
37 68 : if (_globalSize % _localSize != 0) {
38 0 : std::cout << "_globalSize = " << _globalSize << std::endl;
39 0 : std::cout << "_localSize = " << _localSize << std::endl;
40 0 : std::cout << "ERROR MultiMDService::MultiMDService(): _globalSize mod "
41 : "_localSize!=0 !"
42 0 : << std::endl;
43 0 : std::cout << "The number of globally available MPI processes must be "
44 : "filled completely with local MD simulation processes!"
45 0 : << std::endl;
46 0 : exit(EXIT_FAILURE);
47 : }
48 :
49 : // compute number of local communicators
50 68 : _numberLocalComms = _globalSize / _localSize;
51 : // initialise local communicator by splitting the whole process domain into
52 : // _numberLocalComms communicators
53 68 : MPI_Comm_split(getGlobalCommunicator(), _globalRank / _localSize, _globalRank, &_localComm);
54 : // initialise local rank
55 68 : MPI_Comm_rank(_localComm, &_localRank);
56 : // compute avg number of MD simulations per local communicator
57 68 : _avgNumberMDSimulationsPerLocalComm = _totalNumberMDSimulations / _numberLocalComms;
58 : // compute the number of MD simulations on the current communicator. This is
59 : // always the same as _avgMDSimulations..., except for the last communicator
60 : // which is filled up with the rest
61 68 : if ((unsigned int)(_globalRank / _localSize + 1) == _numberLocalComms) {
62 38 : _thisNumberMDSimulations = _totalNumberMDSimulations - _avgNumberMDSimulationsPerLocalComm * (_numberLocalComms - 1);
63 : } else {
64 30 : _thisNumberMDSimulations = _avgNumberMDSimulationsPerLocalComm;
65 : }
66 :
67 : #endif
68 68 : }
69 :
70 : namespace tarch {
71 : namespace utils {
72 64 : template <unsigned int dim> MultiMDService<dim>::~MultiMDService() {}
73 : } // namespace utils
74 : } // namespace tarch
75 :
76 8 : template <unsigned int dim> unsigned int tarch::utils::MultiMDService<dim>::getGlobalNumberOfLocalMDSimulation(unsigned int localMDSimulation) const {
77 8 : return (_globalRank / _localSize) * _avgNumberMDSimulationsPerLocalComm + localMDSimulation;
78 : }
79 :
80 : template <unsigned int dim> int tarch::utils::MultiMDService<dim>::getLocalNumberOfGlobalMDSimulation(unsigned int globalMDSimulation) const {
81 : return globalMDSimulation - (_globalRank / _localSize) * _avgNumberMDSimulationsPerLocalComm;
82 : }
|