The Gaudi Framework  master (37c0b60a)
DataHandleHolderVisitor.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #include <GaudiKernel/DataHandle.h>
13 #include <GaudiKernel/DataObjID.h>
16 #include <functional>
17 #include <tuple>
18 #include <typeinfo>
19 
20 namespace {
21  using std::make_tuple;
22 }
23 
24 DHHVisitor::DHHVisitor( DataObjIDColl& ido, DataObjIDColl& odo ) : m_ido( ido ), m_odo( odo ) {}
25 
27  if ( !v ) { return; }
28 
29  // Record the name of the first IDataHandleHolder we encounter, for cleaner report
30  if ( m_initialName.empty() ) m_initialName = v->name();
31 
32  // Loop over inputs and outputs of handles, extra dependiencies and objects to
33  // collect all of them.
34  // Handles and extra dependencies are those of a specific algorith or tool, while
35  // the collection of data objects also contains those of the tree of tools and
36  // algorithms below it.
37 
38  // Loop over input handles and output handles and store those with with non-empty keys
39  // in the container of input objects passed to us and the others in a container of those
40  // we ignore for debug purposes. To avoid multiple for loops, make some tuples and loop
41  // over those.
42  for ( auto& hs : { make_tuple( v->inputHandles(), std::ref( m_ido ), std::ref( m_ign_i ) ),
43  make_tuple( v->outputHandles(), std::ref( m_odo ), std::ref( m_ign_o ) ) } ) {
44  for ( const auto& h : std::get<0>( hs ) ) {
45  if ( !h->objKey().empty() ) {
46  std::get<1>( hs ).emplace( h->fullKey() );
47  } else {
48  std::get<2>( hs ).emplace( h->fullKey() );
49  }
50  m_owners[h->fullKey()].emplace( v );
51  }
52  }
53 
54  for ( auto& id : v->extraInputDeps() ) { m_owners[id].emplace( v ); }
55  for ( auto& id : v->extraOutputDeps() ) { m_owners[id].emplace( v ); }
56 
57  // The containers of handles are a different type than the on of input deps and input
58  // objects, so we need another loop here.
59  // NOTE: perhaps a view from range v3 can be used to also avoid this second loop.
60  for ( auto& hs : { make_tuple( v->extraInputDeps(), std::ref( m_ido ), std::ref( m_ign_i ) ),
61  make_tuple( v->extraOutputDeps(), std::ref( m_odo ), std::ref( m_ign_o ) ),
62  make_tuple( v->inputDataObjs(), std::ref( m_ido ), std::ref( m_ign_i ) ),
63  make_tuple( v->outputDataObjs(), std::ref( m_odo ), std::ref( m_ign_o ) ) } ) {
64  for ( const auto& h : std::get<0>( hs ) ) {
65  if ( !h.key().empty() ) {
66  std::get<1>( hs ).emplace( h );
67  } else {
68  std::get<2>( hs ).emplace( h );
69  }
70  m_owners[h].emplace( v );
71  }
72  }
73 }
74 
76  if ( auto item = m_owners.find( id ); item != m_owners.end() ) {
77  return { item->second.begin(), item->second.end() };
78  }
79  return {};
80 }
81 
84  for ( auto owner : owners_of( id ) ) {
85  if ( with_main || owner->name() != m_initialName ) tmp.push_back( owner->name() );
86  }
87  if ( !tmp.empty() ) { std::sort( tmp.begin(), tmp.end() ); }
88  return tmp;
89 }
90 
92  // sort DataObjects by path so that logging is reproducible
93  // we define a little helper creating an ordered set from a non ordered one
94  auto sort = []( const DataObjID& a, const DataObjID& b ) -> bool { return a.fullKey() < b.fullKey(); };
95  auto orderset = [&sort]( const DataObjIDColl& in ) -> std::set<DataObjID, decltype( sort )> {
96  return { in.begin(), in.end(), sort };
97  };
98  auto write_owners_of = [this]( auto& stream, const DataObjID& id ) {
99  auto tmp = owners_names_of( id );
100  if ( !tmp.empty() ) { stream << ' ' << tmp; }
101  };
102 
103  for ( auto h : orderset( m_ido ) ) {
104  stream << "\n + INPUT " << h;
105  write_owners_of( stream, h );
106  }
107  for ( auto id : orderset( m_ign_i ) ) {
108  stream << "\n + INPUT IGNORED " << id;
109  write_owners_of( stream, id );
110  }
111  for ( auto h : orderset( m_odo ) ) {
112  stream << "\n + OUTPUT " << h;
113  write_owners_of( stream, h );
114  }
115  for ( auto id : orderset( m_ign_o ) ) {
116  stream << "\n + OUTPUT IGNORED " << id;
117  write_owners_of( stream, id );
118  }
119  return stream;
120 }
121 
122 bool DHHVisitor::empty() const {
123  // any data handle would have as side effect to add something to m_owners,
124  // so it's enough to check this instead of all the other containers
125  return m_owners.empty();
126 }
DHHVisitor::visit
void visit(const IDataHandleHolder *visitee) override
Definition: DataHandleHolderVisitor.cpp:26
IDataHandleHolder
Definition: IDataHandleHolder.h:24
DHHVisitor::m_ign_i
DataObjIDColl m_ign_i
Definition: DataHandleHolderVisitor.h:43
std::make_tuple
T make_tuple(T... args)
Write.stream
stream
Definition: Write.py:32
std::unordered_set
STL class.
DHHVisitor::empty
bool empty() const
return true if no DataHandle was found
Definition: DataHandleHolderVisitor.cpp:122
DHHVisitor::m_initialName
std::string m_initialName
Definition: DataHandleHolderVisitor.h:47
std::vector
STL class.
std::map::find
T find(T... args)
DHHVisitor::m_ido
DataObjIDColl & m_ido
Definition: DataHandleHolderVisitor.h:42
DHHVisitor::m_owners
std::map< DataObjID, std::set< const IDataHandleHolder * > > m_owners
Definition: DataHandleHolderVisitor.h:45
std::map::emplace
T emplace(T... args)
DataObjID.h
DHHVisitor::report
MsgStream & report(MsgStream &stream) const
Definition: DataHandleHolderVisitor.cpp:91
GaudiPartProp.tests.id
id
Definition: tests.py:111
std::sort
T sort(T... args)
DataObjID::fullKey
std::string fullKey() const
combination of the key and the ClassName, mostly for debugging
Definition: DataObjID.cpp:99
std::vector::push_back
T push_back(T... args)
DHHVisitor::DHHVisitor
DHHVisitor(DataObjIDColl &ido, DataObjIDColl &odo)
Definition: DataHandleHolderVisitor.cpp:24
DHHVisitor::owners_names_of
std::vector< std::string > owners_names_of(const DataObjID &id, bool with_main=false) const
Definition: DataHandleHolderVisitor.cpp:82
DHHVisitor::m_odo
DataObjIDColl & m_odo
Definition: DataHandleHolderVisitor.h:42
AlgSequencer.h
h
Definition: AlgSequencer.py:31
DataHandleHolderVisitor.h
MsgStream
Definition: MsgStream.h:33
DataObjID
Definition: DataObjID.h:47
DHHVisitor::m_ign_o
DataObjIDColl m_ign_o
Definition: DataHandleHolderVisitor.h:43
IDataHandleHolder.h
std::vector::begin
T begin(T... args)
DataHandle.h
std::string::empty
T empty(T... args)
Properties.v
v
Definition: Properties.py:122
SerializeSTL.h
std::map::end
T end(T... args)
DHHVisitor::owners_of
std::vector< const IDataHandleHolder * > owners_of(const DataObjID &id) const
Definition: DataHandleHolderVisitor.cpp:75
std::set
STL class.
std::ref
T ref(T... args)