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

PatchMgr.C

Go to the documentation of this file.
00001 
00007 #include "InfoStream.h"
00008 #include "PatchMgr.decl.h"
00009 #include "PatchMgr.h"
00010 
00011 #include "NamdTypes.h"
00012 //#include "Compute.h"
00013 #include "HomePatch.h"
00014 #include "PatchMap.h"
00015 #include "AtomMap.h"
00016 
00017 #ifdef USE_COMM_LIB
00018 #include "ComlibManager.h"
00019 #endif
00020 
00021 #include "main.decl.h"
00022 #include "main.h"
00023 
00024 #include "WorkDistrib.decl.h"
00025 #include "WorkDistrib.h"
00026 #include "Node.h"
00027 #include "SimParameters.h"
00028 
00029 #include "packmsg.h"
00030 
00031 // #define DEBUGM
00032 #define MIN_DEBUG_LEVEL 3
00033 #include "Debug.h"
00034 
00035 
00036 // BOC constructor
00037 PatchMgr::PatchMgr()
00038 {
00039     // CkPrintf("[%d] PatchMgr Created\n", CkMyPe());
00040 
00041     // Singleton pattern
00042     if (CkpvAccess(PatchMgr_instance) == NULL) {
00043         CkpvAccess(PatchMgr_instance) = this;
00044     } else {
00045         iout << iFILE << iERROR << iPE 
00046           << "PatchMgr instanced twice on same processor!" << endi;
00047         CkExit();
00048     }
00049 
00050     // Get PatchMap singleton started
00051     patchMap = PatchMap::Instance();
00052     patchMap->registerPatchMgr(this);
00053 
00054     // Message combining initialization
00055     migrationCountdown = 0;
00056     combineMigrationMsgs = new MigrateAtomsCombinedMsg*[CkNumPes()];
00057 }
00058 
00059 PatchMgr::~PatchMgr()
00060 {
00061     HomePatchListIter hi(homePatches);
00062     for ( hi = hi.begin(); hi != hi.end(); hi++) {
00063       HomePatchElem* elem = homePatches.find(HomePatchElem(hi->pid));
00064       delete elem->patch;
00065     }
00066     delete [] combineMigrationMsgs;
00067 }
00068 
00069 void PatchMgr::preCreateHomePatch(PatchID pid, int atomCnt){
00070     HomePatch *patch = new HomePatch(pid, atomCnt);
00071     homePatches.load(HomePatchElem(pid, patch));
00072     patchMap->registerPatch(pid, patch);
00073 }
00074 
00075 void PatchMgr::createHomePatch(PatchID pid, FullAtomList a) 
00076 {
00077     HomePatch *patch = new HomePatch(pid, a);
00078     homePatches.load(HomePatchElem(pid, patch));
00079     patchMap->registerPatch(pid, patch);
00080 }
00081 
00082 
00083 // Add a HomePatch to a list of patches to be moved 
00084 // HomePatches are actually moved by invoking sendMovePatches() below
00085 void PatchMgr::movePatch(PatchID pid, NodeID nodeID) 
00086 {
00087     move.load(MovePatch(pid,nodeID));
00088 }
00089 
00090 void PatchMgr::sendOneHomePatch(int patchId, int nodeId){
00091     HomePatch *p = homePatch(patchId);
00092     patchMap->unregisterPatch(patchId, p);
00093 
00094     MovePatchesMsg *msg = new MovePatchesMsg(patchId, p->atom);
00095 
00096     // Sending to PatchMgr::recvMovePatches on remote node
00097     CProxy_PatchMgr cp(thisgroup);
00098 #if CHARM_VERSION > 050402
00099     cp[nodeId].recvMovePatches(msg);
00100 #else
00101     cp.recvMovePatches(msg, nodeId);
00102 #endif
00103 
00104     // Deleting the HomePatchElem will call a destructor for clean up
00105     // but the msg elements are safe since they use a container template
00106     // that uses ref counting.
00107     delete p;
00108     homePatches.del(HomePatchElem(patchId)); 
00109 }
00110 
00111 // Uses list constructed by movePatch() and dispatches
00112 // HomePatch(es) to new nodes
00113 void PatchMgr::sendMovePatches() 
00114 {
00115     if (! move.size())
00116         return;
00117 
00118     MovePatchListIter m(move);
00119     for ( m = m.begin(); m != m.end(); m++) {
00120       HomePatch *p = homePatch(m->pid);
00121       patchMap->unregisterPatch(m->pid, p);
00122 
00123       MovePatchesMsg *msg = new MovePatchesMsg(m->pid, p->atom);
00124 
00125       // Sending to PatchMgr::recvMovePatches on remote node
00126       CProxy_PatchMgr cp(thisgroup);
00127 #if CHARM_VERSION > 050402
00128       cp[m->nodeID].recvMovePatches(msg);
00129 #else
00130       cp.recvMovePatches(msg, m->nodeID);
00131 #endif
00132 
00133       // Deleting the HomePatchElem will call a destructor for clean up
00134       // but the msg elements are safe since they use a container template
00135       // that uses ref counting.
00136       delete p;
00137       homePatches.del(HomePatchElem(m->pid)); 
00138     }
00139     move.resize(0);
00140 }
00141 
00142 void PatchMgr::recvMovePatches(MovePatchesMsg *msg) {
00143     // Make a new HomePatch
00144     createHomePatch(msg->pid, msg->atom);
00145     delete msg;
00146 
00147     // Tell sending PatchMgr we received MovePatchMsg
00148 //    AckMovePatchesMsg *ackmsg = 
00149 //      new AckMovePatchesMsg;
00150 //    CSendMsgBranch(PatchMgr,ackMovePatches, ackmsg, thisgroup, msg->fromNodeID);
00151 }
00152     
00153 
00154 //void PatchMgr::ackMovePatches(AckMovePatchesMsg *msg)
00155 //{
00156 //    delete msg;
00157 //    if (! --ackMovePending) 
00158 //      WorkDistrib::messageMovePatchDone();
00159 //}
00160 
00161 
00162 void PatchMgr::sendAtoms(PatchID pid, FullAtomList a) {
00163 
00164       MovePatchesMsg *msg = new MovePatchesMsg(pid, a);
00165 
00166       CProxy_PatchMgr cp(thisgroup);
00167 #if CHARM_VERSION > 050402
00168       cp[patchMap->node(pid)].recvAtoms(msg);
00169 #else
00170       cp.recvAtoms(msg, patchMap->node(pid));
00171 #endif
00172 
00173 }
00174 
00175 void PatchMgr::recvAtoms(MovePatchesMsg *msg) {
00176     patchMap->homePatch(msg->pid)->reinitAtoms(msg->atom);
00177     delete msg;
00178 }
00179 
00180 
00181 // Called by HomePatch to migrate atoms off to new patches
00182 // Message combining could occur here
00183 void PatchMgr::sendMigrationMsg(PatchID src, MigrationInfo m) {
00184   MigrateAtomsMsg *msg = new MigrateAtomsMsg(src,m.destPatchID,m.mList);
00185   CProxy_PatchMgr cp(thisgroup);
00186 #if CHARM_VERSION > 050402
00187   cp[m.destNodeID].recvMigrateAtoms(msg);
00188 #else
00189   cp.recvMigrateAtoms(msg, m.destNodeID);
00190 #endif
00191 }
00192 
00193 // Called by HomePatch to migrate atoms off to new patches
00194 // Message combining occurs here
00195 void PatchMgr::sendMigrationMsgs(PatchID src, MigrationInfo *m, int numMsgs) {
00196 /*
00197   for (int i=0; i < numMsgs; i++) {
00198     PatchMgr::Object()->sendMigrationMsg(src, m[i]);
00199   }
00200 */
00201   if ( ! migrationCountdown )  // (re)initialize
00202   {
00203     // DebugM(3,"migrationCountdown (re)initialize\n");
00204     numHomePatches = patchMap->numHomePatches();
00205     migrationCountdown = numHomePatches;
00206     int numPes = CkNumPes();
00207     for ( int i = 0; i < numPes; ++i ) combineMigrationMsgs[i] = 0;
00208   }
00209   for (int i=0; i < numMsgs; i++) {  // buffer messages
00210     int destNodeID = m[i].destNodeID;
00211     if ( 1 ) // destNodeID != CkMyPe() )
00212     {
00213       if ( ! combineMigrationMsgs[destNodeID] )
00214       {
00215         combineMigrationMsgs[destNodeID] = new MigrateAtomsCombinedMsg();
00216       }
00217       combineMigrationMsgs[destNodeID]->add(src,m[i].destPatchID,m[i].mList);
00218     }
00219     else
00220     {
00221         // for now buffer local messages too
00222     }
00223   }
00224   migrationCountdown -= 1;
00225   // DebugM(3,"migrationCountdown = " << migrationCountdown << "\n");
00226   if ( ! migrationCountdown )  // send out combined messages
00227   {
00228     int numPes = CkNumPes();
00229     for ( int destNodeID = 0; destNodeID < numPes; ++destNodeID )
00230       if ( combineMigrationMsgs[destNodeID] )
00231       {
00232         DebugM(3,"Sending MigrateAtomsCombinedMsg to node " << destNodeID << "\n");
00233         CProxy_PatchMgr cp(thisgroup);
00234 #if CHARM_VERSION > 050402
00235         cp[destNodeID].recvMigrateAtomsCombined(combineMigrationMsgs[destNodeID]);
00236 #else
00237         cp.recvMigrateAtomsCombined(combineMigrationMsgs[destNodeID],destNodeID);
00238 #endif
00239       }
00240   }
00241 }
00242 
00243 // Receive end of sendMigrationMsg() above
00244 void PatchMgr::recvMigrateAtoms (MigrateAtomsMsg *msg) {
00245   //  msg must be deleted by HomePatch::depositMigrationMsg();
00246   PatchMap::Object()->homePatch(msg->destPatchID)->depositMigration(msg);
00247 }
00248 
00249 void PatchMgr::recvMigrateAtomsCombined (MigrateAtomsCombinedMsg *msg)
00250 {
00251   DebugM(3,"Received MigrateAtomsCombinedMsg with " << msg->srcPatchID.size() << " messages.\n");
00252   msg->distribute();
00253   delete msg;
00254 }
00255 
00256 void PatchMgr::moveAtom(MoveAtomMsg *msg) {
00257   LocalID lid = AtomMap::Object()->localID(msg->atomid);
00258   if ( lid.pid != notUsed ) {
00259     HomePatch *hp = patchMap->homePatch(lid.pid);
00260     if ( hp ) {
00261       FullAtom &a = hp->atom[lid.index];
00262       if ( msg->moveto ) {
00263         a.fixedPosition = msg->coord;
00264       } else {
00265         a.fixedPosition = hp->lattice.reverse_transform(a.position,a.transform);
00266         a.fixedPosition += msg->coord;
00267       }
00268       a.position = hp->lattice.apply_transform(a.fixedPosition,a.transform);
00269     }
00270   }
00271   delete msg;
00272 }
00273 
00274 void PatchMgr::moveAllBy(MoveAllByMsg *msg) {
00275   // loop over homePatches, moving every atom
00276   for (HomePatchElem *elem = homePatches.begin(); elem != homePatches.end(); elem++) {
00277     HomePatch *hp = elem->patch;
00278     for (int i=0; i<hp->getNumAtoms(); i++) {
00279       FullAtom &a = hp->atom[i];
00280       a.fixedPosition = hp->lattice.reverse_transform(a.position,a.transform);
00281       a.fixedPosition += msg->offset;
00282       a.position = hp->lattice.apply_transform(a.fixedPosition,a.transform);
00283     }
00284   }
00285   delete msg;
00286 }
00287 
00288 void PatchMgr::setLattice(SetLatticeMsg *msg) {
00289   // loop over homePatches, setting the lattice to the new value.
00290   for (HomePatchElem *elem = homePatches.begin(); elem != homePatches.end(); elem++) {
00291     HomePatch *hp = elem->patch;
00292     hp->lattice = msg->lattice;
00293   }
00294   // Must also do this for SimParameters in order for pressure profile to work!
00295   Node::Object()->simParameters->lattice = msg->lattice;
00296 }
00297 
00298 PACK_MSG(MovePatchesMsg,
00299   PACK(fromNodeID);
00300   PACK(pid);
00301   PACK_RESIZE(atom);
00302 )
00303 
00304 
00305 #include "PatchMgr.def.h"
00306 

Generated on Sat Oct 11 04:07:42 2008 for NAMD by  doxygen 1.3.9.1