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