00001
00005
00006 #ifndef _PROJECTIONS_H
00007 #define _PROJECTIONS_H
00008
00009 #include <stdio.h>
00010 #include <errno.h>
00011 #include <unistd.h>
00012 #include <stack>
00013
00014 #include "trace.h"
00015 #include "trace-common.h"
00016 #include "ckhashtable.h"
00017
00018 #if CMK_USE_ZLIB
00019 #include <zlib.h>
00020 #endif
00021
00022 #include "pup.h"
00023
00024 #define PROJECTION_VERSION "10.0"
00025
00026 #define PROJ_ANALYSIS 1
00027
00028
00029 #define CheckAndFPrintF(f,string,data) \
00030 do { \
00031 int result = fprintf(f,string,data); \
00032 if (result == -1) { \
00033 CmiAbort("Projections I/O error!"); \
00034 } \
00035 } while(false)
00036
00038 class LogEntry {
00039 public:
00040 double time;
00041 double endTime;
00042 double cputime;
00043 double recvTime;
00044 int event;
00045 int pe;
00046 unsigned short mIdx;
00047 unsigned short eIdx;
00048 int msglen;
00049 int nestedID;
00050 CmiObjId id;
00051 int numpes;
00052 int *pes;
00053 unsigned long memUsage;
00054 double stat;
00055 char *userSuppliedNote;
00056
00057
00058
00059
00060 #if CMK_HAS_COUNTER_PAPI
00061 LONG_LONG_PAPI papiValues[NUMPAPIEVENTS];
00062 #endif
00063 char *fName;
00064 int flen;
00065 int userSuppliedData;
00066 unsigned char type;
00067
00068 public:
00069
00070 LogEntry() {
00071 fName=NULL;flen=0;pes=NULL;numpes=0;userSuppliedNote = NULL;
00072 }
00073
00074 LogEntry(double tm, unsigned char t, unsigned short m=0,
00075 unsigned short e=0, int ev=0, int p=0, int ml=0,
00076 CmiObjId *d=NULL, double rt=0., double cputm=0., int numPe=0, double statVal=0., int _nestedID=0) {
00077 type = t; mIdx = m; eIdx = e; event = ev; pe = p;
00078 time = tm; msglen = ml; nestedID=_nestedID;
00079 if (d) id = *d; else {id.id[0]=id.id[1]=id.id[2]=id.id[3]=0; };
00080 recvTime = rt; cputime = cputm;
00081
00082 #if CMK_HAS_COUNTER_PAPI
00083
00084 #else
00085
00086 #endif
00087 userSuppliedNote = NULL;
00088 fName = NULL;
00089 flen=0;
00090 pes=NULL;
00091 numpes=numPe;
00092 stat=statVal;
00093 }
00094
00095 LogEntry(double _time,unsigned char _type,unsigned short _funcID,
00096 int _lineNum,char *_fileName){
00097 time = _time;
00098 type = _type;
00099 mIdx = _funcID;
00100 event = _lineNum;
00101 userSuppliedNote = NULL;
00102 pes=NULL;
00103 numpes=0;
00104 setFName(_fileName);
00105 }
00106
00107
00108 LogEntry(double _time,unsigned char _type, int value,
00109 int _lineNum,char *_fileName){
00110 time = _time;
00111 type = _type;
00112 userSuppliedData = value;
00113 userSuppliedNote = NULL;
00114 pes=NULL;
00115 numpes=0;
00116 setFName(_fileName);
00117 }
00118
00119
00120 LogEntry(double _time,unsigned char _type, char* note,
00121 int _lineNum,char *_fileName){
00122 time = _time;
00123 type = _type;
00124 pes=NULL;
00125 numpes=0;
00126 setFName(_fileName);
00127 if(note != NULL)
00128 setUserSuppliedNote(note);
00129 }
00130
00131
00132
00133 LogEntry(double bt, double et, unsigned char _type, char *note, int eventID){
00134 time = bt;
00135 endTime = et;
00136 type = _type;
00137 pes=NULL;
00138 numpes=0;
00139 event = eventID;
00140 if(note != NULL)
00141 setUserSuppliedNote(note);
00142 }
00143
00144
00145
00146 LogEntry(double tm, unsigned short m, unsigned short e, int ev, int p,
00147 int ml, CmiObjId *d, double rt, int numPe, const int *pelist){
00148
00149 type = CREATION_MULTICAST;
00150 mIdx = m;
00151 eIdx = e;
00152 event = ev;
00153 pe = p;
00154 time = tm;
00155 msglen = ml;
00156
00157 if (d) id = *d; else {id.id[0]=id.id[1]=id.id[2]=id.id[3]=-1; };
00158 recvTime = rt;
00159 numpes = numPe;
00160 userSuppliedNote = NULL;
00161 if (pelist != NULL) {
00162 pes = new int[numPe];
00163 for (int i=0; i<numPe; i++) {
00164 pes[i] = pelist[i];
00165 }
00166 } else {
00167 pes= NULL;
00168 }
00169
00170 }
00171
00172
00173 void setFName(char *_fileName){
00174 if(_fileName == NULL){
00175 fName = NULL;
00176 flen = 0;
00177 }else{
00178 fName = new char[strlen(_fileName)+2];
00179 fName[0] = ' ';
00180 memcpy(fName+1,_fileName,strlen(_fileName)+1);
00181 flen = strlen(fName)+1;
00182 }
00183 }
00184
00185
00186 void addPapi(LONG_LONG_PAPI *papiVals){
00187 #if CMK_HAS_COUNTER_PAPI
00188 memcpy(papiValues, papiVals, sizeof(LONG_LONG_PAPI)*NUMPAPIEVENTS);
00189 #endif
00190 }
00191
00192 void setUserSuppliedData(int data){
00193 userSuppliedData = data;
00194 }
00195
00196 void setUserSuppliedNote(char *note){
00197
00198 int length = strlen(note)+1;
00199 userSuppliedNote = new char[length];
00200 memcpy(userSuppliedNote,note,length);
00201 for(int i=0;i<length;i++){
00202 if(userSuppliedNote[i] == '\n' || userSuppliedNote[i] == '\r'){
00203 userSuppliedNote[i] = ' ';
00204 }
00205 }
00206
00207 }
00208
00209
00211 LogEntry(unsigned char _type, double _time, long _memUsage) {
00212 time = _time;
00213 type = _type;
00214 memUsage = _memUsage;
00215 fName = NULL;
00216 flen = 0;
00217 pes=NULL;
00218 numpes=0;
00219 }
00220
00221
00222 void *operator new(size_t s) {void*ret=malloc(s);_MEMCHECK(ret);return ret;}
00223 void *operator new(size_t, void *ptr) { return ptr; }
00224 void operator delete(void *ptr) {free(ptr); }
00225 #if defined(_WIN32) || CMK_MULTIPLE_DELETE
00226 void operator delete(void *, void *) { }
00227 #endif
00228
00229 void setNewStartTime(double t) {
00230 time -= t;
00231 if (endTime>=t) endTime -= t;
00232 if (recvTime>=t) recvTime -= t;
00233 }
00234
00235 void pup(PUP::er &p);
00236 ~LogEntry(){
00237 if (fName) delete [] fName;
00238 if (userSuppliedNote) delete [] userSuppliedNote;
00239 }
00240 };
00241
00242 class TraceProjections;
00243
00245 class LogPool {
00246 friend class TraceProjections;
00247 #ifdef PROJ_ANALYSIS
00248
00249
00250 friend class TraceProjectionsBOC;
00251 friend class KMeansBOC;
00252 #endif //PROJ_ANALYSIS
00253 friend class controlPointManager;
00254 private:
00255 bool writeData;
00256 bool writeSummaryFiles;
00257 bool binary;
00258 bool hasFlushed;
00259 bool headerWritten;
00260 bool fileCreated;
00261 #if CMK_USE_ZLIB
00262 bool compressed;
00263 #endif
00264 unsigned int poolSize;
00265 unsigned int numEntries;
00266 unsigned int lastCreationEvent;
00267 int numPhases;
00268 int nSubdirs;
00269 LogEntry *pool;
00270 FILE *fp;
00271 FILE *deltafp;
00272 FILE *stsfp;
00273 FILE *rcfp;
00274 FILE *statisfp;
00275 char *fname;
00276 char *dfname;
00277 char *pgmname;
00278 #if CMK_USE_ZLIB
00279 gzFile deltazfp;
00280 gzFile zfp;
00281 #endif
00282
00283
00284
00285
00286 double prevTime;
00287 double timeErr;
00288 double globalStartTime;
00289 double globalEndTime;
00290
00291
00292 bool *keepPhase;
00293
00294
00295 double beginComputationTime;
00296 double endComputationTime;
00297 double statisLastTimer;
00298 double statisLastProcessTimer;
00299 double statisLastIdleTimer;
00300 double statisLastPackTimer;
00301 double statisLastUnpackTimer;
00302 double statisTotalExecutionTime;
00303 double statisTotalIdleTime;
00304 double statisTotalPackTime;
00305 double statisTotalUnpackTime;
00306 long long statisTotalCreationMsgs;
00307 long long statisTotalCreationBytes;
00308 long long statisTotalMCastMsgs;
00309 long long statisTotalMCastBytes;
00310 long long statisTotalEnqueueMsgs;
00311 long long statisTotalDequeueMsgs;
00312 long long statisTotalRecvMsgs;
00313 long long statisTotalRecvBytes;
00314 long long statisTotalMemAlloc;
00315 long long statisTotalMemFree;
00316
00317 void writeHeader();
00318
00319 public:
00320 LogPool(char *pgm);
00321 ~LogPool();
00322 void setBinary(int b) { binary = (b!=0); }
00323 void setNumSubdirs(int n) { nSubdirs = n; }
00324 void setWriteSummaryFiles(int n) { writeSummaryFiles = (n!=0)? true : false;}
00325 #if CMK_USE_ZLIB
00326 void setCompressed(int c) { compressed = c; }
00327 #endif
00328 void createFile(const char *fix="");
00329 void createSts(const char *fix="");
00330 void createRC();
00331 void openLog(const char *mode);
00332 void closeLog(void);
00333 void writeLog(void);
00334 void write(int writedelta);
00335 void writeSts(void);
00336 void writeSts(TraceProjections *traceProj);
00337 void writeRC(void);
00338 void writeStatis();
00339 void initializePhases() {
00340 keepPhase = new bool[numPhases];
00341 for (int i=0; i<numPhases; i++) {
00342 keepPhase[i] = true;
00343 }
00344 }
00345
00346 void setAllPhases(bool val) {
00347 for (int i=0; i<numPhases; i++) {
00348 keepPhase[i] = val;
00349 }
00350 }
00351
00352 void add(unsigned char type, unsigned short mIdx, unsigned short eIdx,
00353 double time, int event, int pe, int ml=0, CmiObjId* id=0,
00354 double recvT=0.0, double cpuT=0.0, int numPe=0, double statVal=0.0);
00355
00356
00357
00358 void addPapi(LONG_LONG_PAPI *papVals) {
00359 pool[numEntries-1].addPapi(papVals);
00360 }
00361
00363 void addUserSupplied(int data);
00364
00365 void updateStat(unsigned char type,int e, double cputime,double time,double stat, int pe);
00367 void addUserSuppliedNote(char *note);
00368
00369 void addUserBracketEventNestedID(unsigned char type, double time,
00370 UShort mIdx, int event, int nestedID);
00371
00372
00373 void add(unsigned char type,double time,unsigned short funcID,int lineNum,char *fileName);
00374
00375 void addMemoryUsage(unsigned char type,double time,double memUsage);
00376 void addUserSuppliedBracketedNote(char *note, int eventID, double bt, double et);
00377
00378 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, const int *pelist=NULL);
00379 void flushLogBuffer();
00380 void postProcessLog();
00381
00382 void setWriteData(bool b){
00383 writeData = b;
00384 }
00385 void modLastEntryTimestamp(double ts);
00386
00387 void setNewStartTime() {
00388 for(UInt i=0; i<numEntries; i++) pool[i].setNewStartTime(globalStartTime);
00389 }
00390 };
00391
00392
00393
00394
00395 class StrKey {
00396 char *str;
00397 unsigned int len;
00398 unsigned int key;
00399 public:
00400 StrKey(const char *name){
00401 len = strlen(name);
00402 str = (char *)malloc((len+1)*sizeof(char));
00403 strcpy(str, name);
00404 key = 0;
00405 for(unsigned int i=0;i<len;i++){
00406 key += str[i];
00407 }
00408 }
00409 ~StrKey(){
00410 free(str);
00411 }
00412 static CkHashCode staticHash(const void *k,size_t){
00413 return ((StrKey *)k)->key;
00414 }
00415 static int staticCompare(const void *a,const void *b,size_t){
00416 StrKey *p,*q;
00417 p = (StrKey *)a;
00418 q = (StrKey *)b;
00419 if(p->len != q->len){
00420 return 0;
00421 }
00422 for(unsigned int i=0;i<p->len;i++){
00423 if(p->str[i] != q->str[i]){
00424 return 0;
00425 }
00426 }
00427 return 1;
00428 }
00429 inline CkHashCode hash() const{
00430 return key;
00431 }
00432 inline int compare(const StrKey &t) const {
00433 if(len != t.len){
00434 return 0;
00435 }
00436 for(unsigned int i=0;i<len;i++){
00437 if(str[i] != t.str[i]){
00438 return 0;
00439 }
00440 }
00441 return 1;
00442 }
00443 inline const char *getStr() const {
00444 return str;
00445 }
00446 };
00447
00448 class NestedEvent {
00449 public:
00450 int event, msgType, ep, srcPe, ml;
00451 CmiObjId *idx;
00452 NestedEvent() {}
00453 NestedEvent(int _event, int _msgType, int _ep, int _srcPe, int _ml, CmiObjId *_idx) :
00454 event(_event), msgType(_msgType), ep(_ep), srcPe(_srcPe), ml(_ml), idx(_idx) { }
00455 };
00456
00458
00462 class TraceProjections : public Trace {
00463 #ifdef PROJ_ANALYSIS
00464
00465
00466 friend class TraceProjectionsBOC;
00467 friend class KMeansBOC;
00468 #endif // PROJ_ANALYSIS
00469 private:
00470 LogPool* _logPool;
00471 int curevent;
00472 int execEvent;
00473 int execEp;
00474 int execPe;
00475 bool inEntry;
00476 bool computationStarted;
00477 bool traceNestedEvents;
00478 public:
00479 bool converseExit;
00480 private:
00481 int funcCount;
00482 int currentPhaseID;
00483
00484
00485 std::stack<NestedEvent, std::vector<NestedEvent>> nestedEvents;
00486
00487 LogEntry* lastPhaseEvent;
00488
00489
00490
00491 CkVec<int> idxVec;
00492 int idxRegistered(int idx);
00493 public:
00494 double endTime;
00495
00496 TraceProjections(char **argv);
00497 void userEvent(int e);
00498 void userBracketEvent(int e, double bt, double et, int nestedID );
00499 void beginUserBracketEvent(int e, int nestedID );
00500 void endUserBracketEvent(int e, int nestedID );
00501 void userSuppliedBracketedNote(char*, int, double, double);
00502
00503 void userSuppliedData(int e);
00504 void userSuppliedNote(char* note);
00505 void memoryUsage(double m);
00506
00507 int traceRegisterUserStat(const char*, int);
00508 void updateStatPair(int e, double stat, double time);
00509 void updateStat(int e, double stat);
00510
00511 void creation(envelope *e, int epIdx, int num=1);
00512 void creation(char *m);
00513 void creationMulticast(envelope *e, int epIdx, int num=1, const int *pelist=NULL);
00514 void creationDone(int num=1);
00515 void beginExecute(envelope *e, void *obj=NULL);
00516 void beginExecute(char *msg);
00517 void beginExecute(CmiObjId *tid);
00518 void beginExecute(int event,int msgType,int ep,int srcPe,int ml,CmiObjId *idx=NULL, void *obj=NULL);
00519 void changeLastEntryTimestamp(double ts);
00520 void beginExecuteLocal(int event,int msgType,int ep,int srcPe,int ml,CmiObjId *idx=NULL);
00521 void endExecute(void);
00522 void endExecute(char *msg);
00523 void endExecuteLocal(void);
00524 void messageRecv(char *env, int pe);
00525 void beginIdle(double curWallTime);
00526 void endIdle(double curWallTime);
00527 void beginPack(void);
00528 void endPack(void);
00529 void beginUnpack(void);
00530 void endUnpack(void);
00531 void enqueue(envelope *e);
00532 void dequeue(envelope *e);
00533 void beginComputation(void);
00534 void endComputation(void);
00535
00536 int traceRegisterUserEvent(const char*, int);
00537 void traceClearEps();
00538 void traceWriteSts();
00539 void traceClose();
00540 void traceBegin();
00541 void traceEnd();
00542 #if CMK_SMP_TRACE_COMMTHREAD
00543 void traceBeginOnCommThread();
00544 void traceEndOnCommThread();
00545 #endif
00546 void traceCommSetMsgID(char *msg);
00547 void traceGetMsgID(char *msg, int *pe, int *event);
00548 void traceSetMsgID(char *msg, int pe, int event);
00549 void traceFlushLog() { _logPool->flushLogBuffer(); }
00550
00551
00552
00553
00554 void endPhase();
00555
00556
00557 void closeTrace(void);
00558
00559 void setWriteData(bool b){
00560 _logPool->setWriteData(b);
00561 }
00562
00563
00564 virtual void traceAddThreadListeners(CthThread tid, envelope *e);
00565 };
00566
00567 using namespace PUP;
00568
00569 class toProjectionsFile : public toTextFile {
00570 protected:
00571 virtual void bytes(void *p,size_t n,size_t itemSize,dataType t);
00572 public:
00573
00574 toProjectionsFile(FILE *f_) :toTextFile(f_) {}
00575 };
00576 class fromProjectionsFile : public fromTextFile {
00577 protected:
00578 virtual void bytes(void *p,size_t n,size_t itemSize,dataType t);
00579 public:
00580
00581 fromProjectionsFile(FILE *f_) :fromTextFile(f_) {}
00582 };
00583
00584 #if CMK_USE_ZLIB
00585 class toProjectionsGZFile : public PUP::er {
00586 gzFile f;
00587 protected:
00588 virtual void bytes(void *p,size_t n,size_t itemSize,dataType t);
00589 public:
00590
00591 toProjectionsGZFile(gzFile f_) :er(IS_PACKING), f(f_) {}
00592 };
00593 #endif
00594
00595
00596
00597
00598 #if CMK_TRACE_ENABLED
00600 void disableTraceLogOutput();
00601
00603 void enableTraceLogOutput();
00604
00605 #else
00606 static inline void disableTraceLogOutput() { }
00607 static inline void enableTraceLogOutput() { }
00608 #endif
00609
00610 #endif
00611