CMS 3D CMS Logo

Principal.cc
Go to the documentation of this file.
1 
5 
15 #include "ProductResolvers.h"
20 
22 
23 #include <algorithm>
24 #include <cstring>
25 #include <limits>
26 #include <sstream>
27 #include <stdexcept>
28 #include <typeinfo>
29 #include <atomic>
30 
31 namespace edm {
32 
34 
35  static
36  std::string appendCurrentProcessIfAlias(std::string const& processFromInputTag, std::string const& currentProcess) {
37  if (processFromInputTag == InputTag::kCurrentProcess) {
38  std::string returnValue = processFromInputTag;
39  returnValue += " (";
40  returnValue += currentProcess;
41  returnValue += ")";
42  return returnValue;
43  }
44  return processFromInputTag;
45  }
46 
47  static
48  void
50  throw Exception(error, "InvalidID")
51  << "Principal::" << where << ": no product with given branch id: "<< bid << "\n";
52  }
53 
54  static
55  std::shared_ptr<cms::Exception>
56  makeNotFoundException(char const* where, KindOfType kindOfType,
57  TypeID const& productType, std::string const& label, std::string const& instance, std::string const& process) {
58  std::shared_ptr<cms::Exception> exception = std::make_shared<Exception>(errors::ProductNotFound);
59  if (kindOfType == PRODUCT_TYPE) {
60  *exception << "Principal::" << where << ": Found zero products matching all criteria\nLooking for type: " << productType << "\n"
61  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
62  << (process.empty() ? "" : "Looking for process: ") << process << "\n";
63  } else {
64  *exception << "Principal::" << where << ": Found zero products matching all criteria\nLooking for a container with elements of type: " << productType << "\n"
65  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
66  << (process.empty() ? "" : "Looking for process: ") << process << "\n";
67  }
68  return exception;
69  }
70 
71  static
72  void
73  throwAmbiguousException(const char* where, TypeID const& productType,std::string const& label, std::string const& instance, std::string const& process) {
74  cms::Exception exception("AmbiguousProduct");
75  exception << "Principal::" << where << ": More than 1 product matches all criteria\nLooking for type: " << productType << "\n"
76  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
77  << (process.empty() ? "" : "Looking for process: ") << process << "\n"
78  << "This can only occur with get function calls using a Handle<View> argument.\n"
79  << "Try a get not using a View or change the instance name of one of the products";
80  throw exception;
81 
82  }
83 
84  namespace {
85  void failedToRegisterConsumesMany(edm::TypeID const& iType) {
86  cms::Exception exception("GetManyWithoutRegistration");
87  exception << "::getManyByType called for " << iType
88  << " without a corresponding consumesMany being called for this module. \n";
89  throw exception;
90  }
91 
92  void failedToRegisterConsumes(KindOfType kindOfType,
93  TypeID const& productType,
94  std::string const& moduleLabel,
95  std::string const& productInstanceName,
96  std::string const& processName) {
97  cms::Exception exception("GetByLabelWithoutRegistration");
98  exception << "::getByLabel without corresponding call to consumes or mayConsumes for this module.\n"
99  << (kindOfType == PRODUCT_TYPE ? " type: " : " type: edm::View<") << productType
100  << (kindOfType == PRODUCT_TYPE ? "\n module label: " : ">\n module label: ") << moduleLabel
101  <<"\n product instance name: '" << productInstanceName
102  <<"'\n process name: '" << processName << "'\n";
103  throw exception;
104  }
105 }
106 
107  //0 means unset
108  static std::atomic<Principal::CacheIdentifier_t> s_nextIdentifier{1};
110  return s_nextIdentifier.fetch_add(1,std::memory_order_acq_rel);
111  }
112 
113  Principal::Principal(std::shared_ptr<ProductRegistry const> reg,
114  std::shared_ptr<ProductResolverIndexHelper const> productLookup,
115  ProcessConfiguration const& pc,
116  BranchType bt,
117  HistoryAppender* historyAppender,
118  bool isForPrimaryProcess) :
119  EDProductGetter(),
120  processHistoryPtr_(),
121  processHistoryID_(),
122  processConfiguration_(&pc),
123  productResolvers_(),
124  preg_(reg),
125  productLookup_(productLookup),
126  lookupProcessOrder_(productLookup->lookupProcessNames().size(), 0),
127  reader_(),
128  branchType_(bt),
129  historyAppender_(historyAppender),
130  cacheIdentifier_(nextIdentifier()),
131  atEndTransition_(false)
132  {
133  productResolvers_.resize(reg->getNextIndexValue(bt));
134  //Now that these have been set, we can create the list of Branches we need.
135  std::string const source("source");
136  ProductRegistry::ProductList const& prodsList = reg->productList();
137  // The constructor of an alias product holder takes as an argument the product holder for which it is an alias.
138  // So, the non-alias product holders must be created first.
139  // Therefore, on this first pass, skip current EDAliases.
140  bool hasAliases = false;
141  for(auto const& prod : prodsList) {
142  BranchDescription const& bd = prod.second;
143  if(bd.branchType() == branchType_) {
144  if(isForPrimaryProcess or bd.processName() == pc.processName()) {
145  if(bd.isAlias()) {
146  hasAliases = true;
147  } else {
148  auto cbd = std::make_shared<BranchDescription const>(bd);
149  if(bd.produced()) {
150  if(bd.moduleLabel() == source) {
151  addSourceProduct(cbd);
152  } else if(bd.onDemand()) {
153  assert(branchType_ == InEvent);
155  } else {
156  addScheduledProduct(cbd);
157  }
158  } else {
159  addInputProduct(cbd);
160  }
161  }
162  } else {
163  //We are in a SubProcess and this branch is from the parent
164  auto cbd =std::make_shared<BranchDescription const>(bd);
166  }
167  }
168  }
169  // Now process any EDAliases
170  if(hasAliases) {
171  for(auto const& prod : prodsList) {
172  BranchDescription const& bd = prod.second;
173  if(bd.isAlias() && bd.branchType() == branchType_) {
174  auto cbd = std::make_shared<BranchDescription const>(bd);
175  addAliasedProduct(cbd);
176  }
177  }
178  }
179 
180  // Now create the ProductResolvers that search in reverse process
181  // order and are used for queries where the process name is the
182  // empty string
183  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
184  std::vector<ProductResolverIndex> matchingHolders(lookupProcessNames.size(), ProductResolverIndexInvalid);
185  std::vector<bool> ambiguous(lookupProcessNames.size(), false);
186  unsigned int beginElements = productLookup_->beginElements();
187  std::vector<TypeID> const& sortedTypeIDs = productLookup_->sortedTypeIDs();
188  std::vector<ProductResolverIndexHelper::Range> const& ranges = productLookup_->ranges();
189  std::vector<ProductResolverIndexHelper::IndexAndNames> const& indexAndNames = productLookup_->indexAndNames();
190  std::vector<char> const& processNamesCharArray = productLookup_->processNames();
191 
192  unsigned int numberOfMatches = 0;
194  if (!sortedTypeIDs.empty()) {
195  ProductResolverIndex productResolverIndex = ProductResolverIndexInvalid;
196  for(unsigned int k = 0, kEnd = sortedTypeIDs.size(); k < kEnd; ++k) {
197  ProductResolverIndexHelper::Range const& range = ranges.at(k);
198  for (unsigned int i = range.begin(); i < range.end(); ++i) {
199  ProductResolverIndexHelper::IndexAndNames const& product = indexAndNames.at(i);
200  if (product.startInProcessNames() == 0) {
201  if (productResolverIndex != ProductResolverIndexInvalid) {
202  if ((numberOfMatches == 1) and
203  (lastMatchIndex != ProductResolverIndexAmbiguous)) {
204  //only one choice so use a special resolver
205  productResolvers_.at(productResolverIndex) = std::make_shared<SingleChoiceNoProcessProductResolver>(lastMatchIndex);
206  } else {
207  std::shared_ptr<ProductResolverBase> newHolder = std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous);
208  productResolvers_.at(productResolverIndex) = newHolder;
209  }
210  matchingHolders.assign(lookupProcessNames.size(), ProductResolverIndexInvalid);
211  ambiguous.assign(lookupProcessNames.size(), false);
212  numberOfMatches= 0;
213  lastMatchIndex = ProductResolverIndexInvalid;
214  }
215  productResolverIndex = product.index();
216  } else {
217  std::string process(&processNamesCharArray.at(product.startInProcessNames()));
218  auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), process);
219  assert(iter != lookupProcessNames.end());
220  ProductResolverIndex iMatchingIndex = product.index();
221  lastMatchIndex = iMatchingIndex;
222  assert(iMatchingIndex != ProductResolverIndexInvalid);
223  ++numberOfMatches;
224  if (iMatchingIndex == ProductResolverIndexAmbiguous) {
225  assert(k >= beginElements);
226  ambiguous.at(iter - lookupProcessNames.begin()) = true;
227  } else {
228  matchingHolders.at(iter - lookupProcessNames.begin()) = iMatchingIndex;
229  }
230  }
231  }
232  }
233  std::shared_ptr<ProductResolverBase> newHolder = std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous);
234  productResolvers_.at(productResolverIndex) = newHolder;
235  }
236  }
237 
239  }
240 
241  // Number of products in the Principal.
242  // For products in an input file and not yet read in due to delayed read,
243  // this routine assumes a real product is there.
244  size_t
245  Principal::size() const {
246  size_t size = 0U;
247  for(auto const& prod : *this) {
248  if(prod->singleProduct() && // Not a NoProcessProductResolver
249  !prod->productUnavailable() &&
250  !prod->unscheduledWasNotRun() &&
251  !prod->branchDescription().dropped()) {
252  ++size;
253  }
254  }
255  return size;
256  }
257 
258  // adjust provenance for input products after new input file has been merged
259  bool
261  ProductRegistry::ProductList const& prodsList = reg.productList();
262  for(auto const& prod : prodsList) {
263  BranchDescription const& bd = prod.second;
264  if(!bd.produced() && (bd.branchType() == branchType_)) {
265  auto cbd = std::make_shared<BranchDescription const>(bd);
266  auto phb = getExistingProduct(cbd->branchID());
267  if(phb == nullptr || phb->branchDescription().branchName() != cbd->branchName()) {
268  return false;
269  }
270  phb->resetBranchDescription(cbd);
271  }
272  }
273  return true;
274  }
275 
276  void
277  Principal::addScheduledProduct(std::shared_ptr<BranchDescription const> bd) {
278  auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
280  }
281 
282  void
283  Principal::addSourceProduct(std::shared_ptr<BranchDescription const> bd) {
284  auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
286  }
287 
288  void
289  Principal::addInputProduct(std::shared_ptr<BranchDescription const> bd) {
290  addProductOrThrow(std::make_unique<InputProductResolver>(std::move(bd)));
291  }
292 
293  void
294  Principal::addUnscheduledProduct(std::shared_ptr<BranchDescription const> bd) {
295  addProductOrThrow(std::make_unique<UnscheduledProductResolver>(std::move(bd)));
296  }
297 
298  void
299  Principal::addAliasedProduct(std::shared_ptr<BranchDescription const> bd) {
300  ProductResolverIndex index = preg_->indexFrom(bd->originalBranchID());
301  assert(index != ProductResolverIndexInvalid);
302 
303  addProductOrThrow(std::make_unique<AliasProductResolver>(std::move(bd), dynamic_cast<ProducedProductResolver&>(*productResolvers_[index])));
304  }
305 
306  void
307  Principal::addParentProcessProduct(std::shared_ptr<BranchDescription const> bd) {
308  addProductOrThrow(std::make_unique<ParentProcessProductResolver>(std::move(bd)));
309  }
310 
311  // "Zero" the principal so it can be reused for another Event.
312  void
314  processHistoryPtr_.reset();
316  reader_ = nullptr;
317  for(auto& prod : *this) {
318  prod->resetProductData();
319  }
320  }
321 
322  void
324  atEndTransition_ = iAtEnd;
325  }
326 
327  void
329  auto phb = getExistingProduct(id);
330  assert(nullptr != phb);
331  phb->unsafe_deleteProduct();
332  }
333 
334  void
336  applyToResolvers([&iConfigure](ProductResolverBase* iResolver) {
337  iResolver->setupUnscheduled(iConfigure);
338  });
339  }
340 
341 
342  // Set the principal for the Event, Lumi, or Run.
343  void
345  ProcessHistoryRegistry const& processHistoryRegistry,
347  //increment identifier here since clearPrincipal isn't called for Run/Lumi
349  atEndTransition_=false;
350  if(reader) {
351  reader_ = reader;
352  }
353 
354  if (historyAppender_ && productRegistry().anyProductProduced()) {
356  historyAppender_->appendToProcessHistory(hist,
357  processHistoryRegistry.getMapped(hist),
360  }
361  else {
362  std::shared_ptr<ProcessHistory const> inputProcessHistory;
363  if (hist.isValid()) {
364  //does not own the pointer
365  auto noDel =[](void const*){};
366  inputProcessHistory =
367  std::shared_ptr<ProcessHistory const>(processHistoryRegistry.getMapped(hist),noDel);
368  if (inputProcessHistory.get() == nullptr) {
370  << "Principal::fillPrincipal\n"
371  << "Input ProcessHistory not found in registry\n"
372  << "Contact a Framework developer\n";
373  }
374  } else {
375  //Since this is static we don't want it deleted
376  inputProcessHistory = std::shared_ptr<ProcessHistory const>(&s_emptyProcessHistory,[](void const*){});
377  }
379  processHistoryPtr_ = inputProcessHistory;
380  }
381 
383  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
384  lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
385  unsigned int k = 0;
386 
387  // We loop over processes in reverse order of the ProcessHistory.
388  // If any entries in the product lookup tables are associated with
389  // the process we add it to the vector of processes in the order
390  // the lookup should be performed. There is one exception though,
391  // We start with the current process even if it is not in the ProcessHistory.
392  // The current process might be needed but not be in the process
393  // history if all the products produced in the current process are
394  // transient.
395  auto nameIter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), processConfiguration_->processName());
396  if (nameIter != lookupProcessNames.end()) {
397  lookupProcessOrder_.at(k) = nameIter - lookupProcessNames.begin();
398  ++k;
399  }
400 
401  // We just looked for the current process so skip it if
402  // it is in the ProcessHistory.
403  auto iter = processHistoryPtr_->rbegin();
404  if (iter->processName() == processConfiguration_->processName()) {
405  ++iter;
406  }
407 
408  for (auto iEnd = processHistoryPtr_->rend(); iter != iEnd; ++iter) {
409  auto nameIter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), iter->processName());
410  if (nameIter == lookupProcessNames.end()) {
411  continue;
412  }
413  lookupProcessOrder_.at(k) = nameIter - lookupProcessNames.begin();
414  ++k;
415  }
417  }
418  }
419 
422  return const_cast<ProductResolverBase*>( const_cast<const Principal*>(this)->getExistingProduct(branchID));
423  }
424 
425  ProductResolverBase const*
426  Principal::getExistingProduct(BranchID const& branchID) const {
427  ProductResolverIndex index = preg_->indexFrom(branchID);
428  assert(index != ProductResolverIndexInvalid);
429  return productResolvers_.at(index).get();
430  }
431 
432  ProductResolverBase const*
433  Principal::getExistingProduct(ProductResolverBase const& productResolver) const {
434  auto phb = getExistingProduct(productResolver.branchDescription().branchID());
435  if(nullptr != phb && BranchKey(productResolver.branchDescription()) != BranchKey(phb->branchDescription())) {
436  BranchDescription const& newProduct = phb->branchDescription();
437  BranchDescription const& existing = productResolver.branchDescription();
438  if(newProduct.branchName() != existing.branchName() && newProduct.branchID() == existing.branchID()) {
439  throw cms::Exception("HashCollision") << "Principal::getExistingProduct\n" <<
440  " Branch " << newProduct.branchName() << " has same branch ID as branch " << existing.branchName() << "\n" <<
441  "Workaround: change process name or product instance name of " << newProduct.branchName() << "\n";
442  } else {
443  assert(nullptr == phb || BranchKey(productResolver.branchDescription()) == BranchKey(phb->branchDescription()));
444  }
445  }
446  return phb;
447  }
448 
449  void
450  Principal::addProduct_(std::unique_ptr<ProductResolverBase> productResolver) {
451  BranchDescription const& bd = productResolver->branchDescription();
452  assert (!bd.className().empty());
453  assert (!bd.friendlyClassName().empty());
454  assert (!bd.moduleLabel().empty());
455  assert (!bd.processName().empty());
456  SharedProductPtr phb(productResolver.release());
457 
458  ProductResolverIndex index = preg_->indexFrom(bd.branchID());
459  assert(index != ProductResolverIndexInvalid);
460  productResolvers_[index] = phb;
461  }
462 
463  void
464  Principal::addProductOrThrow(std::unique_ptr<ProductResolverBase> productResolver) {
465  ProductResolverBase const* phb = getExistingProduct(*productResolver);
466  if(phb != nullptr) {
467  BranchDescription const& bd = productResolver->branchDescription();
468  throw Exception(errors::InsertFailure, "AlreadyPresent")
469  << "addProductOrThrow: Problem found while adding product, "
470  << "product already exists for ("
471  << bd.friendlyClassName() << ","
472  << bd.moduleLabel() << ","
473  << bd.productInstanceName() << ","
474  << bd.processName()
475  << ")\n";
476  }
477  addProduct_(std::move(productResolver));
478  }
479 
482  ProductResolverIndex index = preg_->indexFrom(bid);
483  if(index == ProductResolverIndexInvalid){
484  return ConstProductResolverPtr();
485  }
486  return getProductResolverByIndex(index);
487  }
488 
491 
493  return phb;
494  }
495 
498  TypeID const& typeID,
499  InputTag const& inputTag,
500  EDConsumerBase const* consumer,
502  ModuleCallingContext const* mcc) const {
503 
504  ProductData const* result = findProductByLabel(kindOfType, typeID, inputTag, consumer, sra, mcc);
505  if(result == 0) {
506  return BasicHandle(makeHandleExceptionFactory([=]()->std::shared_ptr<cms::Exception> {
507  return makeNotFoundException("getByLabel", kindOfType, typeID, inputTag.label(), inputTag.instance(),
509  }));
510  }
511  return BasicHandle(result->wrapper(), &(result->provenance()));
512  }
513 
516  TypeID const& typeID,
517  std::string const& label,
518  std::string const& instance,
519  std::string const& process,
520  EDConsumerBase const* consumer,
522  ModuleCallingContext const* mcc) const {
523 
524  ProductData const* result = findProductByLabel(kindOfType, typeID, label, instance, process,consumer, sra, mcc);
525  if(result == 0) {
526  return BasicHandle(makeHandleExceptionFactory([=]()->std::shared_ptr<cms::Exception> {
527  return makeNotFoundException("getByLabel", kindOfType, typeID, label, instance, process);
528  }));
529  }
530  return BasicHandle(result->wrapper(), &(result->provenance()));
531  }
532 
535  TypeID const&,
537  bool skipCurrentProcess,
538  bool& ambiguous,
540  ModuleCallingContext const* mcc) const {
541  assert(index !=ProductResolverIndexInvalid);
542  auto& productResolver = productResolvers_[index];
543  assert(0!=productResolver.get());
544  auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
545  if(resolution.isAmbiguous()) {
546  ambiguous = true;
547  return BasicHandle();
548  }
549  auto productData = resolution.data();
550  if(productData == nullptr) {
551  return BasicHandle();
552  }
553  return BasicHandle(productData->wrapper(), &(productData->provenance()));
554  }
555 
556  void
559  bool skipCurrentProcess,
560  ModuleCallingContext const* mcc) const {
561  auto const& productResolver = productResolvers_.at(index);
562  assert(0!=productResolver.get());
563  productResolver->prefetchAsync(task,*this, skipCurrentProcess,nullptr,mcc);
564  }
565 
566  void
569  EDConsumerBase const* consumer,
571  ModuleCallingContext const* mcc) const {
572 
573  assert(results.empty());
574 
575  if(unlikely(consumer and (not consumer->registeredToConsumeMany(typeID,branchType())))) {
576  failedToRegisterConsumesMany(typeID);
577  }
578 
579  // This finds the indexes to all the ProductResolver's matching the type
582 
583  if (matches.numberOfMatches() == 0) {
584  return;
585  }
586 
587  results.reserve(matches.numberOfMatches());
588 
589  // Loop over the ProductResolvers. Add the products that are actually
590  // present into the results. This will also trigger delayed reading,
591  // on demand production, and check for deleted products as appropriate.
592 
593  // Over the years the code that uses getManyByType has grown to depend
594  // on the ordering of the results. The order originally was just an
595  // accident of how previous versions of the code were written, but
596  // here we have to go through some extra effort to preserve that ordering.
597 
598  // We build a list of holders that match a particular label and instance.
599  // When that list is complete we call findProducts, which loops over
600  // that list in reverse order of the ProcessHistory (starts with the
601  // most recent). Then we clear the list and repeat this until all the
602  // matching label and instance subsets have been dealt with.
603 
604  // Note that the function isFullyResolved returns true for the ProductResolvers
605  // that are associated with an empty process name. Those are the ones that
606  // know how to search for the most recent process name matching
607  // a label and instance. We do not need these for getManyByType and
608  // skip them. In addition to skipping them, we make use of the fact
609  // that they mark the beginning of each subset of holders with the same
610  // label and instance. They tell us when to call findProducts.
611 
612  std::vector<ProductResolverBase const*> holders;
613 
614  for(unsigned int i = 0; i < matches.numberOfMatches(); ++i) {
615 
616  ProductResolverIndex index = matches.index(i);
617 
618  if(!matches.isFullyResolved(i)) {
619  if(!holders.empty()) {
620  // Process the ones with a particular module label and instance
621  findProducts(holders, typeID, results, sra, mcc);
622  holders.clear();
623  }
624  } else {
625  ProductResolverBase const* productResolver = productResolvers_.at(index).get();
626  assert(productResolver);
627  holders.push_back(productResolver);
628  }
629  }
630  // Do not miss the last subset of products
631  if(!holders.empty()) {
632  findProducts(holders, typeID, results, sra, mcc);
633  }
634  return;
635  }
636 
637  void
638  Principal::findProducts(std::vector<ProductResolverBase const*> const& holders,
639  TypeID const&,
642  ModuleCallingContext const* mcc) const {
643 
644  for (auto iter = processHistoryPtr_->rbegin(),
645  iEnd = processHistoryPtr_->rend();
646  iter != iEnd; ++iter) {
647  std::string const& process = iter->processName();
648  for (auto productResolver : holders) {
649  BranchDescription const& bd = productResolver->branchDescription();
650  if (process == bd.processName()) {
651 
652  // Ignore aliases to avoid matching the same product multiple times.
653  if(bd.isAlias()) {
654  continue;
655  }
656 
657  ProductData const* productData = productResolver->resolveProduct(*this,false, sra, mcc).data();
658  if(productData) {
659  // Skip product if not available.
660  results.emplace_back(productData->wrapper(), &(productData->provenance()));
661  }
662  }
663  }
664  }
665  }
666 
667  ProductData const*
669  TypeID const& typeID,
670  InputTag const& inputTag,
671  EDConsumerBase const* consumer,
673  ModuleCallingContext const* mcc) const {
674 
675  bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
676 
678 
679  if (index == ProductResolverIndexInvalid) {
680 
681  char const* processName = inputTag.process().c_str();
682  if (skipCurrentProcess) {
683  processName = "\0";
684  } else if (inputTag.process() == InputTag::kCurrentProcess) {
685  processName = processConfiguration_->processName().c_str();
686  }
687 
688  index = productLookup().index(kindOfType,
689  typeID,
690  inputTag.label().c_str(),
691  inputTag.instance().c_str(),
692  processName);
693 
694  if(index == ProductResolverIndexAmbiguous) {
695  throwAmbiguousException("findProductByLabel", typeID, inputTag.label(), inputTag.instance(),
697  } else if (index == ProductResolverIndexInvalid) {
698  return 0;
699  }
700  inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
701  }
702  if(unlikely( consumer and (not consumer->registeredToConsume(index, skipCurrentProcess, branchType())))) {
703  failedToRegisterConsumes(kindOfType,typeID,inputTag.label(),inputTag.instance(),
705  }
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", typeID, inputTag.label(), inputTag.instance(),
714  }
715  return resolution.data();
716  }
717 
718  ProductData const*
720  TypeID const& typeID,
721  std::string const& label,
722  std::string const& instance,
723  std::string const& process,
724  EDConsumerBase const* consumer,
726  ModuleCallingContext const* mcc) const {
727 
729  typeID,
730  label.c_str(),
731  instance.c_str(),
732  process.c_str());
733 
734  if(index == ProductResolverIndexAmbiguous) {
735  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
736  } else if (index == ProductResolverIndexInvalid) {
737  return 0;
738  }
739 
740  if(unlikely( consumer and (not consumer->registeredToConsume(index, false, branchType())))) {
741  failedToRegisterConsumes(kindOfType,typeID,label,instance,process);
742  }
743 
744  auto const& productResolver = productResolvers_[index];
745 
746  auto resolution = productResolver->resolveProduct(*this, false, sra, mcc);
747  if(resolution.isAmbiguous()) {
748  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
749  }
750  return resolution.data();
751  }
752 
753  ProductData const*
754  Principal::findProductByTag(TypeID const& typeID, InputTag const& tag, ModuleCallingContext const* mcc) const {
755  ProductData const* productData =
757  typeID,
758  tag,
759  nullptr,
760  nullptr,
761  mcc);
762  return productData;
763  }
764 
765  Provenance
767  ModuleCallingContext const* mcc) const {
769  if(phb == nullptr) {
771  }
772 
773  if(phb->unscheduledWasNotRun()) {
774  if(not phb->resolveProduct(*this,false, nullptr, mcc).data() ) {
775  throwProductNotFoundException("getProvenance(onDemand)", errors::ProductNotFound, bid);
776  }
777  }
778  return *phb->provenance();
779  }
780 
781  // This one is mostly for test printout purposes
782  // No attempt to trigger on demand execution
783  // Skips provenance when the EDProduct is not there
784  void
785  Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
786  provenances.clear();
787  for(auto const& productResolver : *this) {
788  if(productResolver->singleProduct() && productResolver->provenanceAvailable() && !productResolver->branchDescription().isAlias()) {
789  // We do not attempt to get the event/lumi/run status from the provenance,
790  // because the per event provenance may have been dropped.
791  if(productResolver->provenance()->branchDescription().present()) {
792  provenances.push_back(productResolver->provenance());
793  }
794  }
795  }
796  }
797 
798  // This one is also mostly for test printout purposes
799  // No attempt to trigger on demand execution
800  // Skips provenance for dropped branches.
801  void
802  Principal::getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const {
803  provenances.clear();
804  for(auto const& productResolver : *this) {
805  if(productResolver->singleProduct() && !productResolver->branchDescription().isAlias()) {
806  if(productResolver->stableProvenance()->branchDescription().present()) {
807  provenances.push_back(productResolver->stableProvenance());
808  }
809  }
810  }
811  }
812 
813  void
814  Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
815  for(auto& prod : bids) {
816  ProductResolverIndex index= preg_->indexFrom(prod);
817  assert(index!=ProductResolverIndexInvalid);
818  ProductResolverIndex indexO = other.preg_->indexFrom(prod);
819  assert(indexO!=ProductResolverIndexInvalid);
821  }
822  reader_->mergeReaders(other.reader());
823  }
824 
825  WrapperBase const*
826  Principal::getIt(ProductID const&) const {
827  assert(false);
828  return nullptr;
829  }
830 
831  WrapperBase const*
832  Principal::getThinnedProduct(ProductID const&, unsigned int&) const {
833  assert(false);
834  return nullptr;
835  }
836 
837  void
839  std::vector<WrapperBase const*>&,
840  std::vector<unsigned int>&) const {
841  assert(false);
842  }
843 
844  void
845  Principal::putOrMerge(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* phb) const {
846  phb->putOrMergeProduct(std::move(prod));
847  }
848 
849  void
850  Principal::putOrMerge(BranchDescription const& bd, std::unique_ptr<WrapperBase> edp) const {
851  if(edp.get() == nullptr) {
852  throw edm::Exception(edm::errors::InsertFailure,"Null Pointer")
853  << "put: Cannot put because unique_ptr to product is null."
854  << "\n";
855  }
856  auto phb = getExistingProduct(bd.branchID());
857  assert(phb);
858  // ProductResolver assumes ownership
859  putOrMerge(std::move(edp), phb);
860  }
861 
862 
863  void
865  if(preg_->getNextIndexValue(branchType_) != productResolvers_.size()) {
866  productResolvers_.resize(preg_->getNextIndexValue(branchType_));
867  for(auto const& prod : preg_->productList()) {
868  BranchDescription const& bd = prod.second;
869  if(bd.branchType() == branchType_) {
870  ProductResolverIndex index = preg_->indexFrom(bd.branchID());
871  assert(index != ProductResolverIndexInvalid);
872  if(!productResolvers_[index]) {
873  // no product holder. Must add one. The new entry must be an input product holder.
874  assert(!bd.produced());
875  auto cbd = std::make_shared<BranchDescription const>(bd);
876  addInputProduct(cbd);
877  }
878  }
879  }
880  }
881  assert(preg_->getNextIndexValue(branchType_) == productResolvers_.size());
882  }
883 
884  void
886  if(not reader()) {return;}
887 
888  for(auto & prod : *this) {
889  prod->retrieveAndMerge(*this);
890  }
891  }
892 
893  void
895  for( auto & prod : *this) {
896  prod->resetFailedFromThisProcess();
897  }
898  }
899 }
BranchType branchType_
Definition: Principal.h:286
size
Write out results.
ProductResolverIndex index(unsigned int i) const
static ProcessHistory const s_emptyProcessHistory
Definition: Principal.cc:33
ProductRegistry const & productRegistry() const
Definition: Principal.h:151
Provenance const & provenance() const
Definition: ProductData.h:30
void clearPrincipal()
Definition: Principal.cc:313
std::string const & branchName() const
size_t size() const
Definition: Principal.cc:245
DelayedReader * reader_
Definition: Principal.h:284
BranchType const & branchType() const
void setupUnscheduled(UnscheduledConfigurator const &)
Definition: Principal.cc:335
unsigned int ProductResolverIndex
bool getMapped(ProcessHistoryID const &key, ProcessHistory &value) const
static std::string const source("source")
ProductResolverCollection productResolvers_
Definition: Principal.h:272
std::shared_ptr< ProcessHistory const > processHistoryPtr_
Definition: Principal.h:265
static PFTauRenderPlugin instance
std::shared_ptr< ProductResolverBase > SharedProductPtr
Definition: Principal.h:67
void addProduct_(std::unique_ptr< ProductResolverBase > phb)
Definition: Principal.cc:450
static std::atomic< Principal::CacheIdentifier_t > s_nextIdentifier
Definition: Principal.cc:108
std::map< BranchKey, BranchDescription > ProductList
static Principal::CacheIdentifier_t nextIdentifier()
Definition: Principal.cc:109
ProcessHistoryID processHistoryID_
Definition: Principal.h:267
void mergeReaders(DelayedReader *other)
Definition: DelayedReader.h:35
ProductResolverBase * getExistingProduct(BranchID const &branchID)
Definition: Principal.cc:421
virtual void setupUnscheduled(UnscheduledConfigurator const &)
void getAllProvenance(std::vector< Provenance const * > &provenances) const
Definition: Principal.cc:785
void applyToResolvers(F iFunc)
Definition: Principal.h:217
void getAllStableProvenance(std::vector< StableProvenance const * > &provenances) const
Definition: Principal.cc:802
Provenance getProvenance(BranchID const &bid, ModuleCallingContext const *mcc) const
Definition: Principal.cc:766
WrapperBase const * wrapper() const
Definition: ProductData.h:32
virtual void getThinnedProducts(ProductID const &, std::vector< WrapperBase const * > &, std::vector< unsigned int > &) const override
Definition: Principal.cc:838
std::string const & processName() const
void setAtEndTransition(bool iAtEnd)
Definition: Principal.cc:323
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
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:113
void addInputProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:289
edm::propagate_const< HistoryAppender * > historyAppender_
Definition: Principal.h:291
BranchType
Definition: BranchType.h:11
ProductResolverIndex indexFor(TypeID const &typeID, BranchType branchType, void const *productRegistry) const
Definition: InputTag.cc:187
void tryToCacheIndex(ProductResolverIndex index, TypeID const &typeID, BranchType branchType, void const *productRegistry) const
Definition: InputTag.cc:205
void readAllFromSourceAndMergeImmediately()
Definition: Principal.cc:885
static void throwAmbiguousException(const char *where, TypeID const &productType, std::string const &label, std::string const &instance, std::string const &process)
Definition: Principal.cc:73
std::string const & processName() const
#define unlikely(x)
ProductList const & productList() const
std::vector< unsigned int > lookupProcessOrder_
Definition: Principal.h:279
BasicHandle getByLabel(KindOfType kindOfType, TypeID const &typeID, InputTag const &inputTag, EDConsumerBase const *consumes, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:497
void addScheduledProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:277
std::string const & className() const
ProductData const * findProductByTag(TypeID const &typeID, InputTag const &tag, ModuleCallingContext const *mcc) const
Definition: Principal.cc:754
std::shared_ptr< ProductResolverIndexHelper const > productLookup_
Definition: Principal.h:277
std::string const & moduleLabel() const
void addProductOrThrow(std::unique_ptr< ProductResolverBase > phb)
Definition: Principal.cc:464
std::shared_ptr< ProductRegistry const > preg_
Definition: Principal.h:276
std::string const & productInstanceName() const
bool registeredToConsume(ProductResolverIndex, bool, BranchType) const
CacheIdentifier_t cacheIdentifier_
Definition: Principal.h:293
BranchType const & branchType() const
Definition: Principal.h:178
std::shared_ptr< HandleExceptionFactory > makeHandleExceptionFactory(T &&iFunctor)
void putOrMerge(BranchDescription const &bd, std::unique_ptr< WrapperBase > edp) const
Definition: Principal.cc:850
void prefetchAsync(WaitingTask *waitTask, ProductResolverIndex index, bool skipCurrentProcess, ModuleCallingContext const *mcc) const
Definition: Principal.cc:557
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
void addSourceProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:283
Matches relatedIndexes(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance) const
ProcessHistoryID orderProcessHistoryID_
Definition: Principal.h:280
static const std::string kCurrentProcess
Definition: InputTag.h:51
std::string const & friendlyClassName() const
BranchID const & branchID() const
std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
void addParentProcessProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:307
Hash< ProcessHistoryType > ProcessHistoryID
int k[5][pyjets_maxn]
string ranges
Definition: diffTwoXMLs.py:78
DelayedReader * reader() const
Definition: Principal.h:184
virtual ~Principal()
Definition: Principal.cc:238
bool willSkipCurrentProcess() const
Definition: InputTag.h:42
bool registeredToConsumeMany(TypeID const &, BranchType) const
void addUnscheduledProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:294
virtual WrapperBase const * getIt(ProductID const &) const override
Definition: Principal.cc:826
ProductResolverIndexHelper const & productLookup() const
Definition: Principal.h:153
void resetFailedFromThisProcess()
Definition: Principal.cc:894
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:63
std::string const & label() const
Definition: InputTag.h:36
void findProducts(std::vector< ProductResolverBase const * > const &holders, TypeID const &typeID, BasicHandleVec &results, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:638
std::string const & process() const
Definition: InputTag.h:40
ProductResolverIndex index(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process=0) const
HLT enums.
unsigned long CacheIdentifier_t
Definition: Principal.h:181
virtual WrapperBase const * getThinnedProduct(ProductID const &, unsigned int &) const override
Definition: Principal.cc:832
bool isValid() const
Definition: Hash.h:151
bool adjustToNewProductRegistry(ProductRegistry const &reg)
Definition: Principal.cc:260
BranchDescription const & branchDescription() const
ProductData const * findProductByLabel(KindOfType kindOfType, TypeID const &typeID, InputTag const &inputTag, EDConsumerBase const *consumer, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:668
ConstProductResolverPtr getProductResolverByIndex(ProductResolverIndex const &oid) const
Definition: Principal.cc:490
ConstProductResolverPtr getProductResolver(BranchID const &oid) const
Definition: Principal.cc:481
void resetBranchDescription(std::shared_ptr< BranchDescription const > bd)
void adjustIndexesAfterProductRegistryAddition()
Definition: Principal.cc:864
static void throwProductNotFoundException(char const *where, errors::ErrorCodes error, BranchID const &bid)
Definition: Principal.cc:49
BasicHandle getByToken(KindOfType kindOfType, TypeID const &typeID, ProductResolverIndex index, bool skipCurrentProcess, bool &ambiguous, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:534
static std::string appendCurrentProcessIfAlias(std::string const &processFromInputTag, std::string const &currentProcess)
Definition: Principal.cc:36
void addAliasedProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:299
void fillPrincipal(ProcessHistoryID const &hist, ProcessHistoryRegistry const &phr, DelayedReader *reader)
Definition: Principal.cc:344
void putOrMergeProduct(std::unique_ptr< WrapperBase > edp) const
void recombine(Principal &other, std::vector< BranchID > const &bids)
Definition: Principal.cc:814
bool atEndTransition_
Definition: Principal.h:295
std::string const & instance() const
Definition: InputTag.h:37
ProcessConfiguration const * processConfiguration_
Definition: Principal.h:269
def move(src, dest)
Definition: eostools.py:510
std::vector< BasicHandle > BasicHandleVec
Definition: Principal.h:64
void getManyByType(TypeID const &typeID, BasicHandleVec &results, EDConsumerBase const *consumes, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:567
void deleteProduct(BranchID const &id) const
Definition: Principal.cc:328