5bb523d8335931aaa7901626eda165d27ce38373
[charm.git] / src / ck-perf / trace-projections.h
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 /**
9  * \addtogroup CkPerf
10 */
11 /*@{*/
12
13 #ifndef _PROJECTIONS_H
14 #define _PROJECTIONS_H
15
16 #include <stdio.h>
17 #include <errno.h>
18 #include <unistd.h>
19
20 #include "trace.h"
21 #include "envelope.h"
22 #include "register.h"
23 #include "ckhashtable.h"
24 #include "trace-common.h"
25
26 #if CMK_HAS_COUNTER_PAPI
27 #include <papi.h>
28 #endif
29
30 #if CMK_PROJECTIONS_USE_ZLIB
31 #include <zlib.h>
32 #endif
33
34 #include "pup.h"
35
36 #define PROJECTION_VERSION  "6.6"
37
38 // Macro to make projections check for errors before an fprintf succeeds.
39 #define CheckAndFPrintF(f,string,data) \
40 { \
41   int result = fprintf(f,string,data); \
42   if (result == -1) { \
43     CmiAbort("Projections I/O error!"); \
44   } \
45 }
46
47 /// a log entry in trace projection
48 class LogEntry {
49   public:
50     double time;
51     double cputime;
52     double recvTime;
53     int event;
54     int pe;
55     unsigned short mIdx;
56     unsigned short eIdx;
57     int msglen;
58     CmiObjId   id;
59     int numpes;
60     int *pes;
61     // this is taken out so as to provide a placeholder value for non-PAPI
62     // versions (whose value is *always* zero).
63     int numPapiEvents;
64 #if CMK_HAS_COUNTER_PAPI
65     int *papiIDs;
66     LONG_LONG_PAPI *papiValues;
67 #endif
68     unsigned char type; 
69     char *fName;
70     int flen;
71   public:
72     LogEntry() {fName=NULL;flen=0;}
73     LogEntry(double tm, unsigned char t, unsigned short m=0, unsigned short e=0, int ev=0, int p=0, int ml=0, CmiObjId *d=NULL, double rt=0., double cputm=0.) {
74       type = t; mIdx = m; eIdx = e; event = ev; pe = p; time = tm; msglen = ml;
75       if (d) id = *d; else {id.id[0]=id.id[1]=id.id[2]=0; };
76       recvTime = rt; cputime = cputm;
77       // initialize for papi as well as non papi versions.
78       numPapiEvents = 0;
79 #if CMK_HAS_COUNTER_PAPI
80       papiIDs = NULL;
81       papiValues = NULL;
82 #endif
83     }
84     LogEntry(double _time,unsigned char _type,unsigned short _funcID,int _lineNum,char *_fileName){
85                         time = _time;
86                         type = _type;
87                         mIdx = _funcID;
88                         event = _lineNum;
89                         if(_fileName == NULL){
90                                 fName = NULL;
91                                 flen = 0;
92                         }else{
93                                 fName = new char[strlen(_fileName)+2];
94                                 fName[0] = ' ';
95                                 memcpy(fName+1,_fileName,strlen(_fileName)+1);
96                                 flen = strlen(fName)+1;
97                         }       
98                 }
99     // **CW** new constructor for multicast data
100     LogEntry(double tm, unsigned short m, unsigned short e, int ev, int p,
101              int ml, CmiObjId *d, double rt, int num, int *pelist);
102     // complementary function for adding papi data
103     void addPapi( int numPapiEvts, int *papi_ids, LONG_LONG_PAPI *papiVals);
104     void *operator new(size_t s) {void*ret=malloc(s);_MEMCHECK(ret);return ret;}
105     void *operator new(size_t, void *ptr) { return ptr; }
106     void operator delete(void *ptr) {free(ptr); }
107 #if defined(WIN32) || CMK_MULTIPLE_DELETE
108     void operator delete(void *, void *) { }
109 #endif
110     void pup(PUP::er &p);
111     ~LogEntry(){
112       delete [] fName;
113     }
114 };
115
116 class TraceProjections;
117
118 /// log pool in trace projection
119 class LogPool {
120   friend class TraceProjections;
121   friend class TraceProjectionsBOC;
122   private:
123     bool writeData;
124     unsigned int poolSize;
125     unsigned int numEntries;
126     LogEntry *pool;
127     FILE *fp;
128     FILE *deltafp;
129     FILE *stsfp;
130     FILE *rcfp;
131     char *fname;
132     char *dfname;
133     char *pgmname;
134     int binary;
135 #if CMK_PROJECTIONS_USE_ZLIB
136     gzFile deltazfp;
137     gzFile zfp;
138     int compressed;
139 #endif
140     // **CW** prevTime stores the timestamp of the last event
141     // written out to log. This allows the implementation of
142     // simple delta encoding and should only be used when
143     // writing out logs.
144     double prevTime;
145     double timeErr;
146     double globalEndTime; // used at the end on Pe 0 only
147
148     int headerWritten;
149     bool fileCreated;
150     void writeHeader();
151   public:
152     LogPool(char *pgm);
153     ~LogPool();
154     void setBinary(int b) { binary = b; }
155 #if CMK_PROJECTIONS_USE_ZLIB
156     void setCompressed(int c) { compressed = c; }
157 #endif
158     void createFile(char *fix="");
159     void createSts(char *fix="");
160     void createRC();
161     void openLog(const char *mode);
162     void closeLog(void);
163     void writeLog(void);
164     void write(int writedelta);
165     void writeSts(void);
166     void writeSts(TraceProjections *traceProj);
167     void writeRC(void);
168
169     void add(unsigned char type,unsigned short mIdx,unsigned short eIdx,double time,int event,int pe, int ml=0, CmiObjId* id=0, double recvT=0., double cpuT=0.0);
170       // complementary function to set papi info to current log entry
171       // must be called after an add()
172     void addPapi(int numPap, int *pap_ids, LONG_LONG_PAPI *papVals) {
173       pool[numEntries-1].addPapi(numPap, pap_ids, papVals);
174     }
175     void add(unsigned char type,double time,unsigned short funcID,int lineNum,char *fileName);
176     void addCreationMulticast(unsigned short mIdx,unsigned short eIdx,double time,int event,int pe, int ml=0, CmiObjId* id=0, double recvT=0., int num=0, int *pelist=NULL);
177     void flushLogBuffer();
178     void postProcessLog();
179 };
180
181 /*
182         class that represents a key in a CkHashtable with a string as a key
183 */
184 class StrKey {
185         char *str;
186         int len;
187         unsigned int key;
188         public:
189         StrKey(char *_str,int _len){
190                 str = _str;
191                 len = _len;
192                 key = 0;
193                 for(int i=0;i<len;i++){
194                         key += str[i];
195                 }
196         }
197         static CkHashCode staticHash(const void *k,size_t){
198                 return ((StrKey *)k)->key;
199         }
200         static int staticCompare(const void *a,const void *b,size_t){
201                 StrKey *p,*q;
202                 p = (StrKey *)a;
203                 q = (StrKey *)b;
204                 if(p->len != q->len){
205                         return 0;
206                 }
207                 for(int i=0;i<p->len;i++){
208                         if(p->str[i] != q->str[i]){
209                                 return 0;
210                         }
211                 }
212                 return 1;
213         }
214         inline CkHashCode hash() const{
215                 return key;
216         }
217         inline int compare(const StrKey &t) const {
218                 if(len != t.len){
219                         return 0;
220                 }
221                 for(int i=0;i<len;i++){
222                         if(str[i] != t.str[i]){
223                                 return 0;
224                         }       
225                 }
226                 return 1;
227         }
228         inline char *getStr(){
229                 return str;
230         }
231 };
232
233 /// class for recording trace projections events 
234 /**
235   TraceProjections will log Converse/Charm++ events and write into .log files;
236   events descriptions will be written into .sts file.
237 */
238 class TraceProjections : public Trace {
239   friend class TraceProjectionsBOC;
240  private:
241     LogPool* _logPool;        /**<  logpool for all events */
242     int curevent;
243     int execEvent;
244     int execEp;
245     int execPe;
246     int inEntry;
247     int computationStarted;
248
249     int funcCount;
250     CkHashtableT<StrKey,int> funcHashtable;
251     
252     //as user now can specify the idx, it's possible that user may specify an existing idx
253     //so that we need a data structure to track idx. --added by Chao Mei
254     CkVec<int> idxVec;
255     int idxRegistered(int idx);    
256 #if CMK_HAS_COUNTER_PAPI
257     int papiEventSet;
258     LONG_LONG_PAPI *papiValues;
259 #endif
260
261   public:
262     int converseExit; // used for exits that bypass CkExit.
263     double endTime;
264
265     TraceProjections(char **argv);
266     void userEvent(int e);
267     void userBracketEvent(int e, double bt, double et);
268     void creation(envelope *e, int epIdx, int num=1);
269     void creationMulticast(envelope *e, int epIdx, int num=1, int *pelist=NULL);
270     void creationDone(int num=1);
271     void beginExecute(envelope *e);
272     void beginExecute(CmiObjId  *tid);
273     void beginExecute(int event,int msgType,int ep,int srcPe,int ml,CmiObjId *idx=NULL);
274     void endExecute(void);
275     void messageRecv(char *env, int pe);
276     void beginIdle(double curWallTime);
277     void endIdle(double curWallTime);
278     void beginPack(void);
279     void endPack(void);
280     void beginUnpack(void);
281     void endUnpack(void);
282     void enqueue(envelope *e);
283     void dequeue(envelope *e);
284     void beginComputation(void);
285     void endComputation(void);
286
287     int traceRegisterUserEvent(const char*, int);
288     void traceClearEps();
289     void traceWriteSts();
290     void traceClose();
291     void traceBegin();
292     void traceEnd();
293     void traceFlushLog() { _logPool->flushLogBuffer(); }
294
295     //functions that perform function tracing
296     CkHashtableIterator *getfuncIterator(){return funcHashtable.iterator();};
297     int getFuncNumber(){return funcHashtable.numObjects();};
298     void regFunc(const char *name, int &idx, int idxSpecifiedByUser=0);
299     void beginFunc(char *name,char *file,int line);
300     void beginFunc(int idx,char *file,int line);
301     void endFunc(char *name);
302     void endFunc(int num);
303
304     /* This is for moving projections to being a charm++ module */
305     void closeTrace(void);
306
307     /* for overiding basic thread listener support in Trace class */
308     virtual void traceAddThreadListeners(CthThread tid, envelope *e);
309 };
310
311 using namespace PUP;
312
313 class toProjectionsFile : public toTextFile {
314  protected:
315   virtual void bytes(void *p,int n,size_t itemSize,dataType t);
316  public:
317   //Begin writing to this file, which should be opened for ascii write.
318   toProjectionsFile(FILE *f_) :toTextFile(f_) {}
319 };
320 class fromProjectionsFile : public fromTextFile {
321  protected:
322   virtual void bytes(void *p,int n,size_t itemSize,dataType t);
323  public:
324   //Begin writing to this file, which should be opened for ascii read.
325   fromProjectionsFile(FILE *f_) :fromTextFile(f_) {}
326 };
327
328 #if CMK_PROJECTIONS_USE_ZLIB
329 class toProjectionsGZFile : public PUP::er {
330   gzFile f;
331  protected:
332   virtual void bytes(void *p,int n,size_t itemSize,dataType t);
333  public:
334   //Begin writing to this gz file, which should be opened for gz write.
335   toProjectionsGZFile(gzFile f_) :er(IS_PACKING), f(f_) {}
336 };
337 #endif
338
339
340 #endif
341
342 /*@}*/