src/Profile/utils/tau_convert.c

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 /*********************************************************************/
00017 /*                  pC++/Sage++  Copyright (C) 1994                  */
00018 /*  Indiana University  University of Oregon  University of Rennes   */
00019 /*********************************************************************/
00020 
00021 /*
00022  * pcxx_convert.c : convert software event traces to other formats
00023  *
00024  * (c) 1994 Jerry Manic Saftware
00025  *
00026  * Version 3.0
00027  */
00028 
00029 # include <stdio.h>
00030 # include <stdlib.h>
00031 # include <sys/types.h>
00032 # include <fcntl.h>
00033 # include <unistd.h>
00034 
00035 # include <string.h>
00036 
00037 # define TRACING_ON
00038 # define PCXX_EVENT_SRC
00039 
00040 # ifdef __PCXX__
00041 #   include "Profile/pcxx_events_def.h"
00042 # else
00043 #   include "Profile/pcxx_events.h"
00044 # endif
00045 # include "Profile/pcxx_ansi.h"
00046 
00047 # ifndef TRUE
00048 #   define FALSE  0
00049 #   define TRUE   1
00050 # endif
00051 
00052 # define F_EXISTS    0
00053 
00054 static struct trcdescr
00055 {
00056   int     fd;              /* -- input file descriptor                     -- */
00057   char   *name;            /* -- corresponding file name                   -- */
00058   int     overflows;       /* -- clock overflows in that trace             -- */
00059   int     numevent;        /* -- number of event types                     -- */
00060   int     numproc;         /* -- number of processors                      -- */
00061   long    numrec;          /* -- number of event records already processed -- */
00062   unsigned long firsttime; /* -- timestamp of first event record           -- */
00063   unsigned long lasttime;  /* -- timestamp of previous event record        -- */
00064 
00065   PCXX_EV  *buffer;   /* -- input buffer                              -- */
00066   PCXX_EV  *erec;     /* -- current event record                      -- */
00067   PCXX_EV  *next;     /* -- next available event record in buffer     -- */
00068   PCXX_EV  *last;     /* -- last event record in buffer               -- */
00069 } intrc;
00070 
00071 static enum format_t { alog, SDDF, pv, dump } outFormat = pv;
00072 static enum pvmode_t { user, pvclass, all } pvMode = user;
00073 static int pvCompact = FALSE;
00074 static int pvComm = TRUE;
00075 
00076 static int dynamictrace = FALSE;
00077 
00078 static char *barrin, *barrout;  /* -- for barrier checking -- */
00079 static int numin, numout;       /* -- for barrier checking -- */
00080 
00081 static struct stkitem
00082 {
00083   char *state;  /* -- state name ---- */
00084   int tag;      /* -- activity tag -- */
00085 }
00086 **statestk,     /* -- state stacks -- */
00087 **stkptr;       /* -- stack pointers -- */
00088 
00089 # define STACKSIZE 1024
00090 
00091 /* -------------------------------------------------------------------------- */
00092 /* -- event type descriptor handling                                       -- */
00093 /* -------------------------------------------------------------------------- */
00094 typedef struct evdescr {
00095   int no;
00096   int id;
00097   int tag;
00098   int used;
00099   char *name;
00100   char *param;
00101   char *state;
00102   struct evdescr *next;
00103 } EVDESCR;
00104 
00105 static EVDESCR **evtable;
00106 static int evno;
00107 static int numEvent;
00108 static int numUsedEvent;
00109 
00110 static void InitEvent (int numev)
00111 {
00112   int i;
00113 
00114   evtable = (EVDESCR **) malloc (numev * sizeof(EVDESCR));
00115   for (i=0; i<numev; i++) evtable[i] = NULL;
00116   evno     = 1;
00117   numEvent = numev;
00118   numUsedEvent = 0;
00119 }
00120 
00121 static void AddEvent (int id, char *name, char *p, char *state, int tag)
00122 {
00123   int h;
00124   char *ptr;
00125   EVDESCR *newev;
00126 
00127   newev = (EVDESCR *) malloc (sizeof(EVDESCR));
00128   newev->id   = id;
00129   newev->tag  = tag;
00130   newev->no   = evno++;
00131   newev->used = FALSE;
00132   newev->name = (char *) malloc (strlen(name) + 1); strcpy (newev->name, name);
00133   if ( *p && outFormat != pv )
00134   {
00135     newev->param = (char *) malloc (strlen(p) + 5);
00136     if ( outFormat == alog )
00137       sprintf (newev->param, "%s: %%d", p);
00138     else
00139       sprintf (newev->param, "%s", p);
00140   }
00141   else
00142     newev->param = "";
00143   if ( state[0] != '-' )
00144   {
00145     if ( tag > 0 && pvMode == all )
00146     {
00147       newev->name[strlen(newev->name)-6] = '\0';
00148       if ( (ptr = strchr(newev->name, ':')) == NULL )
00149         ptr = newev->name;
00150       else
00151         ptr += 2;
00152       newev->state = (char *) malloc (strlen(ptr) + 1);
00153       strcpy (newev->state, ptr);
00154       newev->name[strlen(newev->name)] = '-';
00155     }
00156     else
00157     {
00158       newev->state = (char *) malloc (strlen(state) + 1);
00159       strcpy (newev->state, state);
00160     }
00161   }
00162   else
00163     newev->state = "";
00164 
00165   h = id % numEvent;
00166   newev->next = evtable[h];
00167   evtable[h] = newev;
00168 }
00169 
00170 static void AddEventDynamic (int id, char *name, char *p, char *state, int tag)
00171 {
00172   int h;
00173   char *ptr;
00174   EVDESCR *newev;
00175 
00176 #ifdef DEBUG
00177   printf("Adding id %d name %s par %s state %s tag %d\n",
00178         id, name, p, state, tag);
00179 #endif /* DEBUG */
00180   newev = (EVDESCR *) malloc (sizeof(EVDESCR));
00181   if (newev == (EVDESCR *) NULL) {
00182     fprintf(stderr,"AddEventDynamic : out of memory malloc returns NULL\n");
00183     exit(1);
00184   }
00185   newev->id   = id;
00186   newev->tag  = tag;
00187   newev->no   = evno++;
00188   newev->used = FALSE;
00189   newev->name = (char *) malloc (strlen(name) + 1); strcpy (newev->name, name);
00190   if ( *p && outFormat != pv )
00191   {
00192     newev->param = (char *) malloc (strlen(p) + 5);
00193     if ( outFormat == alog )
00194       sprintf (newev->param, "%s: %%d", p);
00195     else
00196       sprintf (newev->param, "%s", p);
00197   }
00198   else
00199     newev->param = "";
00200   if ( state[0] != '-' )
00201   {
00202     newev->state = (char *) malloc (strlen(state) + 1);
00203     strcpy (newev->state, state);
00204   }
00205   else
00206     newev->state = "";
00207 
00208   h = id % numEvent;
00209   newev->next = evtable[h];
00210   evtable[h] = newev;
00211 }
00212 
00213 static EVDESCR *GetEventStruct (int id)
00214 {
00215   int h;
00216   EVDESCR *ev;
00217 
00218   h = id % numEvent;
00219   ev = evtable[h];
00220 
00221   while ( ev )
00222   {
00223     if ( ev->id == id ) return (ev);
00224     ev = ev->next;
00225   }
00226   return (0);
00227 }
00228 
00229 static int GetEvent (int id)
00230 {
00231   int h;
00232   EVDESCR *ev;
00233 
00234   h = id % numEvent;
00235   ev = evtable[h];
00236 
00237   while ( ev )
00238   {
00239     if ( ev->id == id )
00240     {
00241       if ( !ev->used ) { ev->used = TRUE; numUsedEvent++; }
00242       return (ev->no);
00243     }
00244     ev = ev->next;
00245   }
00246   return (0);
00247 }
00248 
00249 static char *GetEventName (int id, int *hasParam)
00250 {
00251   int h;
00252   EVDESCR *ev;
00253 
00254   h = id % numEvent;
00255   ev = evtable[h];
00256 
00257   while ( ev )
00258   {
00259     if ( ev->id == id ) { *hasParam = ev->param[0]; return (ev->name); }
00260     ev = ev->next;
00261   }
00262   *hasParam = FALSE;
00263   return (0);
00264 }
00265 
00266 static void PrintEventDescr (FILE *out)
00267 {
00268   int i;
00269   EVDESCR *ev;
00270 
00271   for (i=0; i<numEvent; i++)
00272   {
00273     ev = evtable[i];
00274     while ( ev )
00275     {
00276       if ( ev->used )
00277       {
00278         if ( outFormat == alog )
00279         {
00280           fprintf (out, " -9   0 0 %10d 0          0 %s\n", ev->no, ev->name);
00281           fprintf (out, "-10   0 0 %10d 0          0 %s\n", ev->no, ev->param);
00282         }
00283         else if ( outFormat == SDDF )
00284         {
00285           fprintf (out, "#%d:\n", ev->no);
00286           fprintf (out, "\"%s\" {\n", ev->name);
00287           fprintf (out, "\tint\t\"Timestamp\";\n");
00288           fprintf (out, "\tint\t\"Processor Number\";\n");
00289           fprintf (out, "\tint\t\"Thread Id\";\n");
00290           if ( ev->param[0] ) fprintf (out, "\tint\t\"%s\";\n", ev->param);
00291           fprintf (out, "};;\n\n", ev->name);
00292         }
00293         else if ( outFormat == pv )
00294         {
00295           if (! dynamictrace) 
00296           {
00297             if ( ev->tag > 0 || ev->tag < -9 )
00298             {
00299               ev->name[strlen(ev->name)-6] = '\0';
00300               /*fprintf (out, "SYMBOL %s %d %s\n", ev->state, ev->tag, ev->name);*/
00301               fprintf (out, "SYMBOL %s %d %s\n", ev->state, ev->no, ev->name);
00302               ev->name[strlen(ev->name)] = '-';
00303             }
00304           }
00305           else /* don't do anything special for dynamic trace */
00306           {  
00307               fprintf (out, "SYMBOL %s %d %s\n", ev->state, ev->no, ev->name);
00308           } 
00309 
00310         }
00311       }
00312       ev = ev->next;
00313     }
00314   }
00315 }
00316 
00317 /* -------------------------------------------------------------------------- */
00318 /* -- is it an INIT event ?                                                -- */
00319 /* -------------------------------------------------------------------------- */
00320 
00321 int isInitEvent(PCXX_EV *erecord)
00322 {
00323   char *eventName;
00324   int hasParam;
00325  
00326   eventName = GetEventName(erecord->ev, &hasParam);
00327 
00328   if (dynamictrace)
00329   {
00330     if (strcmp(eventName, "\"EV_INIT\"") == 0) 
00331     {
00332       return TRUE;
00333     }
00334     else
00335     {
00336       return FALSE;
00337     }
00338   } 
00339   else
00340   { /* old traces use events determined by fixed #define nos. */
00341     if  ( (erecord->ev == PCXX_EV_INIT) || (erecord->ev == PCXX_EV_INITM) )
00342     {
00343       return TRUE;
00344     }
00345     else
00346     {
00347       return FALSE;
00348     }
00349   } /* old format */
00350 }
00351 
00352 
00353 
00354 /* -------------------------------------------------------------------------- */
00355 /* -- get today's date                                                     -- */
00356 /* -------------------------------------------------------------------------- */
00357 # include <time.h>
00358 
00359 static char tibuf[12];
00360 static char *Months[12] =
00361 {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
00362 
00363 static char *Today (void)
00364 {
00365   time_t t;
00366   struct tm *tm;
00367 
00368   t = time ((time_t *) 0);
00369   tm = localtime (&t);
00370   sprintf (tibuf, "%s-%02d-%02d", Months[tm->tm_mon], tm->tm_mday, tm->tm_year);
00371   return (tibuf);
00372 }
00373 
00374 /* -------------------------------------------------------------------------- */
00375 /* -- input buffer handling                                                -- */
00376 /* -------------------------------------------------------------------------- */
00377 # define INMAX    BUFSIZ   /* records */
00378 
00379 static PCXX_EV *get_next_rec (struct trcdescr *tdes)
00380 {
00381   long no;
00382 
00383   if ( (tdes->last == NULL) || (tdes->next > tdes->last) )
00384   {
00385     /* -- input buffer empty: read new records from file -------------------- */
00386     if ( (no = read (tdes->fd, tdes->buffer, INMAX * sizeof(PCXX_EV)))
00387          != (INMAX * sizeof(PCXX_EV)) )
00388     {
00389       if ( no == 0 )
00390       {
00391         /* -- no more event record: ----------------------------------------- */
00392         close (tdes->fd);
00393         tdes->fd = -1;
00394         return (NULL);
00395       }
00396       else if ( (no % sizeof(PCXX_EV)) != 0 )
00397       {
00398         /* -- read error: --------------------------------------------------- */
00399         fprintf (stderr, "%s: read error\n", tdes->name);
00400         exit (1);
00401       }
00402     }
00403 
00404     /* -- we got some event records ----------------------------------------- */
00405     tdes->next = tdes->buffer;
00406     tdes->last = tdes->buffer + (no / sizeof(PCXX_EV)) - 1;
00407   }
00408   return (tdes->erec = tdes->next++);
00409 }
00410 
00411 /* -------------------------------------------------------------------------- */
00412 /* -- PCXX_CONVERT MAIN PROGRAM --------------------------------------------- */
00413 /* -------------------------------------------------------------------------- */
00414 
00415 # define LINEMAX 64*1024
00416 
00417 int main (int argc, char *argv[])
00418 {
00419   FILE *outfp, *inev;
00420   PCXX_EV *erec;
00421   int i,j,k;
00422   int num;
00423   int tag;
00424   int hasParam;
00425   int fileIdx;
00426   int numproc = 0;
00427   char name[80], state[80], param[80], linebuf[LINEMAX];
00428   char traceflag[32];
00429   char *inFile, *edfFile, *outFile, *ptr;
00430   EVDESCR *ev;
00431 
00432   /* ------------------------------------------------------------------------ */
00433   /* -- scan command line arguments                                        -- */
00434   /* ------------------------------------------------------------------------ */
00435   if ( strcmp (argv[0]+strlen(argv[0])-4, "sddf") == 0 )
00436     outFormat = SDDF;
00437   else if ( strcmp (argv[0]+strlen(argv[0])-4, "alog") == 0 )
00438     outFormat = alog;
00439   else if ( strcmp (argv[0]+strlen(argv[0])-4, "dump") == 0 )
00440     outFormat = dump;
00441   else if ( strcmp (argv[0]+strlen(argv[0])-2, "pv") == 0 )
00442     outFormat = pv;
00443 
00444   fileIdx = 1;
00445 
00446   if ( argc < 3 )
00447   {
00448     fprintf (stderr, "usage: %s [-alog | -SDDF | -dump |", argv[0]);
00449     fprintf (stderr, " -pv [-compact] [-user|-class|-all] [-nocomm]]");
00450     fprintf (stderr, " inputtrc edffile [outputtrc]\n");
00451     exit (1);
00452   }
00453   else if ( strcmp (argv[1], "-alog") == 0 || strcmp (argv[1], "-a") == 0 )
00454   {
00455     outFormat = alog;
00456     fileIdx = 2;
00457   }
00458   else if ( strcmp (argv[1], "-SDDF") == 0 || strcmp (argv[1], "-S") == 0 )
00459   {
00460     outFormat = SDDF;
00461     fileIdx = 2;
00462   }
00463   else if ( strcmp (argv[1], "-pv") == 0 || strcmp (argv[1], "-p") == 0 )
00464   {
00465     outFormat = pv;
00466     i = 2;
00467     while ( argv[i][0] == '-' )
00468     {
00469       if ( strcmp (argv[i], "-compact") == 0 )
00470         pvCompact = TRUE;
00471       else if ( strcmp (argv[i], "-user") == 0 )
00472         pvMode = user;
00473       else if ( strcmp (argv[i], "-class") == 0 )
00474         pvMode = pvclass;
00475       else if ( strcmp (argv[i], "-all") == 0 )
00476         pvMode = all;
00477       else if ( strcmp (argv[i], "-nocomm") == 0 )
00478         pvComm = FALSE;
00479       else
00480         break;
00481       i++;
00482     }
00483     fileIdx = i;
00484   }
00485   else if ( strcmp (argv[1], "-dump") == 0 || strcmp (argv[1], "-d") == 0 )
00486   {
00487     outFormat = dump;
00488     fileIdx = 2;
00489   }
00490 
00491   inFile  = argv[fileIdx];
00492   edfFile = argv[fileIdx+1];
00493   if ( (fileIdx+2) == argc )
00494     outFile = NULL;
00495   else
00496     outFile = argv[fileIdx+2];
00497 
00498   /* ------------------------------------------------------------------------ */
00499   /* -- open input trace                                                   -- */
00500   /* ------------------------------------------------------------------------ */
00501   if ( (intrc.fd = open (inFile, O_RDONLY)) < 0 )
00502   {
00503     perror (inFile);
00504     exit (1);
00505   }
00506   else
00507   {
00508     intrc.name      = inFile;
00509     intrc.buffer    = (PCXX_EV *) malloc (INMAX * sizeof(PCXX_EV));
00510     intrc.erec      = NULL;
00511     intrc.next      = NULL;
00512     intrc.last      = NULL;
00513     intrc.overflows = 0;
00514 
00515     /* -- read first event record ------------------------------------------- */
00516     if ( (erec = get_next_rec (&intrc)) == NULL )
00517     {
00518       /* -- no event record: ------------------------------------------------ */
00519       fprintf (stderr, "%s: warning: trace empty - ignored\n",
00520                intrc.name);
00521       intrc.numrec = 0L;
00522     }
00523 
00524     /* -- check first event record ------------------------------------------ */
00525 /* Can't check this as isInitEvent requires event .edf file to be read in */
00526 /* and at this stage the edf file has not been opened */
00527 /*
00528     else if (!isInitEvent(erec))
00529     {
00530       fprintf (stderr, "%s: no valid event trace\n", intrc.name);
00531       exit (1);
00532     }
00533 */
00534     else
00535     {
00536       intrc.numrec    = 1L;
00537       intrc.numproc   = erec->nid;
00538       intrc.firsttime = erec->ti;
00539       intrc.lasttime  = erec->ti;
00540     }
00541   }
00542 
00543   /* ------------------------------------------------------------------------ */
00544   /* -- open output trace file                                             -- */
00545   /* ------------------------------------------------------------------------ */
00546   if ( outFile )
00547   {
00548     if ( access (outFile, F_EXISTS) == 0  && isatty(2) )
00549     {
00550       fprintf (stderr, "%s exists; override [y]? ", outFile);
00551       if ( getchar() == 'n' ) exit (1);
00552     }
00553 
00554     if ( (outfp = fopen (outFile, "w")) == NULL )
00555     {
00556       perror (outFile);
00557       exit (1);
00558     }
00559   }
00560   else
00561     outfp = stdout;
00562 
00563   /* ------------------------------------------------------------------------ */
00564   /* -- initialize event description database ------------------------------- */
00565   /* ------------------------------------------------------------------------ */
00566 
00567   /* -- read event descriptor file and write event descriptor part header --- */
00568   if ( (inev = fopen (edfFile, "r")) == NULL )
00569   {
00570     perror (edfFile);
00571     exit (1);
00572   }
00573   fgets (linebuf, LINEMAX, inev);
00574   sscanf (linebuf, "%d %s", &intrc.numevent, traceflag);
00575 
00576   if (strcmp(traceflag, "dynamic_trace_events") == 0) 
00577   {
00578     dynamictrace = TRUE;
00579   }
00580 
00581   InitEvent (intrc.numevent);
00582 
00583   for (i=0; i<intrc.numevent; i++)
00584   {
00585     fgets (linebuf, LINEMAX, inev);
00586     if ( (linebuf[0] == '\n') || (linebuf[0] == '#') )
00587     {
00588       /* -- skip empty and comment lines -- */
00589       i--;
00590       continue;
00591     }
00592 
00593     num = -1;
00594     name[0]  = '\0';
00595     param[0] = '\0';
00596     if (dynamictrace) /* get name in quotes */
00597     { 
00598       sscanf (linebuf, "%d %s %d", &num, state, &tag);
00599 #if DEBUG
00600       printf("Got num %d state %s tag %d\n", num, state, tag);
00601 #endif /* DEBUG */
00602       for(j=0; linebuf[j] !='"'; j++)
00603         ;
00604       name[0] = linebuf[j];
00605       j++;
00606       /* skip over till name begins */
00607       for (k=j; linebuf[k] != '"'; k++)
00608       {
00609         name[k-j+1] = linebuf[k];
00610       } 
00611       name[k-j+1] = '"';
00612       name[k-j+2] = '\0'; /* terminate name */
00613 
00614       strcpy(param, &linebuf[k+2]);
00615 
00616 #ifdef DEBUG 
00617       printf(" Got name=%s param=%s\n", name, param);
00618 #endif /* DEBUG */
00619 
00620     } 
00621     else 
00622     {  
00623       sscanf (linebuf, "%d %s %d %s %s", &num, state, &tag, name, param);
00624     }
00625 
00626     if ( (num < 0) || !*name )
00627     {
00628       fprintf (stderr, "%s: blurb in line %d\n", edfFile, i+2);
00629       exit (1);
00630     }
00631    
00632     if (dynamictrace)
00633     { 
00634       AddEventDynamic (num, name, param, state, tag);
00635     } 
00636     else 
00637     {
00638       AddEvent (num, name, param, state, tag);
00639     }
00640   }
00641   fclose (inev);
00642 
00643   /* ------------------------------------------------------------------------ */
00644   /* -- skip through trace file to determine trace parameters --------------- */
00645   /* ------------------------------------------------------------------------ */
00646   do
00647   {
00648     if ( (i = GetEvent (erec->ev)) == 0 )
00649     {
00650       fprintf (stderr, "%s: unknown event type %d in event record %ld\n",
00651                intrc.name, erec->ev, intrc.numrec);
00652     }
00653     else if ( isInitEvent(erec))
00654     {
00655       numproc++;
00656     }
00657 
00658     if ( (erec = get_next_rec (&intrc)) == NULL )
00659       break;
00660     else
00661     {
00662       intrc.numrec++;
00663 
00664       /* -- check clock overflow ---------------------------------------- */
00665       if ( erec->ti < intrc.lasttime ) intrc.overflows++;
00666       intrc.lasttime = erec->ti;
00667 
00668       /* -- check process id -------------------------------------------- */
00669       if ( erec->nid > intrc.numproc ) intrc.numproc = erec->nid;
00670     }
00671   }
00672   while ( erec != NULL );
00673 
00674   /* ------------------------------------------------------------------------ */
00675   /* -- write trace file header --------------------------------------------- */
00676   /* ------------------------------------------------------------------------ */
00677 
00678   /* -- write fixed header -------------------------------------------------- */
00679   if ( outFormat == alog )
00680   {
00681     fprintf (outfp, " -2   0 0 %10ld 0          0\n", intrc.numrec);
00682     fprintf (outfp, " -3   0 0 %10d 0          0\n", intrc.numproc+1);
00683     fprintf (outfp, " -4   0 0          1 0          0\n");
00684     fprintf (outfp, " -5   0 0 %10d 0          0\n", numUsedEvent);
00685     fprintf (outfp, " -6   0 0          0 0 %10lu\n", intrc.firsttime);
00686     fprintf (outfp, " -7   0 0          0 0 %10lu\n", intrc.lasttime);
00687     fprintf (outfp, " -8   0 0 %10d 0          0\n", intrc.overflows+1);
00688     fprintf (outfp, " -1   0 0          0 0          0 pcxx_convert -alog %s\n",
00689              Today());
00690     fprintf (outfp, "-11   0 0          0 0 4294967295\n");
00691   }
00692   else if ( outFormat == SDDF )
00693   {
00694     fprintf (outfp, "/*\n");
00695     fprintf (outfp, " * \"creation program\" \"pcxx_convert -SDDF\"\n");
00696     fprintf (outfp, " * \"creation date\" \"%s\"\n", Today());
00697     fprintf (outfp, " * \"number records\" \"%ld\"\n", intrc.numrec);
00698     fprintf (outfp, " * \"number processors\" \"%d\"\n", intrc.numproc+1);
00699     fprintf (outfp, " * \"first timestamp\" \"%ld\"\n", intrc.firsttime);
00700     fprintf (outfp, " * \"last timestamp\" \"%ld\"\n", intrc.lasttime);
00701     fprintf (outfp, " */\n\n");
00702   }
00703   else if ( outFormat == pv )
00704   {
00705 /* The time in the record comes from GetUSecD() converted to long - so it
00706    should be in microseconds. */
00707 /* old 
00708     fprintf (outfp, "CLKPERIOD 0.1000E-06\n");
00709 */
00710     fprintf (outfp, "CLKPERIOD 1.0E-06\n");
00711     fprintf (outfp, "NCPUS %d\n", intrc.numproc+1);
00712     fprintf (outfp, "C CREATION PROGRAM pcxx_convert -pv\n");
00713     fprintf (outfp, "C CREATION DATE %s\n", Today());
00714     fprintf (outfp, "C NUMBER RECORDS %ld\n", intrc.numrec);
00715     fprintf (outfp, "C FIRST TIMESTAMP %ld\n", intrc.firsttime);
00716     fprintf (outfp, "C LAST TIMESTAMP %ld\n", intrc.lasttime);
00717     fprintf (outfp, "C\n");
00718 
00719     /* -- initialize state stacks -- */
00720     statestk = (struct stkitem **)
00721                malloc ((intrc.numproc+1)*sizeof(struct stkitem *));
00722     stkptr   = (struct stkitem **)
00723                malloc ((intrc.numproc+1)*sizeof(struct stkitem *));
00724     for (i=0; i<=intrc.numproc; i++)
00725     {
00726       stkptr[i] = statestk[i] = (struct stkitem *)
00727                                 malloc (STACKSIZE * sizeof(struct stkitem));
00728       stkptr[i]->state = "IDLE";
00729       stkptr[i]->tag = -99;
00730     }
00731   }
00732   else if ( outFormat == dump )
00733   {
00734     fprintf (outfp, "#  creation program: pcxx_convert -dump\n");
00735     fprintf (outfp, "#     creation date: %s\n", Today());
00736     fprintf (outfp, "#    number records: %ld\n", intrc.numrec);
00737     fprintf (outfp, "# number processors: %d\n", numproc);
00738     fprintf (outfp, "# max processor num: %d\n", intrc.numproc);
00739     fprintf (outfp, "#   first timestamp: %ld\n", intrc.firsttime);
00740     fprintf (outfp, "#    last timestamp: %ld\n\n", intrc.lasttime);
00741 
00742     fprintf (outfp, "#=NO= =======================EVENT==");
00743     fprintf (outfp, " ==TIME [us]= =NODE= =THRD= ==PARAMETER=\n");
00744   }
00745 
00746 
00747   PrintEventDescr (outfp);
00748 
00749   /* ------------------------------------------------------------------------ */
00750   /* -- re-open input trace                                                -- */
00751   /* ------------------------------------------------------------------------ */
00752   if ( (intrc.fd = open (inFile, O_RDONLY)) < 0 )
00753   {
00754     perror (inFile);
00755     exit (1);
00756   }
00757   else
00758   {
00759     intrc.erec      = NULL;
00760     intrc.next      = NULL;
00761     intrc.last      = NULL;
00762     intrc.overflows = 0;
00763     intrc.numrec    = 1;
00764 
00765     erec = get_next_rec (&intrc);
00766     intrc.firsttime = erec->ti;
00767     intrc.lasttime  = erec->ti;
00768   }
00769 
00770   /* ------------------------------------------------------------------------ */
00771   /* -- initialize barrier check variables ---------------------------------- */
00772   /* ------------------------------------------------------------------------ */
00773   numin   = 0;
00774   numout  = numproc;
00775   barrin  = (char *) malloc (intrc.numproc + 1);
00776   barrout = (char *) malloc (intrc.numproc + 1);
00777   for (i=0; i<=intrc.numproc; i++)
00778   {
00779     barrin[i]  = FALSE;
00780     barrout[i] = TRUE;
00781   }
00782 
00783   /* ------------------------------------------------------------------------ */
00784   /* -- convert trace file -------------------------------------------------- */
00785   /* ------------------------------------------------------------------------ */
00786   do
00787   {
00788 # ifdef __PCXX__
00789     /* -- check barrier order ----------------------------------------------- */
00790     if ( erec->ev == PCXX_BARRIER_ENTER )
00791     {
00792       if ( !barrout[erec->nid] )
00793       {
00794         fprintf (stderr, "%s:%d: [%d] not yet out of barrier\n",
00795                  intrc.name, intrc.numrec, erec->nid);
00796       }
00797       if ( barrin[erec->nid] )
00798       {
00799         fprintf (stderr, "%s:%d: [%d] already in barrier\n",
00800                  intrc.name, intrc.numrec, erec->nid);
00801       }
00802       else
00803       {
00804         barrin[erec->nid] = TRUE;
00805         numin++;
00806 
00807         if ( numin == numproc )
00808         {
00809           if ( numout != numproc )
00810           {
00811             fprintf (stderr, "%s:%d: barrier event count error\n",
00812                      intrc.name, intrc.numrec);
00813           }
00814           numin = numout = 0;
00815           for (i=0; i<=intrc.numproc; i++) barrin[i] = barrout[i] = FALSE;
00816         }
00817       }
00818     }
00819     else if ( erec->ev == PCXX_BARRIER_EXIT )
00820     {
00821       if ( barrin[erec->nid] )
00822       {
00823         fprintf (stderr, "%s:%d: [%d] not yet in barrier\n",
00824                  intrc.name, intrc.numrec, erec->nid);
00825       }
00826       if ( barrout[erec->nid] )
00827       {
00828         fprintf (stderr, "%s:%d: [%d] already out of barrier\n",
00829                  intrc.name, intrc.numrec, erec->nid);
00830       }
00831       else
00832       {
00833         barrout[erec->nid] = TRUE;
00834         numout++;
00835       }
00836     }
00837 # endif
00838 
00839     if ( outFormat == alog )
00840     {
00841       i = GetEvent (erec->ev);
00842       fprintf (outfp, "%3d %3d 0 %10ld %d %10lu\n",
00843         i,                /* event type */
00844         erec->nid,        /* process id */
00845         erec->par,        /* integer parameter */
00846         intrc.overflows,  /* clock cycle */
00847         erec->ti);        /* timestamp */
00848     }
00849     else if ( outFormat == SDDF )
00850     {
00851       ptr = GetEventName (erec->ev, &hasParam);
00852       if ( hasParam )
00853         fprintf (outfp, "\"%s\" { %lu, %d, %d, %ld };;\n\n",
00854                  ptr, erec->ti, erec->nid, erec->tid, erec->par);
00855       else
00856         fprintf (outfp, "\"%s\" { %lu, %d, %d };;\n\n",
00857                  ptr, erec->ti, erec->nid, erec->tid);
00858     }
00859     else if ( outFormat == pv )
00860     {
00861       ev = GetEventStruct (erec->ev);
00862       if (( ev->tag != 0 ) || (dynamictrace)) /* dynamic trace doesn't use tag*/
00863       {
00864         if ( (ev->tag == -7) && pvComm )
00865         {
00866           /* send message */ 
00867           /* In dynamic trace the format for par is 
00868                 31 ..... 24 23 ......16 15..............0
00869                    other       type          length       
00870                 So, mynode is the sender and its in erec->nid 
00871                 SENDMSG <type> FROM <sender> TO <receiver> LEN <length>
00872           */
00873           fprintf (outfp, "%lu SENDMSG %d FROM %d TO %d LEN %d\n", 
00874                   erec->ti - intrc.firsttime,
00875                   ((erec->par>>16) & 0x000000FF), erec->nid+1, 
00876                   ((erec->par>>24) & 0x000000FF) + 1, 
00877                   erec->par & 0x0000FFFF);
00878         }
00879         else if ( (ev->tag == -8) && pvComm )
00880         {
00881           /* receive message */
00882           /* In dynamic trace the format for par is 
00883                 31 ..... 24 23 ......16 15..............0
00884                    other       type          length       
00885                 So, mynode is the receiver and its in erec->nid 
00886                 RECVMSG <type> BY <receiver> FROM <sender> LEN <length>
00887           */
00888           fprintf (outfp, "%lu RECVMSG %d BY %d FROM %d LEN %d\n", 
00889                   erec->ti - intrc.firsttime,
00890                   ((erec->par>>16) & 0x000000FF),
00891                   erec->nid+1, ((erec->par>>24) & 0x000000FF) + 1,
00892                   erec->par & 0x0000FFFF);
00893         }
00894         else if (( ev->tag == -9 ) || ( erec->par == -1))
00895         { /* In dynamic tracing, 1/-1 par values are for Entry/Exit resp. */
00896           /* exit state */
00897           /* PARVis needs time values relative to the start of the program! */
00898           stkptr[erec->nid]--;
00899           if ( stkptr[erec->nid] < statestk[erec->nid] )
00900           {
00901             fprintf (stderr, "ERROR: stack underflow on node %d\n", erec->nid);
00902             fprintf (stderr, "       event %s at %lu\n", ev->name, erec->ti);
00903             exit (1);
00904           }
00905           if ( pvCompact )
00906             fprintf (outfp, "%lu EXCH %d 1 1 %s %d\n",
00907                     erec->ti - intrc.firsttime, erec->nid+1,
00908                     stkptr[erec->nid]->state, stkptr[erec->nid]->tag);
00909           else
00910             fprintf (outfp, "%lu EXCHANGE ON CPUID %d TO %s %d CLUSTER 1\n",
00911                     erec->ti - intrc.firsttime, erec->nid+1,
00912                     stkptr[erec->nid]->state, stkptr[erec->nid]->tag);
00913         }
00914         else if (erec->par == 1)
00915         {
00916           /* enter new state */
00917           stkptr[erec->nid]++;
00918           if ( stkptr[erec->nid] > (statestk[erec->nid] + STACKSIZE) )
00919           {
00920             fprintf (stderr, "ERROR: stack overflow on node %d\n", erec->nid);
00921             fprintf (stderr, "       event %s at %lu\n", ev->name, erec->ti);
00922             exit (1);
00923           }
00924           if ( pvCompact )
00925             fprintf (outfp, "%lu EXCH %d 1 1 %s %d\n",
00926                     /*???erec->ti, erec->nid+1, ev->state, ev->tag);*/
00927                     erec->ti - intrc.firsttime, erec->nid+1, ev->state, ev->no);
00928           else
00929             fprintf (outfp, "%lu EXCHANGE ON CPUID %d TO %s %d CLUSTER 1\n",
00930                     /*???erec->ti, erec->nid+1, ev->state, ev->tag);*/
00931                     erec->ti - intrc.firsttime, erec->nid+1, ev->state, ev->no);
00932           stkptr[erec->nid]->state = ev->state;
00933           /*???stkptr[erec->nid]->tag = ev->tag;*/
00934           stkptr[erec->nid]->tag = ev->no;
00935         }
00936       }
00937     }
00938     else if ( outFormat == dump )
00939     {
00940       ptr = GetEventName (erec->ev, &hasParam);
00941       if ( hasParam )
00942         fprintf (outfp, "%5ld %30.30s %12lu %6d %6d %12ld\n",
00943                  intrc.numrec, ptr, erec->ti, erec->nid, erec->tid, erec->par);
00944       else
00945         fprintf (outfp, "%5ld %30.30s %12lu %6d %6d\n",
00946                  intrc.numrec, ptr, erec->ti, erec->nid, erec->tid);
00947     }
00948 
00949     if ( (erec = get_next_rec (&intrc)) == NULL )
00950       break;
00951     else
00952     {
00953       intrc.numrec++;
00954 
00955       /* -- check clock overflow ---------------------------------------- */
00956       if ( erec->ti < intrc.lasttime ) intrc.overflows++;
00957       intrc.lasttime = erec->ti;
00958     }
00959   }
00960   while ( erec != NULL );
00961 
00962   if ( outFormat == pv )
00963   {
00964     for (i=0; i<=intrc.numproc; i++)
00965     {
00966       if ( stkptr[i] != statestk[i] )
00967       {
00968         fprintf (stderr, "ERROR: stack not empty on node %d\n", i);
00969         exit (1);
00970       }
00971     }
00972   }
00973 
00974   fclose (outfp);
00975   exit (0);
00976 }
00977 
00978 /***************************************************************************
00979  * $RCSfile: addheaderfooter,v $   $Author: adelmann $
00980  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:17 $
00981  * IPPL_VERSION_ID: $Id: addheaderfooter,v 1.1.1.1 2003/01/23 07:40:17 adelmann Exp $ 
00982  ***************************************************************************/
00983 

Generated on Mon Jan 16 13:23:55 2006 for IPPL by  doxygen 1.4.6