CMS 3D CMS Logo

EventSetupProvider.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Framework
4 // Module: EventSetupProvider
5 //
6 // Description: <one line class summary>
7 //
8 // Implementation:
9 // <Notes on implementation>
10 //
11 // Author: Chris Jones
12 // Created: Thu Mar 24 16:27:14 EST 2005
13 //
14 
15 // system include files
16 #include <algorithm>
17 #include <cassert>
18 
19 // user include files
37 
38 namespace edm {
39  namespace eventsetup {
40 
42  unsigned subProcessIndex,
43  const PreferredProviderInfo* iInfo)
44  : activityRegistry_(activityRegistry),
45  mustFinishConfiguration_(true),
46  subProcessIndex_(subProcessIndex),
47  preferredProviderInfo_((nullptr != iInfo) ? (new PreferredProviderInfo(*iInfo)) : nullptr),
48  finders_(new std::vector<std::shared_ptr<EventSetupRecordIntervalFinder>>()),
49  dataProviders_(new std::vector<std::shared_ptr<DataProxyProvider>>()),
50  referencedDataKeys_(new std::map<EventSetupRecordKey, std::map<DataKey, ComponentDescription const*>>),
51  recordToFinders_(
53  psetIDToRecordKey_(new std::map<ParameterSetIDHolder, std::set<EventSetupRecordKey>>),
54  recordToPreferred_(new std::map<EventSetupRecordKey, std::map<DataKey, ComponentDescription>>),
55  recordsWithALooperProxy_(new std::set<EventSetupRecordKey>) {}
56 
58 
59  std::shared_ptr<EventSetupRecordProvider>& EventSetupProvider::recordProvider(const EventSetupRecordKey& iKey) {
60  auto lb = std::lower_bound(recordKeys_.begin(), recordKeys_.end(), iKey);
61  if (lb == recordKeys_.end() || iKey != *lb) {
62  throw cms::Exception("LogicError") << "EventSetupProvider::recordProvider Could not find key\n"
63  << "Should be impossible. Please contact Framework developer.\n";
64  }
65  auto index = std::distance(recordKeys_.begin(), lb);
66  return recordProviders_[index];
67  }
68 
70  auto lb = std::lower_bound(recordKeys_.begin(), recordKeys_.end(), iKey);
71  if (lb == recordKeys_.end() || iKey != *lb) {
72  return nullptr;
73  }
74  auto index = std::distance(recordKeys_.begin(), lb);
75  return recordProviders_[index].get();
76  }
77 
79  std::unique_ptr<EventSetupRecordProvider> iProvider) {
80  auto lb = std::lower_bound(recordKeys_.begin(), recordKeys_.end(), iKey);
81  auto index = std::distance(recordKeys_.begin(), lb);
82  if (lb == recordKeys_.end() || iKey != *lb) {
83  recordKeys_.insert(lb, iKey);
84  recordProviders_.insert(recordProviders_.begin() + index, std::move(iProvider));
85  } else {
86  recordProviders_[index] = std::move(iProvider);
87  }
88  }
89 
90  void EventSetupProvider::add(std::shared_ptr<DataProxyProvider> iProvider) {
91  assert(iProvider.get() != nullptr);
92  dataProviders_->push_back(iProvider);
93  if (activityRegistry_) {
94  activityRegistry_->postESModuleRegistrationSignal_(iProvider->description());
95  }
96  }
97 
98  void EventSetupProvider::replaceExisting(std::shared_ptr<DataProxyProvider> dataProxyProvider) {
99  ParameterSetIDHolder psetID(dataProxyProvider->description().pid_);
100  std::set<EventSetupRecordKey> const& keysForPSetID = (*psetIDToRecordKey_)[psetID];
101  for (auto const& key : keysForPSetID) {
102  recordProvider(key)->resetProxyProvider(psetID, dataProxyProvider);
103  }
104  }
105 
106  void EventSetupProvider::add(std::shared_ptr<EventSetupRecordIntervalFinder> iFinder) {
107  assert(iFinder.get() != nullptr);
108  finders_->push_back(iFinder);
109  }
110 
111  using RecordProviders = std::vector<std::shared_ptr<EventSetupRecordProvider>>;
112  using RecordToPreferred = std::map<EventSetupRecordKey, EventSetupRecordProvider::DataToPreferredProviderMap>;
114  static void preferEverything(const ComponentDescription& iComponent,
115  const RecordProviders& iRecordProviders,
116  RecordToPreferred& iReturnValue) {
117  //need to get our hands on the actual DataProxyProvider
118  bool foundProxyProvider = false;
119  for (auto const& recordProvider : iRecordProviders) {
120  std::set<ComponentDescription> components = recordProvider->proxyProviderDescriptions();
121  if (components.find(iComponent) != components.end()) {
122  std::shared_ptr<DataProxyProvider> proxyProv = recordProvider->proxyProvider(*(components.find(iComponent)));
123  assert(proxyProv.get());
124 
125  std::set<EventSetupRecordKey> records = proxyProv->usingRecords();
126  for (auto const& recordKey : records) {
127  unsigned int iovIndex = 0; // Doesn't matter which index is picked, at least 1 should always exist
128  DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(recordKey, iovIndex);
129  if (!keyedProxies.unInitialized()) {
130  //add them to our output
131  EventSetupRecordProvider::DataToPreferredProviderMap& dataToProviderMap = iReturnValue[recordKey];
132 
133  for (auto keyedProxy : keyedProxies) {
134  EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
135  dataToProviderMap.find(keyedProxy.dataKey_);
136  if (itFind != dataToProviderMap.end()) {
137  throw cms::Exception("ESPreferConflict")
138  << "Two providers have been set to be preferred for\n"
139  << keyedProxy.dataKey_.type().name() << " \"" << keyedProxy.dataKey_.name().value() << "\""
140  << "\n the providers are "
141  << "\n 1) type=" << itFind->second.type_ << " label=\"" << itFind->second.label_ << "\""
142  << "\n 2) type=" << iComponent.type_ << " label=\"" << iComponent.label_ << "\""
143  << "\nPlease modify configuration so only one is preferred";
144  }
145  dataToProviderMap.insert(std::make_pair(keyedProxy.dataKey_, iComponent));
146  }
147  }
148  }
149  foundProxyProvider = true;
150  break;
151  }
152  }
153  if (!foundProxyProvider) {
154  throw cms::Exception("ESPreferNoProvider")
155  << "Could not make type=\"" << iComponent.type_ << "\" label=\"" << iComponent.label_
156  << "\" a preferred Provider."
157  << "\n Please check spelling of name, or that it was loaded into the job.";
158  }
159  }
160 
162  using namespace edm::eventsetup;
164  for (auto const& itInfo : *preferredProviderInfo_) {
165  if (itInfo.second.empty()) {
166  //want everything
168  } else {
169  for (auto const& itRecData : itInfo.second) {
170  std::string recordName = itRecData.first;
172  if (recordKey.type() == eventsetup::EventSetupRecordKey::TypeTag()) {
173  throw cms::Exception("ESPreferUnknownRecord")
174  << "Unknown record \"" << recordName
175  << "\" used in es_prefer statement for type=" << itInfo.first.type_ << " label=\""
176  << itInfo.first.label_ << "\"\n Please check spelling.";
177  //record not found
178  }
179  //See if the ProxyProvider provides something for this Record
180  EventSetupRecordProvider& recordProviderForKey = *recordProvider(recordKey);
181 
182  std::set<ComponentDescription> components = recordProviderForKey.proxyProviderDescriptions();
183  std::set<ComponentDescription>::iterator itProxyProv = components.find(itInfo.first);
184  if (itProxyProv == components.end()) {
185  throw cms::Exception("ESPreferWrongRecord")
186  << "The type=" << itInfo.first.type_ << " label=\"" << itInfo.first.label_
187  << "\" does not provide data for the Record " << recordName;
188  }
189  //Does it data type exist?
190  eventsetup::TypeTag datumType = eventsetup::TypeTag::findType(itRecData.second.first);
191  if (datumType == eventsetup::TypeTag()) {
192  //not found
193  throw cms::Exception("ESPreferWrongDataType")
194  << "The es_prefer statement for type=" << itInfo.first.type_ << " label=\"" << itInfo.first.label_
195  << "\" has the unknown data type \"" << itRecData.second.first << "\""
196  << "\n Please check spelling";
197  }
198  eventsetup::DataKey datumKey(datumType, itRecData.second.second.c_str());
199 
200  //Does the proxyprovider make this?
201  std::shared_ptr<DataProxyProvider> proxyProv = recordProviderForKey.proxyProvider(*itProxyProv);
202  unsigned int iovIndex = 0; // Doesn't matter which index is picked, at least 1 should always exist
203  const DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(recordKey, iovIndex);
204  if (!keyedProxies.contains(datumKey)) {
205  throw cms::Exception("ESPreferWrongData")
206  << "The es_prefer statement for type=" << itInfo.first.type_ << " label=\"" << itInfo.first.label_
207  << "\" specifies the data item \n"
208  << " type=\"" << itRecData.second.first << "\" label=\"" << itRecData.second.second << "\""
209  << " which is not provided. Please check spelling.";
210  }
211 
213  (*recordToPreferred_)[recordKey];
214  //has another provider already been specified?
215  if (dataToProviderMap.end() != dataToProviderMap.find(datumKey)) {
216  EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
217  dataToProviderMap.find(datumKey);
218  throw cms::Exception("ESPreferConflict")
219  << "Two providers have been set to be preferred for\n"
220  << datumKey.type().name() << " \"" << datumKey.name().value() << "\""
221  << "\n the providers are "
222  << "\n 1) type=" << itFind->second.type_ << " label=\"" << itFind->second.label_ << "\""
223  << "\n 2) type=" << itProxyProv->type_ << " label=\"" << itProxyProv->label_ << "\""
224  << "\nPlease modify configuration so only one is preferred";
225  }
226  dataToProviderMap.insert(std::make_pair(datumKey, *itProxyProv));
227  }
228  }
229  }
230  }
231  }
232 
234  bool& hasNonconcurrentFinder) {
235  //we delayed adding finders to the system till here so that everything would be loaded first
236  recordToFinders_->clear();
237  for (auto& finder : *finders_) {
238  if (!finder->concurrentFinder()) {
239  hasNonconcurrentFinder = true;
240  }
241 
242  const std::set<EventSetupRecordKey> recordsUsing = finder->findingForRecords();
243 
244  for (auto const& key : recordsUsing) {
245  (*recordToFinders_)[key].push_back(finder);
246 
248  if (recProvider == nullptr) {
249  bool printInfoMsg = true;
250  unsigned int nConcurrentIOVs = numberOfConcurrentIOVs.numberOfConcurrentIOVs(key, printInfoMsg);
251 
252  //create a provider for this record
253  insert(key, std::make_unique<EventSetupRecordProvider>(key, activityRegistry_, nConcurrentIOVs));
254  recProvider = tryToGetRecordProvider(key);
255  }
256  recProvider->addFinder(finder);
257  }
258  }
259  //we've transfered our ownership so this is no longer needed
260  finders_.reset();
261 
262  //Now handle providers since sources can also be finders and the sources can delay registering
263  // their Records and therefore could delay setting up their Proxies
264  psetIDToRecordKey_->clear();
265  for (auto& dataProxyProvider : *dataProviders_) {
266  ParameterSetIDHolder psetID(dataProxyProvider->description().pid_);
267 
268  const std::set<EventSetupRecordKey> recordsUsing = dataProxyProvider->usingRecords();
269  for (auto const& key : recordsUsing) {
270  unsigned int nConcurrentIOVs = numberOfConcurrentIOVs.numberOfConcurrentIOVs(key);
271  dataProxyProvider->createKeyedProxies(key, nConcurrentIOVs);
272 
273  if (dataProxyProvider->description().isLooper_) {
274  recordsWithALooperProxy_->insert(key);
275  }
276 
277  (*psetIDToRecordKey_)[psetID].insert(key);
278 
280  if (recProvider == nullptr) {
281  bool printInfoMsg = true;
282  nConcurrentIOVs = numberOfConcurrentIOVs.numberOfConcurrentIOVs(key, printInfoMsg);
283  //create a provider for this record
284  insert(key, std::make_unique<EventSetupRecordProvider>(key, activityRegistry_, nConcurrentIOVs));
285  recProvider = tryToGetRecordProvider(key);
286  }
287  recProvider->add(dataProxyProvider);
288  }
289  }
290 
291  //used for the case where no preferred Providers have been specified for the Record
293 
295 
296  //For each Provider, find all the Providers it depends on. If a dependent Provider
297  // can not be found pass in an empty list
298  //CHANGE: now allow for missing Providers
299  for (auto& itRecordProvider : recordProviders_) {
300  const EventSetupRecordProvider::DataToPreferredProviderMap* preferredInfo = &kEmptyMap;
301  RecordToPreferred::const_iterator itRecordFound = recordToPreferred_->find(itRecordProvider->key());
302  if (itRecordFound != recordToPreferred_->end()) {
303  preferredInfo = &(itRecordFound->second);
304  }
305  //Give it our list of preferred
306  itRecordProvider->usePreferred(*preferredInfo);
307 
308  std::set<EventSetupRecordKey> records = itRecordProvider->dependentRecords();
309  if (!records.empty()) {
310  std::string missingRecords;
311  std::vector<std::shared_ptr<EventSetupRecordProvider>> depProviders;
312  depProviders.reserve(records.size());
313  bool foundAllProviders = true;
314  for (auto const& key : records) {
315  auto lb = std::lower_bound(recordKeys_.begin(), recordKeys_.end(), key);
316  if (lb == recordKeys_.end() || key != *lb) {
317  foundAllProviders = false;
318  if (missingRecords.empty()) {
319  missingRecords = key.name();
320  } else {
321  missingRecords += ", ";
322  missingRecords += key.name();
323  }
324  } else {
325  auto index = std::distance(recordKeys_.begin(), lb);
326  depProviders.push_back(recordProviders_[index]);
327  }
328  }
329 
330  if (!foundAllProviders) {
331  edm::LogInfo("EventSetupDependency")
332  << "The EventSetup record " << itRecordProvider->key().name() << " depends on at least one Record \n ("
333  << missingRecords
334  << ") which is not present in the job."
335  "\n This may lead to an exception begin thrown during event processing.\n If no exception occurs "
336  "during the job than it is usually safe to ignore this message.";
337 
338  //depProviders.clear();
339  //NOTE: should provide a warning
340  }
341 
342  itRecordProvider->setDependentProviders(depProviders);
343  }
344  }
345 
347  for (auto& provider : *dataProviders_) {
348  provider->updateLookup(indices);
349  }
350  dataProviders_.reset();
351 
352  mustFinishConfiguration_ = false;
353  }
354 
355  using Itr = RecordProviders::iterator;
356  static void findDependents(const EventSetupRecordKey& iKey,
357  Itr itBegin,
358  Itr itEnd,
359  std::vector<std::shared_ptr<EventSetupRecordProvider>>& oDependents) {
360  for (Itr it = itBegin; it != itEnd; ++it) {
361  //does it depend on the record in question?
362  const std::set<EventSetupRecordKey>& deps = (*it)->dependentRecords();
363  if (deps.end() != deps.find(iKey)) {
364  oDependents.push_back(*it);
365  //now see who is dependent on this record since they will be indirectly dependent on iKey
366  findDependents((*it)->key(), itBegin, itEnd, oDependents);
367  }
368  }
369  }
370 
373  if (recProvider == nullptr) {
374  return;
375  }
376 
377  std::vector<std::shared_ptr<EventSetupRecordProvider>> dependents;
378  findDependents(iKey, recordProviders_.begin(), recordProviders_.end(), dependents);
379 
380  dependents.erase(std::unique(dependents.begin(), dependents.end()), dependents.end());
381 
382  recProvider->resetProxies();
383  for (auto& d : dependents) {
384  d->resetProxies();
385  }
386  }
387 
389  for (auto& recProvider : recordProviders_) {
390  if (recProvider) {
391  recProvider->resetProxies();
392  }
393  }
394  }
395 
397  ModuleTypeResolverMaker const* resolverMaker,
398  EventSetupProvider& precedingESProvider,
399  std::set<ParameterSetIDHolder>& sharingCheckDone,
400  std::map<EventSetupRecordKey, std::vector<ComponentDescription const*>>& referencedESProducers,
401  EventSetupsController& esController) {
402  edm::LogVerbatim("EventSetupSharing")
403  << "EventSetupProvider::checkESProducerSharing: Checking processes with SubProcess Indexes "
404  << subProcessIndex() << " and " << precedingESProvider.subProcessIndex();
405 
406  if (referencedESProducers.empty()) {
407  for (auto& recProvider : recordProviders_) {
408  recProvider->getReferencedESProducers(referencedESProducers);
409  }
410  }
411 
412  // This records whether the configurations of all the DataProxyProviders
413  // and finders matches for a particular pair of processes and
414  // a particular record and also the records it depends on.
415  std::map<EventSetupRecordKey, bool> allComponentsMatch;
416 
417  std::map<ParameterSetID, bool> candidateNotRejectedYet;
418 
419  // Loop over all the ESProducers which have a DataProxy
420  // referenced by any EventSetupRecord in this EventSetupProvider
421  for (auto const& iRecord : referencedESProducers) {
422  for (auto const& iComponent : iRecord.second) {
423  ParameterSetID const& psetID = iComponent->pid_;
424  ParameterSetIDHolder psetIDHolder(psetID);
425  if (sharingCheckDone.find(psetIDHolder) != sharingCheckDone.end())
426  continue;
427 
428  bool firstProcessWithThisPSet = false;
429  bool precedingHasMatchingPSet = false;
430 
431  esController.lookForMatches(psetID,
433  precedingESProvider.subProcessIndex_,
434  firstProcessWithThisPSet,
435  precedingHasMatchingPSet);
436 
437  if (firstProcessWithThisPSet) {
438  sharingCheckDone.insert(psetIDHolder);
439  allComponentsMatch[iRecord.first] = false;
440  continue;
441  }
442 
443  if (!precedingHasMatchingPSet) {
444  allComponentsMatch[iRecord.first] = false;
445  continue;
446  }
447 
448  // An ESProducer that survives to this point is a candidate.
449  // It was shared with some other process in the first pass where
450  // ESProducers were constructed and one of three possibilities exists:
451  // 1) It should not have been shared and a new ESProducer needs
452  // to be created and the proper pointers set.
453  // 2) It should have been shared with a different preceding process
454  // in which case some pointers need to be modified.
455  // 3) It was originally shared which the correct prior process
456  // in which case nothing needs to be done, but we do need to
457  // do some work to verify that.
458  // Make an entry in a map for each of these ESProducers. We
459  // will set the value to false if and when we determine
460  // the ESProducer cannot be shared between this pair of processes.
461  auto iCandidateNotRejectedYet = candidateNotRejectedYet.find(psetID);
462  if (iCandidateNotRejectedYet == candidateNotRejectedYet.end()) {
463  candidateNotRejectedYet[psetID] = true;
464  iCandidateNotRejectedYet = candidateNotRejectedYet.find(psetID);
465  }
466 
467  // At this point we know that the two processes both
468  // have an ESProducer matching the type and label in
469  // iComponent and also with exactly the same configuration.
470  // And there was not an earlier preceding process
471  // where the same instance of the ESProducer could
472  // have been shared. And this ESProducer was referenced
473  // by the later process's EventSetupRecord (preferred or
474  // or just the only thing that could have made the data).
475  // To determine if sharing is allowed, now we need to
476  // check if all the DataProxyProviders and all the
477  // finders are the same for this record and also for
478  // all records this record depends on. And even
479  // if this is true, we have to wait until the loop
480  // ends because some other DataProxy associated with
481  // the ESProducer could write to a different record where
482  // the same determination will need to be repeated. Only if
483  // all of the the DataProxy's can be shared, can the ESProducer
484  // instance be shared across processes.
485 
486  if (iCandidateNotRejectedYet->second == true) {
487  auto iAllComponentsMatch = allComponentsMatch.find(iRecord.first);
488  if (iAllComponentsMatch == allComponentsMatch.end()) {
489  // We do not know the value in AllComponents yet and
490  // we need it now so we have to do the difficult calculation
491  // now.
492  bool match = doRecordsMatch(precedingESProvider, iRecord.first, allComponentsMatch, esController);
493  allComponentsMatch[iRecord.first] = match;
494  iAllComponentsMatch = allComponentsMatch.find(iRecord.first);
495  }
496  if (!iAllComponentsMatch->second) {
497  iCandidateNotRejectedYet->second = false;
498  }
499  }
500  } // end loop over components used by record
501  } // end loop over records
502 
503  // Loop over candidates
504  for (auto const& candidate : candidateNotRejectedYet) {
505  ParameterSetID const& psetID = candidate.first;
506  bool canBeShared = candidate.second;
507  if (canBeShared) {
508  ParameterSet const& pset = esController.getESProducerPSet(psetID, subProcessIndex_);
510  ParameterSetIDHolder psetIDHolder(psetID);
511  sharingCheckDone.insert(psetIDHolder);
512  if (esController.isFirstMatch(psetID, subProcessIndex_, precedingESProvider.subProcessIndex_)) {
513  continue; // Proper sharing was already done. Nothing more to do.
514  }
515 
516  // Need to reset the pointer from the EventSetupRecordProvider to the
517  // the DataProxyProvider so these two processes share an ESProducer.
518 
519  std::shared_ptr<DataProxyProvider> dataProxyProvider;
520  std::set<EventSetupRecordKey> const& keysForPSetID1 = (*precedingESProvider.psetIDToRecordKey_)[psetIDHolder];
521  for (auto const& key : keysForPSetID1) {
522  dataProxyProvider = precedingESProvider.recordProvider(key)->proxyProvider(psetIDHolder);
523  assert(dataProxyProvider);
524  break;
525  }
526 
527  std::set<EventSetupRecordKey> const& keysForPSetID2 = (*psetIDToRecordKey_)[psetIDHolder];
528  for (auto const& key : keysForPSetID2) {
529  recordProvider(key)->resetProxyProvider(psetIDHolder, dataProxyProvider);
530  }
531  } else {
532  if (esController.isLastMatch(psetID, subProcessIndex_, precedingESProvider.subProcessIndex_)) {
533  ParameterSet& pset = esController.getESProducerPSet(psetID, subProcessIndex_);
534  ModuleFactory::get()->addTo(esController, *this, pset, resolverMaker, true);
535  }
536  }
537  }
538  }
539 
541  EventSetupRecordKey const& eventSetupRecordKey,
542  std::map<EventSetupRecordKey, bool>& allComponentsMatch,
543  EventSetupsController const& esController) {
544  // first check if this record matches. If not just return false
545 
546  // then find the directly dependent records and iterate over them
547  // recursively call this function on them. If they return false
548  // set allComponentsMatch to false for them and return false.
549  // if they all return true then set allComponents to true
550  // and return true.
551 
552  if (precedingESProvider.recordsWithALooperProxy_->find(eventSetupRecordKey) !=
553  precedingESProvider.recordsWithALooperProxy_->end()) {
554  return false;
555  }
556 
557  if ((*recordToFinders_)[eventSetupRecordKey].size() !=
558  (*precedingESProvider.recordToFinders_)[eventSetupRecordKey].size()) {
559  return false;
560  }
561 
562  for (auto const& finder : (*recordToFinders_)[eventSetupRecordKey]) {
563  ParameterSetID const& psetID = finder->descriptionForFinder().pid_;
564  bool itMatches =
565  esController.isMatchingESSource(psetID, subProcessIndex_, precedingESProvider.subProcessIndex_);
566  if (!itMatches) {
567  return false;
568  }
569  }
570 
571  fillReferencedDataKeys(eventSetupRecordKey);
572  precedingESProvider.fillReferencedDataKeys(eventSetupRecordKey);
573 
574  std::map<DataKey, ComponentDescription const*> const& dataItems = (*referencedDataKeys_)[eventSetupRecordKey];
575 
576  std::map<DataKey, ComponentDescription const*> const& precedingDataItems =
577  (*precedingESProvider.referencedDataKeys_)[eventSetupRecordKey];
578 
579  if (dataItems.size() != precedingDataItems.size()) {
580  return false;
581  }
582 
583  for (auto const& dataItem : dataItems) {
584  auto precedingDataItem = precedingDataItems.find(dataItem.first);
585  if (precedingDataItem == precedingDataItems.end()) {
586  return false;
587  }
588  if (dataItem.second->pid_ != precedingDataItem->second->pid_) {
589  return false;
590  }
591  // Check that the configurations match exactly for the ESProducers
592  // (We already checked the ESSources above and there should not be
593  // any loopers)
594  if (!dataItem.second->isSource_ && !dataItem.second->isLooper_) {
595  bool itMatches = esController.isMatchingESProducer(
596  dataItem.second->pid_, subProcessIndex_, precedingESProvider.subProcessIndex_);
597  if (!itMatches) {
598  return false;
599  }
600  }
601  }
602  EventSetupRecordProvider* recProvider = tryToGetRecordProvider(eventSetupRecordKey);
603  if (recProvider != nullptr) {
604  std::set<EventSetupRecordKey> dependentRecords = recProvider->dependentRecords();
605  for (auto const& dependentRecord : dependentRecords) {
606  auto iter = allComponentsMatch.find(dependentRecord);
607  if (iter != allComponentsMatch.end()) {
608  if (iter->second) {
609  continue;
610  } else {
611  return false;
612  }
613  }
614  bool match = doRecordsMatch(precedingESProvider, dependentRecord, allComponentsMatch, esController);
615  allComponentsMatch[dependentRecord] = match;
616  if (!match)
617  return false;
618  }
619  }
620  return true;
621  }
622 
624  if (referencedDataKeys_->find(eventSetupRecordKey) != referencedDataKeys_->end())
625  return;
626 
627  EventSetupRecordProvider* recProvider = tryToGetRecordProvider(eventSetupRecordKey);
628  if (recProvider == nullptr) {
629  (*referencedDataKeys_)[eventSetupRecordKey];
630  return;
631  }
632  recProvider->fillReferencedDataKeys((*referencedDataKeys_)[eventSetupRecordKey]);
633  }
634 
636  for (auto const& recProvider : recordProviders_) {
638  const EventSetupRecordProvider::DataToPreferredProviderMap* preferredInfo = &kEmptyMap;
639  RecordToPreferred::const_iterator itRecordFound = recordToPreferred_->find(recProvider->key());
640  if (itRecordFound != recordToPreferred_->end()) {
641  preferredInfo = &(itRecordFound->second);
642  }
643  recProvider->resetRecordToProxyPointers(*preferredInfo);
644  }
645  }
646 
648  preferredProviderInfo_.reset();
649  referencedDataKeys_.reset();
650  recordToFinders_.reset();
651  psetIDToRecordKey_.reset();
652  recordToPreferred_.reset();
653  recordsWithALooperProxy_.reset();
654  }
655 
657  std::set<EventSetupRecordKey>& recordsNotAllowingConcurrentIOVs) const {
658  for (auto const& dataProxyProvider : *dataProviders_) {
659  dataProxyProvider->fillRecordsNotAllowingConcurrentIOVs(recordsNotAllowingConcurrentIOVs);
660  }
661  }
662 
664  // First loop sets a flag that helps us to not duplicate calls to the
665  // same EventSetupRecordProvider setting the IOVs. Dependent records
666  // can cause duplicate calls without this protection.
667  for (auto& recProvider : recordProviders_) {
668  recProvider->initializeForNewSyncValue();
669  }
670 
671  for (auto& recProvider : recordProviders_) {
672  recProvider->setValidityIntervalFor(iValue);
673  }
674  }
675 
676  std::shared_ptr<const EventSetupImpl> EventSetupProvider::eventSetupForInstance(const IOVSyncValue& iValue,
677  bool& newEventSetupImpl) {
678  using IntervalStatus = EventSetupRecordProvider::IntervalStatus;
679 
680  // It is important to understand that eventSetupForInstance is a function
681  // where only one call is executing at a time (not multiple calls running
682  // concurrently). These calls are made in the order determined by the
683  // InputSource. One invocation completes and returns before another starts.
684 
685  bool needNewEventSetupImpl = false;
686  if (eventSetupImpl_.get() == nullptr) {
687  needNewEventSetupImpl = true;
688  } else {
689  for (auto& recProvider : recordProviders_) {
690  if (recProvider->intervalStatus() == IntervalStatus::Invalid) {
691  if (eventSetupImpl_->validRecord(recProvider->key())) {
692  needNewEventSetupImpl = true;
693  }
694  } else {
695  if (recProvider->newIntervalForAnySubProcess()) {
696  needNewEventSetupImpl = true;
697  }
698  }
699  }
700  }
701 
702  if (needNewEventSetupImpl) {
703  //cannot use make_shared because constructor is private
704  eventSetupImpl_ = std::shared_ptr<EventSetupImpl>(new EventSetupImpl());
705  newEventSetupImpl = true;
706  eventSetupImpl_->setKeyIters(recordKeys_.begin(), recordKeys_.end());
707 
708  for (auto& recProvider : recordProviders_) {
709  recProvider->setEventSetupImpl(eventSetupImpl_.get());
710  }
711  }
713  }
714 
716  for (auto& recProvider : recordProviders_) {
717  if (recProvider->doWeNeedToWaitForIOVsToFinish(iValue)) {
718  return true;
719  }
720  }
721  return false;
722  }
723 
724  std::set<ComponentDescription> EventSetupProvider::proxyProviderDescriptions() const {
725  typedef std::set<ComponentDescription> Set;
726  Set descriptions;
727 
728  for (auto const& recProvider : recordProviders_) {
729  auto const& d = recProvider->proxyProviderDescriptions();
730  descriptions.insert(d.begin(), d.end());
731  }
732  if (dataProviders_.get()) {
733  for (auto const& p : *dataProviders_) {
734  descriptions.insert(p->description());
735  }
736  }
737 
738  return descriptions;
739  }
740 
742  insert(iKey, std::unique_ptr<EventSetupRecordProvider>());
743  eventSetupImpl_->setKeyIters(recordKeys_.begin(), recordKeys_.end());
744  }
745 
747  preferredProviderInfo_ = std::make_unique<PreferredProviderInfo>(iInfo);
748  }
749 
750  void EventSetupProvider::fillKeys(std::set<EventSetupRecordKey>& keys) const {
751  for (auto const& recProvider : recordProviders_) {
752  keys.insert(recProvider->key());
753  }
754  }
755 
758 
759  unsigned int index = 0;
760  for (const auto& provider : recordProviders_) {
761  index = ret.dataKeysInRecord(
762  index, provider->key(), provider->registeredDataKeys(), provider->componentsForRegisteredDataKeys());
763  }
764 
765  return ret;
766  }
767 
768  //
769  // static member functions
770  //
772  std::string edmtype = iConfiguration.getParameter<std::string>("@module_edm_type");
773  std::string modtype = iConfiguration.getParameter<std::string>("@module_type");
774  std::string label = iConfiguration.getParameter<std::string>("@module_label");
775  edm::LogVerbatim("EventSetupSharing")
776  << "Sharing " << edmtype << ": class=" << modtype << " label='" << label << "'";
777  }
778 
779  } // namespace eventsetup
780 } // namespace edm
size
Write out results.
static void findDependents(const EventSetupRecordKey &iKey, Itr itBegin, Itr itEnd, std::vector< std::shared_ptr< EventSetupRecordProvider >> &oDependents)
Log< level::Info, true > LogVerbatim
std::set< EventSetupRecordKey > dependentRecords() const
Returns the list of Records the provided Record depends on (usually none)
ESRecordsToProxyIndices recordsToProxyIndices() const
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
propagate_const< std::shared_ptr< EventSetupImpl > > eventSetupImpl_
void resetProxies()
This will clear the cache&#39;s of all the Proxies so that next time they are called they will run...
ret
prodAgent to be discontinued
std::unique_ptr< std::map< ParameterSetIDHolder, std::set< EventSetupRecordKey > > > psetIDToRecordKey_
std::set< ComponentDescription > proxyProviderDescriptions() const
return information on which DataProxyProviders are supplying information
bool isMatchingESSource(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
void addRecord(const EventSetupRecordKey &iKey)
Intended for use only in tests.
std::unique_ptr< std::map< EventSetupRecordKey, std::map< DataKey, ComponentDescription const * > > > referencedDataKeys_
void fillKeys(std::set< EventSetupRecordKey > &keys) const
constexpr std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
void addFinder(std::shared_ptr< EventSetupRecordIntervalFinder >)
For now, only use one finder.
void lookForMatches(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex, bool &firstProcessWithThisPSet, bool &precedingHasMatchingPSet) const
assert(be >=bs)
void finishConfiguration(NumberOfConcurrentIOVs const &, bool &hasNonconcurrentFinder)
std::map< ComponentDescription, RecordToDataMap > PreferredProviderInfo
std::set< ComponentDescription > proxyProviderDescriptions() const
void forceCacheClear()
Used when testing that all code properly updates on IOV changes of all Records.
RecordProviders::iterator Itr
ParameterSet & getESProducerPSet(ParameterSetID const &psetID, unsigned subProcessIndex)
char const * label
bool isLastMatch(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
std::shared_ptr< EventSetupRecordProvider > & recordProvider(const EventSetupRecordKey &iKey)
EventSetupRecordProvider * tryToGetRecordProvider(const EventSetupRecordKey &iKey)
bool doWeNeedToWaitForIOVsToFinish(IOVSyncValue const &) const
static void logInfoWhenSharing(ParameterSet const &iConfiguration)
void fillReferencedDataKeys(EventSetupRecordKey const &eventSetupRecordKey)
void add(std::shared_ptr< DataProxyProvider >)
std::unique_ptr< std::set< EventSetupRecordKey > > recordsWithALooperProxy_
void fillRecordsNotAllowingConcurrentIOVs(std::set< EventSetupRecordKey > &recordsNotAllowingConcurrentIOVs) const
static void preferEverything(const ComponentDescription &iComponent, const RecordProviders &iRecordProviders, RecordToPreferred &iReturnValue)
find everything made by a DataProxyProvider and add it to the &#39;preferred&#39; list
std::unique_ptr< std::vector< std::shared_ptr< EventSetupRecordIntervalFinder > > > finders_
def unique(seq, keepstr=True)
Definition: tier0.py:24
bool isMatchingESProducer(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
std::shared_ptr< DataProxyProvider > proxyProvider(ComponentDescription const &)
returns the first matching DataProxyProvider or a &#39;null&#39; if not found
ActivityRegistry const * activityRegistry_
void fillReferencedDataKeys(std::map< DataKey, ComponentDescription const *> &referencedDataKeys) const
std::unique_ptr< PreferredProviderInfo > preferredProviderInfo_
std::shared_ptr< const EventSetupImpl > eventSetupForInstance(IOVSyncValue const &, bool &newEventSetupImpl)
void resetRecordPlusDependentRecords(EventSetupRecordKey const &)
Used when we need to force a Record to reset all its proxies.
std::unique_ptr< std::vector< std::shared_ptr< DataProxyProvider > > > dataProviders_
d
Definition: ztail.py:151
Log< level::Info, false > LogInfo
std::unique_ptr< std::map< EventSetupRecordKey, std::vector< std::shared_ptr< EventSetupRecordIntervalFinder > > > > recordToFinders_
bool doRecordsMatch(EventSetupProvider &precedingESProvider, EventSetupRecordKey const &eventSetupRecordKey, std::map< EventSetupRecordKey, bool > &allComponentsMatch, EventSetupsController const &esController)
EventSetupProvider(ActivityRegistry const *, unsigned subProcessIndex=0U, PreferredProviderInfo const *iInfo=nullptr)
std::map< DataKey, ComponentDescription > DataToPreferredProviderMap
void setPreferredProviderInfo(PreferredProviderInfo const &iInfo)
void checkESProducerSharing(ModuleTypeResolverMaker const *resolverMaker, EventSetupProvider &precedingESProvider, std::set< ParameterSetIDHolder > &sharingCheckDone, std::map< EventSetupRecordKey, std::vector< ComponentDescription const *>> &referencedESProducers, EventSetupsController &esController)
void setAllValidityIntervals(const IOVSyncValue &iValue)
Set the validity intervals in all EventSetupRecordProviders.
bool isFirstMatch(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
heterocontainer::HCTypeTag TypeTag
std::map< EventSetupRecordKey, EventSetupRecordProvider::DataToPreferredProviderMap > RecordToPreferred
void replaceExisting(std::shared_ptr< DataProxyProvider >)
HLT enums.
static ComponentFactory< T > const * get()
void add(std::shared_ptr< DataProxyProvider >)
numberOfConcurrentIOVs
Definition: options_cfi.py:15
std::unique_ptr< std::map< EventSetupRecordKey, std::map< DataKey, ComponentDescription > > > recordToPreferred_
bool contains(DataKey const &dataKey) const
void insert(EventSetupRecordKey const &, std::unique_ptr< EventSetupRecordProvider >)
PostESModuleRegistration postESModuleRegistrationSignal_
def move(src, dest)
Definition: eostools.py:511
std::vector< std::shared_ptr< EventSetupRecordProvider > > RecordProviders
static HCTypeTag findType(char const *iTypeName)
find a type based on the types name, if not found will return default HCTypeTag
Definition: HCTypeTag.cc:121