This tutorial shows how to implement a Kahan summation custom action.
template <typename T>
class KahanSum final : public ROOT::Detail::RDF::RActionImpl<class KahanSum<T>> {
public:
using Result_t = T;
private:
std::vector<T> fPartialSums;
std::vector<T> fCompensations;
int fNSlots;
std::shared_ptr<T> fResultSum;
void KahanAlgorithm(
const T &
x, T &
sum, T &compensation){
compensation = (t -
sum) -
y;
}
public:
KahanSum(KahanSum &&) = default;
KahanSum(const KahanSum &) = delete;
KahanSum(
const std::shared_ptr<T> &
r) : fResultSum(
r)
{
static_assert(std::is_floating_point<T>::value, "Kahan sum makes sense only on floating point numbers");
fPartialSums.resize(fNSlots, 0.);
fCompensations.resize(fNSlots, 0.);
}
std::shared_ptr<Result_t> GetResultPtr() const { return fResultSum; }
void Exec(
unsigned int slot, T
x)
{
KahanAlgorithm(
x, fPartialSums[slot], fCompensations[slot]);
}
template <typename V=T, typename std::enable_if<ROOT::Internal::RDF::IsDataContainer<V>::value,
int>
::type = 0>
void Exec(
unsigned int slot,
const T &vs)
{
}
}
void Finalize()
{
for (int i = 0; i < fNSlots; ++i) {
KahanAlgorithm(fPartialSums[i],
sum, compensation);
}
}
std::string GetActionName(){
return "THnHelper";
}
};
void df022_useKahan()
{
auto dd =
d.Define(
"x",
"(rdfentry_ %2 == 0) ? 0.00000001 : 100000000.");
auto ptr = std::make_shared<double>();
KahanSum<double> helper(ptr);
auto kahanResult = dd.Book<double>(std::move(helper), {"x"});
auto plainResult = dd.Sum<double>({"x"});
std::cout << std::setprecision(24) << "Kahan: " << *kahanResult << " Classical: " << *plainResult << std::endl;
}
ROOT's RDataFrame offers a high level interface for analyses of data stored in TTrees,...
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
CPYCPPYY_EXTERN bool Exec(const std::string &cmd)
void EnableImplicitMT(UInt_t numthreads=0)
Enable ROOT's implicit multi-threading for all objects and methods that provide an internal paralleli...
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
UInt_t GetThreadPoolSize()
Returns the size of ROOT's thread pool.
void Initialize(Bool_t useTMVAStyle=kTRUE)
static uint64_t sum(uint64_t i)