15 #include "boost/lexical_cast.hpp" 16 #include "boost/tokenizer.hpp" 17 #include "range/v3/algorithm/for_each.hpp" 18 #include "range/v3/view/remove_if.hpp" 19 #include "range/v3/view/reverse.hpp" 20 #include "range/v3/view/transform.hpp" 27 struct AlgorithmRepr {
33 if ( a.parent.name() != typ )
s <<
"/" << a.parent.name();
38 struct DataObjIDSorter {
56 return {sc.
isSuccess() ? dynamic_cast<Gaudi::Algorithm*>( tmp ) : nullptr};
68 ranges::for_each(
m_algorithms | ranges::view::transform( [](
const auto& entry ) {
return entry.alg; } ) |
69 ranges::view::remove_if( [](
const auto*
alg ) {
return alg->cardinality() == 0; } ),
71 this->
warning() <<
"non-reentrant algorithm: " << AlgorithmRepr{*
alg} <<
endmsg;
76 msg <<
"Available DataProducers: ";
79 [](
auto& os,
const AlgEntry& e ) -> decltype(
auto ) {
return os << AlgorithmRepr{*e.
alg}; } );
95 ss = algEntry.alg->sysStart();
97 error() <<
"Unable to start Algorithm: " << algEntry.alg->name() <<
endmsg;
103 ss = algEntry.alg->sysStart();
105 error() <<
"Unable to start Algorithm: " << algEntry.alg->name() <<
endmsg;
118 ss = algEntry.alg->sysStop();
120 error() <<
"Unable to stop Algorithm: " << algEntry.alg->name() <<
endmsg;
126 ss = algEntry.alg->sysStop();
128 error() <<
"Unable to stop Algorithm: " << algEntry.alg->name() <<
endmsg;
148 auto appMgr = service<IAlgManager>(
"ApplicationMgr" );
156 myIAlg = createAlgorithm( *
appMgr, theType, theName );
164 throw GaudiException{
"Failed to create " + boost::lexical_cast<std::string>( item ), __func__,
171 throw GaudiException{
"Failed to initialize " + boost::lexical_cast<std::string>( item ), __func__,
184 debug() <<
"Data Dependencies for Algorithms:";
186 debug() <<
"\n " << entry.alg->name() <<
" :";
187 for (
const auto*
id : sortedDataObjIDColl( entry.alg->inputDataObjs() ) ) {
188 debug() <<
"\n o INPUT " <<
id->key();
190 for (
const auto*
id : sortedDataObjIDColl( entry.alg->outputDataObjs() ) ) {
191 debug() <<
"\n o OUTPUT " <<
id->key();
200 const auto&
output =
alg.alg->outputDataObjs();
201 if (
output.empty() ) {
continue; }
202 for (
auto id :
output ) {
203 if (
id.key().find(
":" ) != std::string::npos ) {
204 error() <<
" in Alg " << AlgorithmRepr{*
alg.alg} <<
" alternatives are NOT allowed for outputs! id: " <<
id 210 throw GaudiException(
"multiple algorithms declare " +
id.key() +
" as output (" +
alg.alg->name() +
" and " +
211 producers[id]->alg->name() +
" at least). This is not allowed",
218 for (
auto& algEntry : algorithms ) {
219 auto input = sortedDataObjIDColl( algEntry.alg->inputDataObjs() );
222 if (
id.key().find(
":" ) != std::string::npos ) {
223 warning() << AlgorithmRepr{*( algEntry.alg )} <<
" contains alternatives which require resolution...\n";
224 auto tokens = boost::tokenizer<boost::char_separator<char>>{
id.key(), boost::char_separator<char>{
":"}};
227 if ( itok != tokens.end() ) {
228 warning() <<
"found matching output for " << *itok <<
" -- updating info\n";
229 id.updateKey( *itok );
230 warning() <<
"Please update input to not require alternatives, and " 231 "instead properly configure the dataloader" 234 error() <<
"failed to find alternate in global output list" 235 <<
" for id: " <<
id <<
" in Alg " << algEntry.alg <<
endmsg;
238 auto iproducer = producers.
find(
id );
239 if ( iproducer != producers.
end() ) {
240 algEntry.
dependsOn.insert( iproducer->second );
243 error_message <<
"\nUnknown requested input by " << AlgorithmRepr{*( algEntry.alg )} <<
" : " <<
id.key()
245 error_message <<
"You can set the OutputLevel of HiveDataBrokerSvc to DEBUG to get a list of inputs and " 246 "outputs of every algorithm.\n";
267 for (
const auto& req : requested ) {
269 if (
id.key().find(
":" ) != std::string::npos ) {
270 warning() << req.key() <<
" contains alternatives which require resolution...\n";
271 auto tokens = boost::tokenizer<boost::char_separator<char>>{
id.key(), boost::char_separator<char>{
":"}};
274 if ( itok != tokens.end() ) {
275 warning() <<
"found matching output for " << *itok <<
" -- updating info\n";
276 id.updateKey( *itok );
277 warning() <<
"Please update input to not require alternatives, and " 278 "instead properly configure the dataloader" 281 error() <<
"failed to find alternate in global output list" 282 <<
" for id: " <<
id <<
endmsg;
292 for (
auto current = deps.
begin(); current != deps.
end(); ++current ) {
294 [current](
auto& stopper ) {
return ( *current )->alg->name() == stopper; } ) ) {
297 for (
auto* entry : ( *current )->dependsOn ) {
320 error() <<
"requested " << requested <<
" but have matching name with different type: " <<
alg->alg->type()
325 assert( av.size() == 1 );
330 assert(
alg->alg !=
nullptr );
332 [&requested](
auto& stopper ) {
return requested.
name() == stopper; } ) ==
std::end( stoppers ) ) {
339 debug(), result,
",\n ",
340 [](
auto& os,
const Gaudi::Algorithm* a ) -> decltype(
auto ) {
return os << AlgorithmRepr{*a}; } );
Definition of the MsgStream class used to transmit messages.
StatusCode initialize() override
Define general base for Gaudi exception.
StatusCode finalize() override
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
StatusCode start() override
::details::reverse_wrapper< T > reverse(T &&iterable)
std::vector< AlgEntry > m_cfnodes
The IAlgManager is the interface implemented by the Algorithm Factory in the Application Manager to s...
virtual StatusCode createAlgorithm(const std::string &algtype, const std::string &algname, IAlgorithm *&alg, bool managed=false, bool checkIfExists=true)=0
Create an instance of a algorithm type that has been declared beforehand and assigns to it a name.
std::map< DataObjID, AlgEntry * > mapProducers(std::vector< AlgEntry > &algorithms) const
const std::string & type() const
StatusCode finalize() override
StatusCode start() override
std::map< DataObjID, AlgEntry * > m_dependencies
std::string fullKey() const
virtual StatusCode sysInitialize()=0
Initialization method invoked by the framework.
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
StatusCode stop() override
#define DECLARE_COMPONENT(type)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
std::set< AlgEntry * > dependsOn
Helper class to parse a string of format "type/name".
const std::string & name() const
This class is used for returning status codes from appropriate routines.
Gaudi::Property< std::vector< std::string > > m_producers
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
StatusCode stop() override
std::vector< AlgEntry > m_algorithms
The IAlgorithm is the interface implemented by the Algorithm base class.
Stream & ostream_joiner(Stream &os, Iterator first, Iterator last, Separator sep, OutputElement output=OutputElement{})
std::vector< Gaudi::Algorithm * > algorithmsRequiredFor(const DataObjIDColl &requested, const std::vector< std::string > &stoppers={}) const override
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
Base class from which all concrete algorithm classes should be derived.
constexpr static const auto FAILURE
std::vector< AlgEntry > instantiateAndInitializeAlgorithms(const std::vector< std::string > &names) const
decltype(auto) range(Args &&... args)
Zips multiple containers together to form a single range.
StatusCode initialize() override
AttribStringParser::Iterator begin(const AttribStringParser &parser)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
const std::string & name() const override
The identifying name of the algorithm object.
std::ostream & operator<<(std::ostream &str, const GaudiAlg::ID &id)
Operator overloading for ostream.
T emplace_back(T... args)