File indexing completed on 2024-12-10 23:21:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include "FWCore/Framework/interface/EventSetupsController.h"
0014
0015 #include "FWCore/Concurrency/interface/SerialTaskQueue.h"
0016 #include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
0017 #include "FWCore/Concurrency/interface/WaitingTaskList.h"
0018 #include "FWCore/Concurrency/interface/FinalWaitingTask.h"
0019 #include "FWCore/Framework/interface/DataKey.h"
0020 #include "FWCore/Framework/interface/ESProductResolver.h"
0021 #include "FWCore/Framework/src/EventSetupProviderMaker.h"
0022 #include "FWCore/Framework/interface/EventSetupProvider.h"
0023 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
0024 #include "FWCore/Framework/interface/IOVSyncValue.h"
0025 #include "FWCore/Framework/interface/ParameterSetIDHolder.h"
0026 #include "FWCore/Framework/src/SendSourceTerminationSignalIfException.h"
0027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0028 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
0029 #include "FWCore/ServiceRegistry/interface/ServiceToken.h"
0030 #include "FWCore/Utilities/interface/EDMException.h"
0031 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0032
0033 #include <algorithm>
0034 #include <exception>
0035 #include <iostream>
0036 #include <set>
0037
0038 namespace edm {
0039 namespace eventsetup {
0040
0041 EventSetupsController::EventSetupsController() {}
0042 EventSetupsController::EventSetupsController(ModuleTypeResolverMaker const* resolverMaker)
0043 : typeResolverMaker_(resolverMaker) {}
0044
0045 void EventSetupsController::endIOVsAsync(edm::WaitingTaskHolder iEndTask) {
0046 for (auto& eventSetupRecordIOVQueue : eventSetupRecordIOVQueues_) {
0047 eventSetupRecordIOVQueue->endIOVAsync(iEndTask);
0048 }
0049 }
0050
0051 std::shared_ptr<EventSetupProvider> EventSetupsController::makeProvider(ParameterSet& iPSet,
0052 ActivityRegistry* activityRegistry,
0053 ParameterSet const* eventSetupPset,
0054 unsigned int maxConcurrentIOVs,
0055 bool dumpOptions) {
0056
0057
0058
0059 std::shared_ptr<EventSetupProvider> returnValue(
0060 makeEventSetupProvider(iPSet, providers_.size(), activityRegistry));
0061
0062
0063
0064
0065 fillEventSetupProvider(typeResolverMaker_, *this, *returnValue, iPSet);
0066
0067 numberOfConcurrentIOVs_.readConfigurationParameters(eventSetupPset, maxConcurrentIOVs, dumpOptions);
0068
0069 providers_.push_back(returnValue);
0070 return returnValue;
0071 }
0072
0073 void EventSetupsController::finishConfiguration() {
0074 if (mustFinishConfiguration_) {
0075 for (auto& eventSetupProvider : providers_) {
0076 numberOfConcurrentIOVs_.fillRecordsNotAllowingConcurrentIOVs(*eventSetupProvider);
0077 }
0078
0079 for (auto& eventSetupProvider : providers_) {
0080 eventSetupProvider->finishConfiguration(numberOfConcurrentIOVs_, hasNonconcurrentFinder_);
0081 }
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 checkESProducerSharing();
0093 clearComponents();
0094
0095
0096
0097 for (auto& eventSetupProvider : providers_) {
0098 eventSetupProvider->updateLookup();
0099 }
0100
0101 initializeEventSetupRecordIOVQueues();
0102 numberOfConcurrentIOVs_.clear();
0103 mustFinishConfiguration_ = false;
0104 }
0105 }
0106
0107 void EventSetupsController::runOrQueueEventSetupForInstanceAsync(
0108 IOVSyncValue const& iSync,
0109 WaitingTaskHolder& taskToStartAfterIOVInit,
0110 WaitingTaskList& endIOVWaitingTasks,
0111 std::vector<std::shared_ptr<const EventSetupImpl>>& eventSetupImpls,
0112 edm::SerialTaskQueue& queueWhichWaitsForIOVsToFinish,
0113 ActivityRegistry* actReg,
0114 ServiceToken const& iToken,
0115 bool iForceCacheClear) {
0116 auto asyncEventSetup =
0117 [this, &endIOVWaitingTasks, &eventSetupImpls, &queueWhichWaitsForIOVsToFinish, actReg, iForceCacheClear](
0118 IOVSyncValue const& iSync, WaitingTaskHolder& task) {
0119 queueWhichWaitsForIOVsToFinish.pause();
0120 CMS_SA_ALLOW try {
0121 if (iForceCacheClear) {
0122 forceCacheClear();
0123 }
0124 SendSourceTerminationSignalIfException sentry(actReg);
0125 {
0126
0127
0128
0129 actReg->preESSyncIOVSignal_.emit(iSync);
0130 auto postSignal = [&iSync](ActivityRegistry* actReg) { actReg->postESSyncIOVSignal_.emit(iSync); };
0131 std::unique_ptr<ActivityRegistry, decltype(postSignal)> guard(actReg, postSignal);
0132 eventSetupForInstanceAsync(iSync, task, endIOVWaitingTasks, eventSetupImpls);
0133 }
0134 sentry.completedSuccessfully();
0135 } catch (...) {
0136 task.doneWaiting(std::current_exception());
0137 }
0138 };
0139 if (doWeNeedToWaitForIOVsToFinish(iSync) || iForceCacheClear) {
0140
0141
0142
0143
0144 auto group = taskToStartAfterIOVInit.group();
0145 ServiceWeakToken weakToken = iToken;
0146 queueWhichWaitsForIOVsToFinish.push(*group,
0147 [iSync, taskToStartAfterIOVInit, asyncEventSetup, weakToken]() mutable {
0148 ServiceRegistry::Operate operate(weakToken.lock());
0149 asyncEventSetup(iSync, taskToStartAfterIOVInit);
0150 });
0151 } else {
0152 asyncEventSetup(iSync, taskToStartAfterIOVInit);
0153 }
0154 }
0155
0156 void EventSetupsController::eventSetupForInstanceAsync(
0157 IOVSyncValue const& syncValue,
0158 WaitingTaskHolder const& taskToStartAfterIOVInit,
0159 WaitingTaskList& endIOVWaitingTasks,
0160 std::vector<std::shared_ptr<const EventSetupImpl>>& eventSetupImpls) {
0161 finishConfiguration();
0162
0163 bool newEventSetupImpl = false;
0164 eventSetupImpls.clear();
0165 eventSetupImpls.reserve(providers_.size());
0166
0167
0168
0169
0170 for (auto& eventSetupProvider : providers_) {
0171 eventSetupProvider->setAllValidityIntervals(syncValue);
0172 }
0173
0174 for (auto& eventSetupRecordIOVQueue : eventSetupRecordIOVQueues_) {
0175
0176
0177
0178
0179 eventSetupRecordIOVQueue->setNewIntervalForAnySubProcess();
0180 }
0181
0182 for (auto& eventSetupProvider : providers_) {
0183
0184
0185
0186
0187 eventSetupImpls.push_back(eventSetupProvider->eventSetupForInstance(syncValue, newEventSetupImpl));
0188 }
0189
0190 for (auto& eventSetupRecordIOVQueue : eventSetupRecordIOVQueues_) {
0191 eventSetupRecordIOVQueue->checkForNewIOVs(taskToStartAfterIOVInit, endIOVWaitingTasks, newEventSetupImpl);
0192 }
0193 }
0194
0195 bool EventSetupsController::doWeNeedToWaitForIOVsToFinish(IOVSyncValue const& syncValue) const {
0196 if (hasNonconcurrentFinder()) {
0197 for (auto& eventSetupProvider : providers_) {
0198 if (eventSetupProvider->doWeNeedToWaitForIOVsToFinish(syncValue)) {
0199 return true;
0200 }
0201 }
0202 }
0203 return false;
0204 }
0205
0206 void EventSetupsController::forceCacheClear() {
0207 for (auto& eventSetupProvider : providers_) {
0208 eventSetupProvider->forceCacheClear();
0209 }
0210 }
0211
0212 std::shared_ptr<ESProductResolverProvider> EventSetupsController::getESProducerAndRegisterProcess(
0213 ParameterSet const& pset, unsigned subProcessIndex) {
0214
0215 auto elements = esproducers_.equal_range(pset.id());
0216 for (auto it = elements.first; it != elements.second; ++it) {
0217
0218 if (isTransientEqual(pset, *it->second.pset())) {
0219
0220 it->second.subProcessIndexes().push_back(subProcessIndex);
0221
0222 return it->second.provider();
0223 }
0224 }
0225
0226 return std::shared_ptr<ESProductResolverProvider>();
0227 }
0228
0229 void EventSetupsController::putESProducer(ParameterSet& pset,
0230 std::shared_ptr<ESProductResolverProvider> const& component,
0231 unsigned subProcessIndex) {
0232 auto newElement =
0233 esproducers_.insert(std::pair<ParameterSetID, ESProducerInfo>(pset.id(), ESProducerInfo(&pset, component)));
0234
0235 newElement->second.subProcessIndexes().push_back(subProcessIndex);
0236 }
0237
0238 std::shared_ptr<EventSetupRecordIntervalFinder> EventSetupsController::getESSourceAndRegisterProcess(
0239 ParameterSet const& pset, unsigned subProcessIndex) {
0240
0241 auto elements = essources_.equal_range(pset.id());
0242 for (auto it = elements.first; it != elements.second; ++it) {
0243
0244 if (isTransientEqual(pset, *it->second.pset())) {
0245
0246 it->second.subProcessIndexes().push_back(subProcessIndex);
0247
0248 return it->second.finder();
0249 }
0250 }
0251
0252 return std::shared_ptr<EventSetupRecordIntervalFinder>();
0253 }
0254
0255 void EventSetupsController::putESSource(ParameterSet const& pset,
0256 std::shared_ptr<EventSetupRecordIntervalFinder> const& component,
0257 unsigned subProcessIndex) {
0258 auto newElement =
0259 essources_.insert(std::pair<ParameterSetID, ESSourceInfo>(pset.id(), ESSourceInfo(&pset, component)));
0260
0261 newElement->second.subProcessIndexes().push_back(subProcessIndex);
0262 }
0263
0264 void EventSetupsController::clearComponents() {
0265 esproducers_.clear();
0266 essources_.clear();
0267 }
0268
0269 void EventSetupsController::lookForMatches(ParameterSetID const& psetID,
0270 unsigned subProcessIndex,
0271 unsigned precedingProcessIndex,
0272 bool& firstProcessWithThisPSet,
0273 bool& precedingHasMatchingPSet) const {
0274 auto elements = esproducers_.equal_range(psetID);
0275 for (auto it = elements.first; it != elements.second; ++it) {
0276 std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
0277
0278 auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
0279 if (iFound == subProcessIndexes.end()) {
0280 continue;
0281 }
0282
0283 if (iFound == subProcessIndexes.begin()) {
0284 firstProcessWithThisPSet = true;
0285 precedingHasMatchingPSet = false;
0286 } else {
0287 auto iFoundPreceding = std::find(subProcessIndexes.begin(), iFound, precedingProcessIndex);
0288 if (iFoundPreceding == iFound) {
0289 firstProcessWithThisPSet = false;
0290 precedingHasMatchingPSet = false;
0291 } else {
0292 firstProcessWithThisPSet = false;
0293 precedingHasMatchingPSet = true;
0294 }
0295 }
0296 return;
0297 }
0298 throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::lookForMatches\n"
0299 << "Subprocess index not found. This should never happen\n"
0300 << "Please report this to a Framework Developer\n";
0301 }
0302
0303 bool EventSetupsController::isFirstMatch(ParameterSetID const& psetID,
0304 unsigned subProcessIndex,
0305 unsigned precedingProcessIndex) const {
0306 auto elements = esproducers_.equal_range(psetID);
0307 for (auto it = elements.first; it != elements.second; ++it) {
0308 std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
0309
0310 auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
0311 if (iFound == subProcessIndexes.end()) {
0312 continue;
0313 }
0314
0315 auto iFoundPreceding = std::find(subProcessIndexes.begin(), iFound, precedingProcessIndex);
0316 if (iFoundPreceding == iFound) {
0317 break;
0318 } else {
0319 return iFoundPreceding == subProcessIndexes.begin();
0320 }
0321 }
0322 throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::isFirstMatch\n"
0323 << "Subprocess index not found. This should never happen\n"
0324 << "Please report this to a Framework Developer\n";
0325 return false;
0326 }
0327
0328 bool EventSetupsController::isLastMatch(ParameterSetID const& psetID,
0329 unsigned subProcessIndex,
0330 unsigned precedingProcessIndex) const {
0331 auto elements = esproducers_.equal_range(psetID);
0332 for (auto it = elements.first; it != elements.second; ++it) {
0333 std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
0334
0335 auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
0336 if (iFound == subProcessIndexes.end()) {
0337 continue;
0338 }
0339
0340 auto iFoundPreceding = std::find(subProcessIndexes.begin(), iFound, precedingProcessIndex);
0341 if (iFoundPreceding == iFound) {
0342 break;
0343 } else {
0344 return (++iFoundPreceding) == iFound;
0345 }
0346 }
0347 throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::isLastMatch\n"
0348 << "Subprocess index not found. This should never happen\n"
0349 << "Please report this to a Framework Developer\n";
0350 return false;
0351 }
0352
0353 bool EventSetupsController::isMatchingESSource(ParameterSetID const& psetID,
0354 unsigned subProcessIndex,
0355 unsigned precedingProcessIndex) const {
0356 auto elements = essources_.equal_range(psetID);
0357 for (auto it = elements.first; it != elements.second; ++it) {
0358 std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
0359
0360 auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
0361 if (iFound == subProcessIndexes.end()) {
0362 continue;
0363 }
0364
0365 auto iFoundPreceding = std::find(subProcessIndexes.begin(), iFound, precedingProcessIndex);
0366 if (iFoundPreceding == iFound) {
0367 return false;
0368 } else {
0369 return true;
0370 }
0371 }
0372 throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::lookForMatchingESSource\n"
0373 << "Subprocess index not found. This should never happen\n"
0374 << "Please report this to a Framework Developer\n";
0375 return false;
0376 }
0377
0378 bool EventSetupsController::isMatchingESProducer(ParameterSetID const& psetID,
0379 unsigned subProcessIndex,
0380 unsigned precedingProcessIndex) const {
0381 auto elements = esproducers_.equal_range(psetID);
0382 for (auto it = elements.first; it != elements.second; ++it) {
0383 std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
0384
0385 auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
0386 if (iFound == subProcessIndexes.end()) {
0387 continue;
0388 }
0389
0390 auto iFoundPreceding = std::find(subProcessIndexes.begin(), iFound, precedingProcessIndex);
0391 if (iFoundPreceding == iFound) {
0392 return false;
0393 } else {
0394 return true;
0395 }
0396 }
0397 throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::lookForMatchingESSource\n"
0398 << "Subprocess index not found. This should never happen\n"
0399 << "Please report this to a Framework Developer\n";
0400 return false;
0401 }
0402
0403 ParameterSet& EventSetupsController::getESProducerPSet(ParameterSetID const& psetID, unsigned subProcessIndex) {
0404 auto elements = esproducers_.equal_range(psetID);
0405 for (auto it = elements.first; it != elements.second; ++it) {
0406 std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
0407
0408 auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
0409 if (iFound == subProcessIndexes.end()) {
0410 continue;
0411 }
0412 return *it->second.pset();
0413 }
0414 throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::getESProducerPSet\n"
0415 << "Subprocess index not found. This should never happen\n"
0416 << "Please report this to a Framework Developer\n";
0417 }
0418
0419 void EventSetupsController::checkESProducerSharing() {
0420
0421 auto esProvider = providers_.begin();
0422 auto const esProviderEnd = providers_.end();
0423 if (esProvider != esProviderEnd)
0424 ++esProvider;
0425 for (; esProvider != esProviderEnd; ++esProvider) {
0426
0427
0428
0429
0430
0431
0432
0433 std::set<ParameterSetIDHolder> sharingCheckDone;
0434
0435
0436
0437
0438
0439
0440 std::map<EventSetupRecordKey, std::vector<ComponentDescription const*>> referencedESProducers;
0441
0442
0443
0444
0445
0446 for (auto precedingESProvider = providers_.begin(); precedingESProvider != esProvider; ++precedingESProvider) {
0447 (*esProvider)
0448 ->checkESProducerSharing(
0449 typeResolverMaker_, **precedingESProvider, sharingCheckDone, referencedESProducers, *this);
0450 }
0451
0452 (*esProvider)->resetRecordToResolverPointers();
0453 }
0454 for (auto& eventSetupProvider : providers_) {
0455 eventSetupProvider->clearInitializationData();
0456 }
0457 }
0458
0459 void EventSetupsController::initializeEventSetupRecordIOVQueues() {
0460 std::set<EventSetupRecordKey> keys;
0461 for (auto const& provider : providers_) {
0462 provider->fillKeys(keys);
0463 }
0464
0465 for (auto const& key : keys) {
0466 eventSetupRecordIOVQueues_.push_back(
0467 std::make_unique<EventSetupRecordIOVQueue>(numberOfConcurrentIOVs_.numberOfConcurrentIOVs(key)));
0468 EventSetupRecordIOVQueue& iovQueue = *eventSetupRecordIOVQueues_.back();
0469 for (auto& provider : providers_) {
0470 EventSetupRecordProvider* recProvider = provider->tryToGetRecordProvider(key);
0471 if (recProvider) {
0472 iovQueue.addRecProvider(recProvider);
0473 }
0474 }
0475 }
0476 }
0477
0478 void synchronousEventSetupForInstance(IOVSyncValue const& syncValue,
0479 oneapi::tbb::task_group& iGroup,
0480 eventsetup::EventSetupsController& espController) {
0481 FinalWaitingTask waitUntilIOVInitializationCompletes{iGroup};
0482
0483
0484 WaitingTaskList dummyWaitingTaskList;
0485 std::vector<std::shared_ptr<const EventSetupImpl>> dummyEventSetupImpls;
0486
0487 {
0488 WaitingTaskHolder waitingTaskHolder(iGroup, &waitUntilIOVInitializationCompletes);
0489
0490 CMS_SA_ALLOW try {
0491
0492 espController.eventSetupForInstanceAsync(
0493 syncValue, waitingTaskHolder, dummyWaitingTaskList, dummyEventSetupImpls);
0494 dummyWaitingTaskList.doneWaiting(std::exception_ptr{});
0495 } catch (...) {
0496 dummyWaitingTaskList.doneWaiting(std::exception_ptr{});
0497 waitingTaskHolder.doneWaiting(std::current_exception());
0498 }
0499 }
0500 waitUntilIOVInitializationCompletes.wait();
0501 }
0502 }
0503 }