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