added a hook for bluegene to connect the projections logs with bglogs. This allows...
authorGengbin Zheng <gzheng@illinois.edu>
Fri, 12 Sep 2003 23:04:23 +0000 (23:04 +0000)
committerGengbin Zheng <gzheng@illinois.edu>
Fri, 12 Sep 2003 23:04:23 +0000 (23:04 +0000)
also migrating the output part to pup, wrote a special text PUP::er for projecitons logs. The projections reader can be used in POSE bg simulator.
More cleanup to go.

src/ck-perf/trace-bluegene.C
src/ck-perf/trace-bluegene.h
src/ck-perf/trace-projections.C
src/ck-perf/trace-projections.h

index 3f74b91d541fb5733a197601e9c4f18ef28a6481..e2d62ff347a71da4c5e29d5325193a48ac84663d 100644 (file)
@@ -192,7 +192,7 @@ void TraceBluegene::traceWriteSts(){
 
 void TraceBluegene::bgPrint(char* str){
   if (!genTimeLog) return;
-  bgAddProjEvent(strdup(str), BgGetTime(), writeData, this, 2);
+  bgAddProjEvent(strdup(str), -1, BgGetTime(), writeData, this, 2);
 
 }
 
index 5b18955dc39c69977552a64427c134970f90d38d..7808c928d6560f51bce6762dbd7705c579a04a05 100644 (file)
@@ -54,6 +54,8 @@ extern int traceBluegeneLinked;
 #  define _TRACE_BG_ONLY(code) /*empty*/
 #endif
 
+/* tracing for Blue Gene - before trace projector era */
+#if !defined(CMK_OPTIMIZE) && CMK_TRACE_IN_CHARM
 // for Sdag only
 // fixme - think of better api for tracing sdag code
 #define BgPrint(x)  _TRACE_BG_ONLY(CkpvAccess(_tracebg)->bgPrint(x))
@@ -66,8 +68,6 @@ extern int traceBluegeneLinked;
 #define _TRACE_BG_USER_EVENT_BRACKET(x,bt,et,pLogPtr) _TRACE_BG_ONLY(CkpvAccess(_tracebg)->userBracketEvent(x,bt,et,pLogPtr))
 #define _TRACE_BGLIST_USER_EVENT_BRACKET(x,bt,et,pLogPtr,bgLogList) _TRACE_BG_ONLY(CkpvAccess(_tracebg)->userBracketEvent(x,bt,et,pLogPtr,bgLogList))
 
-/* tracing for Blue Gene - before trace projector era */
-#if !defined(CMK_OPTIMIZE) && CMK_TRACE_IN_CHARM
 # define TRACE_BG_SUSPEND()     \
         if(CpvAccess(traceOn)) traceSuspend();  \
         _TRACE_BG_END_EXECUTE(1);
@@ -87,6 +87,8 @@ extern int traceBluegeneLinked;
         }      \
        }
 #else
+# define _TRACE_BG_TLINE_END(x)
+
 # define TRACE_BG_SUSPEND()
 # define TRACE_BG_RESUME(t, msg)
 # define TRACE_BG_START(t, str)
index 36eabdb76b2574378a58cb9f0a5b05b6e7e7b8b4..9fbcb7f55a4045b75cacea909f751a0fad47b8c9 100644 (file)
@@ -12,6 +12,8 @@
 /*@{*/
 
 #include "charm++.h"
+#include "ck.h"
+#include "trace-common.h"
 #include "trace-projections.h"
 
 #define DEBUGF(x)           // CmiPrintf x
@@ -231,27 +233,6 @@ void LogPool::creatFiles(char *fix)
   }
 #endif
   openLog("w+");
-  if(!binary) {
-#if CMK_PROJECTIONS_USE_ZLIB
-    if(compressed) {
-      if (nonDeltaLog) {
-       gzprintf(zfp, "PROJECTIONS-RECORD\n");
-      }
-      if (deltaLog) {
-       gzprintf(deltazfp, "PROJECTIONS-RECORD DELTA\n");
-      }
-    } 
-    else /* else clause is below... */
-#endif
-    /*... may hang over from else above */ {
-      if (nonDeltaLog) {
-       fprintf(fp, "PROJECTIONS-RECORD\n");
-      }
-      if (deltaLog) {
-       fprintf(deltafp, "PROJECTIONS-RECORD DELTA\n");
-      }
-    }
-  }
   CLOSE_LOG 
 
   if (CkMyPe() == 0) 
