CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ProcessBlockHelper.cc
Go to the documentation of this file.
2 
5 
6 #include <algorithm>
7 #include <cassert>
8 #include <utility>
9 
10 namespace edm {
11 
13 
14  std::vector<std::string> const& ProcessBlockHelper::topProcessesWithProcessBlockProducts() const {
16  }
17 
19 
20  std::vector<std::vector<unsigned int>> const& ProcessBlockHelper::processBlockCacheIndices() const {
22  }
23 
24  std::vector<std::vector<unsigned int>> const& ProcessBlockHelper::nEntries() const { return nEntries_; }
25 
26  std::vector<unsigned int> const& ProcessBlockHelper::cacheIndexVectorsPerFile() const {
28  }
29 
30  std::vector<unsigned int> const& ProcessBlockHelper::cacheEntriesPerFile() const { return cacheEntriesPerFile_; }
31 
33  std::string const& processName, EventToProcessBlockIndexes const& eventToProcessBlockIndexes) const {
34  for (unsigned int iProcess = 0; iProcess < nProcessesInFirstFile_; ++iProcess) {
35  if (processName == processesWithProcessBlockProducts()[iProcess]) {
36  return processBlockCacheIndices_[eventToProcessBlockIndexes.index()][iProcess];
37  }
38  }
39  return invalidCacheIndex();
40  }
41 
42  unsigned int ProcessBlockHelper::outerOffset() const { return outerOffset_; }
43 
44  // Modifies the process names and cache indices in the StoredProcessBlockHelper.
45  // Part of the dropOnInput. Also part of reordering that forces ProcessBlocks
46  // to be read in the same order for all input files.
48  StoredProcessBlockHelper& storedProcessBlockHelper,
49  std::set<std::string> const& processesToKeep,
50  std::vector<unsigned int> const& nEntries,
51  std::vector<unsigned int>& finalIndexToStoredIndex) const {
52  std::vector<std::string> const& storedProcesses = storedProcessBlockHelper.processesWithProcessBlockProducts();
53 
54  bool isModified = false;
55  unsigned int finalSize = 0;
56  for (auto const& process : storedProcesses) {
57  if (processesToKeep.find(process) == processesToKeep.end()) {
58  isModified = true;
59  } else {
60  ++finalSize;
61  }
62  }
63  if (!isModified) {
64  return isModified;
65  }
66 
67  std::vector<std::string> finalProcesses;
68  finalProcesses.reserve(finalSize);
69  finalIndexToStoredIndex.reserve(finalSize);
70  for (unsigned int iStored = 0; iStored < storedProcesses.size(); ++iStored) {
71  if (processesToKeep.find(storedProcesses[iStored]) != processesToKeep.end()) {
72  finalProcesses.emplace_back(storedProcesses[iStored]);
73  finalIndexToStoredIndex.emplace_back(iStored);
74  }
75  }
76  dropProcessesAndReorderStoredImpl(storedProcessBlockHelper, finalProcesses, nEntries, finalIndexToStoredIndex);
77  return isModified;
78  }
79 
80  // Modifies the process names and cache indices in the StoredProcessBlockHelper.
81  // Part of the dropOnInput. Also part of reordering that forces ProcessBlocks
82  // to be read in the same order for all input files.
84  std::set<std::string> const& processesToKeep,
85  std::vector<unsigned int> const& nEntries,
86  std::vector<unsigned int>& finalIndexToStoredIndex,
87  std::vector<std::string> const& firstFileFinalProcesses) const {
88  std::vector<std::string> const& storedProcesses = storedProcessBlockHelper.processesWithProcessBlockProducts();
89 
90  std::vector<std::string> finalProcesses;
91  // Always will allocate enough space (sometimes too much)
92  finalProcesses.reserve(storedProcesses.size());
93  finalIndexToStoredIndex.reserve(storedProcesses.size());
94 
95  // The outer loop here establishes the order
96  // Only allows processes that got into finalProcesses for the first file
97  for (unsigned int iFirst = 0; iFirst < firstFileFinalProcesses.size(); ++iFirst) {
98  // Only includes processes also in storedProcesses
99  for (unsigned int iStored = 0; iStored < storedProcesses.size(); ++iStored) {
100  std::string const& storedProcess = storedProcesses[iStored];
101  if (firstFileFinalProcesses[iFirst] == storedProcess) {
102  // Also requires processes have kept ProcessBlock products
103  if (processesToKeep.find(storedProcess) != processesToKeep.end()) {
104  finalProcesses.emplace_back(storedProcess);
105  finalIndexToStoredIndex.emplace_back(iStored);
106  break;
107  }
108  }
109  }
110  }
111 
112  bool isModified = true;
113  if (storedProcesses == finalProcesses) {
114  isModified = false;
115  return isModified;
116  }
117 
118  dropProcessesAndReorderStoredImpl(storedProcessBlockHelper, finalProcesses, nEntries, finalIndexToStoredIndex);
119  return isModified;
120  }
121 
123  if (!initializedFromInput_) {
124  initializedFromInput_ = true;
125 
129  }
130  }
131 
133  std::vector<unsigned int> const& nEntries) {
134  // I've written this so it will continue to work even if we someday relax
135  // the strict merging requirement in the ProductRegistry (there
136  // is a little extra complexity that may be unnecessary...).
137 
138  std::vector<std::string> const& storedProcesses = storedProcessBlockHelper.processesWithProcessBlockProducts();
139  std::vector<unsigned int> const& storedCacheIndices = storedProcessBlockHelper.processBlockCacheIndices();
140 
142 
143  if (nProcessesInFirstFile_ == 0) {
144  // There were no ProcessBlock products in the first file. Nothing to do.
145  return;
146  } else if (!storedProcesses.empty()) {
147  // Subsequent input file with ProcessBlock products
148  fillFromPrimaryInputWhenNotEmpty(storedProcesses, storedCacheIndices, nEntries);
149  } else if (storedProcesses.empty()) {
150  // Subsequent input file without ProcessBlock products
152  cacheIndexVectorsPerFile_.push_back(1);
153  std::vector<unsigned int> newNEntries(nProcessesInFirstFile_, 0);
155  }
156  }
157 
160  nEntries_.clear();
162  cacheEntriesPerFile_.clear();
163  outerOffset_ = 0;
164  cacheIndexOffset_ = 0;
165  }
166 
167  // Modifies the process names and cache indices in the StoredProcessBlockHelper.
168  // Part of the dropOnInput. Also part of reordering that forces ProcessBlocks
169  // to be read in the same order for all input files.
171  StoredProcessBlockHelper& storedProcessBlockHelper,
172  std::vector<std::string>& finalProcesses,
173  std::vector<unsigned int> const& nEntries,
174  std::vector<unsigned int> const& finalIndexToStoredIndex) const {
175  std::vector<std::string> const& storedProcesses = storedProcessBlockHelper.processesWithProcessBlockProducts();
176  std::vector<unsigned int> const& storedCacheIndices = storedProcessBlockHelper.processBlockCacheIndices();
177 
178  assert(!storedProcesses.empty());
179  std::vector<unsigned int> newCacheIndices;
180  if (!finalProcesses.empty()) {
181  // ProcessBlocks are read in the order of storedProcesses and within
182  // each process in entry order in the TTree. This establishes the cache
183  // order that the values in storedCacheIndices refer to. The "offset" refers
184  // to cache index value of the first ProcessBlock in a TTree.
185  std::vector<unsigned int> oldOffsets;
186  oldOffsets.reserve(storedProcesses.size());
187  unsigned int offset = 0;
188  for (auto const& entries : nEntries) {
189  oldOffsets.emplace_back(offset);
190  offset += entries;
191  }
192 
193  unsigned int nFinalProcesses = finalProcesses.size();
194  std::vector<unsigned int> newOffsets;
195  newOffsets.reserve(nFinalProcesses);
196  offset = 0;
197  for (unsigned int iNew = 0; iNew < nFinalProcesses; ++iNew) {
198  newOffsets.emplace_back(offset);
199  offset += nEntries[finalIndexToStoredIndex[iNew]];
200  }
201 
202  unsigned int nOuterLoop = storedCacheIndices.size() / storedProcesses.size();
203  assert(nOuterLoop * storedProcesses.size() == storedCacheIndices.size());
204  newCacheIndices.reserve(nOuterLoop * nFinalProcesses);
205  unsigned int storedOuterOffset = 0;
206 
207  for (unsigned int k = 0; k < nOuterLoop; ++k) {
208  for (unsigned int j = 0; j < nFinalProcesses; ++j) {
209  unsigned int storedIndex = finalIndexToStoredIndex[j];
210  unsigned int oldCacheIndex = storedCacheIndices[storedOuterOffset + storedIndex];
211  unsigned int newCacheIndex = invalidCacheIndex();
212  if (oldCacheIndex != invalidCacheIndex()) {
213  newCacheIndex = oldCacheIndex - oldOffsets[storedIndex] + newOffsets[j];
214  }
215  newCacheIndices.emplace_back(newCacheIndex);
216  }
217  storedOuterOffset += storedProcesses.size();
218  }
219  }
220  storedProcessBlockHelper.setProcessBlockCacheIndices(std::move(newCacheIndices));
221  storedProcessBlockHelper.setProcessesWithProcessBlockProducts(std::move(finalProcesses));
222  }
223 
224  void ProcessBlockHelper::fillFromPrimaryInputWhenNotEmpty(std::vector<std::string> const& storedProcesses,
225  std::vector<unsigned int> const& storedCacheIndices,
226  std::vector<unsigned int> const& nEntries) {
228 
229  // Calculate a translation from an index into the process names from the first file
230  // to an index into the process names from the current file. Note the value will
231  // be left invalid if the process name is not found in the current file.
232  std::vector<unsigned int> firstFileToStored(nProcessesInFirstFile_, invalidProcessIndex());
233  std::vector<unsigned int> newNEntries(nProcessesInFirstFile_, 0);
234  for (unsigned int j = 0; j < nProcessesInFirstFile_; ++j) {
235  for (unsigned int k = 0; k < storedProcesses.size(); ++k) {
236  if (processesWithProcessBlockProducts()[j] == storedProcesses[k]) {
237  firstFileToStored[j] = k;
238  newNEntries[j] = nEntries[k];
239  break;
240  }
241  }
242  }
243 
244  // Append the cache indices from the current input file to the
245  // cache indices container from the previous files.
246  unsigned int nCacheIndexVectors = storedCacheIndices.size() / storedProcesses.size();
247  assert(storedProcesses.size() * nCacheIndexVectors == storedCacheIndices.size());
248  processBlockCacheIndices_.resize(processBlockCacheIndices_.size() + nCacheIndexVectors);
249  unsigned int storedIndex = 0;
250  for (unsigned int k = 0; k < nCacheIndexVectors; ++k) {
251  processBlockCacheIndices_[outerOffset_ + k].reserve(nProcessesInFirstFile_);
252  for (unsigned int j = 0; j < nProcessesInFirstFile_; ++j) {
253  unsigned int iStored = firstFileToStored[j];
254  if (iStored == invalidProcessIndex()) {
256  } else {
257  unsigned int oldCacheIndex = storedCacheIndices[storedIndex];
258  ++storedIndex;
259  unsigned int newCacheIndex = invalidCacheIndex();
260  if (oldCacheIndex != invalidCacheIndex()) {
261  newCacheIndex = oldCacheIndex + cacheIndexOffset_;
262  }
263  processBlockCacheIndices_[outerOffset_ + k].push_back(newCacheIndex);
264  }
265  }
266  }
267  cacheIndexVectorsPerFile_.push_back(nCacheIndexVectors);
269  }
270 
271  void ProcessBlockHelper::fillEntriesFromPrimaryInput(std::vector<unsigned int> nEntries) {
272  unsigned int entriesThisFile = 0;
273  for (auto const& entries : nEntries) {
274  entriesThisFile += entries;
275  }
276  nEntries_.push_back(std::move(nEntries));
277  cacheEntriesPerFile_.push_back(entriesThisFile);
278  cacheIndexOffset_ += entriesThisFile;
279  }
280 
281 } // namespace edm
void initializeFromPrimaryInput(StoredProcessBlockHelper const &storedProcessBlockHelper)
unsigned int outerOffset() const final
unsigned int processBlockIndex(std::string const &processName, EventToProcessBlockIndexes const &) const final
bool firstFileDropProcessesAndReorderStored(StoredProcessBlockHelper &storedProcessBlockHelper, std::set< std::string > const &processesToKeep, std::vector< unsigned int > const &nEntries, std::vector< unsigned int > &finalIndexToStoredIndex) const
void setProcessesWithProcessBlockProducts(std::vector< std::string > val)
std::vector< unsigned int > const & cacheIndexVectorsPerFile() const final
static constexpr unsigned int invalidProcessIndex()
static constexpr unsigned int invalidCacheIndex()
ProcessBlockHelperBase const * topProcessBlockHelper() const final
void fillEntriesFromPrimaryInput(std::vector< unsigned int > nEntries)
std::vector< unsigned int > cacheEntriesPerFile_
std::vector< std::vector< unsigned int > > const & processBlockCacheIndices() const final
std::vector< std::string > const & topProcessesWithProcessBlockProducts() const final
std::vector< std::vector< unsigned int > > nEntries_
assert(be >=bs)
unsigned int nProcessesInFirstFile() const final
std::vector< std::vector< unsigned int > > const & nEntries() const final
std::vector< unsigned int > cacheIndexVectorsPerFile_
std::vector< unsigned int > const & cacheEntriesPerFile() const final
def move
Definition: eostools.py:511
std::vector< std::string > const & processesWithProcessBlockProducts() const
std::vector< std::string > const & processesWithProcessBlockProducts() const
void setProcessBlockCacheIndices(std::vector< unsigned int > val)
bool dropProcessesAndReorderStored(StoredProcessBlockHelper &storedProcessBlockHelper, std::set< std::string > const &processesToKeep, std::vector< unsigned int > const &nEntries, std::vector< unsigned int > &finalIndexToStoredIndex, std::vector< std::string > const &firstFileFinalProcesses) const
tuple process
Definition: LaserDQM_cfg.py:3
std::vector< unsigned int > const & processBlockCacheIndices() const
void setProcessesWithProcessBlockProducts(std::vector< std::string > const &val)
void fillFromPrimaryInput(StoredProcessBlockHelper const &storedProcessBlockHelper, std::vector< unsigned int > const &nEntries)
tuple size
Write out results.
std::vector< std::vector< unsigned int > > processBlockCacheIndices_
void dropProcessesAndReorderStoredImpl(StoredProcessBlockHelper &storedProcessBlockHelper, std::vector< std::string > &finalProcesses, std::vector< unsigned int > const &nEntries, std::vector< unsigned int > const &finalIndexToStoredIndex) const
void fillFromPrimaryInputWhenNotEmpty(std::vector< std::string > const &storedProcesses, std::vector< unsigned int > const &storedCacheIndices, std::vector< unsigned int > const &nEntries)