Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TProofBenchRunDataRead.cxx
Go to the documentation of this file.
1 // @(#)root/proof:$Id$
2 // Author: Sangsu Ryu 22/06/2010
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 /** \class TProofBenchRunDataRead
13 \ingroup proofbench
14 
15 I/O-intensive PROOF benchmark test reads in event files distributed
16 on the cluster. Number of events processed per second and size of
17 events processed per second are plotted against number of active
18 workers. Performance rate for unit packets and performance rate
19 for query are plotted.
20 
21 */
22 
23 #include "RConfigure.h"
24 
25 #include "TProofBenchRunDataRead.h"
26 #include "TProofBenchDataSet.h"
27 #include "TProofPerfAnalysis.h"
28 #include "TProofNodes.h"
29 #include "TFileCollection.h"
30 #include "TFileInfo.h"
31 #include "TProof.h"
32 #include "TString.h"
33 #include "Riostream.h"
34 #include "TMap.h"
35 #include "TTree.h"
36 #include "TH1.h"
37 #include "TH2D.h"
38 #include "TCanvas.h"
39 #include "TProfile.h"
40 #include "TKey.h"
41 #include "TRegexp.h"
42 #include "TPerfStats.h"
43 #include "THashList.h"
44 #include "TSortedList.h"
45 #include "TPad.h"
46 #include "TEnv.h"
47 #include "TLeaf.h"
48 #include "TQueryResult.h"
49 #include "TMath.h"
50 #include "TStyle.h"
51 #include "TLegend.h"
52 #include "TROOT.h"
53 
54 ClassImp(TProofBenchRunDataRead);
55 
56 ////////////////////////////////////////////////////////////////////////////////
57 
58 TProofBenchRunDataRead::TProofBenchRunDataRead(TProofBenchDataSet *pbds, TPBReadType *readtype,
59  TDirectory* dirproofbench, TProof* proof,
60  TProofNodes* nodes, Long64_t nevents, Int_t ntries,
61  Int_t start, Int_t stop, Int_t step, Int_t debug)
62  : TProofBenchRun(proof, kPROOF_BenchSelDataDef), fProof(proof),
63  fReadType(readtype), fDS(pbds),
64  fNEvents(nevents), fNTries(ntries), fStart(start), fStop(stop), fStep(step),
65  fDebug(debug), fFilesPerWrk(2), fReleaseCache(kTRUE),
66  fDirProofBench(dirproofbench), fNodes(nodes),
67  fListPerfPlots(0), fProfile_perfstat_event(0), fHist_perfstat_event(0),
68  fProfile_perfstat_evtmax(0), fNorm_perfstat_evtmax(0),
69  fProfile_queryresult_event(0), fNorm_queryresult_event(0),
70  fProfile_perfstat_IO(0), fHist_perfstat_IO(0),
71  fProfile_perfstat_IOmax(0), fNorm_perfstat_IOmax(0),
72  fProfile_queryresult_IO(0), fNorm_queryresult_IO(0), fProfile_cpu_eff(0),
73  fProfLegend_evt(0), fNormLegend_evt(0), fProfLegend_mb(0), fNormLegend_mb(0),
74  fCPerfProfiles(0), fName(0)
75 {
76  // Default constructor
77 
78  if (!fProof) fProof = gProof;
79  if (!fDS) fDS = new TProofBenchDataSet(fProof);
80 
81  // Set name
82  fName = "DataRead";
83 
84  if (!fNodes) fNodes = new TProofNodes(fProof);
85  fNodes->GetMapOfActiveNodes()->Print();
86 
87  if (stop == -1) fStop = fNodes->GetNWorkersCluster();
88 
89  fListPerfPlots = new TList;
90 
91  gEnv->SetValue("Proof.StatsTrace",1);
92  gStyle->SetOptStat(0);
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Destructor
97 
98 TProofBenchRunDataRead::~TProofBenchRunDataRead()
99 {
100  fProof=0;
101  fDirProofBench=0;
102  SafeDelete(fListPerfPlots);
103  if (fCPerfProfiles) delete fCPerfProfiles;
104  SafeDelete(fProfLegend_evt);
105  SafeDelete(fProfLegend_mb);
106  SafeDelete(fNormLegend_evt);
107  SafeDelete(fNormLegend_mb);
108 }
109 
110 ////////////////////////////////////////////////////////////////////////////////
111 /// Run benchmark
112 /// Input parameters
113 /// dset: Dataset on which to run
114 /// start: Start scan with 'start' workers.
115 /// stop: Stop scan at 'stop workers.
116 /// step: Scan every 'step' workers.
117 /// ntries: Number of tries. When it is -1, data member fNTries is used.
118 /// debug: debug switch.
119 /// Int_t: Ignored
120 /// Returns
121 /// Nothing
122 
123 void TProofBenchRunDataRead::Run(const char *dset, Int_t start, Int_t stop,
124  Int_t step, Int_t ntries, Int_t debug, Int_t)
125 {
126  if (!fProof){
127  Error("Run", "Proof not set");
128  return;
129  }
130  if (!dset || (dset && strlen(dset) <= 0)){
131  Error("Run", "dataset name not set");
132  return;
133  }
134  // Check if the dataset exists
135  if (!fProof->ExistsDataSet(dset)) {
136  Error("Run", "no such data set found; %s", dset);
137  return;
138  }
139 
140  start = (start == -1) ? fStart : start;
141  stop = (stop == -1) ? fStop : stop;
142  step = (step == -1) ? fStep : step;
143  ntries = (ntries == -1) ? fNTries : ntries;
144  debug = (debug == -1) ? fDebug : debug;
145 
146  Int_t fDebug_sav = fDebug;
147  fDebug = debug;
148 
149  Bool_t nx = kFALSE;
150  if (step == -2){
151  nx = kTRUE;
152  step = 1;
153  }
154 
155  if (nx){
156  Int_t minnworkersanode = fNodes->GetMinWrksPerNode();
157  if (stop > minnworkersanode) stop = minnworkersanode;
158  }
159 
160  // Load the selector, if needed
161  if (!TClass::GetClass(fSelName) || !fDS->IsProof(fProof)) {
162  // Is it the default selector?
163  if (fSelName == kPROOF_BenchSelDataDef) {
164  // Load the parfile
165  TString par = TString::Format("%s/%s%s.par", TROOT::GetEtcDir().Data(), kPROOF_BenchParDir, kPROOF_BenchDataSelPar);
166  Info("Run", "Uploading '%s' ...", par.Data());
167  if (fProof->UploadPackage(par) != 0) {
168  Error("Run", "problems uploading '%s' - cannot continue", par.Data());
169  return;
170  }
171  Info("Run", "Enabling '%s' ...", kPROOF_BenchDataSelPar);
172  if (fProof->EnablePackage(kPROOF_BenchDataSelPar) != 0) {
173  Error("Run", "problems enabling '%s' - cannot continue", kPROOF_BenchDataSelPar);
174  return;
175  }
176  } else {
177  if (fParList.IsNull()) {
178  Error("Run", "you should load the class '%s' before running the benchmark", fSelName.Data());
179  return;
180  } else {
181  TString par;
182  Int_t from = 0;
183  while (fParList.Tokenize(par, from, ",")) {
184  Info("Run", "Uploading '%s' ...", par.Data());
185  if (fProof->UploadPackage(par) != 0) {
186  Error("Run", "problems uploading '%s' - cannot continue", par.Data());
187  return;
188  }
189  Info("Run", "Enabling '%s' ...", par.Data());
190  if (fProof->EnablePackage(par) != 0) {
191  Error("Run", "problems enabling '%s' - cannot continue", par.Data());
192  return;
193  }
194  }
195  }
196  }
197  // Check
198  if (!TClass::GetClass(fSelName)) {
199  Error("Run", "failed to load '%s'", fSelName.Data());
200  return;
201  }
202  }
203 
204  // Build histograms, profiles and graphs needed for this run
205  BuildHistos(start, stop, step, nx);
206 
207  TString dsname(dset);
208  TString dsbasename = gSystem->BaseName(dset);
209 
210  // Get pad
211  if (!fCPerfProfiles){
212  TString canvasname = TString::Format("Performance Profiles %s", GetName());
213  fCPerfProfiles = new TCanvas(canvasname.Data(), canvasname.Data());
214  }
215 
216  // Cleanup up the canvas
217  fCPerfProfiles->Clear();
218 
219  fCPerfProfiles->Divide(2,2);
220 
221  Info("Run", "Running IO-bound tests on dataset '%s'; %d ~ %d active worker(s),"
222  " every %d worker(s).", dset, start, stop, step);
223 
224  Int_t npad = 1; //pad number
225 
226  Int_t nnodes = fNodes->GetNNodes(); // Number of machines
227  Int_t ncores = fNodes->GetNCores(); // Number of cores
228 
229  Bool_t drawpf = kFALSE;
230  Double_t ymi = -1., ymx = -1., emx =- 1, ymiio = -1., ymxio = -1., mbmx = -1.;
231  for (Int_t nactive = start; nactive <= stop; nactive += step) {
232 
233  // For CPU effectiveness (ok for lite; should do it properly for standard clusters)
234  Int_t ncoren = (nactive < ncores) ? nactive : ncores;
235 
236  // Actvate the wanted workers
237  Int_t nw = -1;
238  if (nx) {
239  TString workers;
240  workers.Form("%dx", nactive);
241  nw = fNodes->ActivateWorkers(workers);
242  } else {
243  nw = fNodes->ActivateWorkers(nactive);
244  }
245  if (nw < 0){
246  Error("Run", "could not activate the requested number of"
247  " workers/node on the cluster; skipping the test point"
248  " (%d workers/node)", nactive);
249  continue;
250  }
251 
252  // Prepare the dataset for this run. possibly a subsample of
253  // the total one
254  TFileCollection *fc = GetDataSet(dsname, nactive, nx);
255  if (!fc) {
256  Error("Run", "could not retrieve dataset '%s'", dsname.Data());
257  continue;
258  }
259  fc->Print("F");
260  TString dsn = TString::Format("%s_%d_%d", dsbasename.Data(), nactive, (Int_t)nx);
261  fProof->RegisterDataSet(dsn, fc, "OT");
262  fProof->ShowDataSet(dsn, "F");
263 
264  for (Int_t j=0; j<ntries; j++) {
265 
266  if (nx){
267  Info("Run", "Running IO-bound tests with %d active worker(s)/node;"
268  " trial %d/%d", nactive, j + 1, ntries);
269  } else {
270  Info("Run", "Running IO-bound tests with %d active worker(s);"
271  " trial %d/%d", nactive, j + 1, ntries);
272  }
273 
274  // Cleanup run
275  const char *dsnr = (fDS->IsProof(fProof)) ? dsn.Data() : dsname.Data();
276  if (fReleaseCache) fDS->ReleaseCache(dsnr);
277 
278  DeleteParameters();
279  SetParameters();
280 
281  Info("Run", "Processing data set %s with"
282  " %d active worker(s).", dsn.Data(), nactive);
283 
284  TTime starttime = gSystem->Now();
285  fProof->Process(dsn, fSelName, fSelOption);
286 
287  DeleteParameters();
288 
289  TTime endtime = gSystem->Now();
290 
291  TList *l = fProof->GetOutputList();
292 
293  //save perfstats
294  TString perfstats_name = "PROOF_PerfStats";
295  TTree *t = 0;
296  if (l) t = dynamic_cast<TTree*>(l->FindObject(perfstats_name.Data()));
297  if (t) {
298  drawpf = kTRUE;
299  TTree* tnew=(TTree*)t->Clone("tnew");
300 
301  FillPerfStatProfiles(tnew, nactive);
302 
303  TProofPerfAnalysis pfa(tnew);
304  Double_t pf_eventrate = pfa.GetEvtRateAvgMax();
305  Double_t pf_IOrate = pfa.GetMBRateAvgMax();
306  fProfile_perfstat_evtmax->Fill(nactive, pf_eventrate);
307  fCPerfProfiles->cd(npad);
308  fProfile_perfstat_evtmax->SetMaximum(1.6*emx);
309  fProfile_perfstat_evtmax->SetMinimum(0.);
310  fProfile_perfstat_evtmax->Draw();
311  fProfLegend_evt->Draw();
312  gPad->Update();
313  fProfile_perfstat_IOmax->Fill(nactive, pf_IOrate);
314  fCPerfProfiles->cd(npad + 2);
315  fProfile_perfstat_IOmax->SetMaximum(1.6*mbmx);
316  fProfile_perfstat_IOmax->SetMinimum(0.);
317  fProfile_perfstat_IOmax->Draw();
318  fProfLegend_mb->Draw();
319  gPad->Update();
320  // The normalised histos
321  // Use the first bin to set the Y range for the histo
322  Double_t nert = nx ? pf_eventrate/nactive/nnodes : pf_eventrate/nactive;
323  fNorm_perfstat_evtmax->Fill(nactive, nert);
324  Double_t y1 = fNorm_perfstat_evtmax->GetBinContent(1);
325  Double_t e1 = fNorm_perfstat_evtmax->GetBinError(1);
326  Double_t dy = 5 * e1;
327  if (dy / y1 < 0.2) dy = y1 * 0.2;
328  if (dy > y1) dy = y1*.999999;
329  if (ymi < 0.) ymi = y1 - dy;
330  if (fNorm_perfstat_evtmax->GetBinContent(nactive) < ymi)
331  ymi = fNorm_perfstat_evtmax->GetBinContent(nactive) / 2.;
332  if (ymx < 0.) ymx = y1 + dy;
333  if (fNorm_perfstat_evtmax->GetBinContent(nactive) > ymx)
334  ymx = fNorm_perfstat_evtmax->GetBinContent(nactive) * 1.5;
335  fNorm_perfstat_evtmax->SetMaximum(ymx);
336  fNorm_perfstat_evtmax->SetMinimum(ymi);
337  fCPerfProfiles->cd(npad + 1);
338  fNorm_perfstat_evtmax->Draw();
339  gPad->Update();
340  //
341  Double_t niort = nx ? pf_IOrate/nactive/nnodes : pf_IOrate/nactive;
342  fNorm_perfstat_IOmax->Fill(nactive, niort);
343  y1 = fNorm_perfstat_IOmax->GetBinContent(1);
344  e1 = fNorm_perfstat_IOmax->GetBinError(1);
345  dy = 5 * e1;
346  if (dy / y1 < 0.2) dy = y1 * 0.2;
347  if (dy > y1) dy = y1*.999999;
348  if (ymiio < 0.) ymiio = y1 - dy;
349  if (fNorm_perfstat_IOmax->GetBinContent(nactive) < ymiio)
350  ymiio = fNorm_perfstat_IOmax->GetBinContent(nactive) / 2.;
351  if (ymxio < 0.) ymxio = y1 + dy;
352  if (fNorm_perfstat_IOmax->GetBinContent(nactive) > ymxio)
353  ymxio = fNorm_perfstat_IOmax->GetBinContent(nactive) * 1.5;
354  fNorm_perfstat_IOmax->SetMaximum(ymxio);
355  fNorm_perfstat_IOmax->SetMinimum(ymiio);
356  fCPerfProfiles->cd(npad + 3);
357  fNorm_perfstat_IOmax->Draw();
358  gPad->Update();
359 
360  //change the name
361  TString newname = TString::Format("%s_%s_%dwrks%dthtry", t->GetName(), GetName(), nactive, j);
362  tnew->SetName(newname);
363 
364  if (debug && fDirProofBench->IsWritable()){
365  TDirectory *curdir = gDirectory;
366  TString dirn = nx ? "RunDataReadx" : "RunDataRead";
367  if (!fDirProofBench->GetDirectory(dirn))
368  fDirProofBench->mkdir(dirn, "RunDataRead results");
369  if (fDirProofBench->cd(dirn)) {
370  tnew->SetDirectory(fDirProofBench);
371  tnew->Write();
372  l->Remove(tnew);
373  } else {
374  Warning("Run", "cannot cd to subdirectory '%s' to store the results!", dirn.Data());
375  }
376  curdir->cd();
377  }
378  } else {
379  if (l)
380  Warning("Run", "%s: tree not found", perfstats_name.Data());
381  else
382  Error("Run", "PROOF output list is empty!");
383  }
384 
385  //
386  const char *drawopt = t ? "SAME" : "";
387  // Performance measures from TQueryResult
388  TQueryResult *queryresult = fProof->GetQueryResult();
389  if (queryresult) {
390  TDatime qr_start = queryresult->GetStartTime();
391  TDatime qr_end = queryresult->GetEndTime();
392  Float_t qr_proc = queryresult->GetProcTime();
393  Long64_t qr_bytes = queryresult->GetBytes();
394 
395  Long64_t qr_entries = queryresult->GetEntries();
396 
397  // Calculate and fill CPU efficiency
398  Float_t qr_cpu_eff = -1.;
399  if (qr_proc > 0.) {
400  qr_cpu_eff = queryresult->GetUsedCPU() / ncoren / qr_proc ;
401  fProfile_cpu_eff->Fill(nactive, qr_cpu_eff);
402  Printf("cpu_eff: %f", qr_cpu_eff);
403  }
404 
405  // Calculate event rate, fill and draw
406  Double_t qr_eventrate=0;
407 
408  qr_eventrate = qr_entries / Double_t(qr_proc);
409  if (qr_eventrate > emx) emx = qr_eventrate;
410 
411  fProfile_queryresult_event->Fill(nactive, qr_eventrate);
412  fCPerfProfiles->cd(npad);
413  fProfile_queryresult_event->SetMinimum(0.);
414  fProfile_queryresult_event->Draw(drawopt);
415  fProfLegend_evt->Draw();
416  gPad->Update();
417 
418  // Calculate IO rate, fill and draw
419  Double_t qr_IOrate = 0;
420 
421  const Double_t Dmegabytes = 1024*1024;
422 
423  qr_IOrate = qr_bytes / Dmegabytes / Double_t(qr_proc);
424  if (qr_IOrate > mbmx) mbmx = qr_IOrate;
425 
426  fProfile_queryresult_IO->Fill(nactive, qr_IOrate);
427  fCPerfProfiles->cd(npad + 2);
428  fProfile_queryresult_IO->SetMinimum(0.);
429  fProfile_queryresult_IO->Draw(drawopt);
430  fProfLegend_mb->Draw();
431  gPad->Update();
432 
433  // The normalised histos
434  // Use the first bin to set the Y range for the histo
435  Double_t nert = nx ? qr_eventrate/nactive/nnodes : qr_eventrate/nactive;
436  fNorm_queryresult_event->Fill(nactive, nert);
437  Double_t y1 = fNorm_queryresult_event->GetBinContent(1);
438  Double_t e1 = fNorm_queryresult_event->GetBinError(1);
439  Double_t dy = 5 * e1;
440  if (dy / y1 < 0.2) dy = y1 * 0.2;
441  if (dy > y1) dy = y1*.999999;
442  if (ymi < 0.) ymi = y1 - dy;
443  if (fNorm_queryresult_event->GetBinContent(nactive) < ymi)
444  ymi = fNorm_queryresult_event->GetBinContent(nactive) / 2.;
445  if (ymx < 0.) ymx = y1 + dy;
446  if (fNorm_queryresult_event->GetBinContent(nactive) > ymx)
447  ymx = fNorm_queryresult_event->GetBinContent(nactive) * 1.5;
448 // fNorm_queryresult_event->SetMaximum(ymx);
449  fNorm_queryresult_event->SetMinimum(ymi);
450  fCPerfProfiles->cd(npad + 1);
451  fNorm_queryresult_event->Draw(drawopt);
452  fNormLegend_evt->Draw();
453  gPad->Update();
454  //
455  Double_t niort = nx ? qr_IOrate/nactive/nnodes : qr_IOrate/nactive;
456  fNorm_queryresult_IO->Fill(nactive, niort);
457  y1 = fNorm_queryresult_IO->GetBinContent(1);
458  e1 = fNorm_queryresult_IO->GetBinError(1);
459  dy = 5 * e1;
460  if (dy / y1 < 0.2) dy = y1 * 0.2;
461  if (dy > y1) dy = y1*.999999;
462  if (ymiio < 0.) ymiio = y1 - dy;
463  if (fNorm_queryresult_IO->GetBinContent(nactive) < ymiio)
464  ymiio = fNorm_queryresult_IO->GetBinContent(nactive) / 2.;
465  if (ymxio < 0.) ymxio = y1 + dy;
466  if (fNorm_queryresult_IO->GetBinContent(nactive) > ymxio)
467  ymxio = fNorm_queryresult_IO->GetBinContent(nactive) * 1.5;
468 // fNorm_queryresult_IO->SetMaximum(ymxio);
469  fNorm_queryresult_IO->SetMinimum(ymiio);
470  fCPerfProfiles->cd(npad + 3);
471  fNorm_queryresult_IO->Draw(drawopt);
472  fNormLegend_mb->Draw();
473  gPad->Update();
474  }
475  fCPerfProfiles->cd(0);
476  }
477  // Remove temporary dataset
478  fProof->RemoveDataSet(dsn);
479  SafeDelete(fc);
480  }
481 
482  // Make the result persistent
483  fCPerfProfiles->cd(npad);
484  fProfile_queryresult_event->SetMaximum(1.6*emx);
485  fProfile_queryresult_event->DrawCopy();
486  if (drawpf) fProfile_perfstat_evtmax->DrawCopy("SAME");
487  fProfLegend_evt->Draw();
488  fCPerfProfiles->cd(npad + 2);
489  fProfile_queryresult_IO->SetMaximum(1.6*mbmx);
490  fProfile_queryresult_IO->DrawCopy();
491  if (drawpf) fProfile_perfstat_IOmax->DrawCopy("SAME");
492  fProfLegend_mb->Draw();
493  fCPerfProfiles->cd(npad + 1);
494  fNorm_queryresult_event->DrawCopy();
495  if (drawpf) fNorm_perfstat_evtmax->DrawCopy("SAME");
496  fNormLegend_evt->Draw();
497  fCPerfProfiles->cd(npad + 3);
498  fNorm_queryresult_IO->DrawCopy();
499  if (drawpf) fNorm_perfstat_IOmax->DrawCopy("SAME");
500  fProfLegend_mb->Draw();
501  gPad->Update();
502 
503  //save performance profiles to file
504  if (fDirProofBench->IsWritable()){
505  TDirectory *curdir = gDirectory;
506  TString dirn = nx ? "RunDataReadx" : "RunDataRead";
507  if (!fDirProofBench->GetDirectory(dirn))
508  fDirProofBench->mkdir(dirn, "RunDataRead results");
509  if (fDirProofBench->cd(dirn)) {
510  fListPerfPlots->Write(0, kOverwrite);
511  fListPerfPlots->SetOwner(kFALSE);
512  fListPerfPlots->Clear();
513  } else {
514  Warning("Run", "cannot cd to subdirectory '%s' to store the results!", dirn.Data());
515  }
516  curdir->cd();
517  }
518  // Restore member data
519  fDebug = fDebug_sav;
520 }
521 
522 ////////////////////////////////////////////////////////////////////////////////
523 /// Get a subsample of dsname suited to run with 'nact' and option 'nx'.
524 
525 TFileCollection *TProofBenchRunDataRead::GetDataSet(const char *dset,
526  Int_t nact, Bool_t nx)
527 {
528  TFileCollection *fcsub = 0;
529 
530  // Dataset must exists
531  if (!fProof || (fProof && !fProof->ExistsDataSet(dset))) {
532  Error("GetDataSet", "dataset '%s' does not exist", dset);
533  return fcsub;
534  }
535 
536  // Get the full collection
537  TFileCollection *fcref = fProof->GetDataSet(dset);
538  if (!fcref) {
539  Error("GetDataSet", "dataset '%s' could not be retrieved", dset);
540  return fcsub;
541  }
542  // Is it remote ?
543  Bool_t remote = (fcref->TestBit(TFileCollection::kRemoteCollection)) ? kTRUE : kFALSE;
544 
545  // Separate info per server
546  TMap *mpref = fcref->GetFilesPerServer(fProof->GetMaster(), kTRUE);
547  if (!mpref) {
548  SafeDelete(fcref);
549  Error("GetDataSet", "problems classifying info on per-server base");
550  return fcsub;
551  }
552  mpref->Print();
553 
554  // Get Active node information
555  TMap *mpnodes = fNodes->GetMapOfActiveNodes();
556  if (!mpnodes) {
557  SafeDelete(fcref);
558  SafeDelete(mpref);
559  Error("GetDataSet", "problems getting map of active nodes");
560  return fcsub;
561  }
562  mpnodes->Print();
563 
564  // Number of files: fFilesPerWrk per active worker
565  Int_t nf = fNodes->GetNActives() * fFilesPerWrk;
566  Printf(" number of files needed (ideally): %d (%d per worker)", nf, fFilesPerWrk);
567 
568  // The output dataset
569  fcsub = new TFileCollection(TString::Format("%s_%d_%d", fcref->GetName(), nact, nx),
570  fcref->GetTitle());
571 
572  // Order reference sub-collections
573  TIter nxnd(mpnodes);
574  TObject *key = 0;
575  TFileInfo *fi = 0;
576  TFileCollection *xfc = 0;
577  TList *lswrks = 0;
578  while ((key = nxnd())) {
579  TIter nxsrv(mpref);
580  TObject *ksrv = 0;
581  while ((ksrv = nxsrv())) {
582  TUrl urlsrv(ksrv->GetName());
583  if (TString(urlsrv.GetHostFQDN()).IsNull())
584  urlsrv.SetHost(TUrl(gProof->GetMaster()).GetHostFQDN());
585  if (remote ||
586  !strcmp(urlsrv.GetHostFQDN(), TUrl(key->GetName()).GetHostFQDN())) {
587  if ((xfc = dynamic_cast<TFileCollection *>(mpref->GetValue(ksrv)))) {
588  if ((lswrks = dynamic_cast<TList *>(mpnodes->GetValue(key)))) {
589  Int_t nfnd = fFilesPerWrk * lswrks->GetSize();
590  while (nfnd-- && xfc->GetList()->GetSize() > 0) {
591  if ((fi = (TFileInfo *) xfc->GetList()->First())) {
592  xfc->GetList()->Remove(fi);
593  fcsub->Add(fi);
594  }
595  }
596  } else {
597  Warning("GetDataSet", "could not attach to worker list for node '%s'",
598  key->GetName());
599  }
600  } else {
601  Warning("GetDataSet", "could not attach to file collection for server '%s'",
602  ksrv->GetName());
603  }
604  }
605  }
606  }
607 
608  // Update counters
609  fcsub->Update();
610  fcsub->Print();
611 
612  // Make sure that the tree name is the one of the original dataset
613  if (fcref) {
614  TString dflt(fcref->GetDefaultTreeName());
615  if (!dflt.IsNull()) fcsub->SetDefaultTreeName(dflt);
616  }
617 
618  // Cleanup
619  SafeDelete(fcref);
620  SafeDelete(mpref);
621  // Done
622  return fcsub;
623 }
624 
625 ////////////////////////////////////////////////////////////////////////////////
626 
627 void TProofBenchRunDataRead::FillPerfStatProfiles(TTree *t, Int_t nactive)
628 {
629  // Fill performance profiles using tree 't'(PROOF_PerfStats).
630  // Input parameters
631  // t: Proof output tree (PROOF_PerfStat) containing performance
632  // statistics.
633  // nactive: Number of active workers processed the query.
634  // Return
635  // Nothing
636 
637  // extract timing information
638  TPerfEvent pe;
639  TPerfEvent* pep = &pe;
640  t->SetBranchAddress("PerfEvents",&pep);
641  Long64_t entries = t->GetEntries();
642 
643  const Double_t Dmegabytes = 1024.*1024.;
644  Double_t event_rate_packet = 0;
645  Double_t IO_rate_packet = 0;
646 
647  for (Long64_t k=0; k<entries; k++) {
648  t->GetEntry(k);
649 
650  // Skip information from workers
651  if (pe.fEvtNode.Contains(".")) continue;
652 
653  if (pe.fType==TVirtualPerfStats::kPacket){
654  if (pe.fProcTime != 0.0) {
655  event_rate_packet = pe.fEventsProcessed / pe.fProcTime;
656  fHist_perfstat_event->Fill(Double_t(nactive), event_rate_packet);
657  IO_rate_packet = pe.fBytesRead / Dmegabytes / pe.fProcTime;
658  fHist_perfstat_IO->Fill(Double_t(nactive), IO_rate_packet);
659  }
660  }
661  }
662 
663  return;
664 }
665 
666 ////////////////////////////////////////////////////////////////////////////////
667 /// Print the content of this object
668 
669 void TProofBenchRunDataRead::Print(Option_t* option) const
670 {
671  Printf("Name = %s", fName.Data());
672  if (fProof) fProof->Print(option);
673  Printf("fReadType = %s%s", "k", GetNameStem().Data());
674  Printf("fNEvents = %lld", fNEvents);
675  Printf("fNTries = %d", fNTries);
676  Printf("fStart = %d", fStart);
677  Printf("fStop = %d", fStop);
678  Printf("fStep = %d", fStep);
679  Printf("fDebug = %d", fDebug);
680  if (fDirProofBench)
681  Printf("fDirProofBench = %s", fDirProofBench->GetPath());
682  if (fNodes) fNodes->Print(option);
683  if (fListPerfPlots) fListPerfPlots->Print(option);
684 
685  if (fCPerfProfiles)
686  Printf("Performance Profiles Canvas: Name = %s Title = %s",
687  fCPerfProfiles->GetName(), fCPerfProfiles->GetTitle());
688 }
689 
690 ////////////////////////////////////////////////////////////////////////////////
691 /// Get canvas
692 
693 void TProofBenchRunDataRead::DrawPerfProfiles()
694 {
695  if (!fCPerfProfiles){
696  TString canvasname = TString::Format("Performance Profiles %s", GetName());
697  fCPerfProfiles = new TCanvas(canvasname.Data(), canvasname.Data());
698  }
699 
700  fCPerfProfiles->Clear();
701 
702  // Divide the canvas as many as the number of profiles in the list
703  Int_t nprofiles = fListPerfPlots->GetSize();
704  if (nprofiles <= 2){
705  fCPerfProfiles->Divide(nprofiles);
706  } else {
707  Int_t nside = (Int_t)TMath::Sqrt((Float_t)nprofiles);
708  nside = (nside*nside < nprofiles) ? nside + 1 : nside;
709  fCPerfProfiles->Divide(nside,nside);
710  }
711 
712  Int_t npad=1;
713  TIter nxt(fListPerfPlots);
714  TProfile* profile=0;
715  while ((profile=(TProfile*)(nxt()))){
716  fCPerfProfiles->cd(npad++);
717  profile->Draw();
718  gPad->Update();
719  }
720  return;
721 }
722 
723 ////////////////////////////////////////////////////////////////////////////////
724 /// Get name for this run
725 
726 TString TProofBenchRunDataRead::GetNameStem()const
727 {
728  TString namestem("+++undef+++");
729  if (fReadType) {
730  switch (fReadType->GetType()) {
731  case TPBReadType::kReadFull:
732  namestem="Full";
733  break;
734  case TPBReadType::kReadOpt:
735  namestem="Opt";
736  break;
737  case TPBReadType::kReadNo:
738  namestem="No";
739  break;
740  default:
741  break;
742  }
743  }
744  return namestem;
745 }
746 
747 ////////////////////////////////////////////////////////////////////////////////
748 /// Set parameters
749 
750 Int_t TProofBenchRunDataRead::SetParameters()
751 {
752  if (!fProof){
753  Error("SetParameters", "Proof not set; Doing nothing");
754  return 1;
755  }
756  if (!fReadType) fReadType = new TPBReadType(TPBReadType::kReadOpt);
757  fProof->AddInput(fReadType);
758  fProof->SetParameter("PROOF_BenchmarkDebug", Int_t(fDebug));
759  // For Mac Os X only: do not OS cache the files read
760  fProof->SetParameter("PROOF_DontCacheFiles", Int_t(1));
761  return 0;
762 }
763 
764 ////////////////////////////////////////////////////////////////////////////////
765 /// Delete parameters set for this run
766 
767 Int_t TProofBenchRunDataRead::DeleteParameters()
768 {
769  if (!fProof){
770  Error("DeleteParameters", "Proof not set; Doing nothing");
771  return 1;
772  }
773  if (fProof->GetInputList()) {
774  TObject *type = fProof->GetInputList()->FindObject("PROOF_Benchmark_ReadType");
775  if (type) fProof->GetInputList()->Remove(type);
776  }
777  fProof->DeleteParameters("PROOF_BenchmarkDebug");
778  return 0;
779 }
780 
781 ////////////////////////////////////////////////////////////////////////////////
782 /// Build histograms, profiles and graphs needed for this run
783 
784 void TProofBenchRunDataRead::BuildHistos(Int_t start, Int_t stop, Int_t step, Bool_t nx)
785 {
786  TObject *o = 0;
787  Int_t quotient = (stop - start) / step;
788  Int_t ndiv = quotient + 1;
789  Double_t ns_min = start - step/2.;
790  Double_t ns_max = quotient*step + start + step/2.;
791 
792  fProfLegend_evt = new TLegend(0.1, 0.8, 0.3, 0.9);
793  fNormLegend_evt = new TLegend(0.7, 0.8, 0.9, 0.9);
794  fProfLegend_mb = new TLegend(0.1, 0.8, 0.3, 0.9);
795  fNormLegend_mb = new TLegend(0.7, 0.8, 0.9, 0.9);
796 
797  TString axtitle("Active Workers"), namelab(GetName()), sellab(GetSelName());
798  if (nx) {
799  axtitle = "Active Workers/Node";
800  namelab.Form("x_%s", GetName());
801  }
802  if (fSelName == kPROOF_BenchSelDataDef)
803  sellab.Form("%s_%s", GetSelName(), GetNameStem().Data());
804 
805  TString name, title;
806 
807  // Book perfstat profile (max evts)
808  name.Form("Prof_%s_PS_MaxEvts_%s", namelab.Data(), sellab.Data());
809  title.Form("Profile %s PerfStat Event- %s", namelab.Data(), sellab.Data());
810  fProfile_perfstat_evtmax = new TProfile(name, title, ndiv, ns_min, ns_max);
811  fProfile_perfstat_evtmax->SetDirectory(fDirProofBench);
812  fProfile_perfstat_evtmax->GetYaxis()->SetTitle("Events/sec");
813  fProfile_perfstat_evtmax->GetXaxis()->SetTitle(axtitle);
814  fProfile_perfstat_evtmax->SetMarkerStyle(23);
815  fProfile_perfstat_evtmax->SetMarkerStyle(2);
816  if ((o = fListPerfPlots->FindObject(name))) {
817  fListPerfPlots->Remove(o);
818  delete o;
819  }
820  fListPerfPlots->Add(fProfile_perfstat_evtmax);
821  fProfLegend_evt->AddEntry(fProfile_perfstat_evtmax, "Maximum");
822 
823  // Book perfstat profile (evts)
824  name.Form("Prof_%s_PS_Evts_%s", namelab.Data(), sellab.Data());
825  title.Form("Profile %s PerfStat Event - %s", namelab.Data(), sellab.Data());
826  fProfile_perfstat_event = new TProfile(name, title, ndiv, ns_min, ns_max);
827  fProfile_perfstat_event->SetDirectory(fDirProofBench);
828  fProfile_perfstat_event->GetYaxis()->SetTitle("Events/sec");
829  fProfile_perfstat_event->GetXaxis()->SetTitle(axtitle);
830  fProfile_perfstat_event->SetMarkerStyle(21);
831  if ((o = fListPerfPlots->FindObject(name))) {
832  fListPerfPlots->Remove(o);
833  delete o;
834  }
835  fListPerfPlots->Add(fProfile_perfstat_event);
836 
837  // Book perfstat histogram (evts)
838  name.Form("Hist_%s_PS_Evts_%s", namelab.Data(), sellab.Data());
839  title.Form("Histogram %s PerfStat Event - %s", namelab.Data(), sellab.Data());
840  fHist_perfstat_event = new TH2D(name, title, ndiv, ns_min, ns_max, 100, 0, 0);
841  fHist_perfstat_event->SetDirectory(fDirProofBench);
842  fHist_perfstat_event->GetYaxis()->SetTitle("Events/sec");
843  fHist_perfstat_event->GetXaxis()->SetTitle(axtitle);
844  fHist_perfstat_event->SetMarkerStyle(7);
845  if ((o = fListPerfPlots->FindObject(name))) {
846  fListPerfPlots->Remove(o);
847  delete o;
848  }
849  fListPerfPlots->Add(fHist_perfstat_event);
850 
851  // Book normalized perfstat profile (max evts)
852  name.Form("Norm_%s_PF_MaxEvts_%s", namelab.Data(), sellab.Data());
853  title.Form("Profile %s Normalized QueryResult Event - %s", namelab.Data(), sellab.Data());
854  fNorm_perfstat_evtmax = new TProfile(name, title, ndiv, ns_min, ns_max);
855  fNorm_perfstat_evtmax->SetDirectory(fDirProofBench);
856  fNorm_perfstat_evtmax->GetYaxis()->SetTitle("Events/sec");
857  fNorm_perfstat_evtmax->GetXaxis()->SetTitle(axtitle);
858  fNorm_perfstat_evtmax->SetMarkerStyle(23);
859  fNorm_perfstat_evtmax->SetMarkerColor(2);
860  if ((o = fListPerfPlots->FindObject(name))) {
861  fListPerfPlots->Remove(o);
862  delete o;
863  }
864  fListPerfPlots->Add(fNorm_perfstat_evtmax);
865  fNormLegend_evt->AddEntry(fNorm_perfstat_evtmax, "Maximum");
866 
867  // Book queryresult profile (evts)
868  name.Form("Prof_%s_QR_Evts_%s", namelab.Data(), sellab.Data());
869  title.Form("Profile %s QueryResult Event - %s", namelab.Data(), sellab.Data());
870  fProfile_queryresult_event = new TProfile(name, title, ndiv, ns_min, ns_max);
871  fProfile_queryresult_event->SetDirectory(fDirProofBench);
872  fProfile_queryresult_event->GetYaxis()->SetTitle("Events/sec");
873  fProfile_queryresult_event->GetXaxis()->SetTitle(axtitle);
874  fProfile_queryresult_event->SetMarkerStyle(22);
875  if ((o = fListPerfPlots->FindObject(name))) {
876  fListPerfPlots->Remove(o);
877  delete o;
878  }
879  fListPerfPlots->Add(fProfile_queryresult_event);
880  fProfLegend_evt->AddEntry(fProfile_queryresult_event, "Average");
881 
882  // Book normalized queryresult profile (evts)
883  name.Form("Norm_%s_QR_Evts_%s", namelab.Data(), sellab.Data());
884  title.Form("Profile %s Normalized QueryResult Event - %s", namelab.Data(), sellab.Data());
885  fNorm_queryresult_event = new TProfile(name, title, ndiv, ns_min, ns_max);
886  fNorm_queryresult_event->SetDirectory(fDirProofBench);
887  fNorm_queryresult_event->GetYaxis()->SetTitle("Events/sec");
888  fNorm_queryresult_event->GetXaxis()->SetTitle(axtitle);
889  fNorm_queryresult_event->SetMarkerStyle(22);
890  if ((o = fListPerfPlots->FindObject(name))) {
891  fListPerfPlots->Remove(o);
892  delete o;
893  }
894  fListPerfPlots->Add(fNorm_queryresult_event);
895  fNormLegend_evt->AddEntry(fNorm_queryresult_event, "Average");
896 
897  // Book perfstat profile (mbs)
898  name.Form("Prof_%s_PS_IO_%s", namelab.Data(), sellab.Data());
899  title.Form("Profile %s PerfStat I/O %s", namelab.Data(), sellab.Data());
900  fProfile_perfstat_IO = new TProfile(name, title, ndiv, ns_min, ns_max);
901  fProfile_perfstat_IO->SetDirectory(fDirProofBench);
902  fProfile_perfstat_IO->GetYaxis()->SetTitle("MB/sec");
903  fProfile_perfstat_IO->GetXaxis()->SetTitle(axtitle);
904  fProfile_perfstat_IO->SetMarkerStyle(21);
905  if ((o = fListPerfPlots->FindObject(name))) {
906  fListPerfPlots->Remove(o);
907  delete o;
908  }
909  fListPerfPlots->Add(fProfile_perfstat_IO);
910 
911  // Book perfstat histogram (mbs)
912  name.Form("Hist_%s_PS_IO_%s", namelab.Data(), sellab.Data());
913  title.Form("Histogram %s PerfStat I/O - %s", namelab.Data(), sellab.Data());
914  fHist_perfstat_IO = new TH2D(name, title, ndiv, ns_min, ns_max, 100, 0, 0);
915  fHist_perfstat_IO->SetDirectory(fDirProofBench);
916  fHist_perfstat_IO->GetYaxis()->SetTitle("MB/sec");
917  fHist_perfstat_IO->GetXaxis()->SetTitle(axtitle);
918  fHist_perfstat_IO->SetMarkerStyle(7);
919  if ((o = fListPerfPlots->FindObject(name))) {
920  fListPerfPlots->Remove(o);
921  delete o;
922  }
923  fListPerfPlots->Add(fHist_perfstat_IO);
924 
925  // Book perfstat profile (max mbs)
926  name.Form("Prof_%s_PS_MaxIO_%s", namelab.Data(), sellab.Data());
927  title.Form("Profile %s PerfStat I/O - %s", namelab.Data(), sellab.Data());
928  fProfile_perfstat_IOmax = new TProfile(name, title, ndiv, ns_min, ns_max);
929  fProfile_perfstat_IOmax->SetDirectory(fDirProofBench);
930  fProfile_perfstat_IOmax->GetYaxis()->SetTitle("MB/sec");
931  fProfile_perfstat_IOmax->GetXaxis()->SetTitle(axtitle);
932  fProfile_perfstat_IOmax->SetMarkerStyle(21);
933  fProfile_perfstat_IOmax->SetMarkerColor(2);
934  if ((o = fListPerfPlots->FindObject(name))) {
935  fListPerfPlots->Remove(o);
936  delete o;
937  }
938  fListPerfPlots->Add(fProfile_perfstat_IOmax);
939  fProfLegend_mb->AddEntry(fProfile_perfstat_IOmax, "Maximum");
940 
941  // Book normalized perfstat profile (max mbs)
942  name.Form("Norm_%s_PS_MaxIO_%s", namelab.Data(), sellab.Data());
943  title.Form("Profile %s Normalized PerfStat I/O - %s", namelab.Data(), sellab.Data());
944  fNorm_perfstat_IOmax = new TProfile(name, title, ndiv, ns_min, ns_max);
945  fNorm_perfstat_IOmax->SetDirectory(fDirProofBench);
946  fNorm_perfstat_IOmax->GetYaxis()->SetTitle("MB/sec");
947  fNorm_perfstat_IOmax->GetXaxis()->SetTitle(axtitle);
948  fNorm_perfstat_IOmax->SetMarkerStyle(23);
949  fNorm_perfstat_IOmax->SetMarkerColor(2);
950  if ((o = fListPerfPlots->FindObject(name))) {
951  fListPerfPlots->Remove(o);
952  delete o;
953  }
954  fListPerfPlots->Add(fNorm_perfstat_IOmax);
955  fNormLegend_mb->AddEntry(fNorm_perfstat_IOmax, "Maximum");
956 
957  // Book queryresult profile (mbs)
958  name.Form("Prof_%s_QR_IO_%s", namelab.Data(), sellab.Data());
959  title.Form("Profile %s QueryResult I/O - %s", namelab.Data(), sellab.Data());
960  fProfile_queryresult_IO = new TProfile(name, title, ndiv, ns_min, ns_max);
961  fProfile_queryresult_IO->SetDirectory(fDirProofBench);
962  fProfile_queryresult_IO->GetYaxis()->SetTitle("MB/sec");
963  fProfile_queryresult_IO->GetXaxis()->SetTitle(axtitle);
964  fProfile_queryresult_IO->SetMarkerStyle(22);
965  if ((o = fListPerfPlots->FindObject(name))) {
966  fListPerfPlots->Remove(o);
967  delete o;
968  }
969  fListPerfPlots->Add(fProfile_queryresult_IO);
970  fProfLegend_mb->AddEntry(fProfile_queryresult_IO, "Average");
971 
972  // Book normalized queryresult profile (mbs)
973  name.Form("Norm_%s_QR_IO_%s", namelab.Data(), sellab.Data());
974  title.Form("Profile %s Normalized QueryResult I/O - %s", namelab.Data(), sellab.Data());
975  fNorm_queryresult_IO = new TProfile(name, title, ndiv, ns_min, ns_max);
976  fNorm_queryresult_IO->SetDirectory(fDirProofBench);
977  fNorm_queryresult_IO->GetYaxis()->SetTitle("MB/sec");
978  fNorm_queryresult_IO->GetXaxis()->SetTitle(axtitle);
979  fNorm_queryresult_IO->SetMarkerStyle(22);
980  if ((o = fListPerfPlots->FindObject(name))) {
981  fListPerfPlots->Remove(o);
982  delete o;
983  }
984  fListPerfPlots->Add(fNorm_queryresult_IO);
985  fNormLegend_mb->AddEntry(fNorm_queryresult_IO, "Average");
986 
987  // Book CPU efficiency profile
988  name.Form("Prof_%s_CPU_eff_%s", namelab.Data(), sellab.Data());
989  title.Form("Profile %s CPU efficiency - %s", namelab.Data(), sellab.Data());
990  fProfile_cpu_eff = new TProfile(name, title, ndiv, ns_min, ns_max);
991  fProfile_cpu_eff->SetDirectory(fDirProofBench);
992  fProfile_cpu_eff->GetYaxis()->SetTitle("Efficiency");
993  fProfile_cpu_eff->GetXaxis()->SetTitle(axtitle);
994  fProfile_cpu_eff->SetMarkerStyle(22);
995  if ((o = fListPerfPlots->FindObject(name))) {
996  fListPerfPlots->Remove(o);
997  delete o;
998  }
999  fListPerfPlots->Add(fProfile_cpu_eff);
1000 }