Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:36:22

0001 #ifndef FWCore_Framework_stream_implementors_h
0002 #define FWCore_Framework_stream_implementors_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     FWCore/Framework
0006 // Class  :     implementors
0007 //
0008 /**\file implementors.h "FWCore/Framework/interface/stream/implementors.h"
0009 
0010  Description: Base classes used to implement the interfaces for the edm::stream::* module  abilities
0011 
0012  Usage:
0013     <usage>
0014 
0015 */
0016 //
0017 // Original Author:  Chris Jones
0018 //         Created:  Fri, 02 Aug 2013 11:52:34 GMT
0019 //
0020 
0021 // system include files
0022 #include <cstddef>
0023 #include <functional>
0024 #include <memory>
0025 #include <tuple>
0026 #include <utility>
0027 #include <vector>
0028 
0029 // user include files
0030 #include "FWCore/Framework/interface/CacheHandle.h"
0031 #include "FWCore/Framework/interface/stream/EDProducerBase.h"
0032 #include "FWCore/Framework/interface/Frameworkfwd.h"
0033 #include "FWCore/Framework/interface/InputProcessBlockCacheImpl.h"
0034 #include "FWCore/Framework/interface/TransformerBase.h"
0035 #include "FWCore/Concurrency/interface/WaitingTaskWithArenaHolder.h"
0036 #include "FWCore/Utilities/interface/EDGetToken.h"
0037 #include "FWCore/Utilities/interface/EDMException.h"
0038 #include "FWCore/Utilities/interface/StreamID.h"
0039 #include "FWCore/Utilities/interface/RunIndex.h"
0040 #include "FWCore/Utilities/interface/LuminosityBlockIndex.h"
0041 #include "FWCore/Utilities/interface/TypeID.h"
0042 
0043 // forward declarations
0044 namespace edm {
0045 
0046   class WaitingTaskWithArenaHolder;
0047 
0048   namespace stream {
0049     namespace impl {
0050       class EmptyType {};
0051 
0052       template <typename C>
0053       class GlobalCacheHolder {
0054       public:
0055         GlobalCacheHolder() = default;
0056         GlobalCacheHolder(GlobalCacheHolder<C> const&) = delete;
0057         GlobalCacheHolder<C>& operator=(GlobalCacheHolder<C> const&) = delete;
0058 
0059         void setGlobalCache(C const* iCache) { cache_ = iCache; }
0060 
0061       protected:
0062         C const* globalCache() const { return cache_; }
0063 
0064       private:
0065         C const* cache_;
0066       };
0067 
0068       template <typename... CacheTypes>
0069       class InputProcessBlockCacheHolder {
0070       public:
0071         InputProcessBlockCacheHolder() = default;
0072         InputProcessBlockCacheHolder(InputProcessBlockCacheHolder const&) = delete;
0073         InputProcessBlockCacheHolder& operator=(InputProcessBlockCacheHolder const&) = delete;
0074 
0075         std::tuple<CacheHandle<CacheTypes>...> processBlockCaches(Event const& event) const {
0076           return cacheImpl_->processBlockCaches(event);
0077         }
0078 
0079         template <std::size_t N>
0080         using CacheTypeT = typename std::tuple_element<N, std::tuple<CacheTypes...>>::type;
0081 
0082         template <std::size_t ICacheType, typename DataType, typename Func>
0083         void registerProcessBlockCacheFiller(EDGetTokenT<DataType> const& token, Func&& cacheFiller) {
0084           registerProcessBlockCacheFiller<ICacheType, CacheTypeT<ICacheType>, DataType, Func>(
0085               token, std::forward<Func>(cacheFiller));
0086         }
0087 
0088         template <typename CacheType, typename DataType, typename Func>
0089         void registerProcessBlockCacheFiller(EDGetTokenT<DataType> const& token, Func&& cacheFiller) {
0090           static_assert(edm::impl::countTypeInParameterPack<CacheType, CacheTypes...>() == 1u,
0091                         "If registerProcessBlockCacheFiller is called with a type template parameter\n"
0092                         "then that type must appear exactly once in the template parameters of InputProcessBlockCache");
0093 
0094           // Find the index into the parameter pack from the CacheType
0095           constexpr unsigned int I = edm::impl::indexInputProcessBlockCache<CacheType, CacheTypes...>();
0096 
0097           registerProcessBlockCacheFiller<I, CacheType, DataType, Func>(token, std::forward<Func>(cacheFiller));
0098         }
0099 
0100       private:
0101         template <typename T, bool, bool>
0102         friend struct edm::stream::CallInputProcessBlockImpl;
0103 
0104         void setProcessBlockCache(edm::impl::InputProcessBlockCacheImpl<CacheTypes...> const* cacheImpl) {
0105           cacheImpl_ = cacheImpl;
0106         }
0107 
0108         bool cacheFillersRegistered() const { return registrationInfo_ ? true : false; }
0109         std::vector<edm::impl::TokenInfo>& tokenInfos() { return registrationInfo_->tokenInfos_; }
0110         std::tuple<edm::impl::CacheFiller<CacheTypes>...>& cacheFillers() { return registrationInfo_->cacheFillers_; }
0111 
0112         void clearRegistration() { registrationInfo_.reset(); }
0113 
0114         // The next two functions exist so that it is optional whether modules
0115         // with this ability implement them.
0116 
0117         static void accessInputProcessBlock(edm::ProcessBlock const&) {}
0118 
0119         template <typename GlobalCacheType>
0120         static void accessInputProcessBlock(edm::ProcessBlock const&, GlobalCacheType*) {}
0121 
0122         template <std::size_t ICacheType, typename CacheType, typename DataType, typename Func>
0123         void registerProcessBlockCacheFiller(EDGetTokenT<DataType> const& token, Func&& cacheFiller) {
0124           if (!registrationInfo_) {
0125             registrationInfo_ = std::make_unique<RegistrationInfo>();
0126             tokenInfos().resize(sizeof...(CacheTypes));
0127           }
0128 
0129           if (!tokenInfos()[ICacheType].token_.isUninitialized()) {
0130             throw Exception(errors::LogicError)
0131                 << "registerProcessBlockCacheFiller should only be called once per cache type";
0132           }
0133 
0134           tokenInfos()[ICacheType] = edm::impl::TokenInfo{EDGetToken(token), TypeID(typeid(DataType))};
0135 
0136           std::get<ICacheType>(cacheFillers()).func_ =
0137               std::function<std::shared_ptr<CacheType>(ProcessBlock const&, std::shared_ptr<CacheType> const&)>(
0138                   std::forward<Func>(cacheFiller));
0139         }
0140 
0141         // ------------ Data members --------------------
0142 
0143         edm::impl::InputProcessBlockCacheImpl<CacheTypes...> const* cacheImpl_;
0144 
0145         // The RegistrationInfo is filled while the module constructor runs.
0146         // Later this information is copied to the InputProcessBlockCacheImpl
0147         // object owned by the adaptor and then registrationInfo_ is cleared.
0148         // Note that this is really only needed for one of the stream instances,
0149         // but we fill for all streams so registerProcessBlockCacheFiller can
0150         // be called in the constructor. This keeps the interface as simple as
0151         // possible and makes it similar to the consumes interface.
0152         class RegistrationInfo {
0153         public:
0154           std::vector<edm::impl::TokenInfo> tokenInfos_;
0155           std::tuple<edm::impl::CacheFiller<CacheTypes>...> cacheFillers_;
0156         };
0157         std::unique_ptr<RegistrationInfo> registrationInfo_;
0158       };
0159 
0160       template <typename C>
0161       class RunCacheHolder {
0162       public:
0163         RunCacheHolder() = default;
0164         RunCacheHolder(RunCacheHolder<C> const&) = delete;
0165         RunCacheHolder<C>& operator=(RunCacheHolder<C> const&) = delete;
0166         void setRunCache(C const* iCache) { cache_ = iCache; }
0167 
0168       protected:
0169         C const* runCache() const { return cache_; }
0170 
0171       private:
0172         C const* cache_;
0173       };
0174 
0175       template <typename C>
0176       class LuminosityBlockCacheHolder {
0177       public:
0178         LuminosityBlockCacheHolder() = default;
0179         LuminosityBlockCacheHolder(LuminosityBlockCacheHolder<C> const&) = delete;
0180         LuminosityBlockCacheHolder<C>& operator=(LuminosityBlockCacheHolder<C> const&) = delete;
0181         void setLuminosityBlockCache(C const* iCache) { cache_ = iCache; }
0182 
0183       protected:
0184         C const* luminosityBlockCache() const { return cache_; }
0185 
0186       private:
0187         C const* cache_;
0188       };
0189 
0190       template <typename C>
0191       class RunSummaryCacheHolder {
0192       public:
0193         RunSummaryCacheHolder() = default;
0194         RunSummaryCacheHolder(RunSummaryCacheHolder<C> const&) = delete;
0195         RunSummaryCacheHolder<C>& operator=(RunSummaryCacheHolder<C> const&) = delete;
0196         virtual ~RunSummaryCacheHolder() noexcept(false) {}
0197 
0198       private:
0199         virtual void endRunSummary(edm::Run const&, edm::EventSetup const&, C*) const = 0;
0200       };
0201 
0202       template <typename C>
0203       class LuminosityBlockSummaryCacheHolder {
0204       public:
0205         LuminosityBlockSummaryCacheHolder() = default;
0206         LuminosityBlockSummaryCacheHolder(LuminosityBlockSummaryCacheHolder<C> const&) = delete;
0207         LuminosityBlockSummaryCacheHolder<C>& operator=(LuminosityBlockSummaryCacheHolder<C> const&) = delete;
0208         virtual ~LuminosityBlockSummaryCacheHolder() noexcept(false) {}
0209 
0210       private:
0211         virtual void endLuminosityBlockSummary(edm::LuminosityBlock const&, edm::EventSetup const&, C*) const = 0;
0212       };
0213 
0214       class WatchProcessBlock {
0215       public:
0216         WatchProcessBlock() = default;
0217         WatchProcessBlock(WatchProcessBlock const&) = delete;
0218         WatchProcessBlock& operator=(WatchProcessBlock const&) = delete;
0219 
0220         ///requires the following be defined in the inheriting class
0221         ///static void beginProcessBlockProduce(edm::ProcessBlock const&, GlobalCache*);
0222       };
0223 
0224       class BeginProcessBlockProducer {
0225       public:
0226         BeginProcessBlockProducer() = default;
0227         BeginProcessBlockProducer(BeginProcessBlockProducer const&) = delete;
0228         BeginProcessBlockProducer& operator=(BeginProcessBlockProducer const&) = delete;
0229 
0230         ///requires the following be defined in the inheriting class
0231         ///static void beginProcessBlockProduce(edm::ProcessBlock&, GlobalCache*);
0232       };
0233 
0234       class EndProcessBlockProducer {
0235       public:
0236         EndProcessBlockProducer() = default;
0237         EndProcessBlockProducer(EndProcessBlockProducer const&) = delete;
0238         EndProcessBlockProducer& operator=(EndProcessBlockProducer const&) = delete;
0239 
0240         ///requires the following be defined in the inheriting class
0241         /// static void endProcessBlockProduce(edm::ProcessBlock&, GlobalCache*)
0242       };
0243 
0244       class BeginRunProducer {
0245       public:
0246         BeginRunProducer() = default;
0247         BeginRunProducer(BeginRunProducer const&) = delete;
0248         BeginRunProducer& operator=(BeginRunProducer const&) = delete;
0249 
0250         ///requires the following be defined in the inheriting class
0251         ///static void globalBeginRunProduce(edm::Run&, edm::EventSetup const&, RunContext const* );
0252       };
0253 
0254       class EndRunProducer {
0255       public:
0256         EndRunProducer() = default;
0257         EndRunProducer(EndRunProducer const&) = delete;
0258         EndRunProducer& operator=(EndRunProducer const&) = delete;
0259 
0260         ///requires the following be defined in the inheriting class
0261         /// static void globalEndRunProduce(edm::Run&, edm::EventSetup const&, RunContext const* )
0262       };
0263 
0264       class BeginLuminosityBlockProducer {
0265       public:
0266         BeginLuminosityBlockProducer() = default;
0267         BeginLuminosityBlockProducer(BeginLuminosityBlockProducer const&) = delete;
0268         BeginLuminosityBlockProducer& operator=(BeginLuminosityBlockProducer const&) = delete;
0269 
0270         ///requires the following be defined in the inheriting class
0271         ///static void globalBeginLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&, LuminosityBlockContext const*)
0272       };
0273 
0274       class EndLuminosityBlockProducer {
0275       public:
0276         EndLuminosityBlockProducer() = default;
0277         EndLuminosityBlockProducer(EndLuminosityBlockProducer const&) = delete;
0278         EndLuminosityBlockProducer& operator=(EndLuminosityBlockProducer const&) = delete;
0279 
0280         ///requires the following be defined in the inheriting class
0281         ///static void globalEndLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&, LuminosityBlockContext const*)
0282       };
0283 
0284       class ExternalWork {
0285       public:
0286         ExternalWork() = default;
0287         ExternalWork(ExternalWork const&) = delete;
0288         ExternalWork& operator=(ExternalWork const&) = delete;
0289         virtual ~ExternalWork() noexcept(false) {}
0290 
0291         virtual void acquire(Event const&, edm::EventSetup const&, WaitingTaskWithArenaHolder) = 0;
0292       };
0293 
0294       class WatchLuminosityBlocks {
0295       public:
0296         WatchLuminosityBlocks() = default;
0297         WatchLuminosityBlocks(WatchLuminosityBlocks const&) = delete;
0298         WatchLuminosityBlocks& operator=(WatchLuminosityBlocks const&) = delete;
0299         virtual ~WatchLuminosityBlocks() noexcept(false) {}
0300 
0301         // virtual void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) = 0;
0302         // virtual void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) {}
0303       };
0304 
0305       class WatchRuns {
0306       public:
0307         WatchRuns() = default;
0308         WatchRuns(WatchRuns const&) = delete;
0309         WatchRuns& operator=(WatchRuns const&) = delete;
0310         virtual ~WatchRuns() noexcept(false) {}
0311 
0312         // virtual void beginRun(edm::Run const&, edm::EventSetup const&) = 0;
0313         // virtual void endRun(edm::Run const&, edm::EventSetup const&) {}
0314       };
0315       class Transformer : private TransformerBase, public EDProducerBase {
0316       public:
0317         Transformer() = default;
0318         Transformer(Transformer const&) = delete;
0319         Transformer& operator=(Transformer const&) = delete;
0320         ~Transformer() noexcept(false) override {}
0321 
0322         template <typename G, typename F>
0323         void registerTransform(ProducerBase::BranchAliasSetterT<G> iSetter,
0324                                F&& iF,
0325                                std::string productInstance = std::string()) {
0326           registerTransform(edm::EDPutTokenT<G>(iSetter), std::forward<F>(iF), std::move(productInstance));
0327         }
0328 
0329         template <typename G, typename F>
0330         void registerTransform(edm::EDPutTokenT<G> iToken, F iF, std::string productInstance = std::string()) {
0331           using ReturnTypeT = decltype(iF(std::declval<G>()));
0332           TypeID returnType(typeid(ReturnTypeT));
0333           TransformerBase::registerTransformImp(
0334               *this,
0335               EDPutToken(iToken),
0336               returnType,
0337               std::move(productInstance),
0338               [f = std::move(iF)](std::any const& iGotProduct) {
0339                 auto pGotProduct = std::any_cast<edm::WrapperBase const*>(iGotProduct);
0340                 return std::make_unique<edm::Wrapper<ReturnTypeT>>(
0341                     WrapperBase::Emplace{}, f(*static_cast<edm::Wrapper<G> const*>(pGotProduct)->product()));
0342               });
0343         }
0344 
0345         template <typename G, typename P, typename F>
0346         void registerTransformAsync(edm::EDPutTokenT<G> iToken,
0347                                     P iPre,
0348                                     F iF,
0349                                     std::string productInstance = std::string()) {
0350           using CacheTypeT = decltype(iPre(std::declval<G>(), WaitingTaskWithArenaHolder()));
0351           using ReturnTypeT = decltype(iF(std::declval<CacheTypeT>()));
0352           TypeID returnType(typeid(ReturnTypeT));
0353           TransformerBase::registerTransformAsyncImp(
0354               *this,
0355               EDPutToken(iToken),
0356               returnType,
0357               std::move(productInstance),
0358               [p = std::move(iPre)](edm::WrapperBase const& iGotProduct, WaitingTaskWithArenaHolder iHolder) {
0359                 return std::any(p(*static_cast<edm::Wrapper<G> const&>(iGotProduct).product(), std::move(iHolder)));
0360               },
0361               [f = std::move(iF)](std::any const& iCache) {
0362                 auto cache = std::any_cast<CacheTypeT>(iCache);
0363                 return std::make_unique<edm::Wrapper<ReturnTypeT>>(WrapperBase::Emplace{}, f(cache));
0364               });
0365         }
0366 
0367       private:
0368         size_t transformIndex_(edm::BranchDescription const& iBranch) const noexcept final {
0369           return TransformerBase::findMatchingIndex(*this, iBranch);
0370         }
0371         ProductResolverIndex transformPrefetch_(std::size_t iIndex) const noexcept final {
0372           return TransformerBase::prefetchImp(iIndex);
0373         }
0374         void transformAsync_(WaitingTaskHolder iTask,
0375                              std::size_t iIndex,
0376                              edm::EventForTransformer& iEvent,
0377                              edm::ActivityRegistry* iAct,
0378                              ServiceWeakToken const& iToken) const noexcept final {
0379           return TransformerBase::transformImpAsync(std::move(iTask), iIndex, iAct, *this, iEvent);
0380         }
0381         void extendUpdateLookup(BranchType iBranchType, ProductResolverIndexHelper const& iHelper) override {
0382           if (iBranchType == InEvent) {
0383             TransformerBase::extendUpdateLookup(*this, this->moduleDescription(), iHelper);
0384           }
0385         }
0386       };
0387 
0388       class Accumulator : public EDProducerBase {
0389       public:
0390         Accumulator() = default;
0391         Accumulator(Accumulator const&) = delete;
0392         Accumulator& operator=(Accumulator const&) = delete;
0393         ~Accumulator() noexcept(false) override {}
0394 
0395         virtual void accumulate(Event const& ev, EventSetup const& es) = 0;
0396 
0397         void produce(Event& ev, EventSetup const& es) final { accumulate(ev, es); }
0398       };
0399     }  // namespace impl
0400   }  // namespace stream
0401 }  // namespace edm
0402 
0403 #endif