Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TProofBenchRunCPU.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 TProofBenchRunCPU
13 \ingroup proofbench
14 
15 CPU-intensive PROOF benchmark test generates events and fill 1, 2, or 3-D histograms.
16 No I/O activity is involved.
17 
18 */
19 
20 #include "RConfigure.h"
21 
22 #include "TProofBenchRunCPU.h"
23 #include "TProofNodes.h"
24 #include "TProofPerfAnalysis.h"
25 #include "TFileCollection.h"
26 #include "TFileInfo.h"
27 #include "TProof.h"
28 #include "TString.h"
29 #include "Riostream.h"
30 #include "TMap.h"
31 #include "TEnv.h"
32 #include "TTree.h"
33 #include "TLeaf.h"
34 #include "TCanvas.h"
35 #include "TROOT.h"
36 #include "TH2.h"
37 #include "TF1.h"
38 #include "TProfile.h"
39 #include "TLegend.h"
40 #include "TKey.h"
41 #include "TRegexp.h"
42 #include "TPerfStats.h"
43 #include "TQueryResult.h"
44 #include "TMath.h"
45 #include "TStyle.h"
46 #include "TProofNodes.h"
47 #include "TGraphErrors.h"
48 #include "TLegend.h"
49 
50 ClassImp(TProofBenchRunCPU);
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 /// Default constructor
54 
55 TProofBenchRunCPU::TProofBenchRunCPU(TPBHistType *histtype, Int_t nhists,
56  TDirectory* dirproofbench, TProof* proof,
57  TProofNodes* nodes, Long64_t nevents, Int_t ntries,
58  Int_t start, Int_t stop, Int_t step, Int_t draw,
59  Int_t debug)
60  : TProofBenchRun(proof, kPROOF_BenchSelCPUDef),
61  fHistType(histtype), fNHists(nhists),
62  fNEvents(nevents), fNTries(ntries), fStart(start), fStop(stop),
63  fStep(step), fDraw(draw), fDebug(debug), fDirProofBench(dirproofbench),
64  fNodes(nodes), fListPerfPlots(0),
65  fCanvas(0), fProfile_perfstat_event(0), fHist_perfstat_event(0),
66  fProfile_perfstat_evtmax(0), fNorm_perfstat_evtmax(0),
67  fProfile_queryresult_event(0), fNorm_queryresult_event(0), fProfile_cpu_eff(0),
68  fProfLegend(0), fNormLegend(0), fName(0)
69 {
70  if (TestBit(kInvalidObject)) {
71  Error("TProofBenchRunCPU", "problems validating PROOF session or enabling selector PAR");
72  return;
73  }
74 
75  fName = "CPU";
76 
77  if (!fNodes) fNodes = new TProofNodes(fProof);
78 
79  if (stop == -1) fStop = fNodes->GetNWorkersCluster();
80 
81  fListPerfPlots = new TList;
82 
83  gEnv->SetValue("Proof.StatsTrace",1);
84  gStyle->SetOptStat(0);
85 }
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 /// Destructor
89 
90 TProofBenchRunCPU::~TProofBenchRunCPU()
91 {
92  fProof=0;
93  fDirProofBench=0;
94  SafeDelete(fListPerfPlots);
95  SafeDelete(fCanvas);
96  SafeDelete(fNodes);
97  SafeDelete(fProfLegend);
98  SafeDelete(fNormLegend);
99 }
100 
101 ////////////////////////////////////////////////////////////////////////////////
102 /// Build histograms, profiles and graphs needed for this run
103 
104 void TProofBenchRunCPU::BuildHistos(Int_t start, Int_t stop, Int_t step, Bool_t nx)
105 {
106  TObject *o = 0;
107  Int_t quotient = (stop - start) / step;
108  Int_t ndiv = quotient + 1;
109  Double_t ns_min = start - step/2.;
110  Double_t ns_max = quotient*step + start + step/2.;
111 
112  fProfLegend = new TLegend(0.1, 0.8, 0.3, 0.9);
113  fNormLegend = new TLegend(0.7, 0.8, 0.9, 0.9);
114 
115  TString axtitle("Active Workers"), namelab(GetName()), sellab(GetSelName());
116  if (nx) {
117  axtitle = "Active Workers/Node";
118  namelab.Form("x_%s", GetName());
119  }
120  if (fSelName == kPROOF_BenchSelCPUDef)
121  sellab.Form("%s_%s", GetSelName(), GetNameStem().Data());
122 
123  TString name, title;
124 
125  // Book perfstat profile (max evts)
126  name.Form("Prof_%s_PS_MaxEvts_%s", namelab.Data(), sellab.Data());
127  title.Form("Profile %s PerfStat Event - %s", namelab.Data(), sellab.Data());
128  fProfile_perfstat_evtmax = new TProfile(name, title, ndiv, ns_min, ns_max);
129  fProfile_perfstat_evtmax->SetDirectory(fDirProofBench);
130  fProfile_perfstat_evtmax->GetYaxis()->SetTitle("Events/sec");
131  fProfile_perfstat_evtmax->GetXaxis()->SetTitle(axtitle);
132  fProfile_perfstat_evtmax->SetMarkerStyle(23);
133  fProfile_perfstat_evtmax->SetMarkerColor(2);
134  if ((o = fListPerfPlots->FindObject(name))) {
135  fListPerfPlots->Remove(o);
136  delete o;
137  }
138  fListPerfPlots->Add(fProfile_perfstat_evtmax);
139  fProfLegend->AddEntry(fProfile_perfstat_evtmax, "Maximum");
140 
141  // Book perfstat profile
142  name.Form("Prof_%s_PS_Evts_%s", namelab.Data(), sellab.Data());
143  title.Form("Profile %s PerfStat Event - %s", namelab.Data(), sellab.Data());
144  fProfile_perfstat_event = new TProfile(name, title, ndiv, ns_min, ns_max);
145  fProfile_perfstat_event->SetDirectory(fDirProofBench);
146  fProfile_perfstat_event->GetYaxis()->SetTitle("Events/sec");
147  fProfile_perfstat_event->GetXaxis()->SetTitle(axtitle);
148  fProfile_perfstat_event->SetMarkerStyle(21);
149  if ((o = fListPerfPlots->FindObject(name))) {
150  fListPerfPlots->Remove(o);
151  delete o;
152  }
153  fListPerfPlots->Add(fProfile_perfstat_event);
154  fProfLegend->AddEntry(fProfile_perfstat_event, "Average");
155 
156  // Book perfstat histogram
157  name.Form("Hist_%s_PS_Evts_%s", namelab.Data(), sellab.Data());
158  title.Form("Histogram %s PerfStat Event - %s", namelab.Data(), sellab.Data());
159  fHist_perfstat_event = new TH2D(name, title, ndiv, ns_min, ns_max, 100, 0, 0);
160  fHist_perfstat_event->SetDirectory(fDirProofBench);
161  fHist_perfstat_event->GetYaxis()->SetTitle("Events/sec");
162  fHist_perfstat_event->GetXaxis()->SetTitle(axtitle);
163  fHist_perfstat_event->SetMarkerStyle(7);
164  if ((o = fListPerfPlots->FindObject(name))) {
165  fListPerfPlots->Remove(o);
166  delete o;
167  }
168  fListPerfPlots->Add(fHist_perfstat_event);
169 
170  // Book normalized perfstat profile (max evts)
171  name.Form("Norm_%s_PS_MaxEvts_%s", namelab.Data(), sellab.Data());
172  title.Form("Profile %s Normalized PerfStat Event - %s", namelab.Data(), sellab.Data());
173  fNorm_perfstat_evtmax = new TProfile(name, title, ndiv, ns_min, ns_max);
174  fNorm_perfstat_evtmax->SetDirectory(fDirProofBench);
175  fNorm_perfstat_evtmax->GetYaxis()->SetTitle("Events/sec");
176  fNorm_perfstat_evtmax->GetXaxis()->SetTitle(axtitle);
177  fNorm_perfstat_evtmax->SetMarkerStyle(23);
178  fNorm_perfstat_evtmax->SetMarkerColor(2);
179  if ((o = fListPerfPlots->FindObject(name))) {
180  fListPerfPlots->Remove(o);
181  delete o;
182  }
183  fListPerfPlots->Add(fNorm_perfstat_evtmax);
184  fNormLegend->AddEntry(fNorm_perfstat_evtmax, "Maximum");
185 
186  // Book queryresult profile
187  name.Form("Prof_%s_QR_Evts_%s", namelab.Data(), sellab.Data());
188  title.Form("Profile %s QueryResult Event - %s", namelab.Data(), sellab.Data());
189  fProfile_queryresult_event = new TProfile(name, title, ndiv, ns_min, ns_max);
190  fProfile_queryresult_event->SetDirectory(fDirProofBench);
191  fProfile_queryresult_event->GetYaxis()->SetTitle("Events/sec");
192  fProfile_queryresult_event->GetXaxis()->SetTitle(axtitle);
193  fProfile_queryresult_event->SetMarkerStyle(22);
194  if ((o = fListPerfPlots->FindObject(name))) {
195  fListPerfPlots->Remove(o);
196  delete o;
197  }
198  fListPerfPlots->Add(fProfile_queryresult_event);
199 
200  // Book normalized queryresult profile
201  name.Form("Norm_%s_QR_Evts_%s", namelab.Data(), sellab.Data());
202  title.Form("Profile %s Normalized QueryResult Event - %s", namelab.Data(), sellab.Data());
203  fNorm_queryresult_event = new TProfile(name, title, ndiv, ns_min, ns_max);
204  fNorm_queryresult_event->SetDirectory(fDirProofBench);
205  fNorm_queryresult_event->GetYaxis()->SetTitle("Events/sec");
206  fNorm_queryresult_event->GetXaxis()->SetTitle(axtitle);
207  fNorm_queryresult_event->SetMarkerStyle(22);
208  if ((o = fListPerfPlots->FindObject(name))) {
209  fListPerfPlots->Remove(o);
210  delete o;
211  }
212  fListPerfPlots->Add(fNorm_queryresult_event);
213  fNormLegend->AddEntry(fNorm_queryresult_event, "Average");
214 
215  // Book CPU efficiency profile
216  name.Form("Prof_%s_CPU_eff_%s", namelab.Data(), sellab.Data());
217  title.Form("Profile %s CPU efficiency - %s", namelab.Data(), sellab.Data());
218  fProfile_cpu_eff = new TProfile(name, title, ndiv, ns_min, ns_max);
219  fProfile_cpu_eff->SetDirectory(fDirProofBench);
220  fProfile_cpu_eff->GetYaxis()->SetTitle("Efficiency");
221  fProfile_cpu_eff->GetXaxis()->SetTitle(axtitle);
222  fProfile_cpu_eff->SetMarkerStyle(22);
223  if ((o = fListPerfPlots->FindObject(name))) {
224  fListPerfPlots->Remove(o);
225  delete o;
226  }
227  fListPerfPlots->Add(fProfile_cpu_eff);
228 }
229 
230 ////////////////////////////////////////////////////////////////////////////////
231 /// Run benchmark
232 /// Input parameters
233 /// nevents: Number of events to run per file. When it is -1, use data member fNEvents.
234 /// start: Start scan with 'start' workers. When it is -1, use data member fStart.
235 /// When 0, the same number of workers are activated on all nodes.
236 /// stop: Stop scan at 'stop' workers. When it is -1 , use data member fStop.
237 /// step: Scan every 'step' workers. When it is -1, use data member fStep.
238 /// ntries: Number of repetitions. When it is -1, use data member fNTries.
239 /// debug: debug switch. When it is -1, use data member fDebug.
240 /// draw: draw switch. When it is -1, use data member fDraw.
241 /// Returns
242 /// Nothing
243 
244 void TProofBenchRunCPU::Run(Long64_t nevents, Int_t start, Int_t stop,
245  Int_t step, Int_t ntries, Int_t debug, Int_t draw)
246 {
247  if (!fProof){
248  Error("Run", "Proof not set");
249  return;
250  }
251 
252  nevents = (nevents == -1) ? fNEvents : nevents;
253  start = (start == -1) ? fStart : start;
254  stop = (stop == -1) ? fStop : stop;
255  step = (step == -1) ? fStep : step;
256  ntries = (ntries == -1) ? fNTries : ntries;
257  debug = (debug == -1) ? fDebug : debug;
258  draw = (draw == -1) ? fDraw : draw;
259 
260  Bool_t nx = kFALSE;
261  if (step == -2){
262  nx = kTRUE;
263  start = fStart;
264  step = 1;
265  }
266 
267  if (nx){
268  Int_t minnworkersanode = fNodes->GetMinWrksPerNode();
269  if (stop > minnworkersanode) stop = minnworkersanode;
270  }
271 
272  // Load the selector, if needed
273  if (!TClass::GetClass(fSelName)) {
274  // Is it the default selector?
275  if (fSelName == kPROOF_BenchSelCPUDef) {
276  // Load the parfile
277  TString par = TString::Format("%s/%s%s.par", TROOT::GetEtcDir().Data(), kPROOF_BenchParDir, kPROOF_BenchCPUSelPar);
278  Info("Run", "Uploading '%s' ...", par.Data());
279  if (fProof->UploadPackage(par) != 0) {
280  Error("Run", "problems uploading '%s' - cannot continue", par.Data());
281  return;
282  }
283  Info("Run", "Enabling '%s' ...", kPROOF_BenchCPUSelPar);
284  if (fProof->EnablePackage(kPROOF_BenchCPUSelPar) != 0) {
285  Error("Run", "problems enabling '%s' - cannot continue", kPROOF_BenchCPUSelPar);
286  return;
287  }
288  } else {
289  if (fParList.IsNull()) {
290  Error("Run", "you should load the class '%s' before running the benchmark", fSelName.Data());
291  return;
292  } else {
293  TString par;
294  Int_t from = 0;
295  while (fParList.Tokenize(par, from, ",")) {
296  Info("Run", "Uploading '%s' ...", par.Data());
297  if (fProof->UploadPackage(par) != 0) {
298  Error("Run", "problems uploading '%s' - cannot continue", par.Data());
299  return;
300  }
301  Info("Run", "Enabling '%s' ...", par.Data());
302  if (fProof->EnablePackage(par) != 0) {
303  Error("Run", "problems enabling '%s' - cannot continue", par.Data());
304  return;
305  }
306  }
307  }
308  }
309  // Check
310  if (!TClass::GetClass(fSelName)) {
311  Error("Run", "failed to load '%s'", fSelName.Data());
312  return;
313  }
314  }
315 
316  // Build histograms, profiles and graphs needed for this run
317  BuildHistos(start, stop, step, nx);
318 
319  // Get pad
320  if (!fCanvas) fCanvas = new TCanvas("Canvas");
321  // Cleanup up the canvas
322  fCanvas->Clear();
323 
324  // Divide the canvas as many as the number of profiles in the list
325  fCanvas->Divide(2,1);
326 
327  TString perfstats_name = "PROOF_PerfStats";
328 
329  SetParameters();
330 
331  if (nx){
332  Info("Run", "Running CPU-bound tests; %d ~ %d active worker(s)/node,"
333  " every %d worker(s)/node.", start, stop, step);
334  } else {
335  Info("Run", "Running CPU-bound tests; %d ~ %d active worker(s),"
336  " every %d worker(s).", start, stop, step);
337  }
338 
339  Int_t npad = 1; //pad number
340 
341  Int_t nnodes = fNodes->GetNNodes(); // Number of machines
342  Int_t ncores = fNodes->GetNCores(); // Number of cores
343 
344  Double_t ymi = -1., ymx = -1., emx = -1.;
345  for (Int_t nactive = start; nactive <= stop; nactive += step) {
346 
347  // For CPU effectiveness (ok for lite; should do it properly for standard clusters)
348  Int_t ncoren = (nactive < ncores) ? nactive : ncores;
349 
350  // Actvate the wanted workers
351  Int_t nw = -1;
352  if (nx) {
353  TString workers;
354  workers.Form("%dx", nactive);
355  nw = fNodes->ActivateWorkers(workers);
356  } else {
357  nw = fNodes->ActivateWorkers(nactive);
358  }
359  if (nw < 0){
360  Error("Run", "could not activate the requested number of"
361  " workers/node on the cluster; skipping the test point"
362  " (%d workers/node)", nactive);
363  continue;
364  }
365 
366  for (Int_t j = 0; j < ntries; j++) {
367 
368  if (nx){
369  Info("Run", "Running CPU-bound tests with %d active worker(s)/node;"
370  " trial %d/%d", nactive, j + 1, ntries);
371  } else {
372  Info("Run", "Running CPU-bound tests with %d active worker(s);"
373  " trial %d/%d", nactive, j + 1, ntries);
374  }
375 
376  Int_t nevents_all=0;
377  if (nx){
378  nevents_all=nevents*nactive*nnodes;
379  } else {
380  nevents_all=nevents*nactive;
381  }
382 
383  // Process
384  fProof->Process(fSelName, nevents_all, fSelOption);
385 
386  TList *l = fProof->GetOutputList();
387 
388  // Save perfstats
389  TTree *t = 0;
390  if (l) t = dynamic_cast<TTree*>(l->FindObject(perfstats_name.Data()));
391  if (t) {
392 
393  //FillPerfStatPerfPlots(t, profile_perfstat_event, nactive);
394  FillPerfStatPerfPlots(t, nactive);
395 
396  TProofPerfAnalysis pfa(t);
397  Double_t pf_eventrate = pfa.GetEvtRateAvgMax();
398 // if (pf_eventrate > emx) emx = pf_eventrate;
399  fProfile_perfstat_evtmax->Fill(nactive, pf_eventrate);
400  fCanvas->cd(npad);
401  fProfile_perfstat_evtmax->SetMaximum(emx*1.6);
402  fProfile_perfstat_evtmax->SetMinimum(0.);
403  fProfile_perfstat_evtmax->Draw("L");
404  fProfLegend->Draw();
405  gPad->Update();
406  // The normalised histos
407  // Use the first bin to set the Y range for the histo
408  Double_t nert = nx ? pf_eventrate/nactive/nnodes : pf_eventrate/nactive;
409  fNorm_perfstat_evtmax->Fill(nactive, nert);
410  Double_t y1 = fNorm_perfstat_evtmax->GetBinContent(1);
411  Double_t e1 = fNorm_perfstat_evtmax->GetBinError(1);
412  Double_t dy = 5 * e1;
413  if (dy / y1 < 0.2) dy = y1 * 0.2;
414  if (dy > y1) dy = y1*.999999;
415  if (ymi < 0.) ymi = y1 - dy;
416  if (fNorm_perfstat_evtmax->GetBinContent(nactive) < ymi)
417  ymi = fNorm_perfstat_evtmax->GetBinContent(nactive) / 2.;
418  if (ymx < 0.) ymx = y1 + dy;
419  if (fNorm_perfstat_evtmax->GetBinContent(nactive) > ymx)
420  ymx = fNorm_perfstat_evtmax->GetBinContent(nactive) * 1.5;
421  fNorm_perfstat_evtmax->SetMaximum(ymx);
422  fNorm_perfstat_evtmax->SetMinimum(ymi);
423  fCanvas->cd(npad + 1);
424  fNorm_perfstat_evtmax->Draw("L");
425  fNormLegend->Draw();
426  gPad->Update();
427 
428  // Build up new name
429  TString newname = TString::Format("%s_%s_%dwrks%dthtry", t->GetName(), GetName(), nactive, j);
430  t->SetName(newname);
431 
432  if (debug && fDirProofBench->IsWritable()){
433  TDirectory *curdir = gDirectory;
434  TString dirn = nx ? "RunCPUx" : "RunCPU";
435  if (!fDirProofBench->GetDirectory(dirn))
436  fDirProofBench->mkdir(dirn, "RunCPU results");
437  if (fDirProofBench->cd(dirn)) {
438  t->SetDirectory(fDirProofBench);
439  t->Write();
440  l->Remove(t);
441  } else {
442  Warning("Run", "cannot cd to subdirectory '%s' to store the results!", dirn.Data());
443  }
444  curdir->cd();
445  }
446 
447  } else {
448  if (l)
449  Warning("Run", "%s: tree not found", perfstats_name.Data());
450  else
451  Error("Run", "PROOF output list is empty!");
452  }
453 
454  // Performance measures from TQueryResult
455 
456  const char *drawopt = t ? "LSAME" : "L";
457  TQueryResult *queryresult = fProof->GetQueryResult();
458  if (queryresult) {
459  queryresult->Print("F");
460  TDatime qr_start = queryresult->GetStartTime();
461  TDatime qr_end = queryresult->GetEndTime();
462  Float_t qr_proc = queryresult->GetProcTime();
463 
464  Long64_t qr_entries = queryresult->GetEntries();
465 
466  // Calculate event rate
467  Double_t qr_eventrate = qr_entries / Double_t(qr_proc);
468  if (qr_eventrate > emx) emx = qr_eventrate;
469 
470  // Calculate and fill CPU efficiency
471  Float_t qr_cpu_eff = -1.;
472  if (qr_proc > 0.) {
473  qr_cpu_eff = queryresult->GetUsedCPU() / ncoren / qr_proc ;
474  fProfile_cpu_eff->Fill(nactive, qr_cpu_eff);
475  Printf("cpu_eff: %f", qr_cpu_eff);
476  }
477 
478  // Fill and draw
479  fProfile_queryresult_event->Fill(nactive, qr_eventrate);
480  fCanvas->cd(npad);
481  fProfile_queryresult_event->Draw(drawopt);
482  fProfLegend->Draw();
483  gPad->Update();
484  // The normalised histo
485  Double_t nert = nx ? qr_eventrate/nactive/nnodes : qr_eventrate/nactive;
486  fNorm_queryresult_event->Fill(nactive, nert);
487  // Use the first bin to set the Y range for the histo
488  Double_t y1 = fNorm_queryresult_event->GetBinContent(1);
489  Double_t e1 = fNorm_queryresult_event->GetBinError(1);
490  Double_t dy = 5 * e1;
491  if (dy / y1 < 0.2) dy = y1 * 0.2;
492  if (dy > y1) dy = y1*.999999;
493  if (ymi < 0.) ymi = y1 - dy;
494  if (fNorm_queryresult_event->GetBinContent(nactive) < ymi)
495  ymi = fNorm_queryresult_event->GetBinContent(nactive) / 2.;
496  if (ymx < 0.) ymx = y1 + dy;
497  if (fNorm_queryresult_event->GetBinContent(nactive) > ymx)
498  ymx = fNorm_queryresult_event->GetBinContent(nactive) * 1.5;
499  fNorm_queryresult_event->SetMaximum(ymx);
500 // fNorm_queryresult_event->SetMinimum(ymi);
501  fNorm_queryresult_event->SetMinimum(0.);
502  fCanvas->cd(npad+1);
503  fNorm_queryresult_event->Draw(drawopt);
504  fNormLegend->Draw();
505  } else {
506  Warning("Run", "TQueryResult not found!");
507  }
508  gPad->Update();
509 
510  } // for iterations
511  } // for number of workers
512 
513  // Make the result persistent
514  fCanvas->cd(npad);
515  fProfile_queryresult_event->SetMaximum(1.6*emx);
516  fProfile_queryresult_event->DrawCopy("L");
517  fProfile_perfstat_evtmax->DrawCopy("LSAME");
518  fProfLegend->Draw();
519  fCanvas->cd(npad + 1);
520  fNorm_queryresult_event->DrawCopy("L");
521  fNorm_perfstat_evtmax->DrawCopy("LSAME");
522  fNormLegend->Draw();
523  gPad->Update();
524 
525  //save performance profiles to file
526  if (fDirProofBench && fDirProofBench->IsWritable()){
527  TDirectory *curdir = gDirectory;
528  TString dirn = nx ? "RunCPUx" : "RunCPU";
529  if (!fDirProofBench->GetDirectory(dirn))
530  fDirProofBench->mkdir(dirn, "RunCPU results");
531  if (fDirProofBench->cd(dirn)) {
532  fListPerfPlots->Write(0, kOverwrite);
533  fListPerfPlots->SetOwner(kFALSE);
534  fListPerfPlots->Clear();
535  } else {
536  Warning("Run", "cannot cd to subdirectory '%s' to store the results!", dirn.Data());
537  }
538  curdir->cd();
539  }
540 }
541 
542 ////////////////////////////////////////////////////////////////////////////////
543 
544 void TProofBenchRunCPU::FillPerfStatPerfPlots(TTree* t, Int_t nactive)
545 {
546  // Fill performance profiles using tree 't'(PROOF_PerfStats).
547  // Input parameters
548  // t: Proof output tree (PROOF_PerfStat) containing performance statistics.
549  // profile: Profile to be filled up with information from tree 't'.
550  // nactive: Number of active workers processed the query.
551  // Return
552  // Nothing
553 
554  // find perfstat profile
555  if (!fProfile_perfstat_event){
556  Error("FillPerfStatPerfPlots", "no perfstat profile found");
557  return;
558  }
559 
560  // find perfstat histogram
561  if (!fHist_perfstat_event){
562  Error("FillPerfStatPerfPlots", "no perfstat histogram found");
563  return;
564  }
565 
566  // extract timing information
567  TPerfEvent pe;
568  TPerfEvent* pep = &pe;
569  t->SetBranchAddress("PerfEvents",&pep);
570  Long64_t entries = t->GetEntries();
571 
572  Double_t event_rate_packet = 0;
573 
574  for (Long64_t k=0; k<entries; k++) {
575 
576  t->GetEntry(k);
577 
578  // Skip information from workers
579  if (pe.fEvtNode.Contains(".")) continue;
580 
581  if (pe.fType == TVirtualPerfStats::kPacket){
582  if (pe.fProcTime != 0.0) {
583  event_rate_packet = pe.fEventsProcessed / pe.fProcTime;
584  fHist_perfstat_event->Fill(Double_t(nactive), event_rate_packet);
585  }
586  }
587  }
588 
589  return;
590 }
591 
592 ////////////////////////////////////////////////////////////////////////////////
593 /// Show settings
594 
595 void TProofBenchRunCPU::Print(Option_t* option) const
596 {
597  Printf("+++ TProofBenchRunCPU +++++++++++++++++++++++++++++++++++++++++");
598  Printf("Name = %s", fName.Data());
599  if (fProof) fProof->Print(option);
600  Printf("fHistType = k%s", GetNameStem().Data());
601  Printf("fNHists = %d", fNHists);
602  Printf("fNEvents = %lld", fNEvents);
603  Printf("fNTries = %d", fNTries);
604  Printf("fStart = %d", fStart);
605  Printf("fStop = %d", fStop);
606  Printf("fStep = %d", fStep);
607  Printf("fDraw = %d", fDraw);
608  Printf("fDebug = %d", fDebug);
609  if (fDirProofBench)
610  Printf("fDirProofBench = %s", fDirProofBench->GetPath());
611  if (fNodes) fNodes->Print(option);
612  if (fListPerfPlots) fListPerfPlots->Print(option);
613  if (fCanvas)
614  Printf("Performance Canvas: Name = %s Title = %s",
615  fCanvas->GetName(), fCanvas->GetTitle());
616  Printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
617 }
618 
619 ////////////////////////////////////////////////////////////////////////////////
620 /// Draw Performance plots
621 
622 void TProofBenchRunCPU::DrawPerfPlots()
623 {
624  // Get canvas
625  if (!fCanvas) fCanvas = new TCanvas("Canvas");
626 
627  fCanvas->Clear();
628 
629  // Divide the canvas as many as the number of profiles in the list
630  Int_t nprofiles = fListPerfPlots->GetSize();
631  if (nprofiles <= 2){
632  fCanvas->Divide(1,nprofiles);
633  } else {
634  Int_t nside = (Int_t)TMath::Sqrt((Float_t)nprofiles);
635  nside = (nside*nside<nprofiles)?nside+1:nside;
636  fCanvas->Divide(nside,nside);
637  }
638 
639  Int_t npad=1;
640  TIter nxt(fListPerfPlots);
641  TProfile* profile=0;
642  while ((profile=(TProfile*)(nxt()))){
643  fCanvas->cd(npad++);
644  profile->Draw();
645  gPad->Update();
646  }
647  return;
648 }
649 
650 ////////////////////////////////////////////////////////////////////////////////
651 /// Set histogram type
652 
653 void TProofBenchRunCPU::SetHistType(TPBHistType *histtype)
654 {
655  fHistType = histtype;
656  fName.Form("%sCPU", GetNameStem().Data());
657 }
658 
659 ////////////////////////////////////////////////////////////////////////////////
660 /// Get name for this run
661 
662 TString TProofBenchRunCPU::GetNameStem() const
663 {
664  TString namestem("+++undef+++");
665  if (fHistType) {
666  switch (fHistType->GetType()) {
667  case TPBHistType::kHist1D:
668  namestem = "Hist1D";
669  break;
670  case TPBHistType::kHist2D:
671  namestem = "Hist2D";
672  break;
673  case TPBHistType::kHist3D:
674  namestem = "Hist3D";
675  break;
676  case TPBHistType::kHistAll:
677  namestem = "HistAll";
678  break;
679  default:
680  break;
681  }
682  }
683  return namestem;
684 }
685 
686 ////////////////////////////////////////////////////////////////////////////////
687 /// Set parameters
688 
689 Int_t TProofBenchRunCPU::SetParameters()
690 {
691  if (!fProof) {
692  Error("SetParameters", "proof not set; Doing nothing");
693  return 1;
694  }
695 
696  if (!fHistType) fHistType = new TPBHistType(TPBHistType::kHist1D);
697  fProof->AddInput(fHistType);
698  fProof->SetParameter("PROOF_BenchmarkNHists", fNHists);
699  fProof->SetParameter("PROOF_BenchmarkDraw", Int_t(fDraw));
700  return 0;
701 }
702 
703 ////////////////////////////////////////////////////////////////////////////////
704 /// Delete parameters set for this run
705 
706 Int_t TProofBenchRunCPU::DeleteParameters()
707 {
708  if (!fProof){
709  Error("DeleteParameters", "proof not set; Doing nothing");
710  return 1;
711  }
712  if (fProof->GetInputList()) {
713  TObject *type = fProof->GetInputList()->FindObject("PROOF_Benchmark_HistType");
714  if (type) fProof->GetInputList()->Remove(type);
715  }
716  fProof->DeleteParameters("PROOF_BenchmarkNHists");
717  fProof->DeleteParameters("PROOF_BenchmarkDraw");
718  return 0;
719 }
720