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