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