1 #ifndef FWCore_Framework_InputProcessBlockCacheImpl_h 2 #define FWCore_Framework_InputProcessBlockCacheImpl_h 26 #include <type_traits> 41 template <
typename M,
typename V1,
typename... Vs>
44 : countTypeInParameterPack<M, Vs...>();
54 if constexpr (
sizeof...(
Types) > 0) {
57 static_assert(
sizeof...(
Types) > 0,
58 "CacheType used with registerProcessBlockCacheFiller does not match any template parameters of " 59 "InputProcessBlockCache");
70 template <
typename CacheType>
73 std::function<std::shared_ptr<CacheType>(
ProcessBlock const&, std::shared_ptr<CacheType>
const&)>
func_;
76 template <
typename... CacheTypes>
83 template <std::
size_t I>
85 Event const&)
const {}
87 template <std::
size_t I>
88 typename std::enable_if <
99 std::get<I>(cacheHandles) =
CacheHandle(std::get<I>(caches_.at(
index).cacheTuple_).
get());
101 fillTuple<I + 1>(cacheHandles,
event);
104 std::tuple<CacheHandle<CacheTypes>...> processBlockCaches(
Event const&
event)
const {
105 std::tuple<CacheHandle<CacheTypes>...> cacheHandles;
108 if (!processNames_.empty()) {
109 fillTuple<0>(cacheHandles,
event);
114 void selectInputProcessBlocks(ProductRegistry
const& productRegistry,
115 ProcessBlockHelperBase
const& processBlockHelperBase,
116 EDConsumerBase
const& edConsumerBase) {
118 for (
auto const& tokenInfo : tokenInfos_) {
119 if (!tokenInfo.token_.isUninitialized()) {
121 edConsumerBase.labelsForToken(tokenInfo.token_,
productLabels);
123 processNames_[
i] = processBlockHelperBase.selectProcess(productRegistry,
productLabels, tokenInfo.typeID_);
130 template <std::
size_t N>
131 using CacheTypeT =
typename std::tuple_element<
N,
std::tuple<CacheTypes...>>
::type;
133 template <std::
size_t ICacheType,
typename DataType,
typename Func>
134 void registerProcessBlockCacheFiller(EDGetTokenT<DataType>
const&
token, Func&&
func) {
135 registerProcessBlockCacheFiller<ICacheType, CacheTypeT<ICacheType>,
DataType, Func>(
token,
136 std::forward<Func>(
func));
139 template <
typename CacheType,
typename DataType,
typename Func>
140 void registerProcessBlockCacheFiller(EDGetTokenT<DataType>
const&
token, Func&&
func) {
141 static_assert(countTypeInParameterPack<CacheType, CacheTypes...>() == 1u,
142 "If registerProcessBlockCacheFiller is called with a type template parameter\n" 143 "then that type must appear exactly once in the template parameters of InputProcessBlockCache");
148 registerProcessBlockCacheFiller<I, CacheType, DataType, Func>(
token, std::forward<Func>(
func));
155 void moveProcessBlockCacheFiller(std::vector<edm::impl::TokenInfo>& tokenInfos,
159 if (!tokenInfos_.empty()) {
160 processNames_.resize(
sizeof...(CacheTypes));
169 std::tuple<std::shared_ptr<CacheTypes>...> cacheTuple_;
172 template <std::
size_t I>
173 typename std::enable_if<
I ==
sizeof...(CacheTypes),
void>::
type fillCache(ProcessBlock
const&,
177 template <std::
size_t I>
178 typename std::enable_if <
I<
sizeof...(CacheTypes),
void>::
type fillCache(ProcessBlock
const& pb,
179 CacheTuple
const& previousCacheTuple,
180 CacheTuple& cacheTuple) {
181 if (pb.processName() == processNames_[
I]) {
182 auto const& previousSharedPtr = std::get<I>(previousCacheTuple.cacheTuple_);
183 std::get<I>(cacheTuple.cacheTuple_) = std::get<I>(functors_).func_(pb, previousSharedPtr);
185 fillCache<I + 1>(pb, previousCacheTuple, cacheTuple);
188 void accessInputProcessBlock(ProcessBlock
const& pb) {
189 if (
sizeof...(CacheTypes) > 0 && !processNames_.empty()) {
190 CacheTuple cacheTuple;
191 if (caches_.empty()) {
192 CacheTuple firstCacheTuple;
193 fillCache<0>(pb, firstCacheTuple, cacheTuple);
195 CacheTuple
const& previousCacheTuple = caches_.back();
196 fillCache<0>(pb, previousCacheTuple, cacheTuple);
198 caches_.push_back(
std::move(cacheTuple));
202 void clearCaches() { caches_.clear(); }
203 auto cacheSize()
const {
return caches_.size(); }
206 template <std::
size_t ICacheType,
typename CacheType,
typename DataType,
typename Func>
207 void registerProcessBlockCacheFiller(EDGetTokenT<DataType>
const&
token, Func&&
func) {
208 static_assert(ICacheType <
sizeof...(CacheTypes),
"ICacheType out of range");
209 processNames_.resize(
sizeof...(CacheTypes));
210 tokenInfos_.resize(
sizeof...(CacheTypes));
211 if (!tokenInfos_[ICacheType].token_.isUninitialized()) {
213 <<
"registerProcessBlockCacheFiller should only be called once per cache type";
218 std::get<ICacheType>(functors_).func_ = std::forward<Func>(
func);
224 std::vector<CacheTuple> caches_;
227 std::tuple<CacheFiller<CacheTypes>...> functors_;
228 std::vector<std::string> processNames_;
229 std::vector<TokenInfo> tokenInfos_;
std::function< std::shared_ptr< CacheType >ProcessBlock const &, std::shared_ptr< CacheType > const &)> func_
constexpr std::size_t indexInputProcessBlockCache()
static constexpr unsigned int invalidCacheIndex()
const std::complex< double > I
unsigned int eventProcessBlockIndex(Event const &event, std::string const &processName)
constexpr std::size_t countTypeInParameterPack()