The Gaudi Framework  master (37c0b60a)
AlgExecStateSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 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 
26  : 1;
27 
28  m_algStates.resize( slots );
29  m_eventStatus.resize( slots );
30 
31  if ( msgLevel( MSG::DEBUG ) ) debug() << "resizing state containers to : " << slots << endmsg;
32 
33  SmartIF<IAlgManager> algMan( serviceLocator() );
34  if ( !algMan.isValid() ) {
35  fatal() << "could not get the AlgManager" << endmsg;
36  throw GaudiException( "In AlgExecStateSvc, unable to get the AlgManager!", "AlgExecStateSvc", StatusCode::FAILURE );
37  }
38 
39  m_isInit = true;
40 
41  for ( const auto& alg : algMan->getAlgorithms() ) addAlg( alg );
42  for ( const auto& alg : m_preInitAlgs ) addAlg( alg );
43 
44  if ( msgLevel( MSG::VERBOSE ) ) {
47  verbose() << "dumping state:\n" << ost.str() << endmsg;
48  }
49 }
50 
51 //-----------------------------------------------------------------------------
52 
54 
55  if ( !m_isInit ) {
56  throw GaudiException( "AlgExecStateSvc not initialized before first use!", "AlgExecStateSvc", StatusCode::FAILURE );
57  }
58 }
59 
60 //-----------------------------------------------------------------------------
61 
63  const size_t slotID = ctx.valid() ? ctx.slot() : 0;
64 
65  ost << " [slot: " << slotID << ", incident: " << m_eventStatus.at( slotID ) << "]:\n\n";
66 
67  auto& algState = m_algStates.at( slotID );
68  auto ml = std::accumulate( begin( algState ), end( algState ), size_t{ 0 },
69  []( size_t m, const auto& as ) { return std::max( m, as.first.str().length() ); } );
70 
71  for ( const auto& e : algState ) ost << " + " << std::setw( ml ) << e.first.str() << " " << e.second << '\n';
72 }
73 
74 //-----------------------------------------------------------------------------
75 
77  if ( !m_isInit ) {
78  if ( msgLevel( MSG::DEBUG ) ) debug() << "preInit: will add Alg " << alg.str() << " later" << endmsg;
80  return;
81  }
82 
83  if ( !m_algStates.empty() && m_algStates.front().find( alg ) != m_algStates.front().end() ) {
84  // already added
85  return;
86  }
87 
88  {
89  // in theory, this should only get called during initialization (serial)
90  // so shouldn't have to protect with a mutex...
91  std::scoped_lock lock( m_mut );
92 
94  for ( auto& a : m_algStates ) a[alg] = s;
95  m_errorCount[alg] = 0;
96  }
97 
98  if ( msgLevel( MSG::DEBUG ) )
99  debug() << "adding alg " << alg.str() << " to " << m_algStates.size() << " slots" << endmsg;
100 }
101 
102 //-----------------------------------------------------------------------------
103 
105  checkInit();
106 
107  auto& algState = m_algStates.at( ctx.slot() );
108  auto itr = algState.find( algName );
109  if ( itr == algState.end() ) {
110  throw GaudiException{ "cannot find Alg " + algName.str() + " in AlgStateMap", name(), StatusCode::FAILURE };
111  }
112 
113  // Assuming the alg is known, look for its state in the sub-slot
114  if ( ctx.usesSubSlot() ) {
115  auto& subSlots = m_algSubSlotStates[ctx.slot()];
116  auto& thisSubSlot = subSlots[ctx.subSlot()];
117  auto subitr = thisSubSlot.find( algName );
118  if ( subitr == thisSubSlot.end() ) {
119  throw GaudiException{ "cannot find Alg " + algName.str() + " in AlgStateMap", name(), StatusCode::FAILURE };
120  } else {
121  return subitr->second;
122  }
123  }
124 
125  return itr->second;
126 }
127 
128 //-----------------------------------------------------------------------------
129 
132 
133  auto& algState = m_algStates.at( ctx.slot() );
134  auto itr = algState.find( iAlg->nameKey() );
135  if ( itr == algState.end() ) {
136  throw GaudiException{ std::string{ "cannot find Alg " } + iAlg->name() + " in AlgStateMap", name(),
138  }
139 
140  // Sub-slots are dynamic
141  // Assuming the alg is known, look for a subslot
142  // Return the existing state, or create a new one
143  if ( ctx.usesSubSlot() ) {
144 
145  // Use mutex since dynamic
146  std::scoped_lock lock( m_mut );
147 
148  // Check that there is any sub-slot information for this slot
149  if ( ctx.slot() >= m_algSubSlotStates.size() ) m_algSubSlotStates.resize( ctx.slot() + 1 );
150 
151  // Check that there is information for this sub-slot
152  auto& subSlots = m_algSubSlotStates[ctx.slot()];
153  if ( ctx.subSlot() >= subSlots.size() ) subSlots.resize( ctx.subSlot() + 1 );
154 
155  // Find (or create) the state of the algorithm in this sub-slot
156  auto& thisSubSlot = subSlots[ctx.subSlot()];
157  auto subitr = thisSubSlot.find( iAlg->name() );
158  if ( subitr == thisSubSlot.end() ) {
159  thisSubSlot[iAlg->name()] = AlgExecState();
160  return thisSubSlot[iAlg->name()];
161  } else {
162  return subitr->second;
163  }
164  }
165 
166  return itr->second;
167 }
168 
169 //-----------------------------------------------------------------------------
170 
172  checkInit();
173  return m_algStates.at( ctx.slot() );
174 }
175 
176 //-----------------------------------------------------------------------------
177 
179  checkInit();
180  return m_eventStatus.at( ctx.slot() );
181 }
182 
183 //-----------------------------------------------------------------------------
184 
187  m_eventStatus.at( ctx.slot() ) = sc;
188 }
189 
190 //-----------------------------------------------------------------------------
191 
192 void AlgExecStateSvc::updateEventStatus( const bool& fail, const EventContext& ctx ) {
194  auto& status = m_eventStatus.at( ctx.slot() );
195  if ( status == EventStatus::Success ) {
196  if ( fail ) status = EventStatus::AlgFail;
197  } else if ( status == EventStatus::Invalid ) {
198  status = ( fail ? EventStatus::AlgFail : EventStatus::Success );
199  }
200 }
201 
202 //-----------------------------------------------------------------------------
203 
205  if ( msgLevel( MSG::VERBOSE ) ) verbose() << "reset(" << ctx.slot() << ")" << endmsg;
206 
208  for ( auto& e : m_algStates.at( ctx.slot() ) ) e.second.reset();
209 
210  // Also clear sub slots
211  if ( ctx.slot() < m_algSubSlotStates.size() ) {
212  for ( auto& subSlot : m_algSubSlotStates[ctx.slot()] ) {
213  for ( auto& e : subSlot ) e.second.reset();
214  }
215  }
216 
218 }
219 
220 //-----------------------------------------------------------------------------
221 
222 unsigned int AlgExecStateSvc::algErrorCount( const IAlgorithm* iAlg ) const {
223  auto itr = m_errorCount.find( iAlg->nameKey() );
224  if ( itr == m_errorCount.end() ) {
225  error() << "Unable to find Algorithm \"" << iAlg->name() << "\" in map"
226  << " of ErrorCounts" << endmsg;
227  return 0;
228  }
229 
230  return itr->second;
231 }
232 
233 //-----------------------------------------------------------------------------
234 
236  auto itr = m_errorCount.find( iAlg->nameKey() );
237  if ( itr != m_errorCount.end() ) {
238  itr->second = 0;
239  } else {
240  error() << "Unable to find Algorithm \"" << iAlg->name() << "\" in map"
241  << " of ErrorCounts" << endmsg;
242  }
243 }
244 
245 //-----------------------------------------------------------------------------
246 
248  auto itr = m_errorCount.find( iAlg->nameKey() );
249  if ( itr == m_errorCount.end() ) {
250  error() << "Unable to find Algorithm \"" << iAlg->name() << "\" in map"
251  << " of ErrorCounts" << endmsg;
252  return 0;
253  }
254  return ++( itr->second );
255 }
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:25
std::call_once
T call_once(T... args)
AlgExecStateSvc::incrementErrorCount
unsigned int incrementErrorCount(const IAlgorithm *iAlg) override
Definition: AlgExecStateSvc.cpp:247
IAlgManager.h
AlgExecStateSvc::init
void init()
Definition: AlgExecStateSvc.cpp:22
std::string
STL class.
Gaudi::Hive::currentContext
GAUDI_API const EventContext & currentContext()
Definition: ThreadLocalContext.cpp:30
GaudiPartProp.DumpParticleProperties.dump
def dump()
Definition: DumpParticleProperties.py:26
GaudiException.h
AlgExecStateSvc::algExecState
const AlgExecState & algExecState(const Gaudi::StringKey &algName, const EventContext &ctx) const override
Definition: AlgExecStateSvc.cpp:104
gaudirun.s
string s
Definition: gaudirun.py:346
AlgExecStateSvc::m_eventStatus
std::vector< EventStatus::Status > m_eventStatus
Definition: AlgExecStateSvc.h:59
std::unordered_map::find
T find(T... args)
GaudiException
Definition: GaudiException.h:31
EventStatus::Success
@ Success
Definition: IAlgExecStateSvc.h:72
ConcurrencyFlags.h
AlgExecStateSvc::checkInit
void checkInit() const
Definition: AlgExecStateSvc.cpp:53
AlgExecStateSvc::m_preInitAlgs
std::vector< Gaudi::StringKey > m_preInitAlgs
Definition: AlgExecStateSvc.h:60
EventStatus::Invalid
@ Invalid
Definition: IAlgExecStateSvc.h:72
AlgExecStateSvc::eventStatus
const EventStatus::Status & eventStatus(const EventContext &ctx) const override
Definition: AlgExecStateSvc.cpp:178
AlgExecStateSvc::addAlg
void addAlg(const Gaudi::StringKey &algName) override
Definition: AlgExecStateSvc.cpp:76
AlgExecStateSvc::resetErrorCount
void resetErrorCount(const IAlgorithm *iAlg) override
Definition: AlgExecStateSvc.cpp:235
CommonMessaging< implements< IService, IProperty, IStateful > >::msgLevel
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
Definition: CommonMessaging.h:148
AlgExecStateSvc::m_mut
std::mutex m_mut
Definition: AlgExecStateSvc.h:69
AlgExecStateSvc
A service that keeps track of the execution state of Algorithm.
Definition: AlgExecStateSvc.h:26
std::vector::push_back
T push_back(T... args)
ManySmallAlgs.alg
alg
Definition: ManySmallAlgs.py:81
AlgExecStateSvc::dump
void dump(std::ostringstream &ost, const EventContext &ctx) const override
Definition: AlgExecStateSvc.cpp:62
Gaudi::Concurrency::ConcurrencyFlags::numConcurrentEvents
static GAUDI_API std::size_t numConcurrentEvents()
number of Concurrent Events (for MT)
Definition: ConcurrencyFlags.h:57
Gaudi::Concurrency::ConcurrencyFlags::concurrent
static GAUDI_API bool concurrent()
serial operation, or some form of concurrency
Definition: ConcurrencyFlags.h:65
Gaudi::StringKey
Definition: StringKey.h:44
AlgExecStateSvc::updateEventStatus
void updateEventStatus(const bool &b, const EventContext &ctx) override
Definition: AlgExecStateSvc.cpp:192
Gaudi::Utils::begin
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Definition: AttribStringParser.h:136
SmartIF::isValid
bool isValid() const
Allow for check if smart pointer is valid.
Definition: SmartIF.h:72
GaudiPython.Pythonizations.ctx
ctx
Definition: Pythonizations.py:578
Service::name
const std::string & name() const override
Retrieve name of the service
Definition: Service.cpp:332
AlgExecStateSvc::algErrorCount
unsigned int algErrorCount(const IAlgorithm *iAlg) const override
Definition: AlgExecStateSvc.cpp:222
std::vector::at
T at(T... args)
IAlgorithm
Definition: IAlgorithm.h:38
Gaudi::Units::m
constexpr double m
Definition: SystemOfUnits.h:108
AlgExecStateSvc::m_algSubSlotStates
std::vector< std::vector< AlgStateMap_t > > m_algSubSlotStates
Definition: AlgExecStateSvc.h:57
AlgExecStateSvc::m_isInit
bool m_isInit
Definition: AlgExecStateSvc.h:67
IAlgorithm::nameKey
virtual const Gaudi::StringKey & nameKey() const =0
StringKey rep of name.
std::accumulate
T accumulate(T... args)
SmartIF< IAlgManager >
genconfuser.verbose
verbose
Definition: genconfuser.py:28
AlgExecStateSvc::m_algStates
std::vector< AlgStateMap_t > m_algStates
Definition: AlgExecStateSvc.h:56
AlgExecStateSvc::setEventStatus
void setEventStatus(const EventStatus::Status &sc, const EventContext &ctx) override
Definition: AlgExecStateSvc.cpp:185
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
std::map
STL class.
AlgExecStateSvc::m_errorCount
std::unordered_map< Gaudi::StringKey, std::atomic< unsigned int > > m_errorCount
Definition: AlgExecStateSvc.h:62
AlgExecStateSvc::reset
void reset(const EventContext &ctx) override
Definition: AlgExecStateSvc.cpp:204
EventStatus::AlgFail
@ AlgFail
Definition: IAlgExecStateSvc.h:72
AlgExecStateSvc::m_initFlag
std::once_flag m_initFlag
Definition: AlgExecStateSvc.h:66
std::ostringstream
STL class.
AlgExecStateSvc.h
AlgExecStateSvc::algExecStates
const AlgStateMap_t & algExecStates(const EventContext &ctx) const override
Definition: AlgExecStateSvc.cpp:171
ThreadLocalContext.h
MSG::VERBOSE
@ VERBOSE
Definition: IMessageSvc.h:25
EventContext.h
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:46
EventContext
Definition: EventContext.h:34
EventStatus::Status
Status
Definition: IAlgExecStateSvc.h:72
Gaudi::StringKey::str
const std::string & str() const
the actual string
Definition: StringKey.h:56
std::ostringstream::str
T str(T... args)
std::size_t
std::unordered_map::end
T end(T... args)
IOTest.end
end
Definition: IOTest.py:125
AlgExecState
Definition: IAlgExecStateSvc.h:36
std::setw
T setw(T... args)
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
std::max
T max(T... args)