Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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