Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-19 01:43:56

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