File indexing completed on 2023-03-17 11:03:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "FWCore/ServiceRegistry/interface/ServiceMaker.h"
0013
0014 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0015 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0016
0017 #include "FWCore/ServiceRegistry/interface/SystemBounds.h"
0018 #include "FWCore/Utilities/interface/Exception.h"
0019
0020 #include "DataFormats/Provenance/interface/EventID.h"
0021 #include "DataFormats/Provenance/interface/LuminosityBlockID.h"
0022 #include "DataFormats/Provenance/interface/RunID.h"
0023 #include "DataFormats/Provenance/interface/Timestamp.h"
0024
0025 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0026 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0027 #include "FWCore/ServiceRegistry/interface/GlobalContext.h"
0028 #include "FWCore/ServiceRegistry/interface/PathContext.h"
0029 #include "FWCore/ServiceRegistry/interface/ProcessContext.h"
0030 #include "FWCore/ServiceRegistry/interface/StreamContext.h"
0031
0032 #include <vector>
0033 #include <string>
0034 #include "oneapi/tbb/concurrent_vector.h"
0035 #include <iostream>
0036
0037 namespace edm {
0038
0039 namespace service {
0040 class CheckTransitions {
0041 public:
0042 enum class Phase { kBeginRun, kBeginLumi, kEvent, kEndLumi, kEndRun };
0043
0044 enum class Transition { IsInvalid, IsStop, IsFile, IsRun, IsLumi, IsEvent };
0045
0046 CheckTransitions(const ParameterSet&, ActivityRegistry&);
0047 ~CheckTransitions() noexcept(false);
0048
0049 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0050
0051 void preallocate(service::SystemBounds const&);
0052
0053 void preBeginJob(PathsAndConsumesOfModulesBase const&, ProcessContext const&);
0054 void postEndJob();
0055
0056 void preOpenFile(std::string const&);
0057
0058 void preCloseFile(std::string const& lfn);
0059
0060 void preGlobalBeginRun(GlobalContext const&);
0061
0062 void preGlobalEndRun(GlobalContext const&);
0063
0064 void preStreamBeginRun(StreamContext const&);
0065
0066 void preStreamEndRun(StreamContext const&);
0067
0068 void preGlobalBeginLumi(GlobalContext const&);
0069
0070 void preGlobalEndLumi(GlobalContext const&);
0071
0072 void preStreamBeginLumi(StreamContext const&);
0073
0074 void preStreamEndLumi(StreamContext const&);
0075
0076 void preEvent(StreamContext const&);
0077
0078 private:
0079 oneapi::tbb::concurrent_vector<std::tuple<Phase, edm::EventID, int>> m_seenTransitions;
0080 std::vector<std::pair<Transition, edm::EventID>> m_expectedTransitions;
0081 int m_nstreams = 0;
0082 bool m_failed = false;
0083 };
0084 }
0085 }
0086 using namespace edm::service;
0087
0088 namespace {
0089 using Phase = CheckTransitions::Phase;
0090 using Transition = CheckTransitions::Transition;
0091
0092 Transition stringToType(const std::string& iTrans) {
0093 if (iTrans == "IsStop") {
0094 return Transition::IsStop;
0095 }
0096 if (iTrans == "IsFile") {
0097 return Transition::IsFile;
0098 }
0099 if (iTrans == "IsRun") {
0100 return Transition::IsRun;
0101 }
0102 if (iTrans == "IsLumi") {
0103 return Transition::IsLumi;
0104 }
0105 if (iTrans == "IsEvent") {
0106 return Transition::IsEvent;
0107 }
0108
0109 throw edm::Exception(edm::errors::Configuration) << "Unknown transition type \'" << iTrans << "\'";
0110
0111 return Transition::IsInvalid;
0112 }
0113
0114 std::vector<std::tuple<Phase, edm::EventID, int>> expectedValues(
0115 std::vector<std::pair<Transition, edm::EventID>> const& iTrans, int iNStreams) {
0116 std::vector<std::tuple<Phase, edm::EventID, int>> returnValue;
0117 returnValue.reserve(iTrans.size());
0118
0119 const edm::RunNumber_t maxIDValue = edm::EventID::maxRunNumber();
0120 edm::EventID lastRun = {maxIDValue, 0, 0};
0121 edm::EventID lastLumi = {maxIDValue, maxIDValue, 0};
0122 for (auto const& tran : iTrans) {
0123 switch (tran.first) {
0124 case Transition::IsFile: {
0125 break;
0126 }
0127 case Transition::IsRun: {
0128 if (tran.second != lastRun) {
0129 if (lastRun.run() != maxIDValue) {
0130
0131 for (int i = 0; i < iNStreams; ++i) {
0132 returnValue.emplace_back(Phase::kEndRun, lastRun, i);
0133 }
0134 returnValue.emplace_back(Phase::kEndRun, lastRun, 1000);
0135 }
0136
0137 returnValue.emplace_back(Phase::kBeginRun, tran.second, -1);
0138 for (int i = 0; i < iNStreams; ++i) {
0139 returnValue.emplace_back(Phase::kBeginRun, tran.second, i);
0140 }
0141 lastRun = tran.second;
0142 }
0143 break;
0144 }
0145 case Transition::IsLumi: {
0146 if (tran.second != lastLumi) {
0147 if (lastLumi.run() != maxIDValue) {
0148
0149 for (int i = 0; i < iNStreams; ++i) {
0150 returnValue.emplace_back(Phase::kEndLumi, lastLumi, i);
0151 }
0152 returnValue.emplace_back(Phase::kEndLumi, lastLumi, 1000);
0153 }
0154
0155 returnValue.emplace_back(Phase::kBeginLumi, tran.second, -1);
0156 for (int i = 0; i < iNStreams; ++i) {
0157 returnValue.emplace_back(Phase::kBeginLumi, tran.second, i);
0158 }
0159 lastLumi = tran.second;
0160 }
0161 break;
0162 }
0163 case Transition::IsEvent: {
0164 returnValue.emplace_back(Phase::kEvent, tran.second, -2);
0165 }
0166 case Transition::IsStop:
0167 case Transition::IsInvalid: {
0168 break;
0169 }
0170 }
0171 }
0172 if (lastLumi.run() != maxIDValue) {
0173
0174 for (int i = 0; i < iNStreams; ++i) {
0175 returnValue.emplace_back(Phase::kEndLumi, lastLumi, i);
0176 }
0177 returnValue.emplace_back(Phase::kEndLumi, lastLumi, 1000);
0178 }
0179 if (lastRun.run() != maxIDValue) {
0180
0181 for (int i = 0; i < iNStreams; ++i) {
0182 returnValue.emplace_back(Phase::kEndRun, lastRun, i);
0183 }
0184 returnValue.emplace_back(Phase::kEndRun, lastRun, 1000);
0185 }
0186 return returnValue;
0187 }
0188
0189 }
0190
0191 CheckTransitions::CheckTransitions(ParameterSet const& iPS, ActivityRegistry& iRegistry) {
0192 for (auto const& p : iPS.getUntrackedParameter<std::vector<edm::ParameterSet>>("transitions")) {
0193 m_expectedTransitions.emplace_back(stringToType(p.getUntrackedParameter<std::string>("type")),
0194 p.getUntrackedParameter<EventID>("id"));
0195 }
0196
0197 iRegistry.watchPreallocate(this, &CheckTransitions::preallocate);
0198
0199 iRegistry.watchPostEndJob(this, &CheckTransitions::postEndJob);
0200
0201 iRegistry.watchPreOpenFile(this, &CheckTransitions::preOpenFile);
0202
0203 iRegistry.watchPreCloseFile(this, &CheckTransitions::preCloseFile);
0204
0205 iRegistry.watchPreGlobalBeginRun(this, &CheckTransitions::preGlobalBeginRun);
0206
0207 iRegistry.watchPreGlobalEndRun(this, &CheckTransitions::preGlobalEndRun);
0208
0209 iRegistry.watchPreStreamBeginRun(this, &CheckTransitions::preStreamBeginRun);
0210
0211 iRegistry.watchPreStreamEndRun(this, &CheckTransitions::preStreamEndRun);
0212
0213 iRegistry.watchPreGlobalBeginLumi(this, &CheckTransitions::preGlobalBeginLumi);
0214
0215 iRegistry.watchPreGlobalEndLumi(this, &CheckTransitions::preGlobalEndLumi);
0216
0217 iRegistry.watchPreStreamBeginLumi(this, &CheckTransitions::preStreamBeginLumi);
0218
0219 iRegistry.watchPreStreamEndLumi(this, &CheckTransitions::preStreamEndLumi);
0220
0221 iRegistry.watchPreEvent(this, &CheckTransitions::preEvent);
0222 }
0223
0224 CheckTransitions::~CheckTransitions() noexcept(false) {
0225 if (m_failed) {
0226 throw edm::Exception(errors::EventProcessorFailure) << "incorrect transtions";
0227 }
0228 }
0229
0230 void CheckTransitions::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0231 ParameterSetDescription desc;
0232 desc.setComment("Checks that the transitions specified occur during the job.");
0233
0234 ParameterSetDescription trans;
0235 trans.addUntracked<std::string>("type");
0236 trans.addUntracked<edm::EventID>("id");
0237 desc.addVPSetUntracked("transitions", trans, {{}});
0238 descriptions.add("CheckTransitions", desc);
0239 }
0240
0241 void CheckTransitions::preallocate(service::SystemBounds const& bounds) { m_nstreams = bounds.maxNumberOfStreams(); }
0242
0243 void CheckTransitions::postEndJob() {
0244 auto expectedV = expectedValues(m_expectedTransitions, m_nstreams);
0245
0246 std::vector<std::tuple<Phase, edm::EventID, int>> orderedSeen;
0247 orderedSeen.reserve(m_seenTransitions.size());
0248 for (auto const& i : m_seenTransitions) {
0249
0250 auto s = std::get<2>(i);
0251 if (std::get<1>(i).event() > 0) {
0252 s = -2;
0253 }
0254 orderedSeen.emplace_back(std::get<0>(i), std::get<1>(i), s);
0255 }
0256 std::sort(orderedSeen.begin(), orderedSeen.end());
0257
0258 auto orderedExpected = expectedV;
0259 std::sort(orderedExpected.begin(), orderedExpected.end());
0260
0261
0262
0263
0264 auto itOS = orderedSeen.begin();
0265 for (auto itOE = orderedExpected.begin(); itOE != orderedExpected.end(); ++itOE) {
0266 if (itOS == orderedSeen.end()) {
0267 break;
0268 }
0269 if (*itOE != *itOS) {
0270 auto syncOE = std::get<1>(*itOE);
0271 auto syncOS = std::get<1>(*itOS);
0272 std::cout << "Different ordering " << syncOE << " " << std::get<2>(*itOE) << "\n"
0273 << " " << syncOS << " " << std::get<2>(*itOS) << "\n";
0274 m_failed = true;
0275 }
0276 ++itOS;
0277 }
0278
0279 if (orderedSeen.size() != orderedExpected.size()) {
0280 std::cout << "Wrong number of transition " << orderedSeen.size() << " " << orderedExpected.size() << std::endl;
0281 m_failed = true;
0282 return;
0283 }
0284 }
0285
0286 void CheckTransitions::preOpenFile(std::string const& lfn) {}
0287
0288 void CheckTransitions::preCloseFile(std::string const& lfn) {}
0289
0290 void CheckTransitions::preGlobalBeginRun(GlobalContext const& gc) {
0291 auto id = gc.luminosityBlockID();
0292 m_seenTransitions.emplace_back(Phase::kBeginRun, edm::EventID{id.run(), 0, 0}, -1);
0293 }
0294
0295 void CheckTransitions::preGlobalEndRun(GlobalContext const& gc) {
0296 auto id = gc.luminosityBlockID();
0297 m_seenTransitions.emplace_back(Phase::kEndRun, edm::EventID{id.run(), 0, 0}, 1000);
0298 }
0299
0300 void CheckTransitions::preStreamBeginRun(StreamContext const& sc) {
0301 m_seenTransitions.emplace_back(Phase::kBeginRun, sc.eventID(), sc.streamID());
0302 }
0303
0304 void CheckTransitions::preStreamEndRun(StreamContext const& sc) {
0305 m_seenTransitions.emplace_back(Phase::kEndRun, sc.eventID(), sc.streamID());
0306 }
0307
0308 void CheckTransitions::preGlobalBeginLumi(GlobalContext const& gc) {
0309 auto id = gc.luminosityBlockID();
0310 m_seenTransitions.emplace_back(Phase::kBeginLumi, edm::EventID{id.run(), id.luminosityBlock(), 0}, -1);
0311 }
0312
0313 void CheckTransitions::preGlobalEndLumi(GlobalContext const& gc) {
0314 auto id = gc.luminosityBlockID();
0315 m_seenTransitions.emplace_back(Phase::kEndLumi, edm::EventID{id.run(), id.luminosityBlock(), 0}, 1000);
0316 }
0317
0318 void CheckTransitions::preStreamBeginLumi(StreamContext const& sc) {
0319 m_seenTransitions.emplace_back(Phase::kBeginLumi, sc.eventID(), sc.streamID());
0320 }
0321
0322 void CheckTransitions::preStreamEndLumi(StreamContext const& sc) {
0323 m_seenTransitions.emplace_back(Phase::kEndLumi, sc.eventID(), sc.streamID());
0324 }
0325
0326 void CheckTransitions::preEvent(StreamContext const& sc) {
0327 m_seenTransitions.emplace_back(Phase::kEvent, sc.eventID(), sc.streamID());
0328 }
0329
0330 using edm::service::CheckTransitions;
0331 DEFINE_FWK_SERVICE(CheckTransitions);