1 #ifndef GAUDIKERNEL_DATAHANDLEHOLDERBASE 2 #define GAUDIKERNEL_DATAHANDLEHOLDERBASE 1 6 #include <unordered_set> 9 #include <boost/optional.hpp> 26 template <
typename BASE>
34 template <
typename... Args>
46 if ( m_explicitDepsCollected && isNewDataDependency( handle ) ) {
47 throw GaudiException(
"Cannot register a new data handle after data dependency collection", this->
name(),
50 auto index = accessToIndex( handle.access() );
51 m_dataHandles[index].push_back( &handle );
64 auto index = accessToIndex( access );
65 m_dataDepKeys[index].insert( key );
75 auto index = accessToIndex( access );
76 return allDataDependencies()[index];
82 if ( m_explicitDepsCollected && isNewDataDependency( handle ) ) {
83 throw GaudiException(
"Cannot register a new data handle after data dependency collection", this->
name(),
87 if ( !handle.
owner() ) {
89 }
else if ( handle.
owner() != this ) {
93 m_legacyHandles.insert( &handle );
107 if ( m_explicitDepsCollected &&
109 throw GaudiException(
"Cannot discard legacy handle after data dependency collection", this->
name(),
113 if ( handle.
owner() != this ) {
117 m_legacyHandles.erase( &handle );
124 if ( !m_explicitDepsCollected ) {
125 throw GaudiException(
"Cannot read data dependencies before they are collected", this->
name(),
128 return m_dataDepKeys;
158 updateDependencies( m_dataHandles, keyMap );
159 updateDependencies( m_legacyHandles, keyMap );
160 updateDependencies( m_dataDepKeys, keyMap );
161 updateDependencies( m_extraDeps, keyMap );
177 if ( m_explicitDepsCollected ) {
182 collectDependencies( m_dataHandles );
183 collectDependencies( m_extraDeps );
184 collectDependencies( m_legacyHandles );
187 m_explicitDepsCollected =
true;
235 if ( !m_explicitDepsCollected ) {
246 const DataObjIDColl& outputKeys = m_dataDepKeys[accessToIndex( AccessMode::Write )];
247 DataObjIDColl& inputKeys = m_dataDepKeys[accessToIndex( AccessMode::Read )];
248 for (
const auto& outputKey : outputKeys ) {
249 auto inputPos = inputKeys.
find( outputKey );
250 if ( inputPos != inputKeys.
end() ) {
252 switch ( circularDepHandler( *inputPos ) ) {
254 case CircularDepAction::Abort:
258 case CircularDepAction::Ignore:
259 inputKeys.
erase( inputPos );
281 if ( !child )
return;
291 if ( !m_explicitDepsCollected ) {
292 throw GaudiException(
"Cannot read ignored data dependencies before they are collected", this->
name(),
295 return m_ignoredDataDeps[accessToIndex( access )];
305 for (
auto handle : m_legacyHandles ) handle->init();
307 for (
auto handleArray : m_dataHandles ) {
308 for (
auto handle : handleArray ) {
309 handle->initialize( *
this );
316 static constexpr
size_t NUM_ACCESS_MODES =
static_cast<size_t>( AccessMode::NUM_ACCESS_MODES );
327 static_assert( NUM_ACCESS_MODES == 2,
328 "This part of the code assumes that there are only two DataHandle access modes" );
329 static_assert( static_cast<size_t>( AccessMode::Read ) == 0,
330 "This part of the code assumes that \"Read\" comes first in the AccessMode enum" );
339 bool m_explicitDepsCollected =
false;
351 auto index = accessToIndex( handle.
access() );
352 return m_dataDepKeys[index].
find( handle.
targetKey() ) == m_dataDepKeys[index].
end();
360 auto index = accessToIndex( AccessMode::Read );
361 result &= ( m_dataDepKeys[index].
find( handle.
fullKey() ) == m_dataDepKeys[index].
end() );
364 auto index = accessToIndex( AccessMode::Write );
365 result &= ( m_dataDepKeys[index].
find( handle.
fullKey() ) == m_dataDepKeys[index].
end() );
380 template <
typename KeyHolder>
383 const DataObjID& key = accessKey( holder );
384 if ( !key.
empty() ) {
385 validOutput.
insert( key );
387 ignoredOutput.
insert( key );
398 template <
typename KeyHolderColl>
401 validOutput.
reserve( keyHolders.size() );
402 for (
const auto& holder : keyHolders ) {
403 extractKey( validOutput, ignoredOutput, holder );
407 template <
typename KeyHolderColl>
410 for (
size_t i = 0; i < NUM_ACCESS_MODES; ++i ) {
411 extractKeys( m_dataDepKeys[i], m_ignoredDataDeps[i], keyHolderArray[i] );
422 DataObjIDColl& validInputs = m_dataDepKeys[accessToIndex( AccessMode::Read )];
423 DataObjIDColl& validOutputs = m_dataDepKeys[accessToIndex( AccessMode::Write )];
424 DataObjIDColl& ignoredInputs = m_ignoredDataDeps[accessToIndex( AccessMode::Read )];
425 DataObjIDColl& ignoredOutputs = m_ignoredDataDeps[accessToIndex( AccessMode::Write )];
427 for (
auto handle : legacyHandles ) {
429 extractKey( validInputs, ignoredInputs, handle );
432 extractKey( validOutputs, ignoredOutputs, handle );
452 template <
typename KeyHolderColl>
455 for (
auto& holder : keyHolders ) {
456 const DataObjID& oldKey = accessKey( holder );
457 auto mappedKey = keyMap( oldKey );
459 updateKey( holder, *
std::move( mappedKey ) );
470 for (
const auto& key : keys ) {
471 result.
emplace( keyMap( key ).value_or( key ) );
479 updateDependencies( keys.
value(), keyMap );
483 template <
typename KeyHolderColl>
486 for (
size_t i = 0; i < NUM_ACCESS_MODES; ++i ) {
487 updateDependencies( keyHoldersArray[i], keyMap );
492 #endif // !GAUDIKERNEL_DATAHANDLEHOLDERBASE static size_t accessToIndex(AccessMode access)
Convert a data dependency access mode to its index in our internal storage.
DataHandleHolderBase(Args &&...args)
NOTE: Cannot use "using Super::Super;" due to a GCC 6 bug.
static void updateKey(Gaudi::v1::DataHandle *target, DataObjID &&key)
Update the key of a legacy (non-reentrant) DataHandle.
static void updateKey(DataObjID &target, DataObjID &&key)
Update the key of a DataObjID.
bool isNewDataDependency(const Gaudi::v2::DataHandle &handle) const
Check if a data dependency has not been declared before (new DataHandle version)
constexpr static const auto FAILURE
Define general base for Gaudi exception.
static void updateDependencies(KeyHolderColl keyHoldersArray[], const DataObjIDMapping &keyMap)
Specialization of the above algorithm for arrays of KeyHolderColls.
void collectDependencies(const KeyHolderColl keyHolderArray[])
void initializeDataHandleHolder()
Initialize the DataHandles.
Implementation of property with value of concrete type.
static void updateKey(Gaudi::v2::DataHandle *target, DataObjID &&key)
Update the key of a DataHandle.
IDataHandleMetadata::AccessMode AccessMode
void addDataDependency(const DataObjID &key, AccessMode access) final override
Add a data dependency, even after initialization.
const DataObjID & targetKey() const
(Configurable) ID of the data being accessed via this handle
virtual IDataHandleHolder * owner() const
void renounce(Gaudi::v1::DataHandle &handle) override
Discard ownership of a legacy DataHandle.
std::unordered_set< Gaudi::v1::DataHandle * > m_legacyHandles
void updateDataDependencies(const DataObjIDMapping &keyMap)
Update the key of each registered data dependency, using a user-defined mapping from the old to the n...
const DataObjIDColl & ignoredDataDependencies(AccessMode access) const
Tell which data dependencies have been ignored due to an empty key.
static void updateDependencies(Gaudi::Property< DataObjIDColl > &keys, const DataObjIDMapping &keyMap)
Specialization for properties which accesses the inner collection.
const DataObjIDColl * allDataDependencies() const final override
Entity which holds DataHandles and can track the associated data dependencies for the Scheduler...
virtual const DataObjIDColl * allDataDependencies() const =0
Access the internal array of data dependencies.
CircularDepAction
A circular dependency handling action.
Gaudi::v2::DataHandle::AccessMode AccessMode
void registerDataHandle(Gaudi::v2::DataHandle &handle) final override
Register a data handle of this algorithm/tool.
static const DataObjID & accessKey(const DataObjID &key)
Access the key of a DataObjID (identity function)
virtual void setOwner(IDataHandleHolder *o)
This class is used for returning status codes from appropriate routines.
void collectImplicitDataDependencies(const IDataHandleHolder *child)
Add the dependencies of another DataHandleHolder to our dependency list.
bool isNewDataDependency(const Gaudi::v1::DataHandle &handle) const
Check if a data dependency has not been declared before (new DataHandle version)
virtual const DataObjID & fullKey() const
Common infrastructure for classes that manage data handles and other Scheduler-known data dependencie...
void declare(Gaudi::v1::DataHandle &handle) override
Declare ownership of a legacy DataHandle.
virtual Mode mode() const
Base class to all new-style data handles.
static void updateDependencies(KeyHolderColl &keyHolders, const DataObjIDMapping &keyMap)
Update the DataObjID keys of a collection of key holders.
virtual void setKey(const DataObjID &key) const
static const DataObjID & accessKey(const Gaudi::v1::DataHandle *handlePtr)
Access the key of a legacy (non-reentrant) DataHandle.
void setTargetKey(const DataObjID &id)
Change the ID of the target data.
constexpr static const auto SUCCESS
bool empty() const
Tell if this DataObjID is has an empty key.
Base class used to extend a class implementing other interfaces.
static void updateDependencies(DataObjIDColl &keys, const DataObjIDMapping &keyMap)
Specialization of the above algorithm for DataObjIDColls, where updating the keys in place is not pos...
static void extractKey(DataObjIDColl &validOutput, DataObjIDColl &ignoredOutput, const KeyHolder &holder)
Extract the key of a key holder, putting empty keys on an ignore list.
const DataObjIDColl & dataDependencies(AccessMode access) const final override
Tell which whiteboard keys the algorithm will be reading or writing.
const ValueType & value() const
Backward compatibility (.
AccessMode access() const
StatusCode handleCircularDataDependencies(CircularDepHandler &&circularDepHandler)
Look for circular dependencies and let a user-specified handler deal with each of them...
static void extractKeys(DataObjIDColl &validOutput, DataObjIDColl &ignoredOutput, const KeyHolderColl &keyHolders)
Extract non-empty DataObjID keys from a collection of key holders.
void collectExplicitDataDependencies()
Collect all explicit data dependencies in a single place.
static const DataObjID & accessKey(const Gaudi::v2::DataHandle *handlePtr)
Access the key of a DataHandle.
void collectDependencies(const std::unordered_set< Gaudi::v1::DataHandle * > legacyHandles)
Specialization of extractDependencies for legacy DataHandles.