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