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 32 : 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 4 : 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
|