Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-04-30 22:24:07

0001 // -*- C++ -*-
0002 //
0003 // Package:     Framework
0004 // Class  :     ESProducer
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Author:      Chris Jones
0010 // Created:     Sat Apr 16 10:19:37 EDT 2005
0011 //
0012 
0013 #include "FWCore/Framework/interface/ESProducer.h"
0014 #include "FWCore/Framework/interface/DataKey.h"
0015 #include "FWCore/Framework/interface/ComponentDescription.h"
0016 #include "FWCore/Framework/interface/ESRecordsToProductResolverIndices.h"
0017 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
0018 #include "FWCore/Framework/interface/SharedResourcesRegistry.h"
0019 #include "FWCore/Framework/interface/ESModuleConsumesMinimalInfo.h"
0020 #include "FWCore/ServiceRegistry/interface/ESModuleConsumesInfo.h"
0021 #include "FWCore/Utilities/interface/ESIndices.h"
0022 
0023 #include <cassert>
0024 #include <set>
0025 #include <string_view>
0026 
0027 namespace edm {
0028 
0029   ESProducer::ESProducer() : consumesInfos_{}, acquirer_{{{std::make_shared<SerialTaskQueue>()}}} {}
0030 
0031   ESProducer::~ESProducer() noexcept(false) {}
0032 
0033   void ESProducer::updateLookup(eventsetup::ESRecordsToProductResolverIndices const& iResolverToIndices) {
0034     if (sharedResourceNames_) {
0035       auto instance = SharedResourcesRegistry::instance();
0036       acquirer_ = instance->createAcquirer(*sharedResourceNames_);
0037       sharedResourceNames_.reset();
0038     }
0039 
0040     if (itemsToGetFromRecords_.size() == consumesInfos_.size()) {
0041       return;
0042     }
0043 
0044     itemsToGetFromRecords_.reserve(consumesInfos_.size());
0045     recordsUsedDuringGet_.reserve(consumesInfos_.size());
0046 
0047     for (auto& info : consumesInfos_) {
0048       auto& items = itemsToGetFromRecords_.emplace_back();
0049       items.reserve(info->size());
0050       auto& records = recordsUsedDuringGet_.emplace_back();
0051       records.reserve(info->size());
0052       for (auto& resolverInfo : *info) {
0053         //check for mayConsumes
0054         if (auto chooser = resolverInfo.chooser_.get()) {
0055           hasMayConsumes_ = true;
0056           auto tagGetter = iResolverToIndices.makeTagGetter(chooser->recordKey(), chooser->productType());
0057           if (not tagGetter.hasNothingToGet()) {
0058             records.push_back(iResolverToIndices.recordIndexFor(chooser->recordKey()));
0059           } else {
0060             //The record is not actually missing but the resolver is
0061             records.emplace_back(eventsetup::ESRecordsToProductResolverIndices::missingRecordIndex());
0062           }
0063           chooser->setTagGetter(std::move(tagGetter));
0064           // This value will get overwritten before being used
0065           items.push_back(ESResolverIndex::noResolverConfigured());
0066         } else {
0067           auto index = iResolverToIndices.indexInRecord(resolverInfo.recordKey_, resolverInfo.productKey_);
0068           if (index != ESResolverIndex::noResolverConfigured()) {
0069             if (not resolverInfo.moduleLabel_.empty()) {
0070               auto component = iResolverToIndices.component(resolverInfo.recordKey_, resolverInfo.productKey_);
0071               if (nullptr == component) {
0072                 index = ESResolverIndex::moduleLabelDoesNotMatch();
0073               } else {
0074                 if (component->label_.empty()) {
0075                   if (component->type_ != resolverInfo.moduleLabel_) {
0076                     index = ESResolverIndex::moduleLabelDoesNotMatch();
0077                   }
0078                 } else if (component->label_ != resolverInfo.moduleLabel_) {
0079                   index = ESResolverIndex::moduleLabelDoesNotMatch();
0080                 }
0081               }
0082             }
0083           }
0084           items.push_back(index);
0085           if (index != ESResolverIndex::noResolverConfigured() && index != ESResolverIndex::moduleLabelDoesNotMatch()) {
0086             records.push_back(iResolverToIndices.recordIndexFor(resolverInfo.recordKey_));
0087           } else {
0088             //The record is not actually missing but the resolver is
0089             records.emplace_back(eventsetup::ESRecordsToProductResolverIndices::missingRecordIndex());
0090           }
0091           assert(items.size() == records.size());
0092         }
0093       }
0094     }
0095   }
0096 
0097   std::vector<eventsetup::ESModuleConsumesMinimalInfo> ESProducer::esModuleConsumesMinimalInfos() const {
0098     std::vector<eventsetup::ESModuleConsumesMinimalInfo> result;
0099     size_t totalSize = 0;
0100     for (auto const& esConsumesInfo : consumesInfos_) {
0101       totalSize += esConsumesInfo->size();
0102     }
0103     result.reserve(totalSize);
0104     for (unsigned int index = 0; auto const& esConsumesInfo : consumesInfos_) {
0105       for (auto const& esConsumesInfoEntry : *esConsumesInfo) {
0106         result.emplace_back(
0107             index, esConsumesInfoEntry.recordKey_, esConsumesInfoEntry.productKey_, esConsumesInfoEntry.moduleLabel_);
0108       }
0109       ++index;
0110     }
0111     return result;
0112   }
0113 
0114   std::vector<std::vector<ESModuleConsumesInfo>> ESProducer::esModuleConsumesInfos(
0115       eventsetup::ESRecordsToProductResolverIndices const& iPI) const {
0116     std::vector<std::vector<ESModuleConsumesInfo>> result;
0117     result.resize(consumesInfos_.size());
0118 
0119     ESModuleConsumesInfo info;
0120 
0121     auto resultForTransition = result.begin();
0122     auto resolversForTransition = itemsToGetFromRecords_.begin();
0123     for (auto const& esConsumesInfo : consumesInfos_) {
0124       auto itResolver = resolversForTransition->begin();
0125       for (auto const& esConsumesInfoEntry : *esConsumesInfo) {
0126         info.eventSetupRecordType_ = esConsumesInfoEntry.recordKey_.name();
0127         info.productType_ = esConsumesInfoEntry.productKey_.type().name();
0128         info.moduleType_ = {};
0129         info.moduleLabel_ = {};
0130         info.produceMethodIDOfProducer_ = 0;
0131         info.isSource_ = false;
0132         info.isLooper_ = false;
0133         info.moduleLabelMismatch_ = false;
0134 
0135         // If there is a chooser this is the special case of a "may consumes"
0136         if (esConsumesInfoEntry.chooser_) {
0137           info.requestedModuleLabel_ = {};
0138           info.mayConsumes_ = true;
0139           info.mayConsumesFirstEntry_ = true;
0140 
0141           auto const& esTagGetterInfos = esConsumesInfoEntry.chooser_->tagGetter().lookup();
0142 
0143           if (esTagGetterInfos.empty()) {
0144             info.productLabel_ = {};
0145             info.mayConsumesNoProducts_ = true;
0146             resultForTransition->push_back(info);
0147           }
0148 
0149           // In the "may consumes" case, we iterate over all the possible data products
0150           // the EventSetup can produce with matching record type and product type.
0151           // With the current design of the mayConsumes feature, there is no way to
0152           // know in advance which productLabel or moduleLabel will be requested.
0153           // Maybe none will be. requestedModuleLabel and moduleLabelMismatch
0154           // are meaningless for "may consumes" cases.
0155           for (auto const& esTagGetterInfo : esTagGetterInfos) {
0156             info.productLabel_ = esTagGetterInfo.productLabel_;
0157             info.moduleLabel_ = esTagGetterInfo.moduleLabel_;
0158             info.mayConsumesNoProducts_ = false;
0159 
0160             auto [componentDescription, produceMethodID] =
0161                 iPI.componentAndProduceMethodID(esConsumesInfoEntry.recordKey_, esTagGetterInfo.index_);
0162             assert(componentDescription);
0163             info.moduleType_ = componentDescription->type_;
0164             assert(info.moduleLabel_ ==
0165                    (componentDescription->label_.empty() ? componentDescription->type_ : componentDescription->label_));
0166 
0167             info.produceMethodIDOfProducer_ = produceMethodID;
0168             info.isSource_ = componentDescription->isSource_;
0169             info.isLooper_ = componentDescription->isLooper_;
0170 
0171             resultForTransition->push_back(info);
0172 
0173             info.mayConsumesFirstEntry_ = false;
0174           }
0175 
0176           // Handle cases not involving "may consumes"
0177         } else {
0178           info.productLabel_ = esConsumesInfoEntry.productKey_.name().value();
0179           info.requestedModuleLabel_ = esConsumesInfoEntry.moduleLabel_;
0180           info.moduleLabelMismatch_ = *itResolver == ESResolverIndex::moduleLabelDoesNotMatch();
0181           info.mayConsumes_ = false;
0182           info.mayConsumesFirstEntry_ = false;
0183           info.mayConsumesNoProducts_ = false;
0184 
0185           auto [componentDescription, produceMethodID] =
0186               iPI.componentAndProduceMethodID(esConsumesInfoEntry.recordKey_, *itResolver);
0187 
0188           if (componentDescription) {
0189             info.moduleType_ = componentDescription->type_;
0190             info.moduleLabel_ =
0191                 componentDescription->label_.empty() ? componentDescription->type_ : componentDescription->label_;
0192             info.produceMethodIDOfProducer_ = produceMethodID;
0193             info.isSource_ = componentDescription->isSource_;
0194             info.isLooper_ = componentDescription->isLooper_;
0195           }
0196           resultForTransition->push_back(info);
0197         }
0198         ++itResolver;
0199       }
0200       ++resolversForTransition;
0201       ++resultForTransition;
0202       ++info.produceMethodIDOfConsumer_;
0203     }
0204     return result;
0205   }
0206 
0207   void ESProducer::usesResources(std::vector<std::string> const& iResourceNames) {
0208     auto instance = SharedResourcesRegistry::instance();
0209     if (not sharedResourceNames_ and !iResourceNames.empty()) {
0210       sharedResourceNames_ = std::make_unique<std::vector<std::string>>(iResourceNames);
0211     }
0212 
0213     for (auto const& r : iResourceNames) {
0214       instance->registerSharedResource(r);
0215     }
0216     //Must defer setting acquirer_ until all resources have been registered
0217     // by all modules in the job
0218   }
0219 
0220 }  // namespace edm