| 1 | 
chuckv | 
1538 | 
 | 
| 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 */ |