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