fix comm thread tracing for small and large messages.
[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
64     // for tracing comm thread only
65     virtual void traceBeginOnCommThread() {}   
66     virtual void traceEndOnCommThread() {}
67     virtual void traceCommSetMsgID(char *) {}
68     virtual void traceGetMsgID(char *msg, int *pe, int *event) {}
69     virtual void traceSetMsgID(char *msg, int pe, int event) {}
70                 
71     // registers user event trace module returns int identifier 
72     virtual int traceRegisterUserEvent(const char* eventName, int e) { 
73       return 0; 
74     }
75     // a user event has just occured
76     virtual void userEvent(int eventID) {}
77     // a pair of begin/end user event has just occured
78     virtual void userBracketEvent(int eventID, double bt, double et) {}
79
80     // a user supplied integer value(likely a timestep)
81     virtual void userSuppliedData(int e) {}
82
83     // a user supplied integer value(likely a timestep)
84     virtual void userSuppliedNote(char *note) {}
85
86     virtual void userSuppliedBracketedNote(char *note, int eventID, double bt, double et) {}
87
88     // the current memory usage as a double
89     virtual void memoryUsage(double currentMemUsage) {}
90
91     // creation of message(s)
92     virtual void creation(envelope *, int epIdx, int num=1) {}
93     //epIdx is extracted from the envelope, num is always 1
94     virtual void creation(char *) {}
95     virtual void creationMulticast(envelope *, int epIdx, int num=1,
96                                      int *pelist=NULL) {}
97     virtual void creationDone(int num=1) {}
98     // ???
99     virtual void messageRecv(char *env, int pe) {}
100     virtual void beginSDAGBlock(
101       int event,   // event type defined in trace-common.h
102       int msgType, // message type
103       int ep,      // Charm++ entry point (will correspond to sts file) 
104       int srcPe,   // Which PE originated the call
105       int ml,      // message size
106       CmiObjId* idx)    // index
107     { }
108     virtual void endSDAGBlock(void) {}
109     // **************************************************************
110     // begin/end execution of a Charm++ entry point
111     // NOTE: begin/endPack and begin/endUnpack can be called in between
112     //       a beginExecute and its corresponding endExecute.
113     virtual void beginExecute(envelope *) {}
114     virtual void beginExecute(char *) {}
115     virtual void beginExecute(CmiObjId *tid) {}
116     virtual void beginExecute(
117       int event,   // event type defined in trace-common.h
118       int msgType, // message type
119       int ep,      // Charm++ entry point (will correspond to sts file) 
120       int srcPe,   // Which PE originated the call
121       int ml,      // message size
122       CmiObjId* idx)    // index
123     { }
124     virtual void changeLastEntryTimestamp(double ts) {}
125     virtual void endExecute(void) {}
126     virtual void endExecute(char *) {}
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     // demarkation of a phase boundary
144     virtual void endPhase() {}
145     // clear all data collected for entry points
146     virtual void traceClearEps() {}
147     // enable CCS operations if supported on the trace module
148     virtual void traceEnableCCS() {}
149     // write the summary sts file for this trace
150     virtual void traceWriteSts() {}
151     // do any clean-up necessary for tracing
152     virtual void traceClose() {}
153     // flush log buffer immediately
154     virtual void traceFlushLog() {}
155
156     //for tracing function calls
157     virtual void regFunc(const char *name, int &idx, int idxSpecifiedByUser=0){}
158     virtual void beginFunc(char *name,char *file,int line){}
159     virtual void beginFunc(int idx,char *file,int line){}
160     virtual void endFunc(char *name){}    
161     virtual void endFunc(int idx){}
162
163     /* Memory tracing */
164     virtual void malloc(void *where, int size, void **stack, int stackSize){}
165     virtual void free(void *where, int size){}
166
167     /* for implementing thread listeners */
168     virtual void traceAddThreadListeners(CthThread tid, envelope *e) {}
169
170     virtual ~Trace() {} /* for whining compilers */
171 };
172
173 #define ALLDO(x) for (int i=0; i<length(); i++) if (traces[i]->traceOnPE()) traces[i]->x
174 #define ALLREVERSEDO(x) for (int i=length()-1; i>=0; i--) if (traces[i]->traceOnPE()) traces[i]->x
175
176 /// Array of Traces modules,  every event raised will go through every Trace module.
177 class TraceArray {
178 private:
179   CkVec<Trace *>  traces;
180   int n;
181   int cancel_beginIdle, cancel_endIdle;
182 public:
183     TraceArray(): n(0) {}
184     inline void addTrace(Trace *tr) { traces.push_back(tr); n++;}
185     inline void setTraceOnPE(int flag) { for (int i=0; i<length(); i++) traces[i]->setTraceOnPE(flag); }
186     // to allow traceCLose() to be called multiple times, remove trace module
187     // from the array in each individual trace, and clean up (clearTrace)
188     // after the loop.
189     inline void removeTrace(Trace *tr) {    // remove a Trace from TraceArray
190         int i;
191         for (i=0; i<n; i++) if (tr == traces[i]) break;
192         CmiAssert(i<n);
193         traces[i] = NULL;
194     }
195     inline void clearTrace() {    // remove holes in TraceArray
196         int len = traces.length();
197         int removed = 0;
198         for (int i=0; i<len; i++) {
199           if (traces[i-removed] == NULL) { traces.remove(i-removed); removed++; }
200         }
201         n -= removed;
202     }
203     inline int length() const { return n; }
204
205     inline void userEvent(int e) { ALLDO(userEvent(e));}
206     inline void userBracketEvent(int e,double bt, double et) {ALLDO(userBracketEvent(e,bt,et));}
207     
208         inline void userSuppliedData(int d) { ALLDO(userSuppliedData(d));}
209
210         inline void userSuppliedNote(char *note) { ALLDO(userSuppliedNote(note));}
211         inline void userSuppliedBracketedNote(char *note, int eventID, double bt, double et) {ALLDO(userSuppliedBracketedNote(note, eventID, bt, et));}
212
213
214         inline void memoryUsage(double memUsage) { ALLDO(memoryUsage(memUsage));}
215
216
217     /* Creation needs to access _entryTable, so moved into trace-common.C */
218     void creation(envelope *env, int ep, int num=1);
219     inline void creation(char *msg){
220         /* The check for whether the ep got traced is moved into each elem's
221          * creation call as the ep could not be extracted here
222          */
223         ALLDO(creation(msg));
224     }
225     void creationMulticast(envelope *env, int ep, int num=1, int *pelist=NULL);
226     
227     inline void creationDone(int num=1) { ALLDO(creationDone(num)); }
228     inline void beginSDAGBlock(int event,int msgType,int ep,int srcPe, int mlen,CmiObjId *idx=NULL) {ALLDO(beginSDAGBlock(event, msgType, ep, srcPe, mlen,idx));}
229     inline void endSDAGBlock(void) {ALLREVERSEDO(endExecute());}
230     inline void beginExecute(envelope *env) {ALLDO(beginExecute(env));}
231     inline void beginExecute(char *msg) {ALLDO(beginExecute(msg));}
232     inline void beginExecute(CmiObjId *tid) {ALLDO(beginExecute(tid));}
233     inline void beginExecute(int event,int msgType,int ep,int srcPe, int mlen,CmiObjId *idx=NULL) {ALLDO(beginExecute(event, msgType, ep, srcPe, mlen,idx));}
234     inline void endExecute(void) {ALLREVERSEDO(endExecute());}
235     inline void endExecute(char *msg) {ALLREVERSEDO(endExecute(msg));}
236     inline void changeLastEntryTimestamp(double ts) {ALLDO(changeLastEntryTimestamp(ts));}
237     inline void messageRecv(char *env, int pe) {ALLDO(messageRecv(env, pe));}
238     inline void beginPack(void) {ALLDO(beginPack());}
239     inline void endPack(void) {ALLDO(endPack());}
240     inline void beginUnpack(void) {ALLDO(beginUnpack());}
241     inline void endUnpack(void) {ALLDO(endUnpack());}
242     inline void enqueue(envelope *e) {ALLDO(enqueue(e));}
243     inline void dequeue(envelope *e) {ALLDO(dequeue(e));}
244     inline void beginComputation(void) {ALLDO(beginComputation());}
245     inline void endComputation(void) {ALLDO(endComputation());}
246     inline int traceRegisterUserEvent(const char*x, int evt) {
247           int eno = 0;
248           for (int i=0; i<length(); i++) {
249             if (traces[i]->traceOnPE() == 0) {
250               continue;
251             }
252             int e = traces[i]->traceRegisterUserEvent(x, evt);
253             if (e) eno = e;
254           }
255           return eno;
256     }  
257     inline void traceClearEps() {ALLDO(traceClearEps());}
258     inline void traceEnableCCS() {ALLDO(traceEnableCCS());}
259     inline void traceWriteSts() {ALLDO(traceWriteSts());}
260     inline void traceClose() {ALLDO(traceClose()); clearTrace();}
261     inline void traceFlushLog() {ALLDO(traceFlushLog());}
262     
263     // Tracing module registers *itself* for begin/end idle callbacks:
264     inline void beginIdle(double curWallTime) {ALLDO(beginIdle(curWallTime));}
265     inline void endIdle(double curWallTime) {ALLDO(endIdle(curWallTime));}
266     void traceBegin();    
267     void traceEnd();
268
269     // for tracing comm thread only
270     void traceBeginOnCommThread();
271     void traceEndOnCommThread();
272     void traceCommSetMsgID(char *msg)  { ALLDO(traceCommSetMsgID(msg)); }
273     void traceGetMsgID(char *msg, int *pe, int *event) { ALLDO(traceGetMsgID(msg, pe, event)); }
274     void traceSetMsgID(char *msg, int pe, int event) { ALLDO(traceSetMsgID(msg, pe, event)); }
275     /*Calls for tracing function begins and ends*/
276     inline void regFunc(const char *name, int &idx, int idxSpecifiedByUser=0){ ALLDO(regFunc(name, idx, idxSpecifiedByUser)); }
277     inline void beginFunc(char *name,char *file,int line){ ALLDO(beginFunc(name,file,line)); };
278     inline void beginFunc(int idx,char *file,int line){ ALLDO(beginFunc(idx,file,line)); };
279     inline void endFunc(char *name){ ALLDO(endFunc(name)); }
280     inline void endFunc(int idx){ ALLDO(endFunc(idx)); }
281
282     /* Phase Demarkation */
283     inline void endPhase() { ALLDO(endPhase()); }
284
285     /* Memory tracing */
286     inline void malloc(void *where, int size, void **stack, int stackSize){ ALLDO(malloc(where,size,stack,stackSize)); }
287     inline void free(void *where, int size){ ALLDO(free(where, size)); }
288
289     /* calls for thread listener registration for each trace module */
290     inline void traceAddThreadListeners(CthThread tid, envelope *e) {
291       ALLDO(traceAddThreadListeners(tid, e));
292     }
293 };
294
295 CkpvExtern(TraceArray*, _traces);
296
297 #if CMK_TRACE_ENABLED
298 #if CMK_BIGSIM_CHARM
299 extern void    resetVTime();
300 #  define _TRACE_ONLY(code) do{ BgGetTime(); if(CpvAccess(traceOn) && CkpvAccess(_traces)->length()>0) { code; }  resetVTime(); } while(0)
301 #else
302 #  define _TRACE_ONLY(code) do{if(CpvAccess(traceOn) && CkpvAccess(_traces)->length()>0) { code; }} while(0)
303 #endif
304 #  define _TRACE_ALWAYS(code) do{ code; } while(0)
305 #else
306 #  define _TRACE_ONLY(code) /*empty*/
307 #  define _TRACE_ALWAYS(code) /*empty*/
308 #endif
309
310 extern "C" {
311 #include "conv-trace.h"
312 }
313
314 #define _TRACE_USER_EVENT(x) _TRACE_ONLY(CkpvAccess(_traces)->userEvent(x))
315 #define _TRACE_USER_EVENT_BRACKET(x,bt,et) _TRACE_ONLY(CkpvAccess(_traces)->userBracketEvent(x,bt,et))
316 #define _TRACE_CREATION_1(env) _TRACE_ONLY(CkpvAccess(_traces)->creation(env,env->getEpIdx()))
317 #define _TRACE_CREATION_DETAILED(env,ep) _TRACE_ONLY(CkpvAccess(_traces)->creation(env,ep))
318 #define _TRACE_CREATION_N(env, num) _TRACE_ONLY(CkpvAccess(_traces)->creation(env, env->getEpIdx(), num))
319 #define _TRACE_CREATION_MULTICAST(env, num, pelist) _TRACE_ONLY(CkpvAccess(_traces)->creationMulticast(env, env->getEpIdx(), num, pelist))
320 #define _TRACE_CREATION_DONE(num) _TRACE_ONLY(CkpvAccess(_traces)->creationDone(num))
321 #define _TRACE_BEGIN_SDAG(env) _TRACE_ONLY(CkpvAccess(_traces)->beginSDAGBlock(env))
322 #define _TRACE_END_SDAG(env) _TRACE_ONLY(CkpvAccess(_traces)->endSDAGBlock(env))
323 #define _TRACE_BEGIN_EXECUTE(env) _TRACE_ONLY(CkpvAccess(_traces)->beginExecute(env))
324 #define _TRACE_BEGIN_EXECUTE_DETAILED(evt,typ,ep,src,mlen,idx) _TRACE_ONLY(CkpvAccess(_traces)->beginExecute(evt,typ,ep,src,mlen,idx))
325 #define _TRACE_END_EXECUTE() _TRACE_ONLY(CkpvAccess(_traces)->endExecute())
326 #define _TRACE_MESSAGE_RECV(env, pe) _TRACE_ONLY(CkpvAccess(_traces)->messageRecv(env, pe))
327 #define _TRACE_BEGIN_PACK() _TRACE_ONLY(CkpvAccess(_traces)->beginPack())
328 #define _TRACE_END_PACK() _TRACE_ONLY(CkpvAccess(_traces)->endPack())
329 #define _TRACE_BEGIN_UNPACK() _TRACE_ONLY(CkpvAccess(_traces)->beginUnpack())
330 #define _TRACE_END_UNPACK() _TRACE_ONLY(CkpvAccess(_traces)->endUnpack())
331 #define _TRACE_BEGIN_COMPUTATION() _TRACE_ALWAYS(CkpvAccess(_traces)->beginComputation())
332 #define _TRACE_END_COMPUTATION() _TRACE_ALWAYS(CkpvAccess(_traces)->endComputation())
333 #define _TRACE_ENQUEUE(env) _TRACE_ONLY(CkpvAccess(_traces)->enqueue(env))
334 #define _TRACE_DEQUEUE(env) _TRACE_ONLY(CkpvAccess(_traces)->dequeue(env))
335
336 #define _TRACE_END_PHASE() _TRACE_ONLY(CkpvAccess(_traces)->endPhase())
337
338 /* Memory tracing */
339 #define _TRACE_MALLOC(where, size, stack, stackSize) _TRACE_ONLY(CkpvAccess(_traces)->malloc(where,size,stack,stackSize))
340 #define _TRACE_FREE(where, size) _TRACE_ONLY(CkpvAccess(_traces)->free(where, size))
341
342 #include "trace-bluegene.h"
343
344 #endif
345
346
347 /*@}*/