CMS 3D CMS Logo

Principal.cc
Go to the documentation of this file.
1 
3 #ifdef __clang__
4 #pragma GCC diagnostic ignored "-Wc++20-extensions"
5 #endif
6 
8 
18 #include "ProductResolvers.h"
24 
26 
27 #include <algorithm>
28 #include <cstring>
29 #include <limits>
30 #include <sstream>
31 #include <stdexcept>
32 #include <typeinfo>
33 #include <atomic>
34 
35 namespace edm {
36 
38 
39  static std::string appendCurrentProcessIfAlias(std::string const& processFromInputTag,
40  std::string const& currentProcess) {
41  if (processFromInputTag == InputTag::kCurrentProcess) {
42  std::string returnValue = processFromInputTag;
43  returnValue += " (";
44  returnValue += currentProcess;
45  returnValue += ")";
46  return returnValue;
47  }
48  return processFromInputTag;
49  }
50 
51  static void throwProductNotFoundException(char const* where, errors::ErrorCodes error, BranchID const& bid) {
52  throw Exception(error, "InvalidID") << "Principal::" << where << ": no product with given branch id: " << bid
53  << "\n";
54  }
55 
56  static std::shared_ptr<cms::Exception> makeNotFoundException(char const* where,
57  KindOfType kindOfType,
58  TypeID const& productType,
59  std::string const& label,
60  std::string const& instance,
61  std::string const& process) {
62  std::shared_ptr<cms::Exception> exception = std::make_shared<Exception>(errors::ProductNotFound);
63  if (kindOfType == PRODUCT_TYPE) {
64  *exception << "Principal::" << where
65  << ": Found zero products matching all criteria\nLooking for type: " << productType << "\n"
66  << "Looking for module label: " << label << "\n"
67  << "Looking for productInstanceName: " << instance << "\n"
68  << (process.empty() ? "" : "Looking for process: ") << process << "\n";
69  } else {
70  *exception << "Principal::" << where
71  << ": Found zero products matching all criteria\nLooking for a container with elements of type: "
72  << productType << "\n"
73  << "Looking for module label: " << label << "\n"
74  << "Looking for productInstanceName: " << instance << "\n"
75  << (process.empty() ? "" : "Looking for process: ") << process << "\n";
76  }
77  return exception;
78  }
79 
80  static void throwAmbiguousException(const char* where,
81  TypeID const& productType,
82  std::string const& label,
83  std::string const& instance,
84  std::string const& process) {
85  cms::Exception exception("AmbiguousProduct");
86  exception << "Principal::" << where
87  << ": More than 1 product matches all criteria\nLooking for type: " << productType << "\n"
88  << "Looking for module label: " << label << "\n"
89  << "Looking for productInstanceName: " << instance << "\n"
90  << (process.empty() ? "" : "Looking for process: ") << process << "\n"
91  << "This can only occur with get function calls using a Handle<View> argument.\n"
92  << "Try a get not using a View or change the instance name of one of the products";
93  throw exception;
94  }
95 
96  namespace {
97  void failedToRegisterConsumes(KindOfType kindOfType,
98  TypeID const& productType,
99  std::string const& moduleLabel,
100  std::string const& productInstanceName,
101  std::string const& processName) {
102  cms::Exception exception("GetByLabelWithoutRegistration");
103  exception << "::getByLabel without corresponding call to consumes or mayConsumes for this module.\n"
104  << (kindOfType == PRODUCT_TYPE ? " type: " : " type: edm::View<") << productType
105  << (kindOfType == PRODUCT_TYPE ? "\n module label: " : ">\n module label: ") << moduleLabel
106  << "\n product instance name: '" << productInstanceName << "'\n process name: '" << processName
107  << "'\n";
108  throw exception;
109  }
110  } // namespace
111 
112  //0 means unset
113  static std::atomic<Principal::CacheIdentifier_t> s_nextIdentifier{1};
115  return s_nextIdentifier.fetch_add(1, std::memory_order_acq_rel);
116  }
117 
118  Principal::Principal(std::shared_ptr<ProductRegistry const> reg,
119  std::shared_ptr<ProductResolverIndexHelper const> productLookup,
120  ProcessConfiguration const& pc,
121  BranchType bt,
122  HistoryAppender* historyAppender,
123  bool isForPrimaryProcess)
124  : EDProductGetter(),
125  processHistoryPtr_(),
126  processHistoryID_(),
127  processHistoryIDBeforeConfig_(),
128  processConfiguration_(&pc),
129  productResolvers_(),
130  preg_(reg),
131  productLookup_(productLookup),
132  lookupProcessOrder_(productLookup->lookupProcessNames().size(), 0),
133  reader_(),
134  branchType_(bt),
135  historyAppender_(historyAppender),
136  cacheIdentifier_(nextIdentifier()) {
137  productResolvers_.resize(reg->getNextIndexValue(bt));
138  //Now that these have been set, we can create the list of Branches we need.
139  std::string const source("source");
140  ProductRegistry::ProductList const& prodsList = reg->productList();
141  // The constructor of an alias product holder takes as an argument the product holder for which it is an alias.
142  // So, the non-alias product holders must be created first.
143  // Therefore, on this first pass, skip current EDAliases.
144  bool hasAliases = false;
145  bool hasSwitchAliases = false;
146  for (auto const& prod : prodsList) {
147  BranchDescription const& bd = prod.second;
148  if (bd.branchType() == branchType_) {
149  if (isForPrimaryProcess or bd.processName() == pc.processName()) {
150  if (bd.isAlias()) {
151  hasAliases = true;
152  } else if (bd.isSwitchAlias()) {
153  hasSwitchAliases = true;
154  } else {
155  auto cbd = std::make_shared<BranchDescription const>(bd);
156  if (bd.produced()) {
157  if (bd.moduleLabel() == source) {
158  addSourceProduct(cbd);
159  } else if (bd.onDemand()) {
161  if (bd.isTransform()) {
162  addTransformProduct(cbd);
163  } else {
165  }
166  } else {
167  addScheduledProduct(cbd);
168  }
169  } else {
170  if (bd.onDemand()) {
172  } else {
174  }
175  }
176  }
177  } else {
178  //We are in a SubProcess and this branch is from the parent
179  auto cbd = std::make_shared<BranchDescription const>(bd);
181  }
182  }
183  }
184  // Now process any EDAliases
185  if (hasAliases) {
186  for (auto const& prod : prodsList) {
187  BranchDescription const& bd = prod.second;
188  if (bd.isAlias() && bd.branchType() == branchType_) {
189  addAliasedProduct(std::make_shared<BranchDescription const>(bd));
190  }
191  }
192  }
193  // Finally process any SwitchProducer aliases
194  if (hasSwitchAliases) {
195  for (auto const& prod : prodsList) {
196  BranchDescription const& bd = prod.second;
197  if (bd.isSwitchAlias() && bd.branchType() == branchType_) {
199  auto cbd = std::make_shared<BranchDescription const>(bd);
200  // Need different implementation for SwitchProducers not
201  // in any Path (onDemand) and for those in a Path in order
202  // to prevent the switch-aliased-for EDProducers from
203  // being run when the SwitchProducer is in a Path after a
204  // failing EDFilter.
205  if (bd.onDemand()) {
207  } else {
209  }
210  }
211  }
212  }
213 
214  // Now create the ProductResolvers that search in reverse process
215  // order and are used for queries where the process name is the
216  // empty string
217  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
218  std::vector<ProductResolverIndex> matchingHolders(lookupProcessNames.size(), ProductResolverIndexInvalid);
219  std::vector<bool> ambiguous(lookupProcessNames.size(), false);
220  unsigned int beginElements = productLookup_->beginElements();
221  std::vector<TypeID> const& sortedTypeIDs = productLookup_->sortedTypeIDs();
222  std::vector<ProductResolverIndexHelper::Range> const& ranges = productLookup_->ranges();
223  std::vector<ProductResolverIndexHelper::IndexAndNames> const& indexAndNames = productLookup_->indexAndNames();
224  std::vector<char> const& processNamesCharArray = productLookup_->processNames();
225 
226  unsigned int numberOfMatches = 0;
228  if (!sortedTypeIDs.empty()) {
229  ProductResolverIndex productResolverIndex = ProductResolverIndexInvalid;
230  for (unsigned int k = 0, kEnd = sortedTypeIDs.size(); k < kEnd; ++k) {
232  for (unsigned int i = range.begin(); i < range.end(); ++i) {
233  ProductResolverIndexHelper::IndexAndNames const& product = indexAndNames.at(i);
234  if (product.startInProcessNames() == 0) {
235  if (productResolverIndex != ProductResolverIndexInvalid) {
236  if ((numberOfMatches == 1) and (lastMatchIndex != ProductResolverIndexAmbiguous)) {
237  //only one choice so use a special resolver
238  productResolvers_.at(productResolverIndex) =
239  std::make_shared<SingleChoiceNoProcessProductResolver>(lastMatchIndex);
240  } else {
241  bool productMadeAtEnd = false;
242  //Need to know if the product from this processes is added at end of transition
243  for (unsigned int j = 0; j < matchingHolders.size(); ++j) {
244  if ((not ambiguous[j]) and ProductResolverIndexInvalid != matchingHolders[j] and
245  productResolvers_[matchingHolders[j]]->branchDescription().availableOnlyAtEndTransition()) {
246  productMadeAtEnd = true;
247  break;
248  }
249  }
250  std::shared_ptr<ProductResolverBase> newHolder =
251  std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous, productMadeAtEnd);
252  productResolvers_.at(productResolverIndex) = newHolder;
253  }
254  matchingHolders.assign(lookupProcessNames.size(), ProductResolverIndexInvalid);
255  ambiguous.assign(lookupProcessNames.size(), false);
256  numberOfMatches = 0;
257  lastMatchIndex = ProductResolverIndexInvalid;
258  }
259  productResolverIndex = product.index();
260  } else {
261  std::string process(&processNamesCharArray.at(product.startInProcessNames()));
262  auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), process);
263  assert(iter != lookupProcessNames.end());
264  ProductResolverIndex iMatchingIndex = product.index();
265  lastMatchIndex = iMatchingIndex;
266  assert(iMatchingIndex != ProductResolverIndexInvalid);
267  ++numberOfMatches;
268  if (iMatchingIndex == ProductResolverIndexAmbiguous) {
269  assert(k >= beginElements);
270  ambiguous.at(iter - lookupProcessNames.begin()) = true;
271  } else {
272  matchingHolders.at(iter - lookupProcessNames.begin()) = iMatchingIndex;
273  }
274  }
275  }
276  }
277  //Need to know if the product from this processes is added at end of transition
278  if ((numberOfMatches == 1) and (lastMatchIndex != ProductResolverIndexAmbiguous)) {
279  //only one choice so use a special resolver
280  productResolvers_.at(productResolverIndex) =
281  std::make_shared<SingleChoiceNoProcessProductResolver>(lastMatchIndex);
282  } else {
283  bool productMadeAtEnd = false;
284  for (unsigned int i = 0; i < matchingHolders.size(); ++i) {
285  if ((not ambiguous[i]) and ProductResolverIndexInvalid != matchingHolders[i] and
286  productResolvers_[matchingHolders[i]]->branchDescription().availableOnlyAtEndTransition()) {
287  productMadeAtEnd = true;
288  break;
289  }
290  }
291  std::shared_ptr<ProductResolverBase> newHolder =
292  std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous, productMadeAtEnd);
293  productResolvers_.at(productResolverIndex) = newHolder;
294  }
295  }
296  }
297 
299 
300  // Number of products in the Principal.
301  // For products in an input file and not yet read in due to delayed read,
302  // this routine assumes a real product is there.
303  size_t Principal::size() const {
304  size_t size = 0U;
305  for (auto const& prod : *this) {
306  if (prod->singleProduct() && // Not a NoProcessProductResolver
307  !prod->productUnavailable() && !prod->unscheduledWasNotRun() && !prod->branchDescription().dropped()) {
308  ++size;
309  }
310  }
311  return size;
312  }
313 
314  // adjust provenance for input products after new input file has been merged
316  ProductRegistry::ProductList const& prodsList = reg.productList();
317  for (auto const& prod : prodsList) {
318  BranchDescription const& bd = prod.second;
319  if (!bd.produced() && (bd.branchType() == branchType_)) {
320  auto cbd = std::make_shared<BranchDescription const>(bd);
321  auto phb = getExistingProduct(cbd->branchID());
322  if (phb == nullptr || phb->branchDescription().branchName() != cbd->branchName()) {
323  return false;
324  }
325  phb->resetBranchDescription(cbd);
326  }
327  }
328  return true;
329  }
330 
331  void Principal::addScheduledProduct(std::shared_ptr<BranchDescription const> bd) {
332  auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
334  }
335 
336  void Principal::addSourceProduct(std::shared_ptr<BranchDescription const> bd) {
337  auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
339  }
340 
341  void Principal::addDelayedReaderInputProduct(std::shared_ptr<BranchDescription const> bd) {
342  addProductOrThrow(std::make_unique<DelayedReaderInputProductResolver>(std::move(bd)));
343  }
344 
345  void Principal::addPutOnReadInputProduct(std::shared_ptr<BranchDescription const> bd) {
346  addProductOrThrow(std::make_unique<PutOnReadInputProductResolver>(std::move(bd)));
347  }
348 
349  void Principal::addUnscheduledProduct(std::shared_ptr<BranchDescription const> bd) {
350  addProductOrThrow(std::make_unique<UnscheduledProductResolver>(std::move(bd)));
351  }
352 
353  void Principal::addTransformProduct(std::shared_ptr<BranchDescription const> bd) {
354  addProductOrThrow(std::make_unique<TransformingProductResolver>(std::move(bd)));
355  }
356 
357  void Principal::addAliasedProduct(std::shared_ptr<BranchDescription const> bd) {
358  ProductResolverIndex index = preg_->indexFrom(bd->originalBranchID());
360 
361  addProductOrThrow(std::make_unique<AliasProductResolver>(
362  std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
363  }
364 
365  void Principal::addSwitchProducerProduct(std::shared_ptr<BranchDescription const> bd) {
366  ProductResolverIndex index = preg_->indexFrom(bd->switchAliasForBranchID());
368 
369  addProductOrThrow(std::make_unique<SwitchProducerProductResolver>(
370  std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
371  }
372 
373  void Principal::addSwitchAliasProduct(std::shared_ptr<BranchDescription const> bd) {
374  ProductResolverIndex index = preg_->indexFrom(bd->switchAliasForBranchID());
376 
377  addProductOrThrow(std::make_unique<SwitchAliasProductResolver>(
378  std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
379  }
380 
381  void Principal::addParentProcessProduct(std::shared_ptr<BranchDescription const> bd) {
382  addProductOrThrow(std::make_unique<ParentProcessProductResolver>(std::move(bd)));
383  }
384 
385  // "Zero" the principal so it can be reused for another Event.
387  //We do not clear the product history information
388  // because it rarely changes and recalculating takes
389  // time.
390  reader_ = nullptr;
391  for (auto& prod : *this) {
392  prod->resetProductData();
393  }
394  }
395 
396  void Principal::deleteProduct(BranchID const& id) const {
397  auto phb = getExistingProduct(id);
398  assert(nullptr != phb);
399  phb->unsafe_deleteProduct();
400  }
401 
403  applyToResolvers([&iConfigure](ProductResolverBase* iResolver) { iResolver->setupUnscheduled(iConfigure); });
404  }
405 
407  //increment identifier here since clearPrincipal isn't called for Run/Lumi
409  if (reader) {
410  reader_ = reader;
411  }
412  }
413 
414  // Set the principal for the Event, Lumi, or Run.
416  ProcessHistory const* processHistory,
419 
420  if (historyAppender_ && productRegistry().anyProductProduced()) {
425  }
426  } else {
427  std::shared_ptr<ProcessHistory const> inputProcessHistory;
429  if (hist.isValid()) {
430  //does not own the pointer
431  auto noDel = [](void const*) {};
432  inputProcessHistory = std::shared_ptr<ProcessHistory const>(processHistory, noDel);
433  if (inputProcessHistory.get() == nullptr) {
434  throw Exception(errors::LogicError) << "Principal::fillPrincipal\n"
435  << "Input ProcessHistory not found in registry\n"
436  << "Contact a Framework developer\n";
437  }
438  } else {
439  //Since this is static we don't want it deleted
440  inputProcessHistory = std::shared_ptr<ProcessHistory const>(&s_emptyProcessHistory, [](void const*) {});
441  //no need to do any ordering since it is empty
443  }
445  processHistoryPtr_ = inputProcessHistory;
447  }
448  }
449 
451  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
452  lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
453  unsigned int k = 0;
454 
455  // We loop over processes in reverse order of the ProcessHistory.
456  // If any entries in the product lookup tables are associated with
457  // the process we add it to the vector of processes in the order
458  // the lookup should be performed. There is one exception though,
459  // We start with the current process even if it is not in the ProcessHistory.
460  // The current process might be needed but not be in the process
461  // history if all the products produced in the current process are
462  // transient.
463  {
464  auto nameIterCurrentProcess =
465  std::find(lookupProcessNames.begin(), lookupProcessNames.end(), processConfiguration_->processName());
466  if (nameIterCurrentProcess != lookupProcessNames.end()) {
467  lookupProcessOrder_.at(k) = nameIterCurrentProcess - lookupProcessNames.begin();
468  ++k;
469  }
470  }
471 
472  // We just looked for the current process so skip it if
473  // it is in the ProcessHistory.
474  auto iter = processHistoryPtr_->rbegin();
475  if (iter->processName() == processConfiguration_->processName()) {
476  ++iter;
477  }
478 
479  for (auto iEnd = processHistoryPtr_->rend(); iter != iEnd; ++iter) {
480  auto nameIter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), iter->processName());
481  if (nameIter == lookupProcessNames.end()) {
482  continue;
483  }
484  lookupProcessOrder_.at(k) = nameIter - lookupProcessNames.begin();
485  ++k;
486  }
488  }
489  }
490 
491  // Set the principal for the ProcessBlock
492  void Principal::fillPrincipal(std::string const& processNameOfBlock, DelayedReader* reader) {
494 
495  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
496  lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
497  if (!lookupProcessOrder_.empty()) {
498  auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), processNameOfBlock);
499  if (iter != lookupProcessNames.end()) {
500  lookupProcessOrder_[0] = iter - lookupProcessNames.begin();
501  }
502  }
503  }
504 
506  return const_cast<ProductResolverBase*>(const_cast<const Principal*>(this)->getExistingProduct(branchID));
507  }
508 
510  ProductResolverIndex index = preg_->indexFrom(branchID);
512  return productResolvers_.at(index).get();
513  }
514 
516  auto phb = getExistingProduct(productResolver.branchDescription().branchID());
517  if (nullptr != phb && BranchKey(productResolver.branchDescription()) != BranchKey(phb->branchDescription())) {
518  BranchDescription const& newProduct = phb->branchDescription();
519  BranchDescription const& existing = productResolver.branchDescription();
520  if (newProduct.branchName() != existing.branchName() && newProduct.branchID() == existing.branchID()) {
521  throw cms::Exception("HashCollision")
522  << "Principal::getExistingProduct\n"
523  << " Branch " << newProduct.branchName() << " has same branch ID as branch " << existing.branchName()
524  << "\n"
525  << "Workaround: change process name or product instance name of " << newProduct.branchName() << "\n";
526  } else {
527  assert(nullptr == phb || BranchKey(productResolver.branchDescription()) == BranchKey(phb->branchDescription()));
528  }
529  }
530  return phb;
531  }
532 
533  void Principal::addProduct_(std::unique_ptr<ProductResolverBase> productResolver) {
534  BranchDescription const& bd = productResolver->branchDescription();
535  assert(!bd.className().empty());
536  assert(!bd.friendlyClassName().empty());
537  assert(!bd.moduleLabel().empty());
538  assert(!bd.processName().empty());
539  SharedProductPtr phb(productResolver.release());
540 
541  ProductResolverIndex index = preg_->indexFrom(bd.branchID());
543  productResolvers_[index] = phb;
544  }
545 
546  void Principal::addProductOrThrow(std::unique_ptr<ProductResolverBase> productResolver) {
547  ProductResolverBase const* phb = getExistingProduct(*productResolver);
548  if (phb != nullptr) {
549  BranchDescription const& bd = productResolver->branchDescription();
550  throw Exception(errors::InsertFailure, "AlreadyPresent")
551  << "addProductOrThrow: Problem found while adding product, "
552  << "product already exists for (" << bd.friendlyClassName() << "," << bd.moduleLabel() << ","
553  << bd.productInstanceName() << "," << bd.processName() << ")\n";
554  }
555  addProduct_(std::move(productResolver));
556  }
557 
559  ProductResolverIndex index = preg_->indexFrom(bid);
561  return ConstProductResolverPtr();
562  }
564  }
565 
568  return phb;
569  }
570 
571  unsigned int Principal::processBlockIndex(std::string const&) const {
572  throw Exception(errors::LogicError) << "Principal::processBlockIndex not implemented for this type of Principal";
573  }
574 
576  TypeID const& typeID,
577  InputTag const& inputTag,
578  EDConsumerBase const* consumer,
580  ModuleCallingContext const* mcc) const {
581  // Not implemented for ProcessBlocks, it might work though, not tested
582  // The other getByLabel function is used for ProcessBlocks by TestProcessor
584 
585  ProductData const* result = findProductByLabel(kindOfType, typeID, inputTag, consumer, sra, mcc);
586  if (result == nullptr) {
587  return BasicHandle(makeHandleExceptionFactory([=, this]() -> std::shared_ptr<cms::Exception> {
588  return makeNotFoundException(
589  "getByLabel",
590  kindOfType,
591  typeID,
592  inputTag.label(),
593  inputTag.instance(),
595  }));
596  }
597  return BasicHandle(result->wrapper(), &(result->provenance()));
598  }
599 
601  TypeID const& typeID,
602  std::string const& label,
603  std::string const& instance,
604  std::string const& process,
605  EDConsumerBase const* consumer,
607  ModuleCallingContext const* mcc) const {
608  ProductData const* result = findProductByLabel(kindOfType, typeID, label, instance, process, consumer, sra, mcc);
609  if (result == nullptr) {
610  return BasicHandle(makeHandleExceptionFactory([=]() -> std::shared_ptr<cms::Exception> {
611  return makeNotFoundException("getByLabel", kindOfType, typeID, label, instance, process);
612  }));
613  }
614  return BasicHandle(result->wrapper(), &(result->provenance()));
615  }
616 
618  TypeID const&,
620  bool skipCurrentProcess,
621  bool& ambiguous,
623  ModuleCallingContext const* mcc) const {
625  auto& productResolver = productResolvers_[index];
626  assert(nullptr != productResolver.get());
627  auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
628  if (resolution.isAmbiguous()) {
629  ambiguous = true;
630  //The caller is looking explicitly for this case
631  // and uses the extra data at the caller to setup the exception
632  return BasicHandle::makeInvalid();
633  }
634  auto productData = resolution.data();
635  if (productData == nullptr) {
636  //The caller is looking explicitly for this case
637  // and uses the extra data at the caller to setup the exception
638  return BasicHandle::makeInvalid();
639  }
640  return BasicHandle(productData->wrapper(), &(productData->provenance()));
641  }
642 
645  bool skipCurrentProcess,
646  ServiceToken const& token,
647  ModuleCallingContext const* mcc) const {
648  auto const& productResolver = productResolvers_.at(index);
649  assert(nullptr != productResolver.get());
650  productResolver->prefetchAsync(task, *this, skipCurrentProcess, token, nullptr, mcc);
651  }
652 
654  TypeID const& typeID,
655  InputTag const& inputTag,
656  EDConsumerBase const* consumer,
658  ModuleCallingContext const* mcc) const {
659  bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
660 
662 
664  char const* processName = inputTag.process().c_str();
665  if (skipCurrentProcess) {
666  processName = "\0";
667  } else if (inputTag.process() == InputTag::kCurrentProcess) {
669  }
670 
671  index =
672  productLookup().index(kindOfType, typeID, inputTag.label().c_str(), inputTag.instance().c_str(), processName);
673 
675  throwAmbiguousException("findProductByLabel",
676  typeID,
677  inputTag.label(),
678  inputTag.instance(),
680  } else if (index == ProductResolverIndexInvalid) {
681  // can occur because of missing consumes if nothing else in the process consumes the product
682  for (auto const& item : preg_->productList()) {
683  auto const& bd = item.second;
684  if (bd.present() and bd.unwrappedTypeID() == typeID and bd.moduleLabel() == inputTag.label() and
685  bd.productInstanceName() == inputTag.instance()) {
686  bool const inCurrentProcess = bd.processName() == processConfiguration_->processName();
687  if (inputTag.process().empty() or bd.processName() == inputTag.process() or
688  (skipCurrentProcess and not inCurrentProcess) or
689  (inputTag.process() == InputTag::kCurrentProcess and inCurrentProcess)) {
690  failedToRegisterConsumes(
691  kindOfType,
692  typeID,
693  inputTag.label(),
694  inputTag.instance(),
696  }
697  }
698  }
699  return nullptr;
700  }
701  inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
702  }
703  if (UNLIKELY(consumer and (not consumer->registeredToConsume(index, skipCurrentProcess, branchType())))) {
704  failedToRegisterConsumes(kindOfType,
705  typeID,
706  inputTag.label(),
707  inputTag.instance(),
709  }
710 
711  auto const& productResolver = productResolvers_[index];
712 
713  auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
714  if (resolution.isAmbiguous()) {
715  throwAmbiguousException("findProductByLabel",
716  typeID,
717  inputTag.label(),
718  inputTag.instance(),
720  }
721  return resolution.data();
722  }
723 
725  TypeID const& typeID,
726  std::string const& label,
727  std::string const& instance,
728  std::string const& process,
729  EDConsumerBase const* consumer,
731  ModuleCallingContext const* mcc) const {
733  productLookup().index(kindOfType, typeID, label.c_str(), instance.c_str(), process.c_str());
734 
736  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
737  } else if (index == ProductResolverIndexInvalid) {
738  // can occur because of missing consumes if nothing else in the process consumes the product
739  for (auto const& item : preg_->productList()) {
740  auto const& bd = item.second;
741  if (bd.present() and bd.unwrappedTypeID() == typeID and bd.moduleLabel() == label and
742  bd.productInstanceName() == instance) {
743  if (process.empty() or bd.processName() == process) {
744  failedToRegisterConsumes(kindOfType, typeID, label, instance, process);
745  }
746  }
747  }
748  return nullptr;
749  }
750 
751  if (UNLIKELY(consumer and (not consumer->registeredToConsume(index, false, branchType())))) {
752  failedToRegisterConsumes(kindOfType, typeID, label, instance, process);
753  }
754 
755  auto const& productResolver = productResolvers_[index];
756 
757  auto resolution = productResolver->resolveProduct(*this, false, sra, mcc);
758  if (resolution.isAmbiguous()) {
759  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
760  }
761  return resolution.data();
762  }
763 
765  InputTag const& tag,
766  ModuleCallingContext const* mcc) const {
767  // Not implemented for ProcessBlocks
769 
770  ProductData const* productData = findProductByLabel(PRODUCT_TYPE, typeID, tag, nullptr, nullptr, mcc);
771  return productData;
772  }
773 
774  Provenance const& Principal::getProvenance(BranchID const& bid) const {
776  if (phb == nullptr) {
778  }
779 
780  if (phb->unscheduledWasNotRun()) {
782  << "Requesting provenance from unrun EDProducer. The requested branch ID was: " << bid;
783  }
784  return *phb->provenance();
785  }
786 
789  if (phb == nullptr) {
790  throwProductNotFoundException("getStableProvenance", errors::ProductNotFound, bid);
791  }
792  //NOTE: in all implementations, this never returns a nullptr
793  return *phb->stableProvenance();
794  }
795 
796  // This one is mostly for test printout purposes
797  // No attempt to trigger on demand execution
798  // Skips provenance when the EDProduct is not there
799  void Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
800  provenances.clear();
801  for (auto const& productResolver : *this) {
802  if (productResolver->singleProduct() && productResolver->provenanceAvailable() &&
803  !productResolver->branchDescription().isAnyAlias()) {
804  // We do not attempt to get the event/lumi/run status from the provenance,
805  // because the per event provenance may have been dropped.
806  if (productResolver->provenance()->branchDescription().present()) {
807  provenances.push_back(productResolver->provenance());
808  }
809  }
810  }
811  }
812 
813  // This one is also mostly for test printout purposes
814  // No attempt to trigger on demand execution
815  // Skips provenance for dropped branches.
816  void Principal::getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const {
817  provenances.clear();
818  for (auto const& productResolver : *this) {
819  if (productResolver->singleProduct() && !productResolver->branchDescription().isAnyAlias()) {
820  if (productResolver->stableProvenance()->branchDescription().present()) {
821  provenances.push_back(productResolver->stableProvenance());
822  }
823  }
824  }
825  }
826 
827  void Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
828  for (auto& prod : bids) {
829  ProductResolverIndex index = preg_->indexFrom(prod);
831  ProductResolverIndex indexO = other.preg_->indexFrom(prod);
833  get_underlying_safe(productResolvers_[index]).swap(get_underlying_safe(other.productResolvers_[indexO]));
834  }
835  reader_->mergeReaders(other.reader());
836  }
837 
838  WrapperBase const* Principal::getIt(ProductID const&) const {
839  assert(false);
840  return nullptr;
841  }
842 
843  std::optional<std::tuple<WrapperBase const*, unsigned int>> Principal::getThinnedProduct(ProductID const&,
844  unsigned int) const {
845  assert(false);
846  return std::nullopt;
847  }
848 
850  std::vector<WrapperBase const*>&,
851  std::vector<unsigned int>&) const {
852  assert(false);
853  }
854 
856  assert(false);
857  return std::monostate{};
858  }
859 
860  void Principal::put_(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* phb) const {
861  dynamic_cast<ProductPutterBase const*>(phb)->putProduct(std::move(prod));
862  }
863 
864  void Principal::put_(BranchDescription const& bd, std::unique_ptr<WrapperBase> edp) const {
865  if (edp.get() == nullptr) {
866  throw edm::Exception(edm::errors::InsertFailure, "Null Pointer")
867  << "put: Cannot put because unique_ptr to product is null."
868  << "\n";
869  }
870  auto phb = getExistingProduct(bd.branchID());
871  assert(phb);
872  // ProductResolver assumes ownership
873  put_(std::move(edp), phb);
874  }
875 
877  if (preg_->getNextIndexValue(branchType_) != productResolvers_.size()) {
878  bool changed = false;
879  productResolvers_.resize(preg_->getNextIndexValue(branchType_));
880  for (auto const& prod : preg_->productList()) {
881  BranchDescription const& bd = prod.second;
882  if (bd.branchType() == branchType_) {
883  ProductResolverIndex index = preg_->indexFrom(bd.branchID());
885  if (!productResolvers_[index]) {
886  // no product holder. Must add one. The new entry must be an input product holder.
887  assert(!bd.produced());
888  auto cbd = std::make_shared<BranchDescription const>(bd);
889  if (bd.onDemand()) {
891  } else {
893  }
894  changed = true;
895  }
896  }
897  }
898  if (changed) {
899  changedIndexes_();
900  }
901  }
902  assert(preg_->getNextIndexValue(branchType_) == productResolvers_.size());
903  }
904 
906  if (not reader()) {
907  return;
908  }
909 
910  for (auto& prod : *this) {
911  prod->retrieveAndMerge(*this, mergeableRunProductMetadata);
912  }
913  }
914 } // namespace edm
std::optional< std::tuple< WrapperBase const *, unsigned int > > getThinnedProduct(ProductID const &, unsigned int) const override
Definition: Principal.cc:843
BranchType branchType_
Definition: Principal.h:282
void fillPrincipal(DelayedReader *reader)
Definition: Principal.cc:406
static ProcessHistory const s_emptyProcessHistory
Definition: Principal.cc:37
void clearPrincipal()
Definition: Principal.cc:386
DelayedReader * reader_
Definition: Principal.h:280
void getAllProvenance(std::vector< Provenance const *> &provenances) const
Definition: Principal.cc:799
ProcessHistoryID processHistoryIDBeforeConfig_
Definition: Principal.h:263
void setupUnscheduled(UnscheduledConfigurator const &)
Definition: Principal.cc:402
unsigned int ProductResolverIndex
BasicHandle getByToken(KindOfType kindOfType, TypeID const &typeID, ProductResolverIndex index, bool skipCurrentProcess, bool &ambiguous, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:617
static std::string const source("source")
ProductResolverCollection productResolvers_
Definition: Principal.h:268
std::variant< unsigned int, detail::GetThinnedKeyFromExceptionFactory, std::monostate > OptionalThinnedKey
std::shared_ptr< ProcessHistory const > processHistoryPtr_
Definition: Principal.h:260
ProductList const & productList() const
BranchID const & branchID() const
static PFTauRenderPlugin instance
ProductRegistry const & productRegistry() const
Definition: Principal.h:140
std::shared_ptr< ProductResolverBase > SharedProductPtr
Definition: Principal.h:66
void addProduct_(std::unique_ptr< ProductResolverBase > phb)
Definition: Principal.cc:533
BranchType const & branchType() const
static std::atomic< Principal::CacheIdentifier_t > s_nextIdentifier
Definition: Principal.cc:113
StableProvenance const & getStableProvenance(BranchID const &bid) const
Definition: Principal.cc:787
std::map< BranchKey, BranchDescription > ProductList
static Principal::CacheIdentifier_t nextIdentifier()
Definition: Principal.cc:114
ProcessHistoryID processHistoryID_
Definition: Principal.h:262
void mergeReaders(DelayedReader *other)
Definition: DelayedReader.h:36
ProductResolverBase * getExistingProduct(BranchID const &branchID)
Definition: Principal.cc:505
virtual void setupUnscheduled(UnscheduledConfigurator const &)
void getThinnedProducts(ProductID const &, std::vector< WrapperBase const *> &, std::vector< unsigned int > &) const override
Definition: Principal.cc:849
void applyToResolvers(F iFunc)
Definition: Principal.h:211
~Principal() override
Definition: Principal.cc:298
std::string const & processName() const
void prefetchAsync(WaitingTaskHolder waitTask, ProductResolverIndex index, bool skipCurrentProcess, ServiceToken const &token, ModuleCallingContext const *mcc) const
Definition: Principal.cc:643
size_t size() const
Definition: Principal.cc:303
reader
Definition: DQM.py:105
constexpr std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
assert(be >=bs)
edm::propagate_const< HistoryAppender * > historyAppender_
Definition: Principal.h:287
Principal(std::shared_ptr< ProductRegistry const > reg, std::shared_ptr< ProductResolverIndexHelper const > productLookup, ProcessConfiguration const &pc, BranchType bt, HistoryAppender *historyAppender, bool isForPrimaryProcess=true)
Definition: Principal.cc:118
std::string const & friendlyClassName() const
void addUnscheduledProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:349
BranchType
Definition: BranchType.h:11
ProductData const * findProductByLabel(KindOfType kindOfType, TypeID const &typeID, InputTag const &inputTag, EDConsumerBase const *consumer, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:653
void addAliasedProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:357
static void throwAmbiguousException(const char *where, TypeID const &productType, std::string const &label, std::string const &instance, std::string const &process)
Definition: Principal.cc:80
std::vector< unsigned int > lookupProcessOrder_
Definition: Principal.h:275
virtual unsigned int processBlockIndex(std::string const &processName) const
Definition: Principal.cc:571
char const * label
WrapperBase const * getIt(ProductID const &) const override
Definition: Principal.cc:838
std::shared_ptr< ProductResolverIndexHelper const > productLookup_
Definition: Principal.h:273
std::string const & className() const
std::string const & branchName() const
void addProductOrThrow(std::unique_ptr< ProductResolverBase > phb)
Definition: Principal.cc:546
std::shared_ptr< ProductRegistry const > preg_
Definition: Principal.h:272
CacheIdentifier_t cacheIdentifier_
Definition: Principal.h:289
ProductResolverIndex index(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process=nullptr) const
std::string const & productInstanceName() const
std::shared_ptr< HandleExceptionFactory > makeHandleExceptionFactory(T &&iFunctor)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
BasicHandle getByLabel(KindOfType kindOfType, TypeID const &typeID, InputTag const &inputTag, EDConsumerBase const *consumes, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:575
void getAllStableProvenance(std::vector< StableProvenance const *> &provenances) const
Definition: Principal.cc:816
ProcessHistoryID orderProcessHistoryID_
Definition: Principal.h:276
virtual void changedIndexes_()
Definition: Principal.h:219
static const std::string kCurrentProcess
Definition: InputTag.h:54
void addSourceProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:336
void addPutOnReadInputProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:345
void deleteProduct(BranchID const &id) const
Definition: Principal.cc:396
void addDelayedReaderInputProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:341
string ranges
Definition: diffTwoXMLs.py:79
void put_(BranchDescription const &bd, std::unique_ptr< WrapperBase > edp) const
Definition: Principal.cc:864
void addParentProcessProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:381
ProductData const * findProductByTag(TypeID const &typeID, InputTag const &tag, ModuleCallingContext const *mcc) const
Definition: Principal.cc:764
void addScheduledProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:331
static BasicHandle makeInvalid()
Definition: BasicHandle.h:93
ProcessHistory const & processHistory() const
Definition: Principal.h:134
void addSwitchProducerProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:365
BranchDescription const & branchDescription() const
static std::shared_ptr< cms::Exception > makeNotFoundException(char const *where, KindOfType kindOfType, TypeID const &productType, std::string const &label, std::string const &instance, std::string const &process)
Definition: Principal.cc:56
ProductResolverBase const * ConstProductResolverPtr
Definition: Principal.h:62
std::string const & processName() const
HLT enums.
void readAllFromSourceAndMergeImmediately(MergeableRunProductMetadata const *mergeableRunProductMetadata=nullptr)
Definition: Principal.cc:905
unsigned long CacheIdentifier_t
Definition: Principal.h:178
bool adjustToNewProductRegistry(ProductRegistry const &reg)
Definition: Principal.cc:315
Provenance const & getProvenance(BranchID const &bid) const
Definition: Principal.cc:774
void adjustIndexesAfterProductRegistryAddition()
Definition: Principal.cc:876
static void throwProductNotFoundException(char const *where, errors::ErrorCodes error, BranchID const &bid)
Definition: Principal.cc:51
ProductResolverIndexHelper const & productLookup() const
Definition: Principal.h:142
#define UNLIKELY(x)
Definition: Likely.h:21
void addTransformProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:353
static std::string appendCurrentProcessIfAlias(std::string const &processFromInputTag, std::string const &currentProcess)
Definition: Principal.cc:39
OptionalThinnedKey getThinnedKeyFrom(ProductID const &parent, unsigned int key, ProductID const &thinned) const override
Definition: Principal.cc:855
void recombine(Principal &other, std::vector< BranchID > const &bids)
Definition: Principal.cc:827
ConstProductResolverPtr getProductResolverByIndex(ProductResolverIndex const &oid) const
Definition: Principal.cc:566
std::string const & moduleLabel() const
void resetBranchDescription(std::shared_ptr< BranchDescription const > bd)
ProcessConfiguration const * processConfiguration_
Definition: Principal.h:265
void addSwitchAliasProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:373
def move(src, dest)
Definition: eostools.py:511
DelayedReader * reader() const
Definition: Principal.h:181
BranchType const & branchType() const
Definition: Principal.h:175
ConstProductResolverPtr getProductResolver(BranchID const &oid) const
Definition: Principal.cc:558