NAMD
BackEnd.C
Go to the documentation of this file.
1 
7 #include "BackEnd.h"
8 #include "ProcessorPrivate.h"
9 #include "common.h"
10 #include "Node.h"
11 #include "memusage.h"
12 
13 #include <new>
14 #if defined(WIN32) && !defined(__CYGWIN__)
15 #include <new.h>
16 #endif
17 
18 #include "Lattice.h"
19 #include "ComputeMoa.h"
20 #include "ComputeMsmMsa.h" // needed for MsmMsaData definition
21 #include "main.decl.h"
22 #include "main.h"
23 #include "BOCgroup.h"
24 #include "WorkDistrib.decl.h"
25 #include "ProxyMgr.decl.h"
26 #include "PatchMgr.decl.h"
27 #include "DataExchanger.decl.h"
28 #ifdef CHARM_HAS_MSA
29 #include "ComputeMgr.decl.h"
30 #endif
31 #include "ReductionMgr.decl.h"
32 #include "CollectionMgr.decl.h"
33 #include "CollectionMaster.decl.h"
34 #include "CollectionMgr.h"
35 #include "CollectionMaster.h"
36 #include "BroadcastMgr.decl.h"
37 #include "LdbCoordinator.decl.h"
38 #include "Sync.decl.h"
39 #include "PatchData.decl.h"
40 
41 #ifdef MEM_OPT_VERSION
42 #include "ParallelIOMgr.decl.h"
43 #endif
44 
45 #ifdef NAMD_TCL
46 #include <tcl.h>
47 #endif
48 
49 extern void _initCharm(int, char**);
50 
53 
54 CkpvStaticDeclare(int,exitSchedHndlr);
55 
56 extern "C" void exit_sched(void* msg)
57 {
58  // CmiPrintf("Exiting scheduler on %d\n",CmiMyPe());
59  CsdExitScheduler();
60 }
61 
62 static void register_exit_sched(void)
63 {
64  CkpvInitialize(int,exitSchedHndlr);
65  CkpvAccess(exitSchedHndlr) = CmiRegisterHandler((CmiHandler)exit_sched);
66 }
67 
69 {
70  void* msg = CmiAlloc(CmiMsgHeaderSizeBytes);
71  CmiSetHandler(msg,CkpvAccess(exitSchedHndlr));
72  CmiSyncSendAndFree(pe,CmiMsgHeaderSizeBytes,(char *)msg);
73 }
74 
75 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW_H)
76 int NAMD_new_handler(size_t) {
77 #else
79 #endif
80  char tmp[100];
81  sprintf(tmp,"Memory allocation failed on processor %d.",CmiMyPe());
82  NAMD_die(tmp);
83 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW_H)
84  return 0;
85 #endif
86 }
87 
88 void topo_getargs(char**);
89 void cuda_getargs(char**);
90 // void cuda_initialize();
92 void mic_getargs(char**);
93 // void mic_initialize();
94 #ifdef NAMD_AVXTILES
95 // For "+notiles" commandline option to disable "Tiles" algorithm
96 int avxTilesCommandLineDisable = 0;
97 #endif
98 
99 // called on all procs
100 void all_init(int argc, char **argv)
101 {
102 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW_H)
103  _set_new_handler(NAMD_new_handler);
104 #else
105  std::set_new_handler(NAMD_new_handler);
106 #endif
109  CmiGetArgFlag(argv, "+idlepoll"); // remove +idlepoll if it's still there
110  topo_getargs(argv);
111 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
112  cuda_getargs(argv);
113  argc = CmiGetArgc(argv);
114 #endif
115 #ifdef NAMD_MIC
116  CmiGetArgFlag(argv, "+idlepoll"); // remove +idlepoll if it's still there
117  mic_getargs(argv);
118  argc = CmiGetArgc(argv);
119 #endif
120 #ifdef NAMD_AVXTILES
121  avxTilesCommandLineDisable = CmiGetArgFlag(argv, "+notiles");
122 #endif
123 
124 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
125  // launch CUDA runtime threads before affinity is set by _initCharm
126  // _initCharm contains a node barrier so there is no race here
127  if(CmiMyRank()==0){
129  }
130 #endif
131 
132  _initCharm(argc, argv); // message main Chare
133 
134 //#if 0 // moved to WorkDistrib
135 //#ifdef NAMD_CUDA
136 // if ( CkMyPe() < CkNumPes() ) cuda_initialize();
137 //#endif
138 //#ifdef NAMD_MIC
139 // if ( CkMyPe() < CkNumPes() ) mic_initialize();
140 //#endif
141 //#endif
142 }
143 
144 extern void after_backend_init(int argc, char **argv);
145 void master_init(int argc, char **argv);
146 
147 // called on slave procs
148 void slave_init(int argc, char **argv)
149 {
150 #if CMK_SMP
151  //the original main thread could now be a comm thread
152  //and a slave thread could now be the main thread,
153  //so we have to do the master initialization here
154  if(CmiMyRank()==0){
155  master_init(argc, argv);
156  if(CmiMyPe()==0)
157  after_backend_init(argc, argv);
158  return;
159  }
160 #endif
161 
162  all_init(argc, argv);
163 
164  if (CkMyRank() < CkMyNodeSize()) // skip the communication thread
165  CsdScheduler(-1);
166 }
167 
168 void master_init(int argc, char **argv){
169  cpuTime_start = CmiCpuTimer();
170  wallTime_start = CmiWallTimer();
171  if ( CmiMyPe() ) {
172  all_init(argc, argv);
173  CsdScheduler(-1);
174  ConverseExit(); // should never return
175  }
176 
177  all_init(argc, argv);
178 
179  // Create branch-office chares
180  BOCgroup group;
181  group.workDistrib = CProxy_WorkDistrib::ckNew();
182  group.proxyMgr = CProxy_ProxyMgr::ckNew();
183  group.patchMgr = CProxy_PatchMgr::ckNew();
184  group.computeMgr = CProxy_ComputeMgr::ckNew();
185  group.reductionMgr = CProxy_ReductionMgr::ckNew();
186  // group.computePmeMgr set in constructor during startup
187  group.nodePmeMgr = CProxy_NodePmeMgr::ckNew();
188 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
189  group.patchData = CProxy_PatchData::ckNew();
190  group.computePmeCUDAMgr = CProxy_ComputePmeCUDAMgr::ckNew();
191  group.computeCUDAMgr = CProxy_ComputeCUDAMgr::ckNew();
192 #endif
193 #ifdef OPENATOM_VERSION
194  group.computeMoaMgr = CProxy_ComputeMoaMgr::ckNew();
195 #endif // OPENATOM_VERSION
196  group.computeExtMgr = CProxy_ComputeExtMgr::ckNew();
197  group.computeQMMgr = CProxy_ComputeQMMgr::ckNew();
198  group.computeGBISserMgr = CProxy_ComputeGBISserMgr::ckNew();
199  group.computeFmmSerialMgr = CProxy_ComputeFmmSerialMgr::ckNew();
200  group.computeMsmSerialMgr = CProxy_ComputeMsmSerialMgr::ckNew();
201  group.computeLjPmeSerialMgr = CProxy_ComputeLjPmeSerialMgr::ckNew();
202 #ifdef CHARM_HAS_MSA
203  group.computeMsmMsaMgr = CProxy_ComputeMsmMsaMgr::ckNew();
204 #endif
205  group.computeMsmMgr = CProxy_ComputeMsmMgr::ckNew();
206  // Charm CkMulticast library module
207  group.multicastMgr = CProxy_CkMulticastMgr::ckNew();
208 #ifdef MEM_OPT_VERSION
209  group.ioMgr=CProxy_ParallelIOMgr::ckNew();
210 #endif
211 
212  group.sync = CProxy_Sync::ckNew();
213 
214  #ifdef USE_NODEPATCHMGR
215  group.nodeProxyMgr = CProxy_NodeProxyMgr::ckNew();
216  #endif
217 
218 #if CMK_SMP && USE_CKLOOP
219  group.ckLoop = CkLoop_Init();
220 #endif
221 
222  CkChareID collectionMaster = CProxy_CollectionMaster::ckNew(0);
223  SlaveInitMsg *initmsg7 = new SlaveInitMsg;
224  initmsg7->master = collectionMaster;
225  group.collectionMgr = CProxy_CollectionMgr::ckNew(initmsg7);
226 
227  group.broadcastMgr = CProxy_BroadcastMgr::ckNew();
228  group.ldbCoordinator = CProxy_LdbCoordinator::ckNew();
229 
230  group.dataExchanger = CProxy_DataExchanger::ckNew();
231 
232  GroupInitMsg *msg = new GroupInitMsg;
233  msg->group = group;
234  CkGroupID node = CProxy_Node::ckNew(msg);
235 
236  CkStartQD(CkCallback(CkIndex_Node::exitScheduler(), CkMyPe(), node));
237  CsdScheduler(-1);
238 }
239 
240 char *gNAMDBinaryName = NULL;
241 // called by main on one or all procs
242 void BackEnd::init(int argc, char **argv) {
243 
244  gNAMDBinaryName = argv[0]+strlen(argv[0])-1;
245  while(gNAMDBinaryName != argv[0]){
246  if(*gNAMDBinaryName=='/' || *gNAMDBinaryName=='\\'){
247  gNAMDBinaryName++;
248  break;
249  }
250  gNAMDBinaryName--;
251  }
252 
253 #if defined(NAMD_CUDA) || defined(NAMD_HIP) || defined(NAMD_MIC)
254  // look for but don't remove +idlepoll on command line
255  int idlepoll = 0;
256  for ( int i = 0; i < argc; ++i ) {
257  if ( 0==strcmp(argv[i],"+idlepoll") ) {
258  idlepoll = 1;
259  break;
260  }
261  }
262 #endif
263 
264  ConverseInit(argc, argv, slave_init, 1, 1); // calls slave_init on others
265 
266 // idlepoll only matters for non-smp UDP layer
267 #if (defined(NAMD_CUDA) || defined(NAMD_HIP) || defined(NAMD_MIC)) && CMK_NET_VERSION && CMK_SHARED_VARS_UNAVAILABLE && CMK_WHEN_PROCESSOR_IDLE_USLEEP && ! CMK_USE_IBVERBS && ! CMK_USE_TCP
268  if ( ! idlepoll ) {
269  NAMD_die("Please add +idlepoll to command line for proper performance.");
270  }
271 #endif
272 
273  master_init(argc, argv);
274 }
275 
276 // called on proc 0 by front end
277 void BackEnd::exit(int status) {
278  float cpuTime = CmiCpuTimer() - cpuTime_start;
279  float wallTime = CmiWallTimer() - wallTime_start;
280  CmiPrintf("====================================================\n\n"
281  "WallClock: %f CPUTime: %f Memory: %f MB\n",
282  wallTime, cpuTime, memusage_MB());
283 #ifdef NAMD_TCL
284  Tcl_Finalize();
285 #endif
286 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
287 #ifdef __APPLE__
288 #if 0 && CMK_MULTICORE
289  CmiPrintf("EXITING ABNORMALLY TO AVOID HANGING CUDA RUNTIME THREADS\n");
290  ::exit(0);
291 #endif
292 #endif
293 #endif
294 #ifdef NAMD_MIC
295 #if 0 && CMK_MULTICORE
296  CmiPrintf("EXITING ABNORMALLY TO AVOID HANGING MIC OFFLOAD THREADS\n");
297 #pragma offload target(mic)
298  {
299  ::exit(0);
300  }
301 #endif
302 #endif
303 #if CHARM_VERSION < 61000
304  CkExit();
305 #else
306  CkExit(status);
307 #endif
308 }
309 
310 // start scheduler
311 void BackEnd::suspend(void) {
312  CsdScheduler(-1);
313 }
314 
315 // start quiescence detection to return to front end
316 void BackEnd::awaken(void) {
318 }
319 
320 // start QD and scheduler
321 void BackEnd::barrier(void) {
322  awaken();
323  suspend();
324 }
static Node * Object()
Definition: Node.h:86
CkGroupID broadcastMgr
Definition: BOCgroup.h:44
CkChareID master
Definition: CollectionMgr.h:23
static void awaken(void)
Definition: BackEnd.C:316
static void ExitSchedOn(int pe)
Definition: BackEnd.C:68
void after_backend_init(int argc, char **argv)
Definition: mainfunc.C:55
BOCgroup group
Definition: Node.h:68
CkGroupID patchMgr
Definition: BOCgroup.h:19
void all_init(int argc, char **argv)
Definition: BackEnd.C:100
void NAMD_new_handler()
Definition: BackEnd.C:78
void cuda_getargs(char **)
Definition: DeviceCUDA.C:67
CkGroupID computeLjPmeSerialMgr
Definition: BOCgroup.h:38
static void exit(int status=0)
Definition: BackEnd.C:277
CkGroupID computeMsmMsaMgr
Definition: BOCgroup.h:39
CkGroupID patchData
Definition: BOCgroup.h:27
static void suspend(void)
Definition: BackEnd.C:311
CkGroupID workDistrib
Definition: BOCgroup.h:18
char * gNAMDBinaryName
Definition: BackEnd.C:240
static void init(int argc, char **argv)
Definition: BackEnd.C:242
void master_init(int argc, char **argv)
Definition: BackEnd.C:168
float cpuTime_start
Definition: BackEnd.C:51
CkGroupID computeMgr
Definition: BOCgroup.h:21
CkGroupID computeCUDAMgr
Definition: BOCgroup.h:26
CkGroupID computePmeCUDAMgr
Definition: BOCgroup.h:25
CkGroupID computeMsmSerialMgr
Definition: BOCgroup.h:37
float wallTime_start
Definition: BackEnd.C:52
double memusage_MB()
Definition: memusage.h:13
CkGroupID dataExchanger
Definition: BOCgroup.h:57
CkGroupID collectionMgr
Definition: BOCgroup.h:43
CkGroupID computeMsmMgr
Definition: BOCgroup.h:40
CkGroupID computeExtMgr
Definition: BOCgroup.h:33
CkGroupID multicastMgr
Definition: BOCgroup.h:41
void enableExitScheduler(void)
Definition: Node.C:1382
void ProcessorPrivateInit(void)
CkGroupID proxyMgr
Definition: BOCgroup.h:20
CkGroupID ldbCoordinator
Definition: BOCgroup.h:45
CkGroupID nodePmeMgr
Definition: BOCgroup.h:23
CkGroupID computeGBISserMgr
Definition: BOCgroup.h:35
void NAMD_die(const char *err_msg)
Definition: common.C:147
void exit_sched(void *msg)
Definition: BackEnd.C:56
void mic_getargs(char **)
CkGroupID ioMgr
Definition: BOCgroup.h:48
void topo_getargs(char **)
Definition: WorkDistrib.C:91
static void barrier(void)
Definition: BackEnd.C:321
void _initCharm(int, char **)
static void register_exit_sched(void)
Definition: BackEnd.C:62
CkGroupID sync
Definition: BOCgroup.h:46
void slave_init(int argc, char **argv)
Definition: BackEnd.C:148
CkGroupID computeFmmSerialMgr
Definition: BOCgroup.h:36
void cuda_affinity_initialize()
Definition: CudaUtils.C:55
CkpvStaticDeclare(int, exitSchedHndlr)
CkGroupID computeQMMgr
Definition: BOCgroup.h:34
CkGroupID reductionMgr
Definition: BOCgroup.h:42