CMS 3D CMS Logo

List of all members | Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes
edm::MergeableRunProductMetadata Class Reference

#include <MergeableRunProductMetadata.h>

Inheritance diagram for edm::MergeableRunProductMetadata:
edm::MergeableRunProductMetadataBase

Classes

class  MetadataForProcess
 

Public Types

enum  MergeDecision { MERGE, REPLACE, IGNORE }
 

Public Member Functions

void addEntryToStoredMetadata (StoredMergeableRunProductMetadata &) const
 
MergeDecision getMergeDecision (std::string const &processThatCreatedProduct) const
 
std::string const & getProcessName (unsigned int index) const
 
bool gotLumisFromIndexIntoFile () const
 
bool knownImproperlyMerged (std::string const &processThatCreatedProduct) const override
 
std::vector< LuminosityBlockNumber_t > const & lumisFromIndexIntoFile () const
 
tbb::concurrent_vector< LuminosityBlockNumber_t > const & lumisProcessed () const
 
 MergeableRunProductMetadata (MergeableRunProductProcesses const &)
 
MetadataForProcess const * metadataForOneProcess (std::string const &processName) const
 
std::vector< MetadataForProcess > const & metadataForProcesses () const
 
void postWriteRun ()
 
void preReadFile ()
 
void preWriteRun ()
 
void readRun (long long inputRunEntry, StoredMergeableRunProductMetadata const &inputStoredMergeableRunProductMetadata, IndexIntoFileItrHolder const &inputIndexIntoFileItr)
 
void writeLumi (LuminosityBlockNumber_t lumi)
 
 ~MergeableRunProductMetadata () override
 
- Public Member Functions inherited from edm::MergeableRunProductMetadataBase
virtual ~MergeableRunProductMetadataBase ()
 

Private Member Functions

bool addProcess (StoredMergeableRunProductMetadata &storedMetadata, MetadataForProcess const &metadataForProcess, unsigned int storedProcessIndex, unsigned long long beginProcess, unsigned long long endProcess) const
 
void mergeLumisFromIndexIntoFile ()
 

Private Attributes

bool gotLumisFromIndexIntoFile_ = false
 
std::vector< LuminosityBlockNumber_tlumisFromIndexIntoFile_
 
tbb::concurrent_vector< LuminosityBlockNumber_tlumisProcessed_
 
MergeableRunProductProcesses const * mergeableRunProductProcesses_
 
std::vector< MetadataForProcessmetadataForProcesses_
 

Detailed Description

This class holds information used to decide how to merge together mergeable run products when multiple run entries with the same run number and ProcessHistoryID are read from input files contiguously.

Most of the information here is associated with the current run being processed. Most of it is cleared when a new run is started. If multiple runs are being processed concurrently, then there will be an object instantiated for each concurrent run. (At the present time concurrent runs are not possible, but there plans to implement that in the future). The primary RunPrincipal for the current run owns the object.

This class gets information from the input file from the StoredMergeableRunProductMetadata object and IndexIntoFile object. It uses that information to make the decision how to merge run products read from data, and puts information into the StoredMergeableRunProductMetadata written into the output file to use in later processing steps.

If there are SubProcesses, they use the same object as the top level process because they share the same input.

There will be a TWIKI page on the Framework page of the Software Guide which explains the details about how this works. There are significant limitations related to what the Framework does and does not do managing mergeable run products.

Author
W. David Dagenhart, created 9 July, 2018

Definition at line 52 of file MergeableRunProductMetadata.h.

Member Enumeration Documentation

Constructor & Destructor Documentation

edm::MergeableRunProductMetadata::MergeableRunProductMetadata ( MergeableRunProductProcesses const &  mergeableRunProductProcesses)

Definition at line 14 of file MergeableRunProductMetadata.cc.

16  : mergeableRunProductProcesses_(&mergeableRunProductProcesses),
17  metadataForProcesses_(mergeableRunProductProcesses.size()) {}
MergeableRunProductProcesses const * mergeableRunProductProcesses_
std::vector< MetadataForProcess > metadataForProcesses_
edm::MergeableRunProductMetadata::~MergeableRunProductMetadata ( )
override

Definition at line 19 of file MergeableRunProductMetadata.cc.

19 {}

Member Function Documentation

