Logo ROOT   6.14/05
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 
16 Set 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 
43 class TProofPerfAnalysis::TWrkInfo : public TNamed {
44 public:
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 
99 class TProofPerfAnalysis::TPackInfo : public TNamed {
100 public:
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 
117 class TProofPerfAnalysis::TWrkInfoFile : public TNamed {
118 public:
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 
134 class TProofPerfAnalysis::TWrkEntry : public TObject {
135 public:
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 
146 class TProofPerfAnalysis::TFileInfo : public TNamed {
147 public:
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),
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())) {
235  SafeDelete(fFile);
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();
258  SafeDelete(fFile);
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();
269  SafeDelete(fFile);
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;
309  fTreeName = fTree->GetName();
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 {
335  SafeDelete(fPackets);
336  if (fFile) fFile->Close();
337  SafeDelete(fFile);
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
600  TString wrk(TUrl(pe.fSlaveName.Data()).GetHostFQDN());
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 
626 Int_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 
885 void TProofPerfAnalysis::PrintFileInfo(Int_t showlast, const char *opt, const char *out)
886 {
887  RedirectHandle_t rh;
888  if (out && strlen(out) > 0) gSystem->RedirectOutput(out, "w", &rh);
889 
890  // Create the sorted list
891  Int_t k = fFilesInfo.GetSize();
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 
908 void 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 
915  RedirectHandle_t rh;
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
949  fWrksInfo.Clear();
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
970  if (pe.fType == TVirtualPerfStats::kPacket) {
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);
1006  fEvtRateRun->SetMinimum(0.);
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.);
1013  fMBRate->SetStats(kFALSE);
1014  fMBRate->SetFillColor(kCyan-8);
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);
1018  fMBRateRun->SetMinimum(0.);
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
1033  if (pe.fType == TVirtualPerfStats::kPacket) {
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;
1074  if (pe.fLatency > fLatencyMax) fLatencyMax = pe.fLatency;
1075 
1076  // Fill global rate histos
1077  for (kk = 1; kk <= nbins; kk++) {
1078  Double_t mi = fEvtRate->GetBinLowEdge(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
1198  fMergeTime = fMaxTime;
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
1209  SafeDelete(fPackets);
1210  fEvents = new TH1F("hevents", "Events per worker", fWrksInfo.GetSize(), -.5, fWrksInfo.GetSize()-.5);
1211  fEvents->SetDirectory(0);
1212  fPackets = new TH1F("hpackets", "Packets per worker", fWrksInfo.GetSize(), -.5, fWrksInfo.GetSize()-.5);
1213  fPackets->SetDirectory(0);
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);
1225  fPackets->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 
1239 void TProofPerfAnalysis::Summary(Option_t *opt, const char *out)
1240 {
1241  TString o(out);
1242  RedirectHandle_t rh;
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
1289  if (pe.fType == TVirtualPerfStats::kPacket) {
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
1322  Double_t tt = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
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 = "";
1433  fSaveResult = kFALSE;
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
1442  fSaveResult = kTRUE;
1443  return 0;
1444  }
1445  // New or changed file: validate
1446  fFileResult = "";
1447  fSaveResult = kFALSE;
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;
1462  fSaveResult = kTRUE;
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();
1493  fPackets->SetStats(kFALSE);
1494  DoDraw(fPackets);
1495  c1->cd();
1496  c1->Update();
1497 
1498 }
1499 
1500 ////////////////////////////////////////////////////////////////////////////////
1501 /// Show event processing or MB processing rate plot vs time
1502 
1503 void 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 
1605 void TProofPerfAnalysis::LatencyPlot(const char *wrks)
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 
1661 void 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 }
TString fTitle
Definition: TNamed.h:33
void SetDebug(Int_t d=0)
Static setter for the verbosity level.
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title Offset is a correction factor with respect to the "s...
Definition: TAttAxis.cxx:294
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:932
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
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 Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3251
TVirtualPerfStats::EEventType fType
Definition: TPerfStats.h:44
virtual TList * GetListOfKeys() const
Definition: TDirectory.h:150
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8434
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Bool_t IsValid() const
auto * tt
Definition: textangle.C:16
virtual ~TProofPerfAnalysis()
Destructor: detach the tree and close the file.
long long Long64_t
Definition: RtypesCore.h:69
static constexpr double pi
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:390
auto * m
Definition: textangle.C:8
virtual TVirtualPad * GetPad(Int_t subpadnumber) const
Get a pointer to subpadnumber of this pad.
Definition: TPad.cxx:2864
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
Definition: TDirectory.cxx:805
virtual void Draw(Option_t *option="")=0
Default Draw method for all objects.
Collectable string class.
Definition: TObjString.h:28
virtual Int_t Compare(const TObject *obj) const
Compare two TNamed objects.
Definition: TNamed.cxx:85
float Float_t
Definition: RtypesCore.h:53
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:8231
TString GetCanvasTitle(const char *t)
If defined, add &#39;- <this title>="">&#39; to the canvas title &#39;t&#39;.
void PrintFileInfo(Int_t showlast=10, const char *opt="", const char *out=0)
Print information for all or the slowest showlast workers.
const char Option_t
Definition: RtypesCore.h:62
return c1
Definition: legend1.C:41
void Print(Option_t *options="") const
Print information about this object.
Definition: TFileInfo.cxx:477
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
This class represents a WWW compatible URL.
Definition: TUrl.h:35
R__EXTERN TStyle * gStyle
Definition: TStyle.h:406
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
THist< 1, float, THistStatContent, THistStatUncertainty > TH1F
Definition: THist.hxx:285
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4770
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:47
TVirtualPad * cd(Int_t subpadnumber=0)
Set current canvas & pad.
Definition: TCanvas.cxx:688
Regular expression class.
Definition: TRegexp.h:31
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:391
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
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:5363
TString fSlaveName
Definition: TPerfStats.h:45
Basic string class.
Definition: TString.h:131
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:567
#define f(i)
Definition: RSha256.hxx:104
int Int_t
Definition: RtypesCore.h:41
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1004
bool Bool_t
Definition: RtypesCore.h:59
time_t GetSec() const
Definition: TTimeStamp.h:135
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition: TObject.cxx:195
Double_t fCpuTime
Definition: TPerfStats.h:55
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:550
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8445
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:262
void LoadTree(TDirectory *dir)
Load tree fTreeName from directory &#39;dir&#39;.
virtual void SetNameTitle(const char *name, const char *title)
Set all the TNamed parameters (name and title).
Definition: TNamed.cxx:154
void Reset()
Definition: TCollection.h:252
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:469
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:387
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:677
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3976
void FileDist(Bool_t writedet=kFALSE)
Analyse the file distribution.
const char * GetFile() const
Definition: TUrl.h:72
void FileProcPlot(const char *fn, const char *out=0)
Show event processing or MB processing rate plot vs time.
virtual void Clear(Option_t *option="")
Set name and title to empty strings ("").
Definition: TNamed.cxx:64
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.
TVirtualPad * cd(Int_t subpadnumber=0)
Set Current pad.
Definition: TPad.cxx:594
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:2286
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=0)
Change branch address, dealing with clone trees properly.
Definition: TTree.cxx:7982
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
void EventDist()
Display event and packet distribution.
static double p2(double t, double a, double b, double c)
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:464
TString fEvtNode
Definition: TPerfStats.h:42
void FileRatePlot(const char *fns=0)
Show MB processing rate plot per file vs time.
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
Definition: TMath.h:1282
void RatePlot(const char *wrks=0)
Show event processing or MB processing rate plot vs time.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:24
virtual void Print(Option_t *option="") const
Print TNamed name and title.
Definition: TNamed.cxx:128
TProofPerfAnalysis(const char *perffile, const char *title="", const char *treename="PROOF_PerfStats")
Constructor: open the file and attach to the tree.
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
virtual Bool_t Divide(TF1 *f1, Double_t c1=1)
Performs the operation: this = this/(c1*f1) if errors are defined (see TH1::Sumw2), errors are also recalculated.
Definition: TH1.cxx:2729
A doubly linked list.
Definition: TList.h:44
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
TPaveText * pt
Int_t SetSaveResult(const char *file="results.root", Option_t *mode="RECREATE")
Set save result mode and validate &#39;file&#39; according to &#39;mode&#39;.
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2974
if object ctor succeeded but object should not be used
Definition: TObject.h:68
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
Long64_t fEventsProcessed
Definition: TPerfStats.h:50
Double_t fProcTime
Definition: TPerfStats.h:54
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:250
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2264
The most important graphics class in the ROOT system.
Definition: TPad.h:29
static void SetgDebug(Bool_t on=kTRUE)
Static setter for the verbosity level.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
TString fFileName
Definition: TPerfStats.h:47
TAxis * GetYaxis()
Definition: TH1.h:316
static double p1(double t, double a, double b)
void SetName(const char *name)
Definition: TCollection.h:204
void WorkerActivity()
Measure the worker activity.
virtual void AddBefore(const TObject *before, TObject *obj)
Insert object before object before in the list.
Definition: TList.cxx:193
#define Printf
Definition: TGeoToOCC.h:18
const Bool_t kFALSE
Definition: RtypesCore.h:88
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:279
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:1688
#define SafeDelete(p)
Definition: RConfig.h:529
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
int Ssiz_t
Definition: RtypesCore.h:63
The Canvas class.
Definition: TCanvas.h:31
#define d(i)
Definition: RSha256.hxx:102
TTimeStamp fTimeStamp
Definition: TPerfStats.h:43
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2172
return c2
Definition: legend2.C:14
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8456
Bool_t WrkInfoOK() const
TString fSlave
Definition: TPerfStats.h:49
auto * t1
Definition: textangle.C:20
void GetWrkFileList(TList *wl, TList *sl)
Fill file info.
double Double_t
Definition: RtypesCore.h:55
virtual void ls(Option_t *option="") const
List (ls) all objects in this collection.
Int_t GetOptStat() const
Definition: TStyle.h:232
Describe directory structure in memory.
Definition: TDirectory.h:34
TNamed()
Definition: TNamed.h:36
void DoDraw(TObject *o, Option_t *opt="", const char *name=0)
Draw object &#39;o&#39; with options &#39;opt&#39; Save it with &#39;name&#39; if in saving mode (see SetSaveResult) ...
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
static constexpr double s
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
virtual void SetBinLabel(Int_t bin, const char *label)
Set label for bin.
Definition: TAxis.cxx:809
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:399
Definition: Rtypes.h:59
void FillFileDistOneSrv(TH1F *hx, Bool_t wdet=kFALSE)
Fill file info when there is only one file server.
virtual Long64_t GetEntries() const
Definition: TTree.h:384
Bool_t IsNull() const
Definition: TString.h:402
Mother of all ROOT objects.
Definition: TObject.h:37
void FillFileDist(TH1F *hf, TH1F *hb, TH2F *hx, Bool_t wdet=kFALSE)
Fill file info.
Long64_t fBytesRead
Definition: TPerfStats.h:51
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:401
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:1162
virtual void Add(TObject *obj)
Definition: TList.h:87
Definition: file.py:1
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
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:1444
Double_t fLatency
Definition: TPerfStats.h:53
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1896
Definition: tree.py:1
A TTree object has a header with a name and a title.
Definition: TTree.h:70
#define gDirectory
Definition: TDirectory.h:213
Definition: Rtypes.h:59
Class describing a generic file including meta information.
Definition: TFileInfo.h:38
void Add(TObject *obj)
Add object in sorted list.
Definition: TSortedList.cxx:27
virtual Int_t GetNbinsX() const
Definition: TH1.h:291
void LatencyPlot(const char *wrks=0)
Show event processing or MB processing rate plot vs time Create the histograms.
virtual void Update()
Update canvas pad buffers.
Definition: TCanvas.cxx:2248
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
void FillFileInfo(Bool_t force=kFALSE)
Fill basic worker info; if &#39;force&#39; rescan the TTree even already done.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH2.cxx:292
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
THist< 2, float, THistStatContent, THistStatUncertainty > TH2F
Definition: THist.hxx:291
const Bool_t kTRUE
Definition: RtypesCore.h:87
const Int_t n
Definition: legend1.C:16
void FillWrkInfo(Bool_t force=kFALSE)
Fill basic worker info; if &#39;force&#39; rescan the TTree even already done.
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition: TH1.cxx:8284
Int_t GetNanoSec() const
Definition: TTimeStamp.h:136
char name[80]
Definition: TGX11.cxx:109
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:315
void Summary(Option_t *opt="", const char *out="")
Print summary of query.
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:917
const char * Data() const
Definition: TString.h:364
void PrintWrkInfo(Int_t showlast=10)
Print information for all or the slowest showlast workers.