18 #include <boost/lexical_cast.hpp> 
   19 #include <boost/tokenizer.hpp> 
   22 #ifdef __cpp_lib_ranges 
   24 namespace ranges = std::ranges;
 
   26 #  include <range/v3/algorithm/for_each.hpp> 
   27 #  include <range/v3/view/filter.hpp> 
   28 #  include <range/v3/view/reverse.hpp> 
   29 #  include <range/v3/view/transform.hpp> 
   31 #  if RANGE_V3_VERSION < 900 
   33   using namespace ranges::view;
 
   40   using extends::extends;
 
   54                                              "Attribute any unmet input dependencies to this Algorithm" };
 
   56       this, 
"DataProducers", {}, 
"List of algorithms to be used to resolve data dependencies" };
 
   94   struct AlgorithmRepr {
 
  100       if ( a.parent.name() != typ ) 
s << 
"/" << a.parent.name();
 
  109     v.reserve( coll.
size() );
 
  110     for ( 
const DataObjID& 
id : coll ) 
v.push_back( &
id );
 
  112                []( 
const DataObjID* a, 
const DataObjID* b ) { return a->fullKey() < b->fullKey(); } );
 
  116   template <
typename T>
 
  119     std::sort( 
v.begin(), 
v.end(), []( 
const auto* lhs, 
const auto* rhs ) { return *lhs < *rhs; } );
 
  134     m_algorithms = instantiateAndInitializeAlgorithms( m_producers );
 
  137     ranges::for_each( m_algorithms | ranges::views::transform( []( 
const auto& entry ) { 
return entry.second.alg; } ) |
 
  138                           ranges::views::filter( []( 
const auto* 
alg ) { 
return alg->cardinality() > 0; } ),
 
  140                         this->warning() << 
"non-reentrant algorithm: " << AlgorithmRepr{ *
alg } << 
endmsg;
 
  145       msg << 
"Available DataProducers: ";
 
  148             return os << AlgorithmRepr{ *e.second.alg };
 
  154     m_dependencies = mapProducers( m_algorithms );
 
  164   for ( 
auto& [
name, algEntry] : m_algorithms ) {
 
  165     ss = algEntry.alg->sysStart();
 
  167       error() << 
"Unable to start Algorithm: " << 
name << 
endmsg;
 
  179   for ( 
auto& [
name, algEntry] : m_algorithms ) {
 
  180     ss = algEntry.alg->sysStop();
 
  182       error() << 
"Unable to stop Algorithm: " << 
name << 
endmsg;
 
  190   for ( 
auto& [
name, algEntry] : m_algorithms ) {
 
  191     algEntry.alg->sysFinalize().
ignore(  );
 
  193   m_algorithms.clear();
 
  202   auto   appMgr = service<IAlgManager>( 
"ApplicationMgr" );
 
  218       throw GaudiException{ 
"Failed to create " + boost::lexical_cast<std::string>( item ), __func__,
 
  225       throw GaudiException{ 
"Failed to initialize " + boost::lexical_cast<std::string>( item ), __func__,
 
  238     debug() << 
"Data Dependencies for Algorithms:";
 
  239     for ( 
const auto& [
name, entry] : m_algorithms ) {
 
  240       debug() << 
"\n " << 
name << 
" :";
 
  241       for ( 
const auto* 
id : sorted_( entry.alg->inputDataObjs() ) ) { debug() << 
"\n    o INPUT  " << 
id->key(); }
 
  242       for ( 
const auto* 
id : sorted_( entry.alg->outputDataObjs() ) ) { debug() << 
"\n    o OUTPUT " << 
id->key(); }
 
  250     const auto& 
output = 
alg.alg->outputDataObjs();
 
  251     if ( 
output.empty() ) { 
continue; }
 
  252     for ( 
auto id : 
output ) {
 
  256                                   producers[
id]->
alg->name() + 
" at least). This is not allowed",
 
  264     auto input = sorted_( algEntry.alg->inputDataObjs() );
 
  267       auto      iproducer = producers.
find( 
id );
 
  268       if ( iproducer != producers.
end() ) {
 
  269         algEntry.dependsOn.insert( iproducer->second );
 
  272         error_message << 
"\nUnknown requested input by " << AlgorithmRepr{ *( algEntry.alg ) } << 
" : " 
  273                       << std::quoted( 
id.
key(), 
'\'' ) << 
".\n";
 
  274         error_message << 
"You can set the OutputLevel of HiveDataBrokerSvc to DEBUG to get a list of inputs and " 
  275                          "outputs of every registered algorithm.\n";
 
  291   assert( visited.
size() == m_algorithms.size() );
 
  292   assert( visiting.
size() == m_algorithms.size() );
 
  293   if ( visited[
alg.index] ) { 
return; }
 
  297                      [
alg]( 
auto& stopper ) { 
return alg.alg->name() == stopper; } ) ) {
 
  298     visiting[
alg.index] = 
true;
 
  299     for ( 
auto* dep : sorted_( 
alg.dependsOn ) ) { visit( *dep, stoppers, sorted, visited, visiting ); }
 
  300     visiting[
alg.index] = 
false;
 
  303   visited[
alg.index] = 
true;
 
  316   for ( 
const auto& 
id : requested ) {
 
  317     auto i = m_dependencies.find( 
id );
 
  318     if ( i == m_dependencies.end() )
 
  323   std::sort( deps.
begin(), deps.
end(), []( 
auto const* lhs, 
auto const* rhs ) { return *lhs < *rhs; } );
 
  324   deps.
erase( 
std::unique( deps.
begin(), deps.
end(), []( 
auto const& lhs, 
auto const& rhs ) { return *lhs == *rhs; } ),
 
  329   for ( 
auto* 
alg : deps ) { visit( *
alg, stoppers, result, visited, visiting ); }
 
  338   auto it = m_algorithms.find( requested.
name() );
 
  339   if ( it == 
end( m_algorithms ) ) {
 
  340     throw GaudiException{ 
"No algorithm with name " + requested.
name() + 
" in DataProducers. Type is " +
 
  341                               ( requested.
haveType() ? requested.
type() : 
"not specified" ),
 
  344   auto const& 
alg = it->second;
 
  346     error() << 
"requested " << requested << 
" but have matching name with different type: " << 
alg.alg->type()
 
  349   assert( 
alg.alg != 
nullptr );
 
  353   visit( 
alg, stoppers, result, visited, visiting );
 
  356     debug() << 
std::endl << 
"requested " << requested << 
" returning " << 
std::endl << 
"  ";
 
  358         debug(), result, 
",\n  ",
 
  359         []( 
auto& os, 
const Gaudi::Algorithm* a ) -> decltype( 
auto ) { 
return os << AlgorithmRepr{ *a }; } );