Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 
0002 /*----------------------------------------------------------------------
0003 
0004 Toy edm::global::EDProducer modules of
0005 edm::*Cache templates and edm::*Producer classes
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/EDProducer.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), run(0), lumi(0), strm(0), work(0) {}
0038         //Using mutable since we want to update the value.
0039         mutable std::atomic<unsigned int> value;
0040         mutable std::atomic<unsigned int> run;
0041         mutable std::atomic<unsigned int> lumi;
0042         mutable std::atomic<unsigned int> strm;
0043         mutable std::atomic<unsigned int> work;
0044       };
0045 
0046       struct UnsafeCache {
0047         UnsafeCache() : value(0), run(0), lumi(0), strm(0), work(0) {}
0048         unsigned int value;
0049         unsigned int run;
0050         unsigned int lumi;
0051         unsigned int strm;
0052         unsigned int work;
0053       };
0054 
0055       struct Dummy {};
0056 
0057     }  //end anonymous namespace
0058 
0059     class StreamIntProducer : public edm::global::EDProducer<edm::StreamCache<UnsafeCache>> {
0060     public:
0061       explicit StreamIntProducer(edm::ParameterSet const& p)
0062           : trans_(p.getParameter<int>("transitions")), nLumis_(p.getUntrackedParameter<unsigned int>("nLumis", 1)) {
0063         callWhenNewProductsRegistered([](edm::BranchDescription const& desc) {
0064           std::cout << "global::StreamIntProducer " << desc.moduleLabel() << std::endl;
0065         });
0066         produces<unsigned int>();
0067       }
0068 
0069       const unsigned int trans_;
0070       const unsigned int nLumis_;
0071       mutable std::atomic<unsigned int> m_count{0};
0072       mutable std::atomic<unsigned int> m_countStreams{0};
0073       mutable std::atomic<unsigned int> m_countStreamBeginLumiTransitions{0};
0074       mutable std::atomic<unsigned int> m_countStreamEndLumiTransitions{0};
0075 
0076       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID iID) const override {
0077         ++m_count;
0078         ++m_countStreams;
0079         auto sCache = std::make_unique<UnsafeCache>();
0080         ++(sCache->strm);
0081         sCache->value = iID.value();
0082         return sCache;
0083       }
0084 
0085       void streamBeginRun(edm::StreamID iID, edm::Run const&, edm::EventSetup const&) const override {
0086         ++m_count;
0087         auto sCache = streamCache(iID);
0088         if (sCache->value != iID.value()) {
0089           throw cms::Exception("cache value")
0090               << "StreamIntProducer cache value " << (streamCache(iID))->value << " but it was supposed to be " << iID;
0091         }
0092         if (sCache->run != 0 || sCache->lumi != 0 || sCache->work != 0 || sCache->strm != 1) {
0093           throw cms::Exception("out of sequence") << "streamBeginRun out of sequence in Stream " << iID.value();
0094         }
0095         ++(sCache->run);
0096       }
0097 
0098       void streamBeginLuminosityBlock(edm::StreamID iID,
0099                                       edm::LuminosityBlock const&,
0100                                       edm::EventSetup const&) const override {
0101         ++m_countStreamBeginLumiTransitions;
0102         auto sCache = streamCache(iID);
0103         if (sCache->lumi != 0 || sCache->work != 0) {
0104           throw cms::Exception("out of sequence")
0105               << "streamBeginLuminosityBlock out of sequence in Stream " << iID.value();
0106         }
0107         ++(sCache->lumi);
0108       }
0109 
0110       void produce(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0111         ++m_count;
0112         auto sCache = streamCache(iID);
0113         ++(sCache->work);
0114         if (sCache->lumi == 0 && sCache->run == 0) {
0115           throw cms::Exception("out of sequence") << "produce out of sequence in Stream " << iID.value();
0116         }
0117       }
0118 
0119       void streamEndLuminosityBlock(edm::StreamID iID,
0120                                     edm::LuminosityBlock const&,
0121                                     edm::EventSetup const&) const override {
0122         ++m_countStreamEndLumiTransitions;
0123         auto sCache = streamCache(iID);
0124         --(sCache->lumi);
0125         sCache->work = 0;
0126         if (sCache->lumi != 0 || sCache->run == 0) {
0127           throw cms::Exception("out of sequence")
0128               << "streamEndLuminosityBlock out of sequence in Stream " << iID.value();
0129         }
0130       }
0131 
0132       void streamEndRun(edm::StreamID iID, edm::Run const&, edm::EventSetup const&) const override {
0133         ++m_count;
0134         auto sCache = streamCache(iID);
0135         --(sCache->run);
0136         sCache->work = 0;
0137         if (sCache->run != 0 || sCache->lumi != 0) {
0138           throw cms::Exception("out of sequence") << "streamEndRun out of sequence in Stream " << iID.value();
0139         }
0140       }
0141 
0142       void endStream(edm::StreamID iID) const override {
0143         ++m_count;
0144         auto sCache = streamCache(iID);
0145         --(sCache->strm);
0146         if (sCache->strm != 0 || sCache->run != 0 || sCache->lumi != 0) {
0147           throw cms::Exception("out of sequence") << "endStream out of sequence in Stream " << iID.value();
0148         }
0149       }
0150 
0151       ~StreamIntProducer() {
0152         if (m_count != trans_) {
0153           throw cms::Exception("transitions")
0154               << "StreamIntProducer transitions " << m_count << " but it was supposed to be " << trans_;
0155         }
0156         unsigned int nStreamBeginLumiTransitions = m_countStreamBeginLumiTransitions.load();
0157         unsigned int nStreamEndLumiTransitions = m_countStreamEndLumiTransitions.load();
0158         unsigned int nStreams = m_countStreams.load();
0159         if (nStreamBeginLumiTransitions < nLumis_ || nStreamBeginLumiTransitions > (nLumis_ * nStreams)) {
0160           throw cms::Exception("transitions")
0161               << "StreamIntProducer stream begin lumi transitions " << nStreamBeginLumiTransitions
0162               << " but it was supposed to be between " << nLumis_ << " and " << nLumis_ * nStreams;
0163         }
0164         if (nStreamEndLumiTransitions != nStreamBeginLumiTransitions) {
0165           throw cms::Exception("transitions")
0166               << "StreamIntProducer stream end lumi transitions " << nStreamEndLumiTransitions
0167               << " does not equal stream begin lumi transitions " << nStreamBeginLumiTransitions;
0168         }
0169       }
0170     };
0171 
0172     class RunIntProducer : public edm::global::EDProducer<edm::StreamCache<UnsafeCache>, edm::RunCache<Cache>> {
0173     public:
0174       explicit RunIntProducer(edm::ParameterSet const& p)
0175           : trans_(p.getParameter<int>("transitions")), cvalue_(p.getParameter<int>("cachevalue")) {
0176         produces<unsigned int>();
0177       }
0178 
0179       const unsigned int trans_;
0180       const unsigned int cvalue_;
0181       mutable std::atomic<unsigned int> m_count{0};
0182 
0183       std::shared_ptr<Cache> globalBeginRun(edm::Run const& iRun, edm::EventSetup const&) const override {
0184         ++m_count;
0185         auto rCache = std::make_shared<Cache>();
0186         ++(rCache->run);
0187         return rCache;
0188       }
0189 
0190       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID) const override { return std::make_unique<UnsafeCache>(); }
0191 
0192       void streamBeginRun(edm::StreamID iID, edm::Run const& iRun, edm::EventSetup const&) const override {
0193         auto rCache = runCache(iRun.index());
0194         if (rCache->run == 0) {
0195           throw cms::Exception("out of sequence") << "streamBeginRun before globalBeginRun in Stream " << iID.value();
0196         }
0197       }
0198 
0199       void produce(edm::StreamID iID, edm::Event& iEvent, edm::EventSetup const&) const override {
0200         auto rCache = runCache(iEvent.getRun().index());
0201         ++(rCache->value);
0202       }
0203 
0204       void streamEndRun(edm::StreamID iID, edm::Run const& iRun, edm::EventSetup const&) const override {
0205         auto rCache = runCache(iRun.index());
0206         if (rCache->run == 0) {
0207           throw cms::Exception("out of sequence") << "streamEndRun after globalEndRun in Stream " << iID.value();
0208         }
0209       }
0210 
0211       void globalEndRun(edm::Run const& iRun, edm::EventSetup const&) const override {
0212         ++m_count;
0213         auto rCache = runCache(iRun.index());
0214         if (rCache->value != cvalue_) {
0215           throw cms::Exception("cache value")
0216               << "RunIntProducer cache value " << rCache->value << " but it was supposed to be " << cvalue_;
0217         }
0218         --(rCache->run);
0219       }
0220 
0221       ~RunIntProducer() {
0222         if (m_count != trans_) {
0223           throw cms::Exception("transitions")
0224               << "RunIntProducer transitions " << m_count << " but it was supposed to be " << trans_;
0225         }
0226       }
0227     };
0228 
0229     class LumiIntProducer
0230         : public edm::global::EDProducer<edm::StreamCache<UnsafeCache>, edm::LuminosityBlockCache<Cache>> {
0231     public:
0232       explicit LumiIntProducer(edm::ParameterSet const& p)
0233           : trans_(p.getParameter<int>("transitions")), cvalue_(p.getParameter<int>("cachevalue")) {
0234         produces<unsigned int>();
0235       }
0236       const unsigned int trans_;
0237       const unsigned int cvalue_;
0238       mutable std::atomic<unsigned int> m_count{0};
0239 
0240       std::shared_ptr<Cache> globalBeginLuminosityBlock(edm::LuminosityBlock const& iLB,
0241                                                         edm::EventSetup const&) const override {
0242         ++m_count;
0243         auto lCache = std::make_shared<Cache>();
0244         ++(lCache->lumi);
0245         return lCache;
0246       }
0247 
0248       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID) const override { return std::make_unique<UnsafeCache>(); }
0249 
0250       void streamBeginLuminosityBlock(edm::StreamID iID,
0251                                       edm::LuminosityBlock const& iLB,
0252                                       edm::EventSetup const&) const override {
0253         auto lCache = luminosityBlockCache(iLB.index());
0254         if (lCache->lumi == 0) {
0255           throw cms::Exception("out of sequence")
0256               << "streamBeginLuminosityBlock seen before globalBeginLuminosityBlock in LuminosityBlock"
0257               << iLB.luminosityBlock();
0258         }
0259       }
0260 
0261       void produce(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const override {
0262         auto lCache = luminosityBlockCache(iEvent.getLuminosityBlock().index());
0263         ++(lCache->value);
0264       }
0265 
0266       void streamEndLuminosityBlock(edm::StreamID iID,
0267                                     edm::LuminosityBlock const& iLB,
0268                                     edm::EventSetup const&) const override {
0269         auto lCache = luminosityBlockCache(iLB.index());
0270         if (lCache->lumi == 0) {
0271           throw cms::Exception("out of sequence")
0272               << "streamEndLuminosityBlock seen before globalEndLuminosityBlock in LuminosityBlock"
0273               << iLB.luminosityBlock();
0274         }
0275       }
0276 
0277       void globalEndLuminosityBlock(edm::LuminosityBlock const& iLB, edm::EventSetup const&) const override {
0278         ++m_count;
0279         auto lCache = luminosityBlockCache(iLB.index());
0280         --(lCache->lumi);
0281         if (lCache->lumi != 0) {
0282           throw cms::Exception("end out of sequence")
0283               << "globalEndLuminosityBlock seen before globalBeginLuminosityBlock in LuminosityBlock"
0284               << iLB.luminosityBlock();
0285         }
0286         if (lCache->value != cvalue_) {
0287           throw cms::Exception("cache value")
0288               << "LumiIntProducer cache value " << lCache->value << " but it was supposed to be " << cvalue_;
0289         }
0290       }
0291 
0292       ~LumiIntProducer() {
0293         if (m_count != trans_) {
0294           throw cms::Exception("transitions")
0295               << "LumiIntProducer transitions " << m_count << " but it was supposed to be " << trans_;
0296         }
0297       }
0298     };
0299 
0300     class RunSummaryIntProducer
0301         : public edm::global::EDProducer<edm::StreamCache<UnsafeCache>, edm::RunSummaryCache<UnsafeCache>> {
0302     public:
0303       explicit RunSummaryIntProducer(edm::ParameterSet const& p)
0304           : trans_(p.getParameter<int>("transitions")), cvalue_(p.getParameter<int>("cachevalue")) {
0305         produces<unsigned int>();
0306       }
0307       const unsigned int trans_;
0308       const unsigned int cvalue_;
0309       mutable std::atomic<unsigned int> m_count{0};
0310 
0311       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID) const override { return std::make_unique<UnsafeCache>(); }
0312 
0313       std::shared_ptr<UnsafeCache> globalBeginRunSummary(edm::Run const& iRun, edm::EventSetup const&) const override {
0314         ++m_count;
0315         auto gCache = std::make_shared<UnsafeCache>();
0316         ++(gCache->run);
0317         return gCache;
0318       }
0319 
0320       void produce(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0321         auto sCache = streamCache(iID);
0322         ++(sCache->value);
0323       }
0324 
0325       void streamEndRunSummary(edm::StreamID iID,
0326                                edm::Run const&,
0327                                edm::EventSetup const&,
0328                                UnsafeCache* gCache) const override {
0329         ++m_count;
0330         if (gCache->run == 0) {
0331           throw cms::Exception("out of sequence")
0332               << "streamEndRunSummary after globalEndRunSummary in Stream " << iID.value();
0333         }
0334         auto sCache = streamCache(iID);
0335         gCache->value += sCache->value;
0336         sCache->value = 0;
0337       }
0338 
0339       void globalEndRunSummary(edm::Run const&, edm::EventSetup const&, UnsafeCache* gCache) const override {
0340         ++m_count;
0341         if (gCache->value != cvalue_) {
0342           throw cms::Exception("cache value")
0343               << "RunSummaryIntProducer cache value " << gCache->value << " but it was supposed to be " << cvalue_;
0344         }
0345         --(gCache->run);
0346       }
0347 
0348       ~RunSummaryIntProducer() {
0349         if (m_count != trans_) {
0350           throw cms::Exception("transitions")
0351               << "RunSummaryIntProducer transitions " << m_count << " but it was supposed to be " << trans_;
0352         }
0353       }
0354     };
0355 
0356     class LumiSummaryIntProducer
0357         : public edm::global::EDProducer<edm::StreamCache<UnsafeCache>, edm::LuminosityBlockSummaryCache<UnsafeCache>> {
0358     public:
0359       explicit LumiSummaryIntProducer(edm::ParameterSet const& p)
0360           : trans_(p.getParameter<int>("transitions")), cvalue_(p.getParameter<int>("cachevalue")) {
0361         produces<unsigned int>();
0362       }
0363       const unsigned int trans_;
0364       const unsigned int cvalue_;
0365       mutable std::atomic<unsigned int> m_count{0};
0366       mutable std::atomic<unsigned int> m_countLumis{0};
0367       mutable std::atomic<unsigned int> m_countStreams{0};
0368       mutable std::atomic<unsigned int> m_countStreamLumiTransitions{0};
0369 
0370       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID) const override {
0371         ++m_count;
0372         ++m_countStreams;
0373         return std::make_unique<UnsafeCache>();
0374       }
0375 
0376       std::shared_ptr<UnsafeCache> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const& iLB,
0377                                                                      edm::EventSetup const&) const override {
0378         ++m_count;
0379         ++m_countLumis;
0380         auto gCache = std::make_shared<UnsafeCache>();
0381         gCache->lumi = iLB.luminosityBlockAuxiliary().luminosityBlock();
0382         return gCache;
0383       }
0384 
0385       void produce(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0386         ++m_count;
0387         auto sCache = streamCache(iID);
0388         ++(sCache->value);
0389       }
0390 
0391       void streamEndLuminosityBlockSummary(edm::StreamID iID,
0392                                            edm::LuminosityBlock const& iLB,
0393                                            edm::EventSetup const&,
0394                                            UnsafeCache* gCache) const override {
0395         ++m_countStreamLumiTransitions;
0396         if (gCache->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0397           throw cms::Exception("UnexpectedValue")
0398               << "streamEndLuminosityBlockSummary unexpected lumi number in Stream " << iID.value();
0399         }
0400         auto sCache = streamCache(iID);
0401         gCache->value += sCache->value;
0402         sCache->value = 0;
0403       }
0404 
0405       void globalEndLuminosityBlockSummary(edm::LuminosityBlock const& iLB,
0406                                            edm::EventSetup const&,
0407                                            UnsafeCache* gCache) const override {
0408         ++m_count;
0409         if (gCache->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0410           throw cms::Exception("UnexpectedValue") << "globalEndLuminosityBlockSummary unexpected lumi number";
0411         }
0412         if (gCache->value != cvalue_) {
0413           throw cms::Exception("cache value")
0414               << "LumiSummaryIntProducer cache value " << gCache->value << " but it was supposed to be " << cvalue_;
0415         }
0416       }
0417 
0418       ~LumiSummaryIntProducer() {
0419         if (m_count != trans_) {
0420           throw cms::Exception("transitions")
0421               << "LumiSummaryIntProducer transitions " << m_count << " but it was supposed to be " << trans_;
0422         }
0423         unsigned int nStreamLumiTransitions = m_countStreamLumiTransitions.load();
0424         unsigned int nLumis = m_countLumis.load();
0425         unsigned int nStreams = m_countStreams.load();
0426         if (nStreamLumiTransitions < nLumis || nStreamLumiTransitions > (nLumis * nStreams)) {
0427           throw cms::Exception("transitions")
0428               << "LumiSummaryIntProducer stream lumi transitions " << nStreamLumiTransitions
0429               << " but it was supposed to be between " << nLumis << " and " << nLumis * nStreams;
0430         }
0431       }
0432     };
0433 
0434     class LumiSummaryLumiProducer : public edm::global::EDProducer<edm::StreamCache<UnsafeCache>,
0435                                                                    edm::LuminosityBlockSummaryCache<UnsafeCache>,
0436                                                                    edm::EndLuminosityBlockProducer> {
0437     public:
0438       explicit LumiSummaryLumiProducer(edm::ParameterSet const& p)
0439           : trans_(p.getParameter<int>("transitions")), cvalue_(p.getParameter<int>("cachevalue")) {
0440         produces<unsigned int>();
0441       }
0442       const unsigned int trans_;
0443       const unsigned int cvalue_;
0444       mutable std::atomic<unsigned int> m_count{0};
0445       mutable std::atomic<unsigned int> m_countLumis{0};
0446       mutable std::atomic<unsigned int> m_countStreams{0};
0447       mutable std::atomic<unsigned int> m_countStreamLumiTransitions{0};
0448 
0449       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID) const override {
0450         ++m_count;
0451         ++m_countStreams;
0452         return std::make_unique<UnsafeCache>();
0453       }
0454 
0455       std::shared_ptr<UnsafeCache> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const& iLB,
0456                                                                      edm::EventSetup const&) const override {
0457         ++m_count;
0458         ++m_countLumis;
0459         auto gCache = std::make_shared<UnsafeCache>();
0460         gCache->lumi = iLB.luminosityBlockAuxiliary().luminosityBlock();
0461         return gCache;
0462       }
0463 
0464       void produce(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0465         auto sCache = streamCache(iID);
0466         ++(sCache->value);
0467       }
0468 
0469       void streamEndLuminosityBlockSummary(edm::StreamID iID,
0470                                            edm::LuminosityBlock const& iLB,
0471                                            edm::EventSetup const&,
0472                                            UnsafeCache* gCache) const override {
0473         ++m_countStreamLumiTransitions;
0474         if (gCache->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0475           throw cms::Exception("UnexpectedValue")
0476               << "streamEndLuminosityBlockSummary unexpected lumi number in Stream " << iID.value();
0477         }
0478         auto sCache = streamCache(iID);
0479         gCache->value += sCache->value;
0480         sCache->value = 0;
0481       }
0482 
0483       void globalEndLuminosityBlockSummary(edm::LuminosityBlock const& iLB,
0484                                            edm::EventSetup const&,
0485                                            UnsafeCache* gCache) const override {
0486         ++m_count;
0487         if (gCache->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0488           throw cms::Exception("UnexpectedValue") << "globalEndLuminosityBlockSummary unexpected lumi number";
0489         }
0490         if (gCache->value != cvalue_) {
0491           throw cms::Exception("cache value")
0492               << "LumiSummaryLumiProducer cache value " << gCache->value << " but it was supposed to be " << cvalue_;
0493         }
0494       }
0495 
0496       void globalEndLuminosityBlockProduce(edm::LuminosityBlock& iLB,
0497                                            edm::EventSetup const&,
0498                                            UnsafeCache const* gCache) const override {
0499         ++m_count;
0500         if (gCache->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0501           throw cms::Exception("UnexpectedValue") << "globalEndLuminosityBlockProduce unexpected lumi number";
0502         }
0503       }
0504 
0505       ~LumiSummaryLumiProducer() {
0506         if (m_count != trans_) {
0507           throw cms::Exception("transitions")
0508               << "LumiSummaryLumiProducer transitions " << m_count << " but it was supposed to be " << trans_;
0509         }
0510         unsigned int nStreamLumiTransitions = m_countStreamLumiTransitions.load();
0511         unsigned int nLumis = m_countLumis.load();
0512         unsigned int nStreams = m_countStreams.load();
0513         if (nStreamLumiTransitions < nLumis || nStreamLumiTransitions > (nLumis * nStreams)) {
0514           throw cms::Exception("transitions")
0515               << "LumiSummaryLumiProducer stream lumi transitions " << nStreamLumiTransitions
0516               << " but it was supposed to be between " << nLumis << " and " << nLumis * nStreams;
0517         }
0518       }
0519     };
0520 
0521     class ProcessBlockIntProducer : public edm::global::EDProducer<edm::WatchProcessBlock> {
0522     public:
0523       explicit ProcessBlockIntProducer(edm::ParameterSet const& p) : trans_(p.getParameter<int>("transitions")) {
0524         produces<unsigned int>();
0525         {
0526           auto tag = p.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0527           if (not tag.label().empty()) {
0528             getTokenBegin_ = consumes<unsigned int, edm::InProcess>(tag);
0529           }
0530         }
0531         {
0532           auto tag = p.getParameter<edm::InputTag>("consumesEndProcessBlock");
0533           if (not tag.label().empty()) {
0534             getTokenEnd_ = consumes<unsigned int, edm::InProcess>(tag);
0535           }
0536         }
0537       }
0538 
0539       void beginProcessBlock(edm::ProcessBlock const& processBlock) override {
0540         if (m_count != 0) {
0541           throw cms::Exception("transitions")
0542               << "ProcessBlockIntProducer::begin transitions " << m_count << " but it was supposed to be " << 0;
0543         }
0544         ++m_count;
0545 
0546         const unsigned int valueToGet = 11;
0547         if (not getTokenBegin_.isUninitialized()) {
0548           if (processBlock.get(getTokenBegin_) != valueToGet) {
0549             throw cms::Exception("BadValue")
0550                 << "expected " << valueToGet << " but got " << processBlock.get(getTokenBegin_);
0551           }
0552         }
0553       }
0554 
0555       void produce(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0556         if (m_count < 1u) {
0557           throw cms::Exception("out of sequence") << "produce before beginProcessBlock " << m_count;
0558         }
0559         ++m_count;
0560       }
0561 
0562       void endProcessBlock(edm::ProcessBlock const& processBlock) override {
0563         ++m_count;
0564         if (m_count != trans_) {
0565           throw cms::Exception("transitions")
0566               << "ProcessBlockIntProducer::end transitions " << m_count << " but it was supposed to be " << trans_;
0567         }
0568         {
0569           const unsigned int valueToGet = 11;
0570           if (not getTokenBegin_.isUninitialized()) {
0571             if (processBlock.get(getTokenBegin_) != valueToGet) {
0572               throw cms::Exception("BadValue")
0573                   << "expected " << valueToGet << " but got " << processBlock.get(getTokenBegin_);
0574             }
0575           }
0576         }
0577         {
0578           const unsigned int valueToGet = 21;
0579           if (not getTokenEnd_.isUninitialized()) {
0580             if (processBlock.get(getTokenEnd_) != valueToGet) {
0581               throw cms::Exception("BadValue")
0582                   << "expected " << valueToGet << " but got " << processBlock.get(getTokenEnd_);
0583             }
0584           }
0585         }
0586       }
0587 
0588       ~ProcessBlockIntProducer() {
0589         if (m_count != trans_) {
0590           throw cms::Exception("transitions")
0591               << "ProcessBlockIntProducer transitions " << m_count << " but it was supposed to be " << trans_;
0592         }
0593       }
0594 
0595     private:
0596       const unsigned int trans_;
0597       mutable std::atomic<unsigned int> m_count{0};
0598       edm::EDGetTokenT<unsigned int> getTokenBegin_;
0599       edm::EDGetTokenT<unsigned int> getTokenEnd_;
0600     };
0601 
0602     class TestBeginProcessBlockProducer : public edm::global::EDProducer<edm::BeginProcessBlockProducer> {
0603     public:
0604       explicit TestBeginProcessBlockProducer(edm::ParameterSet const& p)
0605           : trans_(p.getParameter<int>("transitions")),
0606             token_(produces<unsigned int, edm::Transition::BeginProcessBlock>("begin")) {
0607         produces<unsigned int>();
0608 
0609         auto tag = p.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0610         if (not tag.label().empty()) {
0611           getToken_ = consumes<unsigned int, edm::InProcess>(tag);
0612         }
0613       }
0614 
0615       void beginProcessBlockProduce(edm::ProcessBlock& processBlock) override {
0616         if (m_count != 0) {
0617           throw cms::Exception("transitions")
0618               << "TestBeginProcessBlockProducer transitions " << m_count << " but it was supposed to be " << 0;
0619         }
0620         ++m_count;
0621         const unsigned int valueToPutAndGet = 11;
0622         processBlock.emplace(token_, valueToPutAndGet);
0623 
0624         if (not getToken_.isUninitialized()) {
0625           if (processBlock.get(getToken_) != valueToPutAndGet) {
0626             throw cms::Exception("BadValue")
0627                 << "expected " << valueToPutAndGet << " but got " << processBlock.get(getToken_);
0628           }
0629         }
0630       }
0631 
0632       void produce(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0633         if (m_count < 1u) {
0634           throw cms::Exception("out of sequence") << "produce before beginProcessBlockProduce " << m_count;
0635         }
0636         ++m_count;
0637       }
0638 
0639       ~TestBeginProcessBlockProducer() {
0640         if (m_count != trans_) {
0641           throw cms::Exception("transitions")
0642               << "TestBeginProcessBlockProducer transitions " << m_count << " but it was supposed to be " << trans_;
0643         }
0644       }
0645 
0646     private:
0647       const unsigned int trans_;
0648       mutable std::atomic<unsigned int> m_count{0};
0649       edm::EDPutTokenT<unsigned int> token_;
0650       edm::EDGetTokenT<unsigned int> getToken_;
0651     };
0652 
0653     class TestEndProcessBlockProducer : public edm::global::EDProducer<edm::EndProcessBlockProducer> {
0654     public:
0655       explicit TestEndProcessBlockProducer(edm::ParameterSet const& p)
0656           : trans_(p.getParameter<int>("transitions")),
0657             token_(produces<unsigned int, edm::Transition::EndProcessBlock>("end")) {
0658         produces<unsigned int>();
0659 
0660         auto tag = p.getParameter<edm::InputTag>("consumesEndProcessBlock");
0661         if (not tag.label().empty()) {
0662           getToken_ = consumes<unsigned int, edm::InProcess>(tag);
0663         }
0664       }
0665 
0666       void produce(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override { ++m_count; }
0667 
0668       void endProcessBlockProduce(edm::ProcessBlock& processBlock) override {
0669         ++m_count;
0670         if (m_count != trans_) {
0671           throw cms::Exception("transitions")
0672               << "TestEndProcessBlockProducer transitions " << m_count << " but it was supposed to be " << trans_;
0673         }
0674         const unsigned int valueToPutAndGet = 21;
0675         processBlock.emplace(token_, valueToPutAndGet);
0676         if (not getToken_.isUninitialized()) {
0677           if (processBlock.get(getToken_) != valueToPutAndGet) {
0678             throw cms::Exception("BadValue")
0679                 << "expected " << valueToPutAndGet << " but got " << processBlock.get(getToken_);
0680           }
0681         }
0682       }
0683 
0684       ~TestEndProcessBlockProducer() {
0685         if (m_count != trans_) {
0686           throw cms::Exception("transitions")
0687               << "~TestEndProcessBlockProducer transitions " << m_count << " but it was supposed to be " << trans_;
0688         }
0689       }
0690 
0691     private:
0692       const unsigned int trans_;
0693       mutable std::atomic<unsigned int> m_count{0};
0694       edm::EDPutTokenT<unsigned int> token_;
0695       edm::EDGetTokenT<unsigned int> getToken_;
0696     };
0697 
0698     class TestBeginRunProducer : public edm::global::EDProducer<edm::RunCache<Dummy>, edm::BeginRunProducer> {
0699     public:
0700       explicit TestBeginRunProducer(edm::ParameterSet const& p) : trans_(p.getParameter<int>("transitions")) {
0701         produces<unsigned int>();
0702         produces<unsigned int, edm::Transition::BeginRun>("a");
0703       }
0704 
0705       const unsigned int trans_;
0706       mutable std::atomic<unsigned int> m_count{0};
0707       mutable std::atomic<bool> brp{false};
0708 
0709       std::shared_ptr<Dummy> globalBeginRun(edm::Run const& iRun, edm::EventSetup const&) const override {
0710         brp = false;
0711         return std::shared_ptr<Dummy>();
0712       }
0713 
0714       void produce(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0715         if (!brp) {
0716           throw cms::Exception("out of sequence") << "produce before globalBeginRunProduce in Stream " << iID.value();
0717         }
0718       }
0719 
0720       void globalBeginRunProduce(edm::Run&, edm::EventSetup const&) const override {
0721         ++m_count;
0722         brp = true;
0723       }
0724 
0725       void globalEndRun(edm::Run const& iRun, edm::EventSetup const&) const override {}
0726 
0727       ~TestBeginRunProducer() {
0728         if (m_count != trans_) {
0729           throw cms::Exception("transitions")
0730               << "TestBeginRunProducer transitions " << m_count << " but it was supposed to be " << trans_;
0731         }
0732       }
0733     };
0734 
0735     class TestEndRunProducer : public edm::global::EDProducer<edm::RunCache<Dummy>, edm::EndRunProducer> {
0736     public:
0737       explicit TestEndRunProducer(edm::ParameterSet const& p) : trans_(p.getParameter<int>("transitions")) {
0738         produces<unsigned int>();
0739         produces<unsigned int, edm::Transition::EndRun>("a");
0740       }
0741       const unsigned int trans_;
0742       mutable std::atomic<unsigned int> m_count{0};
0743       mutable std::atomic<bool> p{false};
0744 
0745       std::shared_ptr<Dummy> globalBeginRun(edm::Run const& iRun, edm::EventSetup const&) const override {
0746         p = false;
0747         return std::shared_ptr<Dummy>();
0748       }
0749 
0750       void produce(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override { p = true; }
0751 
0752       void globalEndRunProduce(edm::Run&, edm::EventSetup const&) const override {
0753         if (!p) {
0754           throw cms::Exception("out of sequence") << "endRunProduce before produce";
0755         }
0756         ++m_count;
0757       }
0758 
0759       void globalEndRun(edm::Run const& iRun, edm::EventSetup const&) const override {}
0760 
0761       ~TestEndRunProducer() {
0762         if (m_count != trans_) {
0763           throw cms::Exception("transitions")
0764               << "TestEndRunProducer transitions " << m_count << " but it was supposed to be " << trans_;
0765         }
0766       }
0767     };
0768 
0769     class TestBeginLumiBlockProducer
0770         : public edm::global::EDProducer<edm::LuminosityBlockCache<void>, edm::BeginLuminosityBlockProducer> {
0771     public:
0772       explicit TestBeginLumiBlockProducer(edm::ParameterSet const& p) : trans_(p.getParameter<int>("transitions")) {
0773         produces<unsigned int>();
0774         produces<unsigned int, edm::Transition::BeginLuminosityBlock>("a");
0775       }
0776       const unsigned int trans_;
0777       mutable std::atomic<unsigned int> m_count{0};
0778       mutable std::atomic<bool> gblp{false};
0779 
0780       std::shared_ptr<void> globalBeginLuminosityBlock(edm::LuminosityBlock const& iLB,
0781                                                        edm::EventSetup const&) const override {
0782         gblp = false;
0783         return std::shared_ptr<void>();
0784       }
0785 
0786       void produce(edm::StreamID iID, edm::Event&, const edm::EventSetup&) const override {
0787         if (!gblp) {
0788           throw cms::Exception("out of sequence")
0789               << "produce before globalBeginLuminosityBlockProduce in Stream " << iID.value();
0790         }
0791       }
0792 
0793       void globalBeginLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const override {
0794         ++m_count;
0795         gblp = true;
0796       }
0797 
0798       void globalEndLuminosityBlock(edm::LuminosityBlock const& iLB, edm::EventSetup const&) const override {}
0799 
0800       ~TestBeginLumiBlockProducer() {
0801         if (m_count != trans_) {
0802           throw cms::Exception("transitions")
0803               << "TestBeginLumiBlockProducer transitions " << m_count << " but it was supposed to be " << trans_;
0804         }
0805       }
0806     };
0807 
0808     class TestEndLumiBlockProducer
0809         : public edm::global::EDProducer<edm::LuminosityBlockCache<void>, edm::EndLuminosityBlockProducer> {
0810     public:
0811       explicit TestEndLumiBlockProducer(edm::ParameterSet const& p) : trans_(p.getParameter<int>("transitions")) {
0812         produces<unsigned int>();
0813         produces<unsigned int, edm::Transition::EndLuminosityBlock>("a");
0814       }
0815       const unsigned int trans_;
0816       mutable std::atomic<unsigned int> m_count{0};
0817       mutable std::atomic<bool> p{false};
0818 
0819       std::shared_ptr<void> globalBeginLuminosityBlock(edm::LuminosityBlock const& iLB,
0820                                                        edm::EventSetup const&) const override {
0821         p = false;
0822         return std::shared_ptr<void>();
0823       }
0824 
0825       void produce(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override { p = true; }
0826 
0827       void globalEndLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const override {
0828         if (!p) {
0829           throw cms::Exception("out of sequence") << "endLumiBlockProduce before produce";
0830         }
0831         ++m_count;
0832       }
0833 
0834       void globalEndLuminosityBlock(edm::LuminosityBlock const& iLB, edm::EventSetup const&) const override {}
0835 
0836       ~TestEndLumiBlockProducer() {
0837         if (m_count != trans_) {
0838           throw cms::Exception("transitions")
0839               << "TestEndLumiBlockProducer transitions " << m_count << " but it was supposed to be " << trans_;
0840         }
0841       }
0842     };
0843 
0844     class TestAccumulator : public edm::global::EDProducer<edm::Accumulator, edm::EndLuminosityBlockProducer> {
0845     public:
0846       explicit TestAccumulator(edm::ParameterSet const& p)
0847           : m_expectedCount(p.getParameter<unsigned int>("expectedCount")),
0848             m_putToken(produces<edm::Transition::EndLuminosityBlock>()) {}
0849 
0850       void accumulate(edm::StreamID iID, edm::Event const&, edm::EventSetup const&) const override { ++m_count; }
0851 
0852       void globalEndLuminosityBlockProduce(edm::LuminosityBlock& l, edm::EventSetup const&) const override {
0853         l.emplace(m_putToken, m_count.load());
0854       }
0855 
0856       ~TestAccumulator() {
0857         if (m_count.load() != m_expectedCount) {
0858           throw cms::Exception("TestCount")
0859               << "TestAccumulator counter was " << m_count << " but it was supposed to be " << m_expectedCount;
0860         }
0861       }
0862 
0863       mutable std::atomic<unsigned int> m_count{0};
0864       const unsigned int m_expectedCount;
0865       const edm::EDPutTokenT<unsigned int> m_putToken;
0866     };
0867 
0868     class TestInputProcessBlockCache {
0869     public:
0870       long long int value_ = 0;
0871     };
0872 
0873     class TestInputProcessBlockCache1 {
0874     public:
0875       long long int value_ = 0;
0876     };
0877 
0878     class InputProcessBlockIntProducer
0879         : public edm::global::EDProducer<
0880               edm::InputProcessBlockCache<int, TestInputProcessBlockCache, TestInputProcessBlockCache1>> {
0881     public:
0882       explicit InputProcessBlockIntProducer(edm::ParameterSet const& pset) {
0883         expectedTransitions_ = pset.getParameter<int>("transitions");
0884         expectedByRun_ = pset.getParameter<std::vector<int>>("expectedByRun");
0885         expectedSum_ = pset.getParameter<int>("expectedSum");
0886         {
0887           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0888           if (not tag.label().empty()) {
0889             getTokenBegin_ = consumes<IntProduct, edm::InProcess>(tag);
0890           }
0891         }
0892         {
0893           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock");
0894           if (not tag.label().empty()) {
0895             getTokenEnd_ = consumes<IntProduct, edm::InProcess>(tag);
0896           }
0897         }
0898         {
0899           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlockM");
0900           if (not tag.label().empty()) {
0901             getTokenBeginM_ = consumes<IntProduct, edm::InProcess>(tag);
0902           }
0903         }
0904         {
0905           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlockM");
0906           if (not tag.label().empty()) {
0907             getTokenEndM_ = consumes<IntProduct, edm::InProcess>(tag);
0908           }
0909         }
0910         registerProcessBlockCacheFiller<int>(
0911             getTokenBegin_, [this](edm::ProcessBlock const& processBlock, std::shared_ptr<int> const& previousCache) {
0912               auto returnValue = std::make_shared<int>(0);
0913               *returnValue += processBlock.get(getTokenBegin_).value;
0914               *returnValue += processBlock.get(getTokenEnd_).value;
0915               ++transitions_;
0916               return returnValue;
0917             });
0918         registerProcessBlockCacheFiller<1>(getTokenBegin_,
0919                                            [this](edm::ProcessBlock const& processBlock,
0920                                                   std::shared_ptr<TestInputProcessBlockCache> const& previousCache) {
0921                                              auto returnValue = std::make_shared<TestInputProcessBlockCache>();
0922                                              returnValue->value_ += processBlock.get(getTokenBegin_).value;
0923                                              returnValue->value_ += processBlock.get(getTokenEnd_).value;
0924                                              ++transitions_;
0925                                              return returnValue;
0926                                            });
0927         registerProcessBlockCacheFiller<TestInputProcessBlockCache1>(
0928             getTokenBegin_,
0929             [this](edm::ProcessBlock const& processBlock,
0930                    std::shared_ptr<TestInputProcessBlockCache1> const& previousCache) {
0931               auto returnValue = std::make_shared<TestInputProcessBlockCache1>();
0932               returnValue->value_ += processBlock.get(getTokenBegin_).value;
0933               returnValue->value_ += processBlock.get(getTokenEnd_).value;
0934               ++transitions_;
0935               return returnValue;
0936             });
0937       }
0938 
0939       void accessInputProcessBlock(edm::ProcessBlock const& processBlock) override {
0940         if (processBlock.processName() == "PROD1") {
0941           sum_ += processBlock.get(getTokenBegin_).value;
0942           sum_ += processBlock.get(getTokenEnd_).value;
0943         }
0944         if (processBlock.processName() == "MERGE") {
0945           sum_ += processBlock.get(getTokenBeginM_).value;
0946           sum_ += processBlock.get(getTokenEndM_).value;
0947         }
0948         ++transitions_;
0949       }
0950 
0951       void produce(edm::StreamID, edm::Event& event, edm::EventSetup const&) const override {
0952         auto cacheTuple = processBlockCaches(event);
0953         if (!expectedByRun_.empty()) {
0954           if (expectedByRun_.at(event.run() - 1) != *std::get<edm::CacheHandle<int>>(cacheTuple)) {
0955             throw cms::Exception("UnexpectedValue")
0956                 << "InputProcessBlockIntProducer::produce cached value was "
0957                 << *std::get<edm::CacheHandle<int>>(cacheTuple) << " but it was supposed to be "
0958                 << expectedByRun_.at(event.run() - 1);
0959           }
0960           if (expectedByRun_.at(event.run() - 1) != std::get<1>(cacheTuple)->value_) {
0961             throw cms::Exception("UnexpectedValue")
0962                 << "InputProcessBlockIntProducer::produce second cached value was " << std::get<1>(cacheTuple)->value_
0963                 << " but it was supposed to be " << expectedByRun_.at(event.run() - 1);
0964           }
0965           if (expectedByRun_.at(event.run() - 1) !=
0966               std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_) {
0967             throw cms::Exception("UnexpectedValue")
0968                 << "InputProcessBlockIntProducer::produce third cached value was "
0969                 << std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_
0970                 << " but it was supposed to be " << expectedByRun_.at(event.run() - 1);
0971           }
0972         }
0973         ++transitions_;
0974       }
0975 
0976       void endJob() override {
0977         if (transitions_ != expectedTransitions_) {
0978           throw cms::Exception("transitions") << "InputProcessBlockIntProducer transitions " << transitions_
0979                                               << " but it was supposed to be " << expectedTransitions_;
0980         }
0981         if (sum_ != expectedSum_) {
0982           throw cms::Exception("UnexpectedValue")
0983               << "InputProcessBlockIntProducer sum " << sum_ << " but it was supposed to be " << expectedSum_;
0984         }
0985         if (cacheSize() > 0u) {
0986           throw cms::Exception("UnexpectedValue")
0987               << "InputProcessBlockIntProducer cache size not zero at endJob " << cacheSize();
0988         }
0989       }
0990 
0991     private:
0992       edm::EDGetTokenT<IntProduct> getTokenBegin_;
0993       edm::EDGetTokenT<IntProduct> getTokenEnd_;
0994       edm::EDGetTokenT<IntProduct> getTokenBeginM_;
0995       edm::EDGetTokenT<IntProduct> getTokenEndM_;
0996       mutable std::atomic<unsigned int> transitions_{0};
0997       int sum_{0};
0998       unsigned int expectedTransitions_{0};
0999       std::vector<int> expectedByRun_;
1000       int expectedSum_{0};
1001     };
1002   }  // namespace global
1003 }  // namespace edmtest
1004 
1005 DEFINE_FWK_MODULE(edmtest::global::StreamIntProducer);
1006 DEFINE_FWK_MODULE(edmtest::global::RunIntProducer);
1007 DEFINE_FWK_MODULE(edmtest::global::LumiIntProducer);
1008 DEFINE_FWK_MODULE(edmtest::global::RunSummaryIntProducer);
1009 DEFINE_FWK_MODULE(edmtest::global::LumiSummaryIntProducer);
1010 DEFINE_FWK_MODULE(edmtest::global::LumiSummaryLumiProducer);
1011 DEFINE_FWK_MODULE(edmtest::global::ProcessBlockIntProducer);
1012 DEFINE_FWK_MODULE(edmtest::global::TestBeginProcessBlockProducer);
1013 DEFINE_FWK_MODULE(edmtest::global::TestEndProcessBlockProducer);
1014 DEFINE_FWK_MODULE(edmtest::global::TestBeginRunProducer);
1015 DEFINE_FWK_MODULE(edmtest::global::TestEndRunProducer);
1016 DEFINE_FWK_MODULE(edmtest::global::TestBeginLumiBlockProducer);
1017 DEFINE_FWK_MODULE(edmtest::global::TestEndLumiBlockProducer);
1018 DEFINE_FWK_MODULE(edmtest::global::TestAccumulator);
1019 DEFINE_FWK_MODULE(edmtest::global::InputProcessBlockIntProducer);