15 #include "boost/lexical_cast.hpp"
16 #include "boost/tokenizer.hpp"
19 #ifdef __cpp_lib_ranges
21 namespace ranges = std::ranges;
23 # include "range/v3/algorithm/for_each.hpp"
24 # include "range/v3/view/filter.hpp"
25 # include "range/v3/view/reverse.hpp"
26 # include "range/v3/view/transform.hpp"
28 # if RANGE_V3_VERSION < 900
30 using namespace ranges::view;
38 struct AlgorithmRepr {
44 if ( a.parent.name() != typ )
s <<
"/" << a.parent.name();
49 struct DataObjIDSorter {
57 v.reserve( coll.
size() );
58 for (
const DataObjID&
id : coll )
v.push_back( &
id );
75 m_algorithms = instantiateAndInitializeAlgorithms( m_producers );
79 ranges::for_each( m_algorithms | ranges::views::transform( [](
const auto& entry ) {
return entry.alg; } ) |
80 ranges::views::filter( [](
const auto*
alg ) {
return alg->cardinality() > 0; } ),
82 this->warning() <<
"non-reentrant algorithm: " << AlgorithmRepr{*
alg} <<
endmsg;
87 msg <<
"Available DataProducers: ";
89 msg, m_algorithms,
", ",
90 [](
auto& os,
const AlgEntry& e ) -> decltype(
auto ) {
return os << AlgorithmRepr{*e.
alg}; } );
95 m_dependencies = mapProducers( m_algorithms );
105 for (
AlgEntry& algEntry : m_algorithms ) {
106 ss = algEntry.alg->sysStart();
108 error() <<
"Unable to start Algorithm: " << algEntry.alg->name() <<
endmsg;
113 for (
AlgEntry& algEntry : m_cfnodes ) {
114 ss = algEntry.alg->sysStart();
116 error() <<
"Unable to start Algorithm: " << algEntry.alg->name() <<
endmsg;
128 for (
AlgEntry& algEntry : m_algorithms ) {
129 ss = algEntry.alg->sysStop();
131 error() <<
"Unable to stop Algorithm: " << algEntry.alg->name() <<
endmsg;
136 for (
AlgEntry& algEntry : m_cfnodes ) {
137 ss = algEntry.alg->sysStop();
139 error() <<
"Unable to stop Algorithm: " << algEntry.alg->name() <<
endmsg;
148 alg->sysFinalize().ignore( );
150 m_algorithms.clear();
160 auto appMgr = service<IAlgManager>(
"ApplicationMgr" );
168 myIAlg = createAlgorithm( *
appMgr, theType, theName );
176 throw GaudiException{
"Failed to create " + boost::lexical_cast<std::string>( item ), __func__,
183 throw GaudiException{
"Failed to initialize " + boost::lexical_cast<std::string>( item ), __func__,
196 debug() <<
"Data Dependencies for Algorithms:";
197 for (
const auto& entry : m_algorithms ) {
198 debug() <<
"\n " << entry.alg->name() <<
" :";
199 for (
const auto*
id : sortedDataObjIDColl( entry.alg->inputDataObjs() ) ) {
200 debug() <<
"\n o INPUT " <<
id->key();
202 for (
const auto*
id : sortedDataObjIDColl( entry.alg->outputDataObjs() ) ) {
203 debug() <<
"\n o OUTPUT " <<
id->key();
212 const auto&
output =
alg.alg->outputDataObjs();
213 if (
output.empty() ) {
continue; }
214 for (
auto id :
output ) {
215 if (
id.
key().find(
":" ) != std::string::npos ) {
216 error() <<
" in Alg " << AlgorithmRepr{*
alg.alg} <<
" alternatives are NOT allowed for outputs! id: " <<
id
222 throw GaudiException(
"multiple algorithms declare " +
id.
key() +
" as output (" +
alg.alg->name() +
" and " +
223 producers[
id]->alg->name() +
" at least). This is not allowed",
231 auto input = sortedDataObjIDColl( algEntry.alg->inputDataObjs() );
234 if (
id.
key().find(
":" ) != std::string::npos ) {
235 warning() << AlgorithmRepr{*( algEntry.alg )} <<
" contains alternatives which require resolution...\n";
236 auto tokens = boost::tokenizer<boost::char_separator<char>>{
id.
key(), boost::char_separator<char>{
":"}};
238 [&](
DataObjID t ) { return producers.find( t ) != producers.end(); } );
239 if ( itok != tokens.end() ) {
240 warning() <<
"found matching output for " << *itok <<
" -- updating info\n";
241 id.updateKey( *itok );
242 warning() <<
"Please update input to not require alternatives, and "
243 "instead properly configure the dataloader"
246 error() <<
"failed to find alternate in global output list"
247 <<
" for id: " <<
id <<
" in Alg " << algEntry.alg <<
endmsg;
250 auto iproducer = producers.
find(
id );
251 if ( iproducer != producers.
end() ) {
252 algEntry.dependsOn.insert( iproducer->second );
255 error_message <<
"\nUnknown requested input by " << AlgorithmRepr{*( algEntry.alg )} <<
" : " <<
id.key()
257 error_message <<
"You can set the OutputLevel of HiveDataBrokerSvc to DEBUG to get a list of inputs and "
258 "outputs of every algorithm.\n";
279 for (
const auto& req : requested ) {
281 if (
id.
key().find(
":" ) != std::string::npos ) {
282 warning() << req.
key() <<
" contains alternatives which require resolution...\n";
283 auto tokens = boost::tokenizer<boost::char_separator<char>>{
id.key(), boost::char_separator<char>{
":"}};
285 [&](
DataObjID t ) { return m_dependencies.find( t ) != m_dependencies.end(); } );
286 if ( itok != tokens.end() ) {
287 warning() <<
"found matching output for " << *itok <<
" -- updating info\n";
288 id.updateKey( *itok );
289 warning() <<
"Please update input to not require alternatives, and "
290 "instead properly configure the dataloader"
293 error() <<
"failed to find alternate in global output list"
294 <<
" for id: " <<
id <<
endmsg;
297 auto i = m_dependencies.find(
id );
298 if ( i == m_dependencies.end() )
304 for (
auto current = deps.
begin(); current != deps.
end(); ++current ) {
306 [current](
auto& stopper ) {
return ( *current )->alg->name() == stopper; } ) ) {
309 for (
auto* entry : ( *current )->dependsOn ) {
331 if (
alg !=
end( m_cfnodes ) &&
alg->alg->type() != requested.
type() ) {
332 error() <<
"requested " << requested <<
" but have matching name with different type: " <<
alg->alg->type()
335 if (
alg ==
end( m_cfnodes ) ) {
336 auto av = instantiateAndInitializeAlgorithms( {requested.
type() +
'/' + requested.
name()} );
337 assert( av.size() == 1 );
338 m_cfnodes.push_back(
std::move( av.front() ) );
341 assert(
alg !=
end( m_cfnodes ) );
342 assert(
alg->alg !=
nullptr );
344 [&requested](
auto& stopper ) {
return requested.
name() == stopper; } ) ==
std::end( stoppers ) ) {
345 result = algorithmsRequiredFor(
alg->alg->inputDataObjs(), stoppers );
349 debug() <<
std::endl <<
"requested " << requested <<
" returning " <<
std::endl <<
" ";
351 debug(), result,
",\n ",
352 [](
auto& os,
const Gaudi::Algorithm* a ) -> decltype(
auto ) {
return os << AlgorithmRepr{*a}; } );