00001
00002
00003
00004
00005
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
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
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
00118 poolSize = CkpvAccess(binCount);
00119 if (poolSize % 2) poolSize++;
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
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
00134 if (stsfp == 0) {
00135 CmiAbort("Cannot open summary sts file for writing.\n");
00136 }
00137 delete[] fname;
00138 }
00139 #endif
00140
00141
00142 markcount = 0;
00143 }
00144
00145 void SumLogPool::initMem()
00146 {
00147 int _numEntries=_entryTable.size();
00148 epInfoSize = _numEntries + NUM_DUMMY_EPS + 1;
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
00163
00164
00165
00166
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
00186
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
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
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
00251 fprintf(fp, "EPCallTime: ");
00252 for (i=0; i<_numEntries; i++)
00253 fprintf(fp, "%d ", epInfo[i].epCount);
00254 fprintf(fp, "\n");
00255
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
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
00278 if (CkpvAccess(version)>=3.0)
00279 {
00280 phaseTab.write(fp);
00281 }
00282
00283
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
00290
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
00315
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
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
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
00362 void SumLogPool::add(double time, int pe)
00363 {
00364 new (&pool[numBins++]) BinEntry(time);
00365 if(poolSize==numBins) shrink();
00366 }
00367
00368
00369
00370 void SumLogPool::setEp(int epidx, double time)
00371 {
00372 if (epidx >= epInfoSize) {
00373 CmiAbort("Invalid entry point!!\n");
00374 }
00375
00376 epInfo[epidx].setTime(time);
00377
00378 phaseTab.setEp(epidx, time);
00379 }
00380
00381
00382
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
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) {
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
00419 void SumLogPool::shrink(void)
00420 {
00421
00422
00423
00424
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
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
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
00483 if (!sumonly)
00484 sumDetail = CmiGetArgFlagDesc(argv, "+sumDetail", "more detailed summary info");
00485
00486 _logPool = new SumLogPool(CkpvAccess(traceRoot));
00487
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
00508 delete _logPool;
00509
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
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
00539
00540 start = t;
00541 double ts = binStart;
00542
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
00553 double t = TraceTimer();
00554 double ts = start;
00555 double nts = binStart;
00556
00557 if (execEp == TRACEON_EP) {
00558
00559
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());
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
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
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;
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
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
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
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
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