Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:17

0001 
0002 /*----------------------------------------------------------------------
0003 
0004 Toy edm::global::EDAnalyzer modules of
0005 edm::*Cache templates
0006 for testing purposes only.
0007 
0008 ----------------------------------------------------------------------*/
0009 
0010 #include <atomic>
0011 #include <iostream>
0012 #include <memory>
0013 #include <tuple>
0014 #include <vector>
0015 
0016 #include "DataFormats/Provenance/interface/BranchDescription.h"
0017 #include "DataFormats/TestObjects/interface/ToyProducts.h"
0018 #include "FWCore/Framework/interface/CacheHandle.h"
0019 #include "FWCore/Framework/interface/Event.h"
0020 #include "FWCore/Framework/interface/LuminosityBlock.h"
0021 #include "FWCore/Framework/interface/MakerMacros.h"
0022 #include "FWCore/Framework/interface/moduleAbilities.h"
0023 #include "FWCore/Framework/interface/global/EDAnalyzer.h"
0024 #include "FWCore/Framework/interface/ProcessBlock.h"
0025 #include "FWCore/Framework/interface/Run.h"
0026 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0027 #include "FWCore/Utilities/interface/BranchType.h"
0028 #include "FWCore/Utilities/interface/EDMException.h"
0029 #include "FWCore/Utilities/interface/EDGetToken.h"
0030 #include "FWCore/Utilities/interface/InputTag.h"
0031 
0032 namespace edmtest {
0033   namespace global {
0034 
0035     namespace {
0036       struct Cache {
0037         Cache() : value(0) {}
0038         //Using mutable since we want to update the value.
0039         mutable std::atomic<unsigned int> value;
0040       };
0041 
0042       struct UnsafeCache {
0043         UnsafeCache() : value(0), lumi(0) {}
0044         unsigned int value;
0045         unsigned int lumi;
0046       };
0047 
0048     }  //end anonymous namespace
0049 
0050     class StreamIntAnalyzer : public edm::global::EDAnalyzer<edm::StreamCache<UnsafeCache>> {
0051     public:
0052       explicit StreamIntAnalyzer(edm::ParameterSet const& p)
0053           : trans_(p.getParameter<int>("transitions")), nLumis_(p.getUntrackedParameter<unsigned int>("nLumis", 1)) {
0054         bool verbose = p.getUntrackedParameter<bool>("verbose", true);
0055         callWhenNewProductsRegistered([verbose](edm::BranchDescription const& desc) {
0056           if (verbose) {
0057             std::cout << "global::StreamIntAnalyzer " << desc.moduleLabel() << std::endl;
0058           }
0059         });
0060       }
0061       const unsigned int trans_;
0062       const unsigned int nLumis_;
0063       mutable std::atomic<unsigned int> m_count{0};
0064       mutable std::atomic<unsigned int> m_countStreams{0};
0065       mutable std::atomic<unsigned int> m_countStreamBeginLumiTransitions{0};
0066       mutable std::atomic<unsigned int> m_countStreamEndLumiTransitions{0};
0067 
0068       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID iID) const override {
0069         ++m_count;
0070         ++m_countStreams;
0071         auto pCache = std::make_unique<UnsafeCache>();
0072         pCache->value = iID.value();
0073         return pCache;
0074       }
0075 
0076       void streamBeginRun(edm::StreamID iID, edm::Run const&, edm::EventSetup const&) const override {
0077         ++m_count;
0078         if ((streamCache(iID))->value != iID.value()) {
0079           throw cms::Exception("cache value")
0080               << "StreamIntAnalyzer cache value " << (streamCache(iID))->value << " but it was supposed to be " << iID;
0081         }
0082       }
0083 
0084       void streamBeginLuminosityBlock(edm::StreamID iID,
0085                                       edm::LuminosityBlock const&,
0086                                       edm::EventSetup const&) const override {
0087         ++m_countStreamBeginLumiTransitions;
0088         if ((streamCache(iID))->value != iID.value()) {
0089           throw cms::Exception("cache value")
0090               << "StreamIntAnalyzer cache value " << (streamCache(iID))->value << " but it was supposed to be " << iID;
0091         }
0092       }
0093 
0094       void analyze(edm::StreamID iID, const edm::Event&, const edm::EventSetup&) const override {
0095         ++m_count;
0096         if ((streamCache(iID))->value != iID.value()) {
0097           throw cms::Exception("cache value")
0098               << "StreamIntAnalyzer cache value " << (streamCache(iID))->value << " but it was supposed to be " << iID;
0099         }
0100       }
0101 
0102       void streamEndLuminosityBlock(edm::StreamID iID,
0103                                     edm::LuminosityBlock const&,
0104                                     edm::EventSetup const&) const override {
0105         ++m_countStreamEndLumiTransitions;
0106         if ((streamCache(iID))->value != iID.value()) {
0107           throw cms::Exception("cache value")
0108               << "StreamIntAnalyzer cache value " << (streamCache(iID))->value << " but it was supposed to be " << iID;
0109         }
0110       }
0111 
0112       void streamEndRun(edm::StreamID iID, edm::Run const&, edm::EventSetup const&) const override {
0113         ++m_count;
0114         if ((streamCache(iID))->value != iID.value()) {
0115           throw cms::Exception("cache value")
0116               << "StreamIntAnalyzer cache value " << (streamCache(iID))->value << " but it was supposed to be " << iID;
0117         }
0118       }
0119 
0120       void endStream(edm::StreamID iID) const override {
0121         ++m_count;
0122         if ((streamCache(iID))->value != iID.value()) {
0123           throw cms::Exception("cache value")
0124               << "StreamIntAnalyzer cache value " << (streamCache(iID))->value << " but it was supposed to be " << iID;
0125         }
0126       }
0127 
0128       void endJob() override {
0129         if (m_count != trans_) {
0130           throw cms::Exception("transitions")
0131               << "StreamIntAnalyzer transitions " << m_count << " but it was supposed to be " << trans_;
0132         }
0133         unsigned int nStreamBeginLumiTransitions = m_countStreamBeginLumiTransitions.load();
0134         unsigned int nStreamEndLumiTransitions = m_countStreamEndLumiTransitions.load();
0135         unsigned int nStreams = m_countStreams.load();
0136         if (nStreamBeginLumiTransitions < nLumis_ || nStreamBeginLumiTransitions > (nLumis_ * nStreams)) {
0137           throw cms::Exception("transitions")
0138               << "StreamIntAnalyzer stream begin lumi transitions " << nStreamBeginLumiTransitions
0139               << " but it was supposed to be between " << nLumis_ << " and " << nLumis_ * nStreams;
0140         }
0141         if (nStreamEndLumiTransitions != nStreamBeginLumiTransitions) {
0142           throw cms::Exception("transitions")
0143               << "StreamIntAnalyzer stream end lumi transitions " << nStreamEndLumiTransitions
0144               << " does not equal stream begin lumi transitions " << nStreamBeginLumiTransitions;
0145         }
0146       }
0147     };
0148 
0149     class RunIntAnalyzer : public edm::global::EDAnalyzer<edm::RunCache<Cache>> {
0150     public:
0151       explicit RunIntAnalyzer(edm::ParameterSet const& p)
0152           : trans_(p.getParameter<int>("transitions")), cvalue_(p.getParameter<int>("cachevalue")) {}
0153       const unsigned int trans_;
0154       const unsigned int cvalue_;
0155       mutable std::atomic<unsigned int> m_count{0};
0156 
0157       std::shared_ptr<Cache> globalBeginRun(edm::Run const&, edm::EventSetup const&) const override {
0158         ++m_count;
0159         return std::make_shared<Cache>();
0160       }
0161 
0162       void analyze(edm::StreamID iID, const edm::Event& iEvent, const edm::EventSetup&) const override {
0163         ++m_count;
0164         ++((runCache(iEvent.getRun().index()))->value);
0165       }
0166 
0167       void globalEndRun(edm::Run const& iRun, edm::EventSetup const&) const override {
0168         ++m_count;
0169         if ((runCache(iRun.index()))->value != cvalue_) {
0170           throw cms::Exception("cache value") << "RunIntAnalyzer cache value " << (runCache(iRun.index()))->value
0171                                               << " but it was supposed to be " << cvalue_;
0172         }
0173       }
0174 
0175       void endJob() override {
0176         if (m_count != trans_) {
0177           throw cms::Exception("transitions")
0178               << "RunIntAnalyzer transitions " << m_count << " but it was supposed to be " << trans_;
0179         }
0180       }
0181     };
0182 
0183     class LumiIntAnalyzer : public edm::global::EDAnalyzer<edm::LuminosityBlockCache<Cache>> {
0184     public:
0185       explicit LumiIntAnalyzer(edm::ParameterSet const& p)
0186           : trans_(p.getParameter<int>("transitions")), cvalue_(p.getParameter<int>("cachevalue")) {
0187         // just to create a data dependence
0188         auto const& tag = p.getParameter<edm::InputTag>("moduleLabel");
0189         if (not tag.label().empty()) {
0190           consumes<unsigned int, edm::InLumi>(tag);
0191         }
0192       }
0193       const unsigned int trans_;
0194       const unsigned int cvalue_;
0195       mutable std::atomic<unsigned int> m_count{0};
0196 
0197       std::shared_ptr<Cache> globalBeginLuminosityBlock(edm::LuminosityBlock const&,
0198                                                         edm::EventSetup const&) const override {
0199         ++m_count;
0200         return std::make_shared<Cache>();
0201       }
0202 
0203       void analyze(edm::StreamID, const edm::Event& iEvent, const edm::EventSetup&) const override {
0204         ++m_count;
0205         ++(luminosityBlockCache(iEvent.getLuminosityBlock().index())->value);
0206       }
0207 
0208       void globalEndLuminosityBlock(edm::LuminosityBlock const& iLB, edm::EventSetup const&) const override {
0209         ++m_count;
0210         if ((luminosityBlockCache(iLB.index()))->value != cvalue_) {
0211           throw cms::Exception("cache value")
0212               << "LumiIntAnalyzer cache value " << (luminosityBlockCache(iLB.index()))->value
0213               << " but it was supposed to be " << cvalue_;
0214         }
0215       }
0216 
0217       void endJob() override {
0218         if (m_count != trans_) {
0219           throw cms::Exception("transitions")
0220               << "LumiIntAnalyzer transitions " << m_count << " but it was supposed to be " << trans_;
0221         }
0222       }
0223     };
0224 
0225     class RunSummaryIntAnalyzer
0226         : public edm::global::EDAnalyzer<edm::StreamCache<UnsafeCache>, edm::RunSummaryCache<UnsafeCache>> {
0227     public:
0228       explicit RunSummaryIntAnalyzer(edm::ParameterSet const& p)
0229           : trans_(p.getParameter<int>("transitions")), cvalue_(p.getParameter<int>("cachevalue")) {}
0230       const unsigned int trans_;
0231       const unsigned int cvalue_;
0232       mutable std::atomic<unsigned int> m_count{0};
0233 
0234       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID) const override {
0235         ++m_count;
0236         return std::make_unique<UnsafeCache>();
0237       }
0238 
0239       std::shared_ptr<UnsafeCache> globalBeginRunSummary(edm::Run const&, edm::EventSetup const&) const override {
0240         ++m_count;
0241         return std::make_shared<UnsafeCache>();
0242       }
0243 
0244       void analyze(edm::StreamID iID, const edm::Event&, const edm::EventSetup&) const override {
0245         ++m_count;
0246         ++((streamCache(iID))->value);
0247       }
0248 
0249       void streamEndRunSummary(edm::StreamID iID,
0250                                edm::Run const&,
0251                                edm::EventSetup const&,
0252                                UnsafeCache* gCache) const override {
0253         ++m_count;
0254         gCache->value += (streamCache(iID))->value;
0255         (streamCache(iID))->value = 0;
0256       }
0257 
0258       void globalEndRunSummary(edm::Run const&, edm::EventSetup const&, UnsafeCache* gCache) const override {
0259         ++m_count;
0260         if (gCache->value != cvalue_) {
0261           throw cms::Exception("cache value")
0262               << "RunSummaryIntAnalyzer cache value " << gCache->value << " but it was supposed to be " << cvalue_;
0263         }
0264       }
0265 
0266       void endJob() override {
0267         if (m_count != trans_) {
0268           throw cms::Exception("transitions")
0269               << "RunSummaryIntAnalyzer transitions " << m_count << " but it was supposed to be " << trans_;
0270         }
0271       }
0272     };
0273 
0274     class LumiSummaryIntAnalyzer
0275         : public edm::global::EDAnalyzer<edm::StreamCache<UnsafeCache>, edm::LuminosityBlockSummaryCache<UnsafeCache>> {
0276     public:
0277       explicit LumiSummaryIntAnalyzer(edm::ParameterSet const& p)
0278           : trans_(p.getParameter<int>("transitions")), cvalue_(p.getParameter<int>("cachevalue")) {}
0279       const unsigned int trans_;
0280       const unsigned int cvalue_;
0281       mutable std::atomic<unsigned int> m_count{0};
0282       mutable std::atomic<unsigned int> m_countLumis{0};
0283       mutable std::atomic<unsigned int> m_countStreams{0};
0284       mutable std::atomic<unsigned int> m_countStreamLumiTransitions{0};
0285 
0286       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID) const override {
0287         ++m_count;
0288         ++m_countStreams;
0289         return std::make_unique<UnsafeCache>();
0290       }
0291 
0292       std::shared_ptr<UnsafeCache> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const& iLB,
0293                                                                      edm::EventSetup const&) const override {
0294         ++m_count;
0295         ++m_countLumis;
0296         auto gCache = std::make_shared<UnsafeCache>();
0297         gCache->lumi = iLB.luminosityBlockAuxiliary().luminosityBlock();
0298         return gCache;
0299       }
0300 
0301       void analyze(edm::StreamID iID, const edm::Event& iEvent, const edm::EventSetup&) const override {
0302         ++m_count;
0303         ++((streamCache(iID))->value);
0304       }
0305 
0306       void streamEndLuminosityBlockSummary(edm::StreamID iID,
0307                                            edm::LuminosityBlock const& iLB,
0308                                            edm::EventSetup const&,
0309                                            UnsafeCache* gCache) const override {
0310         ++m_countStreamLumiTransitions;
0311         if (gCache->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0312           throw cms::Exception("UnexpectedValue")
0313               << "streamEndLuminosityBlockSummary unexpected lumi number in Stream " << iID.value();
0314         }
0315         gCache->value += (streamCache(iID))->value;
0316         (streamCache(iID))->value = 0;
0317       }
0318 
0319       void globalEndLuminosityBlockSummary(edm::LuminosityBlock const& iLB,
0320                                            edm::EventSetup const&,
0321                                            UnsafeCache* gCache) const override {
0322         ++m_count;
0323         if (gCache->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0324           throw cms::Exception("UnexpectedValue") << "globalEndLuminosityBlockSummary unexpected lumi number";
0325         }
0326         if (gCache->value != cvalue_) {
0327           throw cms::Exception("cache value")
0328               << "LumiSummaryIntAnalyzer cache value " << gCache->value << " but it was supposed to be " << cvalue_;
0329         }
0330       }
0331 
0332       void endJob() override {
0333         if (m_count != trans_) {
0334           throw cms::Exception("transitions")
0335               << "LumiSummaryIntAnalyzer transitions " << m_count << " but it was supposed to be " << trans_;
0336         }
0337         unsigned int nStreamLumiTransitions = m_countStreamLumiTransitions.load();
0338         unsigned int nLumis = m_countLumis.load();
0339         unsigned int nStreams = m_countStreams.load();
0340         if (nStreamLumiTransitions < nLumis || nStreamLumiTransitions > (nLumis * nStreams)) {
0341           throw cms::Exception("transitions")
0342               << "LumiSummaryIntAnalyzer stream lumi transitions " << nStreamLumiTransitions
0343               << " but it was supposed to be between " << nLumis << " and " << nLumis * nStreams;
0344         }
0345       }
0346     };
0347 
0348     class ProcessBlockIntAnalyzer : public edm::global::EDAnalyzer<edm::WatchProcessBlock,
0349                                                                    edm::StreamCache<UnsafeCache>,
0350                                                                    edm::RunCache<UnsafeCache>> {
0351     public:
0352       explicit ProcessBlockIntAnalyzer(edm::ParameterSet const& p) : trans_(p.getParameter<int>("transitions")) {
0353         {
0354           auto tag = p.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0355           if (not tag.label().empty()) {
0356             getTokenBegin_ = consumes<unsigned int, edm::InProcess>(tag);
0357           }
0358         }
0359         {
0360           auto tag = p.getParameter<edm::InputTag>("consumesEndProcessBlock");
0361           if (not tag.label().empty()) {
0362             getTokenEnd_ = consumes<unsigned int, edm::InProcess>(tag);
0363           }
0364         }
0365       }
0366 
0367       void beginJob() override {
0368         if (m_count != 0) {
0369           throw cms::Exception("transitions")
0370               << "ProcessBlockIntAnalyzer::beginJob transition " << m_count << " but it was supposed to be " << 0;
0371         }
0372         ++m_count;
0373       }
0374 
0375       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID) const override {
0376         if (m_count < 1) {
0377           throw cms::Exception("transitions") << "ProcessBlockIntAnalyzer::beginStream transition " << m_count
0378                                               << " but it was supposed to be at least 1";
0379         }
0380         ++m_count;
0381         return std::make_unique<UnsafeCache>();
0382       }
0383 
0384       void beginProcessBlock(edm::ProcessBlock const& processBlock) override {
0385         if (m_count != 5) {
0386           throw cms::Exception("transitions") << "ProcessBlockIntAnalyzer::beginProcessBlock transition " << m_count
0387                                               << " but it was supposed to be " << 5;
0388         }
0389         ++m_count;
0390 
0391         const unsigned int valueToGet = 11;
0392         if (not getTokenBegin_.isUninitialized()) {
0393           if (processBlock.get(getTokenBegin_) != valueToGet) {
0394             throw cms::Exception("BadValue")
0395                 << "expected " << valueToGet << " but got " << processBlock.get(getTokenBegin_);
0396           }
0397         }
0398       }
0399 
0400       std::shared_ptr<UnsafeCache> globalBeginRun(edm::Run const&, edm::EventSetup const&) const override {
0401         if (m_count < 6u) {
0402           throw cms::Exception("transitions") << "ProcessBlockIntAnalyzer::globalBeginRun transition " << m_count
0403                                               << " but it was supposed to be at least 6";
0404         }
0405         ++m_count;
0406         return std::make_shared<UnsafeCache>();
0407       }
0408 
0409       void analyze(edm::StreamID iID, edm::Event const&, edm::EventSetup const&) const override {
0410         if (m_count < 7u) {
0411           throw cms::Exception("out of sequence") << "analyze before beginProcessBlock " << m_count;
0412         }
0413         ++m_count;
0414       }
0415 
0416       void globalEndRun(edm::Run const&, edm::EventSetup const&) const override {
0417         if (m_count < 15u) {
0418           throw cms::Exception("transitions") << "ProcessBlockIntAnalyzer::globalEndRun transition " << m_count
0419                                               << " but it was supposed to be at least 15";
0420         }
0421         ++m_count;
0422       }
0423 
0424       void endProcessBlock(edm::ProcessBlock const& processBlock) override {
0425         if (m_count != 646u) {
0426           throw cms::Exception("transitions") << "ProcessBlockIntAnalyzer::endProcessBlock transition " << m_count
0427                                               << " but it was supposed to be " << 646;
0428         }
0429         ++m_count;
0430         {
0431           const unsigned int valueToGet = 11;
0432           if (not getTokenBegin_.isUninitialized()) {
0433             if (processBlock.get(getTokenBegin_) != valueToGet) {
0434               throw cms::Exception("BadValue")
0435                   << "expected " << valueToGet << " but got " << processBlock.get(getTokenBegin_);
0436             }
0437           }
0438         }
0439         {
0440           const unsigned int valueToGet = 21;
0441           if (not getTokenEnd_.isUninitialized()) {
0442             if (processBlock.get(getTokenEnd_) != valueToGet) {
0443               throw cms::Exception("BadValue")
0444                   << "expected " << valueToGet << " but got " << processBlock.get(getTokenEnd_);
0445             }
0446           }
0447         }
0448       }
0449 
0450       void endStream(edm::StreamID) const override {
0451         if (m_count < 647u) {
0452           throw cms::Exception("transitions") << "ProcessBlockIntAnalyzer::endStream transition " << m_count
0453                                               << " but it was supposed to be at least 647";
0454         }
0455         ++m_count;
0456       }
0457 
0458       void endJob() override {
0459         if (m_count != 651u) {
0460           throw cms::Exception("transitions")
0461               << "ProcessBlockIntAnalyzer::endJob transition " << m_count << " but it was supposed to be " << 651;
0462         }
0463         ++m_count;
0464       }
0465 
0466       ~ProcessBlockIntAnalyzer() {
0467         if (m_count != trans_) {
0468           throw cms::Exception("transitions")
0469               << "ProcessBlockIntAnalyzer transitions " << m_count << " but it was supposed to be " << trans_;
0470         }
0471       }
0472 
0473     private:
0474       const unsigned int trans_;
0475       mutable std::atomic<unsigned int> m_count{0};
0476       edm::EDGetTokenT<unsigned int> getTokenBegin_;
0477       edm::EDGetTokenT<unsigned int> getTokenEnd_;
0478     };
0479 
0480     class TestInputProcessBlockCache {
0481     public:
0482       long long int value_ = 0;
0483     };
0484 
0485     class TestInputProcessBlockCache1 {
0486     public:
0487       long long int value_ = 0;
0488     };
0489 
0490     class InputProcessBlockIntAnalyzer
0491         : public edm::global::EDAnalyzer<
0492               edm::InputProcessBlockCache<int, TestInputProcessBlockCache, TestInputProcessBlockCache1>> {
0493     public:
0494       explicit InputProcessBlockIntAnalyzer(edm::ParameterSet const& pset) {
0495         expectedTransitions_ = pset.getParameter<int>("transitions");
0496         expectedByRun_ = pset.getParameter<std::vector<int>>("expectedByRun");
0497         expectedSum_ = pset.getParameter<int>("expectedSum");
0498         {
0499           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0500           if (not tag.label().empty()) {
0501             getTokenBegin_ = consumes<IntProduct, edm::InProcess>(tag);
0502           }
0503         }
0504         {
0505           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock");
0506           if (not tag.label().empty()) {
0507             getTokenEnd_ = consumes<IntProduct, edm::InProcess>(tag);
0508           }
0509         }
0510         {
0511           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlockM");
0512           if (not tag.label().empty()) {
0513             getTokenBeginM_ = consumes<IntProduct, edm::InProcess>(tag);
0514           }
0515         }
0516         {
0517           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlockM");
0518           if (not tag.label().empty()) {
0519             getTokenEndM_ = consumes<IntProduct, edm::InProcess>(tag);
0520           }
0521         }
0522         registerProcessBlockCacheFiller<int>(
0523             getTokenBegin_, [this](edm::ProcessBlock const& processBlock, std::shared_ptr<int> const& previousCache) {
0524               auto returnValue = std::make_shared<int>(0);
0525               *returnValue += processBlock.get(getTokenBegin_).value;
0526               *returnValue += processBlock.get(getTokenEnd_).value;
0527               ++transitions_;
0528               return returnValue;
0529             });
0530         registerProcessBlockCacheFiller<1>(getTokenBegin_,
0531                                            [this](edm::ProcessBlock const& processBlock,
0532                                                   std::shared_ptr<TestInputProcessBlockCache> const& previousCache) {
0533                                              auto returnValue = std::make_shared<TestInputProcessBlockCache>();
0534                                              returnValue->value_ += processBlock.get(getTokenBegin_).value;
0535                                              returnValue->value_ += processBlock.get(getTokenEnd_).value;
0536                                              ++transitions_;
0537                                              return returnValue;
0538                                            });
0539         registerProcessBlockCacheFiller<TestInputProcessBlockCache1>(
0540             getTokenBegin_,
0541             [this](edm::ProcessBlock const& processBlock,
0542                    std::shared_ptr<TestInputProcessBlockCache1> const& previousCache) {
0543               auto returnValue = std::make_shared<TestInputProcessBlockCache1>();
0544               returnValue->value_ += processBlock.get(getTokenBegin_).value;
0545               returnValue->value_ += processBlock.get(getTokenEnd_).value;
0546               ++transitions_;
0547               return returnValue;
0548             });
0549       }
0550 
0551       void accessInputProcessBlock(edm::ProcessBlock const& processBlock) override {
0552         if (processBlock.processName() == "PROD1") {
0553           sum_ += processBlock.get(getTokenBegin_).value;
0554           sum_ += processBlock.get(getTokenEnd_).value;
0555         }
0556         if (processBlock.processName() == "MERGE") {
0557           sum_ += processBlock.get(getTokenBeginM_).value;
0558           sum_ += processBlock.get(getTokenEndM_).value;
0559         }
0560         ++transitions_;
0561       }
0562 
0563       void analyze(edm::StreamID, edm::Event const& event, edm::EventSetup const&) const override {
0564         auto cacheTuple = processBlockCaches(event);
0565         if (!expectedByRun_.empty()) {
0566           if (expectedByRun_.at(event.run() - 1) != *std::get<edm::CacheHandle<int>>(cacheTuple)) {
0567             throw cms::Exception("UnexpectedValue")
0568                 << "InputProcessBlockIntAnalyzer::analyze cached value was "
0569                 << *std::get<edm::CacheHandle<int>>(cacheTuple) << " but it was supposed to be "
0570                 << expectedByRun_.at(event.run() - 1);
0571           }
0572           if (expectedByRun_.at(event.run() - 1) != std::get<1>(cacheTuple)->value_) {
0573             throw cms::Exception("UnexpectedValue")
0574                 << "InputProcessBlockIntAnalyzer::analyze second cached value was " << std::get<1>(cacheTuple)->value_
0575                 << " but it was supposed to be " << expectedByRun_.at(event.run() - 1);
0576           }
0577           if (expectedByRun_.at(event.run() - 1) !=
0578               std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_) {
0579             throw cms::Exception("UnexpectedValue")
0580                 << "InputProcessBlockIntAnalyzer::analyze third cached value was "
0581                 << std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_
0582                 << " but it was supposed to be " << expectedByRun_.at(event.run() - 1);
0583           }
0584         }
0585         ++transitions_;
0586       }
0587 
0588       void endJob() override {
0589         if (transitions_ != expectedTransitions_) {
0590           throw cms::Exception("transitions") << "InputProcessBlockIntAnalyzer transitions " << transitions_
0591                                               << " but it was supposed to be " << expectedTransitions_;
0592         }
0593         if (sum_ != expectedSum_) {
0594           throw cms::Exception("UnexpectedValue")
0595               << "InputProcessBlockIntAnalyzer sum " << sum_ << " but it was supposed to be " << expectedSum_;
0596         }
0597         if (cacheSize() > 0u) {
0598           throw cms::Exception("UnexpectedValue")
0599               << "InputProcessBlockIntAnalyzer cache size not zero at endJob " << cacheSize();
0600         }
0601       }
0602 
0603     private:
0604       edm::EDGetTokenT<IntProduct> getTokenBegin_;
0605       edm::EDGetTokenT<IntProduct> getTokenEnd_;
0606       edm::EDGetTokenT<IntProduct> getTokenBeginM_;
0607       edm::EDGetTokenT<IntProduct> getTokenEndM_;
0608       mutable std::atomic<unsigned int> transitions_{0};
0609       int sum_{0};
0610       unsigned int expectedTransitions_{0};
0611       std::vector<int> expectedByRun_;
0612       int expectedSum_{0};
0613     };
0614 
0615     class InputProcessBlockAnalyzerThreeTags
0616         : public edm::global::EDAnalyzer<
0617               edm::InputProcessBlockCache<int, TestInputProcessBlockCache, TestInputProcessBlockCache1>> {
0618     public:
0619       explicit InputProcessBlockAnalyzerThreeTags(edm::ParameterSet const& pset) {
0620         expectedTransitions_ = pset.getParameter<int>("transitions");
0621         expectedByRun0_ = pset.getParameter<std::vector<int>>("expectedByRun0");
0622         expectedByRun1_ = pset.getParameter<std::vector<int>>("expectedByRun1");
0623         expectedByRun2_ = pset.getParameter<std::vector<int>>("expectedByRun2");
0624         {
0625           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock0");
0626           if (not tag.label().empty()) {
0627             getTokenBegin0_ = consumes<IntProduct, edm::InProcess>(tag);
0628           }
0629         }
0630         {
0631           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock0");
0632           if (not tag.label().empty()) {
0633             getTokenEnd0_ = consumes<IntProduct, edm::InProcess>(tag);
0634           }
0635         }
0636         {
0637           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock1");
0638           if (not tag.label().empty()) {
0639             getTokenBegin1_ = consumes<IntProduct, edm::InProcess>(tag);
0640           }
0641         }
0642         {
0643           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock1");
0644           if (not tag.label().empty()) {
0645             getTokenEnd1_ = consumes<IntProduct, edm::InProcess>(tag);
0646           }
0647         }
0648         {
0649           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock2");
0650           if (not tag.label().empty()) {
0651             getTokenBegin2_ = consumes<IntProduct, edm::InProcess>(tag);
0652           }
0653         }
0654         {
0655           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock2");
0656           if (not tag.label().empty()) {
0657             getTokenEnd2_ = consumes<IntProduct, edm::InProcess>(tag);
0658           }
0659         }
0660         registerProcessBlockCacheFiller<int>(
0661             getTokenBegin0_, [this](edm::ProcessBlock const& processBlock, std::shared_ptr<int> const& previousCache) {
0662               auto returnValue = std::make_shared<int>(0);
0663               *returnValue += processBlock.get(getTokenBegin0_).value;
0664               *returnValue += processBlock.get(getTokenEnd0_).value;
0665               ++transitions_;
0666               return returnValue;
0667             });
0668         registerProcessBlockCacheFiller<1>(getTokenBegin1_,
0669                                            [this](edm::ProcessBlock const& processBlock,
0670                                                   std::shared_ptr<TestInputProcessBlockCache> const& previousCache) {
0671                                              auto returnValue = std::make_shared<TestInputProcessBlockCache>();
0672                                              returnValue->value_ += processBlock.get(getTokenBegin1_).value;
0673                                              returnValue->value_ += processBlock.get(getTokenEnd1_).value;
0674                                              ++transitions_;
0675                                              return returnValue;
0676                                            });
0677         registerProcessBlockCacheFiller<TestInputProcessBlockCache1>(
0678             getTokenBegin2_,
0679             [this](edm::ProcessBlock const& processBlock,
0680                    std::shared_ptr<TestInputProcessBlockCache1> const& previousCache) {
0681               auto returnValue = std::make_shared<TestInputProcessBlockCache1>();
0682               returnValue->value_ += processBlock.get(getTokenBegin2_).value;
0683               returnValue->value_ += processBlock.get(getTokenEnd2_).value;
0684               ++transitions_;
0685               return returnValue;
0686             });
0687       }
0688 
0689       void analyze(edm::StreamID, edm::Event const& event, edm::EventSetup const&) const override {
0690         auto cacheTuple = processBlockCaches(event);
0691         if (expectedByRun0_.empty()) {
0692           if (std::get<edm::CacheHandle<int>>(cacheTuple).isValid()) {
0693             throw cms::Exception("UnexpectedValue")
0694                 << "InputProcessBlockAnalyzerThreeTags::analyze expected invalid CacheHandle for cache 0";
0695           }
0696         } else {
0697           if (expectedByRun0_.at(event.run() - 1) != *std::get<edm::CacheHandle<int>>(cacheTuple)) {
0698             throw cms::Exception("UnexpectedValue")
0699                 << "InputProcessBlockAnalyzerThreeTags::analyze zeroth cached value was "
0700                 << *std::get<edm::CacheHandle<int>>(cacheTuple) << " but it was supposed to be "
0701                 << expectedByRun0_.at(event.run() - 1);
0702           }
0703         }
0704         if (expectedByRun1_.empty()) {
0705           if (std::get<1>(cacheTuple).isValid()) {
0706             throw cms::Exception("UnexpectedValue")
0707                 << "InputProcessBlockAnalyzerThreeTags::analyze expected invalid CacheHandle for cache 1";
0708           }
0709         } else {
0710           if (expectedByRun1_.at(event.run() - 1) != std::get<1>(cacheTuple)->value_) {
0711             throw cms::Exception("UnexpectedValue")
0712                 << "InputProcessBlockAnalyzerThreeTags::analyze first cached value was "
0713                 << std::get<1>(cacheTuple)->value_ << " but it was supposed to be "
0714                 << expectedByRun1_.at(event.run() - 1);
0715           }
0716         }
0717         if (expectedByRun2_.empty()) {
0718           if (std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple).isValid()) {
0719             throw cms::Exception("UnexpectedValue")
0720                 << "InputProcessBlockAnalyzerThreeTags::analyze expected invalid CacheHandle for cache 2";
0721           }
0722         } else {
0723           if (expectedByRun2_.at(event.run() - 1) !=
0724               std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_) {
0725             throw cms::Exception("UnexpectedValue")
0726                 << "InputProcessBlockAnalyzerThreeTags::analyze second cached value was "
0727                 << std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_
0728                 << " but it was supposed to be " << expectedByRun2_.at(event.run() - 1);
0729           }
0730         }
0731         ++transitions_;
0732       }
0733 
0734       void endJob() override {
0735         if (transitions_ != expectedTransitions_) {
0736           throw cms::Exception("transitions") << "InputProcessBlockAnalyzerThreeTags transitions " << transitions_
0737                                               << " but it was supposed to be " << expectedTransitions_;
0738         }
0739         if (cacheSize() > 0u) {
0740           throw cms::Exception("UnexpectedValue")
0741               << "InputProcessBlockAnalyzerThreeTags cache size not zero at endJob " << cacheSize();
0742         }
0743       }
0744 
0745     private:
0746       edm::EDGetTokenT<IntProduct> getTokenBegin0_;
0747       edm::EDGetTokenT<IntProduct> getTokenEnd0_;
0748       edm::EDGetTokenT<IntProduct> getTokenBegin1_;
0749       edm::EDGetTokenT<IntProduct> getTokenEnd1_;
0750       edm::EDGetTokenT<IntProduct> getTokenBegin2_;
0751       edm::EDGetTokenT<IntProduct> getTokenEnd2_;
0752       mutable std::atomic<unsigned int> transitions_{0};
0753       unsigned int expectedTransitions_{0};
0754       std::vector<int> expectedByRun0_;
0755       std::vector<int> expectedByRun1_;
0756       std::vector<int> expectedByRun2_;
0757     };
0758 
0759     class InputProcessBlockAnalyzerReuseCache
0760         : public edm::global::EDAnalyzer<
0761               edm::InputProcessBlockCache<int, TestInputProcessBlockCache, TestInputProcessBlockCache1>> {
0762     public:
0763       explicit InputProcessBlockAnalyzerReuseCache(edm::ParameterSet const& pset) {
0764         expectedTransitions_ = pset.getParameter<int>("transitions");
0765         expectedByRun_ = pset.getParameter<std::vector<int>>("expectedByRun");
0766         {
0767           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0768           if (not tag.label().empty()) {
0769             getTokenBegin_ = consumes<IntProduct, edm::InProcess>(tag);
0770           }
0771         }
0772         {
0773           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock");
0774           if (not tag.label().empty()) {
0775             getTokenEnd_ = consumes<IntProduct, edm::InProcess>(tag);
0776           }
0777         }
0778         registerProcessBlockCacheFiller<TestInputProcessBlockCache1>(
0779             getTokenBegin_,
0780             [this](edm::ProcessBlock const& processBlock,
0781                    std::shared_ptr<TestInputProcessBlockCache1> const& previousCache) {
0782               ++transitions_;
0783               auto returnValue = std::make_shared<TestInputProcessBlockCache1>();
0784               if (previousCache) {
0785                 returnValue = previousCache;
0786                 return returnValue;
0787               }
0788               returnValue->value_ += processBlock.get(getTokenBegin_).value;
0789               returnValue->value_ += processBlock.get(getTokenEnd_).value;
0790               return returnValue;
0791             });
0792       }
0793 
0794       void analyze(edm::StreamID, edm::Event const& event, edm::EventSetup const&) const override {
0795         auto cacheTuple = processBlockCaches(event);
0796         if (!expectedByRun_.empty()) {
0797           if (expectedByRun_.at(event.run() - 1) !=
0798               std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_) {
0799             throw cms::Exception("UnexpectedValue")
0800                 << "InputProcessBlockAnalyzerReuseCache::analyze cached value was "
0801                 << std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_
0802                 << " but it was supposed to be " << expectedByRun_.at(event.run() - 1);
0803           }
0804         }
0805         ++transitions_;
0806       }
0807 
0808       void endJob() override {
0809         if (transitions_ != expectedTransitions_) {
0810           throw cms::Exception("transitions") << "InputProcessBlockAnalyzerReuseCache transitions " << transitions_
0811                                               << " but it was supposed to be " << expectedTransitions_;
0812         }
0813         if (cacheSize() > 0u) {
0814           throw cms::Exception("UnexpectedValue")
0815               << "InputProcessBlockAnalyzerReuseCache cache size not zero at endJob " << cacheSize();
0816         }
0817       }
0818 
0819     private:
0820       edm::EDGetTokenT<IntProduct> getTokenBegin_;
0821       edm::EDGetTokenT<IntProduct> getTokenEnd_;
0822       mutable std::atomic<unsigned int> transitions_{0};
0823       unsigned int expectedTransitions_{0};
0824       std::vector<int> expectedByRun_;
0825     };
0826 
0827     class InputProcessBlockIntAnalyzerNoRegistration
0828         : public edm::global::EDAnalyzer<
0829               edm::InputProcessBlockCache<int, TestInputProcessBlockCache, TestInputProcessBlockCache1>> {
0830     public:
0831       explicit InputProcessBlockIntAnalyzerNoRegistration(edm::ParameterSet const& pset) {
0832         expectedTransitions_ = pset.getParameter<int>("transitions");
0833       }
0834 
0835       void analyze(edm::StreamID, edm::Event const& event, edm::EventSetup const&) const override {
0836         auto cacheTuple = processBlockCaches(event);
0837         ++transitions_;
0838         if (std::get<0>(cacheTuple).isValid() || std::get<1>(cacheTuple).isValid() ||
0839             std::get<2>(cacheTuple).isValid()) {
0840           throw cms::Exception("LogicError")
0841               << "InputProcessBlockIntAnalyzerNoRegistration expected cacheTuple full of invalid CacheHandles";
0842         }
0843       }
0844 
0845       void endJob() override {
0846         if (transitions_ != expectedTransitions_) {
0847           throw cms::Exception("transitions") << "InputProcessBlockIntAnalyzerNoRegistration transitions "
0848                                               << transitions_ << " but it was supposed to be " << expectedTransitions_;
0849         }
0850       }
0851 
0852     private:
0853       mutable std::atomic<unsigned int> transitions_{0};
0854       unsigned int expectedTransitions_{0};
0855     };
0856 
0857   }  // namespace global
0858 }  // namespace edmtest
0859 
0860 DEFINE_FWK_MODULE(edmtest::global::StreamIntAnalyzer);
0861 DEFINE_FWK_MODULE(edmtest::global::RunIntAnalyzer);
0862 DEFINE_FWK_MODULE(edmtest::global::LumiIntAnalyzer);
0863 DEFINE_FWK_MODULE(edmtest::global::RunSummaryIntAnalyzer);
0864 DEFINE_FWK_MODULE(edmtest::global::LumiSummaryIntAnalyzer);
0865 DEFINE_FWK_MODULE(edmtest::global::ProcessBlockIntAnalyzer);
0866 DEFINE_FWK_MODULE(edmtest::global::InputProcessBlockIntAnalyzer);
0867 DEFINE_FWK_MODULE(edmtest::global::InputProcessBlockAnalyzerThreeTags);
0868 DEFINE_FWK_MODULE(edmtest::global::InputProcessBlockAnalyzerReuseCache);
0869 DEFINE_FWK_MODULE(edmtest::global::InputProcessBlockIntAnalyzerNoRegistration);