void edm::MergeableRunProductMetadata::addEntryToStoredMetadata ( StoredMergeableRunProductMetadata storedMetadata) const

Definition at line 162 of file MergeableRunProductMetadata.cc.

References addProcess(), mergeableRunProductProcesses_, metadataForProcesses_, edm::MergeableRunProductProcesses::processesWithMergeableRunProducts(), edm::StoredMergeableRunProductMetadata::processesWithMergeableRunProducts(), edm::StoredMergeableRunProductMetadata::singleRunEntries(), and edm::StoredMergeableRunProductMetadata::singleRunEntryAndProcesses().

Referenced by edm::RootOutputFile::writeRun().

162  {
163  if (metadataForProcesses_.empty()) {
164  return;
165  }
166 
167  std::vector<std::string> const& storedProcesses = storedMetadata.processesWithMergeableRunProducts();
168  if (storedProcesses.empty()) {
169  return;
170  }
171 
172  unsigned long long beginProcess = storedMetadata.singleRunEntryAndProcesses().size();
173  unsigned long long endProcess = beginProcess;
174 
175  std::vector<std::string> const& processesWithMergeableRunProducts =
177 
178  for (unsigned int storedProcessIndex = 0; storedProcessIndex < storedProcesses.size(); ++storedProcessIndex) {
179  // Look for a matching process. It is intentional that no process
180  // is added when there is no match. storedProcesses only contains
181  // processes which created mergeable run products selected by the
182  // output module to be written out. processesWithMergeableRunProducts_
183  // only has processes which created mergeable run products that were
184  // read from the input data files. Note storedProcesses may be
185  // missing processes because the output module dropped products.
186  // The other vector may be missing processes because of SubProcesses.
187  for (unsigned int transientProcessIndex = 0; transientProcessIndex < processesWithMergeableRunProducts.size();
188  ++transientProcessIndex) {
189  // This string comparison could be optimized away by storing an index mapping in
190  // OutputModuleBase calculated once early in a job. (? Given how rare
191  // mergeable run products are this optimization may not be worth doing)
192  if (processesWithMergeableRunProducts[transientProcessIndex] == storedProcesses[storedProcessIndex]) {
193  if (addProcess(storedMetadata,
194  metadataForProcesses_.at(transientProcessIndex),
195  storedProcessIndex,
196  beginProcess,
197  endProcess)) {
198  ++endProcess;
199  }
200  break;
201  }
202  }
203  }
204  storedMetadata.singleRunEntries().emplace_back(beginProcess, endProcess);
205  }
bool addProcess(StoredMergeableRunProductMetadata &storedMetadata, MetadataForProcess const &metadataForProcess, unsigned int storedProcessIndex, unsigned long long beginProcess, unsigned long long endProcess) const
MergeableRunProductProcesses const * mergeableRunProductProcesses_
std::vector< MetadataForProcess > metadataForProcesses_
std::vector< std::string > const & processesWithMergeableRunProducts() const
bool edm::MergeableRunProductMetadata::addProcess ( StoredMergeableRunProductMetadata storedMetadata,
MetadataForProcess const &  metadataForProcess,
unsigned int  storedProcessIndex,
unsigned long long  beginProcess,
unsigned long long  endProcess 
) const
private

Definition at line 207 of file MergeableRunProductMetadata.cc.

References edm::MergeableRunProductMetadata::MetadataForProcess::allLumisProcessed(), edm::StoredMergeableRunProductMetadata::allValidAndUseIndexIntoFile(), edm::StoredMergeableRunProductMetadata::SingleRunEntryAndProcess::beginLumi(), edm::StoredMergeableRunProductMetadata::SingleRunEntryAndProcess::endLumi(), runEdmFileComparison::found, edm::MergeableRunProductMetadata::MetadataForProcess::lumis(), edm::StoredMergeableRunProductMetadata::lumis(), edm::StoredMergeableRunProductMetadata::singleRunEntryAndProcesses(), and edm::MergeableRunProductMetadata::MetadataForProcess::valid().

Referenced by addEntryToStoredMetadata(), and lumisProcessed().

