Logo ROOT  
Reference Guide
TProofPerfAnalysis.cxx
Go to the documentation of this file.
1// @(#)root/proofx:$Id$
2// Author: G.Ganis Nov 2011
3
4/*************************************************************************
5 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12
13/** \class TProofPerfAnalysis
14\ingroup proofbench
15
16Set of tools to analyse the performance tree
17
18*/
19
20#include <errno.h>
21
22#include "TProofPerfAnalysis.h"
23#include "TCanvas.h"
24#include "TFile.h"
25#include "TGraph.h"
26#include "TH1F.h"
27#include "TH2F.h"
28#include "THashList.h"
29#include "TKey.h"
30#include "TList.h"
31#include "TSortedList.h"
32#include "TPerfStats.h"
33#include "TRegexp.h"
34#include "TStyle.h"
35#include "TSystem.h"
36#include "TTree.h"
37#include "TMath.h"
38
39//
40// Auxilliary internal classes
41////////////////////////////////////////////////////////////////////////////////
42
43class TProofPerfAnalysis::TWrkInfo : public TNamed {
44public:
45 TWrkInfo(const char *ord, const char *name) :
46 TNamed(ord, name), fPackets(0), fRemotePackets(0), fEventsProcessed(0),
47 fBytesRead(0), fLatency(0), fProcTime(0), fCpuTime(0), fStart(0), fStop(-1),
48 fRateT(0), fRateRemoteT(0), fMBRateT(0), fMBRateRemoteT(0), fLatencyT(0) { }
49 virtual ~TWrkInfo() { SafeDelete(fRateT); SafeDelete(fRateRemoteT);
50 SafeDelete(fMBRateT); SafeDelete(fMBRateRemoteT);
51 SafeDelete(fLatencyT); }
52
53 Int_t fPackets; // Number of packets processed
54 Int_t fRemotePackets; // Number of processed packet from non-local files
55 Long64_t fEventsProcessed; // Tot events processed
56 Long64_t fBytesRead; // Tot bytes read
57 Double_t fLatency; // Tot latency
58 Double_t fProcTime; // Tot proc time
59 Double_t fCpuTime; // Tot CPU time
60
61 Float_t fStart; // Start time
62 Float_t fStop; // Stop time
63
64 TGraph *fRateT; // Event processing rate vs time
65 TGraph *fRateRemoteT; // Event processing rate of remote packets vs time
66 TGraph *fMBRateT; // Byte processing rate vs time
67 TGraph *fMBRateRemoteT; // Byte processing rate of remote packets vs time
68 TGraph *fLatencyT; // Packet latency vs time
69
70 Double_t AvgRate() { if (fProcTime > 0) return (fEventsProcessed/fProcTime); return -1.; }
71 Double_t AvgIO() { if (fProcTime > 0) return (fBytesRead/fProcTime); return -1.; }
72
73 void Print(Option_t * = "") const {
74 Printf(" +++ TWrkInfo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ");
75 Printf(" +++ Worker: %s, %s", GetName(), GetTitle());
76 Printf(" +++ Activity interval: %f -> %f", fStart, fStop);
77 Printf(" +++ Amounts processed: %d packets (%d remote), %lld evts, %lld bytes",
78 fPackets, fRemotePackets, fEventsProcessed, fBytesRead);
79 if (fProcTime) {
80 Printf(" +++ Processing time: %f s (CPU: %f s)", fProcTime, fCpuTime);
81 Printf(" +++ Averages: %f evts/s, %f MB/s", (Double_t)fEventsProcessed / fProcTime, (Double_t)fBytesRead /1024./1024./fProcTime);
82 }
83 Printf(" +++ Total latency: %f", fLatency);
84 Printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ");
85 }
86
87 Int_t Compare(const TObject *o) const { TWrkInfo *wi = (TWrkInfo *)o;
88 if (wi) {
89 if (fStop < wi->fStop) {
90 return -1;
91 } else if (fStop == wi->fStop) {
92 return 0;
93 }
94 }
95 return 1; }
96};
97
98
99class TProofPerfAnalysis::TPackInfo : public TNamed {
100public:
101 TPackInfo(const char *ord, const char *host) : TNamed(ord, host), fStart(0), fStop(-1), fSize(0), fMBRate(0.) { }
102 TPackInfo(const char *ord, const char *host, Float_t start, Float_t stop, Long64_t sz, Double_t mbr)
103 : TNamed(ord, host), fStart(start), fStop(stop), fSize(sz), fMBRate(mbr) { }
104 Float_t fStart; // When the packet has been assigned
105 Float_t fStop; // When the packet has been finished
106 Long64_t fSize; // Packet size
107 Double_t fMBRate; // Processing rate MB/s
108 void Print(Option_t *opt= "") const {
109 if (!strcmp(opt, "S")) {
110 Printf(" \t%10lld evts, \t%12.2f MB/s, \t%12.3f -> %12.3f s", fSize, fMBRate, fStart, fStop);
111 } else {
112 Printf(" %s:\t%s \t%10lld evts, \t%12.2f MB/s, \t%12.3f -> %12.3f s", GetTitle(), GetName(), fSize, fMBRate, fStart, fStop);
113 }
114 }
115};
116
117class TProofPerfAnalysis::TWrkInfoFile : public TNamed {
118public:
119 TWrkInfoFile(const char *ord, const char *name) : TNamed(ord, name) { }
120 ~TWrkInfoFile() {fPackets.SetOwner(kFALSE); fPackets.Clear("nodelete");}
121 TList fPackets; // Packest from this file processed by this worker
122 void Print(Option_t *opt= "") const {
123 if (!strcmp(opt, "R")) {
124 Printf(" Worker: %s,\tpacket(s): %d", GetName(), fPackets.GetSize());
125 } else {
126 Printf(" Worker: %s,\t%d packet(s) from file: %s", GetName(), fPackets.GetSize(), GetTitle());
127 }
128 TIter nxp(&fPackets);
129 TObject *o = 0;
130 while ((o = nxp())) { o->Print("S"); }
131 }
132};
133
134class TProofPerfAnalysis::TWrkEntry : public TObject {
135public:
136 TWrkEntry(Double_t xx, Double_t er, Double_t mbr, Double_t pt) : fXx(xx), fEvtRate(er), fMBRate(mbr), fProcTime(pt) { }
137 Double_t fXx; // Bin center
138 Double_t fEvtRate; // Event processing rate from this worker for this packet
139 Double_t fMBRate; // I/O processing rate from this worker for this packet
140 Double_t fProcTime; // Processing time
141 void Print(Option_t * = "") const { Printf("%.4f \t%.3f evt/s \t%.3f MB/s \t%.3f s ", fXx, fEvtRate, fMBRate, fProcTime); }
142};
143
144////////////////////////////////////////////////////////////////////////////////
145
146class TProofPerfAnalysis::TFileInfo : public TNamed {
147public:
148 TFileInfo(const char *name, const char *srv) :
149 TNamed(name, srv), fPackets(0), fRPackets(0), fStart(0), fStop(-1),
150 fSizeAvg(0), fSizeMax(-1.), fSizeMin(-1.),
151 fMBRateAvg(0), fMBRateMax(-1.), fMBRateMin(-1.), fSizeP(0),
152 fRateP(0), fRatePRemote(0), fMBRateP(0), fMBRatePRemote(0) { }
153 virtual ~TFileInfo() {SafeDelete(fSizeP);
154 SafeDelete(fRateP); SafeDelete(fRatePRemote);
155 SafeDelete(fMBRateP); SafeDelete(fMBRatePRemote);
156 fPackList.SetOwner(kTRUE); fPackList.Clear();
157 fWrkList.SetOwner(kTRUE); fWrkList.Clear();
158 fRWrkList.SetOwner(kTRUE); fRWrkList.Clear();}
159
160 Int_t fPackets; // Number of packets from this file
161 Int_t fRPackets; // Number of different remote workers processing this file
162
163 TList fPackList; // List of packet info
164 TList fWrkList; // List of worker names processing this packet
165 TList fRWrkList; // List of remote worker names processing this packet
166
167 Float_t fStart; // When the first packet has been assigned
168 Float_t fStop; // When the last packet has been finished
169
170 Long64_t fSizeAvg; // Average Packet size
171 Long64_t fSizeMax; // Max packet size
172 Long64_t fSizeMin; // Min packet size
173
174 Double_t fMBRateAvg; // Average MB rate
175 Double_t fMBRateMax; // Max MB rate
176 Double_t fMBRateMin; // Min MB rate
177
178 TGraph *fSizeP; // Packet size vs packet (all)
179 TGraph *fRateP; // Event processing rate vs packet (all)
180 TGraph *fRatePRemote; // Event processing rate vs packet (remote workers)
181 TGraph *fMBRateP; // Byte processing rate vs packet (all)
182 TGraph *fMBRatePRemote; // Byte processing rate vs packet (remote workers)
183
184 void Print(Option_t *opt = "") const {
185 Printf(" +++ TFileInfo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ");
186 Printf(" +++ Server: %s", GetTitle());
187 Printf(" +++ File: %s", GetName());
188 Printf(" +++ Processing interval: %f -> %f", fStart, fStop);
189 Printf(" +++ Packets: %d (%d remote)", fPackets, fRPackets);
190 Printf(" +++ Processing wrks: %d (%d remote)", fWrkList.GetSize(), fRWrkList.GetSize());
191 if (!strcmp(opt, "P")) fPackList.Print();
192 if (!strcmp(opt, "WP")) fWrkList.Print("R");
193 if (fPackets > 0) {
194 Printf(" +++ MB rates: %f MB/s (avg), %f MB/s (min), %f MB/s (max)",
195 fMBRateAvg / fPackets, fMBRateMin, fMBRateMax);
196 Printf(" +++ Sizes: %lld (avg), %lld (min), %lld (max)",
197 fSizeAvg / fPackets, fSizeMin, fSizeMax);
198 }
199 Printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ");
200 }
201
202 Int_t Compare(const TObject *o) const { TFileInfo *wi = (TFileInfo *)o;
203 if (wi) {
204 if (fStop < wi->fStop) {
205 return -1;
206 } else if (fStop == wi->fStop) {
207 return 0;
208 }
209 }
210 return 1; }
211};
212
214////////////////////////////////////////////////////////////////////////////////
215/// Constructor: open the file and attach to the tree
216
218 const char *title, const char *treename)
219 : TNamed(perffile, title), fFile(0), fTreeName(treename), fTree(0),
220 fInitTime(-1.), fMergeTime(-1.), fMaxTime(-1.),
221 fEvents(0), fPackets(0),
222 fEvtRateMax(-1.), fMBRateMax(-1.), fLatencyMax(-1.),
223 fEvtRate(0), fEvtRateRun(0), fMBRate(0), fMBRateRun(0),
224 fEvtRateAvgMax(-1.), fMBRateAvgMax(-1.),
225 fEvtRateAvg(-1.), fMBRateAvg(0),
226 fFileResult(""), fSaveResult(kFALSE),
227 fDebug(0)
228{
229 // Use default title, if not specified
230 if (!title) SetTitle("PROOF Performance Analysis");
231
232 fTree = 0;
233 fFile = TFile::Open(perffile);
234 if (!fFile || (fFile && fFile->IsZombie())) {
236 Error("TProofPerfAnalysis", "problems opening file '%s'",
237 perffile ? perffile : "<undef>");
239 return;
240 }
241
242 // Set the subdirectory name, if any
243 if (fTreeName.Contains("/")) {
246 }
247
248 // Adjust the name, if requested
249 if (fTreeName.BeginsWith("+"))
250 fTreeName.Replace(0, 1, "PROOF_PerfStats");
251
252 // Point to the right TDirectory
253 TDirectory *dir = fFile;
254 if (!fDirName.IsNull()) {
255 if (!(dir = dynamic_cast<TDirectory *>(fFile->Get(fDirName)))) {
256 Error("TProofPerfAnalysis", "directory '%s' not found or not loadable", fDirName.Data());
257 fFile->Close();
260 return;
261 }
262 }
263
264 // Load the performance tree
265 LoadTree(dir);
266 if (!fTree) {
267 Error("TProofPerfAnalysis", "tree '%s' not found or not loadable", fTreeName.Data());
268 fFile->Close();
271 return;
272 }
273 if (fgDebug)
274 Printf(" +++ TTree '%s' has %lld entries", fTreeName.Data(), fTree->GetEntries());
275
276 // Init worker information
277 FillWrkInfo();
278
279 // Init file information
280 FillFileInfo();
281
282 // Done
283 return;
284}
285
286////////////////////////////////////////////////////////////////////////////////
287/// Constructor: open the file and attach to the tree
288
290 : TNamed("", title), fFile(0), fTree(0),
291 fInitTime(-1.), fMergeTime(-1.), fMaxTime(-1.),
292 fEvents(0), fPackets(0),
293 fEvtRateMax(-1.), fMBRateMax(-1.), fLatencyMax(-1.),
294 fEvtRate(0), fEvtRateRun(0), fMBRate(0), fMBRateRun(0),
295 fEvtRateAvgMax(-1.), fMBRateAvgMax(-1.),
296 fEvtRateAvg(-1.), fMBRateAvg(0),
297 fDebug(0)
298{
299 // The tree must be defined
300 if (!tree) {
302 return;
303 }
304
305 // Use default title, if not specified
306 if (!title) SetTitle("PROOF Performance Analysis");
307
308 fTree = tree;
310 SetName(TString::Format("heap_%s", fTreeName.Data()));
311
312 // Adjust the name, if requested
313 if (fTreeName.BeginsWith("+"))
314 fTreeName.Replace(0, 1, "PROOF_PerfStats");
315
316 if (fgDebug)
317 Printf(" +++ TTree '%s' has %lld entries", fTreeName.Data(), fTree->GetEntries());
318
319 // Init worker information
320 FillWrkInfo();
321
322 // Init file information
323 FillFileInfo();
324
325 // Done
326 return;
327}
328
329////////////////////////////////////////////////////////////////////////////////
330/// Destructor: detach the tree and close the file
331
333{
336 if (fFile) fFile->Close();
338}
339
340////////////////////////////////////////////////////////////////////////////////
341/// If defined, add '- <this title>' to the canvas title 't'
342
344{
345 if (fTitle.IsNull()) return TString(t);
346
347 TString newt;
348 if (t && strlen(t) > 0) {
349 newt.Form("%s - %s", t, GetTitle());
350 } else {
351 newt = GetTitle();
352 }
353 // Done
354 return newt;
355}
356
357////////////////////////////////////////////////////////////////////////////////
358/// Load tree fTreeName from directory 'dir'. If not found, look for the
359/// first TTree in the directory (and sub-directories) with the name containing
360/// fTreeName.
361/// The tree pointer is saved in fTree.
362
364{
365 fTree = 0;
366 if (!dir) return;
367
368 // Try first the full name in the top directory
369 if ((fTree = dynamic_cast<TTree *>(dir->Get(fTreeName)))) return;
370
371 TRegexp re(fTreeName);
372 // Now look inside: iter on the list of keys first
373 TIter nxk(dir->GetListOfKeys());
374 TKey *k = 0;
375 while ((k = (TKey *) nxk())) {
376 if (!strcmp(k->GetClassName(), "TDirectoryFile")) {
377 TDirectory *kdir = (TDirectory *) dir->Get(k->GetName());
378 LoadTree(kdir);
379 if (fTree) return;
380 } else if (!strcmp(k->GetClassName(), "TTree")) {
381 TString tn(k->GetName());
382 if (tn.Index(re) != kNPOS) {
383 if ((fTree = dynamic_cast<TTree *>(dir->Get(tn)))) {
384 fTreeName = tn;
385 if (fgDebug) Printf(" +++ Found and loaded TTree '%s'", tn.Data());
386 return;
387 }
388 }
389 }
390 }
391
392 // Nothing found
393 return;
394}
395
396////////////////////////////////////////////////////////////////////////////////
397/// Analyse the file distribution. If writedet, underling details are
398/// written out to a text file.
399
401{
402 if (!IsValid()) {
403 Error("FileDist","not a valid instance - do nothing");
404 return;
405 }
406
407 // Fill file info
408 TList *wrkList = new TList;
409 TList *srvList = new TList;
410 GetWrkFileList(wrkList, srvList);
411 Info("FileDist", "%d workers were active during this query", wrkList->GetSize());
412 Info("FileDist", "%d servers were active during this query", srvList->GetSize());
413
414 // Fill the worker-data server mapping
415 TIter nxs(srvList);
416 TIter nxw(wrkList);
417 TNamed *sn = 0, *wn = 0;
418 while ((sn = (TNamed *)nxs())) {
419 nxw.Reset();
420 while ((wn = (TNamed *) nxw())) {
421 if (!strcmp(TUrl(sn->GetName()).GetHostFQDN(), wn->GetTitle())) {
422 sn->SetTitle(wn->GetName());
423 }
424 }
425 }
426
427 // Reorder the lists following the title
428 TList *nwl = new TList;
429 TList *nsl = new TList;
430 nxw.Reset();
431 while ((wn = (TNamed *) nxw())) {
432 TIter nnxw(nwl);
433 TNamed *nwn = 0;
434 while ((nwn = (TNamed *) nnxw())) {
435 if (CompareOrd(wn->GetName(), nwn->GetName()) < 0) {
436 nwl->AddBefore(nwn, wn);
437 break;
438 }
439 }
440 if (!nwn) nwl->Add(wn);
441 // Find the server name, if any
442 nxs.Reset();
443 while ((sn = (TNamed *)nxs())) {
444 if (!strcmp(sn->GetTitle(), wn->GetName())) {
445 TIter nnxs(nsl);
446 TNamed *nsn = 0;
447 while ((nsn = (TNamed *) nnxs())) {
448 if (CompareOrd(sn->GetTitle(), nsn->GetTitle()) < 0) {
449 nsl->AddBefore(nsn, sn);
450 break;
451 }
452 }
453 if (!nsn) nsl->Add(sn);
454 break;
455 }
456 }
457 if (sn) srvList->Remove(sn);
458 }
459 // Add remaining servers at the end
460 nxs.Reset();
461 while ((sn = (TNamed *)nxs())) {
462 nsl->Add(sn);
463 }
464 // Clean the orginal lists
465 wrkList->SetOwner(kFALSE);
466 srvList->SetOwner(kFALSE);
467 delete wrkList;
468 delete srvList;
469 wrkList = nwl;
470 srvList = nsl;
471
472 // Notify
473 wrkList->ls();
474 srvList->ls();
475
476 // Separate out the case with only one file server
477 if (srvList->GetSize() == 1) {
478
479 Printf("\n +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ");
480 Printf(" + Only one data server found: full analysis meaningful + ");
481 Printf(" + only when there are more file servers + ");
482 Printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n");
483
484
485 // Create a 1D histo for cross packets
486 TH1F *hxpak = new TH1F("hxpak", "MBytes / Worker",
487 wrkList->GetSize(), 0., (Double_t)wrkList->GetSize());
488 hxpak->SetDirectory(0);
489 hxpak->SetMinimum(0.);
490 hxpak->GetXaxis()->SetTitle("Worker");
491
492 // Set the labels
493 Int_t j = 1;
494 TIter nxsw(wrkList);
495 while ((wn = (TNamed *)nxsw())) {
496 hxpak->GetXaxis()->SetBinLabel(j++, wn->GetName());
497 }
498
499 // Fill the histograms
500 FillFileDistOneSrv(hxpak, writedet);
501
502 // Display histos
503 gStyle->SetOptStat(0);
504
505 TCanvas *c2 = new TCanvas("cv-hxpak", GetCanvasTitle(hxpak->GetTitle()), 800,350,700,700);
506 c2->cd();
507 DoDraw(hxpak);
508 c2->Update();
509
510 } else {
511 // Create a 1D histo for file distribution
512 TH1F *hfdis = new TH1F("hfdis", "Packet dist",
513 srvList->GetSize(), 0., (Double_t)srvList->GetSize());
514 hfdis->SetDirectory(0);
515 hfdis->SetMinimum(0);
516 hfdis->GetXaxis()->SetTitle("Server");
517 TH1F *hbdis = new TH1F("hbdis", "MBytes dist",
518 srvList->GetSize(), 0., (Double_t)srvList->GetSize());
519 hbdis->SetDirectory(0);
520 hbdis->SetMinimum(0);
521 hbdis->GetXaxis()->SetTitle("Server");
522 // Create a 2D histo for cross packets
523 TH2F *hxpak = new TH2F("hxpak", "MBytes / {Worker,Server}",
524 srvList->GetSize(), 0., (Double_t)srvList->GetSize(),
525 wrkList->GetSize(), 0., (Double_t)wrkList->GetSize());
526 hxpak->SetDirectory(0);
527 hxpak->GetYaxis()->SetTitle("Worker");
528 hxpak->GetXaxis()->SetTitle("Server");
529 hxpak->GetXaxis()->SetTitleOffset(1.4);
530 hxpak->GetYaxis()->SetTitleOffset(1.7);
531
532 // Set the labels
533 Int_t j = 1;
534 TIter nxsw(wrkList);
535 while ((wn = (TNamed *)nxsw())) {
536 hxpak->GetYaxis()->SetBinLabel(j++, wn->GetName());
537 }
538 j = 1;
539 TIter nxss(srvList);
540 while ((sn = (TNamed *)nxss())) {
541 hfdis->GetXaxis()->SetBinLabel(j, sn->GetName());
542 hbdis->GetXaxis()->SetBinLabel(j, sn->GetName());
543 hxpak->GetXaxis()->SetBinLabel(j++, sn->GetName());
544 }
545
546 // Fill the histograms
547 FillFileDist(hfdis, hbdis, hxpak, writedet);
548
549 j = 1;
550 nxss.Reset();
551 while ((sn = (TNamed *)nxss())) {
552 TString lab(sn->GetName());
553 lab = TUrl(sn->GetName()).GetHost();
554 if (strcmp(sn->GetTitle(), "remote") && lab.Index(".") != kNPOS) lab.Remove(lab.Index("."));
555 hfdis->GetXaxis()->SetBinLabel(j, lab);
556 hbdis->GetXaxis()->SetBinLabel(j, lab);
557 hxpak->GetXaxis()->SetBinLabel(j++, lab);
558 }
559
560 // Display histos
561 gStyle->SetOptStat(0);
562
563 TCanvas *c1 = new TCanvas("cv-hfdis", GetCanvasTitle(hfdis->GetTitle()), 800,50,700,700);
564 c1->Divide(1,2);
565 TPad *pad1 = (TPad *) c1->GetPad(1);
566 TPad *pad2 = (TPad *) c1->GetPad(2);
567 pad1->cd();
568 DoDraw(hfdis);
569 pad2->cd();
570 DoDraw(hbdis);
571 c1->Update();
572
573 TCanvas *c2 = new TCanvas("cv-hxpak", GetCanvasTitle(hxpak->GetTitle()), 500,350,700,700);
574 c2->cd();
575 DoDraw(hxpak, "lego");
576 c2->Update();
577 }
578 // Done
579 return;
580}
581
582////////////////////////////////////////////////////////////////////////////////
583/// Fill file info
584
586{
587 if (!wl || !sl) return;
588
589 // Extract information
590 TPerfEvent pe;
591 TPerfEvent* pep = &pe;
592 fTree->SetBranchAddress("PerfEvents", &pep);
593 Long64_t entries = fTree->GetEntries();
594 TNamed *wn = 0, *sn = 0;
595 for (Long64_t k=0; k<entries; k++) {
596 fTree->GetEntry(k);
597 // Analyse only packets
598 if (pe.fType != TVirtualPerfStats::kPacket) continue;
599 // Find out the worker instance
601 wn = (TNamed *) wl->FindObject(pe.fSlave.Data());
602 if (!wn) {
603 wn = new TNamed(pe.fSlave.Data(), wrk.Data());
604 wl->Add(wn);
605 }
606 // Find out the file server instance
607 TUrl uf(pe.fFileName);
608 TString srv(uf.GetUrl());
609 Int_t ifn = srv.Index(uf.GetFile());
610 if (ifn != kNPOS) srv.Remove(ifn);
611 sn = (TNamed *) sl->FindObject(srv.Data());
612 if (!sn) {
613 sn = new TNamed(srv.Data(), "remote");
614 sl->Add(sn);
615 }
616 }
617
618 // Done
619 return;
620}
621
622////////////////////////////////////////////////////////////////////////////////
623/// Return -1 if ord1 comes before ord2, 0 i they are equal,
624/// 1 if ord1 comes after ord2
625
626Int_t TProofPerfAnalysis::CompareOrd(const char *ord1, const char *ord2)
627{
628 TString o1(ord1), o2(ord2), p1, p2;
629 Int_t o1d = 0, o2d = 0;
630 if ((o1d = o1.CountChar('.')) > (o2d = o2.CountChar('.'))) {
631 return 1;
632 } else if (o1d < o2d) {
633 return -1;
634 } else {
635 o1.ReplaceAll(".", " ");
636 o2.ReplaceAll(".", " ");
637 Bool_t b1 = o1.Tokenize(p1, o1d, " ");
638 Bool_t b2 = o2.Tokenize(p2, o2d, " ");
639 while (b1 && b2) {
640 if (p1.Atoi() > p2.Atoi()) {
641 return 1;
642 } else if (p1.Atoi() < p2.Atoi()) {
643 return -1;
644 } else {
645 b1 = o1.Tokenize(p1, o1d, " ");
646 b2 = o2.Tokenize(p2, o2d, " ");
647 }
648 }
649 if (b1 && !b2) {
650 return 1;
651 } else if (b2 && !b1) {
652 return -1;
653 } else {
654 return 0;
655 }
656 }
657}
658
659////////////////////////////////////////////////////////////////////////////////
660/// Fill file info
661
663{
664 if (!hf || !hb || !hx) return;
665
666 TString fnout;
667 FILE *fout = 0;
668 if (wdet) {
669 fnout.Form("%s-FileDist-Details.txt", GetName());
670 if (!(fout = fopen(fnout.Data(), "w"))) {
671 Warning("FillFileDist", "asked to save details in '%s' but file could"
672 " not be open (errno: %d)", fnout.Data(), (int)errno);
673 } else {
674 Info("FillFileDist", "saving details to '%s'", fnout.Data());
675 }
676 }
677 // Extract information
678 TPerfEvent pe;
679 TPerfEvent* pep = &pe;
680 fTree->SetBranchAddress("PerfEvents",&pep);
681 Long64_t entries = fTree->GetEntries();
682 for (Long64_t k=0; k<entries; k++) {
683 fTree->GetEntry(k);
684 // Analyse only packets
685 if (pe.fType != TVirtualPerfStats::kPacket) continue;
686 // Find out the labels ...
687 TString wrk(pe.fSlave.Data());
688 TUrl uf(pe.fFileName);
689 TString srv(uf.GetUrl());
690 Int_t ifn = srv.Index(uf.GetFile());
691 if (ifn != kNPOS) srv.Remove(ifn);
692 // ... and the bins
693 Double_t xhf = hf->GetXaxis()->GetBinCenter(hf->GetXaxis()->FindBin(srv.Data()));
694 Double_t xhx = hx->GetXaxis()->GetBinCenter(hx->GetXaxis()->FindBin(srv.Data()));
695 Double_t yhx = hx->GetYaxis()->GetBinCenter(hx->GetYaxis()->FindBin(wrk.Data()));
696 // Save details, if asked
697 if (fout)
698 fprintf(fout, "%s,%s -> %f,%f (%f)\n",
699 srv.Data(), wrk.Data(), xhx, yhx, pe.fBytesRead / 1024.);
700 // Fill now
701 hf->Fill(xhf);
702 hb->Fill(xhf, pe.fBytesRead / 1024. / 1024.);
703 hx->Fill(xhx, yhx, pe.fBytesRead / 1024. / 1024.);
704 }
705 if (fout) fclose(fout);
706 // Done
707 return;
708}
709
710////////////////////////////////////////////////////////////////////////////////
711/// Fill file info when there is only one file server
712
714{
715 if (!hx) return;
716
717 TString fnout;
718 FILE *fout = 0;
719 if (wdet) {
720 fnout.Form("%s-FileDist-Details.txt", GetName());
721 if (!(fout = fopen(fnout.Data(), "w"))) {
722 Warning("FillFileDistOneSrv", "asked to save details in '%s' but file could"
723 " not be open (errno: %d)", fnout.Data(), (int)errno);
724 } else {
725 Info("FillFileDistOneSrv", "saving details to '%s'", fnout.Data());
726 }
727 }
728 // Extract information
729 TPerfEvent pe;
730 TPerfEvent* pep = &pe;
731 fTree->SetBranchAddress("PerfEvents",&pep);
732 Long64_t entries = fTree->GetEntries();
733 for (Long64_t k=0; k<entries; k++) {
734 fTree->GetEntry(k);
735 // Analyse only packets
736 if (pe.fType != TVirtualPerfStats::kPacket) continue;
737 // Find out the labels ...
738 TString wrk(pe.fSlave.Data());
739 TUrl uf(pe.fFileName);
740 TString srv(uf.GetUrl());
741 Int_t ifn = srv.Index(uf.GetFile());
742 if (ifn != kNPOS) srv.Remove(ifn);
743 // ... and the bins
744 Double_t xhx = hx->GetXaxis()->GetBinCenter(hx->GetXaxis()->FindBin(wrk.Data()));
745 // Save details, if asked
746 if (fout)
747 fprintf(fout, "%s,%s -> %f (%f)\n",
748 srv.Data(), wrk.Data(), xhx, pe.fBytesRead / 1024.);
749 // Fill now
750 hx->Fill(xhx, pe.fBytesRead / 1024. / 1024.);
751 }
752 if (fout) fclose(fout);
753 // Done
754 return;
755}
756
757////////////////////////////////////////////////////////////////////////////////
758/// Measure the worker activity
759
761{
762 if (!IsValid()) {
763 Error("WorkerActivity","not a valid instance - do nothing");
764 return;
765 }
766
767 // Fill basic worker info
768 if (!WrkInfoOK()) FillWrkInfo();
769 if (!WrkInfoOK()) {
770 Error("WorkerActivity", "workers information not available - do nothing");
771 return;
772 }
773
774 TObject *o = 0;
775 // Create the histograms with activity vs time
776 if ((o = gDirectory->FindObject("act10"))) delete o;
777 Float_t t0 = fMergeTime - 2.* (fMaxTime - fMergeTime);
778 Float_t t1 = 2.*fInitTime;
779 if (t1 > t0) t1 = t0;
780 TH1F *hact10 = new TH1F("act10", "Worker activity start (seconds)", 50, 0., t1);
781 hact10->GetXaxis()->SetTitle("Query Processing Time (s)");
782 if ((o = gDirectory->FindObject("act11"))) delete o;
783 TH1F *hact11 = new TH1F("act11", "Worker activity stop (seconds)", 50, t0, fMaxTime);
784 hact11->GetXaxis()->SetTitle("Query Processing Time (s)");
785 if ((o = gDirectory->FindObject("act2"))) delete o;
786 TH1F *hact2 = new TH1F("act2", "End of activity (seconds)", 50, t0, fMaxTime);
787 hact2->GetXaxis()->SetTitle("Query Processing Time (s)");
788
789 // Fine-tune stat printing
790 Int_t curoptstat = gStyle->GetOptStat();
791 gStyle->SetOptStat(1100);
792
793 // Create the sorted list
794 TIter nxw(&fWrksInfo);
795 TWrkInfo *wi = 0;
796 while ((wi = (TWrkInfo *)nxw())) {
797 Int_t j = 0;
798 for (j = 1; j < hact10->GetNbinsX()+1 ; j++) {
799 if (wi->fStart < hact10->GetBinLowEdge(j))
800 hact10->Fill(hact10->GetBinCenter(j));
801 }
802 for (j = 1; j < hact11->GetNbinsX()+1 ; j++) {
803 if (wi->fStop > hact11->GetBinLowEdge(j))
804 hact11->Fill(hact11->GetBinCenter(j));
805 }
806 hact2->Fill(wi->fStop);
807 }
808
809 // Display histos
810 TCanvas *c1 = new TCanvas("perf", GetCanvasTitle("Activity histos"), 800,10,700,780);
811 c1->Divide(1,2);
812 TPad *pad1 = (TPad *) c1->GetPad(1);
813 pad1->Divide(2,1);
814 TPad *pad10 = (TPad *) pad1->GetPad(1);
815 TPad *pad11 = (TPad *) pad1->GetPad(2);
816 pad10->cd();
817 DoDraw(hact10);
818 pad11->cd();
819 DoDraw(hact11);
820 TPad *pad2 = (TPad *) c1->GetPad(2);
821 pad2->cd();
822 DoDraw(hact2);
823 c1->cd();
824 c1->Update();
825
826 // Restore stat options
827 gStyle->SetOptStat(curoptstat);
828
829 // Done
830 return;
831}
832
833////////////////////////////////////////////////////////////////////////////////
834/// Print information for all or the slowest showlast workers.
835/// Use showlast < 0 to print all
836
838{
839 // Create the sorted list
840 Int_t k = fWrksInfo.GetSize();
841 TIter nxw(&fWrksInfo);
842 TWrkInfo *wi = 0;
843 while ((wi = (TWrkInfo *)nxw())) {
844 // Print info about slowest workers
845 k--;
846 if (showlast < 0 || k < showlast) wi->Print();
847 }
848}
849
850////////////////////////////////////////////////////////////////////////////////
851/// Print information for worker 'wn' (ordinal) or on the machine whose
852/// ordinal or fqdn matches 'wn'. Multiple specifications separated by ','
853/// or ' ' are supported, as well as wildcards '*', e.g. '0.2*,lxb10* lxf2323.doma.in"
854
856{
857 if (!wn || (wn && strlen(wn) <= 0)) {
858 Error("PrintWrkInfo", "worker name or host must be defined!");
859 return;
860 }
861
862 // Check exact name
863 TWrkInfo *wi = (TWrkInfo *) fWrksInfo.FindObject(wn);
864 if (wi) {
865 wi->Print();
866 } else {
867 // Check matching
868 TString ww(wn), w;
869 TIter nxw(&fWrksInfo);
870 while ((wi = (TWrkInfo *)nxw())) {
871 TString n(wi->GetName()), t(wi->GetTitle());
872 Ssiz_t from = 0;
873 while (ww.Tokenize(w, from, "[, ]")) {
874 TRegexp re(w, kTRUE);
875 if (n.Index(re) != kNPOS || t.Index(re) != kNPOS) wi->Print();
876 }
877 }
878 }
879}
880
881////////////////////////////////////////////////////////////////////////////////
882/// Print information for all or the slowest showlast workers.
883/// Use showlast < 0 to print all
884
885void TProofPerfAnalysis::PrintFileInfo(Int_t showlast, const char *opt, const char *out)
886{
888 if (out && strlen(out) > 0) gSystem->RedirectOutput(out, "w", &rh);
889
890 // Create the sorted list
892 TIter nxf(&fFilesInfo);
893 TFileInfo *fi = 0;
894 while ((fi = (TFileInfo *)nxf())) {
895 // Print info about files processed last
896 k--;
897 if (showlast < 0 || k < showlast) fi->Print(opt);
898 }
899
900 if (out && strlen(out) > 0) gSystem->RedirectOutput(0, 0, &rh);
901}
902
903////////////////////////////////////////////////////////////////////////////////
904/// Print information for file 'fn' (path including directory) or server 'fn'.
905/// Multiple specifications separated by ','
906/// or ' ' are supported, as well as wildcards '*', e.g. 'pippo.root, h4mu*,lxb10*"
907
908void TProofPerfAnalysis::PrintFileInfo(const char *fn, const char *opt, const char *out)
909{
910 if (!fn || (fn && strlen(fn) <= 0)) {
911 Error("PrintFileInfo", "file path must be defined!");
912 return;
913 }
914
916 if (out && strlen(out) > 0) gSystem->RedirectOutput(out, "w", &rh);
917
918 // Check exact name
919 TFileInfo *fi = (TFileInfo *) fFilesInfo.FindObject(fn);
920 if (fi) {
921 fi->Print(opt);
922 } else {
923 // Check matching
924 TString fw(fn), f;
925 TIter nxf(&fFilesInfo);
926 while ((fi = (TFileInfo *)nxf())) {
927 TString n(fi->GetName()), s(fi->GetTitle());
928 Ssiz_t from = 0;
929 while (fw.Tokenize(f, from, "[, ]")) {
930 TRegexp re(f, kTRUE);
931 if (n.Index(re) != kNPOS || s.Index(re) != kNPOS) fi->Print(opt);
932 }
933 }
934 }
935
936 if (out && strlen(out) > 0) gSystem->RedirectOutput(0, 0, &rh);
937}
938
939////////////////////////////////////////////////////////////////////////////////
940/// Fill basic worker info; if 'force' rescan the TTree even already done
941
943{
944 // Nothing to do if already called
945 if (fWrksInfo.GetSize() > 0 && !force) return;
946
947 // Cleanup existing information
950 fInitTime = -1.;
951 fMergeTime = -1.;
952 fMaxTime = -1.;
953 fEvtRateMax = -1.;
954 fMBRateMax = -1.;
955 fLatencyMax = -1.;
956
957 TList *wl = new TList;
958 // Extract worker information
959 TPerfEvent pe;
960 TPerfEvent* pep = &pe;
961 fTree->SetBranchAddress("PerfEvents",&pep);
962 Long64_t entries = fTree->GetEntries();
963
964 // First determine binning for global rates
965 Int_t nraw = entries * 2, jj = 0, kk = 0;
966 Double_t *xraw = new Double_t[nraw];
967 for (Long64_t k=0; k<entries; k++) {
968 fTree->GetEntry(k);
969 // Analyse only packets
971 Float_t stop = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
972 Float_t start = stop - pe.fProcTime;
973 // Bins
974 xraw[jj++] = start;
975 xraw[jj++] = stop;
976 }
977 }
978 Int_t nbins = jj;
979 Int_t *jidx = new Int_t[nbins];
980 memset(jidx, 0, nbins * sizeof(Int_t));
981 TMath::Sort(nbins, xraw, jidx, kFALSE);
982 Double_t *xbins = new Double_t[nbins];
983 jj = 0;
984 for (kk = 0; kk < nbins; kk++) {
985 Double_t xtmp = xraw[jidx[kk]];
986 if (jj == 0 || xtmp > xbins[jj - 1] + .5) {
987 xbins[jj] = xtmp;
988 jj++;
989 }
990 }
991 nbins = jj;
992 delete [] xraw;
993 delete [] jidx;
994
995 // Create the global histograms
996 Int_t nbin = nbins - 1;
997 TObject *o = 0;
998 if ((o = gDirectory->FindObject("gEvtRate"))) delete o;
999 fEvtRate = new TH1F("gEvtRate", "Total event processing rate (evt/s)", nbin, xbins);
1000 fEvtRate->SetMinimum(0.);
1003 fEvtRate->GetXaxis()->SetTitle("Query Processing Time (s)");
1004 if ((o = gDirectory->FindObject("gEvtRateAvg"))) delete o;
1005 fEvtRateRun = new TH1F("gEvtRateAvg", "Event processing rate running average (evt/s)", nbin, xbins);
1009 fEvtRateRun->GetXaxis()->SetTitle("Query Processing Time (s)");
1010 if ((o = gDirectory->FindObject("gMBRate"))) delete o;
1011 fMBRate = new TH1F("gMBRate", "Total processing rate (MB/s)", nbin, xbins);
1012 fMBRate->SetMinimum(0.);
1015 fMBRate->GetXaxis()->SetTitle("Query Processing Time (s)");
1016 if ((o = gDirectory->FindObject("gMBRateAvg"))) delete o;
1017 fMBRateRun = new TH1F("gMBRateAvg", "Processing rate running average (MB/s)", nbin, xbins);
1021 fMBRateRun->GetXaxis()->SetTitle("Query Processing Time (s)");
1022 // Not needed any longer
1023 delete [] xbins;
1024
1025 THashList gBins;
1026 TList *gwl = 0, *gbl = 0;
1027
1028 // Extract the worker info now
1029 TWrkInfo *wi = 0;
1030 for (Long64_t k=0; k<entries; k++) {
1031 fTree->GetEntry(k);
1032 // Analyse only packets
1034 // Find out the worker instance
1035 if (!(wi = (TWrkInfo *) wl->FindObject(pe.fSlave.Data()))) {
1036 wi = new TWrkInfo(pe.fSlave.Data(), pe.fSlaveName.Data());
1037 wl->Add(wi);
1038 wi->fRateT = new TGraph(100);
1039 wi->fRateRemoteT = new TGraph(100);
1040 wi->fMBRateT = new TGraph(100);
1041 wi->fMBRateRemoteT = new TGraph(100);
1042 wi->fLatencyT = new TGraph(100);
1043 }
1044 // Add Info now
1045 Float_t stop = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1046 Float_t start = stop - pe.fProcTime;
1047 if (wi->fPackets <= 0) {
1048 wi->fStart = start;
1049 } else {
1050 wi->fStop = stop;
1051 }
1052 TUrl uf(pe.fFileName), uw(pe.fSlaveName);
1053 fMaxTime = stop;
1054 wi->fEventsProcessed += pe.fEventsProcessed;
1055 wi->fBytesRead += pe.fBytesRead;
1056 wi->fLatency += pe.fLatency;
1057 wi->fProcTime += pe.fProcTime;
1058 wi->fCpuTime += pe.fCpuTime;
1059 // Fill graphs
1060 Double_t tt = stop;
1061 Double_t ert = pe.fEventsProcessed / pe.fProcTime ;
1062 Double_t brt = pe.fBytesRead / pe.fProcTime / 1024. / 1024. ;
1063 wi->fRateT->SetPoint(wi->fPackets, tt, ert);
1064 if (brt > 0.) wi->fMBRateT->SetPoint(wi->fPackets, tt, brt);
1065 wi->fLatencyT->SetPoint(wi->fPackets, tt, pe.fLatency);
1066 if (!pe.fFileName.IsNull() && strcmp(uf.GetHostFQDN(), uw.GetHostFQDN())) {
1067 wi->fRateRemoteT->SetPoint(wi->fRemotePackets, tt, ert);
1068 wi->fMBRateRemoteT->SetPoint(wi->fRemotePackets, tt, brt);
1069 wi->fRemotePackets++;
1070 }
1071 wi->fPackets++;
1072 if (ert > fEvtRateMax) fEvtRateMax = ert;
1073 if (brt > fMBRateMax) fMBRateMax = brt;
1075
1076 // Fill global rate histos
1077 for (kk = 1; kk <= nbins; kk++) {
1079 if (mi > stop) break;
1080 Double_t wd = fEvtRate->GetBinWidth(kk);
1081 Double_t mx = mi + wd;
1082 Double_t xx = fEvtRate->GetBinCenter(kk);
1083 // Overlap length
1084 Double_t olap = stop - mi;
1085 if (start > mi) olap = mx - start;
1086 if (olap >= 0) {
1087 TString sb = TString::Format("%d", kk);
1088 if (!(gbl = (TList *) gBins.FindObject(sb))) {
1089 gbl = new TList;
1090 gbl->SetName(sb);
1091 gBins.Add(gbl);
1092 }
1093 if (!(gwl = (TList *) gbl->FindObject(pe.fSlave))) {
1094 gwl = new TList;
1095 gwl->SetName(pe.fSlave);
1096 gbl->Add(gwl);
1097 }
1098 gwl->Add(new TWrkEntry(xx, ert, brt, pe.fProcTime));
1099 }
1100 }
1101
1102 // Notify
1103 if (fDebug > 1) {
1104 if (pe.fProcTime > 0.) {
1105 Printf(" +++ %s #:%d at:%fs lat:%fs proc:%fs evts:%lld bytes:%lld (rates:%f evt/s, %f MB/s)",
1106 wi->GetName(), wi->fPackets, fMaxTime - pe.fProcTime,
1108 ert, brt);
1109 } else {
1110 Printf(" +++ %s #:%d at:%fs lat:%fs proc:%fs rate:-- evt/s (-- bytes/s)",
1111 wi->GetName(), wi->fPackets, fMaxTime, pe.fLatency, pe.fProcTime);
1112 }
1113 }
1114 } else if (pe.fType == TVirtualPerfStats::kStart) {
1115 Float_t start = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1116 if (fDebug > 1) Printf(" +++ %s Start: %f s", pe.fEvtNode.Data(), start);
1117 } else if (pe.fType == TVirtualPerfStats::kStop) {
1118 Float_t stop = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1119 if (fDebug > 1) Printf(" +++ %s Stop: %f s", pe.fEvtNode.Data(), stop);
1120 } else {
1121 if (fDebug > 2) Printf(" +++ Event type: %d", pe.fType);
1122 }
1123 }
1124
1125 TIter nxb(&gBins);
1126 gbl = 0;
1127 while ((gbl = (TList *) nxb())) {
1128 gwl = 0;
1129 TIter nxw(gbl);
1130 while ((gwl = (TList *) nxw())) {
1131 Double_t er = 0, br = 0, pt = 0, xx = 0;
1132 TIter nxp(gwl);
1133 TWrkEntry *we = 0;
1134 while ((we = (TWrkEntry *) nxp())) {
1135 if (we->fProcTime > 0) {
1136 er += we->fEvtRate * we->fProcTime;
1137 br += we->fMBRate * we->fProcTime;
1138 pt += we->fProcTime;
1139 }
1140 xx = we->fXx;
1141 }
1142 if (pt > 0.) {
1143 er /= pt;
1144 br /= pt;
1145 fEvtRate->Fill(xx, er);
1146 if (br > 0.) fMBRate->Fill(xx, br);
1147 }
1148 }
1149 }
1150
1151 // Running averages
1152 Double_t er = 0, br = 0, pt = 0;
1153 for (kk = 1; kk < nbins; kk++) {
1154 Double_t wd = fEvtRate->GetBinWidth(kk);
1155 Double_t wx = fEvtRate->GetBinCenter(kk);
1156 Double_t wer = fEvtRate->GetBinContent(kk);
1157 Double_t wbr = fMBRate->GetBinContent(kk);
1158
1159 if (kk == 1) {
1160 er = wer;
1161 br = wbr;
1162 pt = wd;
1163 } else {
1164 er *= pt;
1165 br *= pt;
1166 pt += wd;
1167 er += wer * wd;
1168 br += wbr * wd;
1169 er /= pt;
1170 br /= pt;
1171 }
1172 if (er > fEvtRateAvgMax) fEvtRateAvgMax = er;
1173 if (br > fMBRateAvgMax) fMBRateAvgMax = br;
1174 fEvtRateAvg = er;
1175 fMBRateAvg = br;
1176 // Fill
1177 fEvtRateRun->Fill(wx, er);
1178 fMBRateRun->Fill(wx, br);
1179 }
1180
1181
1182 // Final analysis to find relevant times
1183 TIter nxw(wl);
1184 while ((wi = (TWrkInfo *) nxw())) {
1185 fWrksInfo.Add(wi);
1186 if (wi->fStart > fInitTime) fInitTime = wi->fStart;
1187 // Resize the graphs
1188 wi->fRateT->Set(wi->fPackets);
1189 wi->fRateRemoteT->Set(wi->fRemotePackets);
1190 wi->fLatencyT->Set(wi->fPackets);
1191 wi->fMBRateT->Set(wi->fPackets);
1192 wi->fMBRateRemoteT->Set(wi->fRemotePackets);
1193 }
1194 wl->SetOwner(kFALSE);
1195 delete wl;
1196
1197 // Final analysis to find relevant times
1199 Int_t rsw = (fWrksInfo.GetSize() > 1) ? 2 : 1, ksw = 0;
1200 TIter nxsw(&fWrksInfo);
1201 while ((wi = (TWrkInfo *) nxsw())) {
1202 if (wi->fStop > 0.) ksw++;
1203 if (ksw == rsw) break;
1204 }
1205 if (wi) fMergeTime = wi->fStop;
1206
1207 // (Re-)create the event and packet distribution histograms
1210 fEvents = new TH1F("hevents", "Events per worker", fWrksInfo.GetSize(), -.5, fWrksInfo.GetSize()-.5);
1212 fPackets = new TH1F("hpackets", "Packets per worker", fWrksInfo.GetSize(), -.5, fWrksInfo.GetSize()-.5);
1214 Int_t j = 0;
1215 TIter nxwi(&fWrksInfo);
1216 while ((wi = (TWrkInfo *)nxwi())) {
1217 fEvents->GetXaxis()->SetBinLabel(j+1, wi->GetName());
1218 fEvents->Fill(j, wi->fEventsProcessed);
1219 fPackets->GetXaxis()->SetBinLabel(j+1, wi->GetName());
1220 fPackets->Fill(j++, wi->fPackets);
1221 }
1222 fEvents->SetMinimum(0.);
1223 fPackets->SetMinimum(0.);
1224 fEvents->SetFillColor(38);
1226 fEvents->GetYaxis()->SetTitle("Events");
1227 fEvents->GetXaxis()->SetTitle("Worker");
1228 fPackets->GetYaxis()->SetTitle("Packets");
1229 fPackets->GetXaxis()->SetTitle("Worker");
1230
1231 // Print summary
1232 if (fgDebug) Summary();
1233}
1234
1235////////////////////////////////////////////////////////////////////////////////
1236/// Print summary of query. Use opt = 'S' for compact version.
1237/// Output to 'out' or to screen.
1238
1239void TProofPerfAnalysis::Summary(Option_t *opt, const char *out)
1240{
1241 TString o(out);
1243 if (!o.IsNull()) {
1244 const char *m = (o.BeginsWith("+")) ? "a" : "w";
1245 o.Remove(TString::kLeading, '+');
1246 gSystem->RedirectOutput(o, m, &rh);
1247 }
1248
1249 // Print summary
1250 if (!strcmp(opt, "S")) {
1251 // Short version
1252 Printf("%d %f %f %f %f %f %f %f",
1255 } else {
1256 // Long version
1257 Printf(" +++ %d workers were active during this query", fWrksInfo.GetSize());
1258 Printf(" +++ Total query time: %f secs (init: %f secs, merge: %f secs)",
1260 Printf(" +++ Avg processing rates: %.4f evts/s, %.4f MB/s", fEvtRateAvg, fMBRateAvg);
1261 Printf(" +++ Max processing rates: %.4f evts/s, %.4f MB/s", fEvtRateAvgMax, fMBRateAvgMax);
1262 }
1263
1264 if (!o.IsNull()) gSystem->RedirectOutput(0, 0, &rh);
1265}
1266
1267////////////////////////////////////////////////////////////////////////////////
1268/// Fill basic worker info; if 'force' rescan the TTree even already done
1269
1271{
1272 // Nothing to do if already called
1273 if (fFilesInfo.GetSize() > 0 && !force) return;
1274
1275 // Cleanup existing information
1277 fFilesInfo.Clear();
1278
1279 TList *fl = new TList;
1280 // Extract worker information
1281 TPerfEvent pe;
1282 TPerfEvent* pep = &pe;
1283 fTree->SetBranchAddress("PerfEvents",&pep);
1284 Long64_t entries = fTree->GetEntries();
1285 TFileInfo *fi = 0;
1286 for (Long64_t k=0; k<entries; k++) {
1287 fTree->GetEntry(k);
1288 // Analyse only packets
1290 TUrl uf(pe.fFileName);
1291 TString srv(uf.GetUrl());
1292 Int_t ifn = srv.Index(uf.GetFile());
1293 if (ifn != kNPOS) srv.Remove(ifn);
1294 // Find out the file instance
1295 fi = (TFileInfo *) fl->FindObject(uf.GetFile());
1296 if (!fi) {
1297 fi = new TFileInfo(uf.GetFile(), srv.Data());
1298 fl->Add(fi);
1299 fi->fSizeP = new TGraph(10);
1300 fi->fRateP = new TGraph(10);
1301 fi->fRatePRemote = new TGraph(10);
1302 fi->fMBRateP = new TGraph(10);
1303 fi->fMBRatePRemote = new TGraph(10);
1304 }
1305 // Add Info now
1306 Float_t stop = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1307 Float_t start = stop - pe.fProcTime;
1308 if (fi->fPackets <= 0) {
1309 fi->fStart = start;
1310 } else {
1311 fi->fStop = stop;
1312 }
1313 TUrl uw(pe.fSlaveName);
1314
1315 // Fill size graphs
1316 fi->fSizeP->SetPoint(fi->fPackets, (Double_t) fi->fPackets, (Double_t) pe.fEventsProcessed);
1317 fi->fSizeAvg += pe.fEventsProcessed;
1318 if (pe.fEventsProcessed > fi->fSizeMax || fi->fSizeMax < 0.) fi->fSizeMax = pe.fEventsProcessed;
1319 if (pe.fEventsProcessed < fi->fSizeMin || fi->fSizeMin < 0.) fi->fSizeMin = pe.fEventsProcessed;
1320
1321 // Fill rate graphs
1323 Double_t ert = pe.fEventsProcessed / pe.fProcTime ;
1324 Double_t brt = pe.fBytesRead / pe.fProcTime / 1024. / 1024. ;
1325 fi->fRateP->SetPoint(fi->fPackets, tt, ert);
1326 if (brt > 0.) fi->fMBRateP->SetPoint(fi->fPackets, tt, brt);
1327 if (!pe.fFileName.IsNull() && strcmp(uf.GetHostFQDN(), uw.GetHostFQDN())) {
1328 if (!(fi->fRWrkList.FindObject(pe.fSlave))) fi->fRWrkList.Add(new TNamed(pe.fSlave, pe.fSlaveName));
1329 fi->fRatePRemote->SetPoint(fi->fRPackets, tt, ert);
1330 fi->fMBRatePRemote->SetPoint(fi->fRPackets, tt, brt);
1331 fi->fRPackets++;
1332 }
1333 fi->fPackets++;
1334 if (brt > 0) {
1335 fi->fMBRateAvg += brt;
1336 if (brt > fi->fMBRateMax || fi->fMBRateMax < 0.) fi->fMBRateMax = brt;
1337 if (brt < fi->fMBRateMin || fi->fMBRateMin < 0.) fi->fMBRateMin = brt;
1338 }
1339
1340 // Packet info
1341 TPackInfo *pi = new TPackInfo(pe.fSlave, pe.fSlaveName, start, stop, pe.fEventsProcessed, brt);
1342 fi->fPackList.Add(pi);
1343 TWrkInfoFile *wif = 0;
1344 if (!(wif = (TWrkInfoFile *) fi->fWrkList.FindObject(pe.fSlave))) {
1345 wif = new TWrkInfoFile(pe.fSlave, uf.GetFile());
1346 fi->fWrkList.Add(wif);
1347 }
1348 wif->fPackets.Add(pi);
1349
1350 // Notify
1351 if (fDebug > 1) {
1352 if (pe.fProcTime > 0.) {
1353 Printf(" +++ %s #:%d at:%fs lat:%fs proc:%fs evts:%lld bytes:%lld (rates:%f evt/s, %f MB/s)",
1354 fi->GetName(), fi->fPackets, fMaxTime - pe.fProcTime,
1356 ert, brt);
1357 } else {
1358 Printf(" +++ %s #:%d at:%fs lat:%fs proc:%fs rate:-- evt/s (-- bytes/s)",
1359 fi->GetName(), fi->fPackets, fMaxTime, pe.fLatency, pe.fProcTime);
1360 }
1361 }
1362 } else if (pe.fType == TVirtualPerfStats::kStart) {
1363 Float_t start = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1364 if (fDebug > 1) Printf(" +++ %s Start: %f s", pe.fEvtNode.Data(), start);
1365 } else if (pe.fType == TVirtualPerfStats::kStop) {
1366 Float_t stop = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1367 if (fDebug > 1) Printf(" +++ %s Stop: %f s", pe.fEvtNode.Data(), stop);
1368 } else {
1369 if (fDebug > 2) Printf(" +++ Event type: %d", pe.fType);
1370 }
1371 }
1372 // Final analysis to find relevant times
1373 TIter nxf(fl);
1374 while ((fi = (TFileInfo *) nxf())) {
1375 fFilesInfo.Add(fi);
1376 // Resize the graphs
1377 fi->fRateP->Set(fi->fPackets);
1378 fi->fRatePRemote->Set(fi->fRPackets);
1379 fi->fMBRateP->Set(fi->fPackets);
1380 fi->fMBRatePRemote->Set(fi->fRPackets);
1381 }
1382 fl->SetOwner(kFALSE);
1383 delete fl;
1384
1385 // Print summary
1386 if (fgDebug)
1387 Printf(" +++ %d files were processed during this query", fFilesInfo.GetSize());
1388}
1389
1390////////////////////////////////////////////////////////////////////////////////
1391/// Static setter for the verbosity level
1392
1394{
1395 fDebug = d;
1396}
1397
1398////////////////////////////////////////////////////////////////////////////////
1399/// Draw object 'o' with options 'opt'
1400/// Save it with 'name' if in saving mode (see SetSaveResult)
1401
1403{
1404 // Draw
1405 o->Draw(opt);
1406
1407 // Save the result
1408 if (fSaveResult) {
1409 // Preparation is done in SetSaveResult, here we just update
1410 TDirectory *curdir = gDirectory;
1411 TFile *f = TFile::Open(fFileResult, "UPDATE");
1412 if (f && !f->IsZombie()) {
1413 const char *n = (name && strlen(name) > 0) ? name : 0;
1414 o->Write(n);
1415 f->Close();
1416 }
1417 if (f) delete f;
1418 gDirectory = curdir;
1419 }
1420}
1421
1422////////////////////////////////////////////////////////////////////////////////
1423/// Set save result mode and validate 'file' according to 'mode'.
1424/// Return 0 on success, -1 if any problem with the file is encountered
1425/// (save result mode is not enabled in such a case).
1426/// If 'file' is null saving is disabled.
1427
1429{
1430 // A null 'file' indicates the will to disable
1431 if (!file) {
1432 fFileResult = "";
1434 // Notify
1435 Printf("Drawn objects saving disabled");
1436 return 0;
1437 }
1438
1439 // Check if there is a change
1440 if (!fFileResult.IsNull() && fFileResult == file) {
1441 // No change
1443 return 0;
1444 }
1445 // New or changed file: validate
1446 fFileResult = "";
1448 TDirectory *curdir = gDirectory;
1449 TFile *f = TFile::Open(file, mode);
1450 if (!f || f->IsZombie()) {
1451 if (f) delete f;
1452 fFileResult = "";
1453 Error("SetSaveResult", "could not open file '%s' in mode '%s'", file, mode);
1454 gDirectory = curdir;
1455 return -1;
1456 }
1457 f->Close();
1458 delete f;
1459 gDirectory = curdir;
1460 // Ok
1461 fFileResult = file;
1463 // Notify
1464 Printf("Drawn objects will be saved in file '%s'", file);
1465 return 0;
1466}
1467
1468////////////////////////////////////////////////////////////////////////////////
1469/// Static setter for the verbosity level
1470
1472{
1473 fgDebug = on;
1474}
1475////////////////////////////////////////////////////////////////////////////////
1476/// Display event and packet distribution
1477
1479{
1480 if (!fEvents || !fPackets) {
1481 Error("EventDist", "distributions not initialized - do nothing");
1482 }
1483
1484 // Display histos
1485 TCanvas *c1 = new TCanvas("evtdist", GetCanvasTitle("Event distributions"),800,10,700,780);
1486 c1->Divide(1,2);
1487 TPad *pad1 = (TPad *) c1->GetPad(1);
1488 pad1->cd();
1490 DoDraw(fEvents);
1491 TPad *pad2 = (TPad *) c1->GetPad(2);
1492 pad2->cd();
1495 c1->cd();
1496 c1->Update();
1497
1498}
1499
1500////////////////////////////////////////////////////////////////////////////////
1501/// Show event processing or MB processing rate plot vs time
1502
1503void TProofPerfAnalysis::RatePlot(const char *wrks)
1504{
1505 Bool_t global = (wrks && !strcmp(wrks, "global")) ? kTRUE : kFALSE;
1506
1507 TH1F *hrt1 = 0, *hrt2 = 0;
1508 if (global) {
1509 hrt1 = fEvtRate;
1510 hrt2 = fMBRate;
1511 } else {
1512 // Create the histograms
1513 TObject *o = 0;
1514 if ((o = gDirectory->FindObject("rt1"))) delete o;
1515 hrt1 = new TH1F("rt1", "Evt processing rate (evt/s)", 100, 0., fMaxTime);
1516 hrt1->SetMinimum(0.);
1517 hrt1->SetMaximum(1.05*fEvtRateMax);
1518 hrt1->SetStats(kFALSE);
1519 hrt1->GetXaxis()->SetTitle("Query Processing Time (s)");
1520 if ((o = gDirectory->FindObject("rt2"))) delete o;
1521 hrt2 = new TH1F("rt2", "MB processing rate (MB/s)", 100, 0., fMaxTime);
1522 hrt2->SetMinimum(0.);
1523 hrt2->SetMaximum(1.05*fMBRateMax);
1524 hrt2->SetStats(kFALSE);
1525 hrt2->GetXaxis()->SetTitle("Query Processing Time (s)");
1526 }
1527
1528 // Display histo frames
1529 TCanvas *c1 = new TCanvas("rates", GetCanvasTitle("Processing rates"), 800,10,700,780);
1530 c1->Divide(1,2);
1531 TPad *pad1 = (TPad *) c1->GetPad(1);
1532 pad1->cd();
1533 hrt1->Draw();
1534 if (global) DoDraw(fEvtRateRun, "SAME", "EvtRateRun");
1535 TPad *pad2 = (TPad *) c1->GetPad(2);
1536 pad2->cd();
1537 hrt2->Draw();
1538 if (global) DoDraw(fMBRateRun, "SAME", "MBRateRun");
1539 c1->cd();
1540 c1->Update();
1541
1542 // Done if global
1543 if (global) return;
1544
1545 // Which workers?
1546 THashList *wl = 0;
1547 TString ww(wrks);
1548 if (!ww.IsNull() && ww != "*" && ww != "all") {
1549 TString w;
1550 Ssiz_t from = 0;
1551 while ((ww.Tokenize(w, from, ","))) {
1552 if (!wl) wl = new THashList();
1553 wl->Add(new TObjString(w.Data()));
1554 }
1555 }
1556
1557 // Now plot the graphs per worker
1558 Int_t ci = 40, cir = 30, ic = 0;
1559 TIter nxw(&fWrksInfo);
1560 TWrkInfo *wi = 0;
1561 while ((wi = (TWrkInfo *) nxw())) {
1562 if (wl && !wl->FindObject(wi->GetName())) continue;
1563 if (wi->fRateT && wi->fRateT->GetN() > 0) {
1564 wi->fRateT->SetNameTitle(wi->GetName(), wi->GetTitle());
1565 pad1->cd();
1566 wi->fRateT->SetLineColor(ci);
1567 DoDraw(wi->fRateT, "L", TString::Format("RateT-%s", wi->fRateT->GetName()));
1568 }
1569 if (wi->fRateRemoteT && wi->fRateRemoteT->GetN() > 0) {
1570 wi->fRateRemoteT->SetNameTitle(wi->GetName(), wi->GetTitle());
1571 pad1->cd();
1572 wi->fRateRemoteT->SetLineColor(cir);
1573 DoDraw(wi->fRateRemoteT, "L", TString::Format("RateRemoteT-%s", wi->fRateRemoteT->GetName()));
1574 }
1575 if (wi->fMBRateT && wi->fMBRateT->GetN() > 0) {
1576 wi->fMBRateT->SetNameTitle(wi->GetName(), wi->GetTitle());
1577 pad2->cd();
1578 wi->fMBRateT->SetLineColor(ci);
1579 DoDraw(wi->fMBRateT, "L", TString::Format("MBRateT-%s", wi->fMBRateT->GetName()));
1580 }
1581 if (wi->fMBRateRemoteT && wi->fMBRateRemoteT->GetN() > 0) {
1582 wi->fMBRateRemoteT->SetNameTitle(wi->GetName(), wi->GetTitle());
1583 pad2->cd();
1584 wi->fMBRateRemoteT->SetLineColor(cir);
1585 DoDraw(wi->fMBRateRemoteT, "L", TString::Format("MBRateRemoteT-%s", wi->fMBRateRemoteT->GetName()));
1586 }
1587 ic++;
1588 ci = ic%10 + 40;
1589 cir = ic%10 + 30;
1590 c1->cd();
1591 c1->Update();
1592 }
1593
1594 // Cleanup
1595 if (wl) {
1596 wl->SetOwner(kTRUE);
1597 delete wl;
1598 }
1599}
1600
1601////////////////////////////////////////////////////////////////////////////////
1602/// Show event processing or MB processing rate plot vs time
1603/// Create the histograms
1604
1606{
1607 TObject *o = 0;
1608 if ((o = gDirectory->FindObject("lt1"))) delete o;
1609 TH1F *hlt1 = new TH1F("lt1", "Packet retrieval latency", 100, 0., fMaxTime);
1610 hlt1->SetMinimum(0.);
1611 hlt1->SetMaximum(1.05*fLatencyMax);
1612 hlt1->SetStats(kFALSE);
1613 hlt1->GetXaxis()->SetTitle("Query Processing Time (s)");
1614 hlt1->GetYaxis()->SetTitle("Latency (s)");
1615
1616 // Display histo frames
1617 TCanvas *c1 = new TCanvas("latency", GetCanvasTitle("Packet Retrieval Latency"), 800,10,700,780);
1618 hlt1->Draw();
1619 c1->cd();
1620 c1->Update();
1621
1622 // Which workers?
1623 THashList *wl = 0;
1624 TString ww(wrks);
1625 if (!ww.IsNull() && ww != "*" && ww != "all") {
1626 TString w;
1627 Ssiz_t from = 0;
1628 while ((ww.Tokenize(w, from, ","))) {
1629 if (!wl) wl = new THashList();
1630 wl->Add(new TObjString(w.Data()));
1631 }
1632 }
1633
1634 // Now plot the graphs per worker
1635 Int_t ci = 40, ic = 0;
1636 TIter nxw(&fWrksInfo);
1637 TWrkInfo *wi = 0;
1638 while ((wi = (TWrkInfo *) nxw())) {
1639 if (wl && !wl->FindObject(wi->GetName())) continue;
1640 if (wi->fLatencyT) {
1641 wi->fLatencyT->SetNameTitle(wi->GetName(), wi->GetTitle());
1642 wi->fLatencyT->SetLineColor(ci);
1643 DoDraw(wi->fLatencyT, "L", TString::Format("LatencyT-%s", wi->fLatencyT->GetName()));
1644 }
1645 ic++;
1646 ci = ic%10 + 40;
1647 c1->cd();
1648 c1->Update();
1649 }
1650
1651 // Cleanup
1652 if (wl) {
1653 wl->SetOwner(kTRUE);
1654 delete wl;
1655 }
1656}
1657
1658////////////////////////////////////////////////////////////////////////////////
1659/// Show event processing or MB processing rate plot vs time
1660
1661void TProofPerfAnalysis::FileProcPlot(const char *fn, const char *out)
1662{
1663 if (!fn || strlen(fn) <= 0) {
1664 Error("FileRatePlot", "file name is mandatory!");
1665 return;
1666 }
1667 // Get the file info object
1668 TFileInfo *fi = (TFileInfo *) fFilesInfo.FindObject(fn);
1669 if (!fi) {
1670 Error("FileRatePlot", "TFileInfo object for '%s' not found!", fn);
1671 return;
1672 }
1673
1674 // Output text file, if required
1675 FILE *fo = stdout;
1676 if (out && strlen(out) > 0) {
1677 if (!(fo = fopen(out, "w"))) {
1678 Warning("FileRatePlot", "problems creating '%s': logging to stdout", out);
1679 fo = stdout;
1680 } else {
1681 Printf(" Details logged to %s", out);
1682 }
1683 }
1684
1685 // Get bins
1686 Int_t nbins = fi->fPackList.GetSize() * 2;
1687 Double_t *xraw = new Double_t[nbins];
1688 Int_t jj = 0;
1689 TPackInfo *pi = 0;
1690 TIter nxp(&(fi->fPackList));
1691 while ((pi = (TPackInfo *) nxp())) {
1692 // Bins
1693 xraw[jj++] = pi->fStart;
1694 xraw[jj++] = pi->fStop;
1695 }
1696 Int_t *jidx = new Int_t[nbins];
1697 memset(jidx, 0, nbins * sizeof(Int_t));
1698 TMath::Sort(nbins, xraw, jidx, kFALSE);
1699 Double_t *xbins = new Double_t[nbins];
1700 Int_t kk =0;
1701 for (kk = 0; kk < nbins; kk++) {
1702 xbins[kk] = xraw[jidx[kk]];
1703 }
1704 delete [] xraw;
1705 delete [] jidx;
1706
1707 // Create the histograms
1708 Int_t nbin = nbins - 1;
1709 TObject *o = 0;
1710 if ((o = gDirectory->FindObject("rt1"))) delete o;
1711 TH1F *hrt1 = new TH1F("rt1", "Total processing rate (MB/s)", nbins - 1, xbins);
1712 hrt1->SetMinimum(0.);
1713 hrt1->SetStats(kFALSE);
1714 hrt1->GetXaxis()->SetTitle("Query Processing Time (s)");
1715 if ((o = gDirectory->FindObject("rt2"))) delete o;
1716 TH1F *hrt2 = new TH1F("rt2", "Number of processing workers", nbins - 1, xbins);
1717 hrt2->SetMinimum(0.);
1718 hrt2->SetMaximum(1.2*fWrksInfo.GetSize());
1719 hrt2->SetStats(kFALSE);
1720 hrt2->GetXaxis()->SetTitle("Query Processing Time (s)");
1721 if ((o = gDirectory->FindObject("rt3"))) delete o;
1722 TH1F *hrt3 = new TH1F("rt3", "Total processing events", nbins - 1, xbins);
1723 hrt3->SetMinimum(0.);
1724 hrt3->SetStats(kFALSE);
1725 hrt3->GetXaxis()->SetTitle("Query Processing Time (s)");
1726 if ((o = gDirectory->FindObject("rt4"))) delete o;
1727 TH1F *hrt4 = new TH1F("rt4", "Weighted processing rate (MB/s)", nbins - 1, xbins);
1728 hrt4->SetMinimum(0.);
1729 hrt4->SetStats(kFALSE);
1730 hrt4->GetXaxis()->SetTitle("Query Processing Time (s)");
1731 // Not needed any longer
1732 delete [] xbins;
1733
1734 // Fill histos now
1735 Int_t ii = 0;
1736 for (ii = 1; ii <= nbin; ii++) {
1737 Double_t mi = hrt1->GetBinLowEdge(ii);
1738 Double_t wd = hrt1->GetBinWidth(ii);
1739 Double_t mx = mi + wd;
1740 Double_t xx = hrt1->GetBinCenter(ii);
1741 fprintf(fo, " Bin: %d/%d [%f, %f]\n", ii, nbin, mi, mx);
1742 pi = 0;
1743 kk = 0;
1744 nxp.Reset();
1745 while ((pi = (TPackInfo *) nxp())) {
1746 // Overlap length
1747 Double_t olap = pi->fStop - mi;
1748 if (pi->fStart > mi) olap = mx - pi->fStart;
1749 if (olap >= 0) {
1750 hrt1->Fill(xx, pi->fMBRate);
1751 hrt2->Fill(xx, 1.);
1752 hrt3->Fill(xx, pi->fSize);
1753 hrt4->Fill(xx, pi->fMBRate * pi->fSize);
1754 fprintf(fo, " %d: %s \t%lld \tevts \t%f \tMB/s\n", kk++, pi->GetName(), pi->fSize, pi->fMBRate);
1755 }
1756 }
1757 }
1758 if (fo != stdout) fclose(fo);
1759
1760 // Display histo frames
1761 TCanvas *c1 = new TCanvas("rates", GetCanvasTitle("File processing info"), 800,10,700,780);
1762 c1->Divide(1,3);
1763 TPad *pad1 = (TPad *) c1->GetPad(1);
1764 pad1->cd();
1765 DoDraw(hrt1);
1766 TPad *pad2 = (TPad *) c1->GetPad(2);
1767 pad2->cd();
1768 DoDraw(hrt2);
1769 TPad *pad4 = (TPad *) c1->GetPad(3);
1770 pad4->cd();
1771 hrt4->Divide(hrt3);
1772 DoDraw(hrt4);
1773 c1->cd();
1774 c1->Update();
1775}
1776
1777////////////////////////////////////////////////////////////////////////////////
1778/// Show MB processing rate plot per file vs time
1779
1781{
1782 // Create the histograms
1783 TObject *o = 0;
1784 if ((o = gDirectory->FindObject("rt1"))) delete o;
1785 TH1F *hrt1 = new TH1F("rt1", "Event processing rate per packet (evt/s)", 100, 0., fMaxTime);
1786 hrt1->SetMinimum(0.);
1787 hrt1->SetMaximum(1.05*fEvtRateMax);
1788 hrt1->SetStats(kFALSE);
1789 hrt1->GetXaxis()->SetTitle("Query Processing Time (s)");
1790 if ((o = gDirectory->FindObject("rt2"))) delete o;
1791 TH1F *hrt2 = new TH1F("rt2", "I/O processing rate per packet (MB/s)", 100, 0., fMaxTime);
1792 hrt2->SetMinimum(0.);
1793 hrt2->SetMaximum(1.05*fMBRateMax);
1794 hrt2->SetStats(kFALSE);
1795 hrt2->GetXaxis()->SetTitle("Query Processing Time (s)");
1796
1797 // Display histo frames
1798 TCanvas *c1 = new TCanvas("rates", GetCanvasTitle("Processing rates"), 800,10,700,780);
1799 c1->Divide(1,2);
1800 TPad *pad1 = (TPad *) c1->GetPad(1);
1801 pad1->cd();
1802 hrt1->Draw();
1803 TPad *pad2 = (TPad *) c1->GetPad(2);
1804 pad2->cd();
1805 hrt2->Draw();
1806 c1->cd();
1807 c1->Update();
1808
1809 // Which workers?
1810 THashList *fl = 0;
1811 TString fw(fns);
1812 if (!fw.IsNull() && fw != "*" && fw != "all") {
1813 TString w;
1814 Ssiz_t from = 0;
1815 while ((fw.Tokenize(w, from, ","))) {
1816 if (!fl) fl = new THashList();
1817 fl->Add(new TObjString(w.Data()));
1818 }
1819 }
1820
1821 // Now plot the graphs per worker
1822 Int_t ci = 40, cir = 30, ic = 0;
1823 TIter nxf(&fFilesInfo);
1824 TFileInfo *fi = 0;
1825 while ((fi = (TFileInfo *) nxf())) {
1826 if (fl && !fl->FindObject(fi->GetName())) continue;
1827 if (fi->fRateP && fi->fRateP->GetN() > 0) {
1828 fi->fRateP->SetNameTitle(fi->GetName(), fi->GetTitle());
1829 pad1->cd();
1830 fi->fRateP->SetLineColor(ci);
1831 DoDraw(fi->fRateP, "L", TString::Format("RateP-%d", ic));
1832 }
1833 if (fi->fRatePRemote && fi->fRatePRemote->GetN() > 0) {
1834 fi->fRatePRemote->SetNameTitle(fi->GetName(), fi->GetTitle());
1835 pad1->cd();
1836 fi->fRatePRemote->SetLineColor(cir);
1837 DoDraw(fi->fRatePRemote, "L", TString::Format("RatePRemote-%d", ic));
1838 }
1839 if (fi->fMBRateP && fi->fMBRateP->GetN() > 0) {
1840 fi->fMBRateP->SetNameTitle(fi->GetName(), fi->GetTitle());
1841 pad2->cd();
1842 fi->fMBRateP->SetLineColor(ci);
1843 DoDraw(fi->fMBRateP, "L", TString::Format("MBRateP-%d", ic));
1844 }
1845 if (fi->fMBRatePRemote && fi->fMBRatePRemote->GetN() > 0) {
1846 fi->fMBRatePRemote->SetNameTitle(fi->GetName(), fi->GetTitle());
1847 pad2->cd();
1848 fi->fMBRatePRemote->SetLineColor(cir);
1849 DoDraw(fi->fMBRatePRemote, "L", TString::Format("MBRatePRemote-%d", ic));
1850 }
1851 ic++;
1852 ci = ic%10 + 40;
1853 cir = ic%10 + 30;
1854 c1->cd();
1855 c1->Update();
1856 }
1857
1858 // Cleanup
1859 if (fl) {
1860 fl->SetOwner(kTRUE);
1861 delete fl;
1862 }
1863}
#define SafeDelete(p)
Definition: RConfig.hxx:550
#define d(i)
Definition: RSha256.hxx:102
#define f(i)
Definition: RSha256.hxx:104
#define e(i)
Definition: RSha256.hxx:103
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
int Ssiz_t
Definition: RtypesCore.h:63
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
long long Long64_t
Definition: RtypesCore.h:69
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
@ kCyan
Definition: Rtypes.h:64
@ kBlue
Definition: Rtypes.h:64
#define gDirectory
Definition: TDirectory.h:223
char name[80]
Definition: TGX11.cxx:109
void Printf(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:407
R__EXTERN TSystem * gSystem
Definition: TSystem.h:560
Int_t GetSize() const
Definition: TArray.h:47
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition: TAttAxis.cxx:294
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
virtual void SetBinLabel(Int_t bin, const char *label)
Set label for bin.
Definition: TAxis.cxx:809
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:464
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:279
The Canvas class.
Definition: TCanvas.h:31
virtual void ls(Option_t *option="") const
List (ls) all objects in this collection.
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
void SetName(const char *name)
Definition: TCollection.h:204
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
TObject * Get(const char *namecycle) override
Return pointer to object identified by namecycle.
Describe directory structure in memory.
Definition: TDirectory.h:34
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
Definition: TDirectory.cxx:805
virtual TList * GetListOfKeys() const
Definition: TDirectory.h:160
Class describing a generic file including meta information.
Definition: TFileInfo.h:38
void Print(Option_t *options="") const
Print information about this object.
Definition: TFileInfo.cxx:477
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:48
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3923
void Close(Option_t *option="") override
Close a file.
Definition: TFile.cxx:856
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8381
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8585
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:316
virtual Int_t GetNbinsX() const
Definition: TH1.h:292
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:394
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3275
TAxis * GetYaxis()
Definition: TH1.h:317
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:395
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8596
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2998
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4899
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8607
virtual Bool_t Divide(TF1 *f1, Double_t c1=1)
Performs the operation: this = this/(c1*f1) if errors are defined (see TH1::Sumw2),...
Definition: TH1.cxx:2753
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition: TH1.cxx:8434
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:251
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH2.cxx:292
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:262
void Reset()
Definition: TCollection.h:252
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:24
virtual const char * GetClassName() const
Definition: TKey.h:72
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:819
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:575
virtual void AddBefore(const TObject *before, TObject *obj)
Insert object before object before in the list.
Definition: TList.cxx:193
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:399
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual Int_t Compare(const TObject *obj) const
Compare two TNamed objects.
Definition: TNamed.cxx:85
virtual void Print(Option_t *option="") const
Print TNamed name and title.
Definition: TNamed.cxx:128
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
TString fTitle
Definition: TNamed.h:33
TNamed()
Definition: TNamed.h:36
virtual void Clear(Option_t *option="")
Set name and title to empty strings ("").
Definition: TNamed.cxx:64
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual void SetNameTitle(const char *name, const char *title)
Set all the TNamed parameters (name and title).
Definition: TNamed.cxx:154
Collectable string class.
Definition: TObjString.h:28
Mother of all ROOT objects.
Definition: TObject.h:37
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:785
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition: TObject.cxx:195
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:550
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition: TObject.h:68
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
The most important graphics class in the ROOT system.
Definition: TPad.h:29
virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)
Automatic pad generation by division.
Definition: TPad.cxx:1163
TVirtualPad * cd(Int_t subpadnumber=0)
Set Current pad.
Definition: TPad.cxx:591
virtual TVirtualPad * GetPad(Int_t subpadnumber) const
Get a pointer to subpadnumber of this pad.
Definition: TPad.cxx:2882
TString fEvtNode
Definition: TPerfStats.h:42
TString fSlaveName
Definition: TPerfStats.h:45
Double_t fCpuTime
Definition: TPerfStats.h:55
Double_t fLatency
Definition: TPerfStats.h:53
TString fSlave
Definition: TPerfStats.h:49
TString fFileName
Definition: TPerfStats.h:47
TVirtualPerfStats::EEventType fType
Definition: TPerfStats.h:44
Double_t fProcTime
Definition: TPerfStats.h:54
Long64_t fBytesRead
Definition: TPerfStats.h:51
TTimeStamp fTimeStamp
Definition: TPerfStats.h:43
Long64_t fEventsProcessed
Definition: TPerfStats.h:50
void FileRatePlot(const char *fns=0)
Show MB processing rate plot per file vs time.
void FileProcPlot(const char *fn, const char *out=0)
Show event processing or MB processing rate plot vs time.
void FillFileInfo(Bool_t force=kFALSE)
Fill basic worker info; if 'force' rescan the TTree even already done.
void SetDebug(Int_t d=0)
Static setter for the verbosity level.
TProofPerfAnalysis(const char *perffile, const char *title="", const char *treename="PROOF_PerfStats")
Constructor: open the file and attach to the tree.
void PrintWrkInfo(Int_t showlast=10)
Print information for all or the slowest showlast workers.
void LatencyPlot(const char *wrks=0)
Show event processing or MB processing rate plot vs time Create the histograms.
void WorkerActivity()
Measure the worker activity.
void FileDist(Bool_t writedet=kFALSE)
Analyse the file distribution.
Int_t SetSaveResult(const char *file="results.root", Option_t *mode="RECREATE")
Set save result mode and validate 'file' according to 'mode'.
void GetWrkFileList(TList *wl, TList *sl)
Fill file info.
Bool_t WrkInfoOK() const
void EventDist()
Display event and packet distribution.
TString GetCanvasTitle(const char *t)
If defined, add '- <this title>' to the canvas title 't'.
static void SetgDebug(Bool_t on=kTRUE)
Static setter for the verbosity level.
Bool_t IsValid() const
Int_t CompareOrd(const char *ord1, const char *ord2)
Return -1 if ord1 comes before ord2, 0 i they are equal, 1 if ord1 comes after ord2.
void LoadTree(TDirectory *dir)
Load tree fTreeName from directory 'dir'.
void DoDraw(TObject *o, Option_t *opt="", const char *name=0)
Draw object 'o' with options 'opt' Save it with 'name' if in saving mode (see SetSaveResult)
void PrintFileInfo(Int_t showlast=10, const char *opt="", const char *out=0)
Print information for all or the slowest showlast workers.
void FillFileDistOneSrv(TH1F *hx, Bool_t wdet=kFALSE)
Fill file info when there is only one file server.
void FillWrkInfo(Bool_t force=kFALSE)
Fill basic worker info; if 'force' rescan the TTree even already done.
virtual ~TProofPerfAnalysis()
Destructor: detach the tree and close the file.
void Summary(Option_t *opt="", const char *out="")
Print summary of query.
void RatePlot(const char *wrks=0)
Show event processing or MB processing rate plot vs time.
void FillFileDist(TH1F *hf, TH1F *hb, TH2F *hx, Bool_t wdet=kFALSE)
Fill file info.
Regular expression class.
Definition: TRegexp.h:31
void Add(TObject *obj)
Add object in sorted list.
Definition: TSortedList.cxx:27
Basic string class.
Definition: TString.h:131
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1921
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:677
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
@ kLeading
Definition: TString.h:262
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2197
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
Bool_t IsNull() const
Definition: TString.h:402
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
Int_t GetOptStat() const
Definition: TStyle.h:233
void SetOptStat(Int_t stat=1)
The type of information printed in the histogram statistics box can be selected via the parameter mod...
Definition: TStyle.cxx:1450
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1014
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:942
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=0)
Redirect standard output (stdout, stderr) to the specified file.
Definition: TSystem.cxx:1703
time_t GetSec() const
Definition: TTimeStamp.h:135
Int_t GetNanoSec() const
Definition: TTimeStamp.h:136
A TTree represents a columnar dataset.
Definition: TTree.h:72
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=0)
Change branch address, dealing with clone trees properly.
Definition: TTree.cxx:8127
virtual Long64_t GetEntries() const
Definition: TTree.h:450
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all branches of entry and return total number of bytes read.
Definition: TTree.cxx:5497
This class represents a WWW compatible URL.
Definition: TUrl.h:35
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:385
const char * GetFile() const
Definition: TUrl.h:71
const char * GetHost() const
Definition: TUrl.h:69
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:467
virtual void Draw(Option_t *option="")=0
Default Draw method for all objects.
TPaveText * pt
return c1
Definition: legend1.C:41
const Int_t n
Definition: legend1.C:16
return c2
Definition: legend2.C:14
static constexpr double s
static constexpr double pi
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Definition: TMathBase.h:362
Definition: file.py:1
Definition: tree.py:1
auto * m
Definition: textangle.C:8
auto * tt
Definition: textangle.C:16
auto * t1
Definition: textangle.C:20