| version 1.1041 | version 1.1042 |
|---|
| |
| #include "Debug.h" | #include "Debug.h" |
| | |
| ProxyPatch::ProxyPatch(PatchID pd) : | ProxyPatch::ProxyPatch(PatchID pd) : |
| Patch(pd), msgBuffer(NULL), msgAllBuffer(NULL) | Patch(pd), proxyMsgBufferStatus(PROXYMSGNOTBUFFERED), |
| | curProxyMsg(NULL), prevProxyMsg(NULL) |
| { | { |
| DebugM(4, "ProxyPatch(" << pd << ") at " << this << "\n"); | DebugM(4, "ProxyPatch(" << pd << ") at " << this << "\n"); |
| ProxyMgr::Object()->registerProxy(patchID); | ProxyMgr::Object()->registerProxy(patchID); |
| |
| { | { |
| DebugM(4, "ProxyPatch(" << pd << ") deleted at " << this << "\n"); | DebugM(4, "ProxyPatch(" << pd << ") deleted at " << this << "\n"); |
| ProxyMgr::Object()->unregisterProxy(patchID); | ProxyMgr::Object()->unregisterProxy(patchID); |
| AtomMap::Object()->unregisterIDs(patchID,p.begin(),p.end()); | |
| | // ProxyPatch may be freed because of load balancing if the compute object |
| | // it corresponds to no longer exist on this specific processor. |
| | CmiAssert(prevProxyMsg!=NULL); |
| | if(prevProxyMsg!=NULL) { |
| | //AtomMap::Object()->unregisterIDs(patchID,p.begin(),p.end()); |
| | AtomMap::Object()->unregisterIDs(patchID,positionPtrBegin, positionPtrEnd); |
| | delete prevProxyMsg; |
| | prevProxyMsg = NULL; |
| | } |
| | |
| delete [] child; | delete [] child; |
| | |
| | #ifdef MEM_OPT_VERSION |
| | pExt.resize(0); |
| | #endif |
| | |
| #if CMK_PERSISTENT_COMM | #if CMK_PERSISTENT_COMM |
| CmiDestoryPersistent(localphs); | CmiDestoryPersistent(localphs); |
| localphs = 0; | localphs = 0; |
| |
| void ProxyPatch::boxClosed(int box) | void ProxyPatch::boxClosed(int box) |
| { | { |
| if ( box == 1 ) { | if ( box == 1 ) { |
| | // Note: delay the deletion of proxyDataMsg (of the |
| | // current step) until the next step. This is done |
| | // for the sake of atom migration (ProxyDataMsg) |
| | // as the ProxyPatch has to unregister the atoms |
| | // of the previous step in the AtomMap data structure. |
| sendResults(); | sendResults(); |
| } | } |
| if ( ! --boxesOpen ) { | if ( ! --boxesOpen ) { |
| DebugM(2,patchID << ": " << "Checking message buffer.\n"); | DebugM(2,patchID << ": " << "Checking message buffer.\n"); |
| if ( msgBuffer ) { | |
| DebugM(3,"Patch " << patchID << " processing buffered proxy data.\n"); | if(proxyMsgBufferStatus == PROXYALLMSGBUFFERED) { |
| receiveData(msgBuffer); | CmiAssert(curProxyMsg != NULL); |
| } else if (msgAllBuffer ) { | |
| DebugM(3,"Patch " << patchID << " processing buffered proxy ALL data.\n"); | DebugM(3,"Patch " << patchID << " processing buffered proxy ALL data.\n"); |
| receiveAll(msgAllBuffer); | receiveAll(curProxyMsg); |
| } | }else if(proxyMsgBufferStatus == PROXYDATAMSGBUFFERED) { |
| | CmiAssert(curProxyMsg != NULL); |
| | DebugM(3,"Patch " << patchID << " processing buffered proxy data.\n"); |
| | receiveData(curProxyMsg); |
| } | } |
| else { | } else { |
| DebugM(3,"ProxyPatch " << patchID << ": " << boxesOpen << " boxes left to close.\n"); | DebugM(3,"ProxyPatch " << patchID << ": " << boxesOpen << " boxes left to close.\n"); |
| } | } |
| } | } |
| |
| void ProxyPatch::receiveData(ProxyDataMsg *msg) | void ProxyPatch::receiveData(ProxyDataMsg *msg) |
| { | { |
| DebugM(3, "receiveData(" << patchID << ")\n"); | DebugM(3, "receiveData(" << patchID << ")\n"); |
| | |
| | //delete the ProxyDataMsg of the previous step |
| | delete prevProxyMsg; |
| | prevProxyMsg = NULL; |
| | |
| if ( boxesOpen ) | if ( boxesOpen ) |
| { | { |
| | proxyMsgBufferStatus = PROXYDATAMSGBUFFERED; |
| // store message in queue (only need one element, though) | // store message in queue (only need one element, though) |
| msgBuffer = msg; | curProxyMsg = msg; |
| return; | return; |
| } | } |
| msgBuffer = NULL; | |
| | //Reuse position arrays inside proxyDataMsg --Chao Mei |
| | curProxyMsg = msg; |
| | prevProxyMsg = curProxyMsg; |
| flags = msg->flags; | flags = msg->flags; |
| p = msg->positionList; | |
| p_avg = msg->avgPositionList; | //We could set them to 0 for the sake of easy debugging |
| delete msg; | //if there are something wrong in the "reuse position arrays" code |
| | //--Chao Mei |
| | //p.resize(0); |
| | //p_avg.resize(0); |
| | |
| | positionPtrBegin = msg->positionList; |
| | positionPtrEnd = msg->positionList + msg->plLen; |
| | |
| | avgPositionPtrBegin = msg->avgPositionList; |
| | avgPositionPtrEnd = msg->avgPositionList + msg->avgPlLen; |
| | |
| | |
| if ( numAtoms == -1 ) { // for new proxies since receiveAtoms is not called | if ( numAtoms == -1 ) { // for new proxies since receiveAtoms is not called |
| numAtoms = p.size(); | //numAtoms = p.size(); |
| | numAtoms = msg->plLen; |
| | |
| | #ifdef MEM_OPT_VERSION |
| | //Retrieve the CompAtomExt list |
| | CmiAssert(msg->plExtLen!=0); |
| | pExt.resize(msg->plExtLen); |
| | memcpy(pExt.begin(), msg->positionExtList, sizeof(CompAtomExt)*(msg->plExtLen)); |
| | #endif |
| | |
| | |
| // DMK - Atom Separation (water vs. non-water) | // DMK - Atom Separation (water vs. non-water) |
| #if NAMD_SeparateWaters != 0 | #if NAMD_SeparateWaters != 0 |
| |
| } | } |
| } | } |
| | |
| void ProxyPatch::receiveAll(ProxyAllMsg *msg) | void ProxyPatch::receiveAll(ProxyDataMsg *msg) |
| { | { |
| DebugM(3, "receiveAll(" << patchID << ")\n"); | DebugM(3, "receiveAll(" << patchID << ")\n"); |
| | |
| if ( boxesOpen ) | if ( boxesOpen ) |
| { | { |
| // store message in queue (only need one element, though) | proxyMsgBufferStatus = PROXYALLMSGBUFFERED; |
| msgAllBuffer = msg; | curProxyMsg = msg; |
| return; | return; |
| } | } |
| msgAllBuffer = NULL; | |
| | |
| AtomMap::Object()->unregisterIDs(patchID,p.begin(),p.end()); | //The prevProxyMsg has to be deleted after this if-statement because |
| | // positionPtrBegin points to the space inside the prevProxyMsg |
| | if(prevProxyMsg!=NULL) { |
| | AtomMap::Object()->unregisterIDs(patchID,positionPtrBegin,positionPtrEnd); |
| | } |
| | //Now delete the ProxyDataMsg of the previous step |
| | delete prevProxyMsg; |
| | curProxyMsg = msg; |
| | prevProxyMsg = curProxyMsg; |
| | |
| flags = msg->flags; | flags = msg->flags; |
| p = msg->positionList; | |
| numAtoms = p.size(); | |
| p_avg = msg->avgPositionList; | |
| | |
| // DMK - Atom Separation (water vs. non-water) | positionPtrBegin = msg->positionList; |
| #if NAMD_SeparateWaters != 0 | positionPtrEnd = msg->positionList + msg->plLen; |
| numWaterAtoms = msg->numWaterAtoms; | numAtoms = msg->plLen; |
| #endif | //numAtoms = p.size(); |
| | |
| | avgPositionPtrBegin = msg->avgPositionList; |
| | avgPositionPtrEnd = msg->avgPositionList + msg->avgPlLen; |
| | |
| | //We could set them to 0 for the sake of easy debugging |
| | //if there are something wrong in the "reuse position arrays" code |
| | //--Chao Mei |
| | p.resize(0); |
| | p_avg.resize(0); |
| | |
| #ifdef MEM_OPT_VERSION | #ifdef MEM_OPT_VERSION |
| pExt = msg->extInfoList; | //We cannot reuse the CompAtomExt list inside the msg because |
| | //the information is needed at every step. In the current implementation |
| | //scheme, the ProxyDataMsg msg will be deleted for every step. |
| | //In order to keep this information, we have to do the extra copy. But |
| | //this overhead is amortized among the steps that atoms don't migrate |
| | // --Chao Mei |
| | pExt.resize(msg->plExtLen); |
| | memcpy(pExt.begin(), msg->positionExtList, sizeof(CompAtomExt)*(msg->plExtLen)); |
| #endif | #endif |
| | |
| delete msg; | // DMK - Atom Separation (water vs. non-water) |
| | #if NAMD_SeparateWaters != 0 |
| | numWaterAtoms = msg->numWaterAtoms; |
| | #endif |
| | |
| positionsReady(1); | positionsReady(1); |
| } | } |