The Gaudi Framework  v33r0 (d5ea422b)
AlgExecStateSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #include "AlgExecStateSvc.h"
17 
19 
20 //=============================================================================
21 
22 void AlgExecStateSvc::init() {
23 
24  // seriously? do we have no way of getting a Service by type???
25  std::string wbn;
26  for ( auto& is : serviceLocator()->getServices() ) {
27  IHiveWhiteBoard* iwb = dynamic_cast<IHiveWhiteBoard*>( is );
28  if ( iwb ) {
29  wbn = is->name();
30  if ( msgLevel( MSG::VERBOSE ) ) verbose() << "HiveWhiteBoard service name is " << wbn << endmsg;
31  break;
32  }
33  }
34 
36  wbs = serviceLocator()->service( wbn, false );
37 
38  if ( wbs.isValid() ) {
39  m_algStates.resize( wbs->getNumberOfStores() );
40  m_eventStatus.resize( wbs->getNumberOfStores() );
41  } else {
42  m_algStates.resize( 1 );
43  m_eventStatus.resize( 1 );
44  }
45 
46  if ( msgLevel( MSG::DEBUG ) ) debug() << "resizing state containers to : " << m_algStates.size() << endmsg;
47 
48  SmartIF<IAlgManager> algMan( serviceLocator() );
49  if ( !algMan.isValid() ) {
50  fatal() << "could not get the AlgManager" << endmsg;
51  throw GaudiException( "In AlgExecStateSvc, unable to get the AlgManager!", "AlgExecStateSvc", StatusCode::FAILURE );
52  }
53 
54  m_isInit = true;
55 
56  auto algos = algMan->getAlgorithms();
57  for ( auto& alg : algos ) addAlg( alg );
58  for ( auto& alg : m_preInitAlgs ) addAlg( alg );
59 
60  if ( msgLevel( MSG::VERBOSE ) ) {
62  dump( ost, Gaudi::Hive::currentContext() );
63  verbose() << "dumping state:\n" << ost.str() << endmsg;
64  }
65 }
66 
67 //-----------------------------------------------------------------------------
68 
70 
71  if ( !m_isInit ) {
72  fatal() << "AlgExecStateSvc not initialized before first use" << endmsg;
73  throw GaudiException( "AlgExecStateSvc not initialized before first use!", "AlgExecStateSvc", StatusCode::FAILURE );
74  }
75 }
76 
77 //-----------------------------------------------------------------------------
78 
80  size_t slotID = ctx.valid() ? ctx.slot() : 0;
81 
82  ost << " [slot: " << slotID << ", incident: " << m_eventStatus.at( slotID ) << "]:\n\n";
83 
84  auto& algState = m_algStates.at( slotID );
85  auto ml = std::accumulate( begin( algState ), end( algState ), size_t{0},
86  []( size_t m, const auto& as ) { return std::max( m, as.first.str().length() ); } );
87 
88  for ( auto& e : algState ) ost << " + " << std::setw( ml ) << e.first.str() << " " << e.second << '\n';
89 }
90 
91 //-----------------------------------------------------------------------------
92 
94  if ( !m_isInit ) {
95  if ( msgLevel( MSG::DEBUG ) ) debug() << "preInit: will add Alg " << alg.str() << " later" << endmsg;
97  return;
98  }
99 
100  if ( !m_algStates.empty() && m_algStates.front().find( alg ) != m_algStates.front().end() ) {
101  // already added
102  return;
103  }
104 
105  {
106  // in theory, this should only get called during initialization (serial)
107  // so shouldn't have to protect with a mutex...
109 
110  AlgExecState s;
111  for ( auto& a : m_algStates ) a[alg] = s;
112  m_errorCount[alg] = 0;
113  }
114 
115  if ( msgLevel( MSG::DEBUG ) )
116  debug() << "adding alg " << alg.str() << " to " << m_algStates.size() << " slots" << endmsg;
117 }
118 
119 //-----------------------------------------------------------------------------
120 
122  checkInit();
123 
124  auto& algState = m_algStates.at( ctx.slot() );
125  auto itr = algState.find( algName );
126  if ( UNLIKELY( itr == algState.end() ) ) {
127  throw GaudiException{"cannot find Alg " + algName.str() + " in AlgStateMap", name(), StatusCode::FAILURE};
128  }
129  return itr->second;
130 }
131 
132 //-----------------------------------------------------------------------------
133 
136 
137  auto& algState = m_algStates.at( ctx.slot() );
138  auto itr = algState.find( iAlg->nameKey() );
139 
140  if ( UNLIKELY( itr == algState.end() ) ) {
141  throw GaudiException{std::string{"cannot find Alg "} + iAlg->name() + " in AlgStateMap", name(),
143  }
144 
145  return itr->second;
146 }
147 
148 //-----------------------------------------------------------------------------
149 
151  checkInit();
152  return m_algStates.at( ctx.slot() );
153 }
154 
155 //-----------------------------------------------------------------------------
156 
158  checkInit();
159  return m_eventStatus.at( ctx.slot() );
160 }
161 
162 //-----------------------------------------------------------------------------
163 
166  m_eventStatus.at( ctx.slot() ) = sc;
167 }
168 
169 //-----------------------------------------------------------------------------
170 
171 void AlgExecStateSvc::updateEventStatus( const bool& fail, const EventContext& ctx ) {
173  auto& status = m_eventStatus.at( ctx.slot() );
174  if ( status == EventStatus::Success ) {
175  if ( fail ) status = EventStatus::AlgFail;
176  } else if ( status == EventStatus::Invalid ) {
177  status = ( fail ? EventStatus::AlgFail : EventStatus::Success );
178  }
179 }
180 
181 //-----------------------------------------------------------------------------
182 
184  if ( msgLevel( MSG::DEBUG ) ) verbose() << "reset(" << ctx.slot() << ")" << endmsg;
185 
187  for ( auto& e : m_algStates.at( ctx.slot() ) ) e.second.reset();
188 
190 }
191 
192 //-----------------------------------------------------------------------------
193 
194 unsigned int AlgExecStateSvc::algErrorCount( const IAlgorithm* iAlg ) const {
195  auto itr = m_errorCount.find( iAlg->nameKey() );
196  if ( itr == m_errorCount.end() ) {
197  error() << "Unable to find Algorithm \"" << iAlg->name() << "\" in map"
198  << " of ErrorCounts" << endmsg;
199  return 0;
200  }
201 
202  return itr->second;
203 }
204 
205 //-----------------------------------------------------------------------------
206 
208  auto itr = m_errorCount.find( iAlg->nameKey() );
209  if ( itr != m_errorCount.end() ) {
210  itr->second = 0;
211  } else {
212  error() << "Unable to find Algorithm \"" << iAlg->name() << "\" in map"
213  << " of ErrorCounts" << endmsg;
214  }
215 }
216 
217 //-----------------------------------------------------------------------------
218 
220  auto itr = m_errorCount.find( iAlg->nameKey() );
221  if ( itr == m_errorCount.end() ) {
222  error() << "Unable to find Algorithm \"" << iAlg->name() << "\" in map"
223  << " of ErrorCounts" << endmsg;
224  return 0;
225  }
226  return ++( itr->second );
227 }
void resetErrorCount(const IAlgorithm *iAlg) override
#define UNLIKELY(x)
Definition: Kernel.h:106
A service that keeps track of the execution state of Algorithm.
Define general base for Gaudi exception.
std::vector< AlgStateMap_t > m_algStates
unsigned int algErrorCount(const IAlgorithm *iAlg) const override
const std::string & str() const
the actual string
Definition: StringKey.h:55
std::map< Gaudi::StringKey, std::atomic< unsigned int > > m_errorCount
bool isValid() const
Allow for check if smart pointer is valid.
Definition: SmartIF.h:72
void addAlg(const Gaudi::StringKey &algName) override
T end(T... args)
virtual const std::vector< IAlgorithm * > & getAlgorithms() const =0
Return the list of Algorithms.
void updateEventStatus(const bool &b, const EventContext &ctx) override
std::once_flag m_initFlag
void dump(std::ostringstream &ost, const EventContext &ctx) const override
T call_once(T... args)
This class represents an entry point to all the event specific data.
Definition: EventContext.h:34
STL class.
void checkInit() const
The helper class to represent the efficient "key" for access.
Definition: StringKey.h:44
T setw(T... args)
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
STL class.
#define DECLARE_COMPONENT(type)
T at(T... args)
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:284
T push_back(T... args)
virtual const Gaudi::StringKey & nameKey() const =0
StringKey rep of name.
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
const AlgExecState & algExecState(const Gaudi::StringKey &algName, const EventContext &ctx) const override
constexpr double m
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
const AlgStateMap_t & algExecStates(const EventContext &ctx) const override
GAUDI_API const EventContext & currentContext()
unsigned int incrementErrorCount(const IAlgorithm *iAlg) override
T str(T... args)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
virtual size_t getNumberOfStores() const =0
Get the number of 'slots'.
def end
Definition: IOTest.py:123
std::vector< Gaudi::StringKey > m_preInitAlgs
T max(T... args)
The IAlgorithm is the interface implemented by the Algorithm base class.
Definition: IAlgorithm.h:38
std::mutex m_mut
T find(T... args)
void reset(const EventContext &ctx) override
string s
Definition: gaudirun.py:328
constexpr static const auto FAILURE
Definition: StatusCode.h:97
const EventStatus::Status & eventStatus(const EventContext &ctx) const override
std::vector< EventStatus::Status > m_eventStatus
AttribStringParser::Iterator begin(const AttribStringParser &parser)
T accumulate(T... args)
void setEventStatus(const EventStatus::Status &sc, const EventContext &ctx) override
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202