Remove archaic CVS headers
[charm.git] / src / ck-perf / trace-Tau.C
1 #include <stdlib.h>
2 #include "charm++.h"
3 #include "trace-Tau.h"
4 #include "trace-TauBOC.h"
5 #include "trace-common.h"
6 #include "TAU.h"
7 //#include "tau_selective.cpp"
8 #include "map"
9 #include "stack"
10 #include <string>
11 using namespace std;
12
13 #if defined(_WIN32) && !defined(__CYGWIN__)
14 #include <direct.h>
15 #define CHDIR _chdir
16 #define GETCWD _getcwd
17 #define PATHSEP '\\'
18 #define PATHSEPSTR "\\"
19 #else
20 #include <unistd.h>
21 #define CHDIR chdir
22 #define GETCWD getcwd
23 #define PATHSEP '/'
24 #define PATHSEPSTR "/"
25 #endif
26
27 /*#ifndef PROFILING_ON
28 void TAU_PROFILER_CREATE(void *p, char *n, char *s, taugroup_t t) {
29 dprintf("---> tau
30 create profiler: %s \n", s); }
31
32 void TAU_PROFILER_STOP(void *p) { dprintf("---> tau
33 stop profiler"); }
34
35 void TAU_PROFILER_START(void *p) { dprintf("---> tau
36 start profiler"); }
37
38 void TAU_PROFILE_SET_NODE(int i) { dprintf("---> tau
39 set node"); }
40 #endif
41 */
42
43 #ifdef DEBUG_PROF
44 #define dprintf printf
45 #else // DEBUG_PROF 
46 #define dprintf if (0) printf
47 #endif
48
49 extern bool processFileForInstrumentation(const string& file_name);
50 extern void printExcludeList();
51 extern bool instrumentEntity(const string& function_name);
52 extern int processInstrumentationRequests(char *fname);
53
54 // Charm++ "processor"(user thread)-private global variable
55 CkpvStaticDeclare(TraceTau*, _trace);
56
57 // This global variable is required for any post-execution 
58 // parallel analysis or activities the trace module might wish to perform.
59 CkGroupID traceTauGID;
60
61 /**
62    For each TraceFoo module, _createTraceFoo() must be defined.
63    This function is called in _createTraces() generated in moduleInit.C
64 */
65
66 void *idle, *comp;
67 //char *name = "default";
68 bool profile = true, snapshotProfiling = false;
69
70 //map<const int, void*> events;
71 void* events[5000];
72 stack<void*> eventStack;
73 int EX_VALUE = 0;
74 void *EXCLUDED = &EX_VALUE;
75 void startEntryEvent(int id)
76 {
77   dprintf("---------> starting Entry Event with id: %d\n", id);
78
79   if ((id == -1) || (events[id] == NULL))
80     {
81       dprintf("-------> create event with id: %d\n", id);
82       //sprintf(name, "Event %d", id);
83       if (id == -1)
84         { /*
85             char *name = "dummy_thread_ep";
86             dprintf(" ------> creating event: %s\n", name);
87             TAU_PROFILER_CREATE(events[id], name, "", TAU_DEFAULT);
88             dprintf("timer created.\n");
89             eventStack.push(events[id]);
90             dprintf(" ------> starting event: %s\n", (char*) name);
91             TAU_PROFILER_START(eventStack.top());*/
92           //exclude dummy event
93           dprintf("------> excluding dummy function");
94           events[id] = EXCLUDED;
95           eventStack.push(events[id]);
96         }
97       else
98         {
99           //string check("doFFT(RSFFTMsg* impl_msg)");
100           //string name_s(_entryTable[id]->name);
101           //printf("checking name4: %s", _entryTable[id]->name);
102           //if (check.compare(name_s) != 0)
103           //{
104           char name [500];
105           sprintf(name, "%s::%s::%d", _chareTable[_entryTable[id]->chareIdx]->name,
106                   _entryTable[id]->name, id);
107           //should this fuction be excluded from instrumentation?
108           if (!instrumentEntity(name))
109             {
110               //exclude function.
111               dprintf("------> excluding function %s\n", name);
112               events[id] = EXCLUDED;
113               eventStack.push(events[id]);
114             }
115           else
116             {
117               dprintf(" ------> creating event: %s\n", name);
118               TAU_PROFILER_CREATE(events[id], name, "", TAU_DEFAULT);
119               dprintf("timer created.\n");
120               eventStack.push(events[id]);
121               dprintf("starting event\n");
122               dprintf(" ------> starting event: %s\n", (char*) name);
123               TAU_PROFILER_START(eventStack.top());
124             }
125           dprintf("done.\n");
126         }
127     }
128   else
129     {
130       eventStack.push(events[id]);
131       if (events[id] != EXCLUDED)
132         {
133           TAU_PROFILER_START(eventStack.top());
134         }
135     }
136 }
137
138 void stopEntryEvent()
139 {
140   dprintf("stop timer...\n");
141   if (eventStack.top() != EXCLUDED)
142         {
143           TAU_PROFILER_STOP(eventStack.top());
144         }
145   eventStack.pop();
146 }
147
148
149 void _createTraceTau(char **argv)
150 {
151   //TAU_INIT(1, argv);
152   bzero(events, sizeof(void *)*5000);
153   //CkPrintf("NEWEST VERSION");
154   dprintf("arguments:\n");
155   dprintf("[0] = %s, ", argv[0]);
156   dprintf("[1] = %s, ", argv[1]);
157   dprintf("[2] = %s, ", argv[2]);
158   dprintf("\n");
159   string disable = "disable-profiling";
160   if (argv[1] == NULL) { profile = true; }
161   else if (argv[1] == disable) { profile = false; }
162   if (not CkpvAccess(traceOn)) { 
163     dprintf("traceoff selected using snapshot profiling.\n");
164     snapshotProfiling = true; 
165   }
166
167   CkpvInitialize(TraceTau*, _trace);
168   CkpvAccess(_trace) = new TraceTau(argv);
169   CkpvAccess(_traces)->addTrace(CkpvAccess(_trace));
170 }
171
172 TraceTau::TraceTau(char **argv)
173 {
174   if (CkpvAccess(traceOnPe) == 0) return;
175   
176   // Process runtime arguments intended for the module
177   CmiGetArgIntDesc(argv,"+TauPar0", &par0, "Fake integer parameter 0");
178   CmiGetArgDoubleDesc(argv,"+TauPar1", &par1, "Fake double parameter 1");
179   //TAU_REGISTER_THREAD();
180   if (profile)
181     {
182       if (strcmp(CkpvAccess(selective), ""))
183         {
184           //printf("select file: %s\n", CkpvAccess(selective));
185           //processFileForInstrumentation(CkpvAccess(selective));
186           processInstrumentationRequests(CkpvAccess(selective));
187           printExcludeList();
188           if (!instrumentEntity("Main::done(void)::99"))
189             {
190               dprintf("selective file working...\n");
191             }
192           else
193             dprintf("selective flile not working...\n");
194         }
195       
196       TAU_PROFILER_CREATE(idle, "Idle", "", TAU_DEFAULT);
197       //TAU_PROFILER_CREATE(entry,name,"", TAU_DEFAULT);
198       dprintf("before %p\n", comp);
199       TAU_PROFILER_CREATE(comp, "Main", "", TAU_DEFAULT);
200       dprintf("after %p\n", comp);
201       
202       //Need to add an entry timer to the top of the stack because
203       //traceTauExitFunction calls CkExit() which calls endExecute
204       eventStack.push(EXCLUDED);
205     }
206   else 
207     {
208       dprintf("--> [TAU] creating timers...\n");
209     }
210 }
211
212 void TraceTau::userEvent(int eventID) 
213 {
214   dprintf("[%d] User Point Event id %d encountered\n", CkMyPe(), eventID);
215 }
216
217 void TraceTau::userBracketEvent(int eventID, double bt, double et) {
218   dprintf("[%d] User Bracket Event id %d encountered\n", CkMyPe(), eventID);
219 }
220
221 void TraceTau::creation(envelope *, int epIdx, int num) {
222   dprintf("[%d] Point-to-Point Message for Entry Method id %d sent\n",
223           CkMyPe(), epIdx);
224 }
225
226 void TraceTau::creationMulticast(envelope *, int epIdx, int num, 
227                                  int *pelist) {
228   dprintf("[%d] Multicast Message for Entry Method id %d sent to %d pes\n",
229           CkMyPe(), epIdx, num);
230 }
231
232 void TraceTau::creationDone(int num) {
233   dprintf("[%d] Last initiated send completes\n", CkMyPe());
234 }
235
236 void TraceTau::messageRecv(char *env, int pe) {
237   dprintf("[%d] Message from pe %d received by scheduler\n", 
238           CkMyPe(), pe);
239 }
240
241 void TraceTau::beginExecute(CmiObjId *tid)
242 {
243   // CmiObjId is a 4-integer tuple uniquely identifying a migratable
244   // Charm++ object. Note that there are other non-migratable Charm++
245   // objects that CmiObjId will not identify.
246   dprintf("[%d] Entry Method invoked using object id\n", CkMyPe());
247   if (profile) {
248     startEntryEvent(-1);
249   }
250   else
251     {
252       dprintf("--> [TAU] starting entry timer...\n");
253     }
254 }
255
256 void TraceTau::beginExecute(envelope *e)
257 {
258   // no message means thread execution
259   if (e == NULL) {
260     dprintf("[%d] Entry Method invoked via thread id %d\n", CkMyPe(),
261             _threadEP);
262     if (profile) {
263       startEntryEvent(-1);
264     }
265     else
266       {
267         dprintf("--> [TAU] starting entry timer...\n");
268       }
269     // Below is what is found in trace-summary.
270     // beginExecute(-1,-1,_threadEP,-1);
271   } else {
272     dprintf("[%d] Entry Method %d invoked via message envelope\n", 
273             CkMyPe(), e->getEpIdx());
274     if (profile) {
275       startEntryEvent(e->getEpIdx());
276     }
277     else
278       {
279         dprintf("--> [TAU] starting entry timer...\n");
280       }
281     // Below is what is found in trace-summary.
282     // beginExecute(-1,-1,e->getEpIdx(),-1);
283   }
284 }
285
286 void TraceTau::beginExecute(int event,int msgType,int ep,int srcPe, 
287                             int mlen, CmiObjId *idx)
288 {
289   dprintf("[%d] Entry Method %d invoked by parameters\n", CkMyPe(),
290           ep);
291   if (profile) {
292     startEntryEvent(ep);
293   }
294   else
295     {
296       dprintf("--> [TAU] starting entry timer...\n");
297     }
298 }
299
300 void TraceTau::endExecute(void)
301 {
302   if (profile) {
303     stopEntryEvent();
304   }
305   else
306     {
307       dprintf("--> [TAU] stoping entry timer...\n");
308     }
309   dprintf("[%d] Previously executing Entry Method completes\n", CkMyPe());
310 }
311
312 void TraceTau::beginIdle(double curWallTime) {
313   dprintf("[%d] Scheduler has no useful user-work\n", CkMyPe());
314   if (profile) {
315     TAU_PROFILER_START(idle);
316   }
317   else
318     {
319       dprintf("--> [TAU] starting idle timer...\n");
320     }
321 }
322
323 void TraceTau::endIdle(double curWallTime) {
324   if (profile) {
325     TAU_PROFILER_STOP(idle);
326   }
327   else
328     {
329       dprintf("--> [TAU] stopping idle timer...\n");
330     }
331   dprintf("[%d] Scheduler now has useful user-work\n", CkMyPe());
332 }
333
334 void TraceTau::beginComputation(void)
335 {
336   dprintf("[%d] Computation Begins\n", CkMyPe());
337   //TAU_DISABLE_ALL_GROUPS();
338   // Code Below shows what trace-summary would do.
339   // initialze arrays because now the number of entries is known.
340   // _logPool->initMem();
341 }
342
343 void TraceTau::endComputation(void)
344 {
345   dprintf("[%d] Computation Ends\n", CkMyPe());
346 }
347
348 void TraceTau::traceBegin(void)
349 {
350   dprintf("[%d] >>>>>> Tracing Begins\n", CkMyPe());
351   if (profile) {
352     dprintf("ptr: %p\n", comp);
353       TAU_DB_PURGE();
354       TAU_ENABLE_ALL_GROUPS();
355       TAU_PROFILER_START(comp);
356   }
357   else
358     {
359       dprintf("--> [TAU] starting computation timer...\n");
360     }
361 }
362
363 void TraceTau::traceEnd(void)
364 {
365   dprintf("[%d] >>>>>> Tracing Ends\n", CkMyPe());
366   if (profile){
367     dprintf("ptr: %p\n", comp);
368       //TAU_PROFILER_STOP(comp);
369     TAU_PROFILE_EXIT("tracing complete.");
370     TAU_DISABLE_ALL_GROUPS();
371   }
372   else
373     {
374       dprintf("--> [TAU] stopping computation timer and writing profiles\n");
375     }
376   dprintf("[%d] Computation Ends\n", CkMyPe());
377 }
378
379 void TraceTau::malloc(void *where, int size, void **stack, int stackSize)
380 {
381   dprintf("[%d] Memory allocation of size %d occurred\n", CkMyPe(), size);
382 }
383
384 void TraceTau::free(void *where, int size) {
385   dprintf("[%d] %d-byte Memory block freed\n", CkMyPe(), size);
386 }
387
388 void TraceTau::traceClose(void)
389 {
390   dprintf("traceClose called.\n");
391   CkpvAccess(_trace)->endComputation();
392   CkpvAccess(_trace)->traceEnd();
393   //TAU_PROFILE_EXIT("closing trace...");
394   //dprintf(" [%d] Exit called \n", CkMyPe());
395   //TAU_PROFILE_EXIT("exiting...");
396   // remove myself from traceArray so that no tracing will be called.
397   CkpvAccess(_traces)->removeTrace(this);
398 }
399
400 extern "C" void traceTauExitFunction() {
401   dprintf("traceTauExitFunction called.\n");
402   // The exit function of any Charm++ module must call CkExit() or
403   // the entire exit process will hang if multiple modules are linked.
404   // FIXME: This is NOT a feature. Something needs to be done about this.
405   //TAU_PROFILE_EXIT("exiting...");
406   //TAU_PROFILE_EXIT("done");
407   //eventStack.push(NULL);
408   CkExit();
409 }
410
411 // Initialization of the parallel trace module.
412 void initTraceTauBOC() {
413   //void *main;
414   dprintf("tracetauboc setting node %d\n", CmiMyPe());
415   if (profile) {
416     TAU_PROFILE_SET_NODE(CmiMyPe());
417   }
418   else
419     {
420       dprintf("---> [TAU] settting node.\n");
421     }
422   //TAU_PROFILER_CREATE(main, "main", "", TAU_DEFAULT);
423   //TAU_PROFILER_START(main);
424 #ifdef __BLUEGENE__
425   if (BgNodeRank()==0) {
426 #else
427   if (CkMyRank() == 0) {
428 #endif
429     registerExitFn(traceTauExitFunction);
430   }
431 }
432   
433 #include "TraceTau.def.h"