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

Node.C

Go to the documentation of this file.
00001 
00007 /*
00008    Toplevel routines for initializing a Node for a simulation
00009    one Node per Pe (processor element).
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 //#define DEBUGM
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 // Public Functions
00081 
00082 //----------------------------------------------------------------------
00083 
00084 int eventEndOfTimeStep;
00085 double startupTime;
00086 
00087 //----------------------------------------------------------------------
00088 // BOC constructor
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 // ~Node(void) needs to clean up everything.
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 // Startup Sequence
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(); // Namd1.X style
00194   break;
00195 
00196   case 1:
00197     // send & receive molecule, simparameters... (Namd1.X style)
00198     if (CkMyPe()) {
00199       namdOneRecv();
00200     } else {
00201       namdOneSend();
00202     }
00203 
00204     #ifdef CHARMIZE_NAMD
00205     //send charm array proxies
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     // fix up one-per-node objects
00216     simParameters = node_simParameters;
00217     parameters = node_parameters;
00218     molecule = node_molecule;
00219 
00220     #ifdef MEM_OPT_VERSION
00221     //Allocate CollectionMaster which handles I/O depending on the shiftIOToOne parameter
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         //set CollectionMgr and CollectionMasterHandler's field for CollectionMaster
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     // take care of inital thread setting
00239     threadInit();
00240 
00241     // create blank AtomMap
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; // create output object just on PE(0)
00258       workDistrib->patchMapInit(); // create space division
00259 
00260       #ifdef MEM_OPT_VERSION
00261       //create patches without populating them with atoms
00262       workDistrib->preCreateHomePatches();
00263       #else      
00264       workDistrib->createHomePatches(); // load atoms into HomePatch(es)
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       //a node broadcast
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             //just need to register once
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();  // need Home patches before this
00323     if (!CkMyPe()) LdbCoordinator::Object()->createLoadBalancer();
00324   break;
00325 
00326   case 7:
00327     if (!CkMyPe()) {
00328       ComputeMap::Object()->printComputeMap();
00329     }
00330     Sync::Object()->openSync();  // decide if to open local Sync 
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         //For debugging
00344         /*if(!CkMyPe()){
00345         FILE *dumpFile = fopen("/tmp/NAMD_Bench.dump", "w");
00346         dumpbench(dumpFile);
00347         NAMD_die("Normal execution\n");
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         //we can free the pdb data here to save memory because output
00358         //is always in the binary format thus saving 3 doubles * numAtoms bytes.
00359         pdb->delPDBCoreData();
00360     }
00361     //decide whether to free memory space for cluster information
00362     //the condition could be referred to comment for function
00363     //wrap_coor_int in Output.C
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 //It is only executed on pe(0) and called at startup phase 0
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 // Namd 1.X style Send/Recv of simulation information
00435 
00436 void Node::namdOneRecv() {
00437   if ( CmiMyRank() ) return;
00438 
00439   MIStream *conv_msg;
00440 
00441   // Receive molecule and simulation parameter information
00442   simParameters = node_simParameters = new SimParameters;
00443   //****** BEGIN CHARMM/XPLOR type changes
00444   parameters = node_parameters = new Parameters();
00445   //****** END CHARMM/XPLOR type changes
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   // I'm Pe(0) so I send what I know
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 // Initial thread setup
00489 
00490 void Node::threadInit() {
00491   // Thread initialization
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   // Controller object is only on Pe(0)
00505   if ( ! CkMyPe() ) {
00506     Controller *controller = new Controller(state);
00507     state->useController(controller);
00508   }
00509 
00510   // Assign Sequencer to all HomePatch(es)
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 // Node run() - broadcast to all nodes
00522 //-----------------------------------------------------------------------
00523 void Node::messageRun() {
00524   (CProxy_Node(CkpvAccess(BOCclass_group).node)).run();
00525 }
00526 
00527 
00528 //-----------------------------------------------------------------------
00529 // run(void) runs the specified simulation for the specified number of
00530 // steps, overriding the contents of the configuration file
00531 //-----------------------------------------------------------------------
00532 void Node::run()
00533 {
00534   // Start Controller (aka scalar Sequencer) on Pe(0)
00535   if ( ! CkMyPe() ) {
00536     state->runController();
00537   }
00538 
00539   DebugM(4, "Starting Sequencers\n");
00540   // Run Sequencer on each HomePatch - i.e. start simulation
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 // Node scriptBarrier() - twiddle parameters with simulation halted
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   //script->awaken();
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   //CmiPrintf("sendEnableExitScheduler\n");
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   //CmiPrintf("recvEnableExitScheduler\n");
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   //CmiPrintf("exitScheduler %d\n",CkMyPe());
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 // Some odd utilities
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 // Private functions
00689 
00690 
00691 #include "Node.def.h"
00692 

Generated on Wed Oct 15 04:07:43 2008 for NAMD by  doxygen 1.3.9.1