15 #include "boost/lexical_cast.hpp"
16 #include "boost/tokenizer.hpp"
20 #ifdef __cpp_lib_ranges
22 namespace ranges = std::ranges;
24 # include "range/v3/algorithm/for_each.hpp"
25 # include "range/v3/view/filter.hpp"
26 # include "range/v3/view/reverse.hpp"
27 # include "range/v3/view/transform.hpp"
29 # if RANGE_V3_VERSION < 900
31 using namespace ranges::view;
39 struct AlgorithmRepr {
45 if ( a.parent.name() != typ )
s <<
"/" << a.parent.name();
50 struct DataObjIDSorter {
58 v.reserve( coll.
size() );
59 for (
const DataObjID&
id : coll )
v.push_back( &
id );
75 m_algorithms = instantiateAndInitializeAlgorithms( m_producers );
78 ranges::for_each( m_algorithms | ranges::views::transform( [](
const auto& entry ) {
return entry.alg; } ) |
79 ranges::views::filter( [](
const auto*
alg ) {
return alg->cardinality() > 0; } ),
81 this->warning() <<
"non-reentrant algorithm: " << AlgorithmRepr{ *
alg } <<
endmsg;
86 msg <<
"Available DataProducers: ";
88 msg, m_algorithms,
", ",
89 [](
auto& os,
const AlgEntry& e ) -> decltype(
auto ) {
return os << AlgorithmRepr{ *e.
alg }; } );
94 m_dependencies = mapProducers( m_algorithms );
104 for (
AlgEntry& algEntry : m_algorithms ) {
105 ss = algEntry.alg->sysStart();
107 error() <<
"Unable to start Algorithm: " << algEntry.alg->name() <<
endmsg;
112 for (
AlgEntry& algEntry : m_cfnodes ) {
113 ss = algEntry.alg->sysStart();
115 error() <<
"Unable to start Algorithm: " << algEntry.alg->name() <<
endmsg;
127 for (
AlgEntry& algEntry : m_algorithms ) {
128 ss = algEntry.alg->sysStop();
130 error() <<
"Unable to stop Algorithm: " << algEntry.alg->name() <<
endmsg;
135 for (
AlgEntry& algEntry : m_cfnodes ) {
136 ss = algEntry.alg->sysStop();
138 error() <<
"Unable to stop Algorithm: " << algEntry.alg->name() <<
endmsg;
147 alg->sysFinalize().ignore( );
149 m_algorithms.clear();
159 auto appMgr = service<IAlgManager>(
"ApplicationMgr" );
167 myIAlg = createAlgorithm( *
appMgr, theType, theName );
175 throw GaudiException{
"Failed to create " + boost::lexical_cast<std::string>( item ), __func__,
182 throw GaudiException{
"Failed to initialize " + boost::lexical_cast<std::string>( item ), __func__,
195 debug() <<
"Data Dependencies for Algorithms:";
196 for (
const auto& entry : m_algorithms ) {
197 debug() <<
"\n " << entry.alg->name() <<
" :";
198 for (
const auto*
id : sortedDataObjIDColl( entry.alg->inputDataObjs() ) ) {
199 debug() <<
"\n o INPUT " <<
id->key();
201 for (
const auto*
id : sortedDataObjIDColl( entry.alg->outputDataObjs() ) ) {
202 debug() <<
"\n o OUTPUT " <<
id->key();
211 const auto&
output =
alg.alg->outputDataObjs();
212 if (
output.empty() ) {
continue; }
213 for (
auto id :
output ) {
214 if (
id.
key().find(
":" ) != std::string::npos ) {
215 error() <<
" in Alg " << AlgorithmRepr{ *
alg.alg } <<
" alternatives are NOT allowed for outputs! id: " <<
id
221 throw GaudiException(
"multiple algorithms declare " +
id.
key() +
" as output (" +
alg.alg->name() +
" and " +
222 producers[
id]->alg->name() +
" at least). This is not allowed",
230 auto input = sortedDataObjIDColl( algEntry.alg->inputDataObjs() );
233 if (
id.
key().find(
":" ) != std::string::npos ) {
234 warning() << AlgorithmRepr{ *( algEntry.alg ) } <<
" contains alternatives which require resolution...\n";
235 auto tokens = boost::tokenizer<boost::char_separator<char>>{
id.
key(), boost::char_separator<char>{
":" } };
237 [&](
DataObjID t ) { return producers.find( t ) != producers.end(); } );
238 if ( itok != tokens.end() ) {
239 warning() <<
"found matching output for " << *itok <<
" -- updating info\n";
240 id.updateKey( *itok );
241 warning() <<
"Please update input to not require alternatives, and "
242 "instead properly configure the dataloader"
245 error() <<
"failed to find alternate in global output list"
246 <<
" for id: " <<
id <<
" in Alg " << algEntry.alg <<
endmsg;
249 auto iproducer = producers.
find(
id );
250 if ( iproducer != producers.
end() ) {
251 algEntry.dependsOn.insert( iproducer->second );
254 error_message <<
"\nUnknown requested input by " << AlgorithmRepr{ *( algEntry.alg ) } <<
" : "
255 << std::quoted(
id.
key(),
'\'' ) <<
".\n";
256 error_message <<
"You can set the OutputLevel of HiveDataBrokerSvc to DEBUG to get a list of inputs and "
257 "outputs of every registered algorithm.\n";
278 for (
const auto& req : requested ) {
280 if (
id.
key().find(
":" ) != std::string::npos ) {
281 warning() << req.
key() <<
" contains alternatives which require resolution...\n";
282 auto tokens = boost::tokenizer<boost::char_separator<char>>{
id.key(), boost::char_separator<char>{
":" } };
284 [&](
DataObjID t ) { return m_dependencies.find( t ) != m_dependencies.end(); } );
285 if ( itok != tokens.end() ) {
286 warning() <<
"found matching output for " << *itok <<
" -- updating info\n";
287 id.updateKey( *itok );
288 warning() <<
"Please update input to not require alternatives, and "
289 "instead properly configure the dataloader"
292 error() <<
"failed to find alternate in global output list"
293 <<
" for id: " <<
id <<
endmsg;
296 auto i = m_dependencies.find(
id );
297 if ( i == m_dependencies.end() )
307 for (
auto current = deps.
begin(); current != deps.
end(); ++current ) {
309 [current](
auto& stopper ) {
return ( *current )->alg->name() == stopper; } ) ) {
312 for (
auto* entry : ( *current )->dependsOn ) {
334 if (
alg !=
end( m_cfnodes ) &&
alg->alg->type() != requested.
type() ) {
335 error() <<
"requested " << requested <<
" but have matching name with different type: " <<
alg->alg->type()
338 if (
alg ==
end( m_cfnodes ) ) {
339 auto av = instantiateAndInitializeAlgorithms( { requested.
type() +
'/' + requested.
name() } );
340 assert( av.size() == 1 );
341 m_cfnodes.push_back(
std::move( av.front() ) );
344 assert(
alg !=
end( m_cfnodes ) );
345 assert(
alg->alg !=
nullptr );
347 [&requested](
auto& stopper ) {
return requested.
name() == stopper; } ) ==
std::end( stoppers ) ) {
348 result = algorithmsRequiredFor(
alg->alg->inputDataObjs(), stoppers );
352 debug() <<
std::endl <<
"requested " << requested <<
" returning " <<
std::endl <<
" ";
354 debug(), result,
",\n ",
355 [](
auto& os,
const Gaudi::Algorithm* a ) -> decltype(
auto ) {
return os << AlgorithmRepr{ *a }; } );