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