CMS 3D CMS Logo

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