{ "cells": [ { "cell_type": "markdown", "id": "13dbbb9c", "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, May 19, 2026 at 08:09 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "3b20bb6c", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:09:56.951210Z", "iopub.status.busy": "2026-05-19T20:09:56.951077Z", "iopub.status.idle": "2026-05-19T20:09:56.957371Z", "shell.execute_reply": "2026-05-19T20:09:56.954631Z" } }, "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": "cb5d128f", "metadata": {}, "source": [ "We enable implicit parallelism" ] }, { "cell_type": "code", "execution_count": 2, "id": "8ddc2b5a", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:09:56.958688Z", "iopub.status.busy": "2026-05-19T20:09:56.958552Z", "iopub.status.idle": "2026-05-19T20:09:58.750054Z", "shell.execute_reply": "2026-05-19T20:09:58.749104Z" } }, "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": "c793fc66", "metadata": {}, "source": [ "Outputs: Kahan: 1000000000.00000011920929 Classical: 1000000000" ] }, { "cell_type": "markdown", "id": "e635d350", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 3, "id": "dd6f9aed", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:09:58.751475Z", "iopub.status.busy": "2026-05-19T20:09:58.751355Z", "iopub.status.idle": "2026-05-19T20:09:58.962090Z", "shell.execute_reply": "2026-05-19T20:09:58.959474Z" } }, "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 }