211  {
212  if (metadataForProcess.valid() && metadataForProcess.allLumisProcessed()) {
213  return false;
214  }
215 
216  storedMetadata.allValidAndUseIndexIntoFile() = false;
217 
218  unsigned long long iBeginLumi = 0;
219  unsigned long long iEndLumi = 0;
220 
221  // See if we need to store the set of lumi numbers corresponding
222  // to this process and run entry. If they were all processed then
223  // we can just get the lumi numbers out of IndexIntoFile and do
224  // not need to store them here
225  if (!metadataForProcess.allLumisProcessed()) {
226  // If we need to store the numbers, then we can check to
227  // make sure this does not duplicate the lumi numbers we
228  // stored for another process. If we did then we can just
229  // just reference same indices and avoid copying a duplicate
230  // sequence of lumi numbers. It is sufficient to check the
231  // size only. As you go back in the time sequence of processes
232  // the only thing that can happen is more lumi numbers appear
233  // at steps where a run was only partially processed.
234  bool found = false;
235  for (unsigned long long kProcess = beginProcess; kProcess < endProcess; ++kProcess) {
236  StoredMergeableRunProductMetadata::SingleRunEntryAndProcess const& storedSingleRunEntryAndProcess =
237  storedMetadata.singleRunEntryAndProcesses().at(kProcess);
238 
239  if (metadataForProcess.lumis().size() ==
240  (storedSingleRunEntryAndProcess.endLumi() - storedSingleRunEntryAndProcess.beginLumi())) {
241  iBeginLumi = storedSingleRunEntryAndProcess.beginLumi();
242  iEndLumi = storedSingleRunEntryAndProcess.endLumi();
243  found = true;
244  break;
245  }
246  }
247  if (!found) {
248  std::vector<LuminosityBlockNumber_t>& storedLumis = storedMetadata.lumis();
249  std::vector<LuminosityBlockNumber_t> const& metdataLumis = metadataForProcess.lumis();
250  iBeginLumi = storedLumis.size();
251  storedLumis.insert(storedLumis.end(), metdataLumis.begin(), metdataLumis.end());
252  iEndLumi = storedLumis.size();
253  }
254  }
255  storedMetadata.singleRunEntryAndProcesses().emplace_back(
256  iBeginLumi, iEndLumi, storedProcessIndex, metadataForProcess.valid(), metadataForProcess.allLumisProcessed());
257  return true;
258  }
MergeableRunProductMetadata::MergeDecision edm::MergeableRunProductMetadata::getMergeDecision ( std::string const &  processThatCreatedProduct) const

Definition at line 260 of file MergeableRunProductMetadata.cc.

References Exception, edm::errors::LogicError, MERGE, edm::MergeableRunProductMetadata::MetadataForProcess::mergeDecision(), and metadataForOneProcess().

Referenced by edm::DataManagingProductResolver::mergeProduct().

261  {
262  MetadataForProcess const* metadataForProcess = metadataForOneProcess(processThatCreatedProduct);
263  if (metadataForProcess) {
264  return metadataForProcess->mergeDecision();
265  }
266  throw Exception(errors::LogicError) << "MergeableRunProductMetadata::getMergeDecision could not find process.\n"
267  << "It should not be possible for this error to occur.\n"
268  << "Contact a Framework developer\n";
269  return MERGE;
270  }
MetadataForProcess const * metadataForOneProcess(std::string const &processName) const
std::string const& edm::MergeableRunProductMetadata::getProcessName ( unsigned int  index) const
inline
bool edm::MergeableRunProductMetadata::gotLumisFromIndexIntoFile ( ) const
inline
bool edm::MergeableRunProductMetadata::knownImproperlyMerged ( std::string const &  processThatCreatedProduct) const
overridevirtual

Implements edm::MergeableRunProductMetadataBase.

Definition at line 272 of file MergeableRunProductMetadata.cc.

References metadataForOneProcess(), and edm::MergeableRunProductMetadata::MetadataForProcess::valid().

272  {
273  MetadataForProcess const* metadataForProcess = metadataForOneProcess(processThatCreatedProduct);
274  if (metadataForProcess) {
275  return !metadataForProcess->valid();
276  }
277  return false;
278  }
MetadataForProcess const * metadataForOneProcess(std::string const &processName) const
std::vector<LuminosityBlockNumber_t> const& edm::MergeableRunProductMetadata::lumisFromIndexIntoFile ( ) const
inline

