{
"cells": [
{
"cell_type": "markdown",
"id": "2f7a7cc2",
"metadata": {},
"source": [
"# df022_useKahan\n",
"Implement a custom action that evaluates a Kahan sum.\n",
"\n",
"This tutorial shows how to implement a Kahan summation custom action.\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Enrico Guiraud, Danilo Piparo (CERN), Massimo Tumolo (Politecnico di Torino) \n",
"This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, March 19, 2024 at 07:07 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "637c3968",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2024-03-19T19:07:13.029227Z",
"iopub.status.busy": "2024-03-19T19:07:13.028866Z",
"iopub.status.idle": "2024-03-19T19:07:13.040221Z",
"shell.execute_reply": "2024-03-19T19:07:13.039026Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"\n",
"template \n",
"class KahanSum final : public ROOT::Detail::RDF::RActionImpl> {\n",
"public:\n",
" /// This type is a requirement for every helper.\n",
" using Result_t = T;\n",
"\n",
"private:\n",
" std::vector fPartialSums;\n",
" std::vector fCompensations;\n",
" int fNSlots;\n",
"\n",
" std::shared_ptr fResultSum;\n",
"\n",
" void KahanAlgorithm(const T &x, T &sum, T &compensation){\n",
" T y = x - compensation;\n",
" T t = sum + y;\n",
" compensation = (t - sum) - y;\n",
" sum = t;\n",
" }\n",
"\n",
"public:\n",
" KahanSum(KahanSum &&) = default;\n",
" KahanSum(const KahanSum &) = delete;\n",
"\n",
" KahanSum(const std::shared_ptr &r) : fResultSum(r)\n",
" {\n",
" static_assert(std::is_floating_point::value, \"Kahan sum makes sense only on floating point numbers\");\n",
"\n",
" fNSlots = ROOT::IsImplicitMTEnabled() ? ROOT::GetThreadPoolSize() : 1;\n",
" fPartialSums.resize(fNSlots, 0.);\n",
" fCompensations.resize(fNSlots, 0.);\n",
" }\n",
"\n",
" std::shared_ptr GetResultPtr() const { return fResultSum; }\n",
"\n",
" void Initialize() {}\n",
" void InitTask(TTreeReader *, unsigned int) {}\n",
"\n",
" void Exec(unsigned int slot, T x)\n",
" {\n",
" KahanAlgorithm(x, fPartialSums[slot], fCompensations[slot]);\n",
" }\n",
"\n",
" template ::value, int> = 0>\n",
" void Exec(unsigned int slot, const T &vs)\n",
" {\n",
" for (auto &&v : vs) {\n",
" Exec(slot, v);\n",
" }\n",
" }\n",
"\n",
" void Finalize()\n",
" {\n",
" T sum(0) ;\n",
" T compensation(0);\n",
" for (int i = 0; i < fNSlots; ++i) {\n",
" KahanAlgorithm(fPartialSums[i], sum, compensation);\n",
" }\n",
" *fResultSum = sum;\n",
" }\n",
"\n",
" std::string GetActionName() { return \"KahanSum\"; }\n",
"};"
]
},
{
"cell_type": "markdown",
"id": "7e203037",
"metadata": {},
"source": [
"We enable implicit parallelism"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "868de165",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2024-03-19T19:07:13.045433Z",
"iopub.status.busy": "2024-03-19T19:07:13.045013Z",
"iopub.status.idle": "2024-03-19T19:07:21.827718Z",
"shell.execute_reply": "2024-03-19T19:07:21.826265Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Kahan: 1000000000.00000011920929 Classical: 1000000000.00000011920929\n"
]
}
],
"source": [
"ROOT::EnableImplicitMT(2);\n",
"\n",
"ROOT::RDataFrame d(20);\n",
"auto dd = d.Define(\"x\", \"(rdfentry_ %2 == 0) ? 0.00000001 : 100000000.\");\n",
"\n",
"auto ptr = std::make_shared();\n",
"KahanSum helper(ptr);\n",
"\n",
"auto kahanResult = dd.Book(std::move(helper), {\"x\"});\n",
"auto plainResult = dd.Sum({\"x\"});\n",
"\n",
"std::cout << std::setprecision(24) << \"Kahan: \" << *kahanResult << \" Classical: \" << *plainResult << std::endl;"
]
},
{
"cell_type": "markdown",
"id": "e24375f1",
"metadata": {},
"source": [
"Outputs: Kahan: 1000000000.00000011920929 Classical: 1000000000"
]
},
{
"cell_type": "markdown",
"id": "f0ddf2a5",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "f3a7a58b",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2024-03-19T19:07:21.850793Z",
"iopub.status.busy": "2024-03-19T19:07:21.850411Z",
"iopub.status.idle": "2024-03-19T19:07:22.057061Z",
"shell.execute_reply": "2024-03-19T19:07:22.055964Z"
}
},
"outputs": [],
"source": [
"gROOT->GetListOfCanvases()->Draw()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ROOT C++",
"language": "c++",
"name": "root"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".C",
"mimetype": " text/x-c++src",
"name": "c++"
}
},
"nbformat": 4,
"nbformat_minor": 5
}