00001
00005
00006 #include "charm++.h"
00007 #include "trace-summary.h"
00008 #include "trace-summaryBOC.h"
00009
00010 #define DEBUGF(x) // CmiPrintf x
00011
00012 #define VER 7.1
00013
00014 #define INVALIDEP -2
00015 #define TRACEON_EP -3
00016
00017
00018 #define DefaultBinCount (1000*60*1)
00019
00020 CkpvStaticDeclare(TraceSummary*, _trace);
00021 static int _numEvents = 0;
00022 #define NUM_DUMMY_EPS 9
00023 CkpvDeclare(int, binCount);
00024 CkpvDeclare(double, binSize);
00025 CkpvDeclare(double, version);
00026
00027
00028 CkpvDeclare(int, previouslySentBins);
00029
00030
00031
00039 class compressedBuffer {
00040 public:
00041 char* buf;
00042 int pos;
00043
00044 compressedBuffer(){
00045 buf = NULL;
00046 pos = 0;
00047 }
00048
00049 compressedBuffer(int bytes){
00050 buf = (char*)malloc(bytes);
00051 pos = 0;
00052 }
00053
00054 compressedBuffer(void *buffer){
00055 buf = (char*)buffer;
00056 pos = 0;
00057 }
00058
00059 void init(void *buffer){
00060 buf = (char*)buffer;
00061 pos = 0;
00062 }
00063
00064 inline void * currentPtr(){
00065 return (void*)(buf+pos);
00066 }
00067
00068 template <typename T>
00069 T read(int offset){
00070
00071 T v;
00072 memcpy(&v, buf+offset, sizeof(T));
00073 return v;
00074 }
00075
00076 template <typename T>
00077 void write(T v, int offset){
00078 T v2 = v;
00079
00080 memcpy(buf+offset, &v2, sizeof(T));
00081 }
00082
00083 template <typename T>
00084 void increment(int offset){
00085 T temp;
00086 temp = read<T>(offset);
00087 temp ++;
00088 write<T>(temp, offset);
00089 }
00090
00091 template <typename T>
00092 void accumulate(T v, int offset){
00093 T temp;
00094 temp = read<T>(offset);
00095 temp += v;
00096 write<T>(temp, offset);
00097 }
00098
00099 template <typename T>
00100 int push(T v){
00101 int oldpos = pos;
00102 write<T>(v, pos);
00103 pos += sizeof(T);
00104 return oldpos;
00105 }
00106
00107 template <typename T>
00108 T pop(){
00109 T temp = read<T>(pos);
00110 pos += sizeof(T);
00111 return temp;
00112 }
00113
00114 template <typename T>
00115 T peek(){
00116 T temp = read<T>(pos);
00117 return temp;
00118 }
00119
00120 template <typename T0, typename T>
00121 T peekSecond(){
00122 T temp;
00123 memcpy(&temp, buf+pos+sizeof(T0), sizeof(T));
00124 return temp;
00125 }
00126
00127 int datalength(){
00128 return pos;
00129 }
00130
00131 void * buffer(){
00132 return (void*) buf;
00133 }
00134
00135 void freeBuf(){
00136 free(buf);
00137 }
00138
00139 ~compressedBuffer(){
00140
00141 }
00142
00143 };
00144
00145
00146
00147
00148
00149 CkGroupID traceSummaryGID;
00150 bool summaryCcsStreaming;
00151
00152 int sumonly = 0;
00153 int sumDetail = 0;
00154
00159 void _createTracesummary(char **argv)
00160 {
00161 DEBUGF(("%d createTraceSummary\n", CkMyPe()));
00162 CkpvInitialize(TraceSummary*, _trace);
00163 CkpvInitialize(int, previouslySentBins);
00164 CkpvAccess(previouslySentBins) = 0;
00165 CkpvAccess(_trace) = new TraceSummary(argv);
00166 CkpvAccess(_traces)->addTrace(CkpvAccess(_trace));
00167 if (CkMyPe()==0) CkPrintf("Charm++: Tracemode Summary enabled.\n");
00168 }
00169
00170
00172 extern "C"
00173 void CkSummary_StartPhase(int phase)
00174 {
00175 CkpvAccess(_trace)->startPhase(phase);
00176 }
00177
00178
00180 extern "C"
00181 void CkSummary_MarkEvent(int eventType)
00182 {
00183 CkpvAccess(_trace)->addEventType(eventType);
00184 }
00185
00186 static inline void writeU(FILE* fp, int u)
00187 {
00188 fprintf(fp, "%4d", u);
00189 }
00190
00191 PhaseEntry::PhaseEntry()
00192 {
00193 int _numEntries=_entryTable.size();
00194
00195 nEPs = _numEntries+10;
00196 count = new int[nEPs];
00197 times = new double[nEPs];
00198 maxtimes = new double[nEPs];
00199 for (int i=0; i<nEPs; i++) {
00200 count[i] = 0;
00201 times[i] = 0.0;
00202 maxtimes[i] = 0.;
00203 }
00204 }
00205
00206 SumLogPool::~SumLogPool()
00207 {
00208 if (!sumonly) {
00209 write();
00210 fclose(fp);
00211 if (sumDetail) fclose(sdfp);
00212 }
00213
00214 if (markcount > 0)
00215 for (int i=0; i<MAX_MARKS; i++) {
00216 for (int j=0; j<events[i].length(); j++)
00217 delete events[i][j];
00218 }
00219 delete[] pool;
00220 delete[] epInfo;
00221 delete[] cpuTime;
00222 delete[] numExecutions;
00223 }
00224
00225 void SumLogPool::addEventType(int eventType, double time)
00226 {
00227 if (eventType <0 || eventType >= MAX_MARKS) {
00228 CkPrintf("Invalid event type %d!\n", eventType);
00229 return;
00230 }
00231 MarkEntry *e = new MarkEntry;
00232 e->time = time;
00233 events[eventType].push_back(e);
00234 markcount ++;
00235 }
00236
00237 SumLogPool::SumLogPool(char *pgm) : numBins(0), phaseTab(MAX_PHASES)
00238 {
00239
00240 cpuTime = NULL;
00241 poolSize = CkpvAccess(binCount);
00242 if (poolSize % 2) poolSize++;
00243 pool = new BinEntry[poolSize];
00244 _MEMCHECK(pool);
00245
00246 this->pgm = new char[strlen(pgm)+1];
00247 strcpy(this->pgm,pgm);
00248
00249 #if 0
00250
00251 if (CkMyPe() == 0) {
00252 char *fname =
00253 new char[strlen(CkpvAccess(traceRoot))+strlen(".sum.sts")+1];
00254 sprintf(fname, "%s.sum.sts", CkpvAccess(traceRoot));
00255 stsfp = fopen(fname, "w+");
00256
00257 if (stsfp == 0) {
00258 CmiAbort("Cannot open summary sts file for writing.\n");
00259 }
00260 delete[] fname;
00261 }
00262 #endif
00263
00264
00265 markcount = 0;
00266 }
00267
00268 void SumLogPool::initMem()
00269 {
00270 int _numEntries=_entryTable.size();
00271 epInfoSize = _numEntries + NUM_DUMMY_EPS + 1;
00272 epInfo = new SumEntryInfo[epInfoSize];
00273 _MEMCHECK(epInfo);
00274
00275 cpuTime = NULL;
00276 numExecutions = NULL;
00277 if (sumDetail) {
00278 cpuTime = new double[poolSize*epInfoSize];
00279 _MEMCHECK(cpuTime);
00280 memset(cpuTime, 0, poolSize*epInfoSize*sizeof(double));
00281 numExecutions = new int[poolSize*epInfoSize];
00282 _MEMCHECK(numExecutions);
00283 memset(numExecutions, 0, poolSize*epInfoSize*sizeof(int));
00284
00285
00286
00287
00288
00289
00290
00291
00292 }
00293 }
00294
00295 int SumLogPool::getUtilization(int interval, int ep) {
00296 return (int)(getCPUtime(interval, ep) * 100.0 / CkpvAccess(binSize));
00297 }
00298
00299 void SumLogPool::write(void)
00300 {
00301 int i;
00302 unsigned int j;
00303 int _numEntries=_entryTable.size();
00304
00305 fp = NULL;
00306 sdfp = NULL;
00307
00308
00309
00310 if (!sumonly) {
00311 char pestr[10];
00312 sprintf(pestr, "%d", CkMyPe());
00313 int len = strlen(pgm) + strlen(".sumd.") + strlen(pestr) + 1;
00314 char *fname = new char[len+1];
00315
00316 sprintf(fname, "%s.%s.sum", pgm, pestr);
00317 do {
00318 fp = fopen(fname, "w+");
00319 } while (!fp && errno == EINTR);
00320 if (!fp) {
00321 CkPrintf("[%d] Attempting to open [%s]\n",CkMyPe(),fname);
00322 CmiAbort("Cannot open Summary Trace File for writing...\n");
00323 }
00324
00325 if (sumDetail) {
00326 sprintf(fname, "%s.%s.sumd", pgm, pestr);
00327 do {
00328 sdfp = fopen(fname, "w+");
00329 } while (!sdfp && errno == EINTR);
00330 if(!sdfp) {
00331 CmiAbort("Cannot open Detailed Summary Trace File for writing...\n");
00332 }
00333 }
00334 delete[] fname;
00335 }
00336
00337 fprintf(fp, "ver:%3.1f %d/%d count:%d ep:%d interval:%e", CkpvAccess(version), CkMyPe(), CkNumPes(), numBins, _numEntries, CkpvAccess(binSize));
00338 if (CkpvAccess(version)>=3.0)
00339 {
00340 fprintf(fp, " phases:%d", phaseTab.numPhasesCalled());
00341 }
00342 fprintf(fp, "\n");
00343
00344
00345 #if 1
00346 int last=pool[0].getU();
00347 writeU(fp, last);
00348 int count=1;
00349 for(j=1; j<numBins; j++) {
00350 int u = pool[j].getU();
00351 if (last == u) {
00352 count++;
00353 }
00354 else {
00355 if (count > 1) fprintf(fp, "+%d", count);
00356 writeU(fp, u);
00357 last = u;
00358 count = 1;
00359 }
00360 }
00361 if (count > 1) fprintf(fp, "+%d", count);
00362 #else
00363 for(j=0; j<numEntries; j++)
00364 pool[j].write(fp);
00365 #endif
00366 fprintf(fp, "\n");
00367
00368
00369 fprintf(fp, "EPExeTime: ");
00370 for (i=0; i<_numEntries; i++)
00371 fprintf(fp, "%ld ", (long)(epInfo[i].epTime*1.0e6));
00372 fprintf(fp, "\n");
00373
00374 fprintf(fp, "EPCallTime: ");
00375 for (i=0; i<_numEntries; i++)
00376 fprintf(fp, "%d ", epInfo[i].epCount);
00377 fprintf(fp, "\n");
00378
00379 fprintf(fp, "MaxEPTime: ");
00380 for (i=0; i<_numEntries; i++)
00381 fprintf(fp, "%ld ", (long)(epInfo[i].epMaxTime*1.0e6));
00382 fprintf(fp, "\n");
00383 #if 0
00384 for (i=0; i<SumEntryInfo::HIST_SIZE; i++) {
00385 for (j=0; j<_numEntries; j++)
00386 fprintf(fp, "%d ", epInfo[j].hist[i]);
00387 fprintf(fp, "\n");
00388 }
00389 #endif
00390
00391 if (CkpvAccess(version)>=2.0)
00392 {
00393 fprintf(fp, "NumMarks: %d ", markcount);
00394 for (i=0; i<MAX_MARKS; i++) {
00395 for(int j=0; j<events[i].length(); j++)
00396 fprintf(fp, "%d %f ", i, events[i][j]->time);
00397 }
00398 fprintf(fp, "\n");
00399 }
00400
00401 if (CkpvAccess(version)>=3.0)
00402 {
00403 phaseTab.write(fp);
00404 }
00405
00406 if (CkpvAccess(version)>=7.1) {
00407 fprintf(fp, "IdlePercent: ");
00408 int last=pool[0].getUIdle();
00409 writeU(fp, last);
00410 int count=1;
00411 for(j=1; j<numBins; j++) {
00412 int u = pool[j].getUIdle();
00413 if (last == u) {
00414 count++;
00415 }
00416 else {
00417 if (count > 1) fprintf(fp, "+%d", count);
00418 writeU(fp, u);
00419 last = u;
00420 count = 1;
00421 }
00422 }
00423 if (count > 1) fprintf(fp, "+%d", count);
00424 fprintf(fp, "\n");
00425 }
00426
00427
00428
00429 if (sumDetail) {
00430 fprintf(sdfp, "ver:%3.1f cpu:%d/%d numIntervals:%d numEPs:%d intervalSize:%e\n",
00431 CkpvAccess(version), CkMyPe(), CkNumPes(),
00432 numBins, _numEntries, CkpvAccess(binSize));
00433
00434
00435
00436 fprintf(sdfp, "ExeTimePerEPperInterval ");
00437 unsigned int e, i;
00438 long last= (long) (getCPUtime(0,0)*1.0e6);
00439 int count=0;
00440 fprintf(sdfp, "%ld", last);
00441 for(e=0; e<_numEntries; e++) {
00442 for(i=0; i<numBins; i++) {
00443
00444 long u= (long) (getCPUtime(i,e)*1.0e6);
00445 if (last == u) {
00446 count++;
00447 } else {
00448
00449 if (count > 1) fprintf(sdfp, "+%d", count);
00450 fprintf(sdfp, " %ld", u);
00451 last = u;
00452 count = 1;
00453 }
00454 }
00455 }
00456 if (count > 1) fprintf(sdfp, "+%d", count);
00457 fprintf(sdfp, "\n");
00458
00459
00460 fprintf(sdfp, "EPCallTimePerInterval ");
00461 last= getNumExecutions(0,0);
00462 count=0;
00463 fprintf(sdfp, "%ld", last);
00464 for(e=0; e<_numEntries; e++) {
00465 for(i=0; i<numBins; i++) {
00466
00467 long u= getNumExecutions(i, e);
00468 if (last == u) {
00469 count++;
00470 } else {
00471
00472 if (count > 1) fprintf(sdfp, "+%d", count);
00473 fprintf(sdfp, " %ld", u);
00474 last = u;
00475 count = 1;
00476 }
00477 }
00478 }
00479 if (count > 1) fprintf(sdfp, "+%d", count);
00480 fprintf(sdfp, "\n");
00481 }
00482 }
00483
00484 void SumLogPool::writeSts(void)
00485 {
00486
00487 char *fname =
00488 new char[strlen(CkpvAccess(traceRoot))+strlen(".sum.sts")+1];
00489 sprintf(fname, "%s.sum.sts", CkpvAccess(traceRoot));
00490 stsfp = fopen(fname, "w+");
00491
00492 if (stsfp == 0) {
00493 CmiAbort("Cannot open summary sts file for writing.\n");
00494 }
00495 delete[] fname;
00496
00497 traceWriteSTS(stsfp,_numEvents);
00498 for(int i=0;i<_numEvents;i++)
00499 fprintf(stsfp, "EVENT %d Event%d\n", i, i);
00500 fprintf(stsfp, "END\n");
00501
00502 fclose(stsfp);
00503 }
00504
00505
00506 void SumLogPool::add(double time, double idleTime, int pe)
00507 {
00508 new (&pool[numBins++]) BinEntry(time, idleTime);
00509 if (poolSize==numBins) {
00510 shrink();
00511 }
00512 }
00513
00514
00515
00516 void SumLogPool::setEp(int epidx, double time)
00517 {
00518 if (epidx >= epInfoSize) {
00519 CmiAbort("Invalid entry point!!\n");
00520 }
00521
00522 epInfo[epidx].setTime(time);
00523
00524 phaseTab.setEp(epidx, time);
00525 }
00526
00527
00528
00529 void SumLogPool::updateSummaryDetail(int epIdx, double startTime, double endTime)
00530 {
00531 if (epIdx >= epInfoSize) {
00532 CmiAbort("Too many entry points!!\n");
00533 }
00534
00535 double binSz = CkpvAccess(binSize);
00536 int startingBinIdx, endingBinIdx;
00537 startingBinIdx = (int)(startTime/binSz);
00538 endingBinIdx = (int)(endTime/binSz);
00539
00540 while (endingBinIdx >= poolSize) {
00541 shrink();
00542 CmiAssert(CkpvAccess(binSize) > binSz);
00543 binSz = CkpvAccess(binSize);
00544 startingBinIdx = (int)(startTime/binSz);
00545 endingBinIdx = (int)(endTime/binSz);
00546 }
00547
00548 if (startingBinIdx == endingBinIdx) {
00549 addToCPUtime(startingBinIdx, epIdx, endTime - startTime);
00550 } else if (startingBinIdx < endingBinIdx) {
00551 addToCPUtime(startingBinIdx, epIdx, (startingBinIdx+1)*binSz - startTime);
00552 while(++startingBinIdx < endingBinIdx)
00553 addToCPUtime(startingBinIdx, epIdx, binSz);
00554 addToCPUtime(endingBinIdx, epIdx, endTime - endingBinIdx*binSz);
00555 } else {
00556 CkPrintf("[%d] EP:%d Start:%lf End:%lf\n",CkMyPe(),epIdx,
00557 startTime, endTime);
00558 CmiAbort("Error: end time of EP is less than start time\n");
00559 }
00560
00561 incNumExecutions(startingBinIdx, epIdx);
00562 }
00563
00564
00565 void SumLogPool::shrink(void)
00566 {
00567
00568
00569
00570
00571 int entries = numBins/2;
00572 for (int i=0; i<entries; i++)
00573 {
00574 pool[i].time() = pool[i*2].time() + pool[i*2+1].time();
00575 pool[i].getIdleTime() = pool[i*2].getIdleTime() + pool[i*2+1].getIdleTime();
00576 if (sumDetail)
00577 for (int e=0; e < epInfoSize; e++) {
00578 setCPUtime(i, e, getCPUtime(i*2, e) + getCPUtime(i*2+1, e));
00579 setNumExecutions(i, e, getNumExecutions(i*2, e) + getNumExecutions(i*2+1, e));
00580 }
00581 }
00582
00583 if (sumDetail) {
00584 memset(&cpuTime[entries*epInfoSize], 0, (numBins-entries)*epInfoSize*sizeof(double));
00585 memset(&numExecutions[entries*epInfoSize], 0, (numBins-entries)*epInfoSize*sizeof(int));
00586 }
00587 numBins = entries;
00588 CkpvAccess(binSize) *= 2;
00589
00590
00591 }
00592
00593 void SumLogPool::shrink(double _maxBinSize)
00594 {
00595 while(CkpvAccess(binSize) < _maxBinSize)
00596 {
00597 shrink();
00598 };
00599 }
00600 int BinEntry::getU()
00601 {
00602 return (int)(_time * 100.0 / CkpvAccess(binSize));
00603 }
00604
00605 int BinEntry::getUIdle() {
00606 return (int)(_idleTime * 100.0 / CkpvAccess(binSize));
00607 }
00608
00609 void BinEntry::write(FILE* fp)
00610 {
00611 writeU(fp, getU());
00612 }
00613
00614 TraceSummary::TraceSummary(char **argv):binStart(0.0),idleStart(0.0),
00615 binTime(0.0),binIdle(0.0),msgNum(0)
00616 {
00617 if (CkpvAccess(traceOnPe) == 0) return;
00618
00619
00620 if (CmiTimerAbsolute()) binStart = CmiInitTime();
00621
00622 CkpvInitialize(int, binCount);
00623 CkpvInitialize(double, binSize);
00624 CkpvInitialize(double, version);
00625 CkpvAccess(binSize) = BIN_SIZE;
00626 CkpvAccess(version) = VER;
00627 CkpvAccess(binCount) = DefaultBinCount;
00628 if (CmiGetArgIntDesc(argv,"+bincount",&CkpvAccess(binCount), "Total number of summary bins"))
00629 if (CkMyPe() == 0)
00630 CmiPrintf("Trace: bincount: %d\n", CkpvAccess(binCount));
00631 CmiGetArgDoubleDesc(argv,"+binsize",&CkpvAccess(binSize),
00632 "CPU usage log time resolution");
00633 CmiGetArgDoubleDesc(argv,"+version",&CkpvAccess(version),
00634 "Write this .sum file version");
00635
00636 epThreshold = 0.001;
00637 CmiGetArgDoubleDesc(argv,"+epThreshold",&epThreshold,
00638 "Execution time histogram lower bound");
00639 epInterval = 0.001;
00640 CmiGetArgDoubleDesc(argv,"+epInterval",&epInterval,
00641 "Execution time histogram bin size");
00642
00643 sumonly = CmiGetArgFlagDesc(argv, "+sumonly", "merge histogram bins on processor 0");
00644
00645 if (!sumonly)
00646 sumDetail = CmiGetArgFlagDesc(argv, "+sumDetail", "more detailed summary info");
00647
00648 _logPool = new SumLogPool(CkpvAccess(traceRoot));
00649
00650 execEp=INVALIDEP;
00651 inIdle = 0;
00652 inExec = 0;
00653 depth = 0;
00654 }
00655
00656 void TraceSummary::traceClearEps(void)
00657 {
00658 _logPool->clearEps();
00659 }
00660
00661 void TraceSummary::traceWriteSts(void)
00662 {
00663 if(CkMyPe()==0)
00664 _logPool->writeSts();
00665 }
00666
00667 void TraceSummary::traceClose(void)
00668 {
00669 if(CkMyPe()==0)
00670 _logPool->writeSts();
00671 CkpvAccess(_trace)->endComputation();
00672
00673 delete _logPool;
00674 CkpvAccess(_traces)->removeTrace(this);
00675 }
00676
00677 void TraceSummary::beginExecute(CmiObjId *tid)
00678 {
00679 beginExecute(-1,-1,_threadEP,-1);
00680 }
00681
00682 void TraceSummary::beginExecute(envelope *e)
00683 {
00684
00685 if (e==NULL) {
00686 beginExecute(-1,-1,_threadEP,-1);
00687 }
00688 else {
00689 beginExecute(-1,-1,e->getEpIdx(),-1);
00690 }
00691 }
00692
00693 void TraceSummary::beginExecute(char *msg)
00694 {
00695 #if CMK_SMP_TRACE_COMMTHREAD
00696
00697 envelope *e = (envelope *)msg;
00698 int num = _entryTable.size();
00699 int ep = e->getEpIdx();
00700 if(ep<0 || ep>=num) return;
00701 if(_entryTable[ep]->traceEnabled)
00702 beginExecute(-1,-1,e->getEpIdx(),-1);
00703 #endif
00704 }
00705
00706 void TraceSummary::beginExecute(int event,int msgType,int ep,int srcPe, int mlen, CmiObjId *idx)
00707 {
00708 if (execEp == TRACEON_EP) {
00709 endExecute();
00710 }
00711 CmiAssert(inIdle == 0);
00712 if (inExec == 0) {
00713 CmiAssert(depth == 0);
00714 inExec = 1;
00715 }
00716 depth ++;
00717
00718
00719 if (depth > 1) return;
00720
00721
00722
00723
00724
00725
00726
00727
00728 execEp=ep;
00729 double t = TraceTimer();
00730
00731
00732 start = t;
00733 double ts = binStart;
00734
00735 while ((ts = ts + CkpvAccess(binSize)) < t) {
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747 _logPool->add(binTime, binIdle, CkMyPe());
00748 binTime=0.0;
00749 binIdle = 0.0;
00750 binStart = ts;
00751 }
00752 }
00753
00754 void TraceSummary::endExecute()
00755 {
00756 CmiAssert(inIdle == 0 && inExec == 1);
00757 depth --;
00758 if (depth == 0) inExec = 0;
00759 CmiAssert(depth >= 0);
00760
00761
00762 if (depth != 0) return;
00763
00764 double t = TraceTimer();
00765 double ts = start;
00766 double nts = binStart;
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 if (execEp == INVALIDEP) {
00777 TRACE_WARN("Warning: TraceSummary END_PROCESSING without BEGIN_PROCESSING!\n");
00778 return;
00779 }
00780
00781 if (execEp >= 0)
00782 {
00783 _logPool->setEp(execEp, t-ts);
00784 }
00785
00786 while ((nts = nts + CkpvAccess(binSize)) < t)
00787 {
00788
00789 binTime += nts-ts;
00790 binStart = nts;
00791
00792 _logPool->add(binTime, binIdle, CkMyPe());
00793 binTime = 0.0;
00794 binIdle = 0.0;
00795 ts = nts;
00796 }
00797 binTime += t - ts;
00798
00799 if (sumDetail && execEp >= 0 )
00800 _logPool->updateSummaryDetail(execEp, start, t);
00801
00802 execEp = INVALIDEP;
00803 }
00804
00805 void TraceSummary::endExecute(char *msg){
00806 #if CMK_SMP_TRACE_COMMTHREAD
00807
00808 envelope *e = (envelope *)msg;
00809 int num = _entryTable.size();
00810 int ep = e->getEpIdx();
00811 if(ep<0 || ep>=num) return;
00812 if(_entryTable[ep]->traceEnabled){
00813 endExecute();
00814 }
00815 #endif
00816 }
00817
00818 void TraceSummary::beginIdle(double currT)
00819 {
00820 if (execEp == TRACEON_EP) {
00821 endExecute();
00822 }
00823
00824 CmiAssert(inIdle == 0 && inExec == 0);
00825 inIdle = 1;
00826
00827
00828 double t = TraceTimer(currT);
00829
00830
00831
00832 idleStart = t;
00833 double ts = binStart;
00834
00835 while ((ts = ts + CkpvAccess(binSize)) < t) {
00836 _logPool->add(binTime, binIdle, CkMyPe());
00837 binTime=0.0;
00838 binIdle = 0.0;
00839 binStart = ts;
00840 }
00841 }
00842
00843 void TraceSummary::endIdle(double currT)
00844 {
00845 CmiAssert(inIdle == 1 && inExec == 0);
00846 inIdle = 0;
00847
00848
00849 double t = TraceTimer(currT);
00850 double t_idleStart = idleStart;
00851 double t_binStart = binStart;
00852
00853 while ((t_binStart = t_binStart + CkpvAccess(binSize)) < t)
00854 {
00855
00856 binIdle += t_binStart - t_idleStart;
00857 binStart = t_binStart;
00858 _logPool->add(binTime, binIdle, CkMyPe());
00859 binTime = 0.0;
00860 binIdle = 0.0;
00861 t_idleStart = t_binStart;
00862 }
00863 binIdle += t - t_idleStart;
00864 }
00865
00866 void TraceSummary::traceBegin(void)
00867 {
00868
00869
00870 beginExecute(-1, -1, TRACEON_EP, -1, -1);
00871 }
00872
00873 void TraceSummary::traceEnd(void)
00874 {
00875 endExecute();
00876 }
00877
00878 void TraceSummary::beginPack(void)
00879 {
00880 packstart = CmiWallTimer();
00881 }
00882
00883 void TraceSummary::endPack(void)
00884 {
00885 _logPool->setEp(_packEP, CmiWallTimer() - packstart);
00886 if (sumDetail)
00887 _logPool->updateSummaryDetail(_packEP, TraceTimer(packstart), TraceTimer(CmiWallTimer()));
00888 }
00889
00890 void TraceSummary::beginUnpack(void)
00891 {
00892 unpackstart = CmiWallTimer();
00893 }
00894
00895 void TraceSummary::endUnpack(void)
00896 {
00897 _logPool->setEp(_unpackEP, CmiWallTimer()-unpackstart);
00898 if (sumDetail)
00899 _logPool->updateSummaryDetail(_unpackEP, TraceTimer(unpackstart), TraceTimer(CmiWallTimer()));
00900 }
00901
00902 void TraceSummary::beginComputation(void)
00903 {
00904
00905 _logPool->initMem();
00906 }
00907
00908 void TraceSummary::endComputation(void)
00909 {
00910 static int done = 0;
00911 if (done) return;
00912 done = 1;
00913 if (msgNum==0) {
00914
00915 _logPool->add(binTime, binIdle, CkMyPe());
00916 binTime = 0.0;
00917 binIdle = 0.0;
00918 msgNum ++;
00919
00920 binStart += CkpvAccess(binSize);
00921 double t = TraceTimer();
00922 double ts = binStart;
00923 while (ts < t)
00924 {
00925 _logPool->add(binTime, binIdle, CkMyPe());
00926 binTime=0.0;
00927 binIdle = 0.0;
00928 ts += CkpvAccess(binSize);
00929 }
00930
00931 }
00932 }
00933
00934 void TraceSummary::addEventType(int eventType)
00935 {
00936 _logPool->addEventType(eventType, TraceTimer());
00937 }
00938
00939 void TraceSummary::startPhase(int phase)
00940 {
00941 _logPool->startPhase(phase);
00942 }
00943
00944 void TraceSummary::traceEnableCCS() {
00945 CProxy_TraceSummaryBOC sumProxy(traceSummaryGID);
00946 sumProxy.initCCS();
00947 }
00948
00949
00950 void TraceSummary::fillData(double *buffer, double reqStartTime,
00951 double reqBinSize, int reqNumBins) {
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 int binOffset = (int)(reqStartTime/reqBinSize);
00967 for (int i=binOffset; i<binOffset + reqNumBins; i++) {
00968
00969 buffer[i-binOffset] = pool()->getTime(i);
00970 }
00971 }
00972
00973 void TraceSummaryBOC::traceSummaryParallelShutdown(int pe) {
00974
00975 UInt numBins = CkpvAccess(_trace)->pool()->getNumEntries();
00976
00977 CProxy_TraceSummaryBOC sumProxy(traceSummaryGID);
00978 CkCallback cb(CkIndex_TraceSummaryBOC::maxBinSize(NULL), sumProxy[0]);
00979 contribute(sizeof(double), &(CkpvAccess(binSize)), CkReduction::max_double, cb);
00980 }
00981
00982
00983 void TraceSummaryBOC::maxBinSize(CkReductionMsg *msg)
00984 {
00985 double _maxBinSize = *((double *)msg->getData());
00986 CProxy_TraceSummaryBOC sumProxy(traceSummaryGID);
00987 sumProxy.shrink(_maxBinSize);
00988 }
00989
00990 void TraceSummaryBOC::shrink(double _mBin){
00991 UInt numBins = CkpvAccess(_trace)->pool()->getNumEntries();
00992 UInt epNums = CkpvAccess(_trace)->pool()->getEpInfoSize();
00993 _maxBinSize = _mBin;
00994 if(CkpvAccess(binSize) < _maxBinSize)
00995 {
00996 CkpvAccess(_trace)->pool()->shrink(_maxBinSize);
00997 }
00998 double *sumData = CkpvAccess(_trace)->pool()->getCpuTime();
00999 CProxy_TraceSummaryBOC sumProxy(traceSummaryGID);
01000 CkCallback cb(CkIndex_TraceSummaryBOC::sumData(NULL), sumProxy[0]);
01001 contribute(sizeof(double) * numBins * epNums, CkpvAccess(_trace)->pool()->getCpuTime(), CkReduction::sum_double, cb);
01002 }
01003
01004 void TraceSummaryBOC::sumData(CkReductionMsg *msg) {
01005 double *sumData = (double *)msg->getData();
01006 int totalsize = msg->getSize()/sizeof(double);
01007 UInt epNums = CkpvAccess(_trace)->pool()->getEpInfoSize();
01008 UInt numBins = totalsize/epNums;
01009 int numEntries = epNums - NUM_DUMMY_EPS - 1;
01010 char *fname = new char[strlen(CkpvAccess(traceRoot))+strlen(".sumall")+1];
01011 sprintf(fname, "%s.sumall", CkpvAccess(traceRoot));
01012 FILE *sumfp = fopen(fname, "w+");
01013 fprintf(sumfp, "ver:%3.1f cpu:%d numIntervals:%d numEPs:%d intervalSize:%e\n",
01014 CkpvAccess(version), CkNumPes(),
01015 numBins, numEntries, _maxBinSize);
01016 for(int i=0; i<numBins; i++){
01017 for(int j=0; j<numEntries; j++)
01018 {
01019 fprintf(sumfp, "%ld ", (long)(sumData[i*epNums+j]*1.0e6));
01020 }
01021 }
01022 fclose(sumfp);
01023
01024 CkExit();
01025 }
01026
01028
01029 void TraceSummaryBOC::initCCS() {
01030 if(firstTime){
01031 CkPrintf("[%d] initCCS() called for first time\n", CkMyPe());
01032
01033 lastRequestedIndexBlock = 0;
01034 indicesPerBlock = 1000;
01035 collectionGranularity = 0.001;
01036 nBufferedBins = 0;
01037
01038
01039
01040 if (CkMyPe() == 0) {
01041 ccsBufferedData = new CkVec<double>();
01042
01043 CProxy_TraceSummaryBOC sumProxy(traceSummaryGID);
01044 CkPrintf("Trace Summary now listening in for CCS Client\n");
01045 CcsRegisterHandler("CkPerfSummaryCcsClientCB",
01046 CkCallback(CkIndex_TraceSummaryBOC::ccsRequestSummaryDouble(NULL), sumProxy[0]));
01047 CcsRegisterHandler("CkPerfSummaryCcsClientCB uchar",
01048 CkCallback(CkIndex_TraceSummaryBOC::ccsRequestSummaryUnsignedChar(NULL), sumProxy[0]));
01049
01050 CkPrintf("[%d] Setting up periodic startCollectData callback\n", CkMyPe());
01051 CcdCallOnConditionKeep(CcdPERIODIC_1second, startCollectData,
01052 (void *)this);
01053 summaryCcsStreaming = CmiTrue;
01054 }
01055 firstTime = false;
01056 }
01057 }
01058
01064 void TraceSummaryBOC::ccsRequestSummaryDouble(CkCcsRequestMsg *m) {
01065 double *sendBuffer;
01066
01067 CkPrintf("[%d] Request from Client detected.\n", CkMyPe());
01068
01069 CkPrintf("Responding ...\n");
01070 int datalength = 0;
01071
01072
01073 if (ccsBufferedData->length() == 0) {
01074 sendBuffer = new double[1];
01075 sendBuffer[0] = -13.37;
01076 datalength = sizeof(double);
01077 CcsSendDelayedReply(m->reply, datalength, (void *)sendBuffer);
01078 delete [] sendBuffer;
01079 } else {
01080 sendBuffer = ccsBufferedData->getVec();
01081 datalength = ccsBufferedData->length()*sizeof(double);
01082 CcsSendDelayedReply(m->reply, datalength, (void *)sendBuffer);
01083 ccsBufferedData->free();
01084 }
01085 CkPrintf("Response Sent. Proceeding with computation.\n");
01086 delete m;
01087 }
01088
01089
01095 void TraceSummaryBOC::ccsRequestSummaryUnsignedChar(CkCcsRequestMsg *m) {
01096 unsigned char *sendBuffer;
01097
01098 CkPrintf("[%d] Request from Client detected. \n", CkMyPe());
01099
01100 CkPrintf("Responding ...\n");
01101 int datalength = 0;
01102
01103 if (ccsBufferedData->length() == 0) {
01104 sendBuffer = new unsigned char[1];
01105 sendBuffer[0] = 255;
01106 datalength = sizeof(unsigned char);
01107 CcsSendDelayedReply(m->reply, datalength, (void *)sendBuffer);
01108 delete [] sendBuffer;
01109 } else {
01110 double * doubleData = ccsBufferedData->getVec();
01111 int numData = ccsBufferedData->length();
01112
01113
01114 sendBuffer = new unsigned char[numData];
01115
01116 for(int i=0;i<numData;i++){
01117 sendBuffer[i] = 1000.0 * doubleData[i] / (double)CkNumPes() * 200.0;
01118 }
01119
01120 datalength = sizeof(unsigned char) * numData;
01121
01122 CcsSendDelayedReply(m->reply, datalength, (void *)sendBuffer);
01123 ccsBufferedData->free();
01124 delete [] sendBuffer;
01125 }
01126 CkPrintf("Response Sent. Proceeding with computation.\n");
01127 delete m;
01128 }
01129
01130
01131
01132 void startCollectData(void *data, double currT) {
01133 CkAssert(CkMyPe() == 0);
01134
01135 TraceSummaryBOC *sumObj = (TraceSummaryBOC *)data;
01136 int lastRequestedIndexBlock = sumObj->lastRequestedIndexBlock;
01137 double collectionGranularity = sumObj->collectionGranularity;
01138 int indicesPerBlock = sumObj->indicesPerBlock;
01139
01140 double startTime = lastRequestedIndexBlock*
01141 collectionGranularity * indicesPerBlock;
01142 int numIndicesToGet = (int)floor((currT - startTime)/
01143 collectionGranularity);
01144 int numBlocksToGet = numIndicesToGet/indicesPerBlock;
01145
01146
01147
01148 CProxy_TraceSummaryBOC sumProxy(traceSummaryGID);
01149
01150 sumProxy.collectSummaryData(startTime,
01151 collectionGranularity,
01152 numBlocksToGet*indicesPerBlock);
01153
01154 sumObj->lastRequestedIndexBlock += numBlocksToGet;
01155 }
01156
01157 void TraceSummaryBOC::collectSummaryData(double startTime, double binSize,
01158 int numBins) {
01159
01160
01161 double *contribution = new double[numBins];
01162 for (int i=0; i<numBins; i++) {
01163 contribution[i] = 0.0;
01164 }
01165 CkpvAccess(_trace)->fillData(contribution, startTime, binSize, numBins);
01166
01167
01168
01169
01170
01171
01172
01173 CProxy_TraceSummaryBOC sumProxy(traceSummaryGID);
01174 CkCallback cb(CkIndex_TraceSummaryBOC::summaryDataCollected(NULL), sumProxy[0]);
01175 contribute(sizeof(double)*numBins, contribution, CkReduction::sum_double,
01176 cb);
01177 }
01178
01179 void TraceSummaryBOC::summaryDataCollected(CkReductionMsg *msg) {
01180 CkAssert(CkMyPe() == 0);
01181
01182
01183
01184 double *recvData = (double *)msg->getData();
01185 int numBins = msg->getSize()/sizeof(double);
01186
01187
01188 for (int i=0; i<numBins; i++) {
01189 ccsBufferedData->insertAtEnd(recvData[i]);
01190 }
01191 delete msg;
01192 }
01193
01194
01195
01196
01197 void TraceSummaryBOC::startSumOnly()
01198 {
01199 CmiAssert(CkMyPe() == 0);
01200
01201 CProxy_TraceSummaryBOC p(traceSummaryGID);
01202 int size = CkpvAccess(_trace)->pool()->getNumEntries();
01203 p.askSummary(size);
01204 }
01205
01206 void TraceSummaryBOC::askSummary(int size)
01207 {
01208 if (CkpvAccess(_trace) == NULL) return;
01209
01210 int traced = CkpvAccess(_trace)->traceOnPE();
01211
01212 BinEntry *reductionBuffer = new BinEntry[size+1];
01213 reductionBuffer[size].time() = traced;
01214 reductionBuffer[size].getIdleTime() = 0;
01215 if (traced) {
01216 CkpvAccess(_trace)->endComputation();
01217 int n = CkpvAccess(_trace)->pool()->getNumEntries();
01218 BinEntry *localBins = CkpvAccess(_trace)->pool()->bins();
01219 if (n>size) n=size;
01220 for (int i=0; i<n; i++) reductionBuffer[i] = localBins[i];
01221 }
01222
01223 contribute(sizeof(BinEntry)*(size+1), reductionBuffer,
01224 CkReduction::sum_double);
01225 delete [] reductionBuffer;
01226 }
01227
01228
01229
01230 void TraceSummaryBOC::sendSummaryBOC(CkReductionMsg *msg)
01231 {
01232 if (CkpvAccess(_trace) == NULL) return;
01233
01234 CkAssert(CkMyPe() == 0);
01235
01236 int n = msg->getSize()/sizeof(BinEntry);
01237 nBins = n-1;
01238 bins = (BinEntry *)msg->getData();
01239 nTracedPEs = (int)bins[n-1].time();
01240
01241
01242 write();
01243
01244 delete msg;
01245
01246 CkExit();
01247 }
01248
01249 void TraceSummaryBOC::write(void)
01250 {
01251 unsigned int j;
01252
01253 char *fname = new char[strlen(CkpvAccess(traceRoot))+strlen(".sum")+1];
01254 sprintf(fname, "%s.sum", CkpvAccess(traceRoot));
01255 FILE *sumfp = fopen(fname, "w+");
01256
01257 if(sumfp == 0)
01258 CmiAbort("Cannot open summary sts file for writing.\n");
01259 delete[] fname;
01260
01261 int _numEntries=_entryTable.size();
01262 fprintf(sumfp, "ver:%3.1f %d/%d count:%d ep:%d interval:%e numTracedPE:%d", CkpvAccess(version), CkMyPe(), CkNumPes(), nBins, _numEntries, CkpvAccess(binSize), nTracedPEs);
01263 fprintf(sumfp, "\n");
01264
01265
01266 #if 0
01267 int last=pool[0].getU();
01268 writeU(fp, last);
01269 int count=1;
01270 for(j=1; j<numEntries; j++) {
01271 int u = pool[j].getU();
01272 if (last == u) {
01273 count++;
01274 }
01275 else {
01276 if (count > 1) fprintf(fp, "+%d", count);
01277 writeU(fp, u);
01278 last = u;
01279 count = 1;
01280 }
01281 }
01282 if (count > 1) fprintf(fp, "+%d", count);
01283 #else
01284 for(j=0; j<nBins; j++) {
01285 bins[j].time() /= nTracedPEs;
01286 bins[j].write(sumfp);
01287 }
01288 #endif
01289 fprintf(sumfp, "\n");
01290 fclose(sumfp);
01291
01292 }
01293
01294 extern "C" void CombineSummary()
01295 {
01296 #if CMK_TRACE_ENABLED
01297 CmiPrintf("[%d] CombineSummary called!\n", CkMyPe());
01298 if (sumonly) {
01299 CmiPrintf("[%d] Sum Only start!\n", CkMyPe());
01300
01301 CProxy_TraceSummaryBOC sumProxy(traceSummaryGID);
01302 sumProxy[0].startSumOnly();
01303 }else if(sumDetail)
01304 {
01305 CProxy_TraceSummaryBOC sumProxy(traceSummaryGID);
01306 sumProxy.traceSummaryParallelShutdown(-1);
01307 }
01308 else {
01309 _TRACE_BEGIN_EXECUTE_DETAILED(-1, -1, _threadEP,CkMyPe(), 0, NULL);
01310 CkExit();
01311 }
01312 #else
01313 CkExit();
01314 #endif
01315 }
01316
01317 void initTraceSummaryBOC()
01318 {
01319 #ifdef __BIGSIM__
01320 if(BgNodeRank()==0) {
01321 #else
01322 if (CkMyRank() == 0) {
01323 #endif
01324 registerExitFn(CombineSummary);
01325 }
01326 }
01327
01328
01329
01330
01331
01332
01333 #include "TraceSummary.def.h"
01334
01335