File indexing completed on 2025-04-30 22:24:06
0001
0002 #ifndef FWCore_Framework_EDConsumerBase_h
0003 #define FWCore_Framework_EDConsumerBase_h
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <array>
0023 #include <map>
0024 #include <memory>
0025 #include <string>
0026 #include <vector>
0027 #include <array>
0028 #include <cassert>
0029 #include <tuple>
0030 #include <utility>
0031
0032
0033 #include "DataFormats/Provenance/interface/ProvenanceFwd.h"
0034 #include "FWCore/Common/interface/FWCoreCommonFwd.h"
0035 #include "FWCore/Framework/interface/ProductResolverIndexAndSkipBit.h"
0036 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
0037 #include "FWCore/Framework/interface/HCTypeTag.h"
0038 #include "FWCore/Framework/interface/DataKey.h"
0039 #include "FWCore/Framework/interface/data_default_record_trait.h"
0040 #include "FWCore/Framework/interface/ModuleConsumesMinimalESInfo.h"
0041 #include "FWCore/ServiceRegistry/interface/ServiceRegistryfwd.h"
0042 #include "FWCore/ServiceRegistry/interface/ModuleConsumesInfo.h"
0043 #include "FWCore/Utilities/interface/BranchType.h"
0044 #include "FWCore/Utilities/interface/ESIndices.h"
0045 #include "FWCore/Utilities/interface/TypeID.h"
0046 #include "FWCore/Utilities/interface/TypeToGet.h"
0047 #include "FWCore/Utilities/interface/InputTag.h"
0048 #include "FWCore/Utilities/interface/EDGetToken.h"
0049 #include "FWCore/Utilities/interface/ESGetToken.h"
0050 #include "FWCore/Utilities/interface/ESGetTokenGeneric.h"
0051 #include "FWCore/Utilities/interface/ESInputTag.h"
0052 #include "FWCore/Utilities/interface/SoATuple.h"
0053 #include "FWCore/Utilities/interface/Transition.h"
0054 #include "FWCore/Utilities/interface/ProductResolverIndex.h"
0055 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0056 #include "FWCore/Utilities/interface/ProductLabels.h"
0057
0058
0059
0060 namespace edm {
0061 class ProductResolverIndexHelper;
0062 class ConsumesCollector;
0063 template <Transition Tr>
0064 class EDConsumerBaseESAdaptor;
0065 template <Transition Tr>
0066 class EDConsumerBaseWithTagESAdaptor;
0067 template <BranchType B>
0068 class EDConsumerBaseAdaptor;
0069 template <typename T>
0070 class WillGetIfMatch;
0071
0072 namespace eventsetup {
0073 struct ComponentDescription;
0074 class ESRecordsToProductResolverIndices;
0075 }
0076
0077 class EDConsumerBase {
0078 public:
0079 EDConsumerBase();
0080 virtual ~EDConsumerBase() noexcept(false);
0081
0082
0083 EDConsumerBase(EDConsumerBase const&) = delete;
0084 EDConsumerBase const& operator=(EDConsumerBase const&) = delete;
0085
0086
0087 EDConsumerBase(EDConsumerBase&&) = default;
0088 EDConsumerBase& operator=(EDConsumerBase&&) = default;
0089
0090
0091 ProductResolverIndexAndSkipBit indexFrom(EDGetToken, BranchType, TypeID const&) const;
0092 ProductResolverIndexAndSkipBit uncheckedIndexFrom(EDGetToken) const;
0093
0094 void itemsToGet(BranchType, std::vector<ProductResolverIndexAndSkipBit>&) const;
0095 void itemsMayGet(BranchType, std::vector<ProductResolverIndexAndSkipBit>&) const;
0096
0097
0098 std::vector<ProductResolverIndexAndSkipBit> const& itemsToGetFrom(BranchType iType) const {
0099 return itemsToGetFromBranch_[iType];
0100 }
0101
0102
0103 bool registeredToConsume(ProductResolverIndex, bool, BranchType) const;
0104
0105
0106
0107
0108 void updateLookup(BranchType iBranchType, ProductResolverIndexHelper const&, bool iPrefetchMayGet);
0109 void updateLookup(eventsetup::ESRecordsToProductResolverIndices const&);
0110 void releaseMemoryPostLookupSignal();
0111 void selectInputProcessBlocks(ProductRegistry const& productRegistry,
0112 ProcessBlockHelperBase const& processBlockHelperBase) {
0113 doSelectInputProcessBlocks(productRegistry, processBlockHelperBase);
0114 }
0115
0116 typedef ProductLabels Labels;
0117 void labelsForToken(EDGetToken iToken, Labels& oLabels) const;
0118
0119
0120 void convertCurrentProcessAlias(std::string const& processName);
0121
0122 std::vector<ModuleConsumesInfo> moduleConsumesInfos() const;
0123
0124
0125
0126 std::vector<ModuleConsumesMinimalESInfo> moduleConsumesMinimalESInfos() const;
0127
0128 ESResolverIndex const* esGetTokenIndices(edm::Transition iTrans) const {
0129 if (iTrans < edm::Transition::NumberOfEventSetupTransitions) {
0130 auto const& v = esItemsToGetFromTransition_[static_cast<unsigned int>(iTrans)];
0131 if (v.empty()) {
0132 return nullptr;
0133 }
0134 return &(esItemsToGetFromTransition_[static_cast<unsigned int>(iTrans)].front());
0135 }
0136 return nullptr;
0137 }
0138
0139 std::vector<ESResolverIndex> const& esGetTokenIndicesVector(edm::Transition iTrans) const {
0140 assert(iTrans < edm::Transition::NumberOfEventSetupTransitions);
0141 return esItemsToGetFromTransition_[static_cast<unsigned int>(iTrans)];
0142 }
0143
0144 std::vector<ESRecordIndex> const& esGetTokenRecordIndicesVector(edm::Transition iTrans) const {
0145 assert(iTrans < edm::Transition::NumberOfEventSetupTransitions);
0146 return esRecordsToGetFromTransition_[static_cast<unsigned int>(iTrans)];
0147 }
0148
0149 protected:
0150 friend class ConsumesCollector;
0151 template <Transition Tr>
0152 friend class EDConsumerBaseESAdaptor;
0153 template <Transition Tr>
0154 friend class EDConsumerBaseWithTagESAdaptor;
0155 template <BranchType B>
0156 friend class EDConsumerBaseAdaptor;
0157 template <typename T>
0158 friend class WillGetIfMatch;
0159
0160 ConsumesCollector consumesCollector();
0161
0162 template <typename ProductType, BranchType B = InEvent>
0163 EDGetTokenT<ProductType> consumes(edm::InputTag const& tag) {
0164 TypeToGet tid = TypeToGet::make<ProductType>();
0165 return EDGetTokenT<ProductType>{recordConsumes(B, tid, checkIfEmpty(tag), true)};
0166 }
0167
0168 template <BranchType B = InEvent>
0169 [[nodiscard]] EDConsumerBaseAdaptor<B> consumes(edm::InputTag tag) noexcept {
0170 return EDConsumerBaseAdaptor<B>(this, std::move(tag));
0171 }
0172
0173 EDGetToken consumes(const TypeToGet& id, edm::InputTag const& tag) {
0174 return EDGetToken{recordConsumes(InEvent, id, checkIfEmpty(tag), true)};
0175 }
0176
0177 template <BranchType B>
0178 EDGetToken consumes(TypeToGet const& id, edm::InputTag const& tag) {
0179 return EDGetToken{recordConsumes(B, id, checkIfEmpty(tag), true)};
0180 }
0181
0182 template <typename ProductType, BranchType B = InEvent>
0183 EDGetTokenT<ProductType> mayConsume(edm::InputTag const& tag) {
0184 TypeToGet tid = TypeToGet::make<ProductType>();
0185 return EDGetTokenT<ProductType>{recordConsumes(B, tid, checkIfEmpty(tag), false)};
0186 }
0187
0188 EDGetToken mayConsume(const TypeToGet& id, edm::InputTag const& tag) { return mayConsume<InEvent>(id, tag); }
0189
0190 template <BranchType B>
0191 EDGetToken mayConsume(const TypeToGet& id, edm::InputTag const& tag) {
0192 return EDGetToken{recordConsumes(B, id, checkIfEmpty(tag), false)};
0193 }
0194
0195
0196 template <typename ESProduct, typename ESRecord, Transition Tr = Transition::Event>
0197 auto esConsumes() {
0198 return esConsumes<ESProduct, ESRecord, Tr>(ESInputTag{});
0199 }
0200
0201 template <typename ESProduct, typename ESRecord, Transition Tr = Transition::Event>
0202 auto esConsumes(ESInputTag const& tag) {
0203 auto [index, productLabel] =
0204 recordESConsumes(Tr,
0205 eventsetup::EventSetupRecordKey::makeKey<
0206 std::conditional_t<std::is_same_v<ESRecord, edm::DefaultRecord>,
0207 eventsetup::default_record_t<ESHandleAdapter<ESProduct>>,
0208 ESRecord>>(),
0209 eventsetup::heterocontainer::HCTypeTag::make<ESProduct>(),
0210 tag);
0211 return ESGetToken<ESProduct, ESRecord>{static_cast<unsigned int>(Tr), index, productLabel};
0212 }
0213
0214 template <Transition Tr = Transition::Event>
0215 [[nodiscard]] constexpr auto esConsumes() {
0216 return EDConsumerBaseESAdaptor<Tr>(this);
0217 }
0218
0219 template <Transition Tr = Transition::Event>
0220 [[nodiscard]] auto esConsumes(ESInputTag tag) {
0221 return EDConsumerBaseWithTagESAdaptor<Tr>(this, std::move(tag));
0222 }
0223
0224
0225 template <Transition Tr = Transition::Event>
0226 ESGetTokenGeneric esConsumes(eventsetup::EventSetupRecordKey const& iRecord, eventsetup::DataKey const& iKey) {
0227 auto [index, productLabel] = recordESConsumes(Tr, iRecord, iKey.type(), ESInputTag("", iKey.name().value()));
0228 return ESGetTokenGeneric(static_cast<unsigned int>(Tr), index, iRecord.type());
0229 }
0230
0231
0232
0233
0234
0235 template <typename F>
0236 void consumedProducts(F&& iFunc) const;
0237
0238
0239
0240
0241
0242 template <typename F>
0243 void consumedESProducts(F&& iFunct) const;
0244
0245 private:
0246 virtual void extendUpdateLookup(BranchType iBranchType, ProductResolverIndexHelper const&);
0247 virtual void registerLateConsumes(eventsetup::ESRecordsToProductResolverIndices const&) {}
0248 unsigned int recordConsumes(BranchType iBranch, TypeToGet const& iType, edm::InputTag const& iTag, bool iAlwaysGets);
0249 std::tuple<ESTokenIndex, char const*> recordESConsumes(Transition,
0250 eventsetup::EventSetupRecordKey const&,
0251 eventsetup::heterocontainer::HCTypeTag const&,
0252 edm::ESInputTag const& iTag);
0253
0254 void throwTypeMismatch(edm::TypeID const&, EDGetToken) const;
0255 void throwBranchMismatch(BranchType, EDGetToken) const;
0256 void throwBadToken(edm::TypeID const& iType, EDGetToken iToken) const;
0257 void throwConsumesCallAfterFrozen(TypeToGet const&, InputTag const&) const;
0258 void throwESConsumesCallAfterFrozen(eventsetup::EventSetupRecordKey const&,
0259 eventsetup::heterocontainer::HCTypeTag const&,
0260 edm::ESInputTag const&) const;
0261 void throwESConsumesInProcessBlock() const;
0262
0263 edm::InputTag const& checkIfEmpty(edm::InputTag const& tag);
0264
0265 virtual void doSelectInputProcessBlocks(ProductRegistry const&, ProcessBlockHelperBase const&);
0266
0267 struct ESTokenLookupInfo {
0268 eventsetup::EventSetupRecordKey m_record;
0269 eventsetup::DataKey m_key;
0270 unsigned int m_startOfComponentName;
0271 };
0272
0273 enum { kESLookupInfo, kESResolverIndex };
0274
0275 using ESTokenLookupInfoContainer = edm::SoATuple<ESTokenLookupInfo, ESResolverIndex>;
0276
0277 ESTokenLookupInfoContainer const& esTokenLookupInfoContainer() const {
0278 return esDataThatCanBeDeletedEarly_->esTokenLookupInfoContainer_;
0279 }
0280
0281 using ESResolverIndexContainer = std::array<std::vector<ESResolverIndex>, kNumberOfEventSetupTransitions>;
0282
0283 using ConsumesIndexConverter =
0284 std::vector<std::pair<ESResolverIndexContainer::size_type, std::vector<ESResolverIndex>::size_type>>;
0285
0286
0287
0288 ConsumesIndexConverter const& consumesIndexConverter() const {
0289 return esDataThatCanBeDeletedEarly_->consumesIndexConverter_;
0290 }
0291
0292
0293
0294 struct TokenLookupInfo {
0295 TokenLookupInfo(edm::TypeID const& iID, ProductResolverIndex iIndex, bool skipCurrentProcess, BranchType iBranch)
0296 : m_type(iID), m_index(iIndex, skipCurrentProcess), m_branchType(iBranch) {}
0297 edm::TypeID m_type;
0298 ProductResolverIndexAndSkipBit m_index;
0299 BranchType m_branchType;
0300 };
0301
0302 struct LabelPlacement {
0303 LabelPlacement(unsigned int iStartOfModuleLabel,
0304 unsigned short iDeltaToProductInstance,
0305 unsigned short iDeltaToProcessName)
0306 : m_startOfModuleLabel(iStartOfModuleLabel),
0307 m_deltaToProductInstance(iDeltaToProductInstance),
0308 m_deltaToProcessName(iDeltaToProcessName) {}
0309 unsigned int m_startOfModuleLabel;
0310 unsigned short m_deltaToProductInstance;
0311 unsigned short m_deltaToProcessName;
0312 };
0313
0314
0315 enum { kLookupInfo, kAlwaysGets, kLabels, kKind };
0316 edm::SoATuple<TokenLookupInfo, bool, LabelPlacement, edm::KindOfType> m_tokenInfo;
0317
0318
0319
0320 std::vector<char> m_tokenLabels;
0321
0322 std::array<std::vector<ProductResolverIndexAndSkipBit>, edm::NumBranchTypes> itemsToGetFromBranch_;
0323
0324 struct ESDataThatCanBeDeletedEarly {
0325 ESTokenLookupInfoContainer esTokenLookupInfoContainer_;
0326 ConsumesIndexConverter consumesIndexConverter_;
0327 };
0328
0329 std::unique_ptr<ESDataThatCanBeDeletedEarly> esDataThatCanBeDeletedEarly_;
0330
0331 ESResolverIndexContainer esItemsToGetFromTransition_;
0332
0333 std::array<std::vector<ESRecordIndex>, kNumberOfEventSetupTransitions> esRecordsToGetFromTransition_;
0334
0335 bool frozen_;
0336 bool containsCurrentProcessAlias_;
0337 };
0338
0339 template <typename F>
0340 void EDConsumerBase::consumedProducts(F&& iFunc) const {
0341 auto itKind = m_tokenInfo.begin<kKind>();
0342 auto itLabels = m_tokenInfo.begin<kLabels>();
0343 auto itAlways = m_tokenInfo.begin<kAlwaysGets>();
0344 for (auto itInfo = m_tokenInfo.begin<kLookupInfo>(), itEnd = m_tokenInfo.end<kLookupInfo>(); itInfo != itEnd;
0345 ++itInfo, ++itKind, ++itLabels, ++itAlways) {
0346 auto labels = *itLabels;
0347 unsigned int start = labels.m_startOfModuleLabel;
0348 auto module = &(m_tokenLabels[start]);
0349 auto productInstance = module + labels.m_deltaToProductInstance;
0350 auto process = module + labels.m_deltaToProcessName;
0351
0352 iFunc(ModuleConsumesInfo(itInfo->m_type,
0353 module,
0354 productInstance,
0355 process,
0356 itInfo->m_branchType,
0357 *itKind,
0358 *itAlways,
0359 itInfo->m_index.skipCurrentProcess()));
0360 }
0361 }
0362
0363 template <typename F>
0364 void EDConsumerBase::consumedESProducts(F&& iFunc) const {
0365 unsigned int index = 0;
0366 auto itResolverIndex = esTokenLookupInfoContainer().begin<kESResolverIndex>();
0367 for (auto it = esTokenLookupInfoContainer().begin<kESLookupInfo>();
0368 it != esTokenLookupInfoContainer().end<kESLookupInfo>();
0369 ++it, ++index, ++itResolverIndex) {
0370
0371
0372 iFunc(ModuleConsumesMinimalESInfo(static_cast<Transition>(consumesIndexConverter()[index].first),
0373 it->m_record,
0374 it->m_key,
0375 &(m_tokenLabels[it->m_startOfComponentName]),
0376 *itResolverIndex));
0377 }
0378 }
0379
0380 template <Transition TR>
0381 class EDConsumerBaseESAdaptor {
0382 public:
0383 template <typename TYPE, typename REC>
0384 ESGetToken<TYPE, REC> consumes() {
0385 return m_consumer->template esConsumes<TYPE, REC, TR>();
0386 }
0387
0388 private:
0389
0390 friend class EDConsumerBase;
0391 EDConsumerBaseESAdaptor(EDConsumerBase* iBase) : m_consumer(iBase) {}
0392
0393 EDConsumerBase* m_consumer;
0394 };
0395
0396 template <Transition TR>
0397 class EDConsumerBaseWithTagESAdaptor {
0398 public:
0399 template <typename TYPE, typename REC>
0400 ESGetToken<TYPE, REC> consumes() {
0401 return m_consumer->template esConsumes<TYPE, REC, TR>(m_tag);
0402 }
0403
0404 private:
0405
0406 friend class EDConsumerBase;
0407 EDConsumerBaseWithTagESAdaptor(EDConsumerBase* iBase, ESInputTag iTag) noexcept
0408 : m_consumer(iBase), m_tag(std::move(iTag)) {}
0409
0410 EDConsumerBase* m_consumer;
0411 ESInputTag const m_tag;
0412 };
0413
0414 template <BranchType B>
0415 class EDConsumerBaseAdaptor {
0416 public:
0417 template <typename TYPE>
0418 EDGetTokenT<TYPE> consumes() {
0419 return m_consumer->template consumes<TYPE, B>(m_tag);
0420 }
0421
0422 private:
0423
0424 friend class EDConsumerBase;
0425 EDConsumerBaseAdaptor(EDConsumerBase* iBase, edm::InputTag iTag) noexcept
0426 : m_consumer(iBase), m_tag(std::move(iTag)) {}
0427
0428 EDConsumerBase* m_consumer;
0429 edm::InputTag const m_tag;
0430 };
0431
0432 }
0433
0434 #endif