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