The Gaudi Framework  master (ff829712)
Loading...
Searching...
No Matches
AlgorithmManager.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 "AlgorithmManager.h"
12#include <Gaudi/Algorithm.h>
17#include <GaudiKernel/System.h>
19
20#include <errno.h>
21
23static SmartIF<IAlgorithm> no_algorithm;
24
26 addRef(); // Initial count set to 1
27}
28
30 m_algs.push_back( alg );
31 m_algsMap.emplace( alg->name(), alg );
33}
34
36 auto it = std::find( m_algs.begin(), m_algs.end(), alg );
37 if ( it == m_algs.end() ) { return StatusCode::FAILURE; }
38
39 auto range = m_algsMap.equal_range( alg->name() );
40 auto itm = std::find_if( range.first, range.second, [&]( auto const& p ) { return p.second == alg; } );
41 if ( itm == range.second ) { return StatusCode::FAILURE; }
42
43 m_algs.erase( it );
44 m_algsMap.erase( itm );
46}
47
48StatusCode AlgorithmManager::createAlgorithm( const std::string& algtype, const std::string& algname,
49 IAlgorithm*& algorithm, bool managed, bool checkIfExists ) {
50 // Check if the algorithm is already existing
51 if ( checkIfExists ) {
52 if ( existsAlgorithm( algname ) ) {
53 // return an error because an algorithm with that name already exists
55 }
56 }
57 std::string actualalgtype( algtype );
58 // a '\' in front of the type name prevents alias replacement
59 if ( ( actualalgtype.size() > 8 ) && ( actualalgtype.compare( 0, 8, "unalias:" ) == 0 ) ) {
60 actualalgtype = actualalgtype.substr( 8 );
61 } else {
62 auto typeAlias = m_algTypeAliases.find( algtype );
63 if ( typeAlias != m_algTypeAliases.end() ) { actualalgtype = typeAlias->second; }
64 }
65 algorithm = Gaudi::Algorithm::Factory::create( actualalgtype, algname, serviceLocator().get() ).release();
66 if ( !algorithm ) {
67 this->error() << "Algorithm of type " << actualalgtype << " is unknown (No factory available)." << endmsg;
68 errno =
69 0xAFFEDEAD; // code used by Gaudi for library load errors: forces getLastErrorString do use dlerror (on Linux)
70 std::string err = System::getLastErrorString();
71 if ( !err.empty() ) this->error() << err << endmsg;
72 this->error() << "More information may be available by setting the global jobOpt \"PluginDebugLevel\" to 1"
73 << endmsg;
75 }
76 // Check the compatibility of the version of the interface obtained
77 if ( !isValidInterface( algorithm ) ) {
78 fatal() << "Incompatible interface IAlgorithm version for " << actualalgtype << endmsg;
80 }
81 m_algs.emplace_back( algorithm, managed );
82 m_algsMap.emplace( algorithm->name(), algorithm );
83 // let the algorithm know its type
84 algorithm->setType( std::move( actualalgtype ) );
85 // this is needed to keep the reference count correct, since isValidInterface(algorithm)
86 // implies an increment of the counter by 1
87 algorithm->release();
88 StatusCode rc;
89 if ( managed ) {
90 // Bring the created algorithm to the target state of the ApplicationMgr
92 rc = algorithm->sysInitialize();
93 if ( rc.isSuccess() && targetFSMState() >= Gaudi::StateMachine::RUNNING ) { rc = algorithm->sysStart(); }
94 }
95 if ( !rc.isSuccess() ) { this->error() << "Failed to initialize algorithm: [" << algname << "]" << endmsg; }
96 }
97 return rc;
98}
99
101 auto it = m_algsMap.find( typeName.name() );
102 if ( it != m_algsMap.end() ) { // found
103 return it->second;
104 }
105 if ( createIf ) {
106 IAlgorithm* alg;
107 if ( createAlgorithm( typeName.type(), typeName.name(), alg, true ).isSuccess() ) {
108 return algorithm( typeName, false );
109 }
110 }
111 return no_algorithm;
112}
113
114bool AlgorithmManager::existsAlgorithm( std::string_view name ) const {
115 return m_algsMap.find( std::string( name ) ) != m_algsMap.end();
116}
117
118std::vector<IAlgorithm*> AlgorithmManager::getAlgorithms() const {
119 std::vector<IAlgorithm*> listOfPtrs;
120 listOfPtrs.reserve( m_algs.size() );
121 std::transform( std::begin( m_algs ), std::end( m_algs ), std::back_inserter( listOfPtrs ),
122 []( const AlgorithmItem& alg ) { return alg.algorithm; } );
123 return listOfPtrs;
124}
125
127 StatusCode rc;
128 for ( auto& it : m_algs ) {
129 if ( !it.managed || it.algorithm->FSMState() >= Gaudi::StateMachine::INITIALIZED ) continue;
130 rc = it.algorithm->sysInitialize();
131 if ( rc.isFailure() ) return rc;
132 }
133 return rc;
134}
135
137 StatusCode rc;
138 for ( auto& it : m_algs ) {
139 if ( !it.managed || it.algorithm->FSMState() >= Gaudi::StateMachine::RUNNING ) continue;
140 rc = it.algorithm->sysStart();
141 if ( rc.isFailure() ) return rc;
142 }
143 return rc;
144}
145
147 StatusCode rc;
148 for ( auto& it : m_algs ) {
149 if ( !it.managed ) continue;
150 rc = it.algorithm->sysStop();
151 if ( rc.isFailure() ) return rc;
152 }
153 return rc;
154}
155
157 StatusCode rc;
158 auto it = m_algs.begin();
159 while ( it != m_algs.end() ) { // finalize and remove from the list the managed algorithms
160 if ( it->managed ) {
161 auto range = m_algsMap.equal_range( it->algorithm->name() );
162 auto itm = std::find_if( range.first, range.second, [&]( auto const& p ) { return p.second == it->algorithm; } );
163 if ( itm == range.second ) { return StatusCode::FAILURE; }
164
165 rc = it->algorithm->sysFinalize();
166 if ( rc.isFailure() ) return rc;
167
168 it = m_algs.erase( it );
169 m_algsMap.erase( itm );
170 } else {
171 ++it;
172 }
173 }
174 return rc;
175}
176
178 StatusCode rc;
179 for ( auto& it : m_algs ) {
180 if ( !it.managed ) continue;
181 rc = it.algorithm->sysReinitialize();
182 if ( rc.isFailure() ) {
183 this->error() << "Unable to re-initialize algorithm: " << it.algorithm->name() << endmsg;
184 return rc;
185 }
186 }
187 return rc;
188}
189
192 m_aess = serviceLocator()->service( "AlgExecStateSvc" );
193 if ( !m_aess.isValid() ) {
194 fatal() << "Error retrieving AlgExecStateSvc" << endmsg;
195 return StatusCode::FAILURE;
196 }
197
198 StatusCode rc;
199
200 for ( auto& it : m_algs ) {
201 if ( !it.managed ) continue;
202 rc = it.algorithm->sysRestart();
203 m_aess->resetErrorCount( it.algorithm );
204 if ( rc.isFailure() ) {
205 this->error() << "Unable to re-initialize algorithm: " << it.algorithm->name() << endmsg;
206 return rc;
207 }
208 }
209 return rc;
210}
211
214 for ( auto& algItem : m_algs ) {
215 const auto alg = dynamic_cast<Gaudi::Algorithm*>( algItem.algorithm );
216 if ( alg ) alg->resetMessaging();
217 }
218}
bool isValidInterface(IFace *i)
Templated function that throws an exception if the version if the interface implemented by the object...
Definition IInterface.h:354
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
SmartIF< IAlgorithm > & algorithm(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true) override
AlgorithmManager(IInterface *iface)
default creator
std::vector< IAlgorithm * > getAlgorithms() const override
implementation of IAlgManager::getAlgorithms
AlgTypeAliasesMap m_algTypeAliases
StatusCode start() override
Start (from INITIALIZED to RUNNING).
StatusCode finalize() override
Finalize (from INITIALIZED to CONFIGURED).
StatusCode stop() override
Stop (from RUNNING to INITIALIZED).
StatusCode addAlgorithm(IAlgorithm *alg) override
implementation of IAlgManager::addAlgorithm
bool existsAlgorithm(std::string_view name) const override
implementation of IAlgManager::existsAlgorithm
std::vector< AlgorithmItem > m_algs
algorithms maintained by AlgorithmManager
StatusCode removeAlgorithm(IAlgorithm *alg) override
implementation of IAlgManager::removeAlgorithm
StatusCode reinitialize() override
Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).
StatusCode createAlgorithm(const std::string &algtype, const std::string &algname, IAlgorithm *&algorithm, bool managed=false, bool checkIfExists=true) override
implementation of IAlgManager::createAlgorithm
StatusCode initialize() override
Initialization (from CONFIGURED to INITIALIZED).
StatusCode restart() override
Initialization (from RUNNING to RUNNING, via INITIALIZED).
std::unordered_multimap< std::string, SmartIF< IAlgorithm > > m_algsMap
algorithms maintained by AlgorithmManager
const std::string & name() const override
Return the name of the manager (implementation of INamedInterface)
void outputLevelUpdate() override
Function to call to update the outputLevel of the components (after a change in MessageSvc).
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
MsgStream & err() const
shortcut for the method msgStream(MSG::ERROR)
Gaudi::StateMachine::State targetFSMState() const override
When we are in the middle of a transition, get the state where the transition is leading us.
SmartIF< ISvcLocator > & serviceLocator() const override
Base class from which all concrete algorithm classes should be derived.
Definition Algorithm.h:87
Helper class to parse a string of format "type/name".
The IAlgorithm is the interface implemented by the Algorithm base class.
Definition IAlgorithm.h:36
Definition of the basic interface.
Definition IInterface.h:225
virtual SmartIF< IService > & service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
Small smart pointer class with automatic reference counting for IInterface.
Definition SmartIF.h:28
bool isValid() const
Allow for check if smart pointer is valid.
Definition SmartIF.h:69
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isSuccess() const
Definition StatusCode.h:314
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
Definition System.cpp:234
static const InterfaceID & interfaceID()