All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
SequencerTimerTool.cpp
Go to the documentation of this file.
1 // Include files
2 
3 // From ROOT
4 #include "TH1D.h"
5 
6 // from Gaudi
7 #include "GaudiKernel/RndmGenerators.h"
8 #include "GaudiKernel/IRndmGenSvc.h"
9 #include "GaudiUtils/Aida2ROOT.h"
10 
11 // local
12 #include "SequencerTimerTool.h"
13 
14 //-----------------------------------------------------------------------------
15 // Implementation file for class : SequencerTimerTool
16 //
17 // 2004-05-19 : Olivier Callot
18 //-----------------------------------------------------------------------------
19 
20 // Declaration of the Tool Factory
22 
23 //=============================================================================
24 // Standard constructor, initializes variables
25 //=============================================================================
27  const std::string& name,
28  const IInterface* parent )
29  : GaudiHistoTool ( type, name , parent )
30 {
31  declareInterface<ISequencerTimerTool>(this);
32 
33  declareProperty( "shots" , m_shots );
34  declareProperty( "Normalised" , m_normalised = false );
35  declareProperty( "GlobalTiming" , m_globalTiming = false );
36  declareProperty( "NameSize" , m_headerSize = 30,
37  "Number of characters to be used in algorithm name column" );
38  // Histograms are disabled by default in this tool.
39  setProperty("HistoProduce", false).ignore();
40 }
41 //=========================================================================
42 //
43 //=========================================================================
45 {
47  if ( sc.isFailure() ) return sc;
48  double sum = 0;
49  TimerForSequencer norm( "normalize", m_headerSize, m_normFactor );
50  norm.start();
51  IRndmGenSvc* rsvc = svc<IRndmGenSvc>( "RndmGenSvc", true );
52  { // Use dummy loop suggested by Vanya Belyaev:
54  gauss.initialize( rsvc , Rndm::Gauss(0.,1.0) ).ignore();
55  unsigned int shots = m_shots;
56  while( 0 < --shots ) { sum += gauss() * sum ; }
57  }
58  norm.stop();
59  double time = norm.lastCpu();
60  m_speedRatio = 1./time;
61  info() << "This machine has a speed about "
62  << format( "%6.2f", 1000.*m_speedRatio)
63  << " times the speed of a 2.8 GHz Xeon." << endmsg ;
65  return sc;
66 }
67 
68 //=========================================================================
69 // Finalize : Report timers
70 //=========================================================================
72 {
73 
74  std::string line(m_headerSize + 68, '-');
75  info() << line << endmsg
76  << "This machine has a speed about "
77  << format( "%6.2f", 1000.*m_speedRatio)
78  << " times the speed of a 2.8 GHz Xeon.";
79  if ( m_normalised ) info() <<" *** All times are renormalized ***";
81  << line << endmsg;
82 
83  std::string lastName;
84  for ( const auto& timr : m_timerList)
85  {
86  if ( lastName == timr.name() ) continue; // suppress duplicate
87  lastName = timr.name();
88  info() << timr << endmsg;
89  }
90  info() << line << endmsg;
91 
92  return GaudiHistoTool::finalize();
93 }
94 
95 //=========================================================================
96 // Return the index of a specified name. Trailing and leading spaces ignored
97 //=========================================================================
98 int SequencerTimerTool::indexByName ( const std::string& name )
99 {
100  auto beg = name.find_first_not_of(" \t");
101  auto end = name.find_last_not_of(" \t");
102  auto temp = name.substr( beg, end-beg+1 );
103  auto i = std::find_if( std::begin(m_timerList), std::end(m_timerList),
104  [&](const TimerForSequencer& timer) {
105  beg = timer.name().find_first_not_of(" \t");
106  end = timer.name().find_last_not_of(" \t");
107  return timer.name().compare(beg,end-beg+1,temp) == 0;
108  });
109  return i!=std::end(m_timerList) ? std::distance(std::begin(m_timerList),i) : -1;
110 }
111 
112 //=========================================================================
113 // Build and save the histograms
114 //=========================================================================
116 {
117  if ( produceHistos() )
118  {
119  info() << "Saving Timing histograms" << endmsg;
120  const size_t bins = m_timerList.size();
121  AIDA::IHistogram1D* histoTime = book("ElapsedTime", 0, bins, bins);
122  AIDA::IHistogram1D* histoCPU = book("CPUTime", 0, bins, bins);
123  AIDA::IHistogram1D* histoCount = book("Count", 0, bins, bins);
124  TH1D* tHtime = Gaudi::Utils::Aida2ROOT::aida2root(histoTime);
125  TH1D* tHCPU = Gaudi::Utils::Aida2ROOT::aida2root(histoCPU);
126  TH1D* tHCount = Gaudi::Utils::Aida2ROOT::aida2root(histoCount);
127  for (const auto& tfsq : m_timerList ) {
128  tHtime->Fill(tfsq.name().c_str(), tfsq.elapsedTotal());
129  tHCPU->Fill(tfsq.name().c_str(), tfsq.cpuTotal());
130  tHCount->Fill(tfsq.name().c_str(), tfsq.count());
131  }
132  }
133 }
134 
135 //=============================================================================
136 // Add a timer
137 //=============================================================================
138 int SequencerTimerTool::addTimer( const std::string& name )
139 {
140  std::string myName( 2*m_indent, ' ' );
141  myName += name;
142  if ( myName.size() < m_headerSize ) {
143  myName += std::string( m_headerSize - myName.size(), ' ' );
144  }
145  m_timerList.emplace_back( std::move(myName), m_headerSize, m_normFactor );
146  return m_timerList.size() - 1;
147 }
148 
149 //=============================================================================
StatusCode initialize() override
initialize method, to compute the normalization factor
Auxiliary class.
static std::string header(std::string::size_type size)
header matching the previous format
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
double sum(double x, double y, double z)
uint64_t stop()
Stop time measurement and return the last elapsed time.
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
STL namespace.
double lastCpu() const
returns the last measured time
Parameters for the Gauss random number generation.
void start()
Start a time measurement.
int indexByName(const std::string &name) override
returns the index of the counter with that name, or -1
StatusCode finalize() override
standard finalization method
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
void saveHistograms() override
prepares and saves the timing histograms
Random number accessor This small class encapsulates the use of the random number generator...
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
std::string::size_type m_headerSize
Size of the name field.
Random Generator service interface definition Definition of a interface for a service to access rando...
Definition: IRndmGenSvc.h:35
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
Definition of the basic interface.
Definition: IInterface.h:234
Simple class to extend the functionality of class GaudiTool.
bool PyHelper() setProperty(IInterface *p, char *name, char *value)
Definition: Bootstrap.cpp:254
static TH1D * aida2root(AIDA::IHistogram1D *aida)
get the underlying pointer for 1D-histogram
Definition: Aida2ROOT.cpp:72
AIDA::IHistogram1D * book(const std::string &title, const double low=0, const double high=100, const unsigned long bins=100) const
book the 1D histogram
Definition: GaudiHistos.h:2029
int addTimer(const std::string &name) override
add a timer entry with the specified name
int m_indent
Amount of indentation.
constexpr double gauss
StatusCode initialize() override
standard initialization method
bool produceHistos() const
get the flag for histogram production (property "HistoProduce")
Definition: GaudiHistos.h:2691
Implements the time measurement inside a sequencer.
const std::string & name() const
returns the name
std::vector< TimerForSequencer > m_timerList
bool m_normalised
Is the time scaled to a nominal PIII ?
virtual StatusCode initialize(const SmartIF< IRndmGenSvc > &svc, const IRndmGen::Param &par)
Initialization.
void ignore() const
Definition: StatusCode.h:108
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
list i
Definition: ana.py:128
const std::string & name(int index) override
returns the name of the counter
StatusCode finalize() override
finalize method, to print the time summary table
string type
Definition: gaudirun.py:151
double m_normFactor
Factor to convert to standard CPU (1 GHz PIII)