diff --git a/CondCore/CondHDF5ESSource/plugins/CondHDF5ESSource.cc b/CondCore/CondHDF5ESSource/plugins/CondHDF5ESSource.cc index a8e2d8a8d4ec8..261e7fd2e2c3e 100644 --- a/CondCore/CondHDF5ESSource/plugins/CondHDF5ESSource.cc +++ b/CondCore/CondHDF5ESSource/plugins/CondHDF5ESSource.cc @@ -17,6 +17,7 @@ // user include files #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h" #include "FWCore/Framework/interface/ESProductResolverProvider.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" #include "FWCore/Framework/interface/IOVSyncValue.h" #include "FWCore/Framework/interface/SourceFactory.h" #include "FWCore/Framework/interface/ValidityInterval.h" @@ -52,6 +53,7 @@ class CondHDF5ESSource : public edm::EventSetupRecordIntervalFinder, public edm: bool isConcurrentFinder() const final { return true; } void setIntervalFor(EventSetupRecordKey const&, edm::IOVSyncValue const&, edm::ValidityInterval&) final; KeyedResolversVector registerResolvers(EventSetupRecordKey const&, unsigned int iovIndex) final; + std::vector producesInfo() const final; edm::SerialTaskQueue queue_; std::mutex mutex_; @@ -236,4 +238,25 @@ CondHDF5ESSource::KeyedResolversVector CondHDF5ESSource::registerResolvers(Event return returnValue; } +std::vector CondHDF5ESSource::producesInfo() const { + std::vector returnValue; + auto size = 0; + for (auto const& recInfo : records_) { + size += recInfo.dataProducts_.size(); + } + returnValue.reserve(size); + + for (auto const& recInfo : records_) { + EventSetupRecordKey rec{edm::eventsetup::heterocontainer::HCTypeTag::findType(recInfo.name_)}; + for (auto const& dataProduct : recInfo.dataProducts_) { + unsigned int index = returnValue.size(); + edm::eventsetup::DataKey key{edm::eventsetup::heterocontainer::HCTypeTag::findType(dataProduct.type_), + dataProduct.name_.c_str()}; + returnValue.emplace_back(rec, key, index); + } + } + + return returnValue; +} + DEFINE_FWK_EVENTSETUP_SOURCE(CondHDF5ESSource); diff --git a/CondCore/ESSources/plugins/CondDBESSource.cc b/CondCore/ESSources/plugins/CondDBESSource.cc index 3bce5f1d2bafd..2b19be2138f07 100644 --- a/CondCore/ESSources/plugins/CondDBESSource.cc +++ b/CondCore/ESSources/plugins/CondDBESSource.cc @@ -22,6 +22,7 @@ #include "CondCore/ESSources/interface/ProductResolver.h" #include "CondCore/CondDB/interface/PayloadProxy.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" #include "FWCore/Catalog/interface/SiteLocalConfig.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -648,6 +649,23 @@ edm::eventsetup::ESProductResolverProvider::KeyedResolversVector CondDBESSource: return keyedResolversVector; } +std::vector CondDBESSource::producesInfo() const { + std::vector returnValue; + returnValue.reserve(m_resolvers.size()); + + for (auto const& recToResolver : m_resolvers) { + unsigned int index = returnValue.size(); + + EventSetupRecordKey rec{edm::eventsetup::TypeTag::findType(recToResolver.first)}; + + edm::eventsetup::TypeTag type = recToResolver.second->type(); + DataKey key(type, edm::eventsetup::IdTags(recToResolver.second->label().c_str())); + returnValue.emplace_back(rec, key, index); + } + + return returnValue; +} + void CondDBESSource::initConcurrentIOVs(const EventSetupRecordKey& key, unsigned int nConcurrentIOVs) { std::string recordname = key.name(); ResolverMap::const_iterator b = m_resolvers.lower_bound(recordname); diff --git a/CondCore/ESSources/plugins/CondDBESSource.h b/CondCore/ESSources/plugins/CondDBESSource.h index a627a92a02508..65157c5a9bb63 100644 --- a/CondCore/ESSources/plugins/CondDBESSource.h +++ b/CondCore/ESSources/plugins/CondDBESSource.h @@ -106,6 +106,8 @@ class CondDBESSource : public edm::eventsetup::ESProductResolverProvider, public KeyedResolversVector registerResolvers(const EventSetupRecordKey&, unsigned int iovIndex) override; + std::vector producesInfo() const override; + void initConcurrentIOVs(const EventSetupRecordKey& key, unsigned int nConcurrentIOVs) override; bool isConcurrentFinder() const override { return true; } diff --git a/FWCore/Framework/interface/EDConsumerBase.h b/FWCore/Framework/interface/EDConsumerBase.h index 09d855e3fcaf8..182dc25c02eb3 100644 --- a/FWCore/Framework/interface/EDConsumerBase.h +++ b/FWCore/Framework/interface/EDConsumerBase.h @@ -37,7 +37,9 @@ #include "FWCore/Framework/interface/HCTypeTag.h" #include "FWCore/Framework/interface/DataKey.h" #include "FWCore/Framework/interface/data_default_record_trait.h" +#include "FWCore/Framework/interface/ModuleConsumesMinimalESInfo.h" #include "FWCore/ServiceRegistry/interface/ServiceRegistryfwd.h" +#include "FWCore/ServiceRegistry/interface/ModuleConsumesInfo.h" #include "FWCore/Utilities/interface/BranchType.h" #include "FWCore/Utilities/interface/ESIndices.h" #include "FWCore/Utilities/interface/TypeID.h" @@ -114,20 +116,14 @@ namespace edm { typedef ProductLabels Labels; void labelsForToken(EDGetToken iToken, Labels& oLabels) const; - void modulesWhoseProductsAreConsumed(std::array*, NumBranchTypes>& modulesAll, - ProductRegistry const& preg, - std::map const& labelsToDesc, - std::string const& processName) const; - - void esModulesWhoseProductsAreConsumed( - std::array*, kNumberOfEventSetupTransitions>& esModules, - eventsetup::ESRecordsToProductResolverIndices const&) const; - /// Convert "@currentProcess" in InputTag process names to the actual current process name. void convertCurrentProcessAlias(std::string const& processName); std::vector moduleConsumesInfos() const; - std::vector moduleConsumesESInfos(eventsetup::ESRecordsToProductResolverIndices const&) const; + ///This can only be called before the end of beginJob (after that the underlying data has been deleted) + /// The pointers held by ModuleConsumesMinimalESInfo will also be invalid at that time so copies of + /// that class should not be held beyond the end of beginJob. + std::vector moduleConsumesMinimalESInfos() const; ESResolverIndex const* esGetTokenIndices(edm::Transition iTrans) const { if (iTrans < edm::Transition::NumberOfEventSetupTransitions) { @@ -232,6 +228,20 @@ namespace edm { return ESGetTokenGeneric(static_cast(Tr), index, iRecord.type()); } + /**The passed functor must take the following signature + * F( ModuleConsumesInfo const& ) + * The functor will be called for each consumed EDProduct registered for the module + */ + template + void consumedProducts(F&& iFunc) const; + + /**The passed functor must take the following signature + * F(edm::ModuleConsumesMinimalESInfo const& ) + * The functor will be called for each consumed ESProduct registered for the module + */ + template + void consumedESProducts(F&& iFunct) const; + private: virtual void extendUpdateLookup(BranchType iBranchType, ProductResolverIndexHelper const&); virtual void registerLateConsumes(eventsetup::ESRecordsToProductResolverIndices const&) {} @@ -326,6 +336,47 @@ namespace edm { bool containsCurrentProcessAlias_; }; + template + void EDConsumerBase::consumedProducts(F&& iFunc) const { + auto itKind = m_tokenInfo.begin(); + auto itLabels = m_tokenInfo.begin(); + auto itAlways = m_tokenInfo.begin(); + for (auto itInfo = m_tokenInfo.begin(), itEnd = m_tokenInfo.end(); itInfo != itEnd; + ++itInfo, ++itKind, ++itLabels, ++itAlways) { + auto labels = *itLabels; + unsigned int start = labels.m_startOfModuleLabel; + auto module = &(m_tokenLabels[start]); + auto productInstance = module + labels.m_deltaToProductInstance; + auto process = module + labels.m_deltaToProcessName; + + iFunc(ModuleConsumesInfo(itInfo->m_type, + module, + productInstance, + process, + itInfo->m_branchType, + *itKind, + *itAlways, + itInfo->m_index.skipCurrentProcess())); + } + } + + template + void EDConsumerBase::consumedESProducts(F&& iFunc) const { + unsigned int index = 0; + auto itResolverIndex = esTokenLookupInfoContainer().begin(); + for (auto it = esTokenLookupInfoContainer().begin(); + it != esTokenLookupInfoContainer().end(); + ++it, ++index, ++itResolverIndex) { + //NOTE: memory for it->m_key is passed on to call via the ModuleConsumesMinimalESInfo constructor + // this avoids a copy and avoids code later in the call chain accidently using deleted memory + iFunc(ModuleConsumesMinimalESInfo(static_cast(consumesIndexConverter()[index].first), + it->m_record, + it->m_key, + &(m_tokenLabels[it->m_startOfComponentName]), + *itResolverIndex)); + } + } + template class EDConsumerBaseESAdaptor { public: diff --git a/FWCore/Framework/interface/ESModuleConsumesMinimalInfo.h b/FWCore/Framework/interface/ESModuleConsumesMinimalInfo.h new file mode 100644 index 0000000000000..97e89cab2397d --- /dev/null +++ b/FWCore/Framework/interface/ESModuleConsumesMinimalInfo.h @@ -0,0 +1,38 @@ +#ifndef FWCore_Framework_ESModuleConsumesMinimalInfo_h +#define FWCore_Framework_ESModuleConsumesMinimalInfo_h + +// -*- C++ -*- +// Package: FWCore/Framework +// Class : ESModuleConsumesMinimalInfo +// Minimal information about the consumes call for an EventSetup product by an ESModule + +#include "FWCore/Utilities/interface/ESIndices.h" +#include "FWCore/Framework/interface/EventSetupRecordKey.h" +#include "FWCore/Framework/interface/DataKey.h" +#include + +namespace edm::eventsetup { + struct ESModuleConsumesMinimalInfo { + ESModuleConsumesMinimalInfo(unsigned int iProduceMethodID, + eventsetup::EventSetupRecordKey const& iRecord, + eventsetup::DataKey const& iDataKey, + std::string_view iComponentLabel) + : recordForDataKey_(iRecord), + dataKey_(iDataKey.type(), iDataKey.name(), eventsetup::DataKey::DoNotCopyMemory()), + componentLabel_(iComponentLabel), + produceMethodID_(iProduceMethodID) {} + ESModuleConsumesMinimalInfo() = default; + ESModuleConsumesMinimalInfo(ESModuleConsumesMinimalInfo&&) = default; + ESModuleConsumesMinimalInfo& operator=(ESModuleConsumesMinimalInfo&&) = default; + + // avoid accidentally copying data key as the strings would be copied instead of shared + ESModuleConsumesMinimalInfo(ESModuleConsumesMinimalInfo const&) = delete; + ESModuleConsumesMinimalInfo& operator=(ESModuleConsumesMinimalInfo const&) = delete; + + eventsetup::EventSetupRecordKey recordForDataKey_; + eventsetup::DataKey dataKey_; + std::string_view componentLabel_; + unsigned int produceMethodID_ = 0; + }; +} // namespace edm::eventsetup +#endif // FWCore_Framework_ESModuleConsumesMinimalInfo_h \ No newline at end of file diff --git a/FWCore/Framework/interface/ESModuleProducesInfo.h b/FWCore/Framework/interface/ESModuleProducesInfo.h new file mode 100644 index 0000000000000..5fc2cc7d7c362 --- /dev/null +++ b/FWCore/Framework/interface/ESModuleProducesInfo.h @@ -0,0 +1,29 @@ +#ifndef FWCore_Framework_ESModuleProducesInfo_h +#define FWCore_Framework_ESModuleProducesInfo_h +// -*- C++ -*- + +// Package: Framework +// Class : ESModuleProducesInfo +// +// Description: Contains information about which products +// a module declares it will produce from the EventSetup. + +#include "FWCore/Framework/interface/DataKey.h" +#include "FWCore/Framework/interface/EventSetupRecordKey.h" +namespace edm::eventsetup { + class ESModuleProducesInfo { + public: + ESModuleProducesInfo(EventSetupRecordKey const& iRecord, DataKey const& iDataKey, unsigned int iProduceMethodID) + : record_(iRecord), dataKey_(iDataKey), produceMethodID_(iProduceMethodID) {} + + EventSetupRecordKey const& record() const { return record_; } + DataKey const& dataKey() const { return dataKey_; } + unsigned int produceMethodID() const { return produceMethodID_; } + + private: + EventSetupRecordKey record_; + DataKey dataKey_; + unsigned int produceMethodID_; + }; +} // namespace edm::eventsetup +#endif \ No newline at end of file diff --git a/FWCore/Framework/interface/ESProducer.h b/FWCore/Framework/interface/ESProducer.h index 7879a5b7d9e8e..59d148e86ce32 100644 --- a/FWCore/Framework/interface/ESProducer.h +++ b/FWCore/Framework/interface/ESProducer.h @@ -95,6 +95,7 @@ namespace edm { namespace eventsetup { struct ComponentDescription; class ESRecordsToProductResolverIndices; + struct ESModuleConsumesMinimalInfo; //used by ESProducer to create the proper Decorator based on the // argument type passed. The default it to just 'pass through' @@ -158,12 +159,14 @@ namespace edm { SerialTaskQueueChain& queue() { return acquirer_.serialQueueChain(); } - void esModulesWhoseProductsAreConsumed(std::vector& esModules, - eventsetup::ESRecordsToProductResolverIndices const&) const; - std::vector> esModuleConsumesInfos( eventsetup::ESRecordsToProductResolverIndices const&) const; + /** Returns a vector of ESModuleConsumesMinimalInfo. + Each entry contains minimal information about the products that a method consumes. + */ + std::vector esModuleConsumesMinimalInfos() const; + protected: /** Specify the names of the shared resources used by this ESProducer */ void usesResources(std::vector const&); diff --git a/FWCore/Framework/interface/ESProductResolverArgumentFactoryTemplate.h b/FWCore/Framework/interface/ESProductResolverArgumentFactoryTemplate.h index a14d1d9110554..376d0e5b58991 100644 --- a/FWCore/Framework/interface/ESProductResolverArgumentFactoryTemplate.h +++ b/FWCore/Framework/interface/ESProductResolverArgumentFactoryTemplate.h @@ -65,6 +65,8 @@ namespace edm { return DataKey(DataKey::makeTypeTag(), iName.c_str()); } + unsigned int produceMethodID() const override { return callback_->second->produceMethodID(); } + private: std::shared_ptr>> callback_; }; diff --git a/FWCore/Framework/interface/ESProductResolverFactoryBase.h b/FWCore/Framework/interface/ESProductResolverFactoryBase.h index 584cb02843599..6502582e9da60 100644 --- a/FWCore/Framework/interface/ESProductResolverFactoryBase.h +++ b/FWCore/Framework/interface/ESProductResolverFactoryBase.h @@ -40,6 +40,8 @@ namespace edm { virtual std::unique_ptr makeResolver(unsigned int iovIndex) = 0; virtual DataKey makeKey(const std::string& iName) const = 0; + + virtual unsigned int produceMethodID() const = 0; }; } // namespace eventsetup } // namespace edm diff --git a/FWCore/Framework/interface/ESProductResolverFactoryProducer.h b/FWCore/Framework/interface/ESProductResolverFactoryProducer.h index cad950002accf..305a48971fb69 100644 --- a/FWCore/Framework/interface/ESProductResolverFactoryProducer.h +++ b/FWCore/Framework/interface/ESProductResolverFactoryProducer.h @@ -83,6 +83,8 @@ namespace edm { ~ESProductResolverFactoryProducer() noexcept(false) override; + std::vector producesInfo() const override; + protected: using EventSetupRecordKey = eventsetup::EventSetupRecordKey; diff --git a/FWCore/Framework/interface/ESProductResolverProvider.h b/FWCore/Framework/interface/ESProductResolverProvider.h index b7055edb6e903..ab64db951ea1b 100644 --- a/FWCore/Framework/interface/ESProductResolverProvider.h +++ b/FWCore/Framework/interface/ESProductResolverProvider.h @@ -60,6 +60,7 @@ namespace edm { namespace eventsetup { class ESProductResolver; class ESRecordsToProductResolverIndices; + class ESModuleProducesInfo; class ESProductResolverProvider { public: @@ -161,6 +162,10 @@ namespace edm { void fillRecordsNotAllowingConcurrentIOVs(std::set& recordsNotAllowingConcurrentIOVs) const { productResolverContainer_.fillRecordsNotAllowingConcurrentIOVs(recordsNotAllowingConcurrentIOVs); } + /// @brief Provides information about each product that this module produces. + /// If the value of produceMethodID is same for different infos it means they are produced by the same call. + /// @return the vector of ESModuleProducesInfo objects, one for each product produced by this module. + virtual std::vector producesInfo() const = 0; virtual void initConcurrentIOVs(EventSetupRecordKey const& key, unsigned int nConcurrentIOVs) {} diff --git a/FWCore/Framework/interface/ESTagGetter.h b/FWCore/Framework/interface/ESTagGetter.h index e7cc5b68dc687..1669914de3f07 100644 --- a/FWCore/Framework/interface/ESTagGetter.h +++ b/FWCore/Framework/interface/ESTagGetter.h @@ -10,7 +10,9 @@ Description: Used with mayConsume option of ESConsumesCollector Usage: - + This contains a cache of data about all Resolvers which are + associated with data produces which are in the Record and which + are of the proper type. */ // diff --git a/FWCore/Framework/interface/EventSetupProvider.h b/FWCore/Framework/interface/EventSetupProvider.h index 93111f0f43b33..11771caf87009 100644 --- a/FWCore/Framework/interface/EventSetupProvider.h +++ b/FWCore/Framework/interface/EventSetupProvider.h @@ -122,6 +122,7 @@ namespace edm { void fillKeys(std::set& keys) const; EventSetupRecordProvider* tryToGetRecordProvider(const EventSetupRecordKey& iKey); + EventSetupRecordProvider const* tryToGetRecordProvider(const EventSetupRecordKey& iKey) const; void fillAllESProductResolverProviders(std::vector&) const; diff --git a/FWCore/Framework/interface/EventSetupRecord.h b/FWCore/Framework/interface/EventSetupRecord.h index ced7bb3b8ca7a..c633fee69559f 100644 --- a/FWCore/Framework/interface/EventSetupRecord.h +++ b/FWCore/Framework/interface/EventSetupRecord.h @@ -140,7 +140,7 @@ namespace edm { unsigned int iovIndex() const { return impl_->iovIndex(); } ///clears the oToFill vector and then fills it with the keys for all registered data keys - void fillRegisteredDataKeys(std::vector& oToFill) const { impl_->fillRegisteredDataKeys(oToFill); } + void fillRegisteredDataKeys(std::vector& oToFill) const { oToFill = impl_->registeredDataKeys(); } ///Classes that derive from EventSetupRecord can redefine this with a false value static constexpr bool allowConcurrentIOVs_ = true; diff --git a/FWCore/Framework/interface/EventSetupRecordImpl.h b/FWCore/Framework/interface/EventSetupRecordImpl.h index 04b9875f5a5e6..d2fc6c0bd04ec 100644 --- a/FWCore/Framework/interface/EventSetupRecordImpl.h +++ b/FWCore/Framework/interface/EventSetupRecordImpl.h @@ -113,8 +113,8 @@ namespace edm { unsigned int iovIndex() const { return iovIndex_; } - ///clears the oToFill vector and then fills it with the keys for all registered data keys - void fillRegisteredDataKeys(std::vector& oToFill) const; + ///keys for all registered data keys + std::vector const& registeredDataKeys() const; ///there is a 1-to-1 correspondence between elements returned and the elements returned from fillRegisteredDataKey. std::vector componentsForRegisteredDataKeys() const; diff --git a/FWCore/Framework/interface/EventSetupRecordProvider.h b/FWCore/Framework/interface/EventSetupRecordProvider.h index eaf12a2d9faea..689afa11753d6 100644 --- a/FWCore/Framework/interface/EventSetupRecordProvider.h +++ b/FWCore/Framework/interface/EventSetupRecordProvider.h @@ -79,7 +79,7 @@ namespace edm { std::set resolverProviderDescriptions() const; /// The available DataKeys in the Record. The order can be used to request the data by index - std::vector registeredDataKeys() const; + std::vector const& registeredDataKeys() const; std::vector componentsForRegisteredDataKeys() const; std::vector produceMethodIDsForRegisteredDataKeys() const; diff --git a/FWCore/Framework/interface/ModuleConsumesMinimalESInfo.h b/FWCore/Framework/interface/ModuleConsumesMinimalESInfo.h new file mode 100644 index 0000000000000..115c77b9a6918 --- /dev/null +++ b/FWCore/Framework/interface/ModuleConsumesMinimalESInfo.h @@ -0,0 +1,41 @@ +#ifndef FWCore_Framework_ModuleConsumesMinimalESInfo_h +#define FWCore_Framework_ModuleConsumesMinimalESInfo_h + +// -*- C++ -*- +// Package: FWCore/Framework +// Class : ModuleConsumesMinimalESInfo +// Minimal information about the consumes call for an EventSetup product +// requested from an ED module + +#include "FWCore/Utilities/interface/Transition.h" +#include "FWCore/Utilities/interface/ESIndices.h" +#include "FWCore/Framework/interface/EventSetupRecordKey.h" +#include "FWCore/Framework/interface/DataKey.h" +#include + +namespace edm { + struct ModuleConsumesMinimalESInfo { + ModuleConsumesMinimalESInfo(Transition iTransition, + eventsetup::EventSetupRecordKey const& iRecord, + eventsetup::DataKey const& iDataKey, + std::string_view iComponentLabel, + ESResolverIndex iIndex) + : transition_(iTransition), + record_(iRecord), + dataKey_(iDataKey.type(), iDataKey.name(), eventsetup::DataKey::DoNotCopyMemory()), + componentLabel_(iComponentLabel) {} + ModuleConsumesMinimalESInfo() = default; + ModuleConsumesMinimalESInfo(ModuleConsumesMinimalESInfo&&) = default; + ModuleConsumesMinimalESInfo& operator=(ModuleConsumesMinimalESInfo&&) = default; + + //want to avoid accidently copying dataKey_ + ModuleConsumesMinimalESInfo(ModuleConsumesMinimalESInfo const&) = delete; + ModuleConsumesMinimalESInfo& operator=(ModuleConsumesMinimalESInfo const&) = delete; + + edm::Transition transition_; + eventsetup::EventSetupRecordKey record_; + eventsetup::DataKey dataKey_; + std::string_view componentLabel_; + }; +} // namespace edm +#endif // FWCore_Framework_ModuleConsumesMinimalESInfo_h \ No newline at end of file diff --git a/FWCore/Framework/interface/PathsAndConsumesOfModules.h b/FWCore/Framework/interface/PathsAndConsumesOfModules.h index 82991cbe8ed89..2c73ccebec422 100644 --- a/FWCore/Framework/interface/PathsAndConsumesOfModules.h +++ b/FWCore/Framework/interface/PathsAndConsumesOfModules.h @@ -24,6 +24,7 @@ #include #include #include +#include namespace edm { @@ -43,12 +44,18 @@ namespace edm { ~PathsAndConsumesOfModules() override = default; void initialize(Schedule const*, std::shared_ptr); - void initializeForEventSetup(eventsetup::ESRecordsToProductResolverIndices&&, - eventsetup::EventSetupProvider const&); + void initializeForEventSetup(eventsetup::EventSetupProvider const&); void checkEventSetupInitialization() const; void removeModules(std::vector const& modules); + struct ESProductInfo { + eventsetup::ComponentDescription const* componentDescription_ = nullptr; + unsigned int produceMethodID_ = std::numeric_limits::max(); + }; + using ProducedByESModule = + std::map>; + private: std::vector const& doPaths() const override; std::vector const& doEndPaths() const override; @@ -107,7 +114,7 @@ namespace edm { std::vector> esModulesWhoseProductsAreConsumedByESModule_; Schedule const* schedule_ = nullptr; - eventsetup::ESRecordsToProductResolverIndices esRecordsToProductResolverIndices_; + ProducedByESModule producedByESModule_; std::shared_ptr preg_; bool eventSetupInfoInitialized_ = false; }; diff --git a/FWCore/Framework/interface/Schedule.h b/FWCore/Framework/interface/Schedule.h index 3e2634518a873..ea52b6bc7920d 100644 --- a/FWCore/Framework/interface/Schedule.h +++ b/FWCore/Framework/interface/Schedule.h @@ -245,16 +245,6 @@ namespace edm { std::vector& descriptions, unsigned int hint) const; - void fillModuleAndConsumesInfo(std::vector& allModuleDescriptions, - std::vector>& moduleIDToIndex, - std::array>, NumBranchTypes>& - modulesWhoseProductsAreConsumedBy, - ProductRegistry const& preg) const; - - void fillESModuleAndConsumesInfo(std::array>, - kNumberOfEventSetupTransitions>& esModulesWhoseProductsAreConsumedBy, - eventsetup::ESRecordsToProductResolverIndices const&) const; - /// Return the number of events this Schedule has tried to process /// (inclues both successes and failures, including failures due /// to exceptions during processing). diff --git a/FWCore/Framework/interface/maker/Worker.h b/FWCore/Framework/interface/maker/Worker.h index 7ce6a5ee44288..b45a37b2c750d 100644 --- a/FWCore/Framework/interface/maker/Worker.h +++ b/FWCore/Framework/interface/maker/Worker.h @@ -30,6 +30,7 @@ the worker is reset(). #include "FWCore/Framework/interface/ModuleContextSentry.h" #include "FWCore/Framework/interface/OccurrenceTraits.h" #include "FWCore/Framework/interface/ProductResolverIndexAndSkipBit.h" +#include "FWCore/Framework/interface/ModuleConsumesMinimalESInfo.h" #include "FWCore/Concurrency/interface/WaitingTask.h" #include "FWCore/Concurrency/interface/WaitingTaskHolder.h" #include "FWCore/Concurrency/interface/WaitingTaskList.h" @@ -218,20 +219,10 @@ namespace edm { std::unordered_multimap> const& iIndicies) = 0; - virtual void modulesWhoseProductsAreConsumed( - std::array*, NumBranchTypes>& modules, - ProductRegistry const& preg, - std::map const& labelsToDesc) const = 0; - - virtual void esModulesWhoseProductsAreConsumed( - std::array*, kNumberOfEventSetupTransitions>& esModules, - eventsetup::ESRecordsToProductResolverIndices const&) const = 0; - virtual void convertCurrentProcessAlias(std::string const& processName) = 0; virtual std::vector moduleConsumesInfos() const = 0; - virtual std::vector moduleConsumesESInfos( - eventsetup::ESRecordsToProductResolverIndices const&) const = 0; + virtual std::vector moduleConsumesMinimalESInfos() const = 0; virtual Types moduleType() const = 0; virtual ConcurrencyTypes moduleConcurrencyType() const = 0; diff --git a/FWCore/Framework/interface/maker/WorkerT.h b/FWCore/Framework/interface/maker/WorkerT.h index e393c6423109d..aece3843fb79b 100644 --- a/FWCore/Framework/interface/maker/WorkerT.h +++ b/FWCore/Framework/interface/maker/WorkerT.h @@ -127,26 +127,14 @@ namespace edm { std::string workerType() const override; TaskQueueAdaptor serializeRunModule() override; - void modulesWhoseProductsAreConsumed( - std::array*, NumBranchTypes>& modules, - ProductRegistry const& preg, - std::map const& labelsToDesc) const override { - module_->modulesWhoseProductsAreConsumed(modules, preg, labelsToDesc, module_->moduleDescription().processName()); - } - - void esModulesWhoseProductsAreConsumed( - std::array*, kNumberOfEventSetupTransitions>& esModules, - eventsetup::ESRecordsToProductResolverIndices const& iPI) const override { - module_->esModulesWhoseProductsAreConsumed(esModules, iPI); - } - void convertCurrentProcessAlias(std::string const& processName) override { module_->convertCurrentProcessAlias(processName); } std::vector moduleConsumesInfos() const override; - std::vector moduleConsumesESInfos( - eventsetup::ESRecordsToProductResolverIndices const& iPI) const override; + std::vector moduleConsumesMinimalESInfos() const final { + return module_->moduleConsumesMinimalESInfos(); + } void itemsToGet(BranchType branchType, std::vector& indexes) const override { module_->itemsToGet(branchType, indexes); diff --git a/FWCore/Framework/interface/stream/EDAnalyzerAdaptorBase.h b/FWCore/Framework/interface/stream/EDAnalyzerAdaptorBase.h index d8eecb291b490..647603900eafd 100644 --- a/FWCore/Framework/interface/stream/EDAnalyzerAdaptorBase.h +++ b/FWCore/Framework/interface/stream/EDAnalyzerAdaptorBase.h @@ -50,6 +50,7 @@ namespace edm { class ActivityRegistry; class ThinnedAssociationsHelper; class SignallingProductRegistryFiller; + struct ModuleConsumesMinimalESInfo; namespace maker { template @@ -120,21 +121,10 @@ namespace edm { const EDConsumerBase* consumer() const; - void modulesWhoseProductsAreConsumed(std::array*, NumBranchTypes>& modules, - ProductRegistry const& preg, - std::map const& labelsToDesc, - std::string const& processName) const; - - void esModulesWhoseProductsAreConsumed( - std::array*, kNumberOfEventSetupTransitions>& esModules, - eventsetup::ESRecordsToProductResolverIndices const&) const; - void convertCurrentProcessAlias(std::string const& processName); std::vector moduleConsumesInfos() const; - std::vector moduleConsumesESInfos( - eventsetup::ESRecordsToProductResolverIndices const&) const; - + std::vector moduleConsumesMinimalESInfos() const; void deleteModulesEarly(); private: diff --git a/FWCore/Framework/interface/stream/ProducingModuleAdaptorBase.h b/FWCore/Framework/interface/stream/ProducingModuleAdaptorBase.h index f453eb6eb037c..6b30a0c2494c1 100644 --- a/FWCore/Framework/interface/stream/ProducingModuleAdaptorBase.h +++ b/FWCore/Framework/interface/stream/ProducingModuleAdaptorBase.h @@ -57,6 +57,7 @@ namespace edm { class WaitingTaskHolder; class ServiceWeakToken; class SignallingProductRegistryFiller; + struct ModuleConsumesMinimalESInfo; namespace maker { template @@ -112,20 +113,10 @@ namespace edm { void releaseMemoryPostLookupSignal(); virtual void selectInputProcessBlocks(ProductRegistry const&, ProcessBlockHelperBase const&) = 0; - void modulesWhoseProductsAreConsumed(std::array*, NumBranchTypes>& modules, - ProductRegistry const& preg, - std::map const& labelsToDesc, - std::string const& processName) const; - - void esModulesWhoseProductsAreConsumed( - std::array*, kNumberOfEventSetupTransitions>& esModules, - eventsetup::ESRecordsToProductResolverIndices const&) const; - void convertCurrentProcessAlias(std::string const& processName); std::vector moduleConsumesInfos() const; - std::vector moduleConsumesESInfos( - eventsetup::ESRecordsToProductResolverIndices const&) const; + std::vector moduleConsumesMinimalESInfos() const; using ModuleToResolverIndicies = std::unordered_multimap>; diff --git a/FWCore/Framework/src/EDConsumerBase.cc b/FWCore/Framework/src/EDConsumerBase.cc index 2b3b6b76ed572..93b51bf28e522 100644 --- a/FWCore/Framework/src/EDConsumerBase.cc +++ b/FWCore/Framework/src/EDConsumerBase.cc @@ -24,7 +24,6 @@ #include "FWCore/Framework/interface/ComponentDescription.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/ServiceRegistry/interface/ModuleConsumesInfo.h" -#include "FWCore/ServiceRegistry/interface/ModuleConsumesESInfo.h" #include "FWCore/Utilities/interface/Likely.h" #include "FWCore/Utilities/interface/Exception.h" #include "DataFormats/Provenance/interface/ProductResolverIndexHelper.h" @@ -393,138 +392,6 @@ void EDConsumerBase::throwESConsumesInProcessBlock() const { void EDConsumerBase::doSelectInputProcessBlocks(ProductRegistry const&, ProcessBlockHelperBase const&) {} -namespace { - struct CharStarComp { - bool operator()(const char* iLHS, const char* iRHS) const { return strcmp(iLHS, iRHS) < 0; } - }; -} // namespace - -namespace { - void insertFoundModuleLabel(edm::KindOfType consumedTypeKind, - edm::TypeID consumedType, - const char* consumedModuleLabel, - const char* consumedProductInstance, - std::vector& modules, - std::set& alreadyFound, - std::map const& labelsToDesc, - ProductRegistry const& preg) { - // Convert from label string to module description, eliminate duplicates, - // then insert into the vector of modules - if (auto it = labelsToDesc.find(consumedModuleLabel); it != labelsToDesc.end()) { - if (alreadyFound.insert(consumedModuleLabel).second) { - modules.push_back(it->second); - } - return; - } - // Deal with EDAlias's by converting to the original module label first - if (auto aliasToModuleLabels = - preg.aliasToModules(consumedTypeKind, consumedType, consumedModuleLabel, consumedProductInstance); - not aliasToModuleLabels.empty()) { - bool foundInLabelsToDesc = false; - for (auto const& label : aliasToModuleLabels) { - if (auto it = labelsToDesc.find(label); it != labelsToDesc.end()) { - if (alreadyFound.insert(label).second) { - modules.push_back(it->second); - } - foundInLabelsToDesc = true; - } else { - if (label == "source") { - foundInLabelsToDesc = true; - } - } - } - if (foundInLabelsToDesc) { - return; - } - } - // Ignore the source products, we are only interested in module products. - // As far as I know, it should never be anything else so throw if something - // unknown gets passed in. - if (std::string_view(consumedModuleLabel) != "source") { - throw cms::Exception("EDConsumerBase", "insertFoundModuleLabel") - << "Couldn't find ModuleDescription for the consumed product type: '" << consumedType.className() - << "' module label: '" << consumedModuleLabel << "' product instance name: '" << consumedProductInstance - << "'"; - } - } -} // namespace - -void EDConsumerBase::modulesWhoseProductsAreConsumed( - std::array*, NumBranchTypes>& modulesAll, - ProductRegistry const& preg, - std::map const& labelsToDesc, - std::string const& processName) const { - std::set alreadyFound; - - auto itKind = m_tokenInfo.begin(); - auto itLabels = m_tokenInfo.begin(); - for (auto itInfo = m_tokenInfo.begin(), itEnd = m_tokenInfo.end(); itInfo != itEnd; - ++itInfo, ++itKind, ++itLabels) { - ProductResolverIndexHelper const& helper = *preg.productLookup(itInfo->m_branchType); - std::vector& modules = *modulesAll[itInfo->m_branchType]; - - const unsigned int labelStart = itLabels->m_startOfModuleLabel; - const char* const consumedModuleLabel = &(m_tokenLabels[labelStart]); - const char* const consumedProductInstance = consumedModuleLabel + itLabels->m_deltaToProductInstance; - const char* const consumedProcessName = consumedModuleLabel + itLabels->m_deltaToProcessName; - - if (not itInfo->m_index.skipCurrentProcess()) { - assert(*consumedModuleLabel != '\0'); // consumesMany used to create empty labels before we removed consumesMany - if (*consumedProcessName != '\0') { // process name is specified in consumes call - if (helper.index(*itKind, itInfo->m_type, consumedModuleLabel, consumedProductInstance, consumedProcessName) != - ProductResolverIndexInvalid) { - if (processName == consumedProcessName) { - insertFoundModuleLabel(*itKind, - itInfo->m_type, - consumedModuleLabel, - consumedProductInstance, - modules, - alreadyFound, - labelsToDesc, - preg); - } - } - } else { // process name was empty - auto matches = helper.relatedIndexes(*itKind, itInfo->m_type, consumedModuleLabel, consumedProductInstance); - for (unsigned int j = 0; j < matches.numberOfMatches(); ++j) { - if (processName == matches.processName(j)) { - insertFoundModuleLabel(*itKind, - itInfo->m_type, - consumedModuleLabel, - consumedProductInstance, - modules, - alreadyFound, - labelsToDesc, - preg); - } - } - } - } - } -} - -void EDConsumerBase::esModulesWhoseProductsAreConsumed( - std::array*, kNumberOfEventSetupTransitions>& esModules, - eventsetup::ESRecordsToProductResolverIndices const& iPI) const { - std::array, kNumberOfEventSetupTransitions> alreadyFound; - - unsigned int index = 0; - auto itResolver = esTokenLookupInfoContainer().begin(); - for (auto it = esTokenLookupInfoContainer().begin(); - it != esTokenLookupInfoContainer().end(); - ++it, ++itResolver, ++index) { - auto [componentDescription, produceMethodID] = iPI.componentAndProduceMethodID(it->m_record, *itResolver); - if (componentDescription) { - std::string const& moduleLabel = - componentDescription->label_.empty() ? componentDescription->type_ : componentDescription->label_; - ESResolverIndexContainer::size_type transitionIndex = consumesIndexConverter()[index].first; - if (alreadyFound[transitionIndex].insert(moduleLabel).second) { - esModules[transitionIndex]->push_back(componentDescription); - } - } - } -} - void EDConsumerBase::convertCurrentProcessAlias(std::string const& processName) { frozen_ = true; @@ -573,69 +440,17 @@ void EDConsumerBase::convertCurrentProcessAlias(std::string const& processName) std::vector EDConsumerBase::moduleConsumesInfos() const { std::vector result; - auto itAlways = m_tokenInfo.begin(); - auto itKind = m_tokenInfo.begin(); - auto itLabels = m_tokenInfo.begin(); - for (auto itInfo = m_tokenInfo.begin(), itEnd = m_tokenInfo.end(); itInfo != itEnd; - ++itInfo, ++itKind, ++itLabels, ++itAlways) { - const unsigned int labelStart = itLabels->m_startOfModuleLabel; - const char* consumedModuleLabel = &(m_tokenLabels[labelStart]); - const char* consumedInstance = consumedModuleLabel + itLabels->m_deltaToProductInstance; - const char* consumedProcessName = consumedModuleLabel + itLabels->m_deltaToProcessName; - - assert(*consumedModuleLabel != '\0'); - - // Just copy the information into the ModuleConsumesInfo data structure - result.emplace_back(itInfo->m_type, - consumedModuleLabel, - consumedInstance, - consumedProcessName, - itInfo->m_branchType, - *itKind, - *itAlways, - itInfo->m_index.skipCurrentProcess()); - } + result.reserve(m_tokenInfo.size()); + consumedProducts([&](ModuleConsumesInfo const& info) { + assert(not info.label().empty()); + result.push_back(info); + }); return result; } -std::vector EDConsumerBase::moduleConsumesESInfos( - eventsetup::ESRecordsToProductResolverIndices const& iPI) const { - std::vector result; - - ModuleConsumesESInfo info; - - unsigned int index = 0; - auto itResolver = esTokenLookupInfoContainer().begin(); - for (auto it = esTokenLookupInfoContainer().begin(); - it != esTokenLookupInfoContainer().end(); - ++it, ++itResolver, ++index) { - info.eventSetupRecordType_ = it->m_record.name(); - info.productType_ = it->m_key.type().name(); - info.productLabel_ = it->m_key.name().value(); - info.requestedModuleLabel_ = &(m_tokenLabels[it->m_startOfComponentName]); - info.transitionOfConsumer_ = static_cast(consumesIndexConverter()[index].first); - info.moduleLabelMismatch_ = *itResolver == ESResolverIndex::moduleLabelDoesNotMatch(); - - // Initial values used in the case where there isn't an EventSetup - // module to produce the requested data. Test whether moduleType - // is empty to identify this case because it will be empty if and - // only if this is true. - info.moduleType_ = {}; - info.moduleLabel_ = {}; - info.produceMethodIDOfProducer_ = 0; - info.isSource_ = false; - info.isLooper_ = false; - - auto [componentDescription, produceMethodID] = iPI.componentAndProduceMethodID(it->m_record, *itResolver); - if (componentDescription) { - info.moduleType_ = componentDescription->type_; - info.moduleLabel_ = - componentDescription->label_.empty() ? componentDescription->type_ : componentDescription->label_; - info.produceMethodIDOfProducer_ = produceMethodID; - info.isSource_ = componentDescription->isSource_; - info.isLooper_ = componentDescription->isLooper_; - } - result.push_back(info); - } +std::vector EDConsumerBase::moduleConsumesMinimalESInfos() const { + std::vector result; + result.reserve(esTokenLookupInfoContainer().size()); + consumedESProducts([&](ModuleConsumesMinimalESInfo&& minInfo) mutable { result.emplace_back(std::move(minInfo)); }); return result; } diff --git a/FWCore/Framework/src/ESProducer.cc b/FWCore/Framework/src/ESProducer.cc index 1b82690d3147f..869102d387c41 100644 --- a/FWCore/Framework/src/ESProducer.cc +++ b/FWCore/Framework/src/ESProducer.cc @@ -16,6 +16,7 @@ #include "FWCore/Framework/interface/ESRecordsToProductResolverIndices.h" #include "FWCore/Framework/interface/EventSetupRecordKey.h" #include "FWCore/Framework/interface/SharedResourcesRegistry.h" +#include "FWCore/Framework/interface/ESModuleConsumesMinimalInfo.h" #include "FWCore/ServiceRegistry/interface/ESModuleConsumesInfo.h" #include "FWCore/Utilities/interface/ESIndices.h" @@ -93,47 +94,21 @@ namespace edm { } } - void ESProducer::esModulesWhoseProductsAreConsumed(std::vector& esModules, - eventsetup::ESRecordsToProductResolverIndices const& iPI) const { - std::set alreadyFound; - - // updateLookup should have already been called if we are here - // If it has been called, then this assert should not fail. - assert(consumesInfos_.size() == itemsToGetFromRecords_.size()); - - // Here transition identifies which call to setWhatProduced (each corresponding to a "produce" function) - // Often there is only one. - auto it = itemsToGetFromRecords_.begin(); - for (auto const& transition : consumesInfos_) { - auto itResolver = it->begin(); - for (auto const& esConsumesInfoEntry : *transition) { - // If there is a chooser this is the special case of a "may consumes" - if (esConsumesInfoEntry.chooser_) { - auto const& esTagGetterInfos = esConsumesInfoEntry.chooser_->tagGetter().lookup(); - - for (auto const& esTagGetterInfo : esTagGetterInfos) { - auto [componentDescription, produceMethodID] = - iPI.componentAndProduceMethodID(esConsumesInfoEntry.recordKey_, esTagGetterInfo.index_); - assert(componentDescription); - if (alreadyFound.insert(componentDescription->id_).second) { - esModules.push_back(componentDescription); - } - } - - // Handle cases not involving "may consumes" - } else { - auto [componentDescription, produceMethodID] = - iPI.componentAndProduceMethodID(esConsumesInfoEntry.recordKey_, *itResolver); - if (componentDescription) { - if (alreadyFound.insert(componentDescription->id_).second) { - esModules.push_back(componentDescription); - } - } - } - ++itResolver; + std::vector ESProducer::esModuleConsumesMinimalInfos() const { + std::vector result; + size_t totalSize = 0; + for (auto const& esConsumesInfo : consumesInfos_) { + totalSize += esConsumesInfo->size(); + } + result.reserve(totalSize); + for (unsigned int index = 0; auto const& esConsumesInfo : consumesInfos_) { + for (auto const& esConsumesInfoEntry : *esConsumesInfo) { + result.emplace_back( + index, esConsumesInfoEntry.recordKey_, esConsumesInfoEntry.productKey_, esConsumesInfoEntry.moduleLabel_); } - ++it; + ++index; } + return result; } std::vector> ESProducer::esModuleConsumesInfos( diff --git a/FWCore/Framework/src/ESProductResolverFactoryProducer.cc b/FWCore/Framework/src/ESProductResolverFactoryProducer.cc index 006781a8d3af9..cc04edbad6f14 100644 --- a/FWCore/Framework/src/ESProductResolverFactoryProducer.cc +++ b/FWCore/Framework/src/ESProductResolverFactoryProducer.cc @@ -17,6 +17,7 @@ // user include files #include "FWCore/Framework/interface/ESProductResolverFactoryProducer.h" #include "FWCore/Framework/interface/ESProductResolverFactoryBase.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" #include "FWCore/Framework/interface/ESProductResolver.h" @@ -31,6 +32,14 @@ namespace edm { ESProductResolverFactoryProducer::~ESProductResolverFactoryProducer() noexcept(false) {} + std::vector ESProductResolverFactoryProducer::producesInfo() const { + std::vector producesInfo; + for (auto const& it : record2Factories_) { + producesInfo.emplace_back(it.first, it.second.key_, it.second.factory_->produceMethodID()); + } + return producesInfo; + } + ESProductResolverProvider::KeyedResolversVector ESProductResolverFactoryProducer::registerResolvers( const EventSetupRecordKey& iRecord, unsigned int iovIndex) { KeyedResolversVector keyedResolversVector; diff --git a/FWCore/Framework/src/ESTagGetter.cc b/FWCore/Framework/src/ESTagGetter.cc index 469509e68c485..c30a24fcaff28 100644 --- a/FWCore/Framework/src/ESTagGetter.cc +++ b/FWCore/Framework/src/ESTagGetter.cc @@ -14,7 +14,6 @@ // user include files #include "FWCore/Framework/interface/ESTagGetter.h" -#include "FWCore/Framework/interface/ESRecordsToProductResolverIndices.h" #include "FWCore/Framework/interface/ComponentDescription.h" using namespace edm; diff --git a/FWCore/Framework/src/EventProcessor.cc b/FWCore/Framework/src/EventProcessor.cc index cf27cfb7c9e0a..a0c5990ca2ed1 100644 --- a/FWCore/Framework/src/EventProcessor.cc +++ b/FWCore/Framework/src/EventProcessor.cc @@ -716,7 +716,7 @@ namespace edm { if (firstException) { std::rethrow_exception(firstException); } - pathsAndConsumesOfModules.initializeForEventSetup(std::move(esRecordsToProductResolverIndices), *esp_); + pathsAndConsumesOfModules.initializeForEventSetup(*esp_); actReg_->lookupInitializationCompleteSignal_(pathsAndConsumesOfModules, processContext_); schedule_->releaseMemoryPostLookupSignal(); diff --git a/FWCore/Framework/src/EventSetupProvider.cc b/FWCore/Framework/src/EventSetupProvider.cc index cd3889034a010..32267388436db 100644 --- a/FWCore/Framework/src/EventSetupProvider.cc +++ b/FWCore/Framework/src/EventSetupProvider.cc @@ -76,6 +76,15 @@ namespace edm { return recordProviders_[index].get(); } + EventSetupRecordProvider const* EventSetupProvider::tryToGetRecordProvider(const EventSetupRecordKey& iKey) const { + auto lb = std::lower_bound(recordKeys_.begin(), recordKeys_.end(), iKey); + if (lb == recordKeys_.end() || iKey != *lb) { + return nullptr; + } + auto index = std::distance(recordKeys_.begin(), lb); + return recordProviders_[index].get(); + } + void EventSetupProvider::fillAllESProductResolverProviders( std::vector& allESProductResolverProviders) const { std::unordered_set componentIDs; diff --git a/FWCore/Framework/src/EventSetupRecordImpl.cc b/FWCore/Framework/src/EventSetupRecordImpl.cc index faf92308a183d..6edfc09edf115 100644 --- a/FWCore/Framework/src/EventSetupRecordImpl.cc +++ b/FWCore/Framework/src/EventSetupRecordImpl.cc @@ -254,9 +254,7 @@ namespace edm { return nullptr; } - void EventSetupRecordImpl::fillRegisteredDataKeys(std::vector& oToFill) const { - oToFill = keysForResolvers_; - } + std::vector const& EventSetupRecordImpl::registeredDataKeys() const { return keysForResolvers_; } void EventSetupRecordImpl::addTraceInfoToCmsException(cms::Exception& iException, const char* iName, diff --git a/FWCore/Framework/src/EventSetupRecordProvider.cc b/FWCore/Framework/src/EventSetupRecordProvider.cc index d64685c84c040..593f1b2d199bb 100644 --- a/FWCore/Framework/src/EventSetupRecordProvider.cc +++ b/FWCore/Framework/src/EventSetupRecordProvider.cc @@ -235,8 +235,8 @@ namespace edm { void EventSetupRecordProvider::fillReferencedDataKeys( std::map& referencedDataKeys) const { - std::vector keys; - firstRecordImpl().fillRegisteredDataKeys(keys); + std::vector const& keys = firstRecordImpl().registeredDataKeys(); + std::vector components = firstRecordImpl().componentsForRegisteredDataKeys(); auto itComponents = components.begin(); for (auto const& k : keys) { @@ -316,10 +316,8 @@ namespace edm { } } - std::vector EventSetupRecordProvider::registeredDataKeys() const { - std::vector ret; - firstRecordImpl().fillRegisteredDataKeys(ret); - return ret; + std::vector const& EventSetupRecordProvider::registeredDataKeys() const { + return firstRecordImpl().registeredDataKeys(); } std::vector EventSetupRecordProvider::componentsForRegisteredDataKeys() const { diff --git a/FWCore/Framework/src/PathsAndConsumesOfModules.cc b/FWCore/Framework/src/PathsAndConsumesOfModules.cc index cf51fd7fabb2d..ffb01aa50c4b5 100644 --- a/FWCore/Framework/src/PathsAndConsumesOfModules.cc +++ b/FWCore/Framework/src/PathsAndConsumesOfModules.cc @@ -2,20 +2,180 @@ #include "FWCore/Framework/interface/ESProducer.h" #include "FWCore/Framework/interface/EventSetupProvider.h" +#include "FWCore/Framework/interface/EventSetupRecordProvider.h" #include "FWCore/Framework/interface/Schedule.h" #include "FWCore/Framework/interface/maker/Worker.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" +#include "FWCore/Framework/interface/ESModuleConsumesMinimalInfo.h" +#include "FWCore/Framework/interface/EventSetupRecordKey.h" #include "FWCore/ServiceRegistry/interface/ESModuleConsumesInfo.h" #include "FWCore/ServiceRegistry/interface/ModuleConsumesESInfo.h" #include "FWCore/ServiceRegistry/interface/ModuleConsumesInfo.h" #include "FWCore/Utilities/interface/EDMException.h" - +#include "DataFormats/Provenance/interface/ProductResolverIndexHelper.h" +#include "DataFormats/Provenance/interface/ProductRegistry.h" #include #include #include #include +#include + +#include // for debugging namespace edm { + namespace { + void insertFoundModuleLabel(edm::KindOfType consumedTypeKind, + edm::TypeID consumedType, + const char* consumedModuleLabel, + const char* consumedProductInstance, + std::vector& modules, + std::set& alreadyFound, + std::map const& labelsToDesc, + ProductRegistry const& preg) { + // Convert from label string to module description, eliminate duplicates, + // then insert into the vector of modules + if (auto it = labelsToDesc.find(consumedModuleLabel); it != labelsToDesc.end()) { + if (alreadyFound.insert(consumedModuleLabel).second) { + modules.push_back(it->second); + } + return; + } + // Deal with EDAlias's by converting to the original module label first + if (auto aliasToModuleLabels = + preg.aliasToModules(consumedTypeKind, consumedType, consumedModuleLabel, consumedProductInstance); + not aliasToModuleLabels.empty()) { + bool foundInLabelsToDesc = false; + for (auto const& label : aliasToModuleLabels) { + if (auto it = labelsToDesc.find(label); it != labelsToDesc.end()) { + if (alreadyFound.insert(label).second) { + modules.push_back(it->second); + } + foundInLabelsToDesc = true; + } else { + if (label == "source") { + foundInLabelsToDesc = true; + } + } + } + if (foundInLabelsToDesc) { + return; + } + } + // Ignore the source products, we are only interested in module products. + // As far as I know, it should never be anything else so throw if something + // unknown gets passed in. + if (std::string_view(consumedModuleLabel) != "source") { + throw cms::Exception("EDConsumerBase", "insertFoundModuleLabel") + << "Couldn't find ModuleDescription for the consumed product type: '" << consumedType.className() + << "' module label: '" << consumedModuleLabel << "' product instance name: '" << consumedProductInstance + << "'"; + } + } + + void modulesWhoseProductsAreConsumed(Worker* iWorker, + std::array*, NumBranchTypes>& modulesAll, + ProductRegistry const& preg, + std::map const& labelsToDesc, + std::string const& processName) { + std::set alreadyFound; + + for (ModuleConsumesInfo const& consumesInfo : iWorker->moduleConsumesInfos()) { + ProductResolverIndexHelper const& helper = *preg.productLookup(consumesInfo.branchType()); + std::vector& modules = *modulesAll[consumesInfo.branchType()]; + + auto consumedModuleLabel = consumesInfo.label(); + auto consumedProductInstance = consumesInfo.instance(); + auto consumedProcessName = consumesInfo.process(); + auto kind = consumesInfo.kindOfType(); + auto const& typeID = consumesInfo.type(); + + if (not consumesInfo.skipCurrentProcess()) { + // consumesMany used to create empty labels before we removed consumesMany + assert(*consumedModuleLabel.data() != '\0'); + if (*consumedProcessName.data() != '\0') { // process name is specified in consumes call + if (helper.index(kind, + typeID, + consumedModuleLabel.data(), + consumedProductInstance.data(), + consumedProcessName.data()) != ProductResolverIndexInvalid) { + if (processName == consumedProcessName) { + insertFoundModuleLabel(kind, + typeID, + consumedModuleLabel.data(), + consumedProductInstance.data(), + modules, + alreadyFound, + labelsToDesc, + preg); + } + } + } else { // process name was empty + auto matches = + helper.relatedIndexes(kind, typeID, consumedModuleLabel.data(), consumedProductInstance.data()); + for (unsigned int j = 0; j < matches.numberOfMatches(); ++j) { + if (processName == matches.processName(j)) { + insertFoundModuleLabel(kind, + typeID, + consumedModuleLabel.data(), + consumedProductInstance.data(), + modules, + alreadyFound, + labelsToDesc, + preg); + } + } + } + } + }; + } + void fillModuleAndConsumesInfo(Schedule::AllWorkers const& allWorkers, + std::vector& allModuleDescriptions, + std::vector>& moduleIDToIndex, + std::array>, NumBranchTypes>& + modulesWhoseProductsAreConsumedBy, + ProductRegistry const& preg) { + allModuleDescriptions.clear(); + moduleIDToIndex.clear(); + for (auto iBranchType = 0U; iBranchType < NumBranchTypes; ++iBranchType) { + modulesWhoseProductsAreConsumedBy[iBranchType].clear(); + } + + allModuleDescriptions.reserve(allWorkers.size()); + moduleIDToIndex.reserve(allWorkers.size()); + for (auto iBranchType = 0U; iBranchType < NumBranchTypes; ++iBranchType) { + modulesWhoseProductsAreConsumedBy[iBranchType].resize(allWorkers.size()); + } + + std::map labelToDesc; + unsigned int i = 0; + for (auto const& worker : allWorkers) { + ModuleDescription const* p = worker->description(); + allModuleDescriptions.push_back(p); + moduleIDToIndex.push_back(std::pair(p->id(), i)); + labelToDesc[p->moduleLabel()] = p; + ++i; + } + sort_all(moduleIDToIndex); + + i = 0; + for (auto const& worker : allWorkers) { + std::array*, NumBranchTypes> modules; + for (auto iBranchType = 0U; iBranchType < NumBranchTypes; ++iBranchType) { + modules[iBranchType] = &modulesWhoseProductsAreConsumedBy[iBranchType].at(i); + } + try { + modulesWhoseProductsAreConsumed(worker, modules, preg, labelToDesc, worker->description()->processName()); + } catch (cms::Exception& ex) { + ex.addContext("Calling Worker::modulesWhoseProductsAreConsumed() for module " + + worker->description()->moduleLabel()); + throw; + } + ++i; + } + } + } // namespace + void PathsAndConsumesOfModules::initialize(Schedule const* schedule, std::shared_ptr preg) { schedule_ = schedule; preg_ = preg; @@ -46,17 +206,153 @@ namespace edm { ++i; } - schedule->fillModuleAndConsumesInfo( - allModuleDescriptions_, moduleIDToIndex_, modulesWhoseProductsAreConsumedBy_, *preg); + fillModuleAndConsumesInfo( + schedule_->allWorkers(), allModuleDescriptions_, moduleIDToIndex_, modulesWhoseProductsAreConsumedBy_, *preg); } - void PathsAndConsumesOfModules::initializeForEventSetup( - eventsetup::ESRecordsToProductResolverIndices&& esRecordsToProductResolverIndices, - eventsetup::EventSetupProvider const& eventSetupProvider) { - esRecordsToProductResolverIndices_ = std::move(esRecordsToProductResolverIndices); - schedule_->fillESModuleAndConsumesInfo(esModulesWhoseProductsAreConsumedBy_, esRecordsToProductResolverIndices_); + using ProducedByESModule = PathsAndConsumesOfModules::ProducedByESModule; + namespace { + void esModulesWhoseProductsAreConsumed( + Worker* worker, + std::array*, kNumberOfEventSetupTransitions>& esModules, + ProducedByESModule const& producedByESModule) { + std::array, kNumberOfEventSetupTransitions> alreadyFound; + + for (auto const& info : worker->moduleConsumesMinimalESInfos()) { + auto const& recordInfo = producedByESModule.find(info.record_); + if (recordInfo != producedByESModule.end()) { + auto itFound = recordInfo->second.find(info.dataKey_); + if (itFound != recordInfo->second.end()) { + auto const& componentDescription = itFound->second.componentDescription_; + if (componentDescription) { + std::string const& moduleLabel = + componentDescription->label_.empty() ? componentDescription->type_ : componentDescription->label_; + //check for matching labels if required + if (info.componentLabel_.empty() || info.componentLabel_ == moduleLabel) { + auto transitionIndex = static_cast(info.transition_); + if (alreadyFound[transitionIndex].insert(moduleLabel).second) { + esModules[transitionIndex]->push_back(componentDescription); + } + } + } + } + } + } + } + + std::array>, kNumberOfEventSetupTransitions> + esModulesWhoseProductsAreConsumedByCreate(Schedule::AllWorkers const& allWorkers, + ProducedByESModule const& producedByESModule) { + std::array>, kNumberOfEventSetupTransitions> + esModulesWhoseProductsAreConsumedBy; + + for (auto& item : esModulesWhoseProductsAreConsumedBy) { + item.resize(allWorkers.size()); + } + + for (unsigned int i = 0; auto const& worker : allWorkers) { + std::array*, kNumberOfEventSetupTransitions> esModules; + for (auto transition = 0U; transition < kNumberOfEventSetupTransitions; ++transition) { + esModules[transition] = &esModulesWhoseProductsAreConsumedBy[transition].at(i); + } + try { + esModulesWhoseProductsAreConsumed(worker, esModules, producedByESModule); + } catch (cms::Exception& ex) { + ex.addContext("Calling Worker::esModulesWhoseProductsAreConsumed() for module " + + worker->description()->moduleLabel()); + throw; + } + ++i; + } + return esModulesWhoseProductsAreConsumedBy; + } + + ProducedByESModule fillProducedByESModule(eventsetup::EventSetupProvider const& esProvider) { + ProducedByESModule producedByESModule; + + std::set keys; + esProvider.fillKeys(keys); + + for (auto const& recordKey : keys) { + auto const* providers = esProvider.tryToGetRecordProvider(recordKey); + if (providers) { + auto const& datakeys = providers->registeredDataKeys(); + auto const& componentsForDataKeys = providers->componentsForRegisteredDataKeys(); + auto const& produceMethodIDs = providers->produceMethodIDsForRegisteredDataKeys(); + assert(datakeys.size() == componentsForDataKeys.size()); + assert(datakeys.size() == produceMethodIDs.size()); + for (unsigned int i = 0; i < datakeys.size(); ++i) { + auto const& dataKey = datakeys[i]; + auto const* componentDescription = componentsForDataKeys[i]; + auto produceMethodID = produceMethodIDs[i]; + producedByESModule[recordKey][dataKey] = {componentDescription, produceMethodID}; + } + } + } + return producedByESModule; + } + + std::vector> esModulesWhoseProductsAreConsumedByESModuleCreate( + std::vector const& allESProductResolverProviders, + ProducedByESModule const& producedByESModule) { + std::vector> retValue; + + retValue.resize(allESProductResolverProviders.size()); + auto it = retValue.begin(); + for (auto& provider : allESProductResolverProviders) { + ESProducer const* esProducer = dynamic_cast(provider); + if (esProducer) { + std::set alreadyFound; + auto const& consumesInfo = esProducer->esModuleConsumesMinimalInfos(); + for (auto const& info : consumesInfo) { + auto const& recordKey = info.recordForDataKey_; + auto const& dataKey = info.dataKey_; + auto itFound = producedByESModule.find(recordKey); + if (itFound != producedByESModule.end()) { + if (dataKey.name() == "@mayConsume") { + // This is a "may consume" case, we need to find all components that may produce this dataKey + for (auto const& [dataKey, produceInfo] : itFound->second) { + auto componentDescription = produceInfo.componentDescription_; + if (dataKey.type() == info.dataKey_.type()) { + if (componentDescription and alreadyFound.find(componentDescription->id_) == alreadyFound.end()) { + alreadyFound.insert(componentDescription->id_); + it->push_back(componentDescription); + } + } + } + } else { + // This is a normal case, we need to find the specific component that produces this dataKey + auto itDataKey = itFound->second.find(dataKey); + if (itDataKey != itFound->second.end()) { + eventsetup::ComponentDescription const* componentDescription = + itDataKey->second.componentDescription_; + if (componentDescription and alreadyFound.find(componentDescription->id_) == alreadyFound.end()) { + //an empty label matches any label, else we need an exact match + if (info.componentLabel_.empty() || info.componentLabel_ == componentDescription->label_) { + alreadyFound.insert(componentDescription->id_); + it->push_back(componentDescription); + } + } + } + } + } + } + } + ++it; + } + return retValue; + } + + } // namespace + + void PathsAndConsumesOfModules::initializeForEventSetup(eventsetup::EventSetupProvider const& eventSetupProvider) { eventSetupProvider.fillAllESProductResolverProviders(allESProductResolverProviders_); + producedByESModule_ = fillProducedByESModule(eventSetupProvider); + + esModulesWhoseProductsAreConsumedBy_ = + esModulesWhoseProductsAreConsumedByCreate(schedule_->allWorkers(), producedByESModule_); + for (unsigned int i = 0; i < allESProductResolverProviders_.size(); ++i) { eventsetup::ComponentDescription const& componentDescription = allESProductResolverProviders_[i]->description(); esModuleIDToIndex_.emplace_back(componentDescription.id_, i); @@ -64,15 +360,8 @@ namespace edm { } sort_all(esModuleIDToIndex_); - esModulesWhoseProductsAreConsumedByESModule_.resize(allESProductResolverProviders_.size()); - auto it = esModulesWhoseProductsAreConsumedByESModule_.begin(); - for (auto& provider : allESProductResolverProviders_) { - ESProducer const* esProducer = dynamic_cast(provider); - if (esProducer) { - esProducer->esModulesWhoseProductsAreConsumed(*it, esRecordsToProductResolverIndices_); - } - ++it; - } + esModulesWhoseProductsAreConsumedByESModule_ = + esModulesWhoseProductsAreConsumedByESModuleCreate(allESProductResolverProviders_, producedByESModule_); eventSetupInfoInitialized_ = true; } @@ -171,10 +460,67 @@ namespace edm { return worker->moduleConsumesInfos(); } + auto const& labelForComponentDescription(eventsetup::ComponentDescription const* description) { + if (description->label_.empty()) { + return description->type_; + } + return description->label_; + } + std::vector PathsAndConsumesOfModules::doModuleConsumesESInfos(unsigned int moduleID) const { checkEventSetupInitialization(); Worker const* worker = schedule_->allWorkers().at(moduleIndex(moduleID)); - return worker->moduleConsumesESInfos(esRecordsToProductResolverIndices_); + auto const& minConsumesESInfos = worker->moduleConsumesMinimalESInfos(); + std::vector result; + result.reserve(minConsumesESInfos.size()); + for (auto const& minInfo : minConsumesESInfos) { + ModuleConsumesESInfo info; + info.eventSetupRecordType_ = minInfo.record_.name(); + info.productType_ = minInfo.dataKey_.type().name(); + //Moving this to a string_view is safe as the minInfo.dataKey_ does not own the memory + info.productLabel_ = minInfo.dataKey_.name().value(); + info.requestedModuleLabel_ = minInfo.componentLabel_; + info.transitionOfConsumer_ = minInfo.transition_; + if (not info.requestedModuleLabel_.empty()) { + auto itRec = producedByESModule_.find(minInfo.record_); + if (itRec != producedByESModule_.end()) { + auto itDataKeyInfo = itRec->second.find(minInfo.dataKey_); + if (itDataKeyInfo != itRec->second.end()) { + info.moduleLabelMismatch_ = + labelForComponentDescription(itDataKeyInfo->second.componentDescription_) != info.requestedModuleLabel_; + } + } + } + + // Initial values used in the case where there isn't an EventSetup + // module to produce the requested data. Test whether moduleType + // is empty to identify this case because it will be empty if and + // only if this is true. + info.moduleType_ = {}; + info.moduleLabel_ = {}; + info.produceMethodIDOfProducer_ = 0; + info.isSource_ = false; + info.isLooper_ = false; + + auto itRec = producedByESModule_.find(minInfo.record_); + if (itRec != producedByESModule_.end()) { + auto itDataKeyInfo = itRec->second.find(minInfo.dataKey_); + if (itDataKeyInfo != itRec->second.end()) { + auto produceMethodID = itDataKeyInfo->second.produceMethodID_; + auto componentDescription = itDataKeyInfo->second.componentDescription_; + if (componentDescription) { + info.moduleType_ = componentDescription->type_; + info.moduleLabel_ = + componentDescription->label_.empty() ? componentDescription->type_ : componentDescription->label_; + info.produceMethodIDOfProducer_ = produceMethodID; + info.isSource_ = componentDescription->isSource_; + info.isLooper_ = componentDescription->isLooper_; + } + } + } + result.emplace_back(info); + }; + return result; } unsigned int PathsAndConsumesOfModules::doLargestModuleID() const { @@ -198,6 +544,119 @@ namespace edm { return esModulesWhoseProductsAreConsumedByESModule_; } + namespace { + std::vector> esModuleConsumesInfosCreate( + ESProducer const& esProducer, ProducedByESModule const& producedByESModule) { + auto const& consumesInfos = esProducer.esModuleConsumesMinimalInfos(); + std::vector> result; + // The outer vector has an entry per produce method ID + unsigned int largestProduceMethodID = 0; + for (auto const& produced : esProducer.producesInfo()) { + if (produced.produceMethodID() > largestProduceMethodID) { + largestProduceMethodID = produced.produceMethodID(); + } + } + result.resize(largestProduceMethodID + 1); + if (consumesInfos.empty()) { + return result; + } + result.resize(consumesInfos.back().produceMethodID_ + 1); + + for (auto const& esConsumesInfo : consumesInfos) { + auto& resultForTransition = result[esConsumesInfo.produceMethodID_]; + + ESModuleConsumesInfo info; + info.produceMethodIDOfConsumer_ = esConsumesInfo.produceMethodID_; + info.eventSetupRecordType_ = esConsumesInfo.recordForDataKey_.name(); + info.productType_ = esConsumesInfo.dataKey_.type().name(); + info.moduleType_ = {}; + info.moduleLabel_ = {}; + info.produceMethodIDOfProducer_ = 0; + info.isSource_ = false; + info.isLooper_ = false; + info.moduleLabelMismatch_ = false; + + // If there is a chooser this is the special case of a "may consumes" + if (esConsumesInfo.dataKey_.name() == "@mayConsume") { + info.requestedModuleLabel_ = {}; + info.mayConsumes_ = true; + info.mayConsumesFirstEntry_ = true; + + //look for matches + auto itRec = producedByESModule.find(esConsumesInfo.recordForDataKey_); + if (itRec == producedByESModule.end()) { + // No producers for this record, so no products can be consumed + info.productLabel_ = {}; + info.mayConsumesNoProducts_ = true; + resultForTransition.push_back(info); + continue; + } + // In the "may consumes" case, we iterate over all the possible data products + // the EventSetup can produce with matching record type and product type. + // With the current design of the mayConsumes feature, there is no way to + // know in advance which productLabel or moduleLabel will be requested. + // Maybe none will be. requestedModuleLabel and moduleLabelMismatch + // are meaningless for "may consumes" cases. + + auto const nPreMayConsumes = resultForTransition.size(); + for (auto const& products : itRec->second) { + if (products.first.type() == esConsumesInfo.dataKey_.type()) { + // This is a "may consume" case, we need to find all components that may produce this dataKey + auto const& componentDescription = products.second.componentDescription_; + if (componentDescription) { + info.productLabel_ = products.first.name().value(); + info.moduleType_ = componentDescription->type_; + info.moduleLabel_ = labelForComponentDescription(componentDescription); + info.mayConsumesNoProducts_ = false; + + info.produceMethodIDOfProducer_ = products.second.produceMethodID_; + info.isSource_ = componentDescription->isSource_; + info.isLooper_ = componentDescription->isLooper_; + resultForTransition.push_back(info); + info.mayConsumesFirstEntry_ = false; + } + } + } + if (resultForTransition.size() == nPreMayConsumes) { + // No products can be consumed, so we add an empty entry + // to indicate that this is a "may consumes" case with no products + info.productLabel_ = {}; + info.mayConsumesNoProducts_ = true; + resultForTransition.push_back(info); + } + // Handle cases not involving "may consumes" + } else { + //look for matches + info.productLabel_ = esConsumesInfo.dataKey_.name().value(); + info.requestedModuleLabel_ = esConsumesInfo.componentLabel_; + auto itRec = producedByESModule.find(esConsumesInfo.recordForDataKey_); + if (itRec != producedByESModule.end()) { + auto itProduceInfo = itRec->second.find(esConsumesInfo.dataKey_); + if (itProduceInfo != itRec->second.end()) { + auto const componentDescription = itProduceInfo->second.componentDescription_; + info.moduleLabelMismatch_ = + ((componentDescription) and (not esConsumesInfo.componentLabel_.empty()) and + esConsumesInfo.componentLabel_ != labelForComponentDescription(componentDescription)); + info.mayConsumes_ = false; + info.mayConsumesFirstEntry_ = false; + info.mayConsumesNoProducts_ = false; + + if (componentDescription) { + info.moduleType_ = componentDescription->type_; + info.moduleLabel_ = labelForComponentDescription(componentDescription); + info.produceMethodIDOfProducer_ = itProduceInfo->second.produceMethodID_; + info.isSource_ = componentDescription->isSource_; + info.isLooper_ = componentDescription->isLooper_; + } + } + } + resultForTransition.push_back(info); + } + } + return result; + } + + } // namespace std::vector> PathsAndConsumesOfModules::doESModuleConsumesInfos( unsigned int esModuleID) const { checkEventSetupInitialization(); @@ -205,7 +664,7 @@ namespace edm { allESProductResolverProviders_.at(esModuleIndex(esModuleID)); ESProducer const* esProducer = dynamic_cast(provider); if (esProducer) { - return esProducer->esModuleConsumesInfos(esRecordsToProductResolverIndices_); + return esModuleConsumesInfosCreate(*esProducer, producedByESModule_); } return {}; } diff --git a/FWCore/Framework/src/Schedule.cc b/FWCore/Framework/src/Schedule.cc index 3b397d0629d2c..18ee962375fad 100644 --- a/FWCore/Framework/src/Schedule.cc +++ b/FWCore/Framework/src/Schedule.cc @@ -24,6 +24,8 @@ #include "FWCore/Framework/interface/SignallingProductRegistryFiller.h" #include "FWCore/Framework/src/PathStatusInserter.h" #include "FWCore/Framework/src/EndPathStatusInserter.h" +#include "FWCore/Framework/interface/ESRecordsToProductResolverIndices.h" +#include "FWCore/Framework/interface/ComponentDescription.h" #include "FWCore/Concurrency/interface/WaitingTaskHolder.h" #include "FWCore/Concurrency/interface/chain_first.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -1312,77 +1314,6 @@ namespace edm { streamSchedules_[0]->moduleDescriptionsInEndPath(iEndPathLabel, descriptions, hint); } - void Schedule::fillModuleAndConsumesInfo( - std::vector& allModuleDescriptions, - std::vector>& moduleIDToIndex, - std::array>, NumBranchTypes>& modulesWhoseProductsAreConsumedBy, - ProductRegistry const& preg) const { - allModuleDescriptions.clear(); - moduleIDToIndex.clear(); - for (auto iBranchType = 0U; iBranchType < NumBranchTypes; ++iBranchType) { - modulesWhoseProductsAreConsumedBy[iBranchType].clear(); - } - - allModuleDescriptions.reserve(allWorkers().size()); - moduleIDToIndex.reserve(allWorkers().size()); - for (auto iBranchType = 0U; iBranchType < NumBranchTypes; ++iBranchType) { - modulesWhoseProductsAreConsumedBy[iBranchType].resize(allWorkers().size()); - } - - std::map labelToDesc; - unsigned int i = 0; - for (auto const& worker : allWorkers()) { - ModuleDescription const* p = worker->description(); - allModuleDescriptions.push_back(p); - moduleIDToIndex.push_back(std::pair(p->id(), i)); - labelToDesc[p->moduleLabel()] = p; - ++i; - } - sort_all(moduleIDToIndex); - - i = 0; - for (auto const& worker : allWorkers()) { - std::array*, NumBranchTypes> modules; - for (auto iBranchType = 0U; iBranchType < NumBranchTypes; ++iBranchType) { - modules[iBranchType] = &modulesWhoseProductsAreConsumedBy[iBranchType].at(i); - } - - try { - worker->modulesWhoseProductsAreConsumed(modules, preg, labelToDesc); - } catch (cms::Exception& ex) { - ex.addContext("Calling Worker::modulesWhoseProductsAreConsumed() for module " + - worker->description()->moduleLabel()); - throw; - } - ++i; - } - } - - void Schedule::fillESModuleAndConsumesInfo( - std::array>, kNumberOfEventSetupTransitions>& - esModulesWhoseProductsAreConsumedBy, - eventsetup::ESRecordsToProductResolverIndices const& iPI) const { - for (auto& item : esModulesWhoseProductsAreConsumedBy) { - item.clear(); - item.resize(allWorkers().size()); - } - unsigned int i = 0; - for (auto const& worker : allWorkers()) { - std::array*, kNumberOfEventSetupTransitions> esModules; - for (auto transition = 0U; transition < kNumberOfEventSetupTransitions; ++transition) { - esModules[transition] = &esModulesWhoseProductsAreConsumedBy[transition].at(i); - } - try { - worker->esModulesWhoseProductsAreConsumed(esModules, iPI); - } catch (cms::Exception& ex) { - ex.addContext("Calling Worker::esModulesWhoseProductsAreConsumed() for module " + - worker->description()->moduleLabel()); - throw; - } - ++i; - } - } - void Schedule::getTriggerReport(TriggerReport& rep) const { rep.eventSummary.totalEvents = 0; rep.eventSummary.totalEventsPassed = 0; diff --git a/FWCore/Framework/src/WorkerT.cc b/FWCore/Framework/src/WorkerT.cc index f2ab44679ac96..0f4c52a2fe200 100644 --- a/FWCore/Framework/src/WorkerT.cc +++ b/FWCore/Framework/src/WorkerT.cc @@ -20,7 +20,6 @@ #include "FWCore/Framework/interface/limited/OutputModuleBase.h" #include "FWCore/ServiceRegistry/interface/ModuleConsumesInfo.h" -#include "FWCore/ServiceRegistry/interface/ModuleConsumesESInfo.h" #include @@ -930,12 +929,6 @@ namespace edm { return module_->moduleConsumesInfos(); } - template - std::vector WorkerT::moduleConsumesESInfos( - eventsetup::ESRecordsToProductResolverIndices const& iPI) const { - return module_->moduleConsumesESInfos(iPI); - } - //Explicitly instantiate our needed templates to avoid having the compiler // instantiate them in all of our libraries template class WorkerT; diff --git a/FWCore/Framework/src/stream/EDAnalyzerAdaptorBase.cc b/FWCore/Framework/src/stream/EDAnalyzerAdaptorBase.cc index 999b9d0fd517b..bbe089c60b239 100644 --- a/FWCore/Framework/src/stream/EDAnalyzerAdaptorBase.cc +++ b/FWCore/Framework/src/stream/EDAnalyzerAdaptorBase.cc @@ -24,7 +24,6 @@ #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h" #include "FWCore/Framework/interface/RunPrincipal.h" #include "FWCore/ServiceRegistry/interface/ESParentContext.h" -#include "FWCore/ServiceRegistry/interface/ModuleConsumesESInfo.h" #include "FWCore/ServiceRegistry/interface/ModuleConsumesInfo.h" #include "FWCore/Framework/interface/PreallocationConfiguration.h" @@ -139,22 +138,6 @@ void EDAnalyzerAdaptorBase::releaseMemoryPostLookupSignal() { const edm::EDConsumerBase* EDAnalyzerAdaptorBase::consumer() const { return m_streamModules[0]; } -void EDAnalyzerAdaptorBase::modulesWhoseProductsAreConsumed( - std::array*, NumBranchTypes>& modules, - ProductRegistry const& preg, - std::map const& labelsToDesc, - std::string const& processName) const { - assert(not m_streamModules.empty()); - return m_streamModules[0]->modulesWhoseProductsAreConsumed(modules, preg, labelsToDesc, processName); -} - -void EDAnalyzerAdaptorBase::esModulesWhoseProductsAreConsumed( - std::array*, kNumberOfEventSetupTransitions>& esModules, - eventsetup::ESRecordsToProductResolverIndices const& iPI) const { - assert(not m_streamModules.empty()); - return m_streamModules[0]->esModulesWhoseProductsAreConsumed(esModules, iPI); -} - void EDAnalyzerAdaptorBase::convertCurrentProcessAlias(std::string const& processName) { for (auto mod : m_streamModules) { mod->convertCurrentProcessAlias(processName); @@ -166,10 +149,9 @@ std::vector EDAnalyzerAdaptorBase::moduleConsumesInfos( return m_streamModules[0]->moduleConsumesInfos(); } -std::vector EDAnalyzerAdaptorBase::moduleConsumesESInfos( - eventsetup::ESRecordsToProductResolverIndices const& iPI) const { +std::vector EDAnalyzerAdaptorBase::moduleConsumesMinimalESInfos() const { assert(not m_streamModules.empty()); - return m_streamModules[0]->moduleConsumesESInfos(iPI); + return m_streamModules[0]->moduleConsumesMinimalESInfos(); } bool EDAnalyzerAdaptorBase::doEvent(EventTransitionInfo const& info, diff --git a/FWCore/Framework/src/stream/ProducingModuleAdaptorBase.cc b/FWCore/Framework/src/stream/ProducingModuleAdaptorBase.cc index 6503990a1dd37..f63b8812f1bbd 100644 --- a/FWCore/Framework/src/stream/ProducingModuleAdaptorBase.cc +++ b/FWCore/Framework/src/stream/ProducingModuleAdaptorBase.cc @@ -23,8 +23,8 @@ #include "FWCore/Framework/interface/PreallocationConfiguration.h" #include "FWCore/Framework/interface/TransitionInfoTypes.h" #include "FWCore/Framework/interface/EventForTransformer.h" +#include "FWCore/Framework/interface/ModuleConsumesMinimalESInfo.h" #include "FWCore/ServiceRegistry/interface/ESParentContext.h" -#include "FWCore/ServiceRegistry/interface/ModuleConsumesESInfo.h" #include "FWCore/ServiceRegistry/interface/ModuleConsumesInfo.h" // @@ -129,24 +129,6 @@ namespace edm { return m_streamModules[0]->esGetTokenRecordIndicesVector(iTrans); } - template - void ProducingModuleAdaptorBase::modulesWhoseProductsAreConsumed( - std::array*, NumBranchTypes>& modules, - ProductRegistry const& preg, - std::map const& labelsToDesc, - std::string const& processName) const { - assert(not m_streamModules.empty()); - return m_streamModules[0]->modulesWhoseProductsAreConsumed(modules, preg, labelsToDesc, processName); - } - - template - void ProducingModuleAdaptorBase::esModulesWhoseProductsAreConsumed( - std::array*, kNumberOfEventSetupTransitions>& esModules, - eventsetup::ESRecordsToProductResolverIndices const& iPI) const { - assert(not m_streamModules.empty()); - return m_streamModules[0]->esModulesWhoseProductsAreConsumed(esModules, iPI); - } - template void ProducingModuleAdaptorBase::convertCurrentProcessAlias(std::string const& processName) { for (auto mod : m_streamModules) { @@ -161,10 +143,9 @@ namespace edm { } template - std::vector ProducingModuleAdaptorBase::moduleConsumesESInfos( - eventsetup::ESRecordsToProductResolverIndices const& iPI) const { + std::vector ProducingModuleAdaptorBase::moduleConsumesMinimalESInfos() const { assert(not m_streamModules.empty()); - return m_streamModules[0]->moduleConsumesESInfos(iPI); + return m_streamModules[0]->moduleConsumesMinimalESInfos(); } template diff --git a/FWCore/Framework/test/DummyESProductResolverProvider.h b/FWCore/Framework/test/DummyESProductResolverProvider.h index 7ccb613f58ada..31952cb725086 100644 --- a/FWCore/Framework/test/DummyESProductResolverProvider.h +++ b/FWCore/Framework/test/DummyESProductResolverProvider.h @@ -27,6 +27,7 @@ #include "FWCore/Framework/interface/ESProductResolverTemplate.h" #include "FWCore/Framework/interface/ESProductResolverProvider.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" // forward declarations namespace edm::eventsetup::test { @@ -48,6 +49,15 @@ namespace edm::eventsetup::test { void incrementData() { ++dummy_.value_; } + std::vector producesInfo() const override { + return std::vector( + 1, + eventsetup::ESModuleProducesInfo( + edm::eventsetup::EventSetupRecordKey::makeKey(), + edm::eventsetup::DataKey(edm::eventsetup::DataKey::makeTypeTag(), ""), + 0)); + } + protected: KeyedResolversVector registerResolvers(const EventSetupRecordKey&, unsigned int /* iovIndex */) override { KeyedResolversVector keyedResolversVector; diff --git a/FWCore/Framework/test/ESProductResolverFactoryTemplate.h b/FWCore/Framework/test/ESProductResolverFactoryTemplate.h index ae461d69c251a..553e3a3965c1e 100644 --- a/FWCore/Framework/test/ESProductResolverFactoryTemplate.h +++ b/FWCore/Framework/test/ESProductResolverFactoryTemplate.h @@ -46,6 +46,7 @@ namespace edm { DataKey makeKey(const std::string& iName) const override { return DataKey(DataKey::makeTypeTag(), iName.c_str()); } + unsigned int produceMethodID() const override { return 0; } }; } // namespace eventsetup } // namespace edm diff --git a/FWCore/Framework/test/dependentrecord_t.cppunit.cc b/FWCore/Framework/test/dependentrecord_t.cppunit.cc index 4c28d038b5528..bfd2f4699aca0 100644 --- a/FWCore/Framework/test/dependentrecord_t.cppunit.cc +++ b/FWCore/Framework/test/dependentrecord_t.cppunit.cc @@ -27,6 +27,7 @@ #include "FWCore/Framework/src/SynchronousEventSetupsController.h" #include "FWCore/Framework/interface/NoRecordException.h" #include "FWCore/Framework/test/print_eventsetup_record_dependencies.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h" #include "FWCore/ServiceRegistry/interface/ESParentContext.h" @@ -128,6 +129,9 @@ namespace { KeyedResolversVector registerResolvers(const EventSetupRecordKey&, unsigned int /* iovIndex */) override { return KeyedResolversVector(); } + std::vector producesInfo() const override { + return std::vector(); + } }; class DepRecordResolverProvider : public edm::eventsetup::ESProductResolverProvider { @@ -138,6 +142,9 @@ namespace { KeyedResolversVector registerResolvers(const EventSetupRecordKey&, unsigned int /* iovIndex */) override { return KeyedResolversVector(); } + std::vector producesInfo() const override { + return std::vector(); + } }; class WorkingDepRecordResolver @@ -168,6 +175,14 @@ namespace { keyedResolversVector.emplace_back(dataKey, pResolver); return keyedResolversVector; } + std::vector producesInfo() const override { + return std::vector( + 1, + edm::eventsetup::ESModuleProducesInfo( + edm::eventsetup::EventSetupRecordKey::makeKey(), + edm::eventsetup::DataKey(edm::eventsetup::DataKey::makeTypeTag(), ""), + 0)); + } private: edm::eventsetup::test::DummyData dummy_; @@ -181,6 +196,9 @@ namespace { KeyedResolversVector registerResolvers(const EventSetupRecordKey&, unsigned int /* iovIndex */) override { return KeyedResolversVector(); } + std::vector producesInfo() const override { + return std::vector(); + } }; class DepRecordFinder : public edm::EventSetupRecordIntervalFinder { diff --git a/FWCore/Framework/test/esproducer_t.cppunit.cc b/FWCore/Framework/test/esproducer_t.cppunit.cc index 69207d40666f2..34d87fbe0a2fe 100644 --- a/FWCore/Framework/test/esproducer_t.cppunit.cc +++ b/FWCore/Framework/test/esproducer_t.cppunit.cc @@ -24,8 +24,11 @@ #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/ESProducts.h" #include "FWCore/Framework/interface/ESRecordsToProductResolverIndices.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" +#include "FWCore/Framework/interface/ESModuleConsumesMinimalInfo.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h" +#include "FWCore/Utilities/interface/ESProductTag.h" #include "FWCore/Utilities/interface/do_nothing_deleter.h" #include "FWCore/Utilities/interface/Exception.h" #include "FWCore/Concurrency/interface/ThreadsController.h" @@ -99,6 +102,9 @@ class testEsproducer : public CppUnit::TestFixture { CPPUNIT_TEST(getfromOptionalTestNull); CPPUNIT_TEST(decoratorTest); CPPUNIT_TEST(dependsOnTest); + CPPUNIT_TEST(consumesTest); + CPPUNIT_TEST(mayConsumesTest); + CPPUNIT_TEST(producesTest); CPPUNIT_TEST(labelTest); CPPUNIT_TEST_EXCEPTION(failMultipleRegistration, cms::Exception); CPPUNIT_TEST(forceCacheClearTest); @@ -121,6 +127,9 @@ class testEsproducer : public CppUnit::TestFixture { void getfromOptionalTestNull(); void decoratorTest(); void dependsOnTest(); + void consumesTest(); + void mayConsumesTest(); + void producesTest(); void labelTest(); void failMultipleRegistration(); void forceCacheClearTest(); @@ -636,6 +645,113 @@ void testEsproducer::dependsOnTest() { } } +namespace { + class ConsumesProducer : public ESProducer { + public: + ConsumesProducer() { setWhatProduced(this).consumesFrom(); } + std::shared_ptr produce(const DepRecord& /*iRecord*/) { return ptr_; } + + private: + std::shared_ptr ptr_{std::make_shared(0)}; + }; + + class SetMayConsumeProducer : public ESProducer { + public: + SetMayConsumeProducer() { + auto cc = setWhatProduced(this, "produced"); + cc.setMayConsume( + token_, + [](auto& get, edm::ESTransientHandle const& handle) { + return get.nothing(); + }, + edm::ESProductTag("", "")); + extraToken_ = cc.consumes(); + } + std::unique_ptr produce(const DepRecord& iRecord) { + return std::unique_ptr(); + } + + private: + edm::ESGetToken token_; + edm::ESGetToken extraToken_; + }; + +} // namespace +void testEsproducer::consumesTest() { + ConsumesProducer prod; + + auto const& consumes = prod.esModuleConsumesMinimalInfos(); + CPPUNIT_ASSERT(consumes.size() == 1); + + auto const& consumesInfo = consumes[0]; + CPPUNIT_ASSERT(consumesInfo.recordForDataKey_ == EventSetupRecordKey::makeKey()); + CPPUNIT_ASSERT(consumesInfo.dataKey_.type() == edm::eventsetup::DataKey::makeTypeTag()); + CPPUNIT_ASSERT(consumesInfo.dataKey_.name() == ""); + CPPUNIT_ASSERT(consumesInfo.componentLabel_.empty()); + CPPUNIT_ASSERT(consumesInfo.produceMethodID_ == 0); +} + +void testEsproducer::mayConsumesTest() { + SetMayConsumeProducer prod; + + auto const& consumes = prod.esModuleConsumesMinimalInfos(); + CPPUNIT_ASSERT(consumes.size() == 3); + { + auto const& consumesInfo = consumes[0]; + CPPUNIT_ASSERT(consumesInfo.recordForDataKey_ == EventSetupRecordKey::makeKey()); + CPPUNIT_ASSERT(consumesInfo.dataKey_.type() == edm::eventsetup::DataKey::makeTypeTag()); + CPPUNIT_ASSERT(consumesInfo.dataKey_.name() == ""); + CPPUNIT_ASSERT(consumesInfo.componentLabel_.empty()); + CPPUNIT_ASSERT(consumesInfo.produceMethodID_ == 0); + } + { + auto const& consumesInfo = consumes[1]; + CPPUNIT_ASSERT(consumesInfo.recordForDataKey_ == EventSetupRecordKey::makeKey()); + CPPUNIT_ASSERT(consumesInfo.dataKey_.type() == edm::eventsetup::DataKey::makeTypeTag()); + CPPUNIT_ASSERT(consumesInfo.dataKey_.name() == "@mayConsume"); + CPPUNIT_ASSERT(consumesInfo.componentLabel_ == "@mayConsume"); + CPPUNIT_ASSERT(consumesInfo.produceMethodID_ == 0); + } + + { + auto const& consumesInfo = consumes[2]; + CPPUNIT_ASSERT(consumesInfo.recordForDataKey_ == EventSetupRecordKey::makeKey()); + CPPUNIT_ASSERT(consumesInfo.dataKey_.type() == edm::eventsetup::DataKey::makeTypeTag()); + CPPUNIT_ASSERT(consumesInfo.dataKey_.name() == ""); + CPPUNIT_ASSERT(consumesInfo.componentLabel_.empty()); + CPPUNIT_ASSERT(consumesInfo.produceMethodID_ == 0); + } +} + +void testEsproducer::producesTest() { + LabelledProducer prod; + + auto const& produces = prod.producesInfo(); + CPPUNIT_ASSERT(produces.size() == 3); + { + auto const& producesInfo = produces[0]; + + CPPUNIT_ASSERT(producesInfo.record() == EventSetupRecordKey::makeKey()); + CPPUNIT_ASSERT(producesInfo.dataKey().type() == edm::eventsetup::DataKey::makeTypeTag()); + CPPUNIT_ASSERT(producesInfo.dataKey().name() == "fi"); + CPPUNIT_ASSERT(producesInfo.produceMethodID() == 0); + } + { + auto const& producesInfo = produces[1]; + CPPUNIT_ASSERT(producesInfo.record() == EventSetupRecordKey::makeKey()); + CPPUNIT_ASSERT(producesInfo.dataKey().type() == edm::eventsetup::DataKey::makeTypeTag()); + CPPUNIT_ASSERT(producesInfo.dataKey().name() == "fum"); + CPPUNIT_ASSERT(producesInfo.produceMethodID() == 0); + } + { + auto const& producesInfo = produces[2]; + CPPUNIT_ASSERT(producesInfo.record() == EventSetupRecordKey::makeKey()); + CPPUNIT_ASSERT(producesInfo.dataKey().type() == edm::eventsetup::DataKey::makeTypeTag()); + CPPUNIT_ASSERT(producesInfo.dataKey().name() == "foo"); + CPPUNIT_ASSERT(producesInfo.produceMethodID() == 1); + } +} + void testEsproducer::failMultipleRegistration() { MultiRegisterProducer dummy; } void testEsproducer::forceCacheClearTest() { @@ -715,6 +831,18 @@ namespace { std::shared_ptr resolverDep_1_0_; std::shared_ptr resolverDep_1_1_; + std::vector producesInfo() const override { + std::vector returnValue; + returnValue.reserve(6); + returnValue.emplace_back(EventSetupRecordKey::makeKey(), dataKeyDummy_0_, 0); + returnValue.emplace_back(EventSetupRecordKey::makeKey(), dataKeyDummy2_0_, 1); + returnValue.emplace_back(EventSetupRecordKey::makeKey(), dataKeyDummy2_1_, 2); + returnValue.emplace_back(EventSetupRecordKey::makeKey(), dataKeyDummy2_2_, 3); + returnValue.emplace_back(EventSetupRecordKey::makeKey(), dataKeyDep_0_, 4); + returnValue.emplace_back(EventSetupRecordKey::makeKey(), dataKeyDep_1_, 5); + return returnValue; + } + private: KeyedResolversVector registerResolvers(const EventSetupRecordKey& recordKey, unsigned int iovIndex) override { KeyedResolversVector keyedResolversVector; diff --git a/FWCore/Framework/test/eventsetuprecord_t.cppunit.cc b/FWCore/Framework/test/eventsetuprecord_t.cppunit.cc index d0c3bab1bad49..3574d07fe2ab5 100644 --- a/FWCore/Framework/test/eventsetuprecord_t.cppunit.cc +++ b/FWCore/Framework/test/eventsetuprecord_t.cppunit.cc @@ -25,6 +25,7 @@ #include "FWCore/Framework/interface/ESProductResolverTemplate.h" #include "FWCore/Framework/interface/ESProductResolverProvider.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/ESValidHandle.h" @@ -156,6 +157,12 @@ class WorkingDummyProvider : public edm::eventsetup::ESProductResolverProvider { usingRecord(); } + std::vector producesInfo() const override { + return std::vector( + 1, + edm::eventsetup::ESModuleProducesInfo(edm::eventsetup::EventSetupRecordKey::makeKey(), m_key, 0)); + } + protected: KeyedResolversVector registerResolvers(const EventSetupRecordKey&, unsigned int /* iovIndex */) override { KeyedResolversVector keyedResolversVector; @@ -247,8 +254,7 @@ namespace { } ESRecordsToProductResolverIndices resolverIndices({iKey}); - std::vector dataKeys; - dummyRecordImpl.fillRegisteredDataKeys(dataKeys); + std::vector const& dataKeys = dummyRecordImpl.registeredDataKeys(); (void)resolverIndices.dataKeysInRecord(0, iKey, @@ -555,8 +561,7 @@ void testEventsetupRecord::introspectionTest() { const DataKey dummyDataKey(DataKey::makeTypeTag(), ""); - std::vector keys; - dummyRecordImpl.fillRegisteredDataKeys(keys); + std::vector keys = dummyRecordImpl.registeredDataKeys(); CPPUNIT_ASSERT(keys.empty()); DummyRecord dummyRecord; @@ -567,8 +572,7 @@ void testEventsetupRecord::introspectionTest() { dummyRecordImpl.getESProducers(esproducers); CPPUNIT_ASSERT(esproducers.empty()); - std::vector referencedDataKeys; - dummyRecordImpl.fillRegisteredDataKeys(referencedDataKeys); + std::vector referencedDataKeys = dummyRecordImpl.registeredDataKeys(); auto referencedComponents = dummyRecordImpl.componentsForRegisteredDataKeys(); CPPUNIT_ASSERT(referencedDataKeys.empty()); CPPUNIT_ASSERT(referencedComponents.empty()); @@ -582,7 +586,7 @@ void testEventsetupRecord::introspectionTest() { CPPUNIT_ASSERT(esproducers.size() == 1); CPPUNIT_ASSERT(esproducers[0] == &cd1); - dummyRecordImpl.fillRegisteredDataKeys(referencedDataKeys); + referencedDataKeys = dummyRecordImpl.registeredDataKeys(); referencedComponents = dummyRecordImpl.componentsForRegisteredDataKeys(); CPPUNIT_ASSERT(referencedDataKeys.size() == 1); CPPUNIT_ASSERT(referencedComponents.size() == 1); @@ -609,7 +613,7 @@ void testEventsetupRecord::introspectionTest() { dummyRecordImpl.getESProducers(esproducers); CPPUNIT_ASSERT(esproducers.size() == 1); - dummyRecordImpl.fillRegisteredDataKeys(referencedDataKeys); + referencedDataKeys = dummyRecordImpl.registeredDataKeys(); referencedComponents = dummyRecordImpl.componentsForRegisteredDataKeys(); CPPUNIT_ASSERT(referencedDataKeys.size() == 2); CPPUNIT_ASSERT(referencedComponents.size() == 2); @@ -632,7 +636,7 @@ void testEventsetupRecord::introspectionTest() { dummyRecordImpl.getESProducers(esproducers); CPPUNIT_ASSERT(esproducers.size() == 1); - dummyRecordImpl.fillRegisteredDataKeys(referencedDataKeys); + referencedDataKeys = dummyRecordImpl.registeredDataKeys(); referencedComponents = dummyRecordImpl.componentsForRegisteredDataKeys(); CPPUNIT_ASSERT(referencedDataKeys.size() == 3); CPPUNIT_ASSERT(referencedComponents.size() == 3); @@ -656,7 +660,7 @@ void testEventsetupRecord::introspectionTest() { CPPUNIT_ASSERT(esproducers.size() == 2); CPPUNIT_ASSERT(esproducers[1] == &cd4); - dummyRecordImpl.fillRegisteredDataKeys(referencedDataKeys); + referencedDataKeys = dummyRecordImpl.registeredDataKeys(); referencedComponents = dummyRecordImpl.componentsForRegisteredDataKeys(); CPPUNIT_ASSERT(referencedDataKeys.size() == 4); CPPUNIT_ASSERT(referencedComponents.size() == 4); diff --git a/FWCore/Integration/plugins/ESTestProducers.cc b/FWCore/Integration/plugins/ESTestProducers.cc index 25d0d498267e5..9993b47aa4d0c 100644 --- a/FWCore/Integration/plugins/ESTestProducers.cc +++ b/FWCore/Integration/plugins/ESTestProducers.cc @@ -3,6 +3,7 @@ #include "FWCore/Framework/interface/ESProductResolverTemplate.h" #include "FWCore/Framework/interface/ESProducer.h" #include "FWCore/Framework/interface/ESProductHost.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" @@ -107,6 +108,8 @@ namespace edmtest { static void fillDescriptions(edm::ConfigurationDescriptions&); + std::vector producesInfo() const override; + private: KeyedResolversVector registerResolvers(const edm::eventsetup::EventSetupRecordKey&, unsigned int iovIndex) override; @@ -136,6 +139,14 @@ namespace edmtest { keyedResolversVector.emplace_back(dataKey, resolvers_[iovIndex]); return keyedResolversVector; } + + std::vector ESTestESProductResolverProviderJ::producesInfo() const { + std::vector producesInfo; + producesInfo.emplace_back(edm::eventsetup::EventSetupRecordKey::makeKey(), + edm::eventsetup::DataKey(edm::eventsetup::DataKey::makeTypeTag(), ""), + 0); + return producesInfo; + } } // namespace edmtest namespace edm::test { diff --git a/FWCore/Integration/plugins/TestESConcurrentSource.cc b/FWCore/Integration/plugins/TestESConcurrentSource.cc index 0d4dd07193d79..406354673bf40 100644 --- a/FWCore/Integration/plugins/TestESConcurrentSource.cc +++ b/FWCore/Integration/plugins/TestESConcurrentSource.cc @@ -20,6 +20,7 @@ #include "FWCore/Framework/interface/IOVSyncValue.h" #include "FWCore/Framework/interface/SourceFactory.h" #include "FWCore/Framework/interface/ValidityInterval.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" #include "FWCore/Integration/interface/ESTestRecords.h" #include "FWCore/Integration/interface/IOVTestInfo.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -75,6 +76,8 @@ namespace edmtest { std::atomic count_setIntervalFor_; std::atomic count_initializeForNewIOV_; + std::vector producesInfo() const override; + private: bool isConcurrentFinder() const override { return true; } void setIntervalFor(EventSetupRecordKey const&, edm::IOVSyncValue const&, edm::ValidityInterval&) override; @@ -195,6 +198,17 @@ namespace edmtest { --count_; } + std::vector TestESConcurrentSource::producesInfo() const { + std::vector producesInfo; + producesInfo.emplace_back(ESTestRecordI::keyForClass(), + edm::eventsetup::DataKey(edm::eventsetup::DataKey::makeTypeTag(), ""), + 0); + producesInfo.emplace_back(ESTestRecordI::keyForClass(), + edm::eventsetup::DataKey(edm::eventsetup::DataKey::makeTypeTag(), "other"), + 1); + return producesInfo; + } + edm::eventsetup::ESProductResolverProvider::KeyedResolversVector TestESConcurrentSource::registerResolvers( EventSetupRecordKey const&, unsigned int iovIndex) { if (expectedNumberOfConcurrentIOVs_ != 0 && nConcurrentIOVs_ != expectedNumberOfConcurrentIOVs_) { diff --git a/FWCore/Integration/plugins/TestESSource.cc b/FWCore/Integration/plugins/TestESSource.cc index bacf09312cad0..d13eb8f981dc3 100644 --- a/FWCore/Integration/plugins/TestESSource.cc +++ b/FWCore/Integration/plugins/TestESSource.cc @@ -20,6 +20,7 @@ #include "FWCore/Framework/interface/IOVSyncValue.h" #include "FWCore/Framework/interface/SourceFactory.h" #include "FWCore/Framework/interface/ValidityInterval.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" #include "FWCore/Integration/interface/ESTestRecords.h" #include "FWCore/Integration/interface/IOVTestInfo.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -69,6 +70,8 @@ namespace edmtest { edm::SerialTaskQueue queue_; std::mutex mutex_; + std::vector producesInfo() const override; + private: bool isConcurrentFinder() const override { return true; } void setIntervalFor(EventSetupRecordKey const&, edm::IOVSyncValue const&, edm::ValidityInterval&) override; @@ -195,6 +198,14 @@ namespace edmtest { --count_; } + std::vector TestESSource::producesInfo() const { + std::vector producesInfo; + producesInfo.emplace_back(ESTestRecordI::keyForClass(), + edm::eventsetup::DataKey(edm::eventsetup::DataKey::makeTypeTag(), ""), + 0); + return producesInfo; + } + edm::eventsetup::ESProductResolverProvider::KeyedResolversVector TestESSource::registerResolvers( EventSetupRecordKey const&, unsigned int iovIndex) { if (expectedNumberOfConcurrentIOVs_ != 0 && nConcurrentIOVs_ != expectedNumberOfConcurrentIOVs_) { diff --git a/FWCore/Services/plugins/tracer_setupFile.cc b/FWCore/Services/plugins/tracer_setupFile.cc index 0de45ec6a4e5e..e80844881f907 100644 --- a/FWCore/Services/plugins/tracer_setupFile.cc +++ b/FWCore/Services/plugins/tracer_setupFile.cc @@ -25,8 +25,8 @@ #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h" #include "FWCore/Framework/interface/IOVSyncValue.h" +#include "FWCore/Framework/interface/EventSetupRecordKey.h" #include "FWCore/Framework/interface/ESRecordsToProductResolverIndices.h" - #include "FWCore/AbstractServices/interface/TimingServiceBase.h" using namespace edm::service::monitor_file_utilities; diff --git a/FWCore/TestProcessor/interface/EventSetupTestHelper.h b/FWCore/TestProcessor/interface/EventSetupTestHelper.h index 6b7b32ec8ed46..d502af60c0904 100644 --- a/FWCore/TestProcessor/interface/EventSetupTestHelper.h +++ b/FWCore/TestProcessor/interface/EventSetupTestHelper.h @@ -41,6 +41,8 @@ namespace edm { void resetAllResolvers(); + std::vector producesInfo() const final; + protected: void setIntervalFor(const eventsetup::EventSetupRecordKey&, const IOVSyncValue&, ValidityInterval&) final; diff --git a/FWCore/TestProcessor/src/EventSetupTestHelper.cc b/FWCore/TestProcessor/src/EventSetupTestHelper.cc index 640f4e464b47b..cddfffdbf8ed4 100644 --- a/FWCore/TestProcessor/src/EventSetupTestHelper.cc +++ b/FWCore/TestProcessor/src/EventSetupTestHelper.cc @@ -15,6 +15,7 @@ // user include files #include "FWCore/TestProcessor/interface/EventSetupTestHelper.h" #include "FWCore/Framework/interface/ESProductResolver.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" namespace edm { namespace test { @@ -72,6 +73,15 @@ namespace edm { return resolvers_[iIndex].resolver_; } + std::vector EventSetupTestHelper::producesInfo() const { + std::vector producesInfo; + producesInfo.reserve(resolvers_.size()); + for (auto const& p : resolvers_) { + producesInfo.emplace_back(p.recordKey_, p.dataKey_, p.resolver_->produceMethodID()); + } + return producesInfo; + } + void EventSetupTestHelper::resetAllResolvers() { for (auto const& p : resolvers_) { p.resolver_->invalidate(); diff --git a/PhysicsTools/CondLiteIO/plugins/FWLiteESSource.cc b/PhysicsTools/CondLiteIO/plugins/FWLiteESSource.cc index 6a461273b9ed6..29a004f57f3d0 100644 --- a/PhysicsTools/CondLiteIO/plugins/FWLiteESSource.cc +++ b/PhysicsTools/CondLiteIO/plugins/FWLiteESSource.cc @@ -26,6 +26,7 @@ #include "FWCore/Framework/interface/ESProductResolverProvider.h" #include "FWCore/Framework/interface/ESSourceProductResolverNonConcurrentBase.h" #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h" +#include "FWCore/Framework/interface/ESModuleProducesInfo.h" #include "DataFormats/FWLite/interface/EventSetup.h" #include "DataFormats/FWLite/interface/Record.h" #include "FWCore/Framework/interface/HCTypeTag.h" @@ -114,6 +115,8 @@ class FWLiteESSource : public edm::eventsetup::ESProductResolverProvider, public private: KeyedResolversVector registerResolvers(const EventSetupRecordKey&, unsigned int iovIndex) override; + std::vector producesInfo() const override; + void setIntervalFor(const EventSetupRecordKey&, const edm::IOVSyncValue&, edm::ValidityInterval&) override; void delaySettingRecords() override; @@ -157,6 +160,25 @@ edm::eventsetup::ESProductResolverProvider::KeyedResolversVector FWLiteESSource: return keyedProxiesVector; } +std::vector FWLiteESSource::producesInfo() const { + std::vector returnValue; + using edm::eventsetup::heterocontainer::HCTypeTag; + + for (auto const& keyID : m_keyToID) { + auto const& rec = m_es.get(keyID.second); + for (auto const& typeLabel : rec.typeAndLabelOfAvailableData()) { + HCTypeTag tt = HCTypeTag::findType(typeLabel.first); + if (tt != HCTypeTag()) { + unsigned int index = returnValue.size(); + returnValue.emplace_back( + keyID.first, edm::eventsetup::DataKey(tt, edm::eventsetup::IdTags(typeLabel.second.c_str())), index); + } + } + } + + return returnValue; +} + void FWLiteESSource::setIntervalFor(const EventSetupRecordKey& iKey, const edm::IOVSyncValue& iSync, edm::ValidityInterval& oIOV) {