Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-01-11 16:27:17

0001 
0002 /*----------------------------------------------------------------------
0003 
0004 Toy EDProducers of Ints for testing purposes only.
0005 
0006 ----------------------------------------------------------------------*/
0007 
0008 #include "DataFormats/Common/interface/Handle.h"
0009 #include "DataFormats/Common/interface/TriggerResults.h"
0010 #include "DataFormats/TestObjects/interface/ToyProducts.h"
0011 //
0012 #include "FWCore/Framework/interface/stream/EDProducer.h"
0013 #include "FWCore/Framework/interface/global/EDProducer.h"
0014 #include "FWCore/Framework/interface/limited/EDProducer.h"
0015 #include "FWCore/Framework/interface/one/EDProducer.h"
0016 #include "FWCore/Framework/interface/Event.h"
0017 #include "FWCore/Framework/interface/MakerMacros.h"
0018 #include "FWCore/Framework/interface/ProcessBlock.h"
0019 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0020 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0021 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0022 #include "FWCore/Utilities/interface/EDMException.h"
0023 #include "FWCore/Utilities/interface/InputTag.h"
0024 #include "FWCore/Utilities/interface/transform.h"
0025 //
0026 #include <cassert>
0027 #include <string>
0028 #include <vector>
0029 #include <unistd.h>
0030 
0031 namespace edmtest {
0032 
0033   //--------------------------------------------------------------------
0034   //
0035   // Int producers
0036   //
0037   //--------------------------------------------------------------------
0038 
0039   //--------------------------------------------------------------------
0040   //
0041   // throws an exception.
0042   // Announces an IntProduct but does not produce one;
0043   // every call to FailingProducer::produce throws a cms exception
0044   //
0045   class FailingProducer : public edm::global::EDProducer<> {
0046   public:
0047     explicit FailingProducer(edm::ParameterSet const& /*p*/) { produces<IntProduct>(); }
0048     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0049   };
0050 
0051   void FailingProducer::produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const {
0052     // We throw an edm exception with a configurable action.
0053     throw edm::Exception(edm::errors::NotFound) << "Intentional 'NotFound' exception for testing purposes\n";
0054   }
0055   //--------------------------------------------------------------------
0056   //
0057   // throws an exception.
0058   // Announces an IntProduct but does not produce one;
0059   // every call to FailingInLumiProducer::produce throws a cms exception
0060   //
0061   class FailingInLumiProducer : public edm::global::EDProducer<edm::BeginLuminosityBlockProducer> {
0062   public:
0063     explicit FailingInLumiProducer(edm::ParameterSet const& /*p*/) {
0064       produces<IntProduct, edm::Transition::BeginLuminosityBlock>();
0065     }
0066     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0067 
0068     void globalBeginLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const override;
0069   };
0070 
0071   void FailingInLumiProducer::produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const {}
0072   void FailingInLumiProducer::globalBeginLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const {
0073     // We throw an edm exception with a configurable action.
0074     throw edm::Exception(edm::errors::NotFound) << "Intentional 'NotFound' exception for testing purposes\n";
0075   }
0076 
0077   //--------------------------------------------------------------------
0078   //
0079   // throws an exception.
0080   // Announces an IntProduct but does not produce one;
0081   // every call to FailingProducer::produce throws a cms exception
0082   //
0083   class FailingInRunProducer : public edm::global::EDProducer<edm::BeginRunProducer> {
0084   public:
0085     explicit FailingInRunProducer(edm::ParameterSet const& /*p*/) { produces<IntProduct, edm::Transition::BeginRun>(); }
0086     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0087 
0088     void globalBeginRunProduce(edm::Run&, edm::EventSetup const&) const override;
0089   };
0090 
0091   void FailingInRunProducer::produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const {}
0092   void FailingInRunProducer::globalBeginRunProduce(edm::Run&, edm::EventSetup const&) const {
0093     // We throw an edm exception with a configurable action.
0094     throw edm::Exception(edm::errors::NotFound) << "Intentional 'NotFound' exception for testing purposes\n";
0095   }
0096 
0097   //--------------------------------------------------------------------
0098   //
0099   // Announces an IntProduct but does not produce one;
0100   // every call to NonProducer::produce does nothing.
0101   //
0102   class NonProducer : public edm::global::EDProducer<> {
0103   public:
0104     explicit NonProducer(edm::ParameterSet const& /*p*/) { produces<IntProduct>(); }
0105     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0106   };
0107 
0108   void NonProducer::produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const {}
0109 
0110   //--------------------------------------------------------------------
0111   //
0112   // Produces an IntProduct instance.
0113   //
0114   // NOTE: this really should be a global::EDProducer<> but for testing we use stream
0115   class IntProducer : public edm::stream::EDProducer<> {
0116   public:
0117     explicit IntProducer(edm::ParameterSet const& p)
0118         : token_{produces<IntProduct>()}, value_(p.getParameter<int>("ivalue")) {}
0119     void produce(edm::Event& e, edm::EventSetup const& c) override;
0120 
0121     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0122       edm::ParameterSetDescription desc;
0123       desc.add<int>("ivalue");
0124       descriptions.addDefault(desc);
0125     }
0126 
0127   private:
0128     edm::EDPutTokenT<IntProduct> token_;
0129     int value_;
0130   };
0131 
0132   void IntProducer::produce(edm::Event& e, edm::EventSetup const&) {
0133     // EventSetup is not used.
0134     e.emplace(token_, value_);
0135   }
0136 
0137   //--------------------------------------------------------------------
0138   //
0139   // Produces an IntProduct instance.
0140   //
0141   class IntOneSharedProducer : public edm::one::EDProducer<edm::one::SharedResources> {
0142   public:
0143     explicit IntOneSharedProducer(edm::ParameterSet const& p) : value_(p.getParameter<int>("ivalue")) {
0144       produces<IntProduct>();
0145       for (auto const& r : p.getUntrackedParameter<std::vector<std::string>>("resourceNames")) {
0146         usesResource(r);
0147       }
0148     }
0149     explicit IntOneSharedProducer(int i) : value_(i) {
0150       produces<IntProduct>();
0151       usesResource("IntOneShared");
0152     }
0153     void produce(edm::Event& e, edm::EventSetup const& c) override;
0154 
0155     static void fillDescriptions(edm::ConfigurationDescriptions& iConfig) {
0156       edm::ParameterSetDescription desc;
0157       desc.add<int>("ivalue");
0158       desc.addUntracked<std::vector<std::string>>("resourceNames", std::vector<std::string>{});
0159 
0160       iConfig.addDefault(desc);
0161     }
0162 
0163   private:
0164     int value_;
0165   };
0166 
0167   void IntOneSharedProducer::produce(edm::Event& e, edm::EventSetup const&) {
0168     // EventSetup is not used.
0169     e.put(std::make_unique<IntProduct>(value_));
0170   }
0171 
0172   //--------------------------------------------------------------------
0173   //
0174   // Produces an IntProduct instance.
0175   //
0176   //
0177   class BusyWaitIntProducer : public edm::global::EDProducer<> {
0178   public:
0179     explicit BusyWaitIntProducer(edm::ParameterSet const& p)
0180         : token_{produces<IntProduct>()},
0181           value_(p.getParameter<int>("ivalue")),
0182           iterations_(p.getParameter<unsigned int>("iterations")),
0183           pi_(std::acos(-1)),
0184           lumiNumberToThrow_(p.getParameter<unsigned int>("lumiNumberToThrow")) {}
0185 
0186     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0187 
0188     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0189 
0190   private:
0191     const edm::EDPutTokenT<IntProduct> token_;
0192     const int value_;
0193     const unsigned int iterations_;
0194     const double pi_;
0195     const unsigned int lumiNumberToThrow_;
0196   };
0197 
0198   void BusyWaitIntProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0199     double sum = 0.;
0200     const double stepSize = pi_ / iterations_;
0201     for (unsigned int i = 0; i < iterations_; ++i) {
0202       sum += stepSize * cos(i * stepSize);
0203     }
0204 
0205     e.emplace(token_, value_ + sum);
0206 
0207     if (e.luminosityBlock() == lumiNumberToThrow_) {
0208       throw cms::Exception("Test");
0209     }
0210   }
0211 
0212   void BusyWaitIntProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0213     edm::ParameterSetDescription desc;
0214     desc.add<int>("ivalue");
0215     desc.add<unsigned int>("iterations");
0216     desc.add<unsigned int>("lumiNumberToThrow", 0);
0217     descriptions.addDefault(desc);
0218   }
0219 
0220   //--------------------------------------------------------------------
0221   class BusyWaitIntLimitedProducer : public edm::limited::EDProducer<> {
0222   public:
0223     explicit BusyWaitIntLimitedProducer(edm::ParameterSet const& p)
0224         : edm::limited::EDProducerBase(p),
0225           edm::limited::EDProducer<>(p),
0226           token_{produces<IntProduct>()},
0227           value_(p.getParameter<int>("ivalue")),
0228           iterations_(p.getParameter<unsigned int>("iterations")),
0229           pi_(std::acos(-1)) {}
0230 
0231     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0232 
0233   private:
0234     const edm::EDPutTokenT<IntProduct> token_;
0235     const int value_;
0236     const unsigned int iterations_;
0237     const double pi_;
0238     mutable std::atomic<unsigned int> reentrancy_{0};
0239   };
0240 
0241   void BusyWaitIntLimitedProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0242     auto v = ++reentrancy_;
0243     if (v > concurrencyLimit()) {
0244       --reentrancy_;
0245       throw cms::Exception("NotLimited", "produce called to many times concurrently.");
0246     }
0247 
0248     double sum = 0.;
0249     const double stepSize = pi_ / iterations_;
0250     for (unsigned int i = 0; i < iterations_; ++i) {
0251       sum += stepSize * cos(i * stepSize);
0252     }
0253 
0254     e.emplace(token_, value_ + sum);
0255     --reentrancy_;
0256   }
0257 
0258   //--------------------------------------------------------------------
0259   class BusyWaitIntOneSharedProducer : public edm::one::EDProducer<edm::one::SharedResources> {
0260   public:
0261     explicit BusyWaitIntOneSharedProducer(edm::ParameterSet const& p)
0262         : value_(p.getParameter<int>("ivalue")),
0263           iterations_(p.getParameter<unsigned int>("iterations")),
0264           pi_(std::acos(-1)) {
0265       for (auto const& r : p.getUntrackedParameter<std::vector<std::string>>("resourceNames")) {
0266         usesResource(r);
0267       }
0268       produces<IntProduct>();
0269     }
0270 
0271     static void fillDescriptions(edm::ConfigurationDescriptions& iConfig) {
0272       edm::ParameterSetDescription desc;
0273       desc.add<int>("ivalue");
0274       desc.add<unsigned int>("iterations");
0275       desc.addUntracked<std::vector<std::string>>("resourceNames", std::vector<std::string>{});
0276 
0277       iConfig.addDefault(desc);
0278     }
0279 
0280     void produce(edm::Event& e, edm::EventSetup const& c) override;
0281 
0282   private:
0283     const int value_;
0284     const unsigned int iterations_;
0285     const double pi_;
0286   };
0287 
0288   void BusyWaitIntOneSharedProducer::produce(edm::Event& e, edm::EventSetup const&) {
0289     double sum = 0.;
0290     const double stepSize = pi_ / iterations_;
0291     for (unsigned int i = 0; i < iterations_; ++i) {
0292       sum += stepSize * cos(i * stepSize);
0293     }
0294 
0295     e.put(std::make_unique<IntProduct>(value_ + sum));
0296   }
0297 
0298   //--------------------------------------------------------------------
0299 
0300   class ConsumingIntProducer : public edm::stream::EDProducer<> {
0301   public:
0302     explicit ConsumingIntProducer(edm::ParameterSet const& p)
0303         : token_{produces<IntProduct>()}, value_(p.getParameter<int>("ivalue")) {
0304       // not used, only exists to test PathAndConsumesOfModules
0305       consumes<edm::TriggerResults>(edm::InputTag("TriggerResults"));
0306       consumesMany<edm::TriggerResults>();
0307     }
0308     void produce(edm::Event& e, edm::EventSetup const& c) override;
0309 
0310   private:
0311     const edm::EDPutTokenT<IntProduct> token_;
0312     const int value_;
0313   };
0314 
0315   void ConsumingIntProducer::produce(edm::Event& e, edm::EventSetup const&) { e.emplace(token_, value_); }
0316 
0317   //--------------------------------------------------------------------
0318   //
0319   // Produces an IntProduct instance whose value is the event number,
0320   // rather than the value of a configured parameter.
0321   //
0322   class EventNumberIntProducer : public edm::global::EDProducer<> {
0323   public:
0324     explicit EventNumberIntProducer(edm::ParameterSet const&) : token_{produces<UInt64Product>()} {}
0325     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0326 
0327   private:
0328     const edm::EDPutTokenT<UInt64Product> token_;
0329   };
0330 
0331   void EventNumberIntProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0332     // EventSetup is not used.
0333     e.emplace(token_, e.id().event());
0334   }
0335 
0336   //--------------------------------------------------------------------
0337   //
0338   // Produces a TransientIntProduct instance.
0339   //
0340   class TransientIntProducer : public edm::global::EDProducer<> {
0341   public:
0342     explicit TransientIntProducer(edm::ParameterSet const& p)
0343         : token_{produces<TransientIntProduct>()}, value_(p.getParameter<int>("ivalue")) {}
0344     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0345 
0346   private:
0347     const edm::EDPutTokenT<TransientIntProduct> token_;
0348     const int value_;
0349   };
0350 
0351   void TransientIntProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0352     // EventSetup is not used.
0353     e.emplace(token_, value_);
0354   }
0355 
0356   //--------------------------------------------------------------------
0357   //
0358   // Produces a IntProduct instance from a TransientIntProduct
0359   //
0360   class IntProducerFromTransient : public edm::global::EDProducer<> {
0361   public:
0362     explicit IntProducerFromTransient(edm::ParameterSet const&)
0363         : putToken_{produces<IntProduct>()}, getToken_{consumes(edm::InputTag{"TransientThing"})} {}
0364     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0365 
0366   private:
0367     const edm::EDPutTokenT<IntProduct> putToken_;
0368     const edm::EDGetTokenT<TransientIntProduct> getToken_;
0369   };
0370 
0371   void IntProducerFromTransient::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0372     // EventSetup is not used.
0373     auto result = e.getHandle(getToken_);
0374     assert(result);
0375     e.emplace(putToken_, result.product()->value);
0376   }
0377 
0378   //--------------------------------------------------------------------
0379   //
0380   // Produces a TransientIntParent instance.
0381   //
0382   class TransientIntParentProducer : public edm::global::EDProducer<> {
0383   public:
0384     explicit TransientIntParentProducer(edm::ParameterSet const& p)
0385         : token_{produces<TransientIntParent>()}, value_(p.getParameter<int>("ivalue")) {}
0386     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0387 
0388   private:
0389     const edm::EDPutTokenT<TransientIntParent> token_;
0390     const int value_;
0391   };
0392 
0393   void TransientIntParentProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0394     // EventSetup is not used.
0395     e.emplace(token_, value_);
0396   }
0397 
0398   //--------------------------------------------------------------------
0399   //
0400   // Produces a IntProduct instance from a TransientIntParent
0401   //
0402   class IntProducerFromTransientParent : public edm::global::EDProducer<> {
0403   public:
0404     explicit IntProducerFromTransientParent(edm::ParameterSet const& p)
0405         : putToken_{produces<IntProduct>()}, getToken_{consumes(p.getParameter<edm::InputTag>("src"))} {}
0406     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0407 
0408   private:
0409     const edm::EDPutTokenT<IntProduct> putToken_;
0410     const edm::EDGetTokenT<TransientIntParent> getToken_;
0411   };
0412 
0413   void IntProducerFromTransientParent::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0414     // EventSetup is not used.
0415     e.emplace(putToken_, e.get(getToken_).value);
0416   }
0417 
0418   //--------------------------------------------------------------------
0419   //
0420   // Produces an Int16_tProduct instance.
0421   //
0422   class Int16_tProducer : public edm::global::EDProducer<> {
0423   public:
0424     explicit Int16_tProducer(edm::ParameterSet const& p)
0425         : token_{produces<Int16_tProduct>()}, value_(p.getParameter<int>("ivalue")) {}
0426     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0427 
0428   private:
0429     const edm::EDPutTokenT<Int16_tProduct> token_;
0430     const int16_t value_;
0431   };
0432 
0433   void Int16_tProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0434     // EventSetup is not used.
0435     e.emplace(token_, value_);
0436   }
0437 
0438   //
0439   // Produces an IntProduct instance, using an IntProduct as input.
0440   //
0441 
0442   class AddIntsProducer : public edm::global::EDProducer<> {
0443   public:
0444     explicit AddIntsProducer(edm::ParameterSet const& p)
0445         : putToken_{produces<IntProduct>()},
0446           otherPutToken_{produces<IntProduct>("other")},
0447           onlyGetOnEvent_(p.getUntrackedParameter<unsigned int>("onlyGetOnEvent")) {
0448       auto const& labels = p.getParameter<std::vector<edm::InputTag>>("labels");
0449       for (auto const& label : labels) {
0450         tokens_.emplace_back(consumes(label));
0451       }
0452     }
0453     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0454 
0455     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0456       edm::ParameterSetDescription desc;
0457       desc.addUntracked<unsigned int>("onlyGetOnEvent", 0u);
0458       desc.add<std::vector<edm::InputTag>>("labels");
0459       descriptions.addDefault(desc);
0460     }
0461 
0462   private:
0463     std::vector<edm::EDGetTokenT<IntProduct>> tokens_;
0464     const edm::EDPutTokenT<IntProduct> putToken_;
0465     const edm::EDPutTokenT<IntProduct> otherPutToken_;
0466     unsigned int onlyGetOnEvent_;
0467   };
0468 
0469   void AddIntsProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0470     // EventSetup is not used.
0471     int value = 0;
0472 
0473     if (onlyGetOnEvent_ == 0u || e.eventAuxiliary().event() == onlyGetOnEvent_) {
0474       for (auto const& token : tokens_) {
0475         value += e.get(token).value;
0476       }
0477     }
0478     e.emplace(putToken_, value);
0479     e.emplace(otherPutToken_, value);
0480   }
0481 
0482   //
0483   // Produces an IntProduct instance, using many IntProducts as input.
0484   //
0485 
0486   class AddAllIntsProducer : public edm::global::EDProducer<> {
0487   public:
0488     explicit AddAllIntsProducer(edm::ParameterSet const& p) : putToken_{produces()} { consumesMany<IntProduct>(); }
0489     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0490 
0491     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0492       edm::ParameterSetDescription desc;
0493       descriptions.addDefault(desc);
0494     }
0495 
0496   private:
0497     const edm::EDPutTokenT<int> putToken_;
0498   };
0499 
0500   void AddAllIntsProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0501     std::vector<edm::Handle<IntProduct>> ints;
0502     e.getManyByType(ints);
0503 
0504     int value = 0;
0505     for (auto const& i : ints) {
0506       value += i->value;
0507     }
0508 
0509     e.emplace(putToken_, value);
0510   }
0511 
0512   //
0513   // Produces multiple IntProduct products
0514   //
0515 
0516   class ManyIntProducer : public edm::global::EDProducer<> {
0517   public:
0518     explicit ManyIntProducer(edm::ParameterSet const& p)
0519         : tokenValues_{vector_transform(
0520               p.getParameter<std::vector<edm::ParameterSet>>("values"),
0521               [this](edm::ParameterSet const& pset) {
0522                 auto const& branchAlias = pset.getParameter<std::string>("branchAlias");
0523                 if (not branchAlias.empty()) {
0524                   return TokenValue{
0525                       produces<IntProduct>(pset.getParameter<std::string>("instance")).setBranchAlias(branchAlias),
0526                       pset.getParameter<int>("value")};
0527                 }
0528                 return TokenValue{produces<IntProduct>(pset.getParameter<std::string>("instance")),
0529                                   pset.getParameter<int>("value")};
0530               })},
0531           transientTokenValues_{vector_transform(
0532               p.getParameter<std::vector<edm::ParameterSet>>("transientValues"),
0533               [this](edm::ParameterSet const& pset) {
0534                 auto const& branchAlias = pset.getParameter<std::string>("branchAlias");
0535                 if (not branchAlias.empty()) {
0536                   return TransientTokenValue{produces<TransientIntProduct>(pset.getParameter<std::string>("instance"))
0537                                                  .setBranchAlias(branchAlias),
0538                                              pset.getParameter<int>("value")};
0539                 }
0540                 return TransientTokenValue{produces<TransientIntProduct>(pset.getParameter<std::string>("instance")),
0541                                            pset.getParameter<int>("value")};
0542               })},
0543           throw_{p.getUntrackedParameter<bool>("throw")} {
0544       tokenValues_.push_back(TokenValue{produces<IntProduct>(), p.getParameter<int>("ivalue")});
0545     }
0546 
0547     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0548       edm::ParameterSetDescription desc;
0549       desc.add<int>("ivalue");
0550       desc.addUntracked<bool>("throw", false);
0551 
0552       {
0553         edm::ParameterSetDescription pset;
0554         pset.add<std::string>("instance");
0555         pset.add<int>("value");
0556         pset.add<std::string>("branchAlias", "");
0557         desc.addVPSet("values", pset, std::vector<edm::ParameterSet>{});
0558         desc.addVPSet("transientValues", pset, std::vector<edm::ParameterSet>{});
0559       }
0560 
0561       descriptions.addDefault(desc);
0562     }
0563 
0564     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0565 
0566   private:
0567     struct TokenValue {
0568       edm::EDPutTokenT<IntProduct> token;
0569       int value;
0570     };
0571     std::vector<TokenValue> tokenValues_;
0572 
0573     struct TransientTokenValue {
0574       edm::EDPutTokenT<TransientIntProduct> token;
0575       int value;
0576     };
0577     std::vector<TransientTokenValue> transientTokenValues_;
0578 
0579     bool throw_;
0580   };
0581 
0582   void ManyIntProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0583     if (throw_) {
0584       throw edm::Exception(edm::errors::NotFound) << "Intentional 'NotFound' exception for testing purposes\n";
0585     }
0586 
0587     // EventSetup is not used.
0588     for (auto const& tv : tokenValues_) {
0589       e.emplace(tv.token, tv.value);
0590     }
0591     for (auto const& tv : transientTokenValues_) {
0592       e.emplace(tv.token, tv.value);
0593     }
0594   }
0595 
0596   //
0597   // Produces multiple IntProduct products based on other products
0598   //
0599 
0600   class ManyIntWhenRegisteredProducer : public edm::global::EDProducer<> {
0601   public:
0602     explicit ManyIntWhenRegisteredProducer(edm::ParameterSet const& p)
0603         : sourceLabel_(p.getParameter<std::string>("src")) {
0604       callWhenNewProductsRegistered([=](edm::BranchDescription const& iBranch) {
0605         if (iBranch.moduleLabel() == sourceLabel_) {
0606           if (iBranch.branchType() != edm::InEvent) {
0607             throw edm::Exception(edm::errors::UnimplementedFeature)
0608                 << "ManyIntWhenRegisteredProducer supports only event branches";
0609           }
0610 
0611           this->tokens_.push_back(
0612               Tokens{this->consumes<IntProduct>(
0613                          edm::InputTag{iBranch.moduleLabel(), iBranch.productInstanceName(), iBranch.processName()}),
0614                      this->produces<IntProduct>(iBranch.productInstanceName())});
0615         }
0616       });
0617     }
0618 
0619     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0620       edm::ParameterSetDescription desc;
0621       desc.add<std::string>("src");
0622       descriptions.addDefault(desc);
0623     }
0624 
0625     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0626 
0627   private:
0628     struct Tokens {
0629       edm::EDGetTokenT<IntProduct> get;
0630       edm::EDPutTokenT<IntProduct> put;
0631     };
0632 
0633     std::string sourceLabel_;
0634     std::vector<Tokens> tokens_;
0635   };
0636 
0637   void ManyIntWhenRegisteredProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0638     for (auto const& toks : tokens_) {
0639       e.emplace(toks.put, e.get(toks.get));
0640     }
0641   };
0642 
0643   //--------------------------------------------------------------------
0644 
0645   class NonEventIntProducer : public edm::global::EDProducer<edm::Accumulator,
0646                                                              edm::BeginRunProducer,
0647                                                              edm::BeginLuminosityBlockProducer,
0648                                                              edm::EndLuminosityBlockProducer,
0649                                                              edm::EndRunProducer,
0650                                                              edm::BeginProcessBlockProducer,
0651                                                              edm::EndProcessBlockProducer,
0652                                                              edm::InputProcessBlockCache<>> {
0653   public:
0654     explicit NonEventIntProducer(edm::ParameterSet const& p)
0655         : bpbToken_{produces<IntProduct, edm::Transition::BeginProcessBlock>("beginProcessBlock")},
0656           brToken_{produces<IntProduct, edm::Transition::BeginRun>("beginRun")},
0657           blToken_{produces<IntProduct, edm::Transition::BeginLuminosityBlock>("beginLumi")},
0658           elToken_{produces<IntProduct, edm::Transition::EndLuminosityBlock>("endLumi")},
0659           erToken_{produces<IntProduct, edm::Transition::EndRun>("endRun")},
0660           epbToken_{produces<IntProduct, edm::Transition::EndProcessBlock>("endProcessBlock")},
0661           value_(p.getParameter<int>("ivalue")),
0662           sleepTime_(p.getParameter<unsigned int>("sleepTime")),
0663           bpbExpect_{p.getUntrackedParameter<int>("expectBeginProcessBlock")},
0664           brExpect_{p.getUntrackedParameter<int>("expectBeginRun")},
0665           blExpect_{p.getUntrackedParameter<int>("expectBeginLuminosityBlock")},
0666           elExpect_{p.getUntrackedParameter<int>("expectEndLuminosityBlock")},
0667           erExpect_{p.getUntrackedParameter<int>("expectEndRun")},
0668           epbExpect_{p.getUntrackedParameter<int>("expectEndProcessBlock")},
0669           aipbExpect_{p.getUntrackedParameter<int>("expectAccessInputProcessBlock")} {
0670       {
0671         auto tag = p.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0672         if (not tag.label().empty()) {
0673           bpbGet_ = consumes<edm::InProcess>(tag);
0674         }
0675       }
0676       {
0677         auto tag = p.getParameter<edm::InputTag>("consumesBeginRun");
0678         if (not tag.label().empty()) {
0679           brGet_ = consumes<edm::InRun>(tag);
0680         }
0681       }
0682       {
0683         auto tag = p.getParameter<edm::InputTag>("consumesBeginLuminosityBlock");
0684         if (not tag.label().empty()) {
0685           blGet_ = consumes<edm::InLumi>(tag);
0686         }
0687       }
0688       {
0689         auto tag = p.getParameter<edm::InputTag>("consumesEndLuminosityBlock");
0690         if (not tag.label().empty()) {
0691           elGet_ = consumes<edm::InLumi>(tag);
0692         }
0693       }
0694       {
0695         auto tag = p.getParameter<edm::InputTag>("consumesEndRun");
0696         if (not tag.label().empty()) {
0697           erGet_ = consumes<edm::InRun>(tag);
0698         }
0699       }
0700       {
0701         auto tag = p.getParameter<edm::InputTag>("consumesEndProcessBlock");
0702         if (not tag.label().empty()) {
0703           epbGet_ = consumes<edm::InProcess>(tag);
0704         }
0705       }
0706       {
0707         auto tag = p.getParameter<edm::InputTag>("consumesAccessInputProcessBlock");
0708         if (not tag.label().empty()) {
0709           aipbGet_ = consumes<edm::InProcess>(tag);
0710         }
0711       }
0712     }
0713     void accumulate(edm::StreamID iID, edm::Event const& e, edm::EventSetup const& c) const override;
0714     void beginProcessBlockProduce(edm::ProcessBlock&) override;
0715     void endProcessBlockProduce(edm::ProcessBlock&) override;
0716     void globalBeginRunProduce(edm::Run& e, edm::EventSetup const&) const override;
0717     void globalEndRunProduce(edm::Run& e, edm::EventSetup const&) const override;
0718     void globalBeginLuminosityBlockProduce(edm::LuminosityBlock& e, edm::EventSetup const&) const override;
0719     void globalEndLuminosityBlockProduce(edm::LuminosityBlock& e, edm::EventSetup const&) const override;
0720     void accessInputProcessBlock(edm::ProcessBlock const&) override;
0721 
0722     static void fillDescriptions(edm::ConfigurationDescriptions& conf) {
0723       edm::ParameterSetDescription desc;
0724       desc.add<int>("ivalue", 0);
0725       desc.add<unsigned int>("sleepTime", 0);
0726       desc.add<edm::InputTag>("consumesBeginProcessBlock", {});
0727       desc.addUntracked<int>("expectBeginProcessBlock", 0);
0728       desc.add<edm::InputTag>("consumesEndProcessBlock", {});
0729       desc.addUntracked<int>("expectEndProcessBlock", 0);
0730       desc.add<edm::InputTag>("consumesAccessInputProcessBlock", {});
0731       desc.addUntracked<int>("expectAccessInputProcessBlock", 0);
0732       desc.add<edm::InputTag>("consumesBeginRun", {});
0733       desc.addUntracked<int>("expectBeginRun", 0);
0734       desc.add<edm::InputTag>("consumesEndRun", {});
0735       desc.addUntracked<int>("expectEndRun", 0);
0736       desc.add<edm::InputTag>("consumesBeginLuminosityBlock", {});
0737       desc.addUntracked<int>("expectBeginLuminosityBlock", 0);
0738       desc.add<edm::InputTag>("consumesEndLuminosityBlock", {});
0739       desc.addUntracked<int>("expectEndLuminosityBlock", 0);
0740 
0741       conf.addDefault(desc);
0742     }
0743 
0744   private:
0745     void check(IntProduct, int) const;
0746     const edm::EDPutTokenT<IntProduct> bpbToken_;
0747     const edm::EDPutTokenT<IntProduct> brToken_;
0748     const edm::EDPutTokenT<IntProduct> blToken_;
0749     const edm::EDPutTokenT<IntProduct> elToken_;
0750     const edm::EDPutTokenT<IntProduct> erToken_;
0751     const edm::EDPutTokenT<IntProduct> epbToken_;
0752     const int value_;
0753     const unsigned int sleepTime_;
0754     edm::EDGetTokenT<IntProduct> bpbGet_;
0755     edm::EDGetTokenT<IntProduct> brGet_;
0756     edm::EDGetTokenT<IntProduct> blGet_;
0757     edm::EDGetTokenT<IntProduct> elGet_;
0758     edm::EDGetTokenT<IntProduct> erGet_;
0759     edm::EDGetTokenT<IntProduct> epbGet_;
0760     edm::EDGetTokenT<IntProduct> aipbGet_;
0761     const int bpbExpect_;
0762     const int brExpect_;
0763     const int blExpect_;
0764     const int elExpect_;
0765     const int erExpect_;
0766     const int epbExpect_;
0767     const int aipbExpect_;
0768   };
0769 
0770   void NonEventIntProducer::accumulate(edm::StreamID iID, edm::Event const& e, edm::EventSetup const&) const {}
0771   void NonEventIntProducer::beginProcessBlockProduce(edm::ProcessBlock& processBlock) {
0772     if (not bpbGet_.isUninitialized()) {
0773       check(processBlock.get(bpbGet_), bpbExpect_);
0774     }
0775     if (sleepTime_ > 0) {
0776       // These sleeps are here to force modules to run concurrently
0777       // in multi-threaded processes. Otherwise, the modules are so
0778       // fast it is hard to tell whether a module finishes before the
0779       // the Framework starts the next module.
0780       usleep(sleepTime_);
0781     }
0782     processBlock.emplace(bpbToken_, value_);
0783   }
0784   void NonEventIntProducer::endProcessBlockProduce(edm::ProcessBlock& processBlock) {
0785     if (not epbGet_.isUninitialized()) {
0786       check(processBlock.get(epbGet_), epbExpect_);
0787     }
0788     if (sleepTime_ > 0) {
0789       usleep(sleepTime_);
0790     }
0791     processBlock.emplace(epbToken_, value_);
0792   }
0793   void NonEventIntProducer::accessInputProcessBlock(edm::ProcessBlock const& processBlock) {
0794     if (not aipbGet_.isUninitialized()) {
0795       check(processBlock.get(aipbGet_), aipbExpect_);
0796     }
0797     if (sleepTime_ > 0) {
0798       usleep(sleepTime_);
0799     }
0800   }
0801   void NonEventIntProducer::globalBeginRunProduce(edm::Run& r, edm::EventSetup const&) const {
0802     if (not brGet_.isUninitialized()) {
0803       check(r.get(brGet_), brExpect_);
0804     }
0805     if (sleepTime_ > 0) {
0806       usleep(sleepTime_);
0807     }
0808     r.emplace(brToken_, value_);
0809   }
0810   void NonEventIntProducer::globalEndRunProduce(edm::Run& r, edm::EventSetup const&) const {
0811     if (not erGet_.isUninitialized()) {
0812       check(r.get(erGet_), erExpect_);
0813     }
0814     if (sleepTime_ > 0) {
0815       usleep(sleepTime_);
0816     }
0817     r.emplace(erToken_, value_);
0818   }
0819   void NonEventIntProducer::globalBeginLuminosityBlockProduce(edm::LuminosityBlock& l, edm::EventSetup const&) const {
0820     if (not blGet_.isUninitialized()) {
0821       check(l.get(blGet_), blExpect_);
0822     }
0823     if (sleepTime_ > 0) {
0824       usleep(sleepTime_);
0825     }
0826     l.emplace(blToken_, value_);
0827   }
0828   void NonEventIntProducer::globalEndLuminosityBlockProduce(edm::LuminosityBlock& l, edm::EventSetup const&) const {
0829     if (not elGet_.isUninitialized()) {
0830       check(l.get(elGet_), elExpect_);
0831     }
0832     if (sleepTime_ > 0) {
0833       usleep(sleepTime_);
0834     }
0835     l.emplace(elToken_, value_);
0836   }
0837   void NonEventIntProducer::check(IntProduct iProd, int iExpect) const {
0838     if (iExpect != iProd.value) {
0839       throw cms::Exception("BadValue") << "expected " << iExpect << " but got " << iProd.value;
0840     }
0841   }
0842 
0843   //--------------------------------------------------------------------
0844   //
0845   // Produces an IntProduct in ProcessBlock at beginProcessBlock
0846   //
0847   class IntProducerBeginProcessBlock : public edm::global::EDProducer<edm::BeginProcessBlockProducer> {
0848   public:
0849     explicit IntProducerBeginProcessBlock(edm::ParameterSet const& p)
0850         : token_{produces<IntProduct, edm::Transition::BeginProcessBlock>()}, value_(p.getParameter<int>("ivalue")) {}
0851     void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {}
0852     void beginProcessBlockProduce(edm::ProcessBlock&) override;
0853 
0854   private:
0855     edm::EDPutTokenT<IntProduct> token_;
0856     int value_;
0857   };
0858 
0859   void IntProducerBeginProcessBlock::beginProcessBlockProduce(edm::ProcessBlock& processBlock) {
0860     processBlock.emplace(token_, value_);
0861   }
0862 
0863   //--------------------------------------------------------------------
0864   //
0865   // Produces an IntProduct in ProcessBlock at endProcessBlock
0866   //
0867   class IntProducerEndProcessBlock : public edm::global::EDProducer<edm::EndProcessBlockProducer> {
0868   public:
0869     explicit IntProducerEndProcessBlock(edm::ParameterSet const& p)
0870         : token_{produces<IntProduct, edm::Transition::EndProcessBlock>()},
0871           token2_{produces<IntProduct, edm::Transition::EndProcessBlock>("two")},
0872           token3_{produces<IntProduct, edm::Transition::EndProcessBlock>("three")},
0873           token4_{produces<IntProduct, edm::Transition::EndProcessBlock>("four")},
0874           value_(p.getParameter<int>("ivalue")) {}
0875     void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {}
0876     void endProcessBlockProduce(edm::ProcessBlock&) override;
0877 
0878   private:
0879     edm::EDPutTokenT<IntProduct> token_;
0880     edm::EDPutToken token2_;
0881     edm::EDPutTokenT<IntProduct> token3_;
0882     edm::EDPutToken token4_;
0883     int value_;
0884   };
0885 
0886   void IntProducerEndProcessBlock::endProcessBlockProduce(edm::ProcessBlock& processBlock) {
0887     processBlock.emplace(token_, value_);
0888     processBlock.emplace<IntProduct>(token2_, value_ + 2);
0889     processBlock.put(token3_, std::make_unique<IntProduct>(value_ + 3));
0890     processBlock.put(token4_, std::make_unique<IntProduct>(value_ + 4));
0891   }
0892 
0893   //--------------------------------------------------------------------
0894   //
0895   // Produces an TransientIntProduct in ProcessBlock at endProcessBlock
0896   //
0897   class TransientIntProducerEndProcessBlock : public edm::global::EDProducer<edm::EndProcessBlockProducer> {
0898   public:
0899     explicit TransientIntProducerEndProcessBlock(edm::ParameterSet const& p)
0900         : token_{produces<TransientIntProduct, edm::Transition::EndProcessBlock>()},
0901           value_(p.getParameter<int>("ivalue")) {}
0902     void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {}
0903     void endProcessBlockProduce(edm::ProcessBlock&) override;
0904 
0905   private:
0906     edm::EDPutTokenT<TransientIntProduct> token_;
0907     int value_;
0908   };
0909 
0910   void TransientIntProducerEndProcessBlock::endProcessBlockProduce(edm::ProcessBlock& processBlock) {
0911     processBlock.emplace(token_, value_);
0912   }
0913 
0914   //--------------------------------------------------------------------
0915   //
0916   // Produces an IntProduct instance, the module must get run, otherwise an exception is thrown
0917   class MustRunIntProducer : public edm::global::EDProducer<> {
0918   public:
0919     explicit MustRunIntProducer(edm::ParameterSet const& p)
0920         : moduleLabel_{p.getParameter<std::string>("@module_label")},
0921           token_{produces<IntProduct>()},
0922           value_(p.getParameter<int>("ivalue")),
0923           produce_{p.getParameter<bool>("produce")},
0924           mustRunEvent_{p.getParameter<bool>("mustRunEvent")} {}
0925     ~MustRunIntProducer() {
0926       if (not wasRunEndJob_) {
0927         throw cms::Exception("NotRun") << "This module (" << moduleLabel_
0928                                        << ") should have run for endJob transition, but it did not";
0929       }
0930     }
0931     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0932       edm::ParameterSetDescription desc;
0933       desc.add<int>("ivalue");
0934       desc.add<bool>("produce", true);
0935       desc.add<bool>("mustRunEvent", true)
0936           ->setComment(
0937               "If set to false, the endJob() is still required to be called to check that the module was not deleted "
0938               "early on");
0939       descriptions.addDefault(desc);
0940     }
0941     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override {
0942       wasRunEvent_ = true;
0943       if (produce_) {
0944         e.emplace(token_, value_);
0945       }
0946     }
0947     void endJob() override {
0948       wasRunEndJob_ = true;
0949       if (mustRunEvent_ and not wasRunEvent_) {
0950         throw cms::Exception("NotRun") << "This module should have run for event transitions, but it did not";
0951       }
0952     }
0953 
0954   private:
0955     const std::string moduleLabel_;
0956     const edm::EDPutTokenT<IntProduct> token_;
0957     const int value_;
0958     const bool produce_;
0959     const bool mustRunEvent_;
0960     mutable std::atomic<bool> wasRunEndJob_ = false;
0961     mutable std::atomic<bool> wasRunEvent_ = false;
0962   };
0963 }  // namespace edmtest
0964 
0965 namespace edm::test {
0966   namespace other {
0967     class IntProducer : public edm::global::EDProducer<> {
0968     public:
0969       explicit IntProducer(edm::ParameterSet const& p)
0970           : token_{produces()}, value_(p.getParameter<int>("valueOther")) {}
0971       void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const final { e.emplace(token_, value_); }
0972 
0973       static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0974         edm::ParameterSetDescription desc;
0975         desc.add<int>("valueOther");
0976         desc.add<int>("valueCpu");
0977         desc.addUntracked<std::string>("variant", "");
0978 
0979         descriptions.addWithDefaultLabel(desc);
0980       }
0981 
0982     private:
0983       edm::EDPutTokenT<edmtest::IntProduct> token_;
0984       int value_;
0985     };
0986   }  // namespace other
0987   namespace cpu {
0988     class IntProducer : public edm::global::EDProducer<> {
0989     public:
0990       explicit IntProducer(edm::ParameterSet const& p) : token_{produces()}, value_(p.getParameter<int>("valueCpu")) {}
0991       void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const final { e.emplace(token_, value_); }
0992 
0993       static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0994         edm::ParameterSetDescription desc;
0995         desc.add<int>("valueOther");
0996         desc.add<int>("valueCpu");
0997         desc.addUntracked<std::string>("variant", "");
0998 
0999         descriptions.addWithDefaultLabel(desc);
1000       }
1001 
1002     private:
1003       edm::EDPutTokenT<edmtest::IntProduct> token_;
1004       int value_;
1005     };
1006   }  // namespace cpu
1007 }  // namespace edm::test
1008 
1009 using edmtest::AddAllIntsProducer;
1010 using edmtest::AddIntsProducer;
1011 using edmtest::BusyWaitIntLimitedProducer;
1012 using edmtest::BusyWaitIntOneSharedProducer;
1013 using edmtest::BusyWaitIntProducer;
1014 using edmtest::ConsumingIntProducer;
1015 using edmtest::EventNumberIntProducer;
1016 using edmtest::FailingProducer;
1017 using edmtest::Int16_tProducer;
1018 using edmtest::IntOneSharedProducer;
1019 using edmtest::IntProducer;
1020 using edmtest::IntProducerBeginProcessBlock;
1021 using edmtest::IntProducerEndProcessBlock;
1022 using edmtest::IntProducerFromTransient;
1023 using edmtest::ManyIntProducer;
1024 using edmtest::ManyIntWhenRegisteredProducer;
1025 using edmtest::NonEventIntProducer;
1026 using edmtest::NonProducer;
1027 using edmtest::TransientIntProducer;
1028 using edmtest::TransientIntProducerEndProcessBlock;
1029 DEFINE_FWK_MODULE(FailingProducer);
1030 DEFINE_FWK_MODULE(edmtest::FailingInLumiProducer);
1031 DEFINE_FWK_MODULE(edmtest::FailingInRunProducer);
1032 DEFINE_FWK_MODULE(NonProducer);
1033 DEFINE_FWK_MODULE(IntProducer);
1034 DEFINE_FWK_MODULE(IntOneSharedProducer);
1035 DEFINE_FWK_MODULE(BusyWaitIntProducer);
1036 DEFINE_FWK_MODULE(BusyWaitIntLimitedProducer);
1037 DEFINE_FWK_MODULE(BusyWaitIntOneSharedProducer);
1038 DEFINE_FWK_MODULE(ConsumingIntProducer);
1039 DEFINE_FWK_MODULE(EventNumberIntProducer);
1040 DEFINE_FWK_MODULE(TransientIntProducer);
1041 DEFINE_FWK_MODULE(IntProducerFromTransient);
1042 DEFINE_FWK_MODULE(edmtest::TransientIntParentProducer);
1043 DEFINE_FWK_MODULE(edmtest::IntProducerFromTransientParent);
1044 DEFINE_FWK_MODULE(Int16_tProducer);
1045 DEFINE_FWK_MODULE(AddIntsProducer);
1046 DEFINE_FWK_MODULE(AddAllIntsProducer);
1047 DEFINE_FWK_MODULE(ManyIntProducer);
1048 DEFINE_FWK_MODULE(ManyIntWhenRegisteredProducer);
1049 DEFINE_FWK_MODULE(NonEventIntProducer);
1050 DEFINE_FWK_MODULE(IntProducerBeginProcessBlock);
1051 DEFINE_FWK_MODULE(IntProducerEndProcessBlock);
1052 DEFINE_FWK_MODULE(TransientIntProducerEndProcessBlock);
1053 DEFINE_FWK_MODULE(edmtest::MustRunIntProducer);
1054 DEFINE_FWK_MODULE(edm::test::other::IntProducer);
1055 DEFINE_FWK_MODULE(edm::test::cpu::IntProducer);