Skip to content

Refactor PathsAndConsumesOfModules #47937

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions CondCore/CondHDF5ESSource/plugins/CondHDF5ESSource.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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<edm::eventsetup::ESModuleProducesInfo> producesInfo() const final;

edm::SerialTaskQueue queue_;
std::mutex mutex_;
Expand Down Expand Up @@ -236,4 +238,25 @@ CondHDF5ESSource::KeyedResolversVector CondHDF5ESSource::registerResolvers(Event
return returnValue;
}

std::vector<edm::eventsetup::ESModuleProducesInfo> CondHDF5ESSource::producesInfo() const {
std::vector<edm::eventsetup::ESModuleProducesInfo> returnValue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would returnValue.reserve() be worth it? E.g. with records_.size()? (unlikely to be exact, but maybe would avoid a number of small reallocations)

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);
18 changes: 18 additions & 0 deletions CondCore/ESSources/plugins/CondDBESSource.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -648,6 +649,23 @@ edm::eventsetup::ESProductResolverProvider::KeyedResolversVector CondDBESSource:
return keyedResolversVector;
}

std::vector<edm::eventsetup::ESModuleProducesInfo> CondDBESSource::producesInfo() const {
std::vector<edm::eventsetup::ESModuleProducesInfo> returnValue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about

  returnValue.reserve(m_resolvers.size());

?

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);
Expand Down
2 changes: 2 additions & 0 deletions CondCore/ESSources/plugins/CondDBESSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ class CondDBESSource : public edm::eventsetup::ESProductResolverProvider, public

KeyedResolversVector registerResolvers(const EventSetupRecordKey&, unsigned int iovIndex) override;

std::vector<edm::eventsetup::ESModuleProducesInfo> producesInfo() const override;

void initConcurrentIOVs(const EventSetupRecordKey& key, unsigned int nConcurrentIOVs) override;

