Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

ProxyMgr.h

Go to the documentation of this file.
00001 
00007 #ifndef PROXYMGR_H
00008 #define PROXYMGR_H
00009 
00010 
00011 #include "charm++.h"
00012 #include "envelope.h"
00013 
00014 #include "main.h"
00015 #include "NamdTypes.h"
00016 #include "PatchTypes.h"
00017 #include "UniqueSet.h"
00018 #include "UniqueSetIter.h"
00019 #include "ProcessorPrivate.h"
00020 #include "ProxyMgr.decl.h"
00021 
00022 extern int proxySendSpanning, proxyRecvSpanning;
00023 extern int proxySpanDim;
00024 extern int inNodeProxySpanDim;
00025 
00026 #if CMK_PERSISTENT_COMM
00027 #define USE_PERSISTENT_TREE                  0
00028 #endif
00029 
00030 class ProxyGBISP1ResultMsg: public CMessage_ProxyGBISP1ResultMsg {
00031   public:
00032     int destPe;
00033     int origPe;
00034     PatchID patch;
00035     GBReal *psiSum;
00036     int psiSumLen;// = numAtoms
00037 };
00038 class ProxyGBISP2DataMsg: public CMessage_ProxyGBISP2DataMsg {
00039 public:
00040     int origPe;
00041     int destPe;
00042     PatchID patch;
00043     Real *bornRad;//numAtoms
00044     int bornRadLen;
00045   };
00046 class ProxyGBISP2ResultMsg: public CMessage_ProxyGBISP2ResultMsg {
00047 public:
00048     int destPe;
00049     int origPe;
00050     PatchID patch;
00051     GBReal *dEdaSum;
00052     int dEdaSumLen;//numAtoms
00053   };
00054 class ProxyGBISP3DataMsg: public CMessage_ProxyGBISP3DataMsg {
00055 public:
00056     int origPe;
00057     int destPe;
00058     PatchID patch;
00059     Real *dHdrPrefix;//numAtoms
00060     int dHdrPrefixLen;
00061   };
00062 
00063 class RegisterProxyMsg : public CMessage_RegisterProxyMsg {
00064 public:
00065   NodeID node;
00066   PatchID patch;
00067 };
00068 
00069 class UnregisterProxyMsg : public CMessage_UnregisterProxyMsg {
00070 public:
00071   NodeID node;
00072   PatchID patch;
00073 };
00074 
00075 //1. This class represents for both msg types: one that
00076 //is originally known as ProxyAllMsg which is sent
00077 //at the step where atoms migrate; and the other is
00078 //sent during the steps between two migrations.
00079 //2. In the case of memory optimized version, the scenario
00080 //becomes tricky as load balancer will move compute objects
00081 //around so that new ProxyPatches will be created where
00082 //the CompAtomExt list information is not available. If
00083 //the step immediately after the load balancing is a normal
00084 //step, then the CompAtomExt list info has to be resent by
00085 //the HomePatch. Because of the current Proxy msg communication
00086 //scheme where msg is sent to ProxyMgr first, and then retransmitted
00087 //to ProxyPatches, there's overhead when we want to resend CompAtomExt
00088 //list as not all the ProxyPatches that are managed by ProxyMgr are
00089 //newly created ProxyPatches. 
00090 //--Chao Mei
00091 class ProxyDataMsg : public CMessage_ProxyDataMsg {
00092 public:
00093   PatchID patch;
00094   Flags flags;
00095 
00096   int plLen;
00097 
00098   CompAtom *positionList;
00099   int avgPlLen;
00100   CompAtom *avgPositionList;
00101   // BEGIN LA
00102   int vlLen;
00103   CompAtom *velocityList;
00104   // END LA
00105 
00106   Real *intRadList;// gbis atom intrinsic radii
00107 
00108   int *lcpoTypeList;// LCPO atom type
00109 
00110   //1. The following field will be only
00111   //useful for memory optimized version.
00112   //2. In normal case, adding this field only
00113   //increases the msg length by 4 bytes which
00114   //can be ignored considering the current fast
00115   //communication network
00116   //--Chao Mei
00117   int plExtLen;
00118   CompAtomExt *positionExtList;
00119   CudaAtom *cudaAtomList;
00120 
00121 #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR) && (CMK_SMP) && defined(NAMDSRC_IMMQD_HACK)
00122   //In smp layer, the couter for msg creation and process of communication
00123   //thread is not included in the quiescence detection process. In addition,
00124   //the immediate messages from other nodes are executed on the communication
00125   //thread. If inside the process of immediate messages, some normal Charm++
00126   //messages sent out which will be processed on worker threads. Then QD will
00127   //be a problem that the process of the normal messages sent from communication
00128   //thread is recorded, but the creation of such messages (although recorded
00129   //in the comm thread) is virtually not recorded, i.e., not visible the 
00130   //QD process. So we need to artificially increase the QD counter to 
00131   //compensate for aforementioned msg creation loss.
00132   //The idea is to use the following variable to indicate the normal message
00133   //is sent from the communication thread inside a processing of immediate
00134   //message. If the variable is set, then we should increase the QD counter.
00135   //Chao Mei
00136   char isFromImmMsgCall; //hack for imm msg with QD in SMP 
00137 #endif
00138 
00139   // DMK - Atom Separation (water vs. non-water)
00140   #if NAMD_SeparateWaters != 0
00141     int numWaterAtoms;  // Number of atoms in positionList (from start)
00142                         //   that are part of water hydrogen groups.
00143   #endif
00144 #ifdef REMOVE_PROXYDATAMSG_EXTRACOPY
00145   //Adding padding bytes to make sure that positionList is
00146   //32-byte aligned which usually gives better cache performance,
00147   //especially on BlueGene/L machine. Otherwise, we have to
00148   //do the extra copy.
00149   //The basic method to calculate padding is to add up
00150   //the size of all the fields so far, including
00151   //the message header (the envelope) , then mod (alignment)
00152   // --Chao Mei
00153 #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR) && (CMK_SMP) && defined(NAMDSRC_IMMQD_HACK)
00154  #if NAMD_SeparateWaters != 0
00155   char padding[(32-(sizeof(envelope)+sizeof(PatchID)+sizeof(Flags)+sizeof(isFromImmMsgCall)+4*sizeof(int)+3*sizeof(void *))%32)%32];
00156  #else
00157   char padding[(32-(sizeof(envelope)+sizeof(PatchID)+sizeof(Flags)+sizeof(isFromImmMsgCall)+3*sizeof(int)+3*sizeof(void *))%32)%32];
00158  #endif
00159 #else
00160  #if NAMD_SeparateWaters != 0
00161   char padding[(32-(sizeof(envelope)+sizeof(PatchID)+sizeof(Flags)+4*sizeof(int)+3*sizeof(void *))%32)%32];
00162  #else
00163   char padding[(32-(sizeof(envelope)+sizeof(PatchID)+sizeof(Flags)+3*sizeof(int)+3*sizeof(void *))%32)%32];
00164  #endif
00165 #endif
00166 
00167 #endif
00168 
00169 };
00170 
00171 
00172 
00173 class ProxyResultMsg : public CMessage_ProxyResultMsg {
00174 public:
00175   NodeID node;
00176   PatchID patch;
00177   ForceList forceList[Results::maxNumForces];
00178   static void* pack(ProxyResultMsg *msg);
00179   static ProxyResultMsg* unpack(void *ptr);
00180 };
00181 
00182 class ProxyResultVarsizeMsg: public CMessage_ProxyResultVarsizeMsg{
00183 public:
00184     NodeID node;
00185     PatchID patch;
00186     int flLen[Results::maxNumForces];   
00187 
00188     Force *forceArr;
00189     //Indicate the position of the force list that has zero value
00190     //which is not recorded in the above force array.
00191     char *isZero;
00192 
00193     //add padding bytes to make sure the beginning 
00194     //of force arrays is 8-byte aligned as it is originally.
00195     //Therefore, we have to put the forceArr field as
00196     //the first variable of varsize array type
00197     char padding[(8-(sizeof(envelope)+sizeof(NodeID)+sizeof(PatchID)+sizeof(int)*Results::maxNumForces+2*sizeof(void *))%8)%8];   
00198 
00199     //The length of "fls" is Results::maxNumForces
00200     static ProxyResultVarsizeMsg *getANewMsg(NodeID nid, PatchID pid, int prioSize, ForceList *fls); 
00201 };
00202 
00203 class ProxyNodeAwareSpanningTreeMsg: public CMessage_ProxyNodeAwareSpanningTreeMsg{
00204 public:
00205     PatchID patch;
00206     NodeID procID;
00207     int numNodesWithProxies;
00208     int *numPesOfNode;
00209     int *allPes;
00210 
00211     static ProxyNodeAwareSpanningTreeMsg *getANewMsg(PatchID pid, NodeID nid, proxyTreeNode *tree, int size);
00212 
00213     //For debug
00214     void printOut(char *tag);
00215 };
00216 
00217 class ProxyCombinedResultRawMsg : public CMessage_ProxyCombinedResultRawMsg {
00218 public:
00219         int nodeSize;
00220         NodeID *nodes;
00221 
00222         #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR)
00223         //since this msg may be processed by comm thread in the smp mode,
00224         //this variable helps comm thread to find which proc will actually process it.
00225         NodeID destPe;
00226         #if CMK_SMP && defined(NAMDSRC_IMMQD_HACK)
00227         //Mainly for QD in the presence of the optimization of using immediate
00228         //message. Refer to the explanation from ProxyDataMsg for the same 
00229         //variable. --Chao Mei
00230         char isFromImmMsgCall;
00231         #endif
00232         #endif
00233         PatchID patch;
00234 
00235         int flLen[Results::maxNumForces];
00236         char *isForceNonZero;
00237         //The beginning address of this variable should be 8-byte aligned!!! -Chao Mei
00238         Force *forceArr;
00239 };
00240 
00241 class ProxyCombinedResultMsg : public CMessage_ProxyCombinedResultMsg {
00242 public:
00243   #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR)
00244   //since this msg may be processed by comm thread in the smp mode,
00245   //this variable helps comm thread to find which proc will actually process it.
00246   NodeID destPe;
00247   #if CMK_SMP && defined(NAMDSRC_IMMQD_HACK)
00248   //Mainly for QD in the presence of the optimization of using immediate
00249   //message. Refer to the explanation from ProxyDataMsg for the same 
00250   //variable. --Chao Mei
00251   char isFromImmMsgCall;
00252   #endif
00253   #endif
00254   PatchID patch;
00255   NodeIDList nodes;
00256   ForceList forceList[Results::maxNumForces];
00257   static ProxyCombinedResultRawMsg* toRaw(ProxyCombinedResultMsg *msg);
00258   static ProxyCombinedResultMsg* fromRaw(ProxyCombinedResultRawMsg *msg);
00259 };
00260 
00261 class ProxySpanningTreeMsg : public CMessage_ProxySpanningTreeMsg {
00262 public:
00263   PatchID patch;
00264   NodeID  node;
00265   NodeIDList tree;
00266   static void* pack(ProxySpanningTreeMsg *msg);
00267   static ProxySpanningTreeMsg* unpack(void *ptr);
00268 };
00269 
00270 class ProxyPatch;
00271 class PatchMap;
00272 
00273 struct ProxyElem {
00274   ProxyElem() : proxyPatch(0) { };
00275   ProxyElem(PatchID pid) : patchID(pid), proxyPatch(0) { };
00276   ProxyElem(PatchID pid, ProxyPatch *p) : patchID(pid), proxyPatch(p) { };
00277 
00278   int hash() const { return patchID; }
00279   int operator==(const ProxyElem & pe) const { return patchID == pe.patchID; }
00280 
00281   PatchID patchID;
00282   ProxyPatch *proxyPatch;
00283 };
00284 
00285 typedef UniqueSet<ProxyElem> ProxySet;
00286 typedef UniqueSetIter<ProxyElem> ProxySetIter;
00287 
00288 class ProxyTree {       // keep track of the spanning trees
00289   public:
00290     int proxyMsgCount;
00291     NodeIDList *proxylist;
00292 #ifdef NODEAWARE_PROXY_SPANNINGTREE
00293     //a node-aware spanning tree array, each element of which
00294     //is a spanning tree for all proxies of a patch
00295     proxyTreeNodeList *naTrees;
00296 #else
00297     NodeIDList *trees;
00298     int *sizes;
00299 #endif
00300     
00301   public:
00302     ProxyTree() {
00303       proxyMsgCount = 0;
00304       proxylist = NULL;
00305 #ifdef NODEAWARE_PROXY_SPANNINGTREE
00306       naTrees = NULL;
00307 #else
00308       trees = NULL;
00309       sizes = NULL;
00310 #endif      
00311     }
00312     ~ProxyTree() {
00313     }
00314 };
00315 
00316 class ProxyMgr : public BOCclass
00317 {
00318 public:
00319   ProxyMgr();
00320   ~ProxyMgr();
00321 
00322   void removeProxies(void);
00323   void removeUnusedProxies(void);
00324   void createProxies(void);
00325 
00326   void createProxy(PatchID pid);
00327   void removeProxy(PatchID pid);
00328 
00329   void registerProxy(PatchID pid);
00330   void recvRegisterProxy(RegisterProxyMsg *);
00331 
00332   void unregisterProxy(PatchID pid);
00333   void recvUnregisterProxy(UnregisterProxyMsg *);
00334 
00335   void setSendSpanning();
00336   int  getSendSpanning();
00337 
00338   void setRecvSpanning();
00339   int  getRecvSpanning();
00340 
00341   void setProxyTreeBranchFactor(int dim);
00342 
00343   void buildProxySpanningTree();
00344   void sendSpanningTrees();
00345   void sendSpanningTreeToHomePatch(int pid, int *tree, int n);
00346   void recvSpanningTreeOnHomePatch(int pid, int *tree, int n);
00347   void sendSpanningTree(ProxySpanningTreeMsg *);
00348   void recvSpanningTree(ProxySpanningTreeMsg *);
00349 
00350   void sendNodeAwareSpanningTreeToHomePatch(int pid, proxyTreeNode *tree, int n);
00351   void recvNodeAwareSpanningTreeOnHomePatch(ProxyNodeAwareSpanningTreeMsg *msg);
00352   void sendNodeAwareSpanningTree(ProxyNodeAwareSpanningTreeMsg *);
00353   void recvNodeAwareSpanningTree(ProxyNodeAwareSpanningTreeMsg *);
00354   //set the proxy patch's parent field
00355   void recvNodeAwareSTParent(int patch, int parent);
00356 
00357   void buildProxySpanningTree2();               // centralized version
00358   void sendProxies(int pid, int *list, int n);
00359   void recvProxies(int pid, int *list, int n);
00360   void recvPatchProxyInfo(PatchProxyListMsg *msg);
00361 
00362 #ifdef NODEAWARE_PROXY_SPANNINGTREE
00363   void buildNodeAwareSpanningTree0();
00364   static void buildSinglePatchNodeAwareSpanningTree(PatchID pid, NodeIDList &proxyList, 
00365                                                     proxyTreeNodeList &ptnTree);
00366 #else
00367   void buildSpanningTree0();
00368 #endif
00369 
00370   void sendResults(ProxyResultVarsizeMsg *);
00371   void recvResults(ProxyResultVarsizeMsg *);
00372   void sendResults(ProxyResultMsg *);
00373   void recvResults(ProxyResultMsg *);
00374   void sendResults(ProxyCombinedResultMsg *);
00375 
00376   void sendResult(ProxyGBISP1ResultMsg *);//psiSum
00377   void recvResult(ProxyGBISP1ResultMsg *);
00378   void recvData(   ProxyGBISP2DataMsg *);
00379   void sendResult(ProxyGBISP2ResultMsg *);//dEdaSum
00380   void recvResult(ProxyGBISP2ResultMsg *);
00381   void recvData(   ProxyGBISP3DataMsg *);
00382 
00383   void recvResults(ProxyCombinedResultRawMsg *);
00384   void recvImmediateResults(ProxyCombinedResultRawMsg *);
00385 
00386   void sendProxyData(ProxyDataMsg *, int, int*);
00387   void recvImmediateProxyData(ProxyDataMsg *);
00388   void recvProxyData(ProxyDataMsg *);
00389 
00390   void sendProxyAll(ProxyDataMsg *, int, int*);
00391   void recvImmediateProxyAll(ProxyDataMsg *);
00392   void recvProxyAll(ProxyDataMsg *);
00393 
00394   static ProxyMgr *Object() { return CkpvAccess(ProxyMgr_instance); }
00395   
00396   int numProxies() { return proxySet.size(); }
00397 
00398   static int nodecount;
00399   ProxyTree &getPtree();
00400  
00401 private:
00402   ProxySet proxySet;
00403   ProxyTree ptree;
00404 
00405   void printProxySpanningTree();
00406 };
00407 
00408 struct ProxyListInfo{
00409         int patchID;
00410         int numProxies;
00411         int *proxyList; //record which PE the proxy is on 
00412 };
00413 
00414 class PatchProxyListMsg: public CMessage_PatchProxyListMsg {
00415 public:
00416         int numPatches;
00417         int *patchIDs;
00418         int *proxyListLen;
00419         int *proxyPEs;
00420 
00421 public:
00422         PatchProxyListMsg(int num) { numPatches = num; }
00423         static PatchProxyListMsg *createPatchProxyListMsg(PatchProxyListMsg **bufs, int bufSize, ProxyListInfo *info, int size);
00424 };
00425 
00426 class NodeProxyMgr : public CBase_NodeProxyMgr
00427 {
00428 private:
00429 /*The following vars are for node-aware spanning tree if NodeProxyMgr is used*/
00430         //Potential TODO: change it to a hashtable if necessary
00431     proxyTreeNode **proxyInfo;
00432     int numPatches;
00433 
00434     CkGroupID localProxyMgr; //a charm Group variable
00435     PatchMap **localPatchMaps;
00436 
00437 /* The following vars are for managing sending proxy list of a patch to PE 0*/
00438         int parentNode; //-1 for root node
00439         int numKidNodes;
00440         int kidRecved;
00441         //about local home patches
00442         int numHomePatches; //the number of homepatches on this node
00443         int homepatchRecved;
00444         ProxyListInfo *localProxyLists;
00445         PatchProxyListMsg **remoteProxyLists;
00446         CmiNodeLock localDepositLock;
00447         CmiNodeLock remoteDepositLock;
00448 
00449 public:
00450     NodeProxyMgr(){
00451         proxyInfo = NULL;
00452         numPatches = 0;
00453         localPatchMaps = new PatchMap *[CkMyNodeSize()];
00454 
00455                 parentNode = -1;
00456                 numKidNodes = 0;
00457                 kidRecved = 0;
00458                 numHomePatches = 0;
00459                 homepatchRecved = 0;
00460                 localProxyLists = NULL;
00461                 remoteProxyLists = NULL;
00462                 localDepositLock = CmiCreateLock();
00463                 remoteDepositLock = CmiCreateLock();
00464     }
00465     ~NodeProxyMgr(){
00466         for(int i=0; i<numPatches; i++) {
00467             delete proxyInfo[i];
00468         }
00469         delete [] proxyInfo;
00470         delete [] localPatchMaps;
00471 
00472                 CmiDestroyLock(localDepositLock);
00473                 CmiDestroyLock(remoteDepositLock);
00474     }
00475 
00476     void createProxyInfo(int numPs){
00477         numPatches = numPs;
00478         proxyInfo = new proxyTreeNode *[numPs];
00479         memset(proxyInfo, 0, sizeof(proxyTreeNode *)*numPs);
00480     }
00481     void registerPatch(int patchID, int numPes, int *pes);
00482     proxyTreeNode *getPatchProxyInfo(int patchID){
00483         return proxyInfo[patchID];
00484     }
00485 
00486     void registerLocalProxyMgr(CkGroupID one){
00487         localProxyMgr = one;
00488     }
00489     const CkGroupID &getLocalProxyMgr(){
00490         return localProxyMgr;
00491     }
00492     void registerLocalPatchMap(int rank, PatchMap *one){
00493         localPatchMaps[rank] = one;
00494     }
00495     PatchMap *getLocalPatchMap(int rank){
00496         return localPatchMaps[rank];
00497     }   
00498 
00499     void recvImmediateProxyData(ProxyDataMsg *msg);
00500     void recvImmediateProxyAll(ProxyDataMsg *msg);
00501     void recvImmediateResults(ProxyCombinedResultRawMsg *);
00502 
00503         //initialize the spanning tree of home patches
00504         void createSTForHomePatches(PatchMap *pmap);
00505         //direct call from local home patches
00506         void sendProxyList(int pid, int *plist, int size);
00507         //remote call to send this node's proxy list info
00508         void sendProxyListInfo(PatchProxyListMsg *msg);
00509         void contributeToParent();
00510 };
00511 
00512 #endif /* PATCHMGR_H */
00513 

Generated on Fri May 25 04:07:16 2012 for NAMD by  doxygen 1.3.9.1