@@ -266,6 +247,7 @@ void LogPool::creatFiles(char *fix)
       CmiAbort("Cannot open projections sts file for writing.\n");
     delete[] fname;
   }
+  headerWritten = 0;
 }
 
 LogPool::~LogPool() 
@@ -277,6 +259,7 @@ LogPool::~LogPool()
   if (correctTimeLog) {
     closeLog();
     creatFiles("-bg");
+    writeHeader();
     if (CkMyPe() == 0) writeSts();
     postProcessLog();
   }
@@ -289,9 +272,45 @@ LogPool::~LogPool()
   delete [] fname;
 }
 
+void LogPool::writeHeader()
+{
+  if (headerWritten) return;
+  headerWritten = 1;
+  if(!binary) {
+#if CMK_PROJECTIONS_USE_ZLIB
+    if(compressed) {
+      if (nonDeltaLog) {
+       gzprintf(zfp, "PROJECTIONS-RECORD %d\n", numEntries);
+      }
+      if (deltaLog) {
+       gzprintf(deltazfp, "PROJECTIONS-RECORD %d DELTA\n", numEntries);
+      }
+    } 
+    else /* else clause is below... */
+#endif
+    /*... may hang over from else above */ {
+      if (nonDeltaLog) {
+       fprintf(fp, "PROJECTIONS-RECORD %d\n", numEntries);
+      }
+      if (deltaLog) {
+       fprintf(deltafp, "PROJECTIONS-RECORD %d DELTA\n", numEntries);
+      }
+    }
+  }
+  else { // binary
+      if (nonDeltaLog) {
+        fwrite(&numEntries,sizeof(numEntries),1,fp);
+      }
+      if (deltaLog) {
+        fwrite(&numEntries,sizeof(numEntries),1,deltafp);
+      }
+  }
+}
+
 void LogPool::writeLog(void)
 {
   OPEN_LOG
+  writeHeader();
   if(binary) writeBinary();
 #if CMK_PROJECTIONS_USE_ZLIB
   else if(compressed) writeCompressed();
@@ -306,9 +325,10 @@ void LogPool::write(void)
   // prevTime has to be maintained as an object variable because
   // LogPool::write may be called several times depending on the
   // +logsize value.
+  toProjectionsFile p(fp);
   for(UInt i=0; i<numEntries; i++) {
     if (nonDeltaLog) {
-      pool[i].write(fp); // for non-delta implementation
+      pool[i].pup(p);
     }
     if (deltaLog) {
       prevTime = pool[i].write(deltafp, prevTime, &timeErr);
@@ -319,8 +339,15 @@ void LogPool::write(void)
 void LogPool::writeBinary(void) {
   // **CW** The binary format does not benefit from delta encoding
   // hence it will not employ prevTime.
+#if 0
   for(UInt i=0; i<numEntries; i++)
     pool[i].writeBinary(fp);
+#else
+  PUP::toDisk p(fp);
+  for(UInt i=0; i<numEntries; i++) {
+      pool[i].pup(p);
+  }
+#endif
 }
 
 #if CMK_PROJECTIONS_USE_ZLIB
@@ -355,7 +382,9 @@ static void updateProjLog(void *data, double t, double recvT, void *ptr)
   FILE *fp = *(FILE **)ptr;
   log->time = t;
   log->recvTime = recvT<0.0?0:recvT;
-  log->write(fp);
+//  log->write(fp);
+  toProjectionsFile p(fp);
+  log->pup(p);
 }
 #endif
 
@@ -387,7 +416,7 @@ void LogPool::add(UChar type,UShort mIdx,UShort eIdx,double time,int event,int p
     case BEGIN_UNPACK:
     case END_UNPACK:
     case USER_EVENT_PAIR:
-      bgAddProjEvent(&pool[numEntries-1], time, updateProjLog, &fp, 1);
+      bgAddProjEvent(&pool[numEntries-1], numEntries-1, time, updateProjLog, &fp, 1);
   }
 #endif
 }
@@ -422,34 +451,34 @@ void LogPool::postProcessLog()
 #endif
 }
 