bool isConcurrentFinder() const override { return true; }
Expand Down
69 changes: 59 additions & 10 deletions FWCore/Framework/interface/EDConsumerBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -114,20 +116,12 @@ namespace edm {
typedef ProductLabels Labels;
void labelsForToken(EDGetToken iToken, Labels& oLabels) const;

void modulesWhoseProductsAreConsumed(std::array<std::vector<ModuleDescription const*>*, NumBranchTypes>& modulesAll,
ProductRegistry const& preg,
std::map<std::string, ModuleDescription const*> const& labelsToDesc,
std::string const& processName) const;

void esModulesWhoseProductsAreConsumed(
std::array<std::vector<eventsetup::ComponentDescription const*>*, 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<ModuleConsumesInfo> moduleConsumesInfos() const;
std::vector<ModuleConsumesESInfo> moduleConsumesESInfos(eventsetup::ESRecordsToProductResolverIndices const&) const;
///This can only be called before the end of beginJob (after that the underlying data has been deleted)
std::vector<ModuleConsumesMinimalESInfo> moduleConsumesMinimalESInfos() const;
Comment on lines +123 to +124
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment here if the returned ModuleConsumesMinimalESInfo can be used beyond the end of beginJob would be helpful (given that ModuleConsumesMinimalESInfo holds string_view).


ESResolverIndex const* esGetTokenIndices(edm::Transition iTrans) const {
if (iTrans < edm::Transition::NumberOfEventSetupTransitions) {
Expand Down Expand Up @@ -232,6 +226,20 @@ namespace edm {
return ESGetTokenGeneric(static_cast<unsigned int>(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 <typename F>
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 <typename F>
void consumedESProducts(F&& iFunct) const;

private:
virtual void extendUpdateLookup(BranchType iBranchType, ProductResolverIndexHelper const&);
virtual void registerLateConsumes(eventsetup::ESRecordsToProductResolverIndices const&) {}
Expand Down Expand Up @@ -326,6 +334,47 @@ namespace edm {
bool containsCurrentProcessAlias_;
};

template <typename F>
void EDConsumerBase::consumedProducts(F&& iFunc) const {
auto itKind = m_tokenInfo.begin<kKind>();
auto itLabels = m_tokenInfo.begin<kLabels>();
auto itAlways = m_tokenInfo.begin<kAlwaysGets>();
for (auto itInfo = m_tokenInfo.begin<kLookupInfo>(), itEnd = m_tokenInfo.end<kLookupInfo>(); 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 <typename F>
void EDConsumerBase::consumedESProducts(F&& iFunc) const {
unsigned int index = 0;
auto itResolverIndex = esTokenLookupInfoContainer().begin<kESResolverIndex>();
for (auto it = esTokenLookupInfoContainer().begin<kESLookupInfo>();
it != esTokenLookupInfoContainer().end<kESLookupInfo>();
++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<Transition>(consumesIndexConverter()[index].first),
it->m_record,
it->m_key,
&(m_tokenLabels[it->m_startOfComponentName]),
*itResolverIndex));
}
}

template <Transition TR>
class EDConsumerBaseESAdaptor {
public:
Expand Down
38 changes: 38 additions & 0 deletions FWCore/Framework/interface/ESModuleConsumesMinimalInfo.h
Original file line number Diff line number Diff line change
@@ -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 <string_view>

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
29 changes: 29 additions & 0 deletions FWCore/Framework/interface/ESModuleProducesInfo.h
Original file line number Diff line number Diff line change
@@ -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
9 changes: 6 additions & 3 deletions FWCore/Framework/interface/ESProducer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -158,12 +159,14 @@ namespace edm {

SerialTaskQueueChain& queue() { return acquirer_.serialQueueChain(); }

void esModulesWhoseProductsAreConsumed(std::vector<eventsetup::ComponentDescription const*>& esModules,
eventsetup::ESRecordsToProductResolverIndices const&) const;

std::vector<std::vector<ESModuleConsumesInfo>> esModuleConsumesInfos(
eventsetup::ESRecordsToProductResolverIndices const&) const;

/** Returns a vector of ESModuleConsumesMinimalInfo.
Each entry contains minimal information about the products that a method consumes.
*/
std::vector<eventsetup::ESModuleConsumesMinimalInfo> esModuleConsumesMinimalInfos() const;

protected:
/** Specify the names of the shared resources used by this ESProducer */
void usesResources(std::vector<std::string> const&);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ namespace edm {
return DataKey(DataKey::makeTypeTag<typename ResolverType::ValueType>(), iName.c_str());
}

unsigned int produceMethodID() const override { return callback_->second->produceMethodID(); }

private:
std::shared_ptr<std::pair<unsigned int, std::shared_ptr<CallbackType>>> callback_;
};
Expand Down
2 changes: 2 additions & 0 deletions FWCore/Framework/interface/ESProductResolverFactoryBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ namespace edm {
virtual std::unique_ptr<ESProductResolver> makeResolver(unsigned int iovIndex) = 0;

virtual DataKey makeKey(const std::string& iName) const = 0;

virtual unsigned int produceMethodID() const = 0;
};
} // namespace eventsetup
} // namespace edm
Expand Down
2 changes: 2 additions & 0 deletions FWCore/Framework/interface/ESProductResolverFactoryProducer.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ namespace edm {

~ESProductResolverFactoryProducer() noexcept(false) override;

std::vector<eventsetup::ESModuleProducesInfo> producesInfo() const override;

protected:
using EventSetupRecordKey = eventsetup::EventSetupRecordKey;

Expand Down
5 changes: 5 additions & 0 deletions FWCore/Framework/interface/ESProductResolverProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ namespace edm {
namespace eventsetup {
class ESProductResolver;
class ESRecordsToProductResolverIndices;
class ESModuleProducesInfo;

class ESProductResolverProvider {
public:
Expand Down Expand Up @@ -161,6 +162,10 @@ namespace edm {
void fillRecordsNotAllowingConcurrentIOVs(std::set<EventSetupRecordKey>& 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<ESModuleProducesInfo> producesInfo() const = 0;

virtual void initConcurrentIOVs(EventSetupRecordKey const& key, unsigned int nConcurrentIOVs) {}

Expand Down
4 changes: 3 additions & 1 deletion FWCore/Framework/interface/ESTagGetter.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
Description: Used with mayConsume option of ESConsumesCollector

Usage:
<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.

*/
//
Expand Down
1 change: 1 addition & 0 deletions FWCore/Framework/interface/EventSetupProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ namespace edm {
void fillKeys(std::set<EventSetupRecordKey>& keys) const;

EventSetupRecordProvider* tryToGetRecordProvider(const EventSetupRecordKey& iKey);
EventSetupRecordProvider const* tryToGetRecordProvider(const EventSetupRecordKey& iKey) const;

void fillAllESProductResolverProviders(std::vector<ESProductResolverProvider const*>&) const;

Expand Down
2 changes: 1 addition & 1 deletion FWCore/Framework/interface/EventSetupRecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<DataKey>& oToFill) const { impl_->fillRegisteredDataKeys(oToFill); }
void fillRegisteredDataKeys(std::vector<DataKey>& oToFill) const { oToFill = impl_->registeredDataKeys(); }

///Classes that derive from EventSetupRecord can redefine this with a false value
static constexpr bool allowConcurrentIOVs_ = true;
Expand Down
4 changes: 2 additions & 2 deletions FWCore/Framework/interface/EventSetupRecordImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<DataKey>& oToFill) const;
///keys for all registered data keys
std::vector<DataKey> const& registeredDataKeys() const;
///there is a 1-to-1 correspondence between elements returned and the elements returned from fillRegisteredDataKey.
std::vector<ComponentDescription const*> componentsForRegisteredDataKeys() const;

Expand Down
2 changes: 1 addition & 1 deletion FWCore/Framework/interface/EventSetupRecordProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ namespace edm {
std::set<ComponentDescription> resolverProviderDescriptions() const;

/// The available DataKeys in the Record. The order can be used to request the data by index
std::vector<DataKey> registeredDataKeys() const;
std::vector<DataKey> const& registeredDataKeys() const;

std::vector<ComponentDescription const*> componentsForRegisteredDataKeys() const;
std::vector<unsigned int> produceMethodIDsForRegisteredDataKeys() const;
Expand Down
Loading