Definition at line 125 of file MergeableRunProductMetadata.h.

References lumisFromIndexIntoFile_.

125 { return lumisFromIndexIntoFile_; }
std::vector< LuminosityBlockNumber_t > lumisFromIndexIntoFile_
tbb::concurrent_vector<LuminosityBlockNumber_t> const& edm::MergeableRunProductMetadata::lumisProcessed ( ) const
inline

Definition at line 129 of file MergeableRunProductMetadata.h.

References addProcess(), lumisProcessed_, and mergeLumisFromIndexIntoFile().

Referenced by preWriteRun().

129 { return lumisProcessed_; }
tbb::concurrent_vector< LuminosityBlockNumber_t > lumisProcessed_
void edm::MergeableRunProductMetadata::mergeLumisFromIndexIntoFile ( )
private

Definition at line 302 of file MergeableRunProductMetadata.cc.

References gotLumisFromIndexIntoFile_, lumisFromIndexIntoFile_, metadataForProcesses_, and groupFilesInBlocks::temp.

Referenced by lumisProcessed(), preReadFile(), and preWriteRun().

302  {
303  for (auto& metadataForProcess : metadataForProcesses_) {
304  if (metadataForProcess.useIndexIntoFile()) {
305  metadataForProcess.setUseIndexIntoFile(false);
306 
307  std::vector<LuminosityBlockNumber_t> temp;
308  temp.reserve(metadataForProcess.lumis().size() + lumisFromIndexIntoFile_.size());
309  std::vector<LuminosityBlockNumber_t>::const_iterator end1 = metadataForProcess.lumis().end();
310  std::vector<LuminosityBlockNumber_t>::const_iterator end2 = lumisFromIndexIntoFile_.end();
311  for (std::vector<LuminosityBlockNumber_t>::const_iterator iter1 = metadataForProcess.lumis().begin(),
312  iter2 = lumisFromIndexIntoFile_.begin();
313  iter1 != end1 || iter2 != end2;) {
314  if (iter1 == end1) {
315  temp.push_back(*iter2);
316  ++iter2;
317  continue;
318  } else if (iter2 == end2) {
319  temp.push_back(*iter1);
320  ++iter1;
321  continue;
322  } else if (*iter1 < *iter2) {
323  temp.push_back(*iter1);
324  ++iter1;
325  } else if (*iter1 > *iter2) {
326  temp.push_back(*iter2);
327  ++iter2;
328  } else {
329  // they must be equal
330  temp.push_back(*iter1);
331  ++iter1;
332  ++iter2;
333  }
334  }
335  metadataForProcess.lumis().swap(temp);
336  }
337  }
338  lumisFromIndexIntoFile_.clear();
340  }
std::vector< MetadataForProcess > metadataForProcesses_
std::vector< LuminosityBlockNumber_t > lumisFromIndexIntoFile_
MergeableRunProductMetadata::MetadataForProcess const * edm::MergeableRunProductMetadata::metadataForOneProcess ( std::string const &  processName) const

Definition at line 288 of file MergeableRunProductMetadata.cc.

References getProcessName(), and metadataForProcesses_.

Referenced by getMergeDecision(), and knownImproperlyMerged().

289  {
290  unsigned int processIndex = 0;
291  for (auto const& metadataForProcess : metadataForProcesses_) {
292  // This string comparison could be optimized away by storing an index in
293  // BranchDescription as a transient calculated once early in a job.
294  if (getProcessName(processIndex) == processName) {
295  return &metadataForProcess;
296  }
297  ++processIndex;
298  }
299  return nullptr;
300  }
std::vector< MetadataForProcess > metadataForProcesses_
std::string const & getProcessName(unsigned int index) const
std::vector<MetadataForProcess> const& edm::MergeableRunProductMetadata::metadataForProcesses ( ) const
inline

Definition at line 123 of file MergeableRunProductMetadata.h.

References metadataForProcesses_.

123 { return metadataForProcesses_; }
std::vector< MetadataForProcess > metadataForProcesses_
void edm::MergeableRunProductMetadata::postWriteRun ( )

Definition at line 155 of file MergeableRunProductMetadata.cc.

References lumisProcessed_, and metadataForProcesses_.

Referenced by edm::EventProcessor::endUnfinishedRun().

