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 : #ifndef _TARCH_UTILS_MULTIMDSERVICE_H_ 6 : #define _TARCH_UTILS_MULTIMDSERVICE_H_ 7 : 8 : #include "tarch/TarchDefinitions.h" 9 : #include "tarch/la/Vector.h" 10 : #include <cstdlib> 11 : #include <numeric> 12 : #include <vector> 13 : #if (TARCH_PARALLEL == TARCH_YES) 14 : #include <mpi.h> 15 : #endif 16 : 17 : namespace tarch { 18 : namespace utils { 19 : template <unsigned int dim> class MultiMDService; 20 : } 21 : } // namespace tarch 22 : 23 : /** maps a number of MD simulations onto the total number of available ranks. 24 : * For each MD simulation, a regular domain decomposition into n0 x n1 x ... x 25 : * nD processes is assumed. 26 : * We further assume that the total number of processes can be divided by the 27 : * number of processes required by each MD simulation. 28 : * @author Philipp Neumann 29 : */ 30 : template <unsigned int dim> class tarch::utils::MultiMDService { 31 : public: 32 : MultiMDService(const tarch::la::Vector<dim, unsigned int>& numberProcesses, const unsigned int& totalNumberMDSimulations 33 : #if (TARCH_PARALLEL == TARCH_YES) 34 : , 35 : MPI_Comm globalComm = MPI_COMM_WORLD 36 : #endif 37 : ); 38 : ~MultiMDService(); 39 : 40 : unsigned int getGlobalNumberOfLocalMDSimulation(unsigned int localMDSimulation) const; 41 : 42 : int getLocalNumberOfGlobalMDSimulation(unsigned int globalMDSimulation) const; 43 : 44 48 : unsigned int getLocalNumberOfMDSimulations() const { return _thisNumberMDSimulations; } 45 : 46 36 : unsigned int getAvgNumberOfMDSimulations() const { return _avgNumberMDSimulationsPerLocalComm; } 47 : 48 : tarch::la::Vector<dim, unsigned int> getNumberProcessesPerMDSimulation() const { return _numberProcessesPerMDSimulation; } 49 : 50 : #if (TARCH_PARALLEL == TARCH_YES) 51 12 : MPI_Comm getLocalCommunicator() const { return _localComm; } 52 : #endif 53 : unsigned int getLocalRank() const { return _localRank; } 54 : unsigned int getLocalSize() const { return _localSize; } 55 : 56 : #if (TARCH_PARALLEL == TARCH_YES) 57 136 : MPI_Comm getGlobalCommunicator() const { return _globalComm; } 58 : #endif 59 : unsigned int getGlobalRank() const { return _globalRank; } 60 : unsigned int getGlobalSize() const { return _globalSize; } 61 : 62 : // TODO: unused function 63 : void setTotalNumberMDSimulations(unsigned int n) { _totalNumberMDSimulations = n; } 64 1 : unsigned int getTotalNumberOfMDSimulations() { return _totalNumberMDSimulations; } 65 : 66 : void addMDSimulationBlock() { 67 : _totalNumberMDSimulations += _numberLocalComms; 68 : _avgNumberMDSimulationsPerLocalComm = _totalNumberMDSimulations / _numberLocalComms; 69 : if ((unsigned int)(_globalRank / _localSize + 1) == _numberLocalComms) { 70 : _thisNumberMDSimulations = _totalNumberMDSimulations - _avgNumberMDSimulationsPerLocalComm * (_numberLocalComms - 1); 71 : } else { 72 : _thisNumberMDSimulations = _avgNumberMDSimulationsPerLocalComm; 73 : } 74 : } 75 : 76 : void removeMDSimulationBlock() { 77 : _totalNumberMDSimulations -= _numberLocalComms; 78 : _avgNumberMDSimulationsPerLocalComm = _totalNumberMDSimulations / _numberLocalComms; 79 : if ((unsigned int)(_globalRank / _localSize + 1) == _numberLocalComms) { 80 : _thisNumberMDSimulations = _totalNumberMDSimulations - _avgNumberMDSimulationsPerLocalComm * (_numberLocalComms - 1); 81 : } else { 82 : _thisNumberMDSimulations = _avgNumberMDSimulationsPerLocalComm; 83 : } 84 : } 85 : 86 : int getRank() const { return this->_globalRank; } 87 : int getSize() const { return this->_globalSize; } 88 : 89 21 : unsigned int getNumberLocalComms() const { return _numberLocalComms; } 90 : 91 : private: 92 : #if (TARCH_PARALLEL == TARCH_YES) 93 : MPI_Comm _localComm; // communicator of "local" MD simulation 94 : MPI_Comm _globalComm; // normally MPI_COMM_WORLD, unless there are ranks outside all MD simulations (e.g. due to PinT) 95 : #endif 96 : // number of processes used for a single MD simulation. Currently, the total 97 : // number of MPI processes needs to 98 : // be a multiple of the number of processes per MD simulation (=product of the 99 : // vector components) 100 : const tarch::la::Vector<dim, unsigned int> _numberProcessesPerMDSimulation; 101 : // number of local communicators 102 : unsigned int _numberLocalComms; 103 : // total number of MD simulations 104 : unsigned int _totalNumberMDSimulations; 105 : // average number of MD simulations that is processed per local communicator. 106 : // If we have 4 processes per MD simulation and 12 processes available and 107 : // want to run 26 MD simulations, 108 : // then this value is given by 26/(12/4) = 26/3 = 8 109 : unsigned int _avgNumberMDSimulationsPerLocalComm; 110 : // number of MD simulations for this current local communicator. Except for 111 : // the "last communicator", this value 112 : // equals _avgNumberMDSimulationsPerLocalComm. The last comunicator group 113 : // fills up the missing MD simulations. 114 : // If we have 4 processes per MD simulation and 12 processes available and 115 : // want to run 26 MD simulations, 116 : // then we have 12/4=3 communicator groups, of which group 0 and 1 handle 117 : // 26/3=8 MD simulations. The last group 2 118 : // handles 26-2*8 = 10 MD simulations. 119 : unsigned int _thisNumberMDSimulations; 120 : 121 : int _globalSize; // global number of available MPI processes 122 : int _globalRank; // rank in global communicator getGlobalCommunicator() 123 : 124 : int _localSize; // size of communicator _localComm 125 : int _localRank; // local rank in communicator _localComm 126 : }; 127 : 128 : #include "tarch/utils/MultiMDService.cpph" 129 : #endif