00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "TProofProgressMemoryPlot.h"
00024 #include "TProofProgressDialog.h"
00025 #include "TRootEmbeddedCanvas.h"
00026 #include "TCanvas.h"
00027 #include "TGListBox.h"
00028 #include "TGButton.h"
00029 #include "TGLabel.h"
00030 #include "TGMenu.h"
00031 #include "TProofLog.h"
00032 #include "TUrl.h"
00033 #include "TProof.h"
00034 #include "TError.h"
00035 #include "TGFrame.h"
00036 #include "TMacro.h"
00037 #include "TObjString.h"
00038 #include "TMultiGraph.h"
00039 #include "TGraph.h"
00040 #include "TLegend.h"
00041 #include "TAxis.h"
00042
00043 #define kMemValuePos 8
00044 #define kMemValuePosMaster 8
00045 #define kEventNumberPos 13
00046
00047 ClassImp(TProofProgressMemoryPlot)
00048
00049
00050 TProofProgressMemoryPlot::TProofProgressMemoryPlot(TProofProgressDialog *d,
00051 Int_t w, Int_t h)
00052 : TGTransientFrame(gClient->GetRoot(),
00053 gClient->GetRoot(), w, h)
00054 {
00055
00056
00057 fDialog = d;
00058 fProofLog = 0;
00059 fWPlot = 0;
00060 fMPlot = 0;
00061 fAPlot = 0;
00062 fFullLogs = kFALSE;
00063
00064
00065 SetCleanup(kDeepCleanup);
00066 TGHorizontalFrame *htotal = new TGHorizontalFrame(this, w, h);
00067
00068 TGVerticalFrame *vworkers = new TGVerticalFrame(htotal);
00069 TGLabel *label1 = new TGLabel(vworkers,"Choose workers:");
00070
00071
00072 fWorkers = BuildLogList(vworkers);
00073 fWorkers->Resize(102,52);
00074 fWorkers->SetMultipleSelections(kTRUE);
00075
00076
00077 TGPopupMenu *pm = new TGPopupMenu(gClient->GetRoot());
00078 pm->AddEntry("Select All", 0);
00079 pm->AddEntry("Clear All", 1);
00080
00081 fAllWorkers = new TGSplitButton(vworkers, new TGHotString("Select ... "), pm);
00082 fAllWorkers->Connect("ItemClicked(Int_t)", "TProofProgressMemoryPlot", this,
00083 "Select(Int_t)");
00084 fAllWorkers->SetSplit(kFALSE);
00085
00086 Select(1);
00087 fWorkers->Select(0, kTRUE);
00088 fWorkers->Select(1, kTRUE);
00089
00090 fPlot = new TGTextButton(vworkers, "Plot");
00091 fPlot->Connect("Clicked()", "TProofProgressMemoryPlot", this, "DoPlot()");
00092 vworkers->AddFrame(label1, new TGLayoutHints(kLHintsLeft | kLHintsTop, 7, 2, 5, 2));
00093 vworkers->AddFrame(fAllWorkers, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 5, 2, 2, 2));
00094 vworkers->AddFrame(fWorkers, new TGLayoutHints(kLHintsExpandX | kLHintsTop | kLHintsExpandY, 2, 2, 5, 2));
00095 vworkers->AddFrame(fPlot, new TGLayoutHints(kLHintsExpandX | kLHintsBottom, 2, 2, 2, 2));
00096 htotal->AddFrame(vworkers, new TGLayoutHints(kLHintsCenterY | kLHintsLeft | kLHintsExpandY, 2, 2, 2, 2));
00097
00098 fWorkersPlot = new TRootEmbeddedCanvas("WorkersCanvas", htotal, 300, 300);
00099 htotal->AddFrame(fWorkersPlot, new TGLayoutHints(kLHintsCenterY | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2));
00100 fMasterPlot = new TRootEmbeddedCanvas("MasterCanvas", htotal, 300, 300);
00101 htotal->AddFrame(fMasterPlot, new TGLayoutHints(kLHintsCenterY | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 2, 2, 2 ,2));
00102
00103 AddFrame(htotal, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2));
00104 TString title;
00105 title.Form("PROOF Memory Consumption: %s", (fDialog->fProof ?
00106 fDialog->fProof->GetMaster() : "<dummy>"));
00107 SetWindowName(title);
00108 SetIconName(title);
00109
00110 MapSubwindows();
00111 Resize();
00112 CenterOnParent();
00113 MapWindow();
00114 }
00115
00116
00117 TProofProgressMemoryPlot::~TProofProgressMemoryPlot()
00118 {
00119
00120
00121 if (fProofLog){
00122 delete fProofLog;
00123 fProofLog = 0;
00124 }
00125 if (fMPlot){
00126 delete fMPlot;
00127 fMPlot = 0;
00128 }
00129 if (fWPlot){
00130 delete fWPlot;
00131 fWPlot = 0;
00132 }
00133
00134 fProofLog = 0;
00135 fDialog->fMemWindow = 0;
00136
00137 }
00138
00139
00140 TGListBox* TProofProgressMemoryPlot::BuildLogList(TGFrame *parent)
00141 {
00142
00143
00144
00145 TGListBox *c = new TGListBox(parent);
00146 c->AddEntry("average", 0);
00147
00148 SafeDelete(fProofLog);
00149
00150 fProofLog = TProof::Mgr(fDialog->fSessionUrl.Data())->GetSessionLogs(0, 0, "Svc.*Memory");
00151 if (fDialog->fStatus==TProofProgressDialog::kRunning) {
00152 fFullLogs = kFALSE;
00153 } else {
00154 fFullLogs = kTRUE;
00155 }
00156
00157 TList *elem = fProofLog->GetListOfLogs();
00158 TIter next(elem);
00159 TProofLogElem *pe = 0;
00160
00161 TString buf;
00162 Int_t is = 1;
00163 while ((pe=(TProofLogElem*)next())){
00164 TUrl url(pe->GetTitle());
00165 buf = TString::Format("%s %s", pe->GetName(), url.GetHost());
00166 c->AddEntry(buf.Data(), is);
00167 is++;
00168 }
00169 return c;
00170
00171 }
00172
00173
00174 void TProofProgressMemoryPlot::Clear(Option_t *)
00175 {
00176
00177
00178 if (fWorkersPlot)
00179 fWorkersPlot->GetCanvas()->Clear();
00180 if (fMasterPlot)
00181 fMasterPlot->GetCanvas()->Clear();
00182 }
00183
00184
00185 void TProofProgressMemoryPlot::DoPlot()
00186 {
00187
00188
00189 Clear();
00190
00191 if (!fProofLog || !fFullLogs ||
00192 (fDialog && fDialog->fStatus == TProofProgressDialog::kRunning)){
00193
00194 SafeDelete(fProofLog);
00195 if (fDialog) {
00196 fProofLog = TProof::Mgr(fDialog->fSessionUrl.Data())->GetSessionLogs(0, 0, "Svc.*Memory");
00197 if (fDialog->fStatus==TProofProgressDialog::kRunning) {
00198 fFullLogs = kFALSE;
00199 } else {
00200 fFullLogs = kTRUE;
00201 }
00202 } else {
00203 Error("DoPlot", "TProofProgessDialog instance undefined - protocol error?");
00204 return;
00205 }
00206 }
00207
00208
00209 if (!fProofLog) {
00210 Error("DoPlot", "could not get a valid instance of TProofLog");
00211 return;
00212 }
00213
00214 char name[512];
00215
00216 TList *elem = fProofLog->GetListOfLogs();
00217 if (!elem) {Error("DoPlot", "No log elements\n"); return;}
00218 TIter next(elem);
00219 TProofLogElem *ple=0;
00220
00221 Int_t iwelem = 0;
00222 Int_t imelem = 0;
00223 TGraph *gr=0;
00224
00225 TList *selected = new TList;
00226 fWorkers->GetSelectedEntries(selected);
00227 TIter nextworker(selected);
00228 TGTextLBEntry *selworker;
00229 TLegend *legw = 0;
00230 TLegend *legm = 0;
00231
00232
00233 if (fWPlot){
00234 delete fWPlot;
00235 fWPlot = 0;
00236 }
00237 if (fMPlot) {
00238 delete fMPlot;
00239 fMPlot = 0;
00240 }
00241
00242
00243 Int_t max = -1;
00244 Int_t min = -1;
00245 while ((selworker=(TGTextLBEntry*)nextworker())){
00246
00247 snprintf(name, sizeof(name)-1, "%s", selworker->GetText()->GetString());
00248 char *token;
00249 token = strtok(name, " ");
00250 if (!strcmp(token, "average")) {
00251 gr = DoAveragePlot(max, min);
00252 if (gr && gr->GetN()>0){
00253 if (!fWPlot) {
00254 fWPlot = new TMultiGraph();
00255 }
00256 if (!legw) {
00257 legw = new TLegend(0.1, 0.7, 0.4, 0.9);
00258 legw->SetHeader("Workers");
00259 }
00260 gr->SetMarkerColor(1);
00261 gr->SetMarkerStyle(2);
00262 gr->SetMarkerSize(1);
00263 gr->SetLineWidth(2);
00264 gr->SetLineColor(1);
00265 fWPlot->Add(gr, "l");
00266 legw->AddEntry(gr, token, "l");
00267 }
00268 TProofLogElem *pltemp = (TProofLogElem*)elem->At(min+1);
00269 gr = DoWorkerPlot(pltemp);
00270 if (gr && gr->GetN()>0){
00271 if (!fWPlot) {
00272 fWPlot = new TMultiGraph();
00273 }
00274 if (!legw) {
00275 legw = new TLegend(0.1, 0.7, 0.4, 0.9);
00276 legw->SetHeader("Workers");
00277 }
00278 gr->SetLineWidth(2);
00279 gr->SetLineColor(2);
00280 gr->SetLineStyle(3);
00281 fWPlot->Add(gr, "l");
00282 legw->AddEntry(gr, TString::Format("%s - min", pltemp->GetName()) , "l");
00283 }
00284 pltemp = (TProofLogElem*)elem->At(max+1);
00285 gr = DoWorkerPlot(pltemp);
00286 if (gr && gr->GetN()>0){
00287 if (!fWPlot) {
00288 fWPlot = new TMultiGraph();
00289 }
00290 if (!legw) {
00291 legw = new TLegend(0.1, 0.7, 0.4, 0.9);
00292 legw->SetHeader("Workers");
00293 }
00294 gr->SetLineWidth(2);
00295 gr->SetLineColor(2);
00296 gr->SetLineStyle(2);
00297 fWPlot->Add(gr, "l");
00298 legw->AddEntry(gr, TString::Format("%s - max", pltemp->GetName()), "l");
00299 }
00300
00301 continue;
00302 }
00303
00304
00305 ple = (TProofLogElem*)elem->FindObject(token);
00306 const char *role = ple->GetRole();
00307 if (role[0]=='w'){
00308
00309
00310 gr = DoWorkerPlot(ple);
00311 if (gr && gr->GetN()>0) {
00312 if (!fWPlot) {
00313 fWPlot = new TMultiGraph();
00314 }
00315 if (!legw) {
00316 legw = new TLegend(0.1, 0.7, 0.4, 0.9);
00317 legw->SetHeader("Workers");
00318 }
00319 gr->SetLineWidth(2);
00320 gr->SetLineColor(iwelem+3);
00321 fWPlot->Add(gr, "l");
00322 legw->AddEntry(gr, token, "l");
00323 iwelem++;
00324 }
00325 } else {
00326
00327
00328 gr = DoMasterPlot(ple);
00329 if (gr && gr->GetN()>0){
00330 if (!fMPlot){
00331 fMPlot = new TMultiGraph();
00332 }
00333 if (!legm) {
00334 legm = new TLegend(0.1, 0.7, 0.4, 0.9);
00335 legm->SetHeader("Master");
00336 }
00337 gr->SetLineWidth(2);
00338 gr->SetLineColor(imelem+1);
00339 fMPlot->Add(gr, "l");
00340 legm->AddEntry(gr, token, "l");
00341 imelem++;
00342 }
00343 }
00344
00345 }
00346
00347 if (fWPlot){
00348 fWorkersPlot->GetCanvas()->cd();
00349 fWPlot->Draw("a");
00350 fWPlot->GetXaxis()->SetTitle("Events Processed");
00351 fWPlot->GetYaxis()->SetTitle("MBytes");
00352 if (legw) legw->Draw();
00353
00354 }
00355 if (fMPlot) {
00356 fMasterPlot->GetCanvas()->cd();
00357 fMPlot->Draw("a");
00358 fMPlot->GetXaxis()->SetTitle("Objects Merged");
00359 fMPlot->GetYaxis()->SetTitle("MBytes");
00360 if (legm) legm->Draw();
00361 }
00362 fWorkersPlot->GetCanvas()->Update();
00363 fMasterPlot->GetCanvas()->Update();
00364
00365 delete selected;
00366 }
00367
00368
00369 TGraph *TProofProgressMemoryPlot::DoAveragePlot(Int_t &max_el, Int_t &min_el)
00370 {
00371
00372
00373 TList *elem = fProofLog->GetListOfLogs();
00374 if (!elem) {
00375 Error("DoAveragePlot", "Empty log");
00376 return 0;
00377 }
00378 TIter next(elem);
00379
00380 TProofLogElem *ple=0;
00381 Double_t max_av = 0;
00382 Double_t min_av = 10E9;
00383
00384 Long64_t maxevent = 0;
00385 Long64_t step = -1;
00386 TObjString *curline = 0;
00387 TObjString *prevline = 0;
00388 Long64_t curevent_value;
00389 Long64_t prevevent_value;
00390 Long64_t *last = new Long64_t[elem->GetEntries()];
00391 Long64_t vmem = -1, rmem = -1, nevt = -1;
00392 TString token;
00393 Int_t ielem=0;
00394 for (Int_t i=0; i<elem->GetEntries(); i++) {
00395 last[i] = 0;
00396 }
00397 while ((ple = (TProofLogElem *)next())){
00398
00399 const char *role = ple->GetRole();
00400 if (role[0] != 'w') continue;
00401 TList *lines = ple->GetMacro()->GetListOfLines();
00402 if (!lines || lines->GetSize() <= 0) continue;
00403 curline = (TObjString *) lines->Last();
00404 if (!curline) continue;
00405 curevent_value = 0;
00406 if (ParseLine(curline->String(), vmem, rmem, curevent_value) != 0) {
00407 Warning("DoAveragePlot", "error parsing line: '%s'", curline->String().Data());
00408 continue;
00409 }
00410 if (maxevent < curevent_value) maxevent = curevent_value;
00411 last[ielem] = curevent_value;
00412 if (step < 0) {
00413
00414 prevline = (TObjString *)lines->Before(curline);
00415 if (prevline) {
00416 prevevent_value = 0;
00417 if (ParseLine(prevline->String(), vmem, rmem, prevevent_value) != 0) {
00418 Warning("DoAveragePlot", "error parsing line: '%s'", curline->String().Data());
00419 } else {
00420 step = curevent_value - prevevent_value;
00421 }
00422 }
00423 }
00424 ielem++;
00425 }
00426 Int_t maxlines = Int_t(maxevent/(1.*step));
00427
00428 for (Int_t i=0; i<ielem; i++){
00429 last[i] /= step;
00430 }
00431
00432 Double_t *av_mem = new Double_t[maxlines];
00433 Int_t *nw = new Int_t[maxlines];
00434 for (Int_t i=0; i<maxlines; i++){
00435 av_mem[i]=0;
00436 nw[i]=0;
00437 }
00438 next.Reset();
00439 ielem=0;
00440 Int_t iline=0;
00441 Double_t cur_av;
00442 Long64_t nev;
00443 Long64_t nextevent = Long64_t(10E16);
00444 while ((ple = (TProofLogElem*)next())){
00445 const char *role = ple->GetRole();
00446 if (role[0]!='w') continue;
00447 TList *lines = ple->GetMacro()->GetListOfLines();
00448 if (!lines || lines->GetSize() <= 0) continue;
00449 TIter prev(lines, kIterBackward);
00450 nev = 0;
00451 nextevent = Long64_t(10E16);
00452 iline=0;
00453 cur_av = 0;
00454 while ((curline = (TObjString*)prev()) && iline<last[ielem]){
00455
00456 vmem = 0;
00457 if (ParseLine(curline->String(), vmem, rmem, nevt) != 0) {
00458 Warning("DoWorkerPlot", "error parsing line: '%s'", curline->String().Data());
00459 continue;
00460 }
00461 av_mem[last[ielem] -1 - iline] += vmem;
00462 nw[last[ielem] -1 - iline]++;
00463 if (last[ielem] > 0) cur_av += (Double_t)vmem / last[ielem];
00464 iline++;
00465 }
00466 if (cur_av > max_av){
00467 max_av = cur_av;
00468 max_el = ielem;
00469 }
00470 if (cur_av < min_av){
00471 min_av = cur_av;
00472 min_el = ielem;
00473 }
00474 ielem++;
00475 }
00476
00477 TGraph *gr = new TGraph(maxlines);
00478
00479 for (Int_t i=0; i<maxlines; i++){
00480 gr->SetPoint(i, (i+1)*step, av_mem[i]/(nw[i]*1024.));
00481 }
00482 delete [] av_mem;
00483 av_mem = 0;
00484 delete [] nw;
00485 nw = 0;
00486 delete [] last;
00487 last = 0;
00488 return gr;
00489
00490 }
00491
00492
00493 Int_t TProofProgressMemoryPlot::ParseLine(TString l,
00494 Long64_t &v, Long64_t &r, Long64_t &e)
00495 {
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 if (l.IsNull()) return -1;
00506
00507
00508 if (v < 0 && r < 0 && e < 0) return 0;
00509
00510
00511 Int_t from = kNPOS;
00512 if ((from = l.Index("Memory")) == kNPOS) return -1;
00513
00514
00515 from += 7;
00516 TString tok;
00517
00518
00519 if (v >= 0) {
00520 if (!l.Tokenize(tok, from, " ")) return -1;
00521 v = tok.Atoll();
00522 }
00523
00524
00525 if (r >= 0) {
00526 if ((from = l.Index("virtual", from)) == kNPOS) return -1;
00527 from += 8;
00528 if (!l.Tokenize(tok, from, " ")) return -1;
00529 r = tok.Atoll();
00530 }
00531
00532
00533 if (e >= 0) {
00534 if ((from = l.Index("event", from)) == kNPOS) return -1;
00535 from += 6;
00536 if (!l.Tokenize(tok, from, " ")) return -1;
00537 e = tok.Atoll();
00538 }
00539
00540
00541 return 0;
00542 }
00543
00544
00545 TGraph *TProofProgressMemoryPlot::DoWorkerPlot(TProofLogElem *ple)
00546 {
00547
00548
00549 TObjString *curline;
00550 TList *lines = ple->GetMacro()->GetListOfLines();
00551 if (!lines) {
00552
00553 return 0;
00554 }
00555
00556 Long64_t vmem = -1, rmem = -1, nevt = -1;
00557
00558
00559 curline = (TObjString*)lines->Last();
00560 Long64_t lastevent_value = 0;
00561 if (ParseLine(curline->String(), vmem, rmem, lastevent_value) != 0) {
00562 Error("DoWorkerPlot", "error parsing line: '%s'", curline->String().Data());
00563 return 0;
00564 }
00565
00566
00567 TObjString *prevline = (TObjString*)lines->Before(curline);
00568 Long64_t prevevent_value = 0;
00569 if (prevline && ParseLine(prevline->String(), vmem, rmem, prevevent_value) != 0) {
00570 Error("DoWorkerPlot", "error parsing line: '%s'", prevline->String().Data());
00571 return 0;
00572 }
00573 Long64_t step = lastevent_value - prevevent_value;
00574 if (step <= 0) {
00575 Error("DoWorkerPlot", "null or negative step (%lld) - cannot continue", step);
00576 return 0;
00577 }
00578
00579 Int_t nlines = lastevent_value/step;
00580 TGraph *gr = new TGraph(nlines);
00581
00582 TIter prevl(lines, kIterBackward);
00583 Int_t iline = 0;
00584 TString token;
00585 while ((curline = (TObjString*)prevl()) && iline<nlines){
00586
00587 vmem = 0;
00588 if (ParseLine(curline->String(), vmem, rmem, nevt) != 0) {
00589 Warning("DoWorkerPlot", "error parsing line: '%s'", curline->String().Data());
00590 continue;
00591 }
00592 gr->SetPoint(nlines-1-iline, lastevent_value-iline*step, vmem/1024.);
00593 iline++;
00594 }
00595
00596 return gr;
00597 }
00598
00599
00600 TGraph *TProofProgressMemoryPlot::DoMasterPlot(TProofLogElem *ple)
00601 {
00602
00603
00604
00605 TList *lines = ple->GetMacro()->GetListOfLines();
00606 TIter prevline(lines, kIterBackward);
00607 Int_t iline=0;
00608 TObjString *curline;
00609
00610 while ((curline = (TObjString*)prevline())) {
00611 if (curline->String().Contains("Start")) break;
00612 iline++;
00613 }
00614
00615 Long64_t vmem = -1, rmem = -1, nevt = -1;
00616
00617 Int_t nlines = iline;
00618 TString token;
00619 TGraph *gr = new TGraph(nlines);
00620 prevline.Reset();
00621 iline = 0;
00622 while ((curline = (TObjString*)prevline()) && iline<nlines) {
00623
00624 vmem = 0;
00625 if (ParseLine(curline->String(), vmem, rmem, nevt) != 0) {
00626 Warning("DoWorkerPlot", "error parsing line: '%s'", curline->String().Data());
00627 continue;
00628 }
00629 gr->SetPoint(nlines-iline, nlines-iline, vmem/1024.);
00630 iline++;
00631 }
00632 return gr;
00633 }
00634
00635
00636 void TProofProgressMemoryPlot::Select(Int_t id)
00637 {
00638
00639
00640 Int_t nen = fWorkers->GetNumberOfEntries();
00641 Bool_t sel = id ? 0 : 1;
00642
00643 for (Int_t ie=0; ie<nen; ie++) {
00644 fWorkers->Select(ie, sel);
00645 }
00646 }