155  {
156  lumisProcessed_.clear();
157  for (auto& metadataForProcess : metadataForProcesses_) {
158  metadataForProcess.reset();
159  }
160  }
std::vector< MetadataForProcess > metadataForProcesses_
tbb::concurrent_vector< LuminosityBlockNumber_t > lumisProcessed_
void edm::MergeableRunProductMetadata::preReadFile ( )
void edm::MergeableRunProductMetadata::preWriteRun ( )

Definition at line 125 of file MergeableRunProductMetadata.cc.

References includes, lumisProcessed(), lumisProcessed_, mergeLumisFromIndexIntoFile(), metadataForProcesses_, and tier0::unique().

Referenced by edm::EventProcessor::endUnfinishedRun().

125  {
126  if (metadataForProcesses_.empty()) {
127  return;
128  }
129 
131 
132  // Sort the lumiProcessed vector and ignore the duplicate
133  // entries
134 
135  // Not sure if this copy is necessary. I'm copying because
136  // I am not sure the standard algorithms work on TBB containers.
137  // I couldn't find anything saying they did when I searched ...
138  std::vector<LuminosityBlockNumber_t> lumisProcessed;
139  lumisProcessed.reserve(lumisProcessed_.size());
140  for (auto const& lumi : lumisProcessed_) {
141  lumisProcessed.push_back(lumi);
142  }
143 
144  std::sort(lumisProcessed.begin(), lumisProcessed.end());
145  auto uniqueEnd = std::unique(lumisProcessed.begin(), lumisProcessed.end());
146 
147  for (auto& metadataForProcess : metadataForProcesses_) {
148  // Did we process all the lumis in this process that were processed
149  // in the process that created the mergeable run products.
150  metadataForProcess.setAllLumisProcessed(std::includes(
151  lumisProcessed.begin(), uniqueEnd, metadataForProcess.lumis().begin(), metadataForProcess.lumis().end()));
152  }
153  }
tbb::concurrent_vector< xml::Document > includes
tbb::concurrent_vector< LuminosityBlockNumber_t > const & lumisProcessed() const
std::vector< MetadataForProcess > metadataForProcesses_
def unique(seq, keepstr=True)
Definition: tier0.py:25
tbb::concurrent_vector< LuminosityBlockNumber_t > lumisProcessed_
void edm::MergeableRunProductMetadata::readRun ( long long  inputRunEntry,
StoredMergeableRunProductMetadata const &  inputStoredMergeableRunProductMetadata,
IndexIntoFileItrHolder const &  inputIndexIntoFileItr 
)

Definition at line 23 of file MergeableRunProductMetadata.cc.

References edm::StoredMergeableRunProductMetadata::getLumiContent(), edm::IndexIntoFileItrHolder::getLumisInRun(), gotLumisFromIndexIntoFile_, IGNORE, heppy_report::lumis, lumisFromIndexIntoFile_, MERGE, mergeableRunProductProcesses_, metadataForProcesses_, edm::MergeableRunProductProcesses::processesWithMergeableRunProducts(), modifiedElectrons_cfi::processName, REPLACE, AlCaHLTBitMon_QueryRunRegistry::string, and groupFilesInBlocks::temp.

Referenced by edm::RootFile::readRun_().

