Merge branch 'charm' of charmgit:charm into charm
[charm.git] / src / ck-perf / trace.h
1
2 #ifndef _TRACE_H
3 #define _TRACE_H
4
5 /*
6  *   File: trace.h -- header file defines the super class of all trace modules
7  *         written by Gengbin Zheng, gzheng@uiuc.edu 
8  */ 
9
10 #if CMK_HAS_COUNTER_PAPI
11 #include <papi.h>
12 #endif
13
14 class envelope;
15
16 /**
17  \defgroup CkPerf  Charm++ Trace Module
18 */
19 /*@{*/
20
21 // An additional interface for summary data
22 extern "C" void traceClearEps();
23
24 // **CW** may not be necessary
25 extern "C" void traceEnableCCS();
26
27 extern double CmiTraceTimer();
28
29 extern int _dummyMsg, _dummyChare, _dummyEP;
30
31 /* CW Support for Thread Listener interface */
32 extern "C" void traceAddThreadListeners(CthThread tid, envelope *e);
33
34 // trace_in_charm means only do trace for Charm++ level, skip converse tracing
35 // Cpv traceOnPe controls if charm pe will generate trace logs (a default value)
36 // while traceOnPe flag in each trace module can also control independently if 
37 // tracing is wanted for each module
38 CkpvExtern(int, traceOnPe);
39
40 // A hack. We need to somehow tell the pup framework what size
41 // long_long is wrt PAPI.
42 #if CMK_HAS_COUNTER_PAPI
43 typedef long_long LONG_LONG_PAPI;
44 #else
45 typedef CMK_TYPEDEF_INT8 LONG_LONG_PAPI;
46 #endif
47
48 // Base class of all tracing strategies.
49 // 
50 class Trace {
51   protected:
52     int _traceOn;
53   
54   public:
55     Trace(): _traceOn(0) {}
56     virtual void setTraceOnPE(int flag) { _traceOn = flag; }
57     virtual inline int traceOnPE() { return _traceOn; }
58     // turn trace on/off, note that charm will automatically call traceBegin()
59     // at the beginning of every run unless the command line option "+traceoff"
60     // is specified
61     virtual void traceBegin() {}
62     virtual void traceEnd() {}
63 #if CMK_SMP_TRACE_COMMTHREAD            
64     virtual void traceBeginOnCommThread() {}   
65     virtual void traceEndOnCommThread() {}
66 #endif 
67                 
68     // registers user event trace module returns int identifier 
69     virtual int traceRegisterUserEvent(const char* eventName, int e) { 
70       return 0; 
71     }
72     // a user event has just occured
73     virtual void userEvent(int eventID) {}
74     // a pair of begin/end user event has just occured
75     virtual void userBracketEvent(int eventID, double bt, double et) {}
76
77     // a user supplied integer value(likely a timestep)
78     virtual void userSuppliedData(int e) {}
79
80     // a user supplied integer value(likely a timestep)
81     virtual void userSuppliedNote(char *note) {}
82
83     virtual void userSuppliedBracketedNote(char *note, int eventID, double bt, double et) {}
84
85     // the current memory usage as a double
86     virtual void memoryUsage(double currentMemUsage) {}
87
88     // creation of message(s)
89     virtual void creation(envelope *, int epIdx, int num=1) {}
90     //epIdx is extracted from the envelope, num is always 1
91     virtual void creation(char *) {}
92     virtual void creationMulticast(envelope *, int epIdx, int num=1,
93                                      int *pelist=NULL) {}
94     virtual void creationDone(int num=1) {}
95     // ???
96     virtual void messageRecv(char *env, int pe) {}
97     virtual void beginSDAGBlock(
98       int event,   // event type defined in trace-common.h
99       int msgType, // message type
100       int ep,      // Charm++ entry point (will correspond to sts file) 
101       int srcPe,   // Which PE originated the call
102       int ml,      // message size
103       CmiObjId* idx)    // index
104     { }
105     virtual void endSDAGBlock(void) {}
106     // **************************************************************
107     // begin/end execution of a Charm++ entry point
108     // NOTE: begin/endPack and begin/endUnpack can be called in between
109     //       a beginExecute and its corresponding endExecute.
110     virtual void beginExecute(envelope *) {}
111     virtual void beginExecute(char *) {}
112     virtual void beginExecute(CmiObjId *tid) {}
113     virtual void beginExecute(
114       int event,   // event type defined in trace-common.h
115       int msgType, // message type
116       int ep,      // Charm++ entry point (will correspond to sts file) 
117       int srcPe,   // Which PE originated the call
118       int ml,      // message size
119       CmiObjId* idx)    // index
120     { }
121     virtual void changeLastEntryTimestamp(double ts) {}
122     virtual void endExecute(void) {}
123     virtual void endExecute(char *) {}
124     // begin/end idle time for this pe
125     virtual void beginIdle(double curWallTime) {}
126     virtual void endIdle(double curWallTime) {}
127     // begin/end the process of packing a message (to send)
128     virtual void beginPack(void) {}
129     virtual void endPack(void) {}
130     // begin/end the process of unpacking a message (can occur before calling
131     // a entry point or during an entry point when 
132     virtual void beginUnpack(void) {}
133     virtual void endUnpack(void) {}
134     // ???
135     virtual void enqueue(envelope *) {}
136     virtual void dequeue(envelope *) {}
137     // begin/end of execution
138     virtual void beginComputation(void) {}
139     virtual void endComputation(void) {}
140     // demarkation of a phase boundary
141     virtual void endPhase() {}
142     // clear all data collected for entry points
143     virtual void traceClearEps() {}
144     // enable CCS operations if supported on the trace module
145     virtual void traceEnableCCS() {}
146     // write the summary sts file for this trace
147     virtual void traceWriteSts() {}
148     // do any clean-up necessary for tracing
149     virtual void traceClose() {}
150     // flush log buffer immediately
151     virtual void traceFlushLog() {}
152
153     //for tracing function calls
154     virtual void regFunc(const char *name, int &idx, int idxSpecifiedByUser=0){}
155     virtual void beginFunc(char *name,char *file,int line){}
156     virtual void beginFunc(int idx,char *file,int line){}
157     virtual void endFunc(char *name){}    
158     virtual void endFunc(int idx){}
159
160     /* Memory tracing */
161     virtual void malloc(void *where, int size, void **stack, int stackSize){}
162     virtual void free(void *where, int size){}
163
164     /* for implementing thread listeners */
165     virtual void traceAddThreadListeners(CthThread tid, envelope *e) {}
166
167     virtual ~Trace() {} /* for whining compilers */
168 };
169
170 #define ALLDO(x) for (int i=0; i<length(); i++) if (traces[i]->traceOnPE()) traces[i]->x
171 #define ALLREVERSEDO(x) for (int i=length()-1; i>=0; i--) if (traces[i]->traceOnPE()) traces[i]->x
172
173 /// Array of Traces modules,  every event raised will go through every Trace module.
174 class TraceArray {
175 private:
176   CkVec<Trace *>  traces;
177   int n;
178   int cancel_beginIdle, cancel_endIdle;
179 public:
180     TraceArray(): n(0) {}
181     inline void addTrace(Trace *tr) { traces.push_back(tr); n++;}
182     inline void setTraceOnPE(int flag) { for (int i=0; i<length(); i++) traces[i]->setTraceOnPE(flag); }
183     // to allow traceCLose() to be called multiple times, remove trace module
184     // from the array in each individual trace, and clean up (clearTrace)
185     // after the loop.
186     inline void removeTrace(Trace *tr) {    // remove a Trace from TraceArray
187         int i;
188         for (i=0; i<n; i++) if (tr == traces[i]) break;
189         CmiAssert(i<n);
190         traces[i] = NULL;
191     }
192     inline void clearTrace() {    // remove holes in TraceArray
193         int len = traces.length();
194         int removed = 0;
195         for (int i=0; i<len; i++) {
196           if (traces[i-removed] == NULL) { traces.remove(i-removed); removed++; }
197         }
198         n -= removed;
199     }
200     inline int length() const { return n; }
201
202     inline void userEvent(int e) { ALLDO(userEvent(e));}
203     inline void userBracketEvent(int e,double bt, double et) {ALLDO(userBracketEvent(e,bt,et));}
204     
205         inline void userSuppliedData(int d) { ALLDO(userSuppliedData(d));}
206
207         inline void userSuppliedNote(char *note) { ALLDO(userSuppliedNote(note));}
208         inline void userSuppliedBracketedNote(char *note, int eventID, double bt, double et) {ALLDO(userSuppliedBracketedNote(note, eventID, bt, et));}
209
210
211         inline void memoryUsage(double memUsage) { ALLDO(memoryUsage(memUsage));}
212
213
214     /* Creation needs to access _entryTable, so moved into trace-common.C */
215     void creation(envelope *env, int ep, int num=1);
216     inline void creation(char *msg){
217         /* The check for whether the ep got traced is moved into each elem's
218          * creation call as the ep could not be extracted here
219          */
220         ALLDO(creation(msg));
221     }
222     void creationMulticast(envelope *env, int ep, int num=1, int *pelist=NULL);
223     
224     inline void creationDone(int num=1) { ALLDO(creationDone(num)); }
225     inline void beginSDAGBlock(int event,int msgType,int ep,int srcPe, int mlen,CmiObjId *idx=NULL) {ALLDO(beginSDAGBlock(event, msgType, ep, srcPe, mlen,idx));}
226     inline void endSDAGBlock(void) {ALLREVERSEDO(endExecute());}
227     inline void beginExecute(envelope *env) {ALLDO(beginExecute(env));}
228     inline void beginExecute(char *msg) {ALLDO(beginExecute(msg));}
229     inline void beginExecute(CmiObjId *tid) {ALLDO(beginExecute(tid));}
230     inline void beginExecute(int event,int msgType,int ep,int srcPe, int mlen,CmiObjId *idx=NULL) {ALLDO(beginExecute(event, msgType, ep, srcPe, mlen,idx));}
231     inline void endExecute(void) {ALLREVERSEDO(endExecute());}
232     inline void endExecute(char *msg) {ALLREVERSEDO(endExecute(msg));}
233     inline void changeLastEntryTimestamp(double ts) {ALLDO(changeLastEntryTimestamp(ts));}
234     inline void messageRecv(char *env, int pe) {ALLDO(messageRecv(env, pe));}
235     inline void beginPack(void) {ALLDO(beginPack());}
236     inline void endPack(void) {ALLDO(endPack());}
237     inline void beginUnpack(void) {ALLDO(beginUnpack());}
238     inline void endUnpack(void) {ALLDO(endUnpack());}
239     inline void enqueue(envelope *e) {ALLDO(enqueue(e));}
240     inline void dequeue(envelope *e) {ALLDO(dequeue(e));}
241     inline void beginComputation(void) {ALLDO(beginComputation());}
242     inline void endComputation(void) {ALLDO(endComputation());}
243     inline int traceRegisterUserEvent(const char*x, int evt) {
244           int eno = 0;
245           for (int i=0; i<length(); i++) {
246             if (traces[i]->traceOnPE() == 0) {
247               continue;
248             }
249             int e = traces[i]->traceRegisterUserEvent(x, evt);
250             if (e) eno = e;
251           }
252           return eno;
253     }  
254     inline void traceClearEps() {ALLDO(traceClearEps());}
255     inline void traceEnableCCS() {ALLDO(traceEnableCCS());}
256     inline void traceWriteSts() {ALLDO(traceWriteSts());}
257     inline void traceClose() {ALLDO(traceClose()); clearTrace();}
258     inline void traceFlushLog() {ALLDO(traceFlushLog());}
259     
260     // Tracing module registers *itself* for begin/end idle callbacks:
261     inline void beginIdle(double curWallTime) {ALLDO(beginIdle(curWallTime));}
262     inline void endIdle(double curWallTime) {ALLDO(endIdle(curWallTime));}
263     void traceBegin();    
264     void traceEnd();
265
266 #if CMK_SMP_TRACE_COMMTHREAD
267     void traceBeginOnCommThread();
268     void traceEndOnCommThread();
269 #endif
270         
271     /*Calls for tracing function begins and ends*/
272     inline void regFunc(const char *name, int &idx, int idxSpecifiedByUser=0){ ALLDO(regFunc(name, idx, idxSpecifiedByUser)); }
273     inline void beginFunc(char *name,char *file,int line){ ALLDO(beginFunc(name,file,line)); };
274     inline void beginFunc(int idx,char *file,int line){ ALLDO(beginFunc(idx,file,line)); };
275     inline void endFunc(char *name){ ALLDO(endFunc(name)); }
276     inline void endFunc(int idx){ ALLDO(endFunc(idx)); }
277
278     /* Phase Demarkation */
279     inline void endPhase() { ALLDO(endPhase()); }
280
281     /* Memory tracing */
282     inline void malloc(void *where, int size, void **stack, int stackSize){ ALLDO(malloc(where,size,stack,stackSize)); }
283     inline void free(void *where, int size){ ALLDO(free(where, size)); }
284
285     /* calls for thread listener registration for each trace module */
286     inline void traceAddThreadListeners(CthThread tid, envelope *e) {
287       ALLDO(traceAddThreadListeners(tid, e));
288     }
289 };
290
291 CkpvExtern(TraceArray*, _traces);
292
293 #if CMK_TRACE_ENABLED
294 #if CMK_BIGSIM_CHARM
295 extern void    resetVTime();
296 #  define _TRACE_ONLY(code) do{ BgGetTime(); if(CpvAccess(traceOn) && CkpvAccess(_traces)->length()>0) { code; }  resetVTime(); } while(0)
297 #else
298 #  define _TRACE_ONLY(code) do{if(CpvAccess(traceOn) && CkpvAccess(_traces)->length()>0) { code; }} while(0)
299 #endif
300 #  define _TRACE_ALWAYS(code) do{ code; } while(0)
301 #else
302 #  define _TRACE_ONLY(code) /*empty*/
303 #  define _TRACE_ALWAYS(code) /*empty*/
304 #endif
305
306 extern "C" {
307 #include "conv-trace.h"
308 }
309
310 #define _TRACE_USER_EVENT(x) _TRACE_ONLY(CkpvAccess(_traces)->userEvent(x))
311 #define _TRACE_USER_EVENT_BRACKET(x,bt,et) _TRACE_ONLY(CkpvAccess(_traces)->userBracketEvent(x,bt,et))
312 #define _TRACE_CREATION_1(env) _TRACE_ONLY(CkpvAccess(_traces)->creation(env,env->getEpIdx()))
313 #define _TRACE_CREATION_DETAILED(env,ep) _TRACE_ONLY(CkpvAccess(_traces)->creation(env,ep))
314 #define _TRACE_CREATION_N(env, num) _TRACE_ONLY(CkpvAccess(_traces)->creation(env, env->getEpIdx(), num))
315 #define _TRACE_CREATION_MULTICAST(env, num, pelist) _TRACE_ONLY(CkpvAccess(_traces)->creationMulticast(env, env->getEpIdx(), num, pelist))
316 #define _TRACE_CREATION_DONE(num) _TRACE_ONLY(CkpvAccess(_traces)->creationDone(num))
317 #define _TRACE_BEGIN_SDAG(env) _TRACE_ONLY(CkpvAccess(_traces)->beginSDAGBlock(env))
318 #define _TRACE_END_SDAG(env) _TRACE_ONLY(CkpvAccess(_traces)->endSDAGBlock(env))
319 #define _TRACE_BEGIN_EXECUTE(env) _TRACE_ONLY(CkpvAccess(_traces)->beginExecute(env))
320 #define _TRACE_BEGIN_EXECUTE_DETAILED(evt,typ,ep,src,mlen,idx) _TRACE_ONLY(CkpvAccess(_traces)->beginExecute(evt,typ,ep,src,mlen,idx))
321 #define _TRACE_END_EXECUTE() _TRACE_ONLY(CkpvAccess(_traces)->endExecute())
322 #define _TRACE_MESSAGE_RECV(env, pe) _TRACE_ONLY(CkpvAccess(_traces)->messageRecv(env, pe))
323 #define _TRACE_BEGIN_PACK() _TRACE_ONLY(CkpvAccess(_traces)->beginPack())
324 #define _TRACE_END_PACK() _TRACE_ONLY(CkpvAccess(_traces)->endPack())
325 #define _TRACE_BEGIN_UNPACK() _TRACE_ONLY(CkpvAccess(_traces)->beginUnpack())
326 #define _TRACE_END_UNPACK() _TRACE_ONLY(CkpvAccess(_traces)->endUnpack())
327 #define _TRACE_BEGIN_COMPUTATION() _TRACE_ALWAYS(CkpvAccess(_traces)->beginComputation())
328 #define _TRACE_END_COMPUTATION() _TRACE_ALWAYS(CkpvAccess(_traces)->endComputation())
329 #define _TRACE_ENQUEUE(env) _TRACE_ONLY(CkpvAccess(_traces)->enqueue(env))
330 #define _TRACE_DEQUEUE(env) _TRACE_ONLY(CkpvAccess(_traces)->dequeue(env))
331
332 #define _TRACE_END_PHASE() _TRACE_ONLY(CkpvAccess(_traces)->endPhase())
333
334 /* Memory tracing */
335 #define _TRACE_MALLOC(where, size, stack, stackSize) _TRACE_ONLY(CkpvAccess(_traces)->malloc(where,size,stack,stackSize))
336 #define _TRACE_FREE(where, size) _TRACE_ONLY(CkpvAccess(_traces)->free(where, size))
337
338 #include "trace-bluegene.h"
339
340 #endif
341
342
343 /*@}*/