-// **CW** Wrapper method for backward compatible signature (and behavior)
-// of the write method.
-void LogEntry::write(FILE* fp)
+LogEntry::LogEntry(double tm, unsigned short m, unsigned short e, int ev, int p,
+            int ml, CmiObjId *d, double rt, int num, int *pelist) 
 {
-  // the error value is ignored here
-  double dummyErr = 0.0;
-  write(fp, 0.0, &dummyErr);
+    type = CREATION_MULTICAST; mIdx = m; eIdx = e; event = ev; pe = p; time = tm; msglen = ml;
+    if (d) id = *d; else {id.id[0]=id.id[1]=id.id[2]=0; };
+    recvTime = rt; 
+    numpes = num;
+    if (pelist != NULL) {
+       pes = new int[num];
+       for (int i=0; i<num; i++) {
+         pes[i] = pelist[i];
+       }
+    } else {
+       pes= NULL;
+    }
 }
 
-// **CW** Simple delta encoding implementation. The timestamp of the current
-// entry is returned and passed to the next entry's write call.
-double LogEntry::write(FILE* fp, double prevTime, double *timeErr)
+void LogEntry::pup(PUP::er &p)
 {
-  fprintf(fp, "%d ", type);
-
-  // **CW** Hopefully a correct time correction algorithm
-  double timeDiff = (time-prevTime)*1.0e6;
-  UInt intTimeDiff = (UInt)timeDiff;
-  *timeErr += timeDiff - intTimeDiff; // timeErr is never >= 2.0
-  if (*timeErr > 1.0) {
-    *timeErr -= 1.0;
-    intTimeDiff++;
-  }
+  int itime, irecvtime;
+  char ret = '\n';
 
+  p|type;
+  if (p.isPacking()) itime = (int)(1.0e6*time);
   switch (type) {
     case USER_EVENT:
     case USER_EVENT_PAIR:
-      fprintf(fp, "%d %u %d %d\n", mIdx, intTimeDiff, event, pe);
+      p|mIdx; p|itime; p|event; p|pe;
       break;
     case BEGIN_IDLE:
     case END_IDLE:
@@ -457,43 +486,46 @@ double LogEntry::write(FILE* fp, double prevTime, double *timeErr)
     case END_PACK:
     case BEGIN_UNPACK:
     case END_UNPACK:
-      fprintf(fp, "%u %d\n", intTimeDiff, pe);
+      p|itime; p|pe; 
       break;
     case BEGIN_PROCESSING:
-      fprintf(fp, "%d %d %u %d %d %d %d %d %d %d\n", mIdx, eIdx, 
-             intTimeDiff, event, pe, msglen, (UInt)(recvTime*1.e6), 
-             id.id[0], id.id[1], id.id[2]);
+      if (p.isPacking()) irecvtime = (int)(1.0e6*recvTime);
+      p|mIdx; p|eIdx; p|itime; p|event; p|pe; 
+      p|msglen; p|irecvtime; p|id.id[0]; p|id.id[1]; p|id.id[2];
+      if (p.isUnpacking()) recvTime = irecvtime/1.0e6;
       break;
     case CREATION:
-      fprintf(fp, "%d %d %u %d %d %d %d\n", mIdx, eIdx, intTimeDiff, 
-             event, pe, msglen, (UInt)(recvTime*1.e6));
+      if (p.isPacking()) irecvtime = (int)(1.0e6*recvTime);
+      p|mIdx; p|eIdx; p|itime;
+      p|event; p|pe; p|msglen; p|irecvtime;
+      if (p.isUnpacking()) recvTime = irecvtime/1.0e6;
       break;
     case CREATION_MULTICAST:
-      fprintf(fp, "%d %d %u %d %d %d %d %d ", mIdx, eIdx, intTimeDiff, 
-             event, pe, msglen, (UInt)(recvTime*1.e6), numpes);
+      if (p.isPacking()) irecvtime = (int)(1.0e6*recvTime);
+      p|mIdx; p|eIdx; p|itime;
+      p|event; p|pe; p|msglen; p|irecvtime; p|numpes;
       if (pes == NULL) {
-       fprintf(fp, "-1\n");
-      } else {
-       for (int i=0; i<numpes; i++) {
-         fprintf(fp, "%d ", pes[i]);
-       }
-       fprintf(fp, "\n");
+        int n=-1;
+        p(n);
       }
+      else {
+       for (int i=0; i<numpes; i++) p|pes[i];
+      }
+      if (p.isUnpacking()) recvTime = irecvtime/1.0e6;
       break;
     case END_PROCESSING:
     case MESSAGE_RECV:
-      fprintf(fp, "%d %d %u %d %d %d\n", mIdx, eIdx, intTimeDiff,
-             event, pe, msglen);
+      p|mIdx; p|eIdx; p|itime; p|event; p|pe; p|msglen;
       break;
 
     case ENQUEUE:
     case DEQUEUE:
-      fprintf(fp, "%d %u %d %d\n", mIdx, intTimeDiff, event, pe);
+      p|mIdx; p|itime; p|event; p|pe;
       break;
 
     case BEGIN_INTERRUPT:
     case END_INTERRUPT:
-      fprintf(fp, "%u %d %d\n", intTimeDiff, event, pe);
+      p|itime; p|event; p|pe;
       break;
 
       // **CW** absolute timestamps are used here to support a quick
@@ -501,14 +533,108 @@ double LogEntry::write(FILE* fp, double prevTime, double *timeErr)
       // visualization.
     case BEGIN_COMPUTATION:
     case END_COMPUTATION:
-      fprintf(fp, "%u\n", (UInt)(time*1.e6));
+      p|itime;
       break;
 
     default:
       CmiError("***Internal Error*** Wierd Event %d.\n", type);
       break;
   }
-  return time;
+  if (p.isUnpacking()) time = itime/1.0e6;
+  p|ret;
+}
+
+// **CW** Wrapper method for backward compatible signature (and behavior)
+// of the write method.
+void LogEntry::write(FILE* fp)
+{
+  // the error value is ignored here
+  double dummyErr = 0.0;
+  write(fp, 0.0, &dummyErr);
+}
+
+// **CW** Simple delta encoding implementation. The timestamp of the current
+// entry is returned and passed to the next entry's write call.
+#define write_LogEntry(fp, printfn)    \
+{  \
+  printfn(fp, "%d ", type);  \
+  \
+  double timeDiff = (time-prevTime)*1.0e6;  \
+  UInt intTimeDiff = (UInt)timeDiff;  \
+  *timeErr += timeDiff - intTimeDiff; /* timeErr is never >= 2.0 */ \
+  if (*timeErr > 1.0) {  \
+    *timeErr -= 1.0;  \
+    intTimeDiff++;  \
+  }  \
+  \
+  switch (type) {  \
+    case USER_EVENT:  \
+    case USER_EVENT_PAIR:  \
+      printfn(fp, "%d %u %d %d\n", mIdx, intTimeDiff, event, pe);  \
+      break;  \
+    case BEGIN_IDLE:  \
+    case END_IDLE:  \
+    case BEGIN_PACK:  \
+    case END_PACK:  \
+    case BEGIN_UNPACK:  \
+    case END_UNPACK:  \
+      printfn(fp, "%u %d\n", intTimeDiff, pe);  \
+      break;  \
+    case BEGIN_PROCESSING:  \
+      printfn(fp, "%d %d %u %d %d %d %d %d %d %d\n", mIdx, eIdx,   \
+             intTimeDiff, event, pe, msglen, (UInt)(recvTime*1.e6),   \
+             id.id[0], id.id[1], id.id[2]);  \
+      break;  \
+    case CREATION:  \
+      printfn(fp, "%d %d %u %d %d %d %d\n", mIdx, eIdx, intTimeDiff,   \
+             event, pe, msglen, (UInt)(recvTime*1.e6));  \
+      break;  \
+    case CREATION_MULTICAST:  \
+      printfn(fp, "%d %d %u %d %d %d %d %d ", mIdx, eIdx, intTimeDiff,   \
+             event, pe, msglen, (UInt)(recvTime*1.e6), numpes);  \
+      if (pes == NULL) {  \
+       printfn(fp, "-1\n");  \
+      } else {  \
+       for (int i=0; i<numpes; i++) {  \
+         printfn(fp, "%d ", pes[i]);  \
+       }  \
+       printfn(fp, "\n");  \
+      }  \
+      break;  \
+    case END_PROCESSING:  \
+    case MESSAGE_RECV:  \
+      printfn(fp, "%d %d %u %d %d %d\n", mIdx, eIdx, intTimeDiff,  \
+             event, pe, msglen);  \
+      break;  \
+  \
+    case ENQUEUE:  \
+    case DEQUEUE:  \
+      printfn(fp, "%d %u %d %d\n", mIdx, intTimeDiff, event, pe);  \
+      break;  \
+  \
+    case BEGIN_INTERRUPT:  \
+    case END_INTERRUPT:  \
+      printfn(fp, "%u %d %d\n", intTimeDiff, event, pe);  \
+      break;  \
+  \
+      /* **CW** absolute timestamps are used here to support a quick  \
+      // way of determining the total time of a run in projections  \
+      // visualization.  */ \
+    case BEGIN_COMPUTATION:  \
+    case END_COMPUTATION:  \
+      printfn(fp, "%u\n", (UInt)(time*1.e6));  \
+      break;  \
+  \
+    default:  \
+      CmiError("***Internal Error*** Wierd Event %d.\n", type);  \
+      break;  \
+  }  \
+  return time;  \
+}
+
+double LogEntry::write(FILE* fp, double prevTime, double *timeErr)
+{
+  write_LogEntry(fp, fprintf);
 }
 
 #if CMK_PROJECTIONS_USE_ZLIB
