00001
00007
00008
00009
00010
00011
00012 #if !defined(WIN32) || defined(__CYGWIN__)
00013 #include <unistd.h>
00014 #endif
00015 #include "InfoStream.h"
00016 #include "Node.decl.h"
00017 #include "Node.h"
00018 #ifdef DPMTA
00019 #include <pvm3.h>
00020 #endif
00021
00022 #include "ProcessorPrivate.h"
00023
00024 #define MIN_DEBUG_LEVEL 3
00025
00026 #include "Debug.h"
00027
00028 #include <stdio.h>
00029 #include <converse.h>
00030 #include "memusage.h"
00031 #include "IMDOutput.h"
00032
00033 #ifdef USE_COMM_LIB
00034 #include "ComlibManager.h"
00035 #endif
00036
00037 #include "main.decl.h"
00038 #include "main.h"
00039 #include "WorkDistrib.h"
00040 #include "PatchMgr.h"
00041 #include "Patch.h"
00042 #include "Compute.h"
00043 #include "ComputeMap.h"
00044 #include "ComputeMgr.h"
00045 #include "Molecule.h"
00046 #include "HomePatchList.h"
00047 #include "AtomMap.h"
00048 #include "Sequencer.h"
00049 #include "Controller.h"
00050 #include "NamdState.h"
00051 #include "Output.h"
00052 #include "ProxyMgr.h"
00053 #include "PatchMap.h"
00054 #include "PatchMap.inl"
00055 #include "Parameters.h"
00056 #include "SimParameters.h"
00057 #include "Communicate.h"
00058 #include "LdbCoordinator.h"
00059 #include "ScriptTcl.h"
00060 #include "ComputeMgr.decl.h"
00061 #include "ComputePmeMgr.decl.h"
00062 #include "Sync.h"
00063 #include "BackEnd.h"
00064 #include "PDB.h"
00065
00066 #if(CMK_CCS_AVAILABLE && CMK_WEB_MODE)
00067 extern "C" void CApplicationInit();
00068 #endif
00069
00070 #include "DumpBench.h"
00071
00072 #ifdef MEM_OPT_VERSION
00073 #include "CollectionMgr.h"
00074 #include "CollectionMaster.h"
00075 #include "CollectionMgr.decl.h"
00076 #include "CollectionMaster.decl.h"
00077 #endif
00078
00079
00080
00081
00082
00083
00084 int eventEndOfTimeStep;
00085 double startupTime;
00086
00087
00088
00089 Node::Node(GroupInitMsg *msg)
00090 {
00091 DebugM(4,"Creating Node\n");
00092 #if(CMK_CCS_AVAILABLE && CMK_WEB_MODE)
00093 CApplicationInit();
00094 #endif
00095 if (CkpvAccess(Node_instance) == 0) {
00096 CkpvAccess(Node_instance) = this;
00097 eventEndOfTimeStep = traceRegisterUserEvent("EndOfTimeStep");
00098 } else {
00099 NAMD_bug("Node::Node() - another instance of Node exists!");
00100 }
00101
00102 CkpvAccess(BOCclass_group) = msg->group;
00103 delete msg;
00104
00105 CkpvAccess(BOCclass_group).node = thisgroup;
00106
00107 startupPhase = 0;
00108
00109 molecule = NULL;
00110 parameters = NULL;
00111 simParameters = NULL;
00112 configList = NULL;
00113 pdb = NULL;
00114 state = NULL;
00115 output = NULL;
00116 imd = new IMDOutput;
00117
00118 DebugM(4,"Creating PatchMap, AtomMap, ComputeMap\n");
00119 patchMap = PatchMap::Instance();
00120 atomMap = AtomMap::Instance();
00121 computeMap = ComputeMap::Instance();
00122
00123 DebugM(4,"Binding to BOC's\n");
00124 CProxy_PatchMgr pm(CkpvAccess(BOCclass_group).patchMgr);
00125 patchMgr = pm.ckLocalBranch();
00126 CProxy_ProxyMgr prm(CkpvAccess(BOCclass_group).proxyMgr);
00127 proxyMgr = prm.ckLocalBranch();
00128 CProxy_WorkDistrib wd(CkpvAccess(BOCclass_group).workDistrib);
00129 workDistrib = wd.ckLocalBranch();
00130 CProxy_ComputeMgr cm(CkpvAccess(BOCclass_group).computeMgr);
00131 computeMgr = cm.ckLocalBranch();
00132 CProxy_LdbCoordinator lc(CkpvAccess(BOCclass_group).ldbCoordinator);
00133 ldbCoordinator = lc.ckLocalBranch();
00134
00135 }
00136
00137
00138
00139
00140 Node::~Node(void)
00141 {
00142 delete output;
00143 delete computeMap;
00144 delete atomMap;
00145 delete patchMap;
00146 delete CkpvAccess(comm);
00147 }
00148
00149
00150
00151
00152 void Node::messageStartUp() {
00153 (CProxy_Node(CkpvAccess(BOCclass_group).node)).startup();
00154 }
00155
00156 void Node::startUp(CkQdMsg *qmsg) {
00157 delete qmsg;
00158 (CProxy_Node(CkpvAccess(BOCclass_group).node)).startup();
00159 }
00160
00161 SimParameters *node_simParameters;
00162 Parameters *node_parameters;
00163 Molecule *node_molecule;
00164
00165 extern void registerUserEventsForAllComputeObjs(void);
00166
00167 void Node::startup() {
00168 int gotoRun = false;
00169 double newTime;
00170
00171 if (!CkMyPe()) {
00172 if (!startupPhase) {
00173 iout << iINFO << "\n";
00174 startupTime = CmiWallTimer();
00175 iout << iINFO << "Entering startup at " << startupTime << " s, ";
00176 } else {
00177 newTime = CmiWallTimer();
00178 iout << iINFO << "Startup phase " << startupPhase-1 << " took "
00179 << newTime - startupTime << " s, ";
00180 startupTime = newTime;
00181 }
00182 iout << memusage_MB() << " MB of memory in use\n" << endi;
00183 fflush(stdout);
00184 }
00185
00186 switch (startupPhase) {
00187
00188 case 0:
00189 #ifdef CHARMIZE_NAMD
00190 populateAtomDisArrs(startupPhase);
00191 #endif
00192
00193 namdOneCommInit();
00194 break;
00195
00196 case 1:
00197
00198 if (CkMyPe()) {
00199 namdOneRecv();
00200 } else {
00201 namdOneSend();
00202 }
00203
00204 #ifdef CHARMIZE_NAMD
00205
00206 if(!CkMyPe()){
00207 AllCharmArrsMsg *arrsMsg = new AllCharmArrsMsg;
00208 arrsMsg->atomsDis = atomDisArr;
00209 ((CProxy_Node)thisgroup).sendCharmArrProxies(arrsMsg);
00210 }
00211 #endif
00212 break;
00213
00214 case 2:
00215
00216 simParameters = node_simParameters;
00217 parameters = node_parameters;
00218 molecule = node_molecule;
00219
00220 #ifdef MEM_OPT_VERSION
00221
00222 if(!CkMyPe()){
00223 CkChareID collectionMaster;
00224 if(CkNumPes()>1 && simParameters->shiftIOToOne)
00225 collectionMaster = CProxy_CollectionMaster::ckNew(1);
00226 else
00227 collectionMaster = CProxy_CollectionMaster::ckNew(0);
00228
00229
00230 CollectionMasterHandler::Object()->setRealMaster(collectionMaster);
00231 CProxy_CollectionMgr cmgr(CkpvAccess(BOCclass_group).collectionMgr);
00232 SlaveInitMsg *bcmaster = new SlaveInitMsg;
00233 bcmaster->master = collectionMaster;
00234 cmgr.setCollectionMaster(bcmaster);
00235 }
00236 #endif
00237
00238
00239 threadInit();
00240
00241
00242 AtomMap::Object()->allocateMap(molecule->numAtoms);
00243 break;
00244
00245 case 3:
00246 if(simParameters->isSendProxySTEnabled()) {
00247 ProxyMgr::Object()->setSendSpanning();
00248 }
00249 if(simParameters->isRecvProxySTEnabled()) {
00250 ProxyMgr::Object()->setRecvSpanning();
00251 }
00252 #ifdef PROCTRACE_DEBUG
00253 DebugFileTrace::Instance("procTrace");
00254 #endif
00255
00256 if (!CkMyPe()) {
00257 output = new Output;
00258 workDistrib->patchMapInit();
00259
00260 #ifdef MEM_OPT_VERSION
00261
00262 workDistrib->preCreateHomePatches();
00263 #else
00264 workDistrib->createHomePatches();
00265 #endif
00266
00267 workDistrib->assignNodeToPatch();
00268 workDistrib->mapComputes();
00269 ComputeMap::Object()->printComputeMap();
00270
00271 registerUserEventsForAllComputeObjs();
00272
00273 workDistrib->sendMaps();
00274 #ifdef USE_NODEPATCHMGR
00275 CProxy_NodeProxyMgr npm(CkpvAccess(BOCclass_group).nodeProxyMgr);
00276
00277 npm.createProxyInfo(PatchMap::Object()->numPatches());
00278 #endif
00279 }
00280 {
00281 #if defined(NODEAWARE_PROXY_SPANNINGTREE) && defined(USE_NODEPATCHMGR)
00282 CProxy_NodeProxyMgr npm(CkpvAccess(BOCclass_group).nodeProxyMgr);
00283 if(CkMyRank()==0) {
00284
00285 npm[CkMyNode()].ckLocalBranch()->registerLocalProxyMgr(CkpvAccess(BOCclass_group).proxyMgr);
00286 }
00287 npm[CkMyNode()].ckLocalBranch()->registerLocalPatchMap(CkMyRank(), PatchMap::Object());
00288 #endif
00289 }
00290 break;
00291
00292 case 4:
00293 if ( simParameters->PMEOn ) {
00294 CProxy_ComputePmeMgr pme(CkpvAccess(BOCclass_group).computePmeMgr);
00295 #if CHARM_VERSION > 050402
00296 pme[CkMyPe()].initialize(new CkQdMsg);
00297 #else
00298 pme.initialize(new CkQdMsg, CkMyPe());
00299 #endif
00300 }
00301 break;
00302
00303 case 5:
00304 if ( simParameters->PMEOn ) {
00305 CProxy_ComputePmeMgr pme(CkpvAccess(BOCclass_group).computePmeMgr);
00306 pme[CkMyPe()].initialize_pencils(new CkQdMsg);
00307 }
00308 if (!CkMyPe()) {
00309 #ifdef MEM_OPT_VERSION
00310 workDistrib->initAndSendHomePatch();
00311 #else
00312 workDistrib->distributeHomePatches();
00313 #endif
00314 }
00315 break;
00316
00317 case 6:
00318 if ( simParameters->PMEOn ) {
00319 CProxy_ComputePmeMgr pme(CkpvAccess(BOCclass_group).computePmeMgr);
00320 pme[CkMyPe()].activate_pencils(new CkQdMsg);
00321 }
00322 proxyMgr->createProxies();
00323 if (!CkMyPe()) LdbCoordinator::Object()->createLoadBalancer();
00324 break;
00325
00326 case 7:
00327 if (!CkMyPe()) {
00328 ComputeMap::Object()->printComputeMap();
00329 }
00330 Sync::Object()->openSync();
00331 if (proxySendSpanning || proxyRecvSpanning )
00332 proxyMgr->buildProxySpanningTree();
00333 DebugM(4,"Creating Computes\n");
00334 computeMgr->createComputes(ComputeMap::Object());
00335 DebugM(4,"Building Sequencers\n");
00336 buildSequencers();
00337 DebugM(4,"Initializing LDB\n");
00338 LdbCoordinator::Object()->initialize(patchMap,computeMap);
00339 break;
00340
00341 case 8:
00342 {
00343
00344
00345
00346
00347
00348
00349 }
00350 #ifdef MEM_OPT_VERSION
00351 if(!CkMyPe()){
00352 molecule->delEachAtomSigs();
00353 molecule->delChargeSpace();
00354 if(!simParameters->freeEnergyOn)
00355 molecule->delMassSpace();
00356 molecule->delOtherEachAtomStructs();
00357
00358
00359 pdb->delPDBCoreData();
00360 }
00361
00362
00363
00364 if(simParameters->wrapAll || simParameters->wrapWater){
00365 int peOfCollectionMaster = 0;
00366 if(CkNumPes()>1 && simParameters->shiftIOToOne) peOfCollectionMaster = 1;
00367 if(CkNumPes()>1 && CkMyPe()!=peOfCollectionMaster)
00368 molecule->delClusterSigs();
00369 }else{
00370 molecule->delClusterSigs();
00371 }
00372 #endif
00373 gotoRun = true;
00374 break;
00375
00376 default:
00377 NAMD_bug("Startup Phase has a bug - check case statement");
00378 break;
00379
00380 }
00381
00382 startupPhase++;
00383 if (!CkMyPe()) {
00384 if (!gotoRun) {
00385 #if CHARM_VERSION > 050402
00386 CkStartQD(CkIndex_Node::startUp((CkQdMsg*)0),&thishandle);
00387 #else
00388 CkStartQD(CProxy_Node::ckIdx_startUp((CkQdMsg*)0),&thishandle);
00389 #endif
00390 } else {
00391 Node::messageRun();
00392 }
00393 }
00394 }
00395
00396 void Node::namdOneCommInit()
00397 {
00398 if (CkpvAccess(comm) == NULL) {
00399 CkpvAccess(comm) = new Communicate();
00400 #ifdef DPMTA
00401 pvmc_init();
00402 #endif
00403 }
00404 }
00405
00406 #ifdef CHARMIZE_NAMD
00407
00408 void Node::populateAtomDisArrs(int startupPhase){
00409 if(CkMyPe()) return;
00410 if(startupPhase) return;
00411
00412 int disArrSize = molecule->numAtoms/AtomsDisInfo::ATOMDISNUM;
00413 int remainAtoms = molecule->numAtoms%AtomsDisInfo::ATOMDISNUM;
00414
00415 int totalArrSize = disArrSize + (remainAtoms!=0);
00416 atomDisArr = CProxy_AtomsDisInfo::ckNew(totalArrSize);
00417
00418 int atomIndex = 0;
00419 Atom *allAtoms = molecule->getAllAtoms();
00420 for(int i=0; i<totalArrSize; i++){
00421 int actualAtomCnt = AtomsDisInfo::ATOMDISNUM;
00422 if(i==disArrSize) actualAtomCnt = remainAtoms;
00423
00424 AtomStaticInfoMsg *staticMsg = new(actualAtomCnt, 0)AtomStaticInfoMsg;
00425 staticMsg->actualNumAtoms = actualAtomCnt;
00426 for(int j=0; j<actualAtomCnt; j++, atomIndex++){
00427 staticMsg->atoms[j] = allAtoms[atomIndex];
00428 }
00429 atomDisArr[i].recvStaticInfo(staticMsg);
00430 }
00431 }
00432 #endif
00433
00434
00435
00436 void Node::namdOneRecv() {
00437 if ( CmiMyRank() ) return;
00438
00439 MIStream *conv_msg;
00440
00441
00442 simParameters = node_simParameters = new SimParameters;
00443
00444 parameters = node_parameters = new Parameters();
00445
00446 molecule = node_molecule = new Molecule(simParameters,parameters);
00447
00448 DebugM(4, "Getting SimParameters\n");
00449 conv_msg = CkpvAccess(comm)->newInputStream(0, SIMPARAMSTAG);
00450 simParameters->receive_SimParameters(conv_msg);
00451
00452 DebugM(4, "Getting Parameters\n");
00453 conv_msg = CkpvAccess(comm)->newInputStream(0, STATICPARAMSTAG);
00454 parameters->receive_Parameters(conv_msg);
00455
00456 DebugM(4, "Getting Molecule\n");
00457 conv_msg = CkpvAccess(comm)->newInputStream(0, MOLECULETAG);
00458 molecule->receive_Molecule(conv_msg);
00459
00460 DebugM(4, "Done Receiving\n");
00461 }
00462
00463 void Node::namdOneSend() {
00464 node_simParameters = simParameters;
00465 node_parameters = parameters;
00466 node_molecule = molecule;
00467
00468
00469 DebugM(4, "Sending SimParameters\n");
00470 simParameters->send_SimParameters(CkpvAccess(comm));
00471 DebugM(4, "Sending Parameters\n");
00472 parameters->send_Parameters(CkpvAccess(comm));
00473 DebugM(4, "Sending Molecule\n");
00474 molecule->send_Molecule(CkpvAccess(comm));
00475 }
00476
00477 void Node::sendCharmArrProxies(AllCharmArrsMsg *msg){
00478 #ifdef CHARMIZE_NAMD
00479 if(CkMyPe()){
00480 atomDisArr = msg->atomsDis;
00481 }
00482 delete msg;
00483 #else
00484 NAMD_die("sendCharmArrProxies should not be called in this case!");
00485 #endif
00486 }
00487
00488
00489
00490 void Node::threadInit() {
00491
00492 if (CthImplemented()) {
00493 CthSetStrategyDefault(CthSelf());
00494 } else {
00495 NAMD_bug("Node::startup() Oh no, tiny elvis, threads not implemented");
00496 }
00497 }
00498
00499
00500 void Node::buildSequencers() {
00501 HomePatchList *hpl = PatchMap::Object()->homePatchList();
00502 ResizeArrayIter<HomePatchElem> ai(*hpl);
00503
00504
00505 if ( ! CkMyPe() ) {
00506 Controller *controller = new Controller(state);
00507 state->useController(controller);
00508 }
00509
00510
00511 for (ai=ai.begin(); ai != ai.end(); ai++) {
00512 HomePatch *patch = (*ai).patch;
00513 Sequencer *sequencer = new Sequencer(patch);
00514 patch->useSequencer(sequencer);
00515 }
00516 }
00517
00518
00519
00520
00521
00522
00523 void Node::messageRun() {
00524 (CProxy_Node(CkpvAccess(BOCclass_group).node)).run();
00525 }
00526
00527
00528
00529
00530
00531
00532 void Node::run()
00533 {
00534
00535 if ( ! CkMyPe() ) {
00536 state->runController();
00537 }
00538
00539 DebugM(4, "Starting Sequencers\n");
00540
00541 HomePatchList *hpl = PatchMap::Object()->homePatchList();
00542 ResizeArrayIter<HomePatchElem> ai(*hpl);
00543 for (ai=ai.begin(); ai != ai.end(); ai++) {
00544 HomePatch *patch = (*ai).patch;
00545 patch->runSequencer();
00546 }
00547
00548 if (!CkMyPe()) {
00549 double newTime = CmiWallTimer();
00550 iout << iINFO << "Startup phase " << startupPhase-1 << " took "
00551 << newTime - startupTime << " s, "
00552 << memusage_MB() << " MB of memory in use\n";
00553 iout << iINFO << "Finished startup at " << newTime << " s, "
00554 << memusage_MB() << " MB of memory in use\n\n" << endi;
00555 fflush(stdout);
00556 }
00557
00558 }
00559
00560
00561
00562
00563
00564
00565 void Node::enableScriptBarrier() {
00566 #if CHARM_VERSION > 050402
00567 CkStartQD(CkIndex_Node::scriptBarrier((CkQdMsg*)0),&thishandle);
00568 #else
00569 CkStartQD(CProxy_Node::ckIdx_scriptBarrier((CkQdMsg*)0),&thishandle);
00570 #endif
00571 }
00572
00573 void Node::scriptBarrier(CkQdMsg *qmsg) {
00574 delete qmsg;
00575
00576 }
00577
00578 void Node::scriptParam(ScriptParamMsg *msg) {
00579 simParameters->scriptSet(msg->param,msg->value);
00580 delete msg;
00581 }
00582
00583 void Node::reloadCharges(const char *filename) {
00584 FILE *file = fopen(filename,"r");
00585 if ( ! file ) NAMD_die("node::reloadCharges():Error opening charge file.");
00586
00587 int n = molecule->numAtoms;
00588 float *charge = new float[n];
00589
00590 for ( int i = 0; i < n; ++i ) {
00591 if ( ! fscanf(file,"%f",&charge[i]) )
00592 NAMD_die("Node::reloadCharges():Not enough numbers in charge file.");
00593 }
00594
00595 fclose(file);
00596 CProxy_Node(thisgroup).reloadCharges(charge,n);
00597 delete [] charge;
00598 }
00599
00600 void Node::reloadCharges(float charge[], int n) {
00601 molecule->reloadCharges(charge,n);
00602 }
00603
00604
00605 void Node::sendEnableExitScheduler(void) {
00606
00607 CkQdMsg *msg = new CkQdMsg;
00608 #if CHARM_VERSION > 050402
00609 CProxy_Node nodeProxy(thisgroup);
00610 nodeProxy[0].recvEnableExitScheduler(msg);
00611 #else
00612 CProxy_Node(thisgroup).recvEnableExitScheduler(msg,0);
00613 #endif
00614 }
00615
00616 void Node::recvEnableExitScheduler(CkQdMsg *msg) {
00617
00618 delete msg;
00619 enableExitScheduler();
00620 }
00621
00622 void Node::enableExitScheduler(void) {
00623 if ( CkMyPe() ) {
00624 sendEnableExitScheduler();
00625 } else {
00626 #if CHARM_VERSION > 050402
00627 CkStartQD(CkIndex_Node::exitScheduler((CkQdMsg*)0),&thishandle);
00628 #else
00629 CkStartQD(CProxy_Node::ckIdx_exitScheduler((CkQdMsg*)0),&thishandle);
00630 #endif
00631 }
00632 }
00633
00634 void Node::exitScheduler(CkQdMsg *msg) {
00635
00636 CsdExitScheduler();
00637 delete msg;
00638 }
00639
00640 void Node::sendEnableEarlyExit(void) {
00641 CkQdMsg *msg = new CkQdMsg;
00642 #if CHARM_VERSION > 050402
00643 CProxy_Node nodeProxy(thisgroup);
00644 nodeProxy[0].recvEnableEarlyExit(msg);
00645 #else
00646 CProxy_Node(thisgroup).recvEnableEarlyExit(msg,0);
00647 #endif
00648 }
00649
00650 void Node::recvEnableEarlyExit(CkQdMsg *msg) {
00651 delete msg;
00652 enableEarlyExit();
00653 }
00654
00655 void Node::enableEarlyExit(void) {
00656 if ( CkMyPe() ) {
00657 sendEnableEarlyExit();
00658 } else {
00659 #if CHARM_VERSION > 050402
00660 CkStartQD(CkIndex_Node::earlyExit((CkQdMsg*)0),&thishandle);
00661 #else
00662 CkStartQD(CProxy_Node::ckIdx_earlyExit((CkQdMsg*)0),&thishandle);
00663 #endif
00664 }
00665 }
00666
00667 void Node::earlyExit(CkQdMsg *msg) {
00668 iout << iERROR << "Exiting prematurely.\n" << endi;
00669 BackEnd::exit();
00670 delete msg;
00671 }
00672
00673
00674
00675
00676
00677 void Node::saveMolDataPointers(NamdState *state)
00678 {
00679 this->molecule = state->molecule;
00680 this->parameters = state->parameters;
00681 this->simParameters = state->simParameters;
00682 this->configList = state->configList;
00683 this->pdb = state->pdb;
00684 this->state = state;
00685 }
00686
00687
00688
00689
00690
00691 #include "Node.def.h"
00692