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

BackEnd.C

Go to the documentation of this file.
00001 
00007 #include "BackEnd.h"
00008 #include "ProcessorPrivate.h"
00009 #include "common.h"
00010 #include "Node.h"
00011 #include "memusage.h"
00012 
00013 #include <new>
00014 #if defined(WIN32) && !defined(__CYGWIN__)
00015 #include <new.h>
00016 #endif
00017 
00018 #include "Lattice.h"
00019 #include "ComputeMsm.h"  // needed for MsmData definition
00020 #include "main.decl.h"
00021 #include "main.h"
00022 #include "BOCgroup.h"
00023 #include "WorkDistrib.decl.h"
00024 #include "ProxyMgr.decl.h"
00025 #include "PatchMgr.decl.h"
00026 #ifdef CHARM_HAS_MSA
00027 #include "ComputeMgr.decl.h"
00028 #endif
00029 #include "ReductionMgr.decl.h"
00030 #include "CollectionMgr.decl.h"
00031 #include "CollectionMaster.decl.h"
00032 #include "CollectionMgr.h"
00033 #include "CollectionMaster.h"
00034 #include "BroadcastMgr.decl.h"
00035 #include "LdbCoordinator.decl.h"
00036 #include "Sync.decl.h"
00037 
00038 #ifdef MEM_OPT_VERSION
00039 #include "ParallelIOMgr.decl.h"
00040 #endif
00041 
00042 extern void _initCharm(int, char**);
00043 
00044 float cpuTime_start;
00045 float wallTime_start;
00046 
00047 CkpvStaticDeclare(int,exitSchedHndlr);
00048 
00049 extern "C" void exit_sched(void* msg)
00050 {
00051   //  CmiPrintf("Exiting scheduler on %d\n",CmiMyPe());
00052   CsdExitScheduler();
00053 }
00054 
00055 static void register_exit_sched(void)
00056 {
00057   CkpvInitialize(int,exitSchedHndlr);
00058   CkpvAccess(exitSchedHndlr) = CmiRegisterHandler((CmiHandler)exit_sched);
00059 }
00060 
00061 void BackEnd::ExitSchedOn(int pe)
00062 {
00063   void* msg = CmiAlloc(CmiMsgHeaderSizeBytes);
00064   CmiSetHandler(msg,CkpvAccess(exitSchedHndlr));
00065   CmiSyncSendAndFree(pe,CmiMsgHeaderSizeBytes,(char *)msg);
00066 }
00067 
00068 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW_H)
00069 int NAMD_new_handler(size_t) {
00070 #else
00071 void NAMD_new_handler() {
00072 #endif
00073   char tmp[100];
00074   sprintf(tmp,"Memory allocation failed on processor %d.",CmiMyPe());
00075   NAMD_die(tmp);
00076 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW_H)
00077   return 0;
00078 #endif
00079 }
00080 
00081 void cuda_getargs(char**);
00082 void cuda_initialize();
00083 
00084 // called on all procs
00085 void all_init(int argc, char **argv)
00086 {
00087 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW_H)
00088   _set_new_handler(NAMD_new_handler);
00089 #else
00090   std::set_new_handler(NAMD_new_handler);
00091 #endif
00092   ProcessorPrivateInit();
00093   register_exit_sched();
00094 #ifdef NAMD_CUDA
00095   CmiGetArgFlag(argv, "+idlepoll");  // remove +idlepoll if it's still there
00096   cuda_getargs(argv);
00097   argc = CmiGetArgc(argv);
00098 #endif
00099   
00100   _initCharm(argc, argv);  // message main Chare
00101 
00102 #ifdef NAMD_CUDA
00103   if ( CkMyPe() < CkNumPes() ) cuda_initialize();
00104 #endif
00105 }
00106 
00107 extern void after_backend_init(int argc, char **argv);
00108 void master_init(int argc, char **argv);
00109 
00110 // called on slave procs
00111 void slave_init(int argc, char **argv)
00112 {
00113 #if CMK_SMP
00114   //the original main thread could now be a comm thread
00115   //and a slave thread could now be the main thread,
00116   //so we have to do the master initialization here
00117   if(CmiMyRank()==0){
00118     master_init(argc, argv);
00119     if(CmiMyPe()==0)
00120       after_backend_init(argc, argv);
00121     return;
00122   }
00123 #endif
00124 
00125   all_init(argc, argv);
00126 
00127   if (CkMyRank() < CkMyNodeSize())      // skip the communication thread
00128     CsdScheduler(-1);
00129 }
00130 
00131 void master_init(int argc, char **argv){
00132   cpuTime_start = CmiCpuTimer();
00133   wallTime_start = CmiWallTimer();
00134   if ( CmiMyPe() ) {
00135     all_init(argc, argv);
00136     CsdScheduler(-1);
00137     ConverseExit();  // should never return
00138   }
00139 
00140   all_init(argc, argv);
00141 
00142   // Create branch-office chares
00143   BOCgroup group;
00144   group.workDistrib = CProxy_WorkDistrib::ckNew();
00145   group.proxyMgr = CProxy_ProxyMgr::ckNew();
00146   group.patchMgr = CProxy_PatchMgr::ckNew();
00147   group.computeMgr = CProxy_ComputeMgr::ckNew();
00148   group.reductionMgr = CProxy_ReductionMgr::ckNew();
00149   // group.computePmeMgr set in constructor during startup
00150   group.nodePmeMgr = CProxy_NodePmeMgr::ckNew();
00151   group.computeExtMgr = CProxy_ComputeExtMgr::ckNew();
00152   group.computeGBISserMgr = CProxy_ComputeGBISserMgr::ckNew();
00153   group.computeMsmSerialMgr = CProxy_ComputeMsmSerialMgr::ckNew();
00154 #ifdef CHARM_HAS_MSA
00155   group.computeMsmMgr = CProxy_ComputeMsmMgr::ckNew();
00156 #endif
00157 #ifdef MEM_OPT_VERSION
00158   group.ioMgr=CProxy_ParallelIOMgr::ckNew();
00159 #endif
00160 
00161   group.sync = CProxy_Sync::ckNew();
00162 
00163   #ifdef USE_NODEPATCHMGR
00164   group.nodeProxyMgr = CProxy_NodeProxyMgr::ckNew();
00165   #endif 
00166 
00167   CkChareID collectionMaster = CProxy_CollectionMaster::ckNew(0);  
00168   SlaveInitMsg *initmsg7 = new SlaveInitMsg;
00169   initmsg7->master = collectionMaster;
00170   group.collectionMgr = CProxy_CollectionMgr::ckNew(initmsg7);
00171 
00172   group.broadcastMgr = CProxy_BroadcastMgr::ckNew();
00173   group.ldbCoordinator = CProxy_LdbCoordinator::ckNew();
00174   GroupInitMsg *msg = new GroupInitMsg;
00175   msg->group = group;
00176   CProxy_Node::ckNew(msg);
00177  
00178 }
00179 
00180 char *gNAMDBinaryName = NULL;
00181 // called by main on one or all procs
00182 void BackEnd::init(int argc, char **argv) {
00183 
00184   gNAMDBinaryName = argv[0]+strlen(argv[0])-1;
00185   while(gNAMDBinaryName != argv[0]){
00186     if(*gNAMDBinaryName=='/' || *gNAMDBinaryName=='\\'){
00187       gNAMDBinaryName++;
00188       break;
00189     }
00190     gNAMDBinaryName--;
00191   }
00192 
00193 #ifdef NAMD_CUDA
00194   // look for but don't remove +idlepoll on command line
00195   int idlepoll = 0;
00196   for ( int i = 0; i < argc; ++i ) {
00197     if ( 0==strcmp(argv[i],"+idlepoll") ) {
00198       idlepoll = 1;
00199       break;
00200     }
00201   }
00202 #endif
00203 
00204   ConverseInit(argc, argv, slave_init, 1, 1);  // calls slave_init on others
00205 
00206 #if defined(NAMD_CUDA) && CMK_NET_VERSION
00207   if ( ! idlepoll ) {
00208     NAMD_die("Please add +idlepoll to command line for proper performance.");
00209   }
00210 #endif
00211 
00212   master_init(argc, argv);
00213 }
00214 
00215 // called on proc 0 by front end
00216 void BackEnd::exit(void) {
00217   float cpuTime = CmiCpuTimer() - cpuTime_start;
00218   float wallTime = CmiWallTimer() - wallTime_start;
00219   CmiPrintf("====================================================\n\n"
00220             "WallClock: %f  CPUTime: %f  Memory: %f MB\n",
00221             wallTime, cpuTime, memusage_MB());
00222   int i;
00223   for(i=1; i < CmiNumPes(); i++)
00224     ExitSchedOn(i);
00225   ConverseExit();
00226 }
00227 
00228 // start scheduler
00229 void BackEnd::suspend(void) {
00230   CsdScheduler(-1);
00231 }
00232 
00233 // start quiescence detection to return to front end
00234 void BackEnd::awaken(void) {
00235   Node::Object()->enableExitScheduler();
00236 }
00237 
00238 // start QD and scheduler
00239 void BackEnd::barrier(void) {
00240   awaken();
00241   suspend();
00242 }
00243 

Generated on Sun Feb 12 04:07:52 2012 for NAMD by  doxygen 1.3.9.1