@@ -521,70 +647,12 @@ void LogEntry::writeCompressed(gzFile zfp)
 
 double LogEntry::writeCompressed(gzFile zfp, double prevTime, double *timeErr)
 {
-  gzprintf(zfp, "%d ", type);
-
-  // **CW** Hopefully a correct time correction algorithm
-  double timeDiff = (time-prevTime)*1.0e6;
-  UInt intTimeDiff = (UInt)timeDiff;
-  *timeErr += timeDiff - intTimeDiff; // timeErr is never >= 2.0
-  if (*timeErr > 1.0) {
-    *timeErr -= 1.0;
-    intTimeDiff++;
-  }
-
-  switch (type) {
-    case USER_EVENT:
-    case USER_EVENT_PAIR:
-      gzprintf(zfp, "%d %u %d %d\n", mIdx, intTimeDiff, event, pe);
-      break;
-
-    case BEGIN_IDLE:
-    case END_IDLE:
-    case BEGIN_PACK:
-    case END_PACK:
-    case BEGIN_UNPACK:
-    case END_UNPACK:
-      gzprintf(zfp, "%u %d\n", intTimeDiff, pe);
-      break;
-
-    case CREATION:
-      gzprintf(zfp, "%d %d %u %d %d %d %d\n", mIdx, eIdx, intTimeDiff, event, 
-              pe, msglen, (UInt)(recvTime*1.e6));
-      break;
-      
-    case BEGIN_PROCESSING:
-    case END_PROCESSING:
-    case MESSAGE_RECV:
-      gzprintf(zfp, "%d %d %u %d %d %d\n", mIdx, eIdx, intTimeDiff, event, 
-              pe, msglen);
-      break;
-
-    case ENQUEUE:
-    case DEQUEUE:
-      gzprintf(zfp, "%d %u %d %d\n", mIdx, intTimeDiff, event, pe);
-      break;
-      
-    case BEGIN_INTERRUPT:
-    case END_INTERRUPT:
-      gzprintf(zfp, "%u %d %d\n", intTimeDiff, event, pe);
-      break;
-
-      // **CW** absolute timestamps are used here to support a quick
-      // way of determining the total time of a run in projections
-      // visualization.
-    case BEGIN_COMPUTATION:
-    case END_COMPUTATION:
-      gzprintf(zfp, "%u\n", (UInt)(time*1.e6));
-      break;
-
-    default:
-      CmiError("***Internal Error*** Wierd Event %d.\n", type);
-      break;
-  }
-  return time;
+  write_LogEntry(zfp, gzprintf);
 }
 #endif
 
