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 "ComputeMoa.h" 
00020 #include "ComputeMsmMsa.h"  // needed for MsmMsaData definition
00021 #include "main.decl.h"
00022 #include "main.h"
00023 #include "BOCgroup.h"
00024 #include "WorkDistrib.decl.h"
00025 #include "ProxyMgr.decl.h"
00026 #include "PatchMgr.decl.h"
00027 #include "DataExchanger.decl.h"
00028 #ifdef CHARM_HAS_MSA
00029 #include "ComputeMgr.decl.h"
00030 #endif
00031 #include "ReductionMgr.decl.h"
00032 #include "CollectionMgr.decl.h"
00033 #include "CollectionMaster.decl.h"
00034 #include "CollectionMgr.h"
00035 #include "CollectionMaster.h"
00036 #include "BroadcastMgr.decl.h"
00037 #include "LdbCoordinator.decl.h"
00038 #include "Sync.decl.h"
00039 
00040 #ifdef MEM_OPT_VERSION
00041 #include "ParallelIOMgr.decl.h"
00042 #endif
00043 
00044 #ifdef NAMD_TCL
00045 #include <tcl.h>
00046 #endif
00047 
00048 extern void _initCharm(int, char**);
00049 
00050 float cpuTime_start;
00051 float wallTime_start;
00052 
00053 CkpvStaticDeclare(int,exitSchedHndlr);
00054 
00055 extern "C" void exit_sched(void* msg)
00056 {
00057   //  CmiPrintf("Exiting scheduler on %d\n",CmiMyPe());
00058   CsdExitScheduler();
00059 }
00060 
00061 static void register_exit_sched(void)
00062 {
00063   CkpvInitialize(int,exitSchedHndlr);
00064   CkpvAccess(exitSchedHndlr) = CmiRegisterHandler((CmiHandler)exit_sched);
00065 }
00066 
00067 void BackEnd::ExitSchedOn(int pe)
00068 {
00069   void* msg = CmiAlloc(CmiMsgHeaderSizeBytes);
00070   CmiSetHandler(msg,CkpvAccess(exitSchedHndlr));
00071   CmiSyncSendAndFree(pe,CmiMsgHeaderSizeBytes,(char *)msg);
00072 }
00073 
00074 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW_H)
00075 int NAMD_new_handler(size_t) {
00076 #else
00077 void NAMD_new_handler() {
00078 #endif
00079   char tmp[100];
00080   sprintf(tmp,"Memory allocation failed on processor %d.",CmiMyPe());
00081   NAMD_die(tmp);
00082 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW_H)
00083   return 0;
00084 #endif
00085 }
00086 
00087 void topo_getargs(char**);
00088 void cuda_getargs(char**);
00089 // void cuda_initialize();
00090 void mic_getargs(char**);
00091 // void mic_initialize();
00092 
00093 // called on all procs
00094 void all_init(int argc, char **argv)
00095 {
00096 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW_H)
00097   _set_new_handler(NAMD_new_handler);
00098 #else
00099   std::set_new_handler(NAMD_new_handler);
00100 #endif
00101   ProcessorPrivateInit();
00102   register_exit_sched();
00103   CmiGetArgFlag(argv, "+idlepoll");  // remove +idlepoll if it's still there
00104   topo_getargs(argv);
00105 #ifdef NAMD_CUDA
00106   cuda_getargs(argv);
00107   argc = CmiGetArgc(argv);
00108 #endif
00109 #ifdef NAMD_MIC
00110   CmiGetArgFlag(argv, "+idlepoll");  // remove +idlepoll if it's still there
00111   mic_getargs(argv);
00112   argc = CmiGetArgc(argv);
00113 #endif
00114   
00115   _initCharm(argc, argv);  // message main Chare
00116 
00117 //#if 0  // moved to WorkDistrib
00118 //#ifdef NAMD_CUDA
00119 //  if ( CkMyPe() < CkNumPes() ) cuda_initialize();
00120 //#endif
00121 //#ifdef NAMD_MIC
00122 //  if ( CkMyPe() < CkNumPes() ) mic_initialize();
00123 //#endif
00124 //#endif
00125 }
00126 
00127 extern void after_backend_init(int argc, char **argv);
00128 void master_init(int argc, char **argv);
00129 
00130 // called on slave procs
00131 void slave_init(int argc, char **argv)
00132 {
00133 #if CMK_SMP
00134   //the original main thread could now be a comm thread
00135   //and a slave thread could now be the main thread,
00136   //so we have to do the master initialization here
00137   if(CmiMyRank()==0){
00138     master_init(argc, argv);
00139     if(CmiMyPe()==0)
00140       after_backend_init(argc, argv);
00141     return;
00142   }
00143 #endif
00144 
00145   all_init(argc, argv);
00146 
00147   if (CkMyRank() < CkMyNodeSize())      // skip the communication thread
00148     CsdScheduler(-1);
00149 }
00150 
00151 void master_init(int argc, char **argv){
00152   cpuTime_start = CmiCpuTimer();
00153   wallTime_start = CmiWallTimer();
00154   if ( CmiMyPe() ) {
00155     all_init(argc, argv);
00156     CsdScheduler(-1);
00157     ConverseExit();  // should never return
00158   }
00159 
00160   all_init(argc, argv);
00161 
00162   // Create branch-office chares
00163   BOCgroup group;
00164   group.workDistrib = CProxy_WorkDistrib::ckNew();
00165   group.proxyMgr = CProxy_ProxyMgr::ckNew();
00166   group.patchMgr = CProxy_PatchMgr::ckNew();
00167   group.computeMgr = CProxy_ComputeMgr::ckNew();
00168   group.reductionMgr = CProxy_ReductionMgr::ckNew();
00169   // group.computePmeMgr set in constructor during startup
00170   group.nodePmeMgr = CProxy_NodePmeMgr::ckNew();
00171 #ifdef NAMD_CUDA
00172   group.computePmeCUDAMgr = CProxy_ComputePmeCUDAMgr::ckNew();
00173   group.computeCUDAMgr = CProxy_ComputeCUDAMgr::ckNew();
00174 #endif
00175 #ifdef OPENATOM_VERSION
00176   group.computeMoaMgr = CProxy_ComputeMoaMgr::ckNew();
00177 #endif // OPENATOM_VERSION
00178   group.computeExtMgr = CProxy_ComputeExtMgr::ckNew();
00179   group.computeQMMgr = CProxy_ComputeQMMgr::ckNew();
00180   group.computeGBISserMgr = CProxy_ComputeGBISserMgr::ckNew();
00181   group.computeFmmSerialMgr = CProxy_ComputeFmmSerialMgr::ckNew();
00182   group.computeMsmSerialMgr = CProxy_ComputeMsmSerialMgr::ckNew();
00183 #ifdef CHARM_HAS_MSA
00184   group.computeMsmMsaMgr = CProxy_ComputeMsmMsaMgr::ckNew();
00185 #endif
00186   group.computeMsmMgr = CProxy_ComputeMsmMgr::ckNew();
00187   // Charm CkMulticast library module
00188   group.multicastMgr = CProxy_CkMulticastMgr::ckNew();
00189 #ifdef MEM_OPT_VERSION
00190   group.ioMgr=CProxy_ParallelIOMgr::ckNew();
00191 #endif
00192 
00193   group.sync = CProxy_Sync::ckNew();
00194 
00195   #ifdef USE_NODEPATCHMGR
00196   group.nodeProxyMgr = CProxy_NodeProxyMgr::ckNew();
00197   #endif
00198   
00199 #if     CMK_SMP && USE_CKLOOP
00200   group.ckLoop = CkLoop_Init();
00201 #endif
00202 
00203   CkChareID collectionMaster = CProxy_CollectionMaster::ckNew(0);  
00204   SlaveInitMsg *initmsg7 = new SlaveInitMsg;
00205   initmsg7->master = collectionMaster;
00206   group.collectionMgr = CProxy_CollectionMgr::ckNew(initmsg7);
00207 
00208   group.broadcastMgr = CProxy_BroadcastMgr::ckNew();
00209   group.ldbCoordinator = CProxy_LdbCoordinator::ckNew();
00210 
00211   group.dataExchanger = CProxy_DataExchanger::ckNew();
00212 
00213   GroupInitMsg *msg = new GroupInitMsg;
00214   msg->group = group;
00215   CkGroupID node = CProxy_Node::ckNew(msg);
00216  
00217   CkStartQD(CkCallback(CkIndex_Node::exitScheduler((CkQdMsg*)0), CkMyPe(), node));
00218   CsdScheduler(-1);
00219 }
00220 
00221 char *gNAMDBinaryName = NULL;
00222 // called by main on one or all procs
00223 void BackEnd::init(int argc, char **argv) {
00224 
00225   gNAMDBinaryName = argv[0]+strlen(argv[0])-1;
00226   while(gNAMDBinaryName != argv[0]){
00227     if(*gNAMDBinaryName=='/' || *gNAMDBinaryName=='\\'){
00228       gNAMDBinaryName++;
00229       break;
00230     }
00231     gNAMDBinaryName--;
00232   }
00233 
00234 #if defined(NAMD_CUDA) || defined(NAMD_MIC)
00235   // look for but don't remove +idlepoll on command line
00236   int idlepoll = 0;
00237   for ( int i = 0; i < argc; ++i ) {
00238     if ( 0==strcmp(argv[i],"+idlepoll") ) {
00239       idlepoll = 1;
00240       break;
00241     }
00242   }
00243 #endif
00244 
00245   ConverseInit(argc, argv, slave_init, 1, 1);  // calls slave_init on others
00246 
00247 // idlepoll only matters for non-smp UDP layer
00248 #if (defined(NAMD_CUDA) || defined(NAMD_MIC)) && CMK_NET_VERSION && CMK_SHARED_VARS_UNAVAILABLE && CMK_WHEN_PROCESSOR_IDLE_USLEEP && ! CMK_USE_IBVERBS && ! CMK_USE_TCP
00249   if ( ! idlepoll ) {
00250     NAMD_die("Please add +idlepoll to command line for proper performance.");
00251   }
00252 #endif
00253 
00254   master_init(argc, argv);
00255 }
00256 
00257 void cuda_finalize();
00258 
00259 // called on proc 0 by front end
00260 void BackEnd::exit(void) {
00261   float cpuTime = CmiCpuTimer() - cpuTime_start;
00262   float wallTime = CmiWallTimer() - wallTime_start;
00263   CmiPrintf("====================================================\n\n"
00264             "WallClock: %f  CPUTime: %f  Memory: %f MB\n",
00265             wallTime, cpuTime, memusage_MB());
00266 #ifdef NAMD_TCL
00267   Tcl_Finalize();
00268 #endif
00269 #ifdef NAMD_CUDA
00270   cuda_finalize();
00271 #ifdef __APPLE__
00272 #if 0 && CMK_MULTICORE
00273   CmiPrintf("EXITING ABNORMALLY TO AVOID HANGING CUDA RUNTIME THREADS\n");
00274   ::exit(0);
00275 #endif
00276 #endif
00277 #endif
00278 #ifdef NAMD_MIC
00279 #if 0 && CMK_MULTICORE
00280   CmiPrintf("EXITING ABNORMALLY TO AVOID HANGING MIC OFFLOAD THREADS\n");
00281 #pragma offload target(mic)
00282   {
00283     ::exit(0);
00284   }
00285 #endif
00286 #endif
00287   CkExit();
00288 }
00289 
00290 // start scheduler
00291 void BackEnd::suspend(void) {
00292   CsdScheduler(-1);
00293 }
00294 
00295 // start quiescence detection to return to front end
00296 void BackEnd::awaken(void) {
00297   Node::Object()->enableExitScheduler();
00298 }
00299 
00300 // start QD and scheduler
00301 void BackEnd::barrier(void) {
00302   awaken();
00303   suspend();
00304 }
00305 

Generated on Mon Nov 20 01:17:10 2017 for NAMD by  doxygen 1.4.7