ck-perf/trace-summary.C

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * $Source: /cvsroot/charm/src/ck-perf/trace-summary.C,v $
00003  * $Author: gzheng $
00004  * $Date: 2008-03-30 05:39:19 $
00005  * $Revision: 1.100 $
00006  *****************************************************************************/
00007 
00012 
00013 #include "charm++.h"
00014 #include "trace-summary.h"
00015 #include "trace-summaryBOC.h"
00016 
00017 #define DEBUGF(x)  // CmiPrintf x
00018 
00019 #define VER   7.0
00020 
00021 #define INVALIDEP     -2
00022 #define TRACEON_EP     -3
00023 
00024 #define DefaultBinCount      10000
00025 
00026 CkpvStaticDeclare(TraceSummary*, _trace);
00027 static int _numEvents = 0;
00028 #define NUM_DUMMY_EPS 9
00029 CkpvDeclare(int, binCount);
00030 CkpvDeclare(double, binSize);
00031 CkpvDeclare(double, version);
00032 
00033 int sumonly = 0;
00034 int sumDetail = 0;
00035 
00040 void _createTracesummary(char **argv)
00041 {
00042   DEBUGF(("%d createTraceSummary\n", CkMyPe()));
00043   CkpvInitialize(TraceSummary*, _trace);
00044   CkpvAccess(_trace) = new  TraceSummary(argv);
00045   CkpvAccess(_traces)->addTrace(CkpvAccess(_trace));
00046 }
00047 
00048 
00050 extern "C" 
00051 void CkSummary_StartPhase(int phase)
00052 {
00053    CkpvAccess(_trace)->startPhase(phase);
00054 }
00055 
00056 
00058 extern "C" 
00059 void CkSummary_MarkEvent(int eventType)
00060 {
00061    CkpvAccess(_trace)->addEventType(eventType);
00062 }
00063 
00064 static inline void writeU(FILE* fp, int u)
00065 {
00066   fprintf(fp, "%4d", u);
00067 }
00068 
00069 PhaseEntry::PhaseEntry() 
00070 {
00071   int _numEntries=_entryTable.size();
00072   // FIXME: Hopes there won't be more than 10 more EP's registered from now on...
00073   nEPs = _numEntries+10; 
00074   count = new int[nEPs];
00075   times = new double[nEPs];
00076   maxtimes = new double[nEPs];
00077   for (int i=0; i<nEPs; i++) {
00078     count[i] = 0;
00079     times[i] = 0.0;
00080     maxtimes[i] = 0.;
00081   }
00082 }
00083 
00084 SumLogPool::~SumLogPool() 
00085 {
00086   if (!sumonly) {
00087     write();
00088     fclose(fp);
00089     if (sumDetail) fclose(sdfp);
00090   }
00091   // free memory for mark
00092   if (markcount > 0)
00093   for (int i=0; i<MAX_MARKS; i++) {
00094     for (int j=0; j<events[i].length(); j++)
00095       delete events[i][j];
00096   }
00097   delete[] pool;
00098   delete[] epInfo;
00099   delete[] cpuTime;
00100   delete[] numExecutions;
00101 }
00102 
00103 void SumLogPool::addEventType(int eventType, double time)
00104 {
00105    if (eventType <0 || eventType >= MAX_MARKS) {
00106        CkPrintf("Invalid event type %d!\n", eventType);
00107        return;
00108    }
00109    MarkEntry *e = new MarkEntry;
00110    e->time = time;
00111    events[eventType].push_back(e);
00112    markcount ++;
00113 }
00114 
00115 SumLogPool::SumLogPool(char *pgm) : numBins(0), phaseTab(MAX_PHASES) 
00116 {
00117    // TBD: Can this be moved to initMem?
00118    poolSize = CkpvAccess(binCount);
00119    if (poolSize % 2) poolSize++;        // make sure it is even
00120    pool = new BinEntry[poolSize];
00121    _MEMCHECK(pool);
00122 
00123    this->pgm = new char[strlen(pgm)+1];
00124    strcpy(this->pgm,pgm);
00125    
00126 #if 0
00127    // create the sts file
00128    if (CkMyPe() == 0) {
00129      char *fname = 
00130        new char[strlen(CkpvAccess(traceRoot))+strlen(".sum.sts")+1];
00131      sprintf(fname, "%s.sum.sts", CkpvAccess(traceRoot));
00132      stsfp = fopen(fname, "w+");
00133      //CmiPrintf("File: %s \n", fname);
00134      if (stsfp == 0) {
00135        CmiAbort("Cannot open summary sts file for writing.\n");
00136       }
00137      delete[] fname;
00138    }
00139 #endif
00140    
00141    // event
00142    markcount = 0;
00143 }
00144 
00145 void SumLogPool::initMem()
00146 {
00147    int _numEntries=_entryTable.size();
00148    epInfoSize = _numEntries + NUM_DUMMY_EPS + 1; // keep a spare EP
00149    epInfo = new SumEntryInfo[epInfoSize];
00150    _MEMCHECK(epInfo);
00151 
00152    cpuTime = NULL;
00153    numExecutions = NULL;
00154    if (sumDetail) {
00155        cpuTime = new double[poolSize*epInfoSize];
00156        _MEMCHECK(cpuTime);
00157        memset(cpuTime, 0, poolSize*epInfoSize*sizeof(double));
00158        numExecutions = new int[poolSize*epInfoSize];
00159        _MEMCHECK(numExecutions);
00160        memset(numExecutions, 0, poolSize*epInfoSize*sizeof(int));
00161 
00162 //         int i, e;
00163 //         for(i=0; i<poolSize; i++) {
00164 //             for(e=0; e< epInfoSize; e++) {
00165 //                 setCPUtime(i,e,0.0);
00166 //                 setNumExecutions(i,e,0);
00167 //             }
00168 //         }
00169    }
00170 }
00171 
00172 int SumLogPool::getUtilization(int interval, int ep) {
00173     return (int)(getCPUtime(interval, ep) * 100.0 / CkpvAccess(binSize)); 
00174 };
00175 
00176 void SumLogPool::write(void) 
00177 {
00178   int i;
00179   unsigned int j;
00180   int _numEntries=_entryTable.size();
00181 
00182   fp = NULL;
00183   sdfp = NULL;
00184 
00185   // create file(s)
00186   // CmiPrintf("TRACE: %s:%d\n", fname, errno);
00187   if (!sumonly) {
00188     char pestr[10];
00189     sprintf(pestr, "%d", CkMyPe());
00190     int len = strlen(pgm) + strlen(".sumd.") + strlen(pestr) + 1;
00191     char *fname = new char[len+1];
00192     
00193     sprintf(fname, "%s.%s.sum", pgm, pestr);
00194     do {
00195       fp = fopen(fname, "w+");
00196     } while (!fp && errno == EINTR);
00197     if (!fp) {
00198       CkPrintf("[%d] Attempting to open [%s]\n",CkMyPe(),fname);
00199       CmiAbort("Cannot open Summary Trace File for writing...\n");
00200     }
00201     
00202     if (sumDetail) {
00203       sprintf(fname, "%s.%s.sumd", pgm, pestr);
00204       do {
00205         sdfp = fopen(fname, "w+");
00206       } while (!sdfp && errno == EINTR);
00207       if(!sdfp) {
00208         CmiAbort("Cannot open Detailed Summary Trace File for writing...\n");
00209       }
00210     }
00211     delete[] fname;
00212   }
00213 
00214   fprintf(fp, "ver:%3.1f %d/%d count:%d ep:%d interval:%e", CkpvAccess(version), CkMyPe(), CkNumPes(), numBins, _numEntries, CkpvAccess(binSize));
00215   if (CkpvAccess(version)>=3.0)
00216   {
00217     fprintf(fp, " phases:%d", phaseTab.numPhasesCalled());
00218   }
00219   fprintf(fp, "\n");
00220 
00221   // write bin time
00222 #if 1
00223   int last=pool[0].getU();
00224   writeU(fp, last);
00225   int count=1;
00226   for(j=1; j<numBins; j++) {
00227     int u = pool[j].getU();
00228     if (last == u) {
00229       count++;
00230     }
00231     else {
00232       if (count > 1) fprintf(fp, "+%d", count);
00233       writeU(fp, u);
00234       last = u;
00235       count = 1;
00236     }
00237   }
00238   if (count > 1) fprintf(fp, "+%d", count);
00239 #else
00240   for(j=0; j<numEntries; j++) 
00241       pool[j].write(fp);
00242 #endif
00243   fprintf(fp, "\n");
00244 
00245   // write entry execution time
00246   fprintf(fp, "EPExeTime: ");
00247   for (i=0; i<_numEntries; i++)
00248     fprintf(fp, "%ld ", (long)(epInfo[i].epTime*1.0e6));
00249   fprintf(fp, "\n");
00250   // write entry function call times
00251   fprintf(fp, "EPCallTime: ");
00252   for (i=0; i<_numEntries; i++)
00253     fprintf(fp, "%d ", epInfo[i].epCount);
00254   fprintf(fp, "\n");
00255   // write max entry function execute times
00256   fprintf(fp, "MaxEPTime: ");
00257   for (i=0; i<_numEntries; i++)
00258     fprintf(fp, "%ld ", (long)(epInfo[i].epMaxTime*1.0e6));
00259   fprintf(fp, "\n");
00260 #if 0
00261   for (i=0; i<SumEntryInfo::HIST_SIZE; i++) {
00262     for (j=0; j<_numEntries; j++) 
00263       fprintf(fp, "%d ", epInfo[j].hist[i]);
00264     fprintf(fp, "\n");
00265   }
00266 #endif
00267   // write marks
00268   if (CkpvAccess(version)>=2.0) 
00269   {
00270     fprintf(fp, "NumMarks: %d ", markcount);
00271     for (i=0; i<MAX_MARKS; i++) {
00272       for(int j=0; j<events[i].length(); j++)
00273         fprintf(fp, "%d %f ", i, events[i][j]->time);
00274     }
00275     fprintf(fp, "\n");
00276   }
00277   // write phases
00278   if (CkpvAccess(version)>=3.0)
00279   {
00280     phaseTab.write(fp);
00281   }
00282 
00283   // write summary details
00284   if (sumDetail) {
00285         fprintf(sdfp, "ver:%3.1f cpu:%d/%d numIntervals:%d numEPs:%d intervalSize:%e\n",
00286                 CkpvAccess(version), CkMyPe(), CkNumPes(),
00287                 numBins, _numEntries, CkpvAccess(binSize));
00288 
00289         // Write out cpuTime in microseconds
00290         // Run length encoding (RLE) along EP axis
00291         fprintf(sdfp, "ExeTimePerEPperInterval ");
00292         unsigned int e, i;
00293         long last= (long) (getCPUtime(0,0)*1.0e6);
00294         int count=0;
00295         fprintf(sdfp, "%ld", last);
00296         for(e=0; e<_numEntries; e++) {
00297             for(i=0; i<numBins; i++) {
00298 
00299                 long u= (long) (getCPUtime(i,e)*1.0e6);
00300                 if (last == u) {
00301                     count++;
00302                 } else {
00303 
00304                     if (count > 1) fprintf(sdfp, "+%d", count);
00305                     fprintf(sdfp, " %ld", u);
00306                     last = u;
00307                     count = 1;
00308                 }
00309             }
00310         }
00311         if (count > 1) fprintf(sdfp, "+%d", count);
00312         fprintf(sdfp, "\n");
00313 
00314         // Write out numExecutions
00315         // Run length encoding (RLE) along EP axis
00316         fprintf(sdfp, "EPCallTimePerInterval ");
00317         last= getNumExecutions(0,0);
00318         count=0;
00319         fprintf(sdfp, "%d", last);
00320         for(e=0; e<_numEntries; e++) {
00321             for(i=0; i<numBins; i++) {
00322 
00323                 long u= getNumExecutions(i, e);
00324                 if (last == u) {
00325                     count++;
00326                 } else {
00327 
00328                     if (count > 1) fprintf(sdfp, "+%d", count);
00329                     fprintf(sdfp, " %d", u);
00330                     last = u;
00331                     count = 1;
00332                 }
00333             }
00334         }
00335         if (count > 1) fprintf(sdfp, "+%d", count);
00336         fprintf(sdfp, "\n");
00337   }
00338 }
00339 
00340 void SumLogPool::writeSts(void)
00341 {
00342     // open sts file
00343   char *fname = 
00344        new char[strlen(CkpvAccess(traceRoot))+strlen(".sum.sts")+1];
00345   sprintf(fname, "%s.sum.sts", CkpvAccess(traceRoot));
00346   stsfp = fopen(fname, "w+");
00347   //CmiPrintf("File: %s \n", fname);
00348   if (stsfp == 0) {
00349        CmiAbort("Cannot open summary sts file for writing.\n");
00350   }
00351   delete[] fname;
00352 
00353   traceWriteSTS(stsfp,_numEvents);
00354   for(int i=0;i<_numEvents;i++)
00355     fprintf(stsfp, "EVENT %d Event%d\n", i, i);
00356   fprintf(stsfp, "END\n");
00357 
00358   fclose(stsfp);
00359 }
00360 
00361 // Called once per interval
00362 void SumLogPool::add(double time, int pe) 
00363 {
00364   new (&pool[numBins++]) BinEntry(time);
00365   if(poolSize==numBins) shrink();
00366 }
00367 
00368 // Called once per run of an EP
00369 // adds 'time' to EP's time, increments epCount
00370 void SumLogPool::setEp(int epidx, double time) 
00371 {
00372   if (epidx >= epInfoSize) {
00373         CmiAbort("Invalid entry point!!\n");
00374   }
00375   //CmiPrintf("set EP: %d %e \n", epidx, time);
00376   epInfo[epidx].setTime(time);
00377   // set phase table counter
00378   phaseTab.setEp(epidx, time);
00379 }
00380 
00381 // Called once from endExecute, endPack, etc. this function updates
00382 // the sumDetail intervals.
00383 void SumLogPool::updateSummaryDetail(int epIdx, double startTime, double endTime)
00384 {
00385         if (epIdx >= epInfoSize) {
00386             CmiAbort("Too many entry points!!\n");
00387         }
00388 
00389         double binSz = CkpvAccess(binSize);
00390         int startingBinIdx, endingBinIdx;
00391         startingBinIdx = (int)(startTime/binSz);
00392         endingBinIdx = (int)(endTime/binSz);
00393         // shrink if needed
00394         while (endingBinIdx >= poolSize) {
00395           shrink();
00396           CmiAssert(CkpvAccess(binSize) > binSz);
00397           binSz = CkpvAccess(binSize);
00398           startingBinIdx = (int)(startTime/binSz);
00399           endingBinIdx = (int)(endTime/binSz);
00400         }
00401 
00402         if (startingBinIdx == endingBinIdx) {
00403             addToCPUtime(startingBinIdx, epIdx, endTime - startTime);
00404         } else if (startingBinIdx < endingBinIdx) { // EP spans intervals
00405             addToCPUtime(startingBinIdx, epIdx, (startingBinIdx+1)*binSz - startTime);
00406             while(++startingBinIdx < endingBinIdx)
00407                 addToCPUtime(startingBinIdx, epIdx, binSz);
00408             addToCPUtime(endingBinIdx, epIdx, endTime - endingBinIdx*binSz);
00409         } else {
00410           CkPrintf("[%d] EP:%d Start:%lf End:%lf\n",CkMyPe(),epIdx,
00411                    startTime, endTime);
00412             CmiAbort("Error: end time of EP is less than start time\n");
00413         }
00414 
00415         incNumExecutions(startingBinIdx, epIdx);
00416 };
00417 
00418 // Shrinks pool[], cpuTime[], and numExecutions[]
00419 void SumLogPool::shrink(void)
00420 {
00421 //  double t = CmiWallTimer();
00422 
00423   // We ensured earlier that poolSize is even; therefore now numBins
00424   // == poolSize == even.
00425   int entries = numBins/2;
00426   for (int i=0; i<entries; i++)
00427   {
00428      pool[i].time() = pool[i*2].time() + pool[i*2+1].time();
00429      if (sumDetail)
00430      for (int e=0; e < epInfoSize; e++) {
00431          setCPUtime(i, e, getCPUtime(i*2, e) + getCPUtime(i*2+1, e));
00432          setNumExecutions(i, e, getNumExecutions(i*2, e) + getNumExecutions(i*2+1, e));
00433      }
00434   }
00435   // zero out the remaining intervals
00436   if (sumDetail) {
00437     memset(&cpuTime[entries*epInfoSize], 0, (numBins-entries)*epInfoSize*sizeof(double));
00438     memset(&numExecutions[entries*epInfoSize], 0, (numBins-entries)*epInfoSize*sizeof(int));
00439   }
00440   numBins = entries;
00441   CkpvAccess(binSize) *= 2;
00442 
00443 //CkPrintf("Shrinked binsize: %f entries:%d takes %fs!!!!\n", CkpvAccess(binSize), numEntries, CmiWallTimer()-t);
00444 }
00445 
00446 int  BinEntry::getU() 
00447 { 
00448   return (int)(_time * 100.0 / CkpvAccess(binSize)); 
00449 }
00450 
00451 void BinEntry::write(FILE* fp)
00452 {
00453   writeU(fp, getU());
00454 }
00455 
00456 TraceSummary::TraceSummary(char **argv):binStart(0.0),bin(0.0),msgNum(0)
00457 {
00458   if (CkpvAccess(traceOnPe) == 0) return;
00459 
00460   CkpvInitialize(int, binCount);
00461   CkpvInitialize(double, binSize);
00462   CkpvInitialize(double, version);
00463   CkpvAccess(binSize) = BIN_SIZE;
00464   CkpvAccess(version) = VER;
00465   CkpvAccess(binCount) = DefaultBinCount;
00466   if (CmiGetArgIntDesc(argv,"+bincount",&CkpvAccess(binCount), "Total number of summary bins"))
00467     if (CkMyPe() == 0) 
00468       CmiPrintf("Trace: bincount: %d\n", CkpvAccess(binCount));
00469   CmiGetArgDoubleDesc(argv,"+binsize",&CkpvAccess(binSize),
00470         "CPU usage log time resolution");
00471   CmiGetArgDoubleDesc(argv,"+version",&CkpvAccess(version),
00472         "Write this .sum file version");
00473 
00474   epThreshold = 0.001; 
00475   CmiGetArgDoubleDesc(argv,"+epThreshold",&epThreshold,
00476         "Execution time histogram lower bound");
00477   epInterval = 0.001; 
00478   CmiGetArgDoubleDesc(argv,"+epInterval",&epInterval,
00479         "Execution time histogram bin size");
00480 
00481   sumonly = CmiGetArgFlagDesc(argv, "+sumonly", "merge histogram bins on processor 0");
00482   // +sumonly overrides +sumDetail
00483   if (!sumonly)
00484       sumDetail = CmiGetArgFlagDesc(argv, "+sumDetail", "more detailed summary info");
00485 
00486   _logPool = new SumLogPool(CkpvAccess(traceRoot));
00487   // assume invalid entry point on start
00488   execEp=INVALIDEP;
00489 }
00490 
00491 void TraceSummary::traceClearEps(void)
00492 {
00493   _logPool->clearEps();
00494 }
00495 
00496 void TraceSummary::traceWriteSts(void)
00497 {
00498   if(CkMyPe()==0)
00499       _logPool->writeSts();
00500 }
00501 
00502 void TraceSummary::traceClose(void)
00503 {
00504   if(CkMyPe()==0)
00505       _logPool->writeSts();
00506   CkpvAccess(_trace)->endComputation();
00507   // destructor call the write()
00508   delete _logPool;
00509   // remove myself from traceArray so that no tracing will be called.
00510   CkpvAccess(_traces)->removeTrace(this);
00511 }
00512 
00513 void TraceSummary::beginExecute(CmiObjId *tid)
00514 {
00515   beginExecute(-1,-1,_threadEP,-1);
00516 }
00517 
00518 void TraceSummary::beginExecute(envelope *e)
00519 {
00520   // no message means thread execution
00521   if (e==NULL) {
00522     beginExecute(-1,-1,_threadEP,-1);
00523   }
00524   else {
00525     beginExecute(-1,-1,e->getEpIdx(),-1);
00526   }  
00527 }
00528 
00529 void TraceSummary::beginExecute(int event,int msgType,int ep,int srcPe, int mlen, CmiObjId *idx)
00530 {
00531   if (execEp != INVALIDEP) {
00532     TRACE_WARN("Warning: TraceSummary two consecutive BEGIN_PROCESSING!\n");
00533     return;
00534   }
00535   
00536   execEp=ep;
00537   double t = TraceTimer();
00538   //CmiPrintf("start: %f \n", start);
00539   
00540   start = t;
00541   double ts = binStart;
00542   // fill gaps
00543   while ((ts = ts + CkpvAccess(binSize)) < t) {
00544      _logPool->add(bin, CkMyPe());
00545      bin=0.0;
00546      binStart = ts;
00547   }
00548 }
00549 
00550 void TraceSummary::endExecute(void)
00551 {
00552 //  if (!flag) return;
00553   double t = TraceTimer();
00554   double ts = start;
00555   double nts = binStart;
00556 
00557   if (execEp == TRACEON_EP) {
00558     // if trace just got turned on, then one expects to see this
00559     // END_PROCESSING event without seeing a preceeding BEGIN_PROCESSING
00560     return;
00561   }
00562 
00563   if (execEp == INVALIDEP) {
00564     TRACE_WARN("Warning: TraceSummary END_PROCESSING without BEGIN_PROCESSING!\n");
00565     return;
00566   }
00567 
00568   if (execEp != -1)
00569   {
00570     _logPool->setEp(execEp, t-ts);
00571   }
00572 
00573   while ((nts = nts + CkpvAccess(binSize)) < t)
00574   {
00575      bin += nts-ts;
00576      binStart  = nts;
00577      _logPool->add(bin, CkMyPe()); // This calls shrink() if needed
00578      bin = 0;
00579      ts = nts;
00580   }
00581   bin += t - ts;
00582 
00583   if (sumDetail)
00584       _logPool->updateSummaryDetail(execEp, start, t);
00585 
00586   execEp = INVALIDEP;
00587 }
00588 
00589 void TraceSummary::beginPack(void)
00590 {
00591     packstart = CmiWallTimer();
00592 }
00593 
00594 void TraceSummary::endPack(void)
00595 {
00596     _logPool->setEp(_packEP, CmiWallTimer() - packstart);
00597     if (sumDetail)
00598         _logPool->updateSummaryDetail(_packEP,  TraceTimer(packstart), TraceTimer(CmiWallTimer()));
00599 }
00600 
00601 void TraceSummary::beginUnpack(void)
00602 {
00603     unpackstart = CmiWallTimer();
00604 }
00605 
00606 void TraceSummary::endUnpack(void)
00607 {
00608     _logPool->setEp(_unpackEP, CmiWallTimer()-unpackstart);
00609     if (sumDetail)
00610         _logPool->updateSummaryDetail(_unpackEP,  TraceTimer(unpackstart), TraceTimer(CmiWallTimer()));
00611 }
00612 
00613 void TraceSummary::beginComputation(void)
00614 {
00615   // initialze arrays because now the number of entries is known.
00616   _logPool->initMem();
00617 }
00618 
00619 void TraceSummary::endComputation(void)
00620 {
00621   static int done = 0;
00622   if (done) return;
00623   done = 1;
00624   if (msgNum==0) {
00625 //CmiPrintf("Add at last: %d pe:%d time:%f msg:%d\n", index, CkMyPe(), bin, msgNum);
00626      _logPool->add(bin, CkMyPe());
00627      bin = 0.0;
00628      msgNum ++;
00629 
00630      binStart  += CkpvAccess(binSize);
00631      double t = TraceTimer();
00632      double ts = binStart;
00633      while (ts < t)
00634      {
00635        _logPool->add(bin, CkMyPe());
00636        bin=0.0;
00637        ts += CkpvAccess(binSize);
00638      }
00639 
00640   }
00641 }
00642 
00643 void TraceSummary::addEventType(int eventType)
00644 {
00645   _logPool->addEventType(eventType, TraceTimer());
00646 }
00647 
00648 void TraceSummary::startPhase(int phase)
00649 {
00650    _logPool->startPhase(phase);
00651 }
00652 
00653 
00655 
00656 CkGroupID traceSummaryGID;
00657 
00658 void TraceSummaryBOC::startSumOnly()
00659 {
00660   CmiAssert(CkMyPe() == 0);
00661 
00662   CProxy_TraceSummaryBOC p(traceSummaryGID);
00663   int size = CkpvAccess(_trace)->pool()->getNumEntries();
00664   p.askSummary(size);
00665 }
00666 
00667 void TraceSummaryBOC::askSummary(int size)
00668 {
00669   if (CkpvAccess(_trace) == NULL) return;
00670 
00671   int traced = CkpvAccess(_trace)->traceOnPE();
00672 
00673   BinEntry *bins = new BinEntry[size+1];
00674   bins[size] = traced;          // last element is the traced pe count
00675   if (traced) {
00676     CkpvAccess(_trace)->endComputation();
00677     int n = CkpvAccess(_trace)->pool()->getNumEntries();
00678     BinEntry *localBins = CkpvAccess(_trace)->pool()->bins();
00679 #if 0
00680   CmiPrintf("askSummary on [%d] numEntried=%d\n", CkMyPe(), n);
00681 #if 1
00682   for (int i=0; i<n; i++) CmiPrintf("%4d", localBins[i].getU());
00683   CmiPrintf("\n");
00684 #endif
00685 #endif
00686     if (n>size) n=size;
00687     for (int i=0; i<n; i++) bins[i] = localBins[i];
00688   }
00689 
00690   contribute(sizeof(BinEntry)*(size+1), bins, CkReduction::sum_double);
00691   delete [] bins;
00692 }
00693 
00694 extern "C" void _CkExit();
00695 
00696 void TraceSummaryBOC::sendSummaryBOC(CkReductionMsg *msg)
00697 {
00698   if (CkpvAccess(_trace) == NULL) return;
00699 
00700   CkAssert(CkMyPe() == 0);
00701 
00702   int n = msg->getSize()/sizeof(BinEntry);
00703   nBins = n-1;
00704   bins = (BinEntry *)msg->getData();
00705   nTracedPEs = (int)bins[n-1].time();
00706   //CmiPrintf("traced: %d entry:%d\n", nTracedPEs, nBins);
00707 
00708   write();
00709 
00710   delete msg;
00711 
00712   _CkExit();
00713 }
00714 
00715 void TraceSummaryBOC::write(void) 
00716 {
00717   int i;
00718   unsigned int j;
00719 
00720   char *fname = new char[strlen(CkpvAccess(traceRoot))+strlen(".sum")+1];
00721   sprintf(fname, "%s.sum", CkpvAccess(traceRoot));
00722   FILE *sumfp = fopen(fname, "w+");
00723   //CmiPrintf("File: %s \n", fname);
00724   if(sumfp == 0)
00725       CmiAbort("Cannot open summary sts file for writing.\n");
00726   delete[] fname;
00727 
00728   int _numEntries=_entryTable.size();
00729   fprintf(sumfp, "ver:%3.1f %d/%d count:%d ep:%d interval:%e numTracedPE:%d", CkpvAccess(version), CkMyPe(), CkNumPes(), nBins, _numEntries, CkpvAccess(binSize), nTracedPEs);
00730   fprintf(sumfp, "\n");
00731 
00732   // write bin time
00733 #if 0
00734   int last=pool[0].getU();
00735   writeU(fp, last);
00736   int count=1;
00737   for(j=1; j<numEntries; j++) {
00738     int u = pool[j].getU();
00739     if (last == u) {
00740       count++;
00741     }
00742     else {
00743       if (count > 1) fprintf(fp, "+%d", count);
00744       writeU(fp, u);
00745       last = u;
00746       count = 1;
00747     }
00748   }
00749   if (count > 1) fprintf(fp, "+%d", count);
00750 #else
00751   for(j=0; j<nBins; j++) {
00752     bins[j].time() /= nTracedPEs;
00753     bins[j].write(sumfp);
00754   }
00755 #endif
00756   fprintf(sumfp, "\n");
00757   fclose(sumfp);
00758 
00759 }
00760 
00761 extern "C" void CombineSummary()
00762 {
00763 #ifndef CMK_OPTIMIZE
00764   CmiPrintf("[%d] CombineSummary called!\n", CkMyPe());
00765   if (sumonly) {
00766     CmiPrintf("[%d] Sum Only start!\n", CkMyPe());
00767       // pe 0 start the sumonly process
00768     CProxy_TraceSummaryBOC sumProxy(traceSummaryGID);
00769     sumProxy[0].startSumOnly();
00770   }
00771   else CkExit();
00772 #else
00773   CkExit();
00774 #endif
00775 }
00776 
00777 void initTraceSummaryBOC()
00778 {
00779 #ifdef __BLUEGENE__
00780   if(BgNodeRank()==0) {
00781 #else
00782   if (CkMyRank() == 0) {
00783 #endif
00784     registerExitFn(CombineSummary);
00785   }
00786 }
00787 
00788 #include "TraceSummary.def.h"
00789 
00790 

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