Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:03:39

0001 // -*- C++ -*-
0002 //
0003 // Package:     Services
0004 // Class  :     CheckTransitions
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:  Chris Jones
0010 //         Created:  Thu Sep  8 14:17:58 EDT 2005
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   }  // namespace service
0085 }  // namespace edm
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               //end transitions
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             //begin transitions
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               //end transitions
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             //begin transitions
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       //end transitions
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       //end transitions
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 }  // namespace
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     //      std::cout <<i.first.m_run<<" "<<i.first.m_lumi<<" "<<i.first.m_event<<" "<<i.second<<std::endl;
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   /*   for(auto const& i: expectedV) {
0261    std::cout <<i.first.m_run<<" "<<i.first.m_lumi<<" "<<i.first.m_event<<" "<<i.second<<std::endl;
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);