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 : }