Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-08-23 03:25:08

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