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