| 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 */ |