From 18b75bbfd758ade8df034f45f40fa31aad5108e3 Mon Sep 17 00:00:00 2001 From: Attila Krasznahorkay <krasznaa@cern.ch> Date: Tue, 31 May 2016 11:23:48 +0200 Subject: [PATCH] Adding xAODMaker::ElementLinkResetAlg to the trunk as well (xAODCoreCnv-00-01-02) * Adding the xAODMaker::ElementLinkResetAlg algorithm from xAODCoreCnv-00-00-07-branch. * Updated the package's CMT and CMake configuration to build the new code correctly. * Tagging as xAODCoreCnv-00-01-02 Former-commit-id: 26e5f0ab0649ef211f8712ebd08a8a8d89a3b747 --- Event/xAOD/xAODCoreCnv/CMakeLists.txt | 3 +- Event/xAOD/xAODCoreCnv/cmt/requirements | 5 +- .../xAODCoreCnv/src/ElementLinkResetAlg.cxx | 149 ++++++++++++++++++ .../xAODCoreCnv/src/ElementLinkResetAlg.h | 75 +++++++++ .../src/components/xAODCoreCnv_entries.cxx | 7 +- 5 files changed, 233 insertions(+), 6 deletions(-) create mode 100644 Event/xAOD/xAODCoreCnv/src/ElementLinkResetAlg.cxx create mode 100644 Event/xAOD/xAODCoreCnv/src/ElementLinkResetAlg.h diff --git a/Event/xAOD/xAODCoreCnv/CMakeLists.txt b/Event/xAOD/xAODCoreCnv/CMakeLists.txt index 30798230743..d8ebff32460 100644 --- a/Event/xAOD/xAODCoreCnv/CMakeLists.txt +++ b/Event/xAOD/xAODCoreCnv/CMakeLists.txt @@ -11,6 +11,7 @@ atlas_depends_on_subdirs( PRIVATE Control/AthContainers Control/AthContainersInterfaces + Control/AthLinks Control/AthenaBaseComps Control/AthenaKernel Control/SGTools @@ -20,7 +21,7 @@ atlas_depends_on_subdirs( # Component(s) in the package: atlas_add_component( xAODCoreCnv src/*.h src/*.cxx src/components/*.cxx - LINK_LIBRARIES AthContainers AthenaBaseComps AthenaKernel SGTools + LINK_LIBRARIES AthContainers AthLinks AthenaBaseComps AthenaKernel SGTools xAODCore GaudiKernel ) # Install files from the package: diff --git a/Event/xAOD/xAODCoreCnv/cmt/requirements b/Event/xAOD/xAODCoreCnv/cmt/requirements index 7d7f0d32b4c..be7aa53adb7 100644 --- a/Event/xAOD/xAODCoreCnv/cmt/requirements +++ b/Event/xAOD/xAODCoreCnv/cmt/requirements @@ -1,5 +1,5 @@ package xAODCoreCnv -# $Id: requirements 742532 2016-04-25 07:57:58Z krasznaa $ +# $Id: requirements 751107 2016-05-31 11:23:23Z krasznaa $ author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> @@ -16,6 +16,7 @@ use AthenaBaseComps AthenaBaseComps-* Control use AthenaKernel AthenaKernel-* Control use AthContainers AthContainers-* Control use AthContainersInterfaces AthContainersInterfaces-* Control +use AthLinks AthLinks-* Control use SGTools SGTools-* Control # EDM package(s): @@ -29,5 +30,3 @@ apply_pattern component_library # Install the jobOptions: apply_pattern declare_joboptions files=*.py - -# Useless comment, to allow modifying the CMakeLists.txt file diff --git a/Event/xAOD/xAODCoreCnv/src/ElementLinkResetAlg.cxx b/Event/xAOD/xAODCoreCnv/src/ElementLinkResetAlg.cxx new file mode 100644 index 00000000000..d0a3fdc46cc --- /dev/null +++ b/Event/xAOD/xAODCoreCnv/src/ElementLinkResetAlg.cxx @@ -0,0 +1,149 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: ElementLinkResetAlg.cxx 751107 2016-05-31 11:23:23Z krasznaa $ + +// EDM include(s): +#include "AthContainersInterfaces/IConstAuxStore.h" +#include "AthContainers/AuxTypeRegistry.h" +#include "AthContainers/normalizedTypeinfoName.h" +#include "AthLinks/ElementLinkBase.h" + +// Local include(s): +#include "ElementLinkResetAlg.h" + +namespace xAODMaker { + + ElementLinkResetAlg::ElementLinkResetAlg( const std::string& name, + ISvcLocator* svcLoc ) + : AthAlgorithm( name, svcLoc ) { + + declareProperty( "SGKeys", m_keys ); + } + + StatusCode ElementLinkResetAlg::initialize() { + + // Tell the user what's happening: + ATH_MSG_INFO( "Initialising - Package version: " << PACKAGE_VERSION ); + ATH_MSG_DEBUG( "SGKeys = " << m_keys ); + + // Return gracefully: + return StatusCode::SUCCESS; + } + + StatusCode ElementLinkResetAlg::execute() { + + // Collect all the container(s): + std::vector< const SG::IConstAuxStore* > stores; + if( m_keys.size() ) { + for( const std::string& key : m_keys ) { + const SG::IConstAuxStore* store = 0; + ATH_CHECK( evtStore()->retrieve( store, key ) ); + stores.push_back( store ); + } + } else { + SG::ConstIterator< SG::IConstAuxStore > begin, end; + ATH_CHECK( evtStore()->retrieve( begin, end ) ); + for( auto itr = begin; itr != end; ++itr ) { + const SG::IConstAuxStore* store = 0; + ATH_CHECK( evtStore()->retrieve( store, itr.key() ) ); + stores.push_back( store ); + } + } + ATH_MSG_DEBUG( "Number of IConstAuxStore objects retrieved: " + << stores.size() ); + + // Reset the ElementLinks in all of them: + for( const SG::IConstAuxStore* store : stores ) { + ATH_MSG_VERBOSE( "Reseting element links in store: " << store ); + ATH_CHECK( reset( *store ) ); + } + + // Return gracefully: + return StatusCode::SUCCESS; + } + + StatusCode ElementLinkResetAlg::reset( const SG::IConstAuxStore& store ) { + + // Get all the IDs stored in this object: + const SG::auxid_set_t& auxids = store.getAuxIDs(); + + // The auxiliary type registry: + SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance(); + + // Loop over them: + for( SG::auxid_t auxid : auxids ) { + + // Check/cache its type: + if( m_typeCache.size() <= auxid ) { + m_typeCache.resize( auxid + 1 ); + } + if( ! m_typeCache[ auxid ].isSet ) { + const std::string tname = + SG::normalizedTypeinfoName( *( reg.getType( auxid ) ) ); + static const std::string pat1 = "ElementLink<"; + static const std::string pat2 = "std::vector<ElementLink<"; + if( tname.substr( 0, pat1.size() ) == pat1 ) { + m_typeCache[ auxid ].isEL = true; + } else if( tname.substr( 0, pat2.size() ) == pat2 ) { + m_typeCache[ auxid ].isELVec = true; + } + m_typeCache[ auxid ].isSet = true; + ATH_MSG_VERBOSE( "Type for \"" << tname << "\": isEL = " + << m_typeCache[ auxid ].isEL << ", isELVec = " + << m_typeCache[ auxid ].isELVec ); + } + + // If it's not an EL type, then don't bother: + if( ! ( m_typeCache[ auxid ].isEL || m_typeCache[ auxid ].isELVec ) ) { + continue; + } + + // Get a pointer to the vector variable. We need to cast away + // its constness in this ugly way, we can't afford to only ask for + // non-const pointers from the store. Since the ElementLink to be + // reset may very well be a const variable that was accessed already, + // and now needs its cache wiped. + void* ptr = const_cast< void* >( store.getData( auxid ) ); + + // Get the variable's element size: + const size_t eltSize = reg.getEltSize( auxid ); + + // Loop over its elements: + const size_t sz_i = store.size(); + for( size_t i = 0; i < sz_i; ++i ) { + + // Raw pointer to the object: + void* eltPtr = reinterpret_cast< char* >( ptr ) + i * eltSize; + + // Do different things based on the variable type: + if( m_typeCache[ auxid ].isEL ) { + // For a single ElementLink, the logic is relatively simple: + reinterpret_cast< ElementLinkBase* >( eltPtr )->toTransient(); + } else if( m_typeCache[ auxid ].isELVec ) { + // For a vector of links we heavily rely on knowing how GCC/Clang + // lays out the memory for vectors. + std::vector< ElementLinkBase >& v = + *( reinterpret_cast< std::vector< ElementLinkBase >* >( eltPtr ) ); + const size_t sz_j = v.size(); + for( size_t j = 0; j < sz_j; ++j ) { + v[ j ].toTransient(); + } + } else { + ATH_MSG_FATAL( "There is a logic error in the code" ); + return StatusCode::FAILURE; + } + } + } + + // Return gracefully: + return StatusCode::SUCCESS; + } + + ElementLinkResetAlg::AuxIDType::AuxIDType() + : isSet( false ), isEL( false ), isELVec( false ) { + + } + +} // namespace xAODMaker diff --git a/Event/xAOD/xAODCoreCnv/src/ElementLinkResetAlg.h b/Event/xAOD/xAODCoreCnv/src/ElementLinkResetAlg.h new file mode 100644 index 00000000000..6f819948a46 --- /dev/null +++ b/Event/xAOD/xAODCoreCnv/src/ElementLinkResetAlg.h @@ -0,0 +1,75 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: ElementLinkResetAlg.h 751107 2016-05-31 11:23:23Z krasznaa $ +#ifndef XAODCORECNV_ELEMENTLINKRESETALG_H +#define XAODCORECNV_ELEMENTLINKRESETALG_H + +// System include(s): +#include <vector> +#include <string> + +// Gaudi/Athena include(s): +#include "AthenaBaseComps/AthAlgorithm.h" + +// Forward declaration(s): +namespace SG { + class IConstAuxStore; +} + +namespace xAODMaker { + + /** + * @short Algorithm reseting ElementLink objects to their default state + * + * This algorithm can be used to make sure that during/after an + * AODFix-like configuration EDM objects are not left with cached + * pointers to no longer existing objects. + * + * The algorithm can make sure that every ElementLink in some + * selected container(s), or all containers that are in StoreGate, + * are cleared of all cached information. + * + * @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> + * + * $Revision: 751107 $ + * $Date: 2016-05-31 13:23:23 +0200 (Tue, 31 May 2016) $ + */ + class ElementLinkResetAlg : public AthAlgorithm { + + public: + /// Regular Algorithm constructor + ElementLinkResetAlg( const std::string& name, ISvcLocator* svcLoc ); + + /// Function initialising the algorithm + virtual StatusCode initialize(); + /// Function executing the algorithm + virtual StatusCode execute(); + + private: + /// Function reseting all the ElementLinks in one specific container + StatusCode reset( const SG::IConstAuxStore& store ); + + /// StoreGate keys of the auxiliary objects to be processed + std::vector< std::string > m_keys; + + /// Helper class for caching auxiliary ID types + class AuxIDType { + public: + AuxIDType(); + bool isSet; ///< Flag for whether this type was already set up + bool isEL; ///< True if the type is an ElementLink + bool isELVec; ///< True of the type is an ElementLink vector + }; + + /// Cached types of the auxiliary IDs + std::vector< AuxIDType > m_typeCache; + + }; // class ElementLinkResetAlg + +} // namespace xAODMaker + +#endif // XAODCORECNV_ELEMENTLINKRESETALG_H diff --git a/Event/xAOD/xAODCoreCnv/src/components/xAODCoreCnv_entries.cxx b/Event/xAOD/xAODCoreCnv/src/components/xAODCoreCnv_entries.cxx index 15f70da1100..012b331a940 100644 --- a/Event/xAOD/xAODCoreCnv/src/components/xAODCoreCnv_entries.cxx +++ b/Event/xAOD/xAODCoreCnv/src/components/xAODCoreCnv_entries.cxx @@ -1,15 +1,18 @@ -// $Id: xAODCoreCnv_entries.cxx 583869 2014-02-18 11:31:09Z krasznaa $ +// $Id: xAODCoreCnv_entries.cxx 751107 2016-05-31 11:23:23Z krasznaa $ // Gaudi/Athena include(s): #include "GaudiKernel/DeclareFactoryEntries.h" // Local include(s): #include "../AuxStoreWrapper.h" +#include "../ElementLinkResetAlg.h" DECLARE_NAMESPACE_ALGORITHM_FACTORY( xAODMaker, AuxStoreWrapper ) +DECLARE_NAMESPACE_ALGORITHM_FACTORY( xAODMaker, ElementLinkResetAlg ) -DECLARE_FACTORY_ENTRIES( xAODCreatorAlgs ) { +DECLARE_FACTORY_ENTRIES( xAODCoreCnv ) { DECLARE_NAMESPACE_ALGORITHM( xAODMaker, AuxStoreWrapper ) + DECLARE_NAMESPACE_ALGORITHM( xAODMaker, ElementLinkResetAlg ) } -- GitLab