+#if 0
+// use pup now
 void LogEntry::writeBinary(FILE* fp)
 {
   UInt ttime = (UInt) (time*1.0e6);
@@ -657,6 +725,7 @@ void LogEntry::writeBinary(FILE* fp)
       break;
   }
 }
+#endif
 
 TraceProjections::TraceProjections(char **argv): curevent(0), isIdle(0), inEntry(0)
 {
@@ -695,22 +764,6 @@ TraceProjections::TraceProjections(char **argv): curevent(0), isIdle(0), inEntry
   _logPool->creatFiles();
 }
 
-/*
-old version
-int TraceProjections::traceRegisterUserEvent(const char* evt, int e=-1)
-{
-  OPTIMIZED_VERSION
-  if(CkMyPe()==0) {
-    CkAssert(evt != NULL);
-    CkAssert(CkpvAccess(usrEventlist).length() ==  _numEvents);
-    CkpvAccess(usrEventlist).push_back((char *)evt);
-    return _numEvents++;
-  }
-  else
-    return 0;
-}
-*/
-
 int TraceProjections::traceRegisterUserEvent(const char* evt, int e)
 {
   OPTIMIZED_VERSION
@@ -959,4 +1012,49 @@ void TraceProjections::endComputation(void)
   _logPool->add(END_COMPUTATION, 0, 0, TraceTimer(), -1, -1);
 }
 
