CMS 3D CMS Logo

EventSetupsController.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Framework
4 // Class : EventSetupsController
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Chris Jones, W. David Dagenhart
10 // Created: Wed Jan 12 14:30:44 CST 2011
11 //
12 
14 
27 
28 #include <algorithm>
29 #include <iostream>
30 #include <set>
31 
32 namespace edm {
33  namespace eventsetup {
34 
36 
38  for (auto& eventSetupRecordIOVQueue : eventSetupRecordIOVQueues_) {
39  eventSetupRecordIOVQueue->endIOVAsync(iEndTask);
40  }
41  }
42 
43  std::shared_ptr<EventSetupProvider> EventSetupsController::makeProvider(ParameterSet& iPSet,
44  ActivityRegistry* activityRegistry,
45  ParameterSet const* eventSetupPset,
46  unsigned int maxConcurrentIOVs,
47  bool dumpOptions) {
48  // Makes an EventSetupProvider
49  // Also parses the prefer information from ParameterSets and puts
50  // it in a map that is stored in the EventSetupProvider
51  std::shared_ptr<EventSetupProvider> returnValue(
52  makeEventSetupProvider(iPSet, providers_.size(), activityRegistry));
53 
54  // Construct the ESProducers and ESSources
55  // shared_ptrs to them are temporarily stored in this
56  // EventSetupsController and in the EventSetupProvider
57  fillEventSetupProvider(*this, *returnValue, iPSet);
58 
59  numberOfConcurrentIOVs_.readConfigurationParameters(eventSetupPset, maxConcurrentIOVs, dumpOptions);
60 
61  providers_.push_back(returnValue);
62  return returnValue;
63  }
64 
67  for (auto& eventSetupProvider : providers_) {
69  }
70 
71  for (auto& eventSetupProvider : providers_) {
72  eventSetupProvider->finishConfiguration(numberOfConcurrentIOVs_, hasNonconcurrentFinder_);
73  }
74 
75  // When the ESSources and ESProducers were constructed a first pass was
76  // done which attempts to get component sharing between SubProcesses
77  // correct, but in this pass only the configuration of the components
78  // being shared are compared. This is not good enough for ESProducers.
79  // In the following function, all the other components that contribute
80  // to the same record and also the records that record depends on are
81  // also checked. The component sharing is appropriately fixed as necessary.
84 
88  }
89  }
90 
92  IOVSyncValue const& syncValue,
93  WaitingTaskHolder const& taskToStartAfterIOVInit,
94  WaitingTaskList& endIOVWaitingTasks,
95  std::vector<std::shared_ptr<const EventSetupImpl>>& eventSetupImpls) {
97 
98  bool newEventSetupImpl = false;
99  eventSetupImpls.clear();
100  eventSetupImpls.reserve(providers_.size());
101 
102  // Note that unless there are one or more SubProcesses providers_ will only
103  // contain one element.
104 
105  for (auto& eventSetupProvider : providers_) {
106  eventSetupProvider->setAllValidityIntervals(syncValue);
107  }
108 
109  for (auto& eventSetupRecordIOVQueue : eventSetupRecordIOVQueues_) {
110  // For a particular record, if the top level process or any SubProcess requires
111  // starting a new IOV, then we must start a new IOV for all of them. And we
112  // need to know whether this is needed at this point in time. This is
113  // recorded in the EventSetupRecordProviders.
114  eventSetupRecordIOVQueue->setNewIntervalForAnySubProcess();
115  }
116 
117  for (auto& eventSetupProvider : providers_) {
118  // Decides whether we can reuse the existing EventSetupImpl and if we can
119  // returns it. If a new one is needed it will create it, although the pointers
120  // to the EventSetupRecordImpl's will not be set yet in the returned EventSetupImpl
121  // object.
122  eventSetupImpls.push_back(eventSetupProvider->eventSetupForInstance(syncValue, newEventSetupImpl));
123  }
124 
125  for (auto& eventSetupRecordIOVQueue : eventSetupRecordIOVQueues_) {
126  eventSetupRecordIOVQueue->checkForNewIOVs(taskToStartAfterIOVInit, endIOVWaitingTasks, newEventSetupImpl);
127  }
128  }
129 
131  if (hasNonconcurrentFinder()) {
132  for (auto& eventSetupProvider : providers_) {
133  if (eventSetupProvider->doWeNeedToWaitForIOVsToFinish(syncValue)) {
134  return true;
135  }
136  }
137  }
138  return false;
139  }
140 
142  for (auto& eventSetupProvider : providers_) {
143  eventSetupProvider->forceCacheClear();
144  }
145  }
146 
147  std::shared_ptr<DataProxyProvider> EventSetupsController::getESProducerAndRegisterProcess(
148  ParameterSet const& pset, unsigned subProcessIndex) {
149  // Try to find a DataProxyProvider with a matching ParameterSet
150  auto elements = esproducers_.equal_range(pset.id());
151  for (auto it = elements.first; it != elements.second; ++it) {
152  // Untracked parameters must also match, do complete comparison if IDs match
153  if (isTransientEqual(pset, *it->second.pset())) {
154  // Register processes with an exact match
155  it->second.subProcessIndexes().push_back(subProcessIndex);
156  // Return the DataProxyProvider
157  return it->second.provider();
158  }
159  }
160  // Could not find it
161  return std::shared_ptr<DataProxyProvider>();
162  }
163 
165  std::shared_ptr<DataProxyProvider> const& component,
166  unsigned subProcessIndex) {
167  auto newElement =
168  esproducers_.insert(std::pair<ParameterSetID, ESProducerInfo>(pset.id(), ESProducerInfo(&pset, component)));
169  // Register processes with an exact match
170  newElement->second.subProcessIndexes().push_back(subProcessIndex);
171  }
172 
173  std::shared_ptr<EventSetupRecordIntervalFinder> EventSetupsController::getESSourceAndRegisterProcess(
174  ParameterSet const& pset, unsigned subProcessIndex) {
175  // Try to find a EventSetupRecordIntervalFinder with a matching ParameterSet
176  auto elements = essources_.equal_range(pset.id());
177  for (auto it = elements.first; it != elements.second; ++it) {
178  // Untracked parameters must also match, do complete comparison if IDs match
179  if (isTransientEqual(pset, *it->second.pset())) {
180  // Register processes with an exact match
181  it->second.subProcessIndexes().push_back(subProcessIndex);
182  // Return the EventSetupRecordIntervalFinder
183  return it->second.finder();
184  }
185  }
186  // Could not find it
187  return std::shared_ptr<EventSetupRecordIntervalFinder>();
188  }
189 
191  std::shared_ptr<EventSetupRecordIntervalFinder> const& component,
192  unsigned subProcessIndex) {
193  auto newElement =
194  essources_.insert(std::pair<ParameterSetID, ESSourceInfo>(pset.id(), ESSourceInfo(&pset, component)));
195  // Register processes with an exact match
196  newElement->second.subProcessIndexes().push_back(subProcessIndex);
197  }
198 
200  esproducers_.clear();
201  essources_.clear();
202  }
203 
205  unsigned subProcessIndex,
206  unsigned precedingProcessIndex,
207  bool& firstProcessWithThisPSet,
208  bool& precedingHasMatchingPSet) const {
209  auto elements = esproducers_.equal_range(psetID);
210  for (auto it = elements.first; it != elements.second; ++it) {
211  std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
212 
213  auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
214  if (iFound == subProcessIndexes.end()) {
215  continue;
216  }
217 
218  if (iFound == subProcessIndexes.begin()) {
219  firstProcessWithThisPSet = true;
220  precedingHasMatchingPSet = false;
221  } else {
222  auto iFoundPreceding = std::find(subProcessIndexes.begin(), iFound, precedingProcessIndex);
223  if (iFoundPreceding == iFound) {
224  firstProcessWithThisPSet = false;
225  precedingHasMatchingPSet = false;
226  } else {
227  firstProcessWithThisPSet = false;
228  precedingHasMatchingPSet = true;
229  }
230  }
231  return;
232  }
233  throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::lookForMatches\n"
234  << "Subprocess index not found. This should never happen\n"
235  << "Please report this to a Framework Developer\n";
236  }
237 
239  unsigned subProcessIndex,
240  unsigned precedingProcessIndex) const {
241  auto elements = esproducers_.equal_range(psetID);
242  for (auto it = elements.first; it != elements.second; ++it) {
243  std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
244 
245  auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
246  if (iFound == subProcessIndexes.end()) {
247  continue;
248  }
249 
250  auto iFoundPreceding = std::find(subProcessIndexes.begin(), iFound, precedingProcessIndex);
251  if (iFoundPreceding == iFound) {
252  break;
253  } else {
254  return iFoundPreceding == subProcessIndexes.begin();
255  }
256  }
257  throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::isFirstMatch\n"
258  << "Subprocess index not found. This should never happen\n"
259  << "Please report this to a Framework Developer\n";
260  return false;
261  }
262 
264  unsigned subProcessIndex,
265  unsigned precedingProcessIndex) const {
266  auto elements = esproducers_.equal_range(psetID);
267  for (auto it = elements.first; it != elements.second; ++it) {
268  std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
269 
270  auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
271  if (iFound == subProcessIndexes.end()) {
272  continue;
273  }
274 
275  auto iFoundPreceding = std::find(subProcessIndexes.begin(), iFound, precedingProcessIndex);
276  if (iFoundPreceding == iFound) {
277  break;
278  } else {
279  return (++iFoundPreceding) == iFound;
280  }
281  }
282  throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::isLastMatch\n"
283  << "Subprocess index not found. This should never happen\n"
284  << "Please report this to a Framework Developer\n";
285  return false;
286  }
287 
289  unsigned subProcessIndex,
290  unsigned precedingProcessIndex) const {
291  auto elements = essources_.equal_range(psetID);
292  for (auto it = elements.first; it != elements.second; ++it) {
293  std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
294 
295  auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
296  if (iFound == subProcessIndexes.end()) {
297  continue;
298  }
299 
300  auto iFoundPreceding = std::find(subProcessIndexes.begin(), iFound, precedingProcessIndex);
301  if (iFoundPreceding == iFound) {
302  return false;
303  } else {
304  return true;
305  }
306  }
307  throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::lookForMatchingESSource\n"
308  << "Subprocess index not found. This should never happen\n"
309  << "Please report this to a Framework Developer\n";
310  return false;
311  }
312 
314  unsigned subProcessIndex,
315  unsigned precedingProcessIndex) const {
316  auto elements = esproducers_.equal_range(psetID);
317  for (auto it = elements.first; it != elements.second; ++it) {
318  std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
319 
320  auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
321  if (iFound == subProcessIndexes.end()) {
322  continue;
323  }
324 
325  auto iFoundPreceding = std::find(subProcessIndexes.begin(), iFound, precedingProcessIndex);
326  if (iFoundPreceding == iFound) {
327  return false;
328  } else {
329  return true;
330  }
331  }
332  throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::lookForMatchingESSource\n"
333  << "Subprocess index not found. This should never happen\n"
334  << "Please report this to a Framework Developer\n";
335  return false;
336  }
337 
339  unsigned subProcessIndex) const {
340  auto elements = esproducers_.equal_range(psetID);
341  for (auto it = elements.first; it != elements.second; ++it) {
342  std::vector<unsigned> const& subProcessIndexes = it->second.subProcessIndexes();
343 
344  auto iFound = std::find(subProcessIndexes.begin(), subProcessIndexes.end(), subProcessIndex);
345  if (iFound == subProcessIndexes.end()) {
346  continue;
347  }
348  return it->second.pset();
349  }
350  throw edm::Exception(edm::errors::LogicError) << "EventSetupsController::getESProducerPSet\n"
351  << "Subprocess index not found. This should never happen\n"
352  << "Please report this to a Framework Developer\n";
353  return nullptr;
354  }
355 
357  // Loop over SubProcesses, skip the top level process.
358  auto esProvider = providers_.begin();
359  auto const esProviderEnd = providers_.end();
360  if (esProvider != esProviderEnd)
361  ++esProvider;
362  for (; esProvider != esProviderEnd; ++esProvider) {
363  // An element is added to this set for each ESProducer
364  // when we have determined which preceding process
365  // this process can share that ESProducer with or
366  // we have determined that it cannot be shared with
367  // any preceding process.
368  // Note the earliest possible preceding process
369  // will be the one selected if there is more than one.
370  std::set<ParameterSetIDHolder> sharingCheckDone;
371 
372  // This will hold an entry for DataProxy's that are
373  // referenced by an EventSetupRecord in this SubProcess.
374  // But only for DataProxy's that are associated with
375  // an ESProducer (not the ones associated with ESSource's
376  // or EDLooper's)
377  std::map<EventSetupRecordKey, std::vector<ComponentDescription const*>> referencedESProducers;
378 
379  // For each EventSetupProvider from a SubProcess, loop over the
380  // EventSetupProviders from the preceding processes (the first
381  // preceding process will be the top level process and the others
382  // SubProcess's)
383  for (auto precedingESProvider = providers_.begin(); precedingESProvider != esProvider; ++precedingESProvider) {
384  (*esProvider)->checkESProducerSharing(**precedingESProvider, sharingCheckDone, referencedESProducers, *this);
385  }
386 
387  (*esProvider)->resetRecordToProxyPointers();
388  }
389  for (auto& eventSetupProvider : providers_) {
390  eventSetupProvider->clearInitializationData();
391  }
392  }
393 
395  std::set<EventSetupRecordKey> keys;
396  for (auto const& provider : providers_) {
397  provider->fillKeys(keys);
398  }
399 
400  for (auto const& key : keys) {
401  eventSetupRecordIOVQueues_.push_back(
402  std::make_unique<EventSetupRecordIOVQueue>(numberOfConcurrentIOVs_.numberOfConcurrentIOVs(key)));
404  for (auto& provider : providers_) {
405  EventSetupRecordProvider* recProvider = provider->tryToGetRecordProvider(key);
406  if (recProvider) {
407  iovQueue.addRecProvider(recProvider);
408  }
409  }
410  }
411  }
412 
414  oneapi::tbb::task_group& iGroup,
415  eventsetup::EventSetupsController& espController) {
416  FinalWaitingTask waitUntilIOVInitializationCompletes{iGroup};
417 
418  // These do nothing ...
419  WaitingTaskList dummyWaitingTaskList;
420  std::vector<std::shared_ptr<const EventSetupImpl>> dummyEventSetupImpls;
421 
422  {
423  WaitingTaskHolder waitingTaskHolder(iGroup, &waitUntilIOVInitializationCompletes);
424  // Caught exception is propagated via WaitingTaskHolder
425  CMS_SA_ALLOW try {
426  // All the real work is done here.
427  espController.eventSetupForInstanceAsync(
428  syncValue, waitingTaskHolder, dummyWaitingTaskList, dummyEventSetupImpls);
429  dummyWaitingTaskList.doneWaiting(std::exception_ptr{});
430  } catch (...) {
431  dummyWaitingTaskList.doneWaiting(std::exception_ptr{});
432  waitingTaskHolder.doneWaiting(std::current_exception());
433  }
434  }
435  waitUntilIOVInitializationCompletes.wait();
436  }
437  } // namespace eventsetup
438 } // namespace edm
std::shared_ptr< EventSetupRecordIntervalFinder > getESSourceAndRegisterProcess(ParameterSet const &pset, unsigned subProcessIndex)
#define CMS_SA_ALLOW
void addRecProvider(EventSetupRecordProvider *recProvider)
std::vector< propagate_const< std::unique_ptr< EventSetupRecordIOVQueue > > > eventSetupRecordIOVQueues_
void putESSource(ParameterSet const &pset, std::shared_ptr< EventSetupRecordIntervalFinder > const &component, unsigned subProcessIndex)
Definition: Hash.h:43
ParameterSet const * getESProducerPSet(ParameterSetID const &psetID, unsigned subProcessIndex) const
void putESProducer(ParameterSet const &pset, std::shared_ptr< DataProxyProvider > const &component, unsigned subProcessIndex)
bool isMatchingESSource(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
std::multimap< ParameterSetID, ESProducerInfo > esproducers_
std::unique_ptr< EventSetupProvider > makeEventSetupProvider(ParameterSet const &params, unsigned subProcessIndex, ActivityRegistry *activityRegistry)
void lookForMatches(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex, bool &firstProcessWithThisPSet, bool &precedingHasMatchingPSet) const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
void synchronousEventSetupForInstance(IOVSyncValue const &syncValue, oneapi::tbb::task_group &iGroup, eventsetup::EventSetupsController &espController)
bool isLastMatch(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
void doneWaiting(std::exception_ptr iPtr)
Signals that the resource is now available and tasks should be spawned.
std::shared_ptr< DataProxyProvider > getESProducerAndRegisterProcess(ParameterSet const &pset, unsigned subProcessIndex)
void fillEventSetupProvider(EventSetupsController &esController, EventSetupProvider &cp, ParameterSet &params)
void doneWaiting(std::exception_ptr iExcept)
void fillRecordsNotAllowingConcurrentIOVs(EventSetupProvider const &)
std::multimap< ParameterSetID, ESSourceInfo > essources_
bool isMatchingESProducer(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
std::shared_ptr< EventSetupProvider > makeProvider(ParameterSet &, ActivityRegistry *, ParameterSet const *eventSetupPset=nullptr, unsigned int maxConcurrentIOVs=0, bool dumpOptions=false)
void eventSetupForInstanceAsync(IOVSyncValue const &, WaitingTaskHolder const &taskToStartAfterIOVInit, WaitingTaskList &endIOVWaitingTasks, std::vector< std::shared_ptr< const EventSetupImpl >> &)
void readConfigurationParameters(ParameterSet const *eventSetupPset, unsigned int maxConcurrentIOVs, bool dumpOptions)
bool isFirstMatch(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
void endIOVsAsync(edm::WaitingTaskHolder iEndTask)
HLT enums.
bool doWeNeedToWaitForIOVsToFinish(IOVSyncValue const &) const
std::vector< propagate_const< std::shared_ptr< EventSetupProvider > > > providers_
bool isTransientEqual(ParameterSet const &a, ParameterSet const &b)
unsigned int numberOfConcurrentIOVs(EventSetupRecordKey const &, bool printInfoMsg=false) const