The Gaudi Framework  master (d98a2936)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 
20 #include <errno.h>
21 
23 static 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 );
32  return StatusCode::SUCCESS;
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 );
45  return StatusCode::SUCCESS;
46 }
47 
48 StatusCode 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
54  return StatusCode::FAILURE;
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;
74  return StatusCode::FAILURE;
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;
79  return StatusCode::FAILURE;
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 
114 bool AlgorithmManager::existsAlgorithm( std::string_view name ) const {
115  return m_algsMap.find( std::string( name ) ) != m_algsMap.end();
116 }
117 
118 std::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 
213  resetMessaging();
214  for ( auto& algItem : m_algs ) {
215  const auto alg = dynamic_cast<Gaudi::Algorithm*>( algItem.algorithm );
216  if ( alg ) alg->resetMessaging();
217  }
218 }
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:114
AlgorithmManager::restart
StatusCode restart() override
Initialization (from RUNNING to RUNNING, via INITIALIZED).
Definition: AlgorithmManager.cpp:190
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:212
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:156
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:126
AlgorithmManager::getAlgorithms
std::vector< IAlgorithm * > getAlgorithms() const override
implementation of IAlgManager::getAlgorithms
Definition: AlgorithmManager.cpp:118
AlgorithmManager::removeAlgorithm
StatusCode removeAlgorithm(IAlgorithm *alg) override
implementation of IAlgManager::removeAlgorithm
Definition: AlgorithmManager.cpp:35
Algorithm.h
SmartIF< IAlgorithm >
AlgorithmManager::start
StatusCode start() override
Start (from INITIALIZED to RUNNING).
Definition: AlgorithmManager.cpp:136
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:100
AlgorithmManager::AlgorithmItem
Definition: AlgorithmManager.h:41
AlgorithmManager::addAlgorithm
StatusCode addAlgorithm(IAlgorithm *alg) override
implementation of IAlgManager::addAlgorithm
Definition: AlgorithmManager.cpp:29
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:25
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:234
AlgorithmManager::reinitialize
StatusCode reinitialize() override
Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).
Definition: AlgorithmManager.cpp:177
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:146
MsgStream.h
Gaudi::Functional::details::zip::range
decltype(auto) range(Args &&... args)
Zips multiple containers together to form a single range.
Definition: details.h:86
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:48