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}; } );