26  {
27  unsigned int processIndex{0};
28  for (auto& metadataForProcess : metadataForProcesses_) {
29  bool valid = true;
30  std::vector<LuminosityBlockNumber_t>::const_iterator lumisInRunBeingReadBegin;
31  std::vector<LuminosityBlockNumber_t>::const_iterator lumisInRunBeingReadEnd;
32 
34 
35  if (inputStoredMergeableRunProductMetadata.getLumiContent(
36  inputRunEntry, processName, valid, lumisInRunBeingReadBegin, lumisInRunBeingReadEnd)) {
37  // This is a reference to the container accumulating the luminosity
38  // block numbers for the run entries read associated with the current
39  // run being processed that correspond to the luminosity block content
40  // for the mergeable run products created in the process.
41  std::vector<LuminosityBlockNumber_t>& lumis = metadataForProcess.lumis();
42 
43  // In the following, iter1 refers to the lumis associated with run entries already read
44  // and iter2 refers to the lumis associated with the current run entry being read.
45 
46  bool elementsIn2NotIn1 = false;
47  bool elementsIn1NotIn2 = false;
48  bool sharedElements = false;
49 
50  std::vector<LuminosityBlockNumber_t> temp;
51  temp.reserve(lumis.size() + (lumisInRunBeingReadEnd - lumisInRunBeingReadBegin));
52  std::vector<LuminosityBlockNumber_t>::const_iterator end1 = lumis.end();
53  std::vector<LuminosityBlockNumber_t>::const_iterator end2 = lumisInRunBeingReadEnd;
54  for (std::vector<LuminosityBlockNumber_t>::const_iterator iter1 = lumis.begin(),
55  iter2 = lumisInRunBeingReadBegin;
56  iter1 != end1 || iter2 != end2;) {
57  if (iter1 == end1) {
58  temp.push_back(*iter2);
59  ++iter2;
60  elementsIn2NotIn1 = true;
61  continue;
62  } else if (iter2 == end2) {
63  temp.push_back(*iter1);
64  ++iter1;
65  elementsIn1NotIn2 = true;
66  continue;
67  } else if (*iter1 < *iter2) {
68  temp.push_back(*iter1);
69  ++iter1;
70  elementsIn1NotIn2 = true;
71  } else if (*iter1 > *iter2) {
72  temp.push_back(*iter2);
73  ++iter2;
74  elementsIn2NotIn1 = true;
75  } else {
76  // they must be equal
77  sharedElements = true;
78  temp.push_back(*iter1);
79  ++iter1;
80  ++iter2;
81  }
82  }
83  lumis.swap(temp);
84  if (!sharedElements && elementsIn2NotIn1 && elementsIn1NotIn2) {
85  metadataForProcess.setMergeDecision(MERGE);
86  if (!valid) {
87  metadataForProcess.setValid(false);
88  }
89  } else if (!elementsIn2NotIn1) {
90  metadataForProcess.setMergeDecision(IGNORE);
91  } else if (!elementsIn1NotIn2) {
92  metadataForProcess.setMergeDecision(REPLACE);
93  if (!valid) {
94  metadataForProcess.setValid(false);
95  }
96  } else {
97  // In this case there is no way to get the correct answer.
98  // The result will always be invalid.
99  metadataForProcess.setMergeDecision(MERGE);
100  metadataForProcess.setValid(false);
101  }
102 
103  } else {
104  metadataForProcess.setMergeDecision(MERGE);
105  if (!valid) {
106  metadataForProcess.setValid(false);
107  }
108  metadataForProcess.setUseIndexIntoFile(true);
110  inputIndexIntoFileItr.getLumisInRun(lumisFromIndexIntoFile_);
112  }
113  }
114  ++processIndex;
115  } // end of loop over processes
116  } // end of readRun function
MergeableRunProductProcesses const * mergeableRunProductProcesses_
std::vector< MetadataForProcess > metadataForProcesses_
std::vector< LuminosityBlockNumber_t > lumisFromIndexIntoFile_
std::vector< std::string > const & processesWithMergeableRunProducts() const
void edm::MergeableRunProductMetadata::writeLumi ( LuminosityBlockNumber_t  lumi)

Definition at line 118 of file MergeableRunProductMetadata.cc.

References lumisProcessed_, and metadataForProcesses_.

Referenced by edm::EventProcessor::writeLumiAsync().

118  {
119  if (metadataForProcesses_.empty()) {
120  return;
121  }
122  lumisProcessed_.push_back(lumi);
123  }
std::vector< MetadataForProcess > metadataForProcesses_
tbb::concurrent_vector< LuminosityBlockNumber_t > lumisProcessed_

Member Data Documentation

bool edm::MergeableRunProductMetadata::gotLumisFromIndexIntoFile_ = false
private
std::vector<LuminosityBlockNumber_t> edm::MergeableRunProductMetadata::lumisFromIndexIntoFile_
private
tbb::concurrent_vector<LuminosityBlockNumber_t> edm::MergeableRunProductMetadata::lumisProcessed_
private
MergeableRunProductProcesses const* edm::MergeableRunProductMetadata::mergeableRunProductProcesses_
private
std::vector<MetadataForProcess> edm::MergeableRunProductMetadata::metadataForProcesses_
private