+// special PUP:ers for handling trace projections logs
+void toProjectionsFile::bytes(void *p,int n,size_t itemSize,dataType t)
+{
+  for (int i=0;i<n;i++) 
+    switch(t) {
+    case Tchar: fprintf(f,"%c",((char *)p)[i]); break;
+    case Tuchar:
+    case Tbyte: fprintf(f,"%d",((unsigned char *)p)[i]); break;
+    case Tshort: fprintf(f," %d",((short *)p)[i]); break;
+    case Tushort: fprintf(f," %u",((unsigned short *)p)[i]); break;
+    case Tint: fprintf(f," %d",((int *)p)[i]); break;
+    case Tuint: fprintf(f," %u",((unsigned int *)p)[i]); break;
+    case Tlong: fprintf(f," %ld",((long *)p)[i]); break;
+    case Tulong: fprintf(f," %lu",((unsigned long *)p)[i]); break;
+    case Tfloat: fprintf(f," %.7g",((float *)p)[i]); break;
+    case Tdouble: fprintf(f," %.15g",((double *)p)[i]); break;
+    default: CmiAbort("Unrecognized pup type code!");
+    };
+}
+
+void fromProjectionsFile::bytes(void *p,int n,size_t itemSize,dataType t)
+{
+  for (int i=0;i<n;i++) 
+    switch(t) {
+    case Tchar: { 
+      char c = fgetc(f);
+      if (c==EOF)
+       parseError("Could not match character");
+      else
+        ((char *)p)[i] = c;
+      break;
+    }
+    case Tuchar:
+    case Tbyte: ((unsigned char *)p)[i]=(unsigned char)readInt("%d"); break;
+    case Tshort:((short *)p)[i]=(short)readInt(); break;
+    case Tushort: ((unsigned short *)p)[i]=(unsigned short)readUint(); break;
+    case Tint:  ((int *)p)[i]=readInt(); break;
+    case Tuint: ((unsigned int *)p)[i]=readUint(); break;
+    case Tlong: ((long *)p)[i]=readInt(); break;
+    case Tulong:((unsigned long *)p)[i]=readUint(); break;
+    case Tfloat: ((float *)p)[i]=(float)readDouble(); break;
+    case Tdouble:((double *)p)[i]=readDouble(); break;
+    default: CmiAbort("Unrecognized pup type code!");
+    };
+}
 /*@}*/
index 85b0228397d92bf7811bc7ce6e445e6b4a199447..2f51906aaa4ecd9fc9878838771cd95739308a76 100644 (file)
@@ -14,7 +14,6 @@
 #define _PROJECTIONS_H
 
 #include "trace.h"
-#include "ck.h"
 #include "stdio.h"
 #include "errno.h"
 
 #include <zlib.h>
 #endif
 
-#include "trace-common.h"
-#include "trace-projector.h"
+#include "pup.h"
 
