11#ifndef ROOT_RDF_RVARIATION
12#define ROOT_RDF_RVARIATION
49 return results.size() == expected;
51 return std::all_of(results.begin(), results.end(), [&expected](
const RVec<T> &
v) { return v.size() == expected; });
57 assert(nColumns == 1);
60 return results.
size() == expected;
66 assert(!results.empty());
67 return results[0].size();
73 return results.
size();
76template <
typename RVec_t,
typename Value_t =
typename RVec_t::value_type>
77std::enable_if_t<!IsRVec<Value_t>::value,
const std::type_info &>
GetInnerValueType(std::size_t)
79 return typeid(Value_t);
82template <
typename RVec_t,
typename Value_t =
typename RVec_t::value_type>
83std::enable_if_t<IsRVec<Value_t>::value,
const std::type_info &>
GetInnerValueType(std::size_t nCols)
86 return typeid(Value_t);
88 return typeid(
typename Value_t::value_type);
93std::enable_if_t<!IsRVec<T>::value,
void>
96 results.
resize(nVariations);
101std::enable_if_t<IsRVec<T>::value,
void>
105 results.
resize(nVariations);
108 for (
auto &rvecOverVariations : results) {
109 rvecOverVariations.resize(nVariations);
118std::enable_if_t<!IsRVec<T>::value,
void>
121 const auto nVariations = resStorage.
size();
123 for (
auto i = 0u; i < nVariations; ++i)
124 resStorage[i] = std::move(tmpResults[i]);
129std::enable_if_t<IsRVec<T>::value,
void>
133 const auto nVariations = nCols == 1 ? resStorage.
size() : resStorage[0].
size();
136 for (
auto varIdx = 0u; varIdx < nVariations; ++varIdx)
137 resStorage[varIdx] = std::move(tmpResults[varIdx]);
139 for (
auto colIdx = 0u; colIdx < nCols; ++colIdx)
140 for (
auto varIdx = 0u; varIdx < nVariations; ++varIdx)
141 resStorage[colIdx][varIdx] = std::move(tmpResults[colIdx][varIdx]);
148 using TypeInd_t = std::make_index_sequence<ColumnTypes_t::list_size>;
155 std::vector<std::array<std::unique_ptr<RColumnReaderBase>, ColumnTypes_t::list_size>>
fValues;
157 template <
typename... ColTypes, std::size_t... S>
161 auto &&results = fExpression(fValues[slot][S]->
template Get<ColTypes>(entry)...);
163 if (!
ResultsSizeEq(results, fVariationNames.size(), fColNames.size())) {
164 std::string variationName = fVariationNames[0].substr(0, fVariationNames[0].find_first_of(
':'));
165 throw std::runtime_error(
"The evaluation of the expression for variation \"" + variationName +
166 "\" resulted in " + std::to_string(
GetNVariations(results)) +
" values, but " +
167 std::to_string(fVariationNames.size()) +
" were expected.");
170 AssignResults(fLastResults[slot * CacheLineStep<ret_type>()], std::move(results), fColNames.size());
178 template <
typename U =
typename ret_type::value_type>
179 std::enable_if_t<!IsRVec<U>::value,
void *>
182 auto &value = fLastResults[slot * CacheLineStep<ret_type>()][varIdx];
183 return static_cast<void *
>(&value);
187 template <
typename U =
typename ret_type::value_type>
188 std::enable_if_t<IsRVec<U>::value,
void *>
GetValuePtr(
unsigned int slot, std::size_t colIdx, std::size_t varIdx)
190 if (fColNames.size() == 1) {
191 auto &value = fLastResults[slot * CacheLineStep<ret_type>()][varIdx];
192 return static_cast<void *
>(&value);
195 auto &value = fLastResults[slot * CacheLineStep<ret_type>()][colIdx][varIdx];
196 return static_cast<void *
>(&value);
200 RVariation(
const std::vector<std::string> &colNames, std::string_view variationName,
F expression,
201 const std::vector<std::string> &variationTags, std::string_view
type,
const RColumnRegister &defines,
203 :
RVariationBase(colNames, variationName, variationTags,
type, defines, lm, inputColNames),
207 fLoopManager->Book(
this);
209 for (
auto i = 0u; i < lm.
GetNSlots(); ++i)
210 ResizeResults(fLastResults[i * RDFInternal::CacheLineStep<ret_type>()], colNames.size(), variationTags.size());
219 for (
auto &define : fColumnRegister.GetColumns())
220 define.second->InitSlot(
r, slot);
221 RColumnReadersInfo info{fInputColumns, fColumnRegister, fIsDefine.data(), fLoopManager->GetDSValuePtrs(),
222 fLoopManager->GetDataSource()};
224 fLastCheckedEntry[slot * CacheLineStep<Long64_t>()] = -1;
228 void *
GetValuePtr(
unsigned int slot,
const std::string &column,
const std::string &variation)
final
230 const auto colIt = std::find(fColNames.begin(), fColNames.end(), column);
231 assert(colIt != fColNames.end());
232 const auto colIdx = std::distance(fColNames.begin(), colIt);
234 const auto varIt = std::find(fVariationNames.begin(), fVariationNames.end(), variation);
235 assert(varIt != fVariationNames.end());
236 const auto varIdx = std::distance(fVariationNames.begin(), varIt);
238 return GetValuePtr(slot, colIdx, varIdx);
244 if (entry != fLastCheckedEntry[slot * CacheLineStep<Long64_t>()]) {
247 fLastCheckedEntry[slot * CacheLineStep<Long64_t>()] = entry;
251 const std::type_info &
GetTypeId()
const {
return GetInnerValueType<ret_type>(fColNames.size()); }
256 for (
auto &
v : fValues[slot])
typedef void(GLAPIENTRYP _GLUfuncptr)(void)
The head node of a RDF computation graph.
unsigned int GetNSlots() const
A binder for user-defined columns and aliases.
This type includes all parts of RVariation that do not depend on the callable signature.
std::make_index_sequence< ColumnTypes_t::list_size > TypeInd_t
void InitSlot(TTreeReader *r, unsigned int slot) final
typename CallableTraits< F >::ret_type ret_type
void FinalizeSlot(unsigned int slot) final
Clean-up operations to be performed at the end of a task.
std::enable_if_t< IsRVec< U >::value, void * > GetValuePtr(unsigned int slot, std::size_t colIdx, std::size_t varIdx)
RVariation(const std::vector< std::string > &colNames, std::string_view variationName, F expression, const std::vector< std::string > &variationTags, std::string_view type, const RColumnRegister &defines, RLoopManager &lm, const ColumnNames_t &inputColNames)
void * GetValuePtr(unsigned int slot, const std::string &column, const std::string &variation) final
Return the (type-erased) address of the value for the given processing slot.
std::enable_if_t<!IsRVec< U >::value, void * > GetValuePtr(unsigned int slot, std::size_t, std::size_t varIdx)
typename CallableTraits< F >::arg_types ColumnTypes_t
void UpdateHelper(unsigned int slot, Long64_t entry, TypeList< ColTypes... >, std::index_sequence< S... >)
std::vector< ret_type > fLastResults
void Update(unsigned int slot, Long64_t entry) final
Update the value at the address returned by GetValuePtr with the content corresponding to the given e...
RVariation(const RVariation &)=delete
RVariation & operator=(const RVariation &)=delete
const std::type_info & GetTypeId() const
std::vector< std::array< std::unique_ptr< RColumnReaderBase >, ColumnTypes_t::list_size > > fValues
Column readers per slot and per input column.
A "std::vector"-like collection of values implementing handy operation to analyse them.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
std::enable_if_t<!IsRVec< Value_t >::value, const std::type_info & > GetInnerValueType(std::size_t)
std::enable_if_t<!IsRVec< T >::value, void > ResizeResults(ROOT::RVec< T > &results, std::size_t, std::size_t nVariations)
std::enable_if_t<!IsRVec< T >::value, void > AssignResults(ROOT::RVec< T > &resStorage, ROOT::RVec< T > &&tmpResults, std::size_t)
std::size_t GetNVariations(const RVec< RVec< T > > &results)
constexpr std::size_t CacheLineStep()
Stepping through CacheLineStep<T> values in a vector<T> brings you to a new cache line.
std::array< std::unique_ptr< RDFDetail::RColumnReaderBase >, sizeof...(ColTypes)> MakeColumnReaders(unsigned int slot, TTreeReader *r, TypeList< ColTypes... >, const RColumnReadersInfo &colInfo, const std::string &variationName="nominal")
Create a group of column readers, one per type in the parameter pack.
bool ResultsSizeEq(const RVec< RVec< T > > &results, std::size_t expected, std::size_t nColumns)
std::vector< std::string > ColumnNames_t
ROOT type_traits extensions.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Extract types from the signature of a callable object. See CallableTraits.
This type aggregates some of the arguments passed to MakeColumnReaders.
Lightweight storage for a collection of types.