CMS 3D CMS Logo

CheckTransitions.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Services
4 // Class : CheckTransitions
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Thu Sep 8 14:17:58 EDT 2005
11 //
13 
16 
19 
24 
31 
32 #include <vector>
33 #include <string>
34 #include "oneapi/tbb/concurrent_vector.h"
35 #include <iostream>
36 
37 namespace edm {
38 
39  namespace service {
41  public:
43 
45 
47  ~CheckTransitions() noexcept(false);
48 
49  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
50 
52 
54  void postEndJob();
55 
56  void preOpenFile(std::string const&);
57 
58  void preCloseFile(std::string const& lfn);
59 
61 
63 
65 
67 
69 
71 
73 
75 
77 
78  private:
79  oneapi::tbb::concurrent_vector<std::tuple<Phase, edm::EventID, int>> m_seenTransitions;
81  int m_nstreams = 0;
82  bool m_failed = false;
83  };
84  } // namespace service
85 } // namespace edm
86 using namespace edm::service;
87 
88 namespace {
91 
92  Transition stringToType(const std::string& iTrans) {
93  if (iTrans == "IsStop") {
94  return Transition::IsStop;
95  }
96  if (iTrans == "IsFile") {
97  return Transition::IsFile;
98  }
99  if (iTrans == "IsRun") {
100  return Transition::IsRun;
101  }
102  if (iTrans == "IsLumi") {
103  return Transition::IsLumi;
104  }
105  if (iTrans == "IsEvent") {
106  return Transition::IsEvent;
107  }
108 
109  throw edm::Exception(edm::errors::Configuration) << "Unknown transition type \'" << iTrans << "\'";
110 
111  return Transition::IsInvalid;
112  }
113 
114  std::vector<std::tuple<Phase, edm::EventID, int>> expectedValues(
115  std::vector<std::pair<Transition, edm::EventID>> const& iTrans, int iNStreams) {
116  std::vector<std::tuple<Phase, edm::EventID, int>> returnValue;
117  returnValue.reserve(iTrans.size());
118 
119  const edm::RunNumber_t maxIDValue = edm::EventID::maxRunNumber();
120  edm::EventID lastRun = {maxIDValue, 0, 0};
121  edm::EventID lastLumi = {maxIDValue, maxIDValue, 0};
122  for (auto const& tran : iTrans) {
123  switch (tran.first) {
124  case Transition::IsFile: {
125  break;
126  }
127  case Transition::IsRun: {
128  if (tran.second != lastRun) {
129  if (lastRun.run() != maxIDValue) {
130  //end transitions
131  for (int i = 0; i < iNStreams; ++i) {
132  returnValue.emplace_back(Phase::kEndRun, lastRun, i);
133  }
134  returnValue.emplace_back(Phase::kEndRun, lastRun, 1000);
135  }
136  //begin transitions
137  returnValue.emplace_back(Phase::kBeginRun, tran.second, -1);
138  for (int i = 0; i < iNStreams; ++i) {
139  returnValue.emplace_back(Phase::kBeginRun, tran.second, i);
140  }
141  lastRun = tran.second;
142  }
143  break;
144  }
145  case Transition::IsLumi: {
146  if (tran.second != lastLumi) {
147  if (lastLumi.run() != maxIDValue) {
148  //end transitions
149  for (int i = 0; i < iNStreams; ++i) {
150  returnValue.emplace_back(Phase::kEndLumi, lastLumi, i);
151  }
152  returnValue.emplace_back(Phase::kEndLumi, lastLumi, 1000);
153  }
154  //begin transitions
155  returnValue.emplace_back(Phase::kBeginLumi, tran.second, -1);
156  for (int i = 0; i < iNStreams; ++i) {
157  returnValue.emplace_back(Phase::kBeginLumi, tran.second, i);
158  }
159  lastLumi = tran.second;
160  }
161  break;
162  }
163  case Transition::IsEvent: {
164  returnValue.emplace_back(Phase::kEvent, tran.second, -2);
165  }
166  case Transition::IsStop:
167  case Transition::IsInvalid: {
168  break;
169  }
170  }
171  }
172  if (lastLumi.run() != maxIDValue) {
173  //end transitions
174  for (int i = 0; i < iNStreams; ++i) {
175  returnValue.emplace_back(Phase::kEndLumi, lastLumi, i);
176  }
177  returnValue.emplace_back(Phase::kEndLumi, lastLumi, 1000);
178  }
179  if (lastRun.run() != maxIDValue) {
180  //end transitions
181  for (int i = 0; i < iNStreams; ++i) {
182  returnValue.emplace_back(Phase::kEndRun, lastRun, i);
183  }
184  returnValue.emplace_back(Phase::kEndRun, lastRun, 1000);
185  }
186  return returnValue;
187  }
188 
189 } // namespace
190 
192  for (auto const& p : iPS.getUntrackedParameter<std::vector<edm::ParameterSet>>("transitions")) {
193  m_expectedTransitions.emplace_back(stringToType(p.getUntrackedParameter<std::string>("type")),
194  p.getUntrackedParameter<EventID>("id"));
195  }
196 
198 
200 
202 
204 
206 
208 
210 
212 
214 
216 
218 
220 
221  iRegistry.watchPreEvent(this, &CheckTransitions::preEvent);
222 }
223 
225  if (m_failed) {
226  throw edm::Exception(errors::EventProcessorFailure) << "incorrect transtions";
227  }
228 }
229 
232  desc.setComment("Checks that the transitions specified occur during the job.");
233 
235  trans.addUntracked<std::string>("type");
236  trans.addUntracked<edm::EventID>("id");
237  desc.addVPSetUntracked("transitions", trans, {{}});
238  descriptions.add("CheckTransitions", desc);
239 }
240 
242 
244  auto expectedV = expectedValues(m_expectedTransitions, m_nstreams);
245 
246  std::vector<std::tuple<Phase, edm::EventID, int>> orderedSeen;
247  orderedSeen.reserve(m_seenTransitions.size());
248  for (auto const& i : m_seenTransitions) {
249  // std::cout <<i.first.m_run<<" "<<i.first.m_lumi<<" "<<i.first.m_event<<" "<<i.second<<std::endl;
250  auto s = std::get<2>(i);
251  if (std::get<1>(i).event() > 0) {
252  s = -2;
253  }
254  orderedSeen.emplace_back(std::get<0>(i), std::get<1>(i), s);
255  }
256  std::sort(orderedSeen.begin(), orderedSeen.end());
257 
258  auto orderedExpected = expectedV;
259  std::sort(orderedExpected.begin(), orderedExpected.end());
260  /* for(auto const& i: expectedV) {
261  std::cout <<i.first.m_run<<" "<<i.first.m_lumi<<" "<<i.first.m_event<<" "<<i.second<<std::endl;
262  } */
263 
264  unsigned int nSkippedStreamLumiTransitions = 0;
265 
266  // Use the next two vectors to test that skipped stream lumi transitions
267  // come in matched begin and end pairs.
268  std::vector<std::tuple<Phase, edm::EventID, int>> expectedSkippedStreamEndLumi;
269  std::vector<std::tuple<Phase, edm::EventID, int>> seenSkippedStreamEndLumi;
270 
271  // Use the next two sets to test that for every global begin lumi there
272  // is at least one stream begin lumi, even when some stream begin lumi
273  // transitions are skipped.
274  std::set<std::tuple<Phase, edm::EventID, int>> seenGlobalBeginLumi;
275  std::set<std::tuple<Phase, edm::EventID, int>> seenStreamBeginLumi;
276 
277  auto itOS = orderedSeen.begin();
278  for (auto itOE = orderedExpected.begin(); itOE != orderedExpected.end(); ++itOE) {
279  if (itOS == orderedSeen.end()) {
280  break;
281  }
282 
283  if (std::get<0>(*itOS) == Phase::kBeginLumi && std::get<2>(*itOS) == -1) {
284  seenGlobalBeginLumi.emplace(*itOS);
285  }
286  if (std::get<0>(*itOS) == Phase::kBeginLumi && (std::get<2>(*itOS) > -1 && std::get<2>(*itOS) < 1000)) {
287  // Note that the third field is falsely filled with the value for a global begin lumi to
288  // make a comparison with seenGlobalBeginLumi easier.
289  seenStreamBeginLumi.emplace(std::get<0>(*itOS), std::get<1>(*itOS), -1);
290  }
291 
292  while (*itOE != *itOS && (std::get<0>(*itOE) == Phase::kBeginLumi || std::get<0>(*itOE) == Phase::kEndLumi) &&
293  (std::get<2>(*itOE) > -1 && std::get<2>(*itOE) < 1000)) {
294  ++nSkippedStreamLumiTransitions;
295  if (std::get<0>(*itOE) == Phase::kBeginLumi) {
296  expectedSkippedStreamEndLumi.emplace_back(Phase::kEndLumi, std::get<1>(*itOE), std::get<2>(*itOE));
297  } else {
298  seenSkippedStreamEndLumi.emplace_back(*itOE);
299  }
300 
301  ++itOE;
302  }
303  if (*itOE != *itOS) {
304  auto syncOE = std::get<1>(*itOE);
305  auto syncOS = std::get<1>(*itOS);
306  std::cout << "Different ordering " << syncOE << " " << std::get<2>(*itOE) << "\n"
307  << " " << syncOS << " " << std::get<2>(*itOS) << "\n";
308  m_failed = true;
309  }
310  ++itOS;
311  }
312 
313  if (seenGlobalBeginLumi != seenStreamBeginLumi) {
314  std::cout << "We didn't see at least one stream begin lumi for every global begin lumi" << std::endl;
315  m_failed = true;
316  }
317 
318  if (expectedSkippedStreamEndLumi != seenSkippedStreamEndLumi) {
319  std::cout << "Skipped stream begin and end lumi transitions do not match" << std::endl;
320  m_failed = true;
321  }
322 
323  if (orderedSeen.size() + nSkippedStreamLumiTransitions != orderedExpected.size()) {
324  std::cout << "Wrong number of transition " << orderedSeen.size() << " " << orderedExpected.size() << std::endl;
325  m_failed = true;
326  return;
327  }
328 }
329 
331 
333 
335  auto id = gc.luminosityBlockID();
336  m_seenTransitions.emplace_back(Phase::kBeginRun, edm::EventID{id.run(), 0, 0}, -1);
337 }
338 
340  auto id = gc.luminosityBlockID();
341  m_seenTransitions.emplace_back(Phase::kEndRun, edm::EventID{id.run(), 0, 0}, 1000);
342 }
343 
345  m_seenTransitions.emplace_back(Phase::kBeginRun, sc.eventID(), sc.streamID());
346 }
347 
349  m_seenTransitions.emplace_back(Phase::kEndRun, sc.eventID(), sc.streamID());
350 }
351 
353  auto id = gc.luminosityBlockID();
354  m_seenTransitions.emplace_back(Phase::kBeginLumi, edm::EventID{id.run(), id.luminosityBlock(), 0}, -1);
355 }
356 
358  auto id = gc.luminosityBlockID();
359  m_seenTransitions.emplace_back(Phase::kEndLumi, edm::EventID{id.run(), id.luminosityBlock(), 0}, 1000);
360 }
361 
363  m_seenTransitions.emplace_back(Phase::kBeginLumi, sc.eventID(), sc.streamID());
364 }
365 
367  m_seenTransitions.emplace_back(Phase::kEndLumi, sc.eventID(), sc.streamID());
368 }
369 
371  m_seenTransitions.emplace_back(Phase::kEvent, sc.eventID(), sc.streamID());
372 }
373 
void watchPreEvent(PreEvent::slot_type const &iSlot)
CheckTransitions(const ParameterSet &, ActivityRegistry &)
void preBeginJob(PathsAndConsumesOfModulesBase const &, ProcessContext const &)
void watchPreallocate(Preallocate::slot_type const &iSlot)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
void watchPostEndJob(PostEndJob::slot_type const &iSlot)
static RunNumber_t maxRunNumber()
Definition: EventID.h:92
void watchPreGlobalEndLumi(PreGlobalEndLumi::slot_type const &iSlot)
void watchPreStreamEndRun(PreStreamEndRun::slot_type const &iSlot)
void watchPreGlobalBeginLumi(PreGlobalBeginLumi::slot_type const &iSlot)
void preStreamEndLumi(StreamContext const &)
void watchPreStreamEndLumi(PreStreamEndLumi::slot_type const &iSlot)
void preCloseFile(std::string const &lfn)
std::vector< std::pair< Transition, edm::EventID > > m_expectedTransitions
void preEvent(StreamContext const &)
void preStreamEndRun(StreamContext const &)
T getUntrackedParameter(std::string const &, T const &) const
void preStreamBeginLumi(StreamContext const &)
void watchPreOpenFile(PreOpenFile::slot_type const &iSlot)
void watchPreGlobalEndRun(PreGlobalEndRun::slot_type const &iSlot)
StreamID const & streamID() const
Definition: StreamContext.h:55
void preGlobalEndRun(GlobalContext const &)
void preGlobalBeginRun(GlobalContext const &)
LuminosityBlockID const & luminosityBlockID() const
Definition: GlobalContext.h:66
void watchPreGlobalBeginRun(PreGlobalBeginRun::slot_type const &iSlot)
RunNumber_t run() const
Definition: EventID.h:38
#define DEFINE_FWK_SERVICE(type)
Definition: ServiceMaker.h:97
oneapi::tbb::concurrent_vector< std::tuple< Phase, edm::EventID, int > > m_seenTransitions
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void watchPreCloseFile(PreCloseFile::slot_type const &iSlot)
void watchPreStreamBeginLumi(PreStreamBeginLumi::slot_type const &iSlot)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void preGlobalBeginLumi(GlobalContext const &)
HLT enums.
void watchPreStreamBeginRun(PreStreamBeginRun::slot_type const &iSlot)
void preStreamBeginRun(StreamContext const &)
EventID const & eventID() const
Definition: StreamContext.h:60
void preGlobalEndLumi(GlobalContext const &)
void preallocate(service::SystemBounds const &)
unsigned int RunNumber_t
void preOpenFile(std::string const &)