Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-09-11 22:29:26

0001 #ifndef FWCore_Framework_global_implementors_h
0002 #define FWCore_Framework_global_implementors_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     FWCore/Framework
0006 // Class  :     implementors
0007 //
0008 /**\file implementors.h "FWCore/Framework/interface/global/implementors.h"
0009 
0010  Description: Base classes used to implement the interfaces for the edm::global::* module  abilities
0011 
0012  Usage:
0013     <usage>
0014 
0015 */
0016 //
0017 // Original Author:  Chris Jones
0018 //         Created:  Thu, 18 Jul 2013 11:52:34 GMT
0019 //
0020 
0021 // system include files
0022 #include <cstddef>
0023 #include <memory>
0024 #include <mutex>
0025 #include <string>
0026 #include <tuple>
0027 #include <utility>
0028 #include <vector>
0029 
0030 // user include files
0031 #include "FWCore/Common/interface/FWCoreCommonFwd.h"
0032 #include "FWCore/Framework/interface/CacheHandle.h"
0033 #include "FWCore/Framework/interface/Frameworkfwd.h"
0034 #include "FWCore/Framework/interface/InputProcessBlockCacheImpl.h"
0035 #include "FWCore/Framework/interface/LuminosityBlock.h"
0036 #include "FWCore/Framework/interface/TransformerBase.h"
0037 #include "FWCore/Framework/interface/ProductRegistryHelper.h"
0038 #include "FWCore/Utilities/interface/EDGetToken.h"
0039 #include "FWCore/Utilities/interface/StreamID.h"
0040 #include "FWCore/Utilities/interface/ProcessBlockIndex.h"
0041 #include "FWCore/Utilities/interface/RunIndex.h"
0042 #include "FWCore/Utilities/interface/LuminosityBlockIndex.h"
0043 #include "FWCore/Utilities/interface/propagate_const.h"
0044 #include "DataFormats/Common/interface/Wrapper.h"
0045 
0046 // forward declarations
0047 namespace edm {
0048 
0049   class WaitingTaskWithArenaHolder;
0050 
0051   namespace global {
0052     namespace impl {
0053       class EmptyType {};
0054 
0055       template <typename T, typename C>
0056       class StreamCacheHolder : public virtual T {
0057       public:
0058         StreamCacheHolder() = default;
0059         StreamCacheHolder(StreamCacheHolder<T, C> const&) = delete;
0060         StreamCacheHolder<T, C>& operator=(StreamCacheHolder<T, C> const&) = delete;
0061         ~StreamCacheHolder() override {
0062           for (auto c : caches_) {
0063             delete c;
0064           }
0065         }
0066 
0067       protected:
0068         C* streamCache(edm::StreamID iID) const { return caches_[iID.value()]; }
0069 
0070       private:
0071         void preallocStreams(unsigned int iNStreams) final { caches_.resize(iNStreams, static_cast<C*>(nullptr)); }
0072         void doBeginStream_(StreamID id) final { caches_[id.value()] = beginStream(id).release(); }
0073         void doEndStream_(StreamID id) final {
0074           endStream(id);
0075           delete caches_[id.value()];
0076           caches_[id.value()] = nullptr;
0077         }
0078         void doStreamBeginRun_(StreamID id, Run const& rp, EventSetup const& c) final { streamBeginRun(id, rp, c); }
0079         void doStreamEndRun_(StreamID id, Run const& rp, EventSetup const& c) final { streamEndRun(id, rp, c); }
0080         void doStreamBeginLuminosityBlock_(StreamID id, LuminosityBlock const& lbp, EventSetup const& c) final {
0081           streamBeginLuminosityBlock(id, lbp, c);
0082         }
0083         void doStreamEndLuminosityBlock_(StreamID id, LuminosityBlock const& lbp, EventSetup const& c) final {
0084           streamEndLuminosityBlock(id, lbp, c);
0085         }
0086 
0087         virtual std::unique_ptr<C> beginStream(edm::StreamID) const = 0;
0088         virtual void streamBeginRun(edm::StreamID, edm::Run const&, edm::EventSetup const&) const {}
0089         virtual void streamBeginLuminosityBlock(edm::StreamID,
0090                                                 edm::LuminosityBlock const&,
0091                                                 edm::EventSetup const&) const {}
0092         virtual void streamEndLuminosityBlock(edm::StreamID,
0093                                               edm::LuminosityBlock const&,
0094                                               edm::EventSetup const&) const {}
0095         virtual void streamEndRun(edm::StreamID, edm::Run const&, edm::EventSetup const&) const {}
0096         virtual void endStream(edm::StreamID) const {}
0097 
0098         //When threaded we will have a container for N items whre N is # of streams
0099         std::vector<C*> caches_;
0100       };
0101 
0102       template <typename T, typename... CacheTypes>
0103       class InputProcessBlockCacheHolder : public virtual T {
0104       public:
0105         InputProcessBlockCacheHolder() = default;
0106         InputProcessBlockCacheHolder(InputProcessBlockCacheHolder const&) = delete;
0107         InputProcessBlockCacheHolder& operator=(InputProcessBlockCacheHolder const&) = delete;
0108         ~InputProcessBlockCacheHolder() override {}
0109 
0110         std::tuple<CacheHandle<CacheTypes>...> processBlockCaches(Event const& event) const {
0111           return cacheImpl_.processBlockCaches(event);
0112         }
0113 
0114         template <std::size_t ICacheType, typename DataType, typename Func>
0115         void registerProcessBlockCacheFiller(EDGetTokenT<DataType> const& token, Func&& func) {
0116           cacheImpl_.template registerProcessBlockCacheFiller<ICacheType, DataType, Func>(token,
0117                                                                                           std::forward<Func>(func));
0118         }
0119 
0120         template <typename CacheType, typename DataType, typename Func>
0121         void registerProcessBlockCacheFiller(EDGetTokenT<DataType> const& token, Func&& func) {
0122           cacheImpl_.template registerProcessBlockCacheFiller<CacheType, DataType, Func>(token,
0123                                                                                          std::forward<Func>(func));
0124         }
0125 
0126         // This is intended for use by Framework unit tests only
0127         unsigned int cacheSize() const { return cacheImpl_.cacheSize(); }
0128 
0129       private:
0130         void doSelectInputProcessBlocks(ProductRegistry const& productRegistry,
0131                                         ProcessBlockHelperBase const& processBlockHelperBase) final {
0132           cacheImpl_.selectInputProcessBlocks(productRegistry, processBlockHelperBase, *this);
0133         }
0134 
0135         void doAccessInputProcessBlock_(ProcessBlock const& pb) final {
0136           cacheImpl_.accessInputProcessBlock(pb);
0137           accessInputProcessBlock(pb);
0138         }
0139 
0140         // Alternate method to access ProcessBlocks without using the caches
0141         // Mostly intended for unit testing, but might have other uses...
0142         virtual void accessInputProcessBlock(ProcessBlock const&) {}
0143 
0144         void clearInputProcessBlockCaches() final { cacheImpl_.clearCaches(); }
0145 
0146         edm::impl::InputProcessBlockCacheImpl<CacheTypes...> cacheImpl_;
0147       };
0148 
0149       template <typename T, typename C>
0150       class RunCacheHolder : public virtual T {
0151       public:
0152         RunCacheHolder() = default;
0153         RunCacheHolder(RunCacheHolder<T, C> const&) = delete;
0154         RunCacheHolder<T, C>& operator=(RunCacheHolder<T, C> const&) = delete;
0155         ~RunCacheHolder() noexcept(false) override{};
0156 
0157       protected:
0158         C const* runCache(edm::RunIndex iID) const { return cache_.get(); }
0159 
0160       private:
0161         void doBeginRun_(Run const& rp, EventSetup const& c) final { cache_ = globalBeginRun(rp, c); }
0162         void doEndRun_(Run const& rp, EventSetup const& c) final {
0163           globalEndRun(rp, c);
0164           cache_ = nullptr;  // propagate_const<T> has no reset() function
0165         }
0166 
0167         virtual std::shared_ptr<C> globalBeginRun(edm::Run const&, edm::EventSetup const&) const = 0;
0168         virtual void globalEndRun(edm::Run const&, edm::EventSetup const&) const = 0;
0169         //When threaded we will have a container for N items whre N is # of simultaneous runs
0170         edm::propagate_const<std::shared_ptr<C>> cache_;
0171       };
0172 
0173       template <typename T, typename C>
0174       class LuminosityBlockCacheHolder : public virtual T {
0175       public:
0176         LuminosityBlockCacheHolder() = default;
0177         LuminosityBlockCacheHolder(LuminosityBlockCacheHolder<T, C> const&) = delete;
0178         LuminosityBlockCacheHolder<T, C>& operator=(LuminosityBlockCacheHolder<T, C> const&) = delete;
0179         ~LuminosityBlockCacheHolder() noexcept(false) override{};
0180 
0181       protected:
0182         void preallocLumis(unsigned int iNLumis) final { caches_.reset(new std::shared_ptr<C>[iNLumis]); }
0183 
0184         C const* luminosityBlockCache(edm::LuminosityBlockIndex iID) const { return caches_[iID].get(); }
0185 
0186       private:
0187         void doBeginLuminosityBlock_(LuminosityBlock const& lp, EventSetup const& c) final {
0188           caches_[lp.index()] = globalBeginLuminosityBlock(lp, c);
0189         }
0190         void doEndLuminosityBlock_(LuminosityBlock const& lp, EventSetup const& c) final {
0191           globalEndLuminosityBlock(lp, c);
0192           caches_[lp.index()].reset();
0193         }
0194 
0195         virtual std::shared_ptr<C> globalBeginLuminosityBlock(edm::LuminosityBlock const&,
0196                                                               edm::EventSetup const&) const = 0;
0197         virtual void globalEndLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) const = 0;
0198         //When threaded we will have a container for N items whre N is # of simultaneous runs
0199         std::unique_ptr<std::shared_ptr<C>[]> caches_;
0200       };
0201 
0202       template <typename T, typename C>
0203       class EndRunSummaryProducer;
0204 
0205       template <typename T, typename C>
0206       class RunSummaryCacheHolder : public virtual T {
0207       public:
0208         RunSummaryCacheHolder() = default;
0209         RunSummaryCacheHolder(RunSummaryCacheHolder<T, C> const&) = delete;
0210         RunSummaryCacheHolder<T, C>& operator=(RunSummaryCacheHolder<T, C> const&) = delete;
0211         ~RunSummaryCacheHolder() noexcept(false) override{};
0212 
0213       private:
0214         friend class EndRunSummaryProducer<T, C>;
0215         void doBeginRunSummary_(edm::Run const& rp, EventSetup const& c) final {
0216           cache_ = globalBeginRunSummary(rp, c);
0217         }
0218         void doStreamEndRunSummary_(StreamID id, Run const& rp, EventSetup const& c) final {
0219           //NOTE: in future this will need to be serialized
0220           std::lock_guard<std::mutex> guard(mutex_);
0221           streamEndRunSummary(id, rp, c, cache_.get());
0222         }
0223         void doEndRunSummary_(Run const& rp, EventSetup const& c) final { globalEndRunSummary(rp, c, cache_.get()); }
0224 
0225         virtual std::shared_ptr<C> globalBeginRunSummary(edm::Run const&, edm::EventSetup const&) const = 0;
0226         virtual void streamEndRunSummary(StreamID, edm::Run const&, edm::EventSetup const&, C*) const = 0;
0227 
0228         virtual void globalEndRunSummary(edm::Run const&, edm::EventSetup const&, C*) const = 0;
0229 
0230         //When threaded we will have a container for N items where N is # of simultaneous runs
0231         std::shared_ptr<C> cache_;
0232         std::mutex mutex_;
0233       };
0234 
0235       template <typename T, typename C>
0236       class EndLuminosityBlockSummaryProducer;
0237 
0238       template <typename T, typename C>
0239       class LuminosityBlockSummaryCacheHolder : public virtual T {
0240       public:
0241         LuminosityBlockSummaryCacheHolder() = default;
0242         LuminosityBlockSummaryCacheHolder(LuminosityBlockSummaryCacheHolder<T, C> const&) = delete;
0243         LuminosityBlockSummaryCacheHolder<T, C>& operator=(LuminosityBlockSummaryCacheHolder<T, C> const&) = delete;
0244         ~LuminosityBlockSummaryCacheHolder() noexcept(false) override{};
0245 
0246       private:
0247         void preallocLumisSummary(unsigned int iNLumis) final { caches_.reset(new std::shared_ptr<C>[iNLumis]); }
0248 
0249         friend class EndLuminosityBlockSummaryProducer<T, C>;
0250 
0251         void doBeginLuminosityBlockSummary_(edm::LuminosityBlock const& lb, EventSetup const& c) final {
0252           caches_[lb.index()] = globalBeginLuminosityBlockSummary(lb, c);
0253         }
0254 
0255         void doStreamEndLuminosityBlockSummary_(StreamID id, LuminosityBlock const& lb, EventSetup const& c) final {
0256           std::lock_guard<std::mutex> guard(mutex_);
0257           streamEndLuminosityBlockSummary(id, lb, c, caches_[lb.index()].get());
0258         }
0259         void doEndLuminosityBlockSummary_(LuminosityBlock const& lb, EventSetup const& c) final {
0260           globalEndLuminosityBlockSummary(lb, c, caches_[lb.index()].get());
0261           maybeClearCache(lb);
0262         }
0263 
0264         virtual std::shared_ptr<C> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const&,
0265                                                                      edm::EventSetup const&) const = 0;
0266         virtual void streamEndLuminosityBlockSummary(StreamID,
0267                                                      edm::LuminosityBlock const&,
0268                                                      edm::EventSetup const&,
0269                                                      C*) const = 0;
0270 
0271         virtual void globalEndLuminosityBlockSummary(edm::LuminosityBlock const&, edm::EventSetup const&, C*) const = 0;
0272 
0273         virtual void maybeClearCache(LuminosityBlock const& lb) { caches_[lb.index()].reset(); }
0274 
0275         //When threaded we will have a container for N items where N is # of simultaneous Lumis
0276         std::unique_ptr<std::shared_ptr<C>[]> caches_;
0277         std::mutex mutex_;
0278       };
0279 
0280       template <typename T>
0281       class WatchProcessBlock : public virtual T {
0282       public:
0283         WatchProcessBlock() = default;
0284         WatchProcessBlock(WatchProcessBlock const&) = delete;
0285         WatchProcessBlock& operator=(WatchProcessBlock const&) = delete;
0286         ~WatchProcessBlock() noexcept(false) override {}
0287 
0288       private:
0289         void doBeginProcessBlock_(ProcessBlock const&) final;
0290         void doEndProcessBlock_(ProcessBlock const&) final;
0291 
0292         virtual void beginProcessBlock(ProcessBlock const&) {}
0293         virtual void endProcessBlock(ProcessBlock const&) {}
0294       };
0295 
0296       template <typename T>
0297       class BeginProcessBlockProducer : public virtual T {
0298       public:
0299         BeginProcessBlockProducer() = default;
0300         BeginProcessBlockProducer(BeginProcessBlockProducer const&) = delete;
0301         BeginProcessBlockProducer& operator=(BeginProcessBlockProducer const&) = delete;
0302         ~BeginProcessBlockProducer() noexcept(false) override{};
0303 
0304       private:
0305         void doBeginProcessBlockProduce_(ProcessBlock&) final;
0306 
0307         virtual void beginProcessBlockProduce(edm::ProcessBlock&) = 0;
0308       };
0309 
0310       template <typename T>
0311       class EndProcessBlockProducer : public virtual T {
0312       public:
0313         EndProcessBlockProducer() = default;
0314         EndProcessBlockProducer(EndProcessBlockProducer const&) = delete;
0315         EndProcessBlockProducer& operator=(EndProcessBlockProducer const&) = delete;
0316         ~EndProcessBlockProducer() noexcept(false) override{};
0317 
0318       private:
0319         void doEndProcessBlockProduce_(ProcessBlock&) final;
0320 
0321         virtual void endProcessBlockProduce(edm::ProcessBlock&) = 0;
0322       };
0323 
0324       template <typename T>
0325       class BeginRunProducer : public virtual T {
0326       public:
0327         BeginRunProducer() = default;
0328         BeginRunProducer(BeginRunProducer const&) = delete;
0329         BeginRunProducer& operator=(BeginRunProducer const&) = delete;
0330         ~BeginRunProducer() noexcept(false) override{};
0331 
0332       private:
0333         void doBeginRunProduce_(Run& rp, EventSetup const& c) final;
0334 
0335         virtual void globalBeginRunProduce(edm::Run&, edm::EventSetup const&) const = 0;
0336       };
0337 
0338       template <typename T>
0339       class EndRunProducer : public virtual T {
0340       public:
0341         EndRunProducer() = default;
0342         EndRunProducer(EndRunProducer const&) = delete;
0343         EndRunProducer& operator=(EndRunProducer const&) = delete;
0344         ~EndRunProducer() noexcept(false) override{};
0345 
0346       private:
0347         void doEndRunProduce_(Run& rp, EventSetup const& c) final;
0348 
0349         virtual void globalEndRunProduce(edm::Run&, edm::EventSetup const&) const = 0;
0350       };
0351 
0352       template <typename T, typename C>
0353       class EndRunSummaryProducer : public RunSummaryCacheHolder<T, C> {
0354       public:
0355         EndRunSummaryProducer() = default;
0356         EndRunSummaryProducer(EndRunSummaryProducer const&) = delete;
0357         EndRunSummaryProducer& operator=(EndRunSummaryProducer const&) = delete;
0358         ~EndRunSummaryProducer() noexcept(false) override{};
0359 
0360       private:
0361         void doEndRunProduce_(Run& rp, EventSetup const& c) final {
0362           globalEndRunProduce(rp, c, RunSummaryCacheHolder<T, C>::cache_.get());
0363         }
0364 
0365         virtual void globalEndRunProduce(edm::Run&, edm::EventSetup const&, C const*) const = 0;
0366       };
0367 
0368       template <typename T>
0369       class BeginLuminosityBlockProducer : public virtual T {
0370       public:
0371         BeginLuminosityBlockProducer() = default;
0372         BeginLuminosityBlockProducer(BeginLuminosityBlockProducer const&) = delete;
0373         BeginLuminosityBlockProducer& operator=(BeginLuminosityBlockProducer const&) = delete;
0374         ~BeginLuminosityBlockProducer() noexcept(false) override{};
0375 
0376       private:
0377         void doBeginLuminosityBlockProduce_(LuminosityBlock& lb, EventSetup const& c) final;
0378         virtual void globalBeginLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const = 0;
0379       };
0380 
0381       template <typename T>
0382       class EndLuminosityBlockProducer : public virtual T {
0383       public:
0384         EndLuminosityBlockProducer() = default;
0385         EndLuminosityBlockProducer(EndLuminosityBlockProducer const&) = delete;
0386         EndLuminosityBlockProducer& operator=(EndLuminosityBlockProducer const&) = delete;
0387         ~EndLuminosityBlockProducer() noexcept(false) override{};
0388 
0389       private:
0390         void doEndLuminosityBlockProduce_(LuminosityBlock& lb, EventSetup const& c) final;
0391         virtual void globalEndLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const = 0;
0392       };
0393 
0394       template <typename T, typename S>
0395       class EndLuminosityBlockSummaryProducer : public LuminosityBlockSummaryCacheHolder<T, S> {
0396       public:
0397         EndLuminosityBlockSummaryProducer() = default;
0398         EndLuminosityBlockSummaryProducer(EndLuminosityBlockSummaryProducer const&) = delete;
0399         EndLuminosityBlockSummaryProducer& operator=(EndLuminosityBlockSummaryProducer const&) = delete;
0400         ~EndLuminosityBlockSummaryProducer() noexcept(false) override{};
0401 
0402       private:
0403         void doEndLuminosityBlockProduce_(LuminosityBlock& lb, EventSetup const& c) final {
0404           globalEndLuminosityBlockProduce(lb, c, LuminosityBlockSummaryCacheHolder<T, S>::caches_[lb.index()].get());
0405           LuminosityBlockSummaryCacheHolder<T, S>::caches_[lb.index()].reset();
0406         }
0407 
0408         virtual void globalEndLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&, S const*) const = 0;
0409 
0410         // Do nothing because the cache is cleared in doEndLuminosityBlockProduce_
0411         void maybeClearCache(LuminosityBlock const&) final {}
0412       };
0413 
0414       template <typename T>
0415       class ExternalWork : public virtual T {
0416       public:
0417         ExternalWork() = default;
0418         ExternalWork(ExternalWork const&) = delete;
0419         ExternalWork& operator=(ExternalWork const&) = delete;
0420         ~ExternalWork() noexcept(false) override{};
0421 
0422       private:
0423         bool hasAcquire() const override { return true; }
0424 
0425         void doAcquire_(StreamID, Event const&, edm::EventSetup const&, WaitingTaskWithArenaHolder&) final;
0426 
0427         virtual void acquire(StreamID, Event const&, edm::EventSetup const&, WaitingTaskWithArenaHolder) const = 0;
0428       };
0429 
0430       template <typename T>
0431       class Accumulator : public virtual T {
0432       public:
0433         Accumulator() = default;
0434         Accumulator(Accumulator const&) = delete;
0435         Accumulator& operator=(Accumulator const&) = delete;
0436         ~Accumulator() noexcept(false) override{};
0437 
0438       private:
0439         bool hasAccumulator() const override { return true; }
0440 
0441         void produce(StreamID streamID, Event& ev, EventSetup const& es) const final { accumulate(streamID, ev, es); }
0442 
0443         virtual void accumulate(StreamID streamID, Event const& ev, EventSetup const& es) const = 0;
0444       };
0445 
0446       template <typename T>
0447       class Transformer : public virtual T, private TransformerBase {
0448       public:
0449         Transformer() = default;
0450         Transformer(Transformer const&) = delete;
0451         Transformer& operator=(Transformer const&) = delete;
0452         ~Transformer() noexcept(false) override{};
0453 
0454         template <typename G, typename F>
0455         void registerTransform(ProductRegistryHelper::BranchAliasSetterT<G> iSetter,
0456                                F&& iF,
0457                                std::string productInstance = std::string()) {
0458           registerTransform(edm::EDPutTokenT<G>(iSetter), std::forward<F>(iF), std::move(productInstance));
0459         }
0460 
0461         template <typename G, typename F>
0462         void registerTransform(edm::EDPutTokenT<G> iToken, F iF, std::string productInstance = std::string()) {
0463           using ReturnTypeT = decltype(iF(std::declval<G>()));
0464           TypeID returnType(typeid(ReturnTypeT));
0465           TransformerBase::registerTransformImp(*this,
0466                                                 EDPutToken(iToken),
0467                                                 returnType,
0468                                                 std::move(productInstance),
0469                                                 [f = std::move(iF)](edm::WrapperBase const& iGotProduct) {
0470                                                   return std::make_unique<edm::Wrapper<ReturnTypeT>>(
0471                                                       WrapperBase::Emplace{},
0472                                                       f(*static_cast<edm::Wrapper<G> const&>(iGotProduct).product()));
0473                                                 });
0474         }
0475 
0476       private:
0477         size_t transformIndex_(edm::BranchDescription const& iBranch) const final {
0478           return TransformerBase::findMatchingIndex(*this, iBranch);
0479         }
0480         ProductResolverIndex transformPrefetch_(std::size_t iIndex) const final {
0481           return TransformerBase::prefetchImp(iIndex);
0482         }
0483         void transform_(std::size_t iIndex, edm::EventForTransformer& iEvent) const final {
0484           return TransformerBase::transformImp(iIndex, *this, iEvent);
0485         }
0486         void extendUpdateLookup(BranchType iBranchType, ProductResolverIndexHelper const& iHelper) override {
0487           if (iBranchType == InEvent) {
0488             TransformerBase::extendUpdateLookup(*this, this->moduleDescription(), iHelper);
0489           }
0490         }
0491       };
0492     }  // namespace impl
0493   }    // namespace global
0494 }  // namespace edm
0495 
0496 #endif