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