The Gaudi Framework  master (181af51f)
Loading...
Searching...
No Matches
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
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
129void 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
139unsigned 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 );
161 getInternalState( ctx, k ).setFilterPassed( b );
162}
164 assert( m_isInit );
165 return getInternalState( ctx, k ).state();
166}
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 );
182 getInternalState( ctx, k ).setExecStatus( s );
183}
185 assert( m_isInit );
186 return m_algNames[static_cast<size_t>( k )];
187}
188
189void 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
199void 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}
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
#define DECLARE_COMPONENT(type)
AlgExecState::State State
internal state of an algorithm
void setState(AlgExecStateRef::State s)
const StatusCode & execStatus() const
AlgExecStateRef::State state() const
void setExecStatus(const StatusCode &sc=StatusCode::SUCCESS)
A service that keeps track of the execution state of Algorithm.
void reset(const EventContext &ctx) override
void dump(std::ostream &ost, const EventContext &ctx) const override
std::vector< std::string > m_algNames
std::vector< EventStatus::Status > m_eventStatus
AlgExecStateRef::AlgKey addAlg(const Gaudi::StringKey &) override
unsigned int incrementErrorCount(const IAlgorithm *iAlg) override
void setFilterPassed(const EventContext &, AlgExecStateRef::AlgKey, bool) override
void updateEventStatus(const bool &b, const EventContext &ctx) override
AlgExecStateInternal & getInternalState(const EventContext &ctx, AlgExecStateRef::AlgKey k)
const StatusCode & execStatus(const EventContext &, AlgExecStateRef::AlgKey) const override
void setState(const EventContext &, AlgExecStateRef::AlgKey, AlgExecStateRef::State) override
std::unordered_map< AlgExecStateRef::AlgKey, std::atomic< unsigned int > > m_errorCount
unsigned int algErrorCount(const IAlgorithm *iAlg) const override
std::vector< std::vector< AlgStatesWithSubSlot > > m_algSubSlotStates
void setEventStatus(const EventStatus::Status &sc, const EventContext &ctx) override
const EventStatus::Status & eventStatus(const EventContext &ctx) const override
std::vector< Gaudi::StringKey > m_preInitAlgs
bool filterPassed(const EventContext &, AlgExecStateRef::AlgKey) const override
std::once_flag m_initFlag
std::vector< AlgStates > m_algStates
std::unordered_map< Gaudi::StringKey, AlgExecStateRef::AlgKey, Gaudi::StringKeyHash, std::equal_to<> > m_algNameToIndex
const std::string & algName(AlgExecStateRef::AlgKey) const override
AlgExecStateRef::AlgKey algKey(const std::string &algName) const
void setExecStatus(const EventContext &, AlgExecStateRef::AlgKey, const StatusCode &) override
AlgExecStateRef::State state(const EventContext &, AlgExecStateRef::AlgKey) const override
void resetErrorCount() override
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
This class represents an entry point to all the event specific data.
static GAUDI_API std::size_t numConcurrentEvents()
number of Concurrent Events (for MT)
static GAUDI_API bool concurrent()
serial operation, or some form of concurrency
Helper class for efficient "key" access for strings.
Definition StringKey.h:66
Define general base for Gaudi exception.
The IAlgorithm is the interface implemented by the Algorithm base class.
Definition IAlgorithm.h:36
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
constexpr static const auto FAILURE
Definition StatusCode.h:100
GAUDI_API const EventContext & currentContext()
@ DEBUG
Definition IMessageSvc.h:22
@ VERBOSE
Definition IMessageSvc.h:22