1 |
|
2 |
#ifndef PARALLEL_PARALLEL_HPP |
3 |
#define PARALLEL_PARALLEL_HPP |
4 |
#include <vector> |
5 |
#include <string> |
6 |
|
7 |
//#include <protomol/type/Real.h> |
8 |
//#include <protomol/parallel/ParallelType.h> |
9 |
|
10 |
namespace OpenMD { |
11 |
class ScalarStructure; |
12 |
class Vector3DBlock; |
13 |
class GenericTopology; |
14 |
|
15 |
//____ Parallel |
16 |
class Parallel { |
17 |
|
18 |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
19 |
// Constructors, destructors, assignment |
20 |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
21 |
private: |
22 |
Parallel(); |
23 |
~Parallel(); |
24 |
Parallel(const Parallel &) {} |
25 |
|
26 |
Parallel &operator=(const Parallel &) {return *this;} |
27 |
|
28 |
public: |
29 |
static void init(int &argc, char ** &argv); ///< MPI_Init and sets id and |
30 |
///< number of process. |
31 |
static void finalize(); ///< MPI_Finialize. |
32 |
|
33 |
static bool initialized() {return myInitialized;} |
34 |
|
35 |
static bool finalized() {return myFinalized;} |
36 |
|
37 |
static bool ok() {return myInitialized && !myFinalized;} |
38 |
|
39 |
static int getId() {return myId;} |
40 |
|
41 |
static int getMasterId() {return myMasterId;} |
42 |
|
43 |
static int getNum() {return myNum;} |
44 |
|
45 |
static int getAvailableId() {return myAvailableId;} |
46 |
|
47 |
static int getAvailableNum() {return myAvailableNum;} |
48 |
|
49 |
static bool isParallel() {return myIsParallel;} |
50 |
|
51 |
static bool iAmMaster() {return myIAmMaster;} |
52 |
|
53 |
static bool iAmSlave() {return myIAmSlave;} |
54 |
|
55 |
|
56 |
public: |
57 |
|
58 |
/** |
59 |
* Broadcast a Vector3DBlock from the master to the rest. |
60 |
* Handles also the case if the receiving nodes have an emty |
61 |
* (other size) Vector3DBlock. |
62 |
*/ |
63 |
static void bcast(Vector3DBlock *coords); |
64 |
static void bcast(int &n); |
65 |
|
66 |
/** |
67 |
* Does the preprocessing, clearing the energies and forces for |
68 |
* all nodes except the master. |
69 |
*/ |
70 |
static void distribute(ScalarStructure *energy, Vector3DBlock *coords); |
71 |
|
72 |
/** |
73 |
* Does a reduction and a broadcast, such that all |
74 |
* nodes have the correct summed energies and forces locally. |
75 |
*/ |
76 |
static void reduce(ScalarStructure *energy, Vector3DBlock *coords); |
77 |
|
78 |
/// Takes care of sending a Vector3DBlock to a single node. |
79 |
static void send(Vector3DBlock *vect, int address); |
80 |
|
81 |
/// Recieves a Vector3DBlock from a node. |
82 |
static void recv(Vector3DBlock *vect, int address); |
83 |
|
84 |
/// Sends a Vector3DBlock, to one node, and overwrites it with one recieved |
85 |
/// from another node |
86 |
static void sendrecv_replace(Vector3DBlock *Vect, int sendaddr, |
87 |
int recvaddr); |
88 |
|
89 |
/// Sends a Real (or array of Reals) from one node to another |
90 |
static void send(RealType *data, int num, int address); |
91 |
|
92 |
/// Recieves a Real (or array of Reals) from another node |
93 |
static void recv(RealType *data, int num, int address); |
94 |
|
95 |
/// Sends one real and receives another real from one or two nodes (sends |
96 |
/// to one, recieves to the other) |
97 |
static void sendrecv(Real *senddata, int sendnum, int sendaddr, |
98 |
Real *recvdata, int recvnum, |
99 |
int recvaddr); |
100 |
|
101 |
/// Sends a Real (or array of Reals) to one node and overwrites it with |
102 |
/// data from another node. |
103 |
static void sendrecv_replace(Real *data, int num, int sendaddr, |
104 |
int recvaddr); |
105 |
|
106 |
/// Gathers a vector of Reals from the compute nodes and stores it in an |
107 |
/// array. |
108 |
static void gather(Real *data, int num, Real *data_array, int address); |
109 |
|
110 |
/// Gathers a vector of Reals from the compute nodes and stores it in an |
111 |
/// array, distributed to all the nodes. |
112 |
static void allgather(Real *data, int num, Real *data_array); |
113 |
|
114 |
// Partitioning |
115 |
public: |
116 |
/// Returns the number of packages over all forces. |
117 |
static unsigned int getNumberOfPackages(unsigned int n); |
118 |
|
119 |
public: |
120 |
/// true if the actual work package should computed, false skip it |
121 |
static bool next(); |
122 |
|
123 |
static void resetNext() {myNext = 0; myNextRange[0] = 0; myNextRange[1] = 0; |
124 |
myWorkState = getWorkState();} |
125 |
|
126 |
static void resetNext(const std::vector<int> &blocks); |
127 |
|
128 |
public: |
129 |
/// Disables MPI on the current node |
130 |
static void isolateNode(); |
131 |
|
132 |
/// Enables MPI on the current node |
133 |
static void integrateNode(); |
134 |
|
135 |
private: |
136 |
static void kill(); |
137 |
static Parallel &instance(); |
138 |
static bool ok(const std::string &err); |
139 |
static WorkState getWorkState(); |
140 |
static void nextMaster(); |
141 |
|
142 |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
143 |
// My data members |
144 |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
145 |
public: |
146 |
static const bool isMPI; |
147 |
private: |
148 |
static bool myInitialized; ///< If Parallel is initialized |
149 |
static bool myFinalized; // /<If Parallel is finalized |
150 |
static int myId; ///< Actual id of the node, [0,1,...,N-1] |
151 |
static int myMasterId; ///< Id of the master |
152 |
static int myNum; ///< Number of nodes, N |
153 |
static int myAvailableId; ///< Actual master-slave id, -1 for the master |
154 |
static int myAvailableNum; ///< Available number of nodes for computation |
155 |
static bool myIsParallel; ///< If environment has more that 1 node |
156 |
static bool myIAmMaster; ///< If this node is master |
157 |
static bool myIAmSlave; ///< If this node is slave/worker |
158 |
static ParallelType myMode; ///< Parallelization scheme |
159 |
static WorkState myWorkState; ///< Actual work state |
160 |
|
161 |
static int myPipeSize; ///< Number of add. work packages to push to |
162 |
///< slaves |
163 |
static bool myUseBarrier; ///< Flag to signal usage of MPI_Barrier |
164 |
static int myMaxPackages; ///< Number of max. packages per node per force |
165 |
|
166 |
static int *myBuffer; ///< Bsend buffer |
167 |
static int myNext; ///< Counter of next() calls |
168 |
static int myNextRange[2]; ///< Actual work package to work on [from,to] |
169 |
static std::vector<int> myDone; ///< Master, keeps track of slave |
170 |
///< have got already their work |
171 |
static std::vector<int> myBlockList; ///< List of of the force |
172 |
///< partitioning |
173 |
|
174 |
static int myRecv; ///< Number of outstanding receives |
175 |
static int myI; ///< Index of the actual work package (only |
176 |
///< master) |
177 |
static int myP; ///< Node number |
178 |
|
179 |
static Parallel *obj; ///< Instance |
180 |
|
181 |
static bool myIsolated; ///< Saves isolation state |
182 |
static int myOldId; ///< Saves processor id when switching MPI off |
183 |
static int myOldNum; ///< Saves number of processors when switching |
184 |
///< MPI off |
185 |
static ParallelType myOldMode; ///< Saves parallelization scheme when |
186 |
///< switching MPI off |
187 |
}; |
188 |
//____ INLINES |
189 |
} |
190 |
#endif /* PARAMETER_H */ |