ProxyPatch.C

Go to the documentation of this file.
00001 
00007 #include "InfoStream.h"
00008 #include "Lattice.h"
00009 #include "ComputeMsmMsa.h"  // needed for MsmMsaData definition
00010 #include "main.decl.h"
00011 #include "main.h"
00012 #include "ProxyPatch.h"
00013 #include "ProxyMgr.decl.h"
00014 #include "ProxyMgr.h"
00015 #include "AtomMap.h"
00016 #include "PatchMap.h"
00017 #include "Priorities.h"
00018 
00019 #define MIN_DEBUG_LEVEL 2
00020 //#define  DEBUGM
00021 #include "Debug.h"
00022 
00023 ProxyPatch::ProxyPatch(PatchID pd) : 
00024   Patch(pd), proxyMsgBufferStatus(PROXYMSGNOTBUFFERED), 
00025   curProxyMsg(NULL), prevProxyMsg(NULL)
00026 {
00027   DebugM(4, "ProxyPatch(" << pd << ") at " << this << "\n");
00028   ProxyMgr::Object()->registerProxy(patchID);
00029   numAtoms = -1;
00030   parent = -1;
00031 
00032 #ifndef NODEAWARE_PROXY_SPANNINGTREE
00033   nChild = 0;
00034   child = new int[proxySpanDim];
00035 #endif
00036 
00037 #if CMK_PERSISTENT_COMM && USE_PERSISTENT_TREE
00038   localphs = 0;
00039 #ifdef REMOVE_PROXYRESULTMSG_EXTRACOPY
00040   int msgstart = sizeof(envelope)+sizeof(ProxyResultVarsizeMsg);
00041 #else
00042   int msgstart = sizeof(envelope)+sizeof(ProxyResultMsg);
00043 #endif
00044   localphs = CmiCreatePersistent(PatchMap::Object()->node(patchID), 30000, msgstart);
00045   ntreephs = 0;
00046 #ifdef NODEAWARE_PROXY_SPANNINGTREE
00047   treephs = NULL;
00048 #else
00049   treephs = new PersistentHandle[proxySpanDim];
00050 #endif
00051 #endif
00052 
00053   // DMK - Atom Separation (water vs. non-water)
00054   #if NAMD_SeparateWaters != 0
00055     numWaterAtoms = -1;
00056   #endif
00057   
00058   #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR)
00059     depositLock = CmiCreateLock();
00060   #endif
00061 }
00062 
00063 ProxyPatch::~ProxyPatch()
00064 {
00065   DebugM(4, "ProxyPatch(" << patchID << ") deleted at " << this << "\n");
00066   ProxyMgr::Object()->unregisterProxy(patchID);
00067 
00068   // ProxyPatch may be freed because of load balancing if the compute object
00069   // it corresponds to no longer exist on this specific processor.
00070   CmiAssert(prevProxyMsg!=NULL);
00071   if(prevProxyMsg!=NULL) {
00072 // #ifdef REMOVE_PROXYDATAMSG_EXTRACOPY
00073 //       AtomMap::Object()->unregisterIDs(patchID,positionPtrBegin, positionPtrEnd);
00074 // #else
00075       atomMapper->unregisterIDsCompAtomExt(pExt.begin(),pExt.end());
00076 // #endif      
00077 #if ! CMK_PERSISTENT_COMM || ! USE_PERSISTENT_TREE
00078       delete prevProxyMsg;
00079 #endif
00080       prevProxyMsg = NULL;
00081   }
00082 
00083 
00084 #ifdef NODEAWARE_PROXY_SPANNINGTREE
00085   #ifdef USE_NODEPATCHMGR
00086   delete [] nodeChildren;  
00087   #endif
00088 #endif
00089   delete [] child;
00090 
00091   p.resize(0);
00092   pExt.resize(0);
00093 
00094   lcpoType.resize(0);
00095 
00096 #if CMK_PERSISTENT_COMM && USE_PERSISTENT_TREE
00097   CmiDestoryPersistent(localphs);
00098   localphs = 0;
00099   for (int i=0; i<ntreephs; i++)  CmiDestoryPersistent(treephs[i]);
00100   delete [] treephs;
00101 #endif
00102 }
00103 
00104 void ProxyPatch::boxClosed(int box) {
00105   ProxyGBISP1ResultMsg *msg1;
00106   ProxyGBISP2ResultMsg *msg2;
00107  
00108   if (box == 1) { // force Box
00109     // Note: delay the deletion of proxyDataMsg (of the 
00110     // current step) until the next step. This is done 
00111     // for the sake of atom migration (ProxyDataMsg) 
00112     // as the ProxyPatch has to  unregister the atoms 
00113     // of the previous step in the AtomMap data structure 
00114     // also denotes end of gbis phase 3
00115     sendResults();
00116   } else if ( box == 5) {//end phase 1
00117     //this msg should only have nonzero atoms if flags.doNonbonded
00118     int msgAtoms = (flags.doNonbonded) ? numAtoms : 0;
00119     msg1 = new (msgAtoms,PRIORITY_SIZE) ProxyGBISP1ResultMsg;
00120     for (int i = 0; i < msgAtoms; i++) {
00121       msg1->psiSum[i] = psiSum[i];
00122     }
00123     msg1->patch = patchID;
00124     msg1->psiSumLen = msgAtoms;
00125     msg1->origPe = CkMyPe();
00126     SET_PRIORITY(msg1,flags.sequence,GB1_PROXY_RESULTS_PRIORITY + PATCH_PRIORITY(patchID));
00127     ProxyMgr::Object()->sendResult(msg1);
00128   } else if ( box == 8) {//end phase 2
00129     //this msg should only have nonzero atoms if flags.doFullElectrostatics
00130     int msgAtoms = (flags.doFullElectrostatics) ? numAtoms : 0;
00131     msg2 = new (msgAtoms,PRIORITY_SIZE) ProxyGBISP2ResultMsg;
00132     for (int i = 0; i < msgAtoms; i++) {
00133       msg2->dEdaSum[i] = dEdaSum[i];
00134     }
00135     msg2->patch = patchID;
00136     msg2->dEdaSumLen = msgAtoms;
00137     msg2->origPe = CkMyPe();
00138     SET_PRIORITY(msg2,flags.sequence,GB2_PROXY_RESULTS_PRIORITY + PATCH_PRIORITY(patchID));
00139     ProxyMgr::Object()->sendResult(msg2);
00140   } else if (box == 9) {
00141     //nothing
00142   } else if (box == 10) {
00143     // LCPO do nothing
00144   }
00145 
00146 
00147   if ( ! --boxesOpen ) {
00148     DebugM(2,patchID << ": " << "Checking message buffer.\n");    
00149     
00150     if(proxyMsgBufferStatus == PROXYALLMSGBUFFERED) {
00151           CmiAssert(curProxyMsg != NULL);
00152           DebugM(3,"Patch " << patchID << " processing buffered proxy ALL data.\n");
00153           receiveAll(curProxyMsg);          
00154     }else if(proxyMsgBufferStatus == PROXYDATAMSGBUFFERED) {
00155           CmiAssert(curProxyMsg != NULL);
00156           DebugM(3,"Patch " << patchID << " processing buffered proxy data.\n");
00157           receiveData(curProxyMsg);
00158     }
00159   } else {
00160        DebugM(3,"ProxyPatch " << patchID << ": " << boxesOpen << " boxes left to close.\n");
00161   }
00162 }
00163 
00164 //each timestep
00165 void ProxyPatch::receiveData(ProxyDataMsg *msg)
00166 {
00167   DebugM(3, "receiveData(" << patchID << ")\n");
00168 
00169   //delete the ProxyDataMsg of the previous step
00170   delete prevProxyMsg;
00171   prevProxyMsg = NULL;
00172 
00173   if ( boxesOpen )
00174   {
00175       proxyMsgBufferStatus = PROXYDATAMSGBUFFERED;
00176     // store message in queue (only need one element, though)
00177     curProxyMsg = msg;
00178     return;
00179   }
00180 
00181   //Reuse position arrays inside proxyDataMsg --Chao Mei
00182   curProxyMsg = msg;
00183   prevProxyMsg = curProxyMsg;
00184   flags = msg->flags;
00185 
00186 #ifdef REMOVE_PROXYDATAMSG_EXTRACOPY
00187   if ( ((int64)msg->positionList) % 32 ) { // not aligned
00188     p.resize(msg->plLen);
00189     positionPtrBegin = p.begin();
00190     memcpy(positionPtrBegin, msg->positionList, sizeof(CompAtom)*(msg->plLen));
00191   } else { // aligned
00192     positionPtrBegin = msg->positionList;
00193   }
00194   positionPtrEnd = positionPtrBegin + msg->plLen;
00195   if ( ((int64)positionPtrBegin) % 32 ) NAMD_bug("ProxyPatch::receiveData positionPtrBegin not 32-byte aligned");
00196 #else
00197   p.resize(msg->plLen);
00198   memcpy(p.begin(), msg->positionList, sizeof(CompAtom)*(msg->plLen));
00199 #endif
00200 
00201 // DMK
00202 #if defined(NAMD_CUDA) || defined(NAMD_MIC)
00203   cudaAtomPtr = msg->cudaAtomList;
00204 #endif
00205   
00206   avgPositionPtrBegin = msg->avgPositionList;
00207   avgPositionPtrEnd = msg->avgPositionList + msg->avgPlLen;
00208   
00209   // BEGIN LA
00210   velocityPtrBegin = msg->velocityList;
00211   velocityPtrEnd = msg->velocityList + msg->vlLen;
00212   // END LA
00213 
00214   if ( numAtoms == -1 ) { // for new proxies since receiveAtoms is not called
00215       //numAtoms = p.size();
00216       numAtoms = msg->plLen;
00217 
00218       //Retrieve the CompAtomExt list
00219       CmiAssert(msg->plExtLen!=0);
00220       pExt.resize(msg->plExtLen);
00221       memcpy(pExt.begin(), msg->positionExtList, sizeof(CompAtomExt)*(msg->plExtLen));
00222 
00223 
00224     // DMK - Atom Separation (water vs. non-water)
00225     #if NAMD_SeparateWaters != 0
00226       numWaterAtoms = msg->numWaterAtoms;
00227     #endif
00228 
00229     positionsReady(1);
00230   } else {
00231     positionsReady(0);
00232   }
00233 }
00234 
00235 //every doMigration
00236 void ProxyPatch::receiveAll(ProxyDataMsg *msg)
00237 {
00238   DebugM(3, "receiveAll(" << patchID << ")\n");
00239 
00240   if ( boxesOpen )
00241   {
00242     proxyMsgBufferStatus = PROXYALLMSGBUFFERED;    
00243     curProxyMsg = msg;
00244     return;
00245   }  
00246 
00247   //The prevProxyMsg has to be deleted after this if-statement because
00248   // positionPtrBegin points to the space inside the prevProxyMsg
00249   if(prevProxyMsg!=NULL) {
00250 // #ifdef REMOVE_PROXYDATAMSG_EXTRACOPY
00251 //       AtomMap::Object()->unregisterIDs(patchID,positionPtrBegin,positionPtrEnd);
00252 // #else
00253       atomMapper->unregisterIDsCompAtomExt(pExt.begin(), pExt.end());
00254 // #endif
00255   }
00256   //Now delete the ProxyDataMsg of the previous step
00257 #if ! CMK_PERSISTENT_COMM || ! USE_PERSISTENT_TREE
00258   delete prevProxyMsg;
00259 #endif
00260   curProxyMsg = msg;
00261   prevProxyMsg = curProxyMsg;
00262 
00263   flags = msg->flags;
00264 
00265 #ifdef REMOVE_PROXYDATAMSG_EXTRACOPY
00266   if ( ((int64)msg->positionList) % 32 ) { // not aligned
00267     p.resize(msg->plLen);
00268     positionPtrBegin = p.begin();
00269     memcpy(positionPtrBegin, msg->positionList, sizeof(CompAtom)*(msg->plLen));
00270   } else { // aligned
00271     positionPtrBegin = msg->positionList;
00272   }
00273   positionPtrEnd = positionPtrBegin + msg->plLen;
00274   if ( ((int64)positionPtrBegin) % 32 ) NAMD_bug("ProxyPatch::receiveAll positionPtrBegin not 32-byte aligned");
00275 #else
00276   p.resize(msg->plLen);
00277   memcpy(p.begin(), msg->positionList, sizeof(CompAtom)*(msg->plLen));
00278 #endif
00279 
00280 // DMK
00281 #if defined(NAMD_CUDA) || defined(NAMD_MIC)
00282   cudaAtomPtr = msg->cudaAtomList;
00283 #endif
00284 
00285   numAtoms = msg->plLen;
00286   //numAtoms = p.size();
00287   
00288   avgPositionPtrBegin = msg->avgPositionList;
00289   avgPositionPtrEnd = msg->avgPositionList + msg->avgPlLen;
00290   
00291   // BEGIN LA
00292   velocityPtrBegin = msg->velocityList;
00293   velocityPtrEnd = msg->velocityList + msg->vlLen;
00294   // END LA
00295 
00296   if (flags.doGBIS) {
00297     intRad.resize(numAtoms*2);
00298     for (int i = 0; i < numAtoms*2;i++) {
00299       intRad[i] = msg->intRadList[i];
00300     }
00301   }
00302 
00303   if (flags.doLCPO) {
00304     lcpoType.resize(numAtoms);
00305     for (int i = 0; i < numAtoms; i++) {
00306       lcpoType[i] = msg->lcpoTypeList[i];
00307     }
00308   }
00309 
00310   //We cannot reuse the CompAtomExt list inside the msg because
00311   //the information is needed at every step. In the current implementation
00312   //scheme, the ProxyDataMsg msg will be deleted for every step.
00313   //In order to keep this information, we have to do the extra copy. But
00314   //this overhead is amortized among the steps that atoms don't migrate
00315   // --Chao Mei
00316   pExt.resize(msg->plExtLen);
00317   memcpy(pExt.begin(), msg->positionExtList, sizeof(CompAtomExt)*(msg->plExtLen));
00318 
00319   // DMK - Atom Separation (water vs. non-water)
00320   #if NAMD_SeparateWaters != 0
00321     numWaterAtoms = msg->numWaterAtoms;
00322   #endif
00323 
00324   positionsReady(1);
00325 }
00326 
00327 void ProxyPatch::sendResults(void)
00328 {
00329   DebugM(3, "sendResults(" << patchID << ")\n");
00330   register int i = 0;
00331   register ForceList::iterator f_i, f_e, f2_i;
00332   for ( i = Results::normal + 1 ; i <= flags.maxForceMerged; ++i ) {
00333     f_i = f[Results::normal].begin(); f_e = f[Results::normal].end();
00334     f2_i = f[i].begin();
00335     for ( ; f_i != f_e; ++f_i, ++f2_i ) *f_i += *f2_i;
00336     f[i].resize(0);
00337   }
00338   for ( i = flags.maxForceUsed + 1; i < Results::maxNumForces; ++i )
00339     f[i].resize(0);
00340 
00341 #if CMK_PERSISTENT_COMM && USE_PERSISTENT_TREE
00342   CmiUsePersistentHandle(&localphs, 1);
00343 #endif
00344 
00345   if (proxyRecvSpanning == 0) {
00346 #ifdef REMOVE_PROXYRESULTMSG_EXTRACOPY
00347     ProxyResultVarsizeMsg *msg = ProxyResultVarsizeMsg::getANewMsg(CkMyPe(), patchID, PRIORITY_SIZE, f); 
00348 #else
00349     ProxyResultMsg *msg = new (PRIORITY_SIZE) ProxyResultMsg;    
00350     msg->node = CkMyPe();
00351     msg->patch = patchID;
00352     for ( i = 0; i < Results::maxNumForces; ++i ) 
00353       msg->forceList[i] = &(f[i]);
00354 #endif
00355     SET_PRIORITY(msg,flags.sequence,PROXY_RESULTS_PRIORITY + PATCH_PRIORITY(patchID));
00356     //sending results to HomePatch
00357     ProxyMgr::Object()->sendResults(msg);
00358   }
00359   else {
00360     ProxyCombinedResultMsg *msg = new (PRIORITY_SIZE) ProxyCombinedResultMsg;
00361     SET_PRIORITY(msg,flags.sequence,
00362                 PROXY_RESULTS_PRIORITY + PATCH_PRIORITY(patchID));
00363     msg->nodes.add(CkMyPe());
00364     msg->patch = patchID;
00365     for ( i = 0; i < Results::maxNumForces; ++i ) 
00366       msg->forceList[i] = &(f[i]);
00367     //sending results to HomePatch
00368     ProxyMgr::Object()->sendResults(msg);
00369   }
00370 #if CMK_PERSISTENT_COMM && USE_PERSISTENT_TREE
00371   CmiUsePersistentHandle(NULL, 0);
00372 #endif
00373 }
00374 
00375 #ifdef NODEAWARE_PROXY_SPANNINGTREE
00376 void ProxyPatch::setSpanningTree(int p, int *c, int n) { 
00377 #if CMK_PERSISTENT_COMM && USE_PERSISTENT_TREE && ! defined(USE_NODEPATCHMGR)
00378   if (ntreephs!=0) {
00379       for (int i=0; i<ntreephs; i++)  CmiDestoryPersistent(treephs[i]);
00380       delete [] treephs;
00381   }
00382   treephs = NULL;
00383   if (n) {
00384       treephs = new PersistentHandle[n];
00385       for (int i=0; i<n; i++) {
00386            treephs[i] = CmiCreatePersistent(c[i], 27000, sizeof(envelope)+sizeof(ProxyDataMsg));
00387       }
00388   }
00389   ntreephs = n;
00390 #endif
00391   parent=p; nChild = n; nWait = 0;
00392   delete [] child;
00393   if(n==0) {
00394       child = NULL;
00395       return;
00396   }
00397   child = new int[n];
00398   for (int i=0; i<n; i++) child[i] = c[i];
00399 
00400   #if defined(PROCTRACE_DEBUG) && defined(NAST_DEBUG)
00401     DebugFileTrace *dft = DebugFileTrace::Object();
00402     dft->openTrace();
00403     dft->writeTrace("ProxyPatch[%d] has %d children: ", patchID, nChild);
00404     for(int i=0; i<nChild; i++)
00405         dft->writeTrace("%d ", child[i]);
00406     dft->writeTrace("\n");
00407     dft->closeTrace();
00408   #endif
00409 //CkPrintf("setSpanningTree: [%d:%d] %d %d:%d %d\n", CkMyPe(), patchID, parent, nChild, child[0], child[1]);
00410 }
00411 
00412 #ifdef USE_NODEPATCHMGR
00413 void ProxyPatch::setSTNodeChildren(int numNids, int *nids){
00414 #if CMK_PERSISTENT_COMM && USE_PERSISTENT_TREE
00415   if (numNodeChild!=0) {
00416       for (int i=0; i<numNodeChild; i++)  CmiDestoryPersistent(treephs[i]);
00417       delete [] treephs;
00418   }
00419   treephs = NULL;
00420   if (numNids) {
00421       treephs = new PersistentHandle[numNids];
00422       for (int i=0; i<numNids; i++) {
00423            treephs[i] = CmiCreateNodePersistent(nids[i], 27000, sizeof(envelope)+sizeof(ProxyDataMsg));
00424       }
00425   }
00426   ntreephs = numNids;
00427 #endif
00428     numNodeChild = numNids;
00429     delete [] nodeChildren;
00430     if(numNids==0) {
00431         nodeChildren = NULL;
00432         return;
00433     }
00434     nodeChildren = new int[numNids];
00435     for(int i=0; i<numNids; i++) nodeChildren[i] = nids[i]; 
00436 }
00437 #endif
00438 
00439 #else //branch for NODEAWARE_PROXY_SPANNINGTREE not defined
00440 void ProxyPatch::setSpanningTree(int p, int *c, int n) { 
00441 #if CMK_PERSISTENT_COMM && USE_PERSISTENT_TREE
00442   if (ntreephs!=0) {
00443       for (int i=0; i<ntreephs; i++)  CmiDestoryPersistent(treephs[i]);
00444   }
00445   for (int i=0; i<n; i++) {
00446        treephs[i] = CmiCreatePersistent(c[i], 27000, sizeof(envelope)+sizeof(ProxyDataMsg));
00447   }
00448   ntreephs = n;
00449 #endif
00450   parent=p; nChild = n; nWait = 0;
00451   for (int i=0; i<n; i++) child[i] = c[i];
00452 //CkPrintf("setSpanningTree: [%d:%d] %d %d:%d %d\n", CkMyPe(), patchID, parent, nChild, child[0], child[1]);
00453 }
00454 #endif
00455 
00456 int ProxyPatch::getSpanningTreeChild(int *c) { 
00457   for (int i=0; i<nChild; i++) c[i] = child[i];
00458   return nChild;
00459 }
00460 
00461 ProxyCombinedResultMsg *ProxyPatch::depositCombinedResultMsg(ProxyCombinedResultMsg *msg) {
00462 #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR)
00463   CmiLock(depositLock);
00464 #endif
00465   nWait++;
00466   if (nWait == 1) msgCBuffer = msg;
00467   else {
00468     NodeIDList::iterator n_i, n_e;
00469     n_i = msg->nodes.begin();
00470     n_e = msg->nodes.end();
00471     for (; n_i!=n_e; ++n_i) msgCBuffer->nodes.add(*n_i);
00472     for ( int k = 0; k < Results::maxNumForces; ++k )
00473     {
00474     register ForceList::iterator r_i;
00475     r_i = msgCBuffer->forceList[k]->begin();
00476     register ForceList::iterator f_i, f_e;
00477     f_i = msg->forceList[k]->begin();
00478     f_e = msg->forceList[k]->end();
00479     //    for ( ; f_i != f_e; ++f_i, ++r_i ) *r_i += *f_i;
00480 
00481     int nf = f_e - f_i;
00482 #ifdef ARCH_POWERPC
00483 #pragma disjoint (*f_i, *r_i)
00484 #pragma unroll(4)
00485 #endif
00486     for (int count = 0; count < nf; count++) {
00487       r_i[count].x += f_i[count].x;      
00488       r_i[count].y += f_i[count].y;      
00489       r_i[count].z += f_i[count].z;
00490     }
00491 
00492     }
00493     delete msg;
00494   }
00495 //CkPrintf("[%d:%d] wait: %d of %d (%d %d %d)\n", CkMyPe(), patchID, nWait, nChild+1, parent, child[0],child[1]);
00496   if (nWait == nChild + 1) {
00497     nWait = 0;
00498 #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR)
00499     CmiUnlock(depositLock);
00500 #endif
00501     
00502     return msgCBuffer;
00503   }
00504 
00505 #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR)
00506   CmiUnlock(depositLock);
00507 #endif
00508 
00509   return NULL;
00510 }
00511 
00512 //receive data after phase 1 to begin phase 2
00513 void ProxyPatch::receiveData(ProxyGBISP2DataMsg *msg) {
00514   memcpy(bornRad.begin(), msg->bornRad, sizeof(Real)*numAtoms);
00515   delete msg;
00516   Patch::gbisP2Ready();
00517 }
00518 
00519 void ProxyPatch::receiveData(ProxyGBISP3DataMsg *msg) {
00520   memcpy(dHdrPrefix.begin(), msg->dHdrPrefix, sizeof(Real)*msg->dHdrPrefixLen);
00521   delete msg;
00522   Patch::gbisP3Ready();
00523 }
00524 
00525 ProxyCombinedResultMsg *ProxyPatch::depositCombinedResultRawMsg(ProxyCombinedResultRawMsg *msg) {
00526 #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR)
00527   CmiLock(depositLock);
00528 #endif
00529   nWait++;
00530   if (nWait == 1) msgCBuffer = ProxyCombinedResultMsg::fromRaw(msg);
00531   else {
00532     for (int i=0; i<msg->nodeSize; i++) msgCBuffer->nodes.add(msg->nodes[i]);
00533 
00534     register char* isNonZero = msg->isForceNonZero;
00535         register Force* f_i = msg->forceArr;
00536         for ( int k = 0; k < Results::maxNumForces; ++k )
00537     {
00538                 register ForceList::iterator r_i;
00539                 r_i = msgCBuffer->forceList[k]->begin();
00540         int nf = msg->flLen[k];
00541 
00542 #ifdef ARCH_POWERPC
00543 #pragma disjoint (*f_i, *r_i)
00544 #endif
00545                 for (int count = 0; count < nf; count++) {
00546                         if(*isNonZero){
00547                                 r_i[count].x += f_i->x;
00548                                 r_i[count].y += f_i->y;
00549                                 r_i[count].z += f_i->z;
00550                                 f_i++;
00551                         }
00552                         isNonZero++;
00553                 }
00554     }
00555     delete msg;
00556   }
00557 //CkPrintf("[%d:%d] wait: %d of %d (%d %d %d)\n", CkMyPe(), patchID, nWait, nChild+1, parent, child[0],child[1]);
00558   if (nWait == nChild + 1) {
00559     nWait = 0;
00560 #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR)
00561     CmiUnlock(depositLock);
00562 #endif
00563 
00564     return msgCBuffer;
00565   }
00566 
00567 #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR)
00568   CmiUnlock(depositLock);
00569 #endif
00570 
00571   return NULL;
00572 }
00573 
00574 
00575 

Generated on Sat Sep 23 01:17:15 2017 for NAMD by  doxygen 1.4.7