Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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