7 #include "boost/lexical_cast.hpp" 8 #include "boost/tokenizer.hpp" 9 #include "range/v3/algorithm/for_each.hpp" 10 #include "range/v3/view/remove_if.hpp" 11 #include "range/v3/view/reverse.hpp" 12 #include "range/v3/view/transform.hpp" 19 struct AlgorithmRepr {
26 if ( a.parent.name() != typ ) s <<
"/" << a.parent.name();
31 struct DataObjIDSorter {
62 m_algorithms = instantiateAndInitializeAlgorithms( m_producers );
66 ranges::for_each( m_algorithms | ranges::view::transform( [](
const auto& entry ) {
return entry.alg; } ) |
67 ranges::view::remove_if( [](
const auto* alg ) {
return alg->cardinality() == 0; } ),
69 this->warning() <<
"non-reentrant algorithm: " << AlgorithmRepr{*alg} <<
endmsg;
74 msg <<
"Available DataProducers: ";
76 auto ) {
return os << AlgorithmRepr{*e.
alg}; } );
81 m_dependencies = mapProducers( m_algorithms );
93 for (
AlgEntry& algEntry : m_algorithms ) {
94 ss = algEntry.alg->sysStart();
96 error() <<
"Unable to start Algorithm: " << algEntry.alg->name() <<
endmsg;
101 for (
AlgEntry& algEntry : m_cfnodes ) {
102 ss = algEntry.alg->sysStart();
104 error() <<
"Unable to start Algorithm: " << algEntry.alg->name() <<
endmsg;
117 for (
AlgEntry& algEntry : m_algorithms ) {
118 ss = algEntry.alg->sysStop();
120 error() <<
"Unable to stop Algorithm: " << algEntry.alg->name() <<
endmsg;
125 for (
AlgEntry& algEntry : m_cfnodes ) {
126 ss = algEntry.alg->sysStop();
128 error() <<
"Unable to stop Algorithm: " << algEntry.alg->name() <<
endmsg;
137 ranges::for_each( m_algorithms | ranges::view::transform( &AlgEntry::alg ),
141 m_algorithms | ranges::view::remove_if( [](
const auto& entry ) {
return entry.requestCount != 0; } ) |
142 ranges::view::transform( &AlgEntry::alg ),
143 [&](
Algorithm* alg ) { this->warning() <<
"Unused algorithm: " << AlgorithmRepr{*alg} <<
endmsg; } );
144 m_algorithms.clear();
155 auto appMgr = service<IAlgManager>(
"ApplicationMgr" );
163 myIAlg = createAlgorithm( *
appMgr, theType, theName );
177 if ( sc.isFailure() ) {
193 for (
AlgEntry& alg : algorithms ) {
194 const auto&
output = alg.alg->dataDependencies( AccessMode::Write );
196 error() << AlgorithmRepr{*algorithms.back().alg} <<
" does not produce any data -- should not appear in list of " 197 "producers. Ignoring." 201 for (
auto id :
output ) {
202 if (
id.key().find(
":" ) != std::string::npos ) {
203 error() <<
" in Alg " << AlgorithmRepr{*alg.alg} <<
" alternatives are NOT allowed for outputs! id: " <<
id 207 auto r = producers.
emplace(
id, &alg );
209 if ( output.size() == 1 ) {
210 warning() <<
"multiple algorithms declare " <<
id <<
" as output! -- IGNORING " << AlgorithmRepr{*alg.alg}
213 error() <<
"multiple algorithms declate " <<
id <<
" as output; given that " << AlgorithmRepr{*alg.alg}
214 <<
" produces multiple outputs ";
216 error() <<
" this could lead to clashes in case any of the other " 217 "items is ever requested" 225 for (
auto& algEntry : algorithms ) {
226 auto input = sortedDataObjIDColl( algEntry.alg->dataDependencies( AccessMode::Read ) );
229 if (
id.key().find(
":" ) != std::string::npos ) {
230 warning() <<
" contains alternatives which require resolution...\n";
231 auto tokens = boost::tokenizer<boost::char_separator<char>>{
id.
key(), boost::char_separator<char>{
":"}};
234 if ( itok != tokens.end() ) {
235 warning() <<
"found matching output for " << *itok <<
" -- updating info\n";
236 id.updateKey( *itok );
237 warning() <<
"Please update input to not require alternatives, and " 238 "instead properly configure the dataloader" 241 error() <<
"failed to find alternate in global output list" 242 <<
" for id: " <<
id <<
" in Alg " << algEntry.alg <<
endmsg;
245 auto iproducer = producers.
find(
id );
246 if ( iproducer != producers.
end() ) {
247 algEntry.dependsOn.insert( iproducer->second );
268 for (
const auto& req : requested ) {
270 if (
id.key().find(
":" ) != std::string::npos ) {
271 warning() << req.
key() <<
" contains alternatives which require resolution...\n";
272 auto tokens = boost::tokenizer<boost::char_separator<char>>{
id.key(), boost::char_separator<char>{
":"}};
274 [&](
DataObjID t ) {
return m_dependencies.find( t ) != m_dependencies.end(); } );
275 if ( itok != tokens.end() ) {
276 warning() <<
"found matching output for " << *itok <<
" -- updating info\n";
277 id.updateKey( *itok );
278 warning() <<
"Please update input to not require alternatives, and " 279 "instead properly configure the dataloader" 282 error() <<
"failed to find alternate in global output list" 283 <<
" for id: " <<
id <<
endmsg;
286 auto i = m_dependencies.find(
id );
287 if ( i == m_dependencies.end() )
293 for (
auto current = deps.
begin(); current != deps.
end(); ++current ) {
295 [current](
auto& stopper ) {
return ( *current )->alg->name() == stopper; } ) ) {
298 for (
auto* entry : ( *current )->dependsOn ) {
309 return {
begin( range ),
end( range )};
320 if ( alg !=
end( m_cfnodes ) && alg->alg->type() != requested.
type() ) {
321 error() <<
"requested " << requested <<
" but have matching name with different type: " << alg->alg->
type()
324 if ( alg ==
end( m_cfnodes ) ) {
325 auto av = instantiateAndInitializeAlgorithms( {requested.
type() +
'/' + requested.
name()} );
326 assert( av.size() == 1 );
327 m_cfnodes.push_back(
std::move( av.front() ) );
328 alg =
std::next( m_cfnodes.rbegin() ).base();
330 assert( alg !=
end( m_cfnodes ) );
331 assert( alg->alg !=
nullptr );
333 [&requested](
auto& stopper ) {
return requested.
name() == stopper; } ) ==
std::end( stoppers ) ) {
334 result = algorithmsRequiredFor( alg->alg->dataDependencies( AccessMode::Read ), stoppers );
338 debug() <<
std::endl <<
"requested " << requested <<
" returning " <<
std::endl <<
" ";
340 auto ) {
return os << AlgorithmRepr{*a}; } );
341 debug() << std::endl <<
endmsg;
constexpr static const auto FAILURE
Definition of the MsgStream class used to transmit messages.
StatusCode initialize() override
Define general base for Gaudi exception.
std::map< DataObjID, AlgEntry * > mapProducers(std::vector< AlgEntry > &algorithms) const
const std::string & name() const override
The identifying name of the algorithm object.
StatusCode finalize() override
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
StatusCode start() override
IDataHandleMetadata::AccessMode AccessMode
::details::reverse_wrapper< T > reverse(T &&iterable)
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...
StatusCode finalize() override
StatusCode start() override
virtual StatusCode sysInitialize()=0
Initialization method invoked by the framework.
StatusCode stop() override
#define DECLARE_COMPONENT(type)
Helper class to parse a string of format "type/name".
This class is used for returning status codes from appropriate routines.
std::vector< AlgEntry > instantiateAndInitializeAlgorithms(const std::vector< std::string > &names) const
const std::string & key() const
StatusCode sysFinalize() override
System finalization.
decltype(auto) range(Args &&...args)
Zips multiple containers together to form a single range.
StatusCode stop() override
std::vector< Algorithm * > algorithmsRequiredFor(const DataObjIDColl &requested, const std::vector< std::string > &stoppers={}) const override
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{})
Base class from which all concrete algorithm classes should be derived.
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
const std::string & type() const
StatusCode initialize() override
AttribStringParser::Iterator begin(const AttribStringParser &parser)
const std::string & name() const
std::string fullKey() const
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
std::ostream & operator<<(std::ostream &str, const GaudiAlg::ID &id)
Operator overloading for ostream.