ck-perf/trace-projections.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * $Source: /cvsroot/charm/src/ck-perf/trace-projections.h,v $
00003  * $Author: idooley2 $
00004  * $Date: 2008-02-04 22:20:47 $
00005  * $Revision: 2.72 $
00006  *****************************************************************************/
00007 
00012 
00013 #ifndef _PROJECTIONS_H
00014 #define _PROJECTIONS_H
00015 
00016 #include <stdio.h>
00017 #include <errno.h>
00018 #include <unistd.h>
00019 
00020 #include "trace.h"
00021 #include "ckhashtable.h"
00022 
00023 #if CMK_HAS_COUNTER_PAPI
00024 #include <papi.h>
00025 #endif
00026 
00027 #if CMK_PROJECTIONS_USE_ZLIB
00028 #include <zlib.h>
00029 #endif
00030 
00031 #include "pup.h"
00032 
00033 #define PROJECTION_VERSION  "7.0"
00034 
00035 // Macro to make projections check for errors before an fprintf succeeds.
00036 #define CheckAndFPrintF(f,string,data) \
00037 { \
00038   int result = fprintf(f,string,data); \
00039   if (result == -1) { \
00040     CmiAbort("Projections I/O error!"); \
00041   } \
00042 }
00043 
00045 class LogEntry {
00046   public:
00047     double time;
00048     double cputime;
00049     double recvTime;
00050     int event;
00051     int pe;
00052     unsigned short mIdx;
00053     unsigned short eIdx;
00054     int msglen;
00055     CmiObjId   id;
00056     int numpes;
00057     int *pes;
00058         int userSuppliedData;
00059         unsigned long memUsage;
00060 
00061     // this is taken out so as to provide a placeholder value for non-PAPI
00062     // versions (whose value is *always* zero).
00063     int numPapiEvents;
00064 #if CMK_HAS_COUNTER_PAPI
00065     int *papiIDs;
00066     LONG_LONG_PAPI *papiValues;
00067 #endif
00068     unsigned char type; 
00069     char *fName;
00070     int flen;
00071   public:
00072     LogEntry() {fName=NULL;flen=0;pes=NULL;numpes=0;}
00073     LogEntry(double tm, unsigned char t, unsigned short m=0, 
00074              unsigned short e=0, int ev=0, int p=0, int ml=0, 
00075              CmiObjId *d=NULL, double rt=0., double cputm=0., int numPe=0) {
00076       type = t; mIdx = m; eIdx = e; event = ev; pe = p; 
00077       time = tm; msglen = ml;
00078       if (d) id = *d; else {id.id[0]=id.id[1]=id.id[2]=id.id[3]=0; };
00079       recvTime = rt; cputime = cputm;
00080       // initialize for papi as well as non papi versions.
00081       numPapiEvents = 0;
00082 #if CMK_HAS_COUNTER_PAPI
00083       papiIDs = NULL;
00084       papiValues = NULL;
00085 #endif
00086       fName = NULL; flen=0;
00087       pes=NULL;
00088       numpes=numPe;
00089     }
00090     LogEntry(double _time,unsigned char _type,unsigned short _funcID,
00091              int _lineNum,char *_fileName){
00092       time = _time;
00093       type = _type;
00094       mIdx = _funcID;
00095       event = _lineNum;
00096       if(_fileName == NULL){
00097         fName = NULL;
00098         flen = 0;
00099       }else{
00100         fName = new char[strlen(_fileName)+2];
00101         fName[0] = ' ';
00102         memcpy(fName+1,_fileName,strlen(_fileName)+1);
00103         flen = strlen(fName)+1;
00104       } 
00105       pes=NULL;numpes=0;
00106     }
00107 
00108         // Constructor for User Supplied Data
00109         LogEntry(double _time,unsigned char _type, int value,
00110              int _lineNum,char *_fileName){
00111       time = _time;
00112       type = _type;
00113       userSuppliedData = value;
00114       if(_fileName == NULL){
00115                 fName = NULL;
00116                 flen = 0;
00117       }else{
00118                 fName = new char[strlen(_fileName)+2];
00119                 fName[0] = ' ';
00120                 memcpy(fName+1,_fileName,strlen(_fileName)+1);
00121                 flen = strlen(fName)+1;
00122       } 
00123       pes=NULL;numpes=0;
00124     }
00125 
00126     // **CW** new constructor for multicast data
00127     LogEntry(double tm, unsigned short m, unsigned short e, int ev, int p,
00128              int ml, CmiObjId *d, double rt, int numPe, int *pelist);
00129     // complementary function for adding papi data
00130     void addPapi( int numPapiEvts, int *papi_ids, LONG_LONG_PAPI *papiVals);
00131         void setUserSuppliedData(int data){
00132           userSuppliedData = data;
00133         }
00134 
00136         LogEntry(unsigned char _type, double _time, long _memUsage) {
00137             time = _time;
00138                 type = _type;
00139                 memUsage = _memUsage;
00140                 fName = NULL;
00141                 flen = 0;
00142                 pes=NULL;
00143                 numpes=0;
00144         }
00145 
00146 
00147     void *operator new(size_t s) {void*ret=malloc(s);_MEMCHECK(ret);return ret;}
00148     void *operator new(size_t, void *ptr) { return ptr; }
00149     void operator delete(void *ptr) {free(ptr); }
00150 #if defined(WIN32) || CMK_MULTIPLE_DELETE
00151     void operator delete(void *, void *) { }
00152 #endif
00153     void pup(PUP::er &p);
00154     ~LogEntry(){
00155       if (fName) delete [] fName;
00156     }
00157 };
00158 
00159 class TraceProjections;
00160 
00162 class LogPool {
00163   friend class TraceProjections;
00164   friend class TraceProjectionsBOC;
00165   private:
00166     bool writeData;
00167     unsigned int poolSize;
00168     unsigned int numEntries;
00169     LogEntry *pool;
00170     FILE *fp;
00171     FILE *deltafp;
00172     FILE *stsfp;
00173     FILE *rcfp;
00174     char *fname;
00175     char *dfname;
00176     char *pgmname;
00177     int binary;
00178 #if CMK_PROJECTIONS_USE_ZLIB
00179     gzFile deltazfp;
00180     gzFile zfp;
00181     int compressed;
00182 #endif
00183     // **CW** prevTime stores the timestamp of the last event
00184     // written out to log. This allows the implementation of
00185     // simple delta encoding and should only be used when
00186     // writing out logs.
00187     double prevTime;
00188     double timeErr;
00189     double globalEndTime; // used at the end on Pe 0 only
00190 
00191     int headerWritten;
00192     bool fileCreated;
00193     void writeHeader();
00194   public:
00195     LogPool(char *pgm);
00196     ~LogPool();
00197     void setBinary(int b) { binary = b; }
00198 #if CMK_PROJECTIONS_USE_ZLIB
00199     void setCompressed(int c) { compressed = c; }
00200 #endif
00201     void createFile(char *fix="");
00202     void createSts(char *fix="");
00203     void createRC();
00204     void openLog(const char *mode);
00205     void closeLog(void);
00206     void writeLog(void);
00207     void write(int writedelta);
00208     void writeSts(void);
00209     void writeSts(TraceProjections *traceProj);
00210     void writeRC(void);
00211 
00212     void add(unsigned char type, unsigned short mIdx, unsigned short eIdx,
00213              double time, int event, int pe, int ml=0, CmiObjId* id=0, 
00214              double recvT=0.0, double cpuT=0.0, int numPe=0);
00215 
00216     // complementary function to set papi info to current log entry
00217     // must be called after an add()
00218     void addPapi(int numPap, int *pap_ids, LONG_LONG_PAPI *papVals) {
00219       pool[numEntries-1].addPapi(numPap, pap_ids, papVals);
00220     }
00221 
00223         void addUserSupplied(int data);
00224 
00225     void add(unsigned char type,double time,unsigned short funcID,int lineNum,char *fileName);
00226   
00227         void addMemoryUsage(unsigned char type,double time,double memUsage);
00228    
00229     void addCreationMulticast(unsigned short mIdx,unsigned short eIdx,double time,int event,int pe, int ml=0, CmiObjId* id=0, double recvT=0., int numPe=0, int *pelist=NULL);
00230     void flushLogBuffer();
00231     void postProcessLog();
00232 };
00233 
00234 /*
00235         class that represents a key in a CkHashtable with a string as a key
00236 */
00237 class StrKey {
00238         char *str;
00239         int len;
00240         unsigned int key;
00241         public:
00242         StrKey(char *_str,int _len){
00243                 str = _str;
00244                 len = _len;
00245                 key = 0;
00246                 for(int i=0;i<len;i++){
00247                         key += str[i];
00248                 }
00249         }
00250         static CkHashCode staticHash(const void *k,size_t){
00251                 return ((StrKey *)k)->key;
00252         }
00253         static int staticCompare(const void *a,const void *b,size_t){
00254                 StrKey *p,*q;
00255                 p = (StrKey *)a;
00256                 q = (StrKey *)b;
00257                 if(p->len != q->len){
00258                         return 0;
00259                 }
00260                 for(int i=0;i<p->len;i++){
00261                         if(p->str[i] != q->str[i]){
00262                                 return 0;
00263                         }
00264                 }
00265                 return 1;
00266         }
00267         inline CkHashCode hash() const{
00268                 return key;
00269         }
00270         inline int compare(const StrKey &t) const {
00271                 if(len != t.len){
00272                         return 0;
00273                 }
00274                 for(int i=0;i<len;i++){
00275                         if(str[i] != t.str[i]){
00276                                 return 0;
00277                         }       
00278                 }
00279                 return 1;
00280         }
00281         inline char *getStr(){
00282                 return str;
00283         }
00284 };
00285 
00287 
00291 class TraceProjections : public Trace {
00292   friend class TraceProjectionsBOC;
00293  private:
00294     LogPool* _logPool;        
00295     int curevent;
00296     int execEvent;
00297     int execEp;
00298     int execPe;
00299     int inEntry;
00300     int computationStarted;
00301 
00302     int funcCount;
00303     CkHashtableT<StrKey,int> funcHashtable;
00304     
00305     //as user now can specify the idx, it's possible that user may specify an existing idx
00306     //so that we need a data structure to track idx. --added by Chao Mei
00307     CkVec<int> idxVec;
00308     int idxRegistered(int idx);    
00309 #if CMK_HAS_COUNTER_PAPI
00310     int papiEventSet;
00311     LONG_LONG_PAPI *papiValues;
00312 #endif
00313 
00314   public:
00315     int converseExit; // used for exits that bypass CkExit.
00316     double endTime;
00317 
00318     TraceProjections(char **argv);
00319     void userEvent(int e);
00320     void userBracketEvent(int e, double bt, double et);
00321     void userSuppliedData(int e);
00322     void memoryUsage(double m);
00323     void creation(envelope *e, int epIdx, int num=1);
00324     void creationMulticast(envelope *e, int epIdx, int num=1, int *pelist=NULL);
00325     void creationDone(int num=1);
00326     void beginExecute(envelope *e);
00327     void beginExecute(CmiObjId  *tid);
00328     void beginExecute(int event,int msgType,int ep,int srcPe,int ml,CmiObjId *idx=NULL);
00329     void endExecute(void);
00330     void messageRecv(char *env, int pe);
00331     void beginIdle(double curWallTime);
00332     void endIdle(double curWallTime);
00333     void beginPack(void);
00334     void endPack(void);
00335     void beginUnpack(void);
00336     void endUnpack(void);
00337     void enqueue(envelope *e);
00338     void dequeue(envelope *e);
00339     void beginComputation(void);
00340     void endComputation(void);
00341 
00342     int traceRegisterUserEvent(const char*, int);
00343     void traceClearEps();
00344     void traceWriteSts();
00345     void traceClose();
00346     void traceBegin();
00347     void traceEnd();
00348     void traceFlushLog() { _logPool->flushLogBuffer(); }
00349 
00350     //functions that perform function tracing
00351     CkHashtableIterator *getfuncIterator(){return funcHashtable.iterator();};
00352     int getFuncNumber(){return funcHashtable.numObjects();};
00353     void regFunc(const char *name, int &idx, int idxSpecifiedByUser=0);
00354     void beginFunc(char *name,char *file,int line);
00355     void beginFunc(int idx,char *file,int line);
00356     void endFunc(char *name);
00357     void endFunc(int num);
00358 
00359     /* This is for moving projections to being a charm++ module */
00360     void closeTrace(void);
00361 
00362     /* for overiding basic thread listener support in Trace class */
00363     virtual void traceAddThreadListeners(CthThread tid, envelope *e);
00364 };
00365 
00366 using namespace PUP;
00367 
00368 class toProjectionsFile : public toTextFile {
00369  protected:
00370   virtual void bytes(void *p,int n,size_t itemSize,dataType t);
00371  public:
00372   //Begin writing to this file, which should be opened for ascii write.
00373   toProjectionsFile(FILE *f_) :toTextFile(f_) {}
00374 };
00375 class fromProjectionsFile : public fromTextFile {
00376  protected:
00377   virtual void bytes(void *p,int n,size_t itemSize,dataType t);
00378  public:
00379   //Begin writing to this file, which should be opened for ascii read.
00380   fromProjectionsFile(FILE *f_) :fromTextFile(f_) {}
00381 };
00382 
00383 #if CMK_PROJECTIONS_USE_ZLIB
00384 class toProjectionsGZFile : public PUP::er {
00385   gzFile f;
00386  protected:
00387   virtual void bytes(void *p,int n,size_t itemSize,dataType t);
00388  public:
00389   //Begin writing to this gz file, which should be opened for gz write.
00390   toProjectionsGZFile(gzFile f_) :er(IS_PACKING), f(f_) {}
00391 };
00392 #endif
00393 
00394 
00395 #endif
00396 

Generated on Sun Jun 29 13:29:10 2008 for Charm++ by  doxygen 1.5.1