-#define PROJECTION_VERSION  "5.0"
+#define PROJECTION_VERSION  "6.0"
 
 /// a log entry in trace projection
 class LogEntry {
@@ -33,9 +31,9 @@ class LogEntry {
     double time;
     int event;
     int pe;
-    UShort mIdx;
-    UShort eIdx;
-    UChar type; 
+    unsigned short mIdx;
+    unsigned short eIdx;
+    unsigned char type; 
     int msglen;
     double recvTime;
     CmiObjId   id;
@@ -43,27 +41,14 @@ class LogEntry {
     int *pes;
   public:
     LogEntry() {}
-    LogEntry(double tm, UChar t, UShort m=0, UShort e=0, int ev=0, int p=0, int ml=0, CmiObjId *d=NULL, double rt=0.) {
+    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.) {
       type = t; mIdx = m; eIdx = e; event = ev; pe = p; time = tm; msglen = ml;
       if (d) id = *d; else {id.id[0]=id.id[1]=id.id[2]=0; };
       recvTime = rt; 
     }
     // **CW** new constructor for multicast data
-    LogEntry(double tm, UShort m, UShort e, int ev, int p,
-            int ml, CmiObjId *d, double rt, int num, int *pelist) {
-      type = CREATION_MULTICAST; mIdx = m; eIdx = e; event = ev; pe = p; time = tm; msglen = ml;
-      if (d) id = *d; else {id.id[0]=id.id[1]=id.id[2]=0; };
-      recvTime = rt; 
-      numpes = num;
-      if (pelist != NULL) {
-       pes = new int[num];
-       for (int i=0; i<num; i++) {
-         pes[i] = pelist[i];
-       }
-      } else {
-       pes= NULL;
-      }
-    }
+    LogEntry(double tm, unsigned short m, unsigned short e, int ev, int p,
+            int ml, CmiObjId *d, double rt, int num, int *pelist);
     void *operator new(size_t s) {void*ret=malloc(s);_MEMCHECK(ret);return ret;}
     void *operator new(size_t, void *ptr) { return ptr; }
     void operator delete(void *ptr) { free(ptr); }
@@ -81,14 +66,15 @@ class LogEntry {
     // **CW** Simple delta encoding implementation
     double writeCompressed(gzFile fp, double prevTime, double *timeErr);
 #endif
+    void pup(PUP::er &p);
 };
 
 /// log pool in trace projection
 class LogPool {
   friend class TraceProjections;
   private:
-    UInt poolSize;
-    UInt numEntries;
+    unsigned int poolSize;
+    unsigned int numEntries;
     LogEntry *pool;
     FILE *fp;
     FILE *deltafp;
@@ -108,6 +94,9 @@ class LogPool {
     // writing out logs.
     double prevTime;
     double timeErr;
+
+    int headerWritten;
+    void writeHeader();
   public:
     LogPool(char *pgm);
     ~LogPool();
@@ -125,8 +114,8 @@ class LogPool {
     void writeCompressed(void);
 #endif
     void writeSts(void);
-    void add(UChar type,UShort mIdx,UShort eIdx,double time,int event,int pe, int ml=0, CmiObjId* id=0, double recvT=0.);
-    void addCreationMulticast(UShort mIdx,UShort eIdx,double time,int event,int pe, int ml=0, CmiObjId* id=0, double recvT=0., int num=0, int *pelist=NULL);
+    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.);
+    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);
     void postProcessLog();
 };
 
@@ -175,6 +164,25 @@ class TraceProjections : public Trace {
     void traceEnd();
 };
 
+using namespace PUP;
+
+class toProjectionsFile : public toTextFile {
+ protected:
+  virtual void bytes(void *p,int n,size_t itemSize,dataType t);
+ public:
+  //Begin writing to this file, which should be opened for ascii write.
+  // Closes file when deleted.
+  toProjectionsFile(FILE *f_) :toTextFile(f_) {}
+};
+class fromProjectionsFile : public fromTextFile {
+ protected:
+  virtual void bytes(void *p,int n,size_t itemSize,dataType t);
+ public:
+  //Begin writing to this file, which should be opened for ascii read.
+  // Closes file when deleted.
+  fromProjectionsFile(FILE *f_) :fromTextFile(f_) {}
+};
+
 
 #endif