Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:02:26

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