The Gaudi Framework  master (d98a2936)
AlgExecStateSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2025 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 void AlgExecStateSvc::init() {
21 
22  const std::size_t slots = Gaudi::Concurrency::ConcurrencyFlags::concurrent()
24  : 1;
25  m_algStates.resize( slots );
26  m_eventStatus.resize( slots );
27 
28  if ( msgLevel( MSG::DEBUG ) ) debug() << "resizing state containers to : " << slots << endmsg;
29 
30  m_isInit = true;
31 
32  // call addAlg for algorithms which called it too early.
33  for ( const auto& alg : m_preInitAlgs ) addAlg( alg );
34 
35  if ( msgLevel( MSG::VERBOSE ) ) {
36  std::ostringstream ost;
38  verbose() << "dumping state:\n" << ost.str() << endmsg;
39  }
40 }
41 
43  if ( !m_isInit ) {
44  if ( msgLevel( MSG::DEBUG ) ) debug() << "preInit: will add Alg " << alg.str() << " later" << endmsg;
45  auto it = std::find( begin( m_preInitAlgs ), end( m_preInitAlgs ), alg );
46  if ( it == m_preInitAlgs.end() ) {
47  m_preInitAlgs.push_back( alg );
48  return static_cast<AlgExecStateRef::AlgKey>( m_preInitAlgs.size() - 1 );
49  } else {
50  return static_cast<AlgExecStateRef::AlgKey>( std::distance( begin( m_preInitAlgs ), it ) );
51  }
52  }
53  // try to create default state for first slot and retrieve the key
54  auto [it, b] =
55  m_algNameToIndex.try_emplace( alg, static_cast<AlgExecStateRef::AlgKey>( m_algStates.front().size() ) );
56  if ( b ) {
57  // create default state for all slots
58  for ( auto& a : m_algStates ) a.emplace_back();
59  m_errorCount.emplace( it->second, 0 );
60  m_algNames.push_back( alg );
61  if ( msgLevel( MSG::DEBUG ) )
62  debug() << "adding alg " << alg.str() << " to " << m_algStates.size() << " slots" << endmsg;
63  }
64  return it->second;
65 }
66 
69  std::call_once( m_initFlag, &AlgExecStateSvc::init, this );
70  // Sub-slots are dynamic
71  // Assuming the alg is known, look for a subslot
72  // Return the existing state, or create a new one
73  if ( ctx.usesSubSlot() ) {
74  // Use mutex since dynamic
75  std::scoped_lock lock( m_mut );
76 
77  // Check that there is any sub-slot information for this slot
78  if ( ctx.slot() >= m_algSubSlotStates.size() ) m_algSubSlotStates.resize( ctx.slot() + 1 );
79 
80  // Check that there is information for this sub-slot
81  auto& subSlots = m_algSubSlotStates[ctx.slot()];
82  if ( ctx.subSlot() >= subSlots.size() ) subSlots.resize( ctx.subSlot() + 1 );
83 
84  // Find (and potentially extend) the AlgStates
85  return subSlots[ctx.subSlot()].try_emplace( k ).first->second;
86  }
87  // regular case with no subslot
88  assert( ctx.slot() < m_algStates.size() );
89  assert( static_cast<size_t>( k ) < m_algStates.at( ctx.slot() ).size() );
90  return m_algStates.at( ctx.slot() )[static_cast<size_t>( k )];
91 }
92 
94  AlgExecStateRef::AlgKey k ) const {
95  assert( m_isInit );
96 
97  // Sub-slots are dynamic
98  // Assuming the alg is known, look for a subslot
99  // Return the existing state, or create a new one
100  if ( ctx.usesSubSlot() ) {
101  // Use mutex since dynamic
102  std::scoped_lock lock( m_mut );
103  // Check that there is any sub-slot information for this slot
104  if ( ctx.slot() >= m_algSubSlotStates.size() ) {
105  throw GaudiException( "Could not find slot in m_algSubSlotStates", "AlgExecStateSvc", StatusCode::FAILURE );
106  }
107  // Check that there is information for this sub-slot
108  auto& subSlots = m_algSubSlotStates[ctx.slot()];
109  if ( ctx.subSlot() >= subSlots.size() ) {
110  throw GaudiException( "Could not find subslot in m_algSubSlotStates", "AlgExecStateSvc", StatusCode::FAILURE );
111  }
112  // Find the AlgStates
113  return subSlots[ctx.subSlot()].at( k );
114  }
115  // regular case with no subslot
116  return m_algStates.at( ctx.slot() )[static_cast<size_t>( k )];
117 }
118 
120  assert( m_isInit );
121  return m_eventStatus.at( ctx.slot() );
122 }
123 
125  std::call_once( m_initFlag, &AlgExecStateSvc::init, this );
126  m_eventStatus.at( ctx.slot() ) = sc;
127 }
128 
129 void AlgExecStateSvc::updateEventStatus( const bool& fail, const EventContext& ctx ) {
130  std::call_once( m_initFlag, &AlgExecStateSvc::init, this );
131  auto& status = m_eventStatus.at( ctx.slot() );
132  if ( status == EventStatus::Success ) {
133  if ( fail ) status = EventStatus::AlgFail;
134  } else if ( status == EventStatus::Invalid ) {
135  status = ( fail ? EventStatus::AlgFail : EventStatus::Success );
136  }
137 }
138 
139 unsigned int AlgExecStateSvc::algErrorCount( const IAlgorithm* iAlg ) const {
140  assert( m_isInit );
141  return m_errorCount.at( algKey( iAlg->name() ) );
142 }
144  std::call_once( m_initFlag, &AlgExecStateSvc::init, this );
145  for ( unsigned int k = 0; k < m_errorCount.size(); k++ ) m_errorCount[static_cast<AlgExecStateRef::AlgKey>( k )] = 0;
146 }
148  std::call_once( m_initFlag, &AlgExecStateSvc::init, this );
149  m_errorCount[algKey( iAlg->name() )] = 0;
150 }
152  std::call_once( m_initFlag, &AlgExecStateSvc::init, this );
153  return ++m_errorCount[algKey( iAlg->name() )];
154 }
156  assert( m_isInit );
157  return getInternalState( ctx, k ).filterPassed();
158 }
160  std::call_once( m_initFlag, &AlgExecStateSvc::init, this );
162 }
164  assert( m_isInit );
165  return getInternalState( ctx, k ).state();
166 }
168  std::call_once( m_initFlag, &AlgExecStateSvc::init, this );
169  getInternalState( ctx, k ).setState( s );
170 }
172  const StatusCode& sc ) {
173  std::call_once( m_initFlag, &AlgExecStateSvc::init, this );
174  getInternalState( ctx, k ).setState( s, sc );
175 }
177  assert( m_isInit );
178  return getInternalState( ctx, k ).execStatus();
179 }
181  std::call_once( m_initFlag, &AlgExecStateSvc::init, this );
183 }
184 const std::string& AlgExecStateSvc::algName( AlgExecStateRef::AlgKey k ) const {
185  assert( m_isInit );
186  return m_algNames[static_cast<size_t>( k )];
187 }
188 
189 void AlgExecStateSvc::dump( std::ostream& ost, const EventContext& ctx ) const {
190  const size_t slotID = ctx.valid() ? ctx.slot() : 0;
191  ost << " [slot: " << slotID << ", incident: " << m_eventStatus.at( slotID ) << "]:\n\n";
192  auto& algState = m_algStates.at( slotID );
193  auto ml = std::accumulate( begin( m_algNames ), end( m_algNames ), size_t{ 0 },
194  []( size_t m, const auto& as ) { return std::max( m, as.length() ); } );
195  for ( size_t k = 0; const auto& e : algState )
196  ost << " + " << std::setw( ml ) << algName( static_cast<AlgExecStateRef::AlgKey>( k++ ) ) << " " << e << '\n';
197 }
198 
199 void AlgExecStateSvc::dump( std::ostream& ost, const EventContext& ctx, AlgExecStateRef::AlgKey k ) const {
200  ost << getInternalState( ctx, k );
201 }
202 
204  if ( msgLevel( MSG::VERBOSE ) ) verbose() << "reset(" << ctx.slot() << ")" << endmsg;
205 
206  std::call_once( m_initFlag, &AlgExecStateSvc::init, this );
207  for ( auto& it : m_algStates.at( ctx.slot() ) ) it.reset();
208 
209  // Also clear sub slots
210  if ( ctx.slot() < m_algSubSlotStates.size() ) {
211  for ( auto& subSlot : m_algSubSlotStates[ctx.slot()] ) {
212  for ( auto& it : subSlot ) it.second.reset();
213  }
214  }
215 
216  m_eventStatus.at( ctx.slot() ) = EventStatus::Invalid;
217 }
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:22
AlgExecStateSvc::incrementErrorCount
unsigned int incrementErrorCount(const IAlgorithm *iAlg) override
Definition: AlgExecStateSvc.cpp:151
IAlgManager.h
AlgExecStateSvc::init
void init()
Definition: AlgExecStateSvc.cpp:20
AlgExecStateSvc::AlgExecStateInternal::setFilterPassed
void setFilterPassed(bool f=true)
Definition: AlgExecStateSvc.h:35
Gaudi::Hive::currentContext
GAUDI_API const EventContext & currentContext()
Definition: ThreadLocalContext.cpp:30
GaudiPartProp.DumpParticleProperties.dump
def dump()
Definition: DumpParticleProperties.py:26
AlgExecStateSvc::dump
void dump(std::ostream &ost, const EventContext &ctx) const override
Definition: AlgExecStateSvc.cpp:189
GaudiException.h
gaudirun.s
string s
Definition: gaudirun.py:346
AlgExecStateSvc::m_eventStatus
std::vector< EventStatus::Status > m_eventStatus
Definition: AlgExecStateSvc.h:120
AlgExecStateSvc::getInternalState
AlgExecStateInternal & getInternalState(const EventContext &ctx, AlgExecStateRef::AlgKey k)
Definition: AlgExecStateSvc.cpp:67
GaudiException
Definition: GaudiException.h:29
EventStatus::Success
@ Success
Definition: IAlgExecStateSvc.h:75
ConcurrencyFlags.h
AlgExecStateSvc::AlgExecStateInternal::execStatus
const StatusCode & execStatus() const
Definition: AlgExecStateSvc.h:42
AlgExecStateSvc::AlgExecStateInternal::setState
void setState(AlgExecStateRef::State s)
Definition: AlgExecStateSvc.h:37
AlgExecStateSvc::m_preInitAlgs
std::vector< Gaudi::StringKey > m_preInitAlgs
Definition: AlgExecStateSvc.h:121
AlgExecStateSvc::execStatus
const StatusCode & execStatus(const EventContext &, AlgExecStateRef::AlgKey) const override
Definition: AlgExecStateSvc.cpp:176
AlgExecStateSvc::addAlg
AlgExecStateRef::AlgKey addAlg(const Gaudi::StringKey &) override
Definition: AlgExecStateSvc.cpp:42
AlgExecState::State
State
Definition: IAlgExecStateSvc.h:23
EventStatus::Invalid
@ Invalid
Definition: IAlgExecStateSvc.h:75
AlgExecStateSvc::eventStatus
const EventStatus::Status & eventStatus(const EventContext &ctx) const override
Definition: AlgExecStateSvc.cpp:119
CommonMessaging< implements< IService, IProperty, IStateful > >::msgLevel
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
Definition: CommonMessaging.h:147
AlgExecStateSvc::m_mut
std::mutex m_mut
Definition: AlgExecStateSvc.h:133
AlgExecStateSvc::AlgExecStateInternal::filterPassed
bool filterPassed() const
Definition: AlgExecStateSvc.h:34
AlgExecStateSvc
A service that keeps track of the execution state of Algorithm.
Definition: AlgExecStateSvc.h:27
ManySmallAlgs.alg
alg
Definition: ManySmallAlgs.py:81
Gaudi::Concurrency::ConcurrencyFlags::numConcurrentEvents
static GAUDI_API std::size_t numConcurrentEvents()
number of Concurrent Events (for MT)
Definition: ConcurrencyFlags.h:56
Gaudi::Concurrency::ConcurrencyFlags::concurrent
static GAUDI_API bool concurrent()
serial operation, or some form of concurrency
Definition: ConcurrencyFlags.h:64
Gaudi::StringKey
Definition: StringKey.h:66
AlgExecStateSvc::m_algSubSlotStates
std::vector< std::vector< AlgStatesWithSubSlot > > m_algSubSlotStates
Definition: AlgExecStateSvc.h:116
AlgExecStateSvc::updateEventStatus
void updateEventStatus(const bool &b, const EventContext &ctx) override
Definition: AlgExecStateSvc.cpp:129
Gaudi::Utils::begin
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Definition: AttribStringParser.h:135
GaudiPython.Pythonizations.ctx
ctx
Definition: Pythonizations.py:578
StatusCode
Definition: StatusCode.h:64
AlgExecStateSvc::algErrorCount
unsigned int algErrorCount(const IAlgorithm *iAlg) const override
Definition: AlgExecStateSvc.cpp:139
IAlgorithm
Definition: IAlgorithm.h:36
Gaudi::Units::m
constexpr double m
Definition: SystemOfUnits.h:107
AlgExecStateSvc::m_isInit
bool m_isInit
Definition: AlgExecStateSvc.h:131
AlgExecStateSvc::filterPassed
bool filterPassed(const EventContext &, AlgExecStateRef::AlgKey) const override
Definition: AlgExecStateSvc.cpp:155
AlgExecStateSvc::m_algNames
std::vector< std::string > m_algNames
Definition: AlgExecStateSvc.h:123
AlgExecStateSvc::AlgExecStateInternal::setExecStatus
void setExecStatus(const StatusCode &sc=StatusCode::SUCCESS)
Definition: AlgExecStateSvc.h:43
genconfuser.verbose
verbose
Definition: genconfuser.py:28
AlgExecStateSvc::setState
void setState(const EventContext &, AlgExecStateRef::AlgKey, AlgExecStateRef::State) override
Definition: AlgExecStateSvc.cpp:167
AlgExecStateSvc::setEventStatus
void setEventStatus(const EventStatus::Status &sc, const EventContext &ctx) override
Definition: AlgExecStateSvc.cpp:124
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:198
AlgExecStateSvc::reset
void reset(const EventContext &ctx) override
Definition: AlgExecStateSvc.cpp:203
EventStatus::AlgFail
@ AlgFail
Definition: IAlgExecStateSvc.h:75
AlgExecStateSvc::m_initFlag
std::once_flag m_initFlag
Definition: AlgExecStateSvc.h:130
AlgExecStateSvc::m_errorCount
std::unordered_map< AlgExecStateRef::AlgKey, std::atomic< unsigned int > > m_errorCount
Definition: AlgExecStateSvc.h:126
AlgExecStateSvc.h
ThreadLocalContext.h
MSG::VERBOSE
@ VERBOSE
Definition: IMessageSvc.h:22
AlgExecStateSvc::AlgExecStateInternal::state
AlgExecStateRef::State state() const
Definition: AlgExecStateSvc.h:36
AlgExecStateRef::AlgKey
AlgKey
Definition: IAlgExecStateSvc.h:35
AlgExecStateSvc::m_algNameToIndex
std::unordered_map< Gaudi::StringKey, AlgExecStateRef::AlgKey, Gaudi::StringKeyHash, std::equal_to<> > m_algNameToIndex
Definition: AlgExecStateSvc.h:118
EventContext.h
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:45
EventContext
Definition: EventContext.h:34
EventStatus::Status
Status
Definition: IAlgExecStateSvc.h:75
AlgExecStateSvc::algName
const std::string & algName(AlgExecStateRef::AlgKey) const override
Definition: AlgExecStateSvc.cpp:184
AlgExecStateSvc::algKey
AlgExecStateRef::AlgKey algKey(const std::string &algName) const
Definition: AlgExecStateSvc.h:111
IOTest.end
end
Definition: IOTest.py:125
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:100
Gaudi::Accumulators::accumulate
void accumulate(Counter &counter, const Container &container, Fun f=Identity{})
A helper function for accumulating data from a container into a counter This is internally using buff...
Definition: Accumulators.h:1227
AlgExecStateSvc::m_algStates
std::vector< AlgStates > m_algStates
Definition: AlgExecStateSvc.h:114
AlgExecStateSvc::resetErrorCount
void resetErrorCount() override
Definition: AlgExecStateSvc.cpp:143
AlgExecStateSvc::AlgExecStateInternal
internal state of an algorithm
Definition: AlgExecStateSvc.h:32
AlgExecStateSvc::state
AlgExecStateRef::State state(const EventContext &, AlgExecStateRef::AlgKey) const override
Definition: AlgExecStateSvc.cpp:163
AlgExecStateSvc::setFilterPassed
void setFilterPassed(const EventContext &, AlgExecStateRef::AlgKey, bool) override
Definition: AlgExecStateSvc.cpp:159
AlgExecStateSvc::setExecStatus
void setExecStatus(const EventContext &, AlgExecStateRef::AlgKey, const StatusCode &) override
Definition: AlgExecStateSvc.cpp:180