Dear Root-experts,
I am trying to understand how to use the ROOT::TThreadedObject<> wrapper, so I was looking at the tutorial mt304_fillHistos.C. The macro in tutorial works if I run it with the interpreter but I could not get it compiled.
What additional headers do I need to include?
/// \file
/// \ingroup tutorial_multicore
/// \notebook -draw
/// Fill histograms in parallel with automatic binning.
/// Illustrates use of power-of-two autobin algorithm
///
/// \macro_code
/// \macro_image
///
/// \date November 2017
/// \author Gerardo Ganis
#include <TROOT.h>
#include <TSystem.h>
#include <TH1.h>
#include <TCanvas.h>
#include <TRandom3.h>
#include <TStyle.h>
// The number of workers
const UInt_t nWorkers = 8U;
// Reference boundaries
const Double_t xmiref = -1.;
const Double_t xmaref = 7.;
Int_t mt304_fillHistos(UInt_t nNumbers = 1001)
{
// The first, fundamental operation to be performed in order to make ROOT
// thread-aware.
ROOT::EnableThreadSafety();
// Histograms to be filled in parallel
ROOT::TThreadedObject<TH1D> h1d("h1d", "1D test histogram", 64, 0., -1.);
ROOT::TThreadedObject<TH1D> h1dr("h1dr", "1D test histogram w/ ref boundaries", 64, xmiref, xmaref);
// We define our work item
auto workItem = [&](UInt_t workerID) {
// One generator, file and ntuple per worker
TRandom3 workerRndm(workerID); // Change the seed
auto wh1d = h1d.Get();
wh1d->SetBit(TH1::kAutoBinPTwo);
auto wh1dr = h1dr.Get();
Double_t x;
for (UInt_t i = 0; i < nNumbers; ++i) {
x = workerRndm.Gaus(3.);
wh1d->Fill(x);
wh1dr->Fill(x);
}
};
// Create the collection which will hold the threads, our "pool"
std::vector<std::thread> workers;
// Fill the "pool" with workers
for (auto workerID : ROOT::TSeqI(nWorkers)) {
workers.emplace_back(workItem, workerID);
}
// Now join them
for (auto &&worker : workers)
worker.join();
// Merge
auto fh1d = h1d.Merge();
auto fh1dr = h1dr.Merge();
// Make the canvas
auto c = new TCanvas("c", "c", 800, 800);
c->Divide(1, 2);
gStyle->SetOptStat(111110);
c->cd(1);
fh1d->DrawCopy();
c->cd(2);
fh1dr->DrawCopy();
c->Update();
return 0;
}
I get the following errors:
------------------------------------------------------------------
| Welcome to ROOT 6.34.04 https://root.cern |
| (c) 1995-2024, The ROOT Team; conception: R. Brun, F. Rademakers |
| Built for win64 on Feb 10 2025, 12:25:15 |
| From tags/v6-34-04@v6-34-04 |
| With MSVC 19.39.33521.0 |
| Try '.help'/'.?', '.demo', '.license', '.credits', '.quit'/'.q' |
------------------------------------------------------------------
root [0] .L mt304_fillHistos.C+
Info in <TWinNTSystem::ACLiC>: creating shared library D:/Multicore/mt304_fillHistos_C.dll
In file included from input_line_9:9:
.\mt304_fillHistos.C:36:10: error: no member named 'TThreadedObject' in namespace 'ROOT'
ROOT::TThreadedObject<TH1D> h1d("h1d", "1D test histogram", 64, 0., -1.);
~~~~~~^
.\mt304_fillHistos.C:36:26: error: 'TH1D' does not refer to a value
ROOT::TThreadedObject<TH1D> h1d("h1d", "1D test histogram", 64, 0., -1.);
^
D:/ROOT/include\TH1.h:670:7: note: declared here
class TH1D : public TH1, public TArrayD {
^
In file included from input_line_9:9:
.\mt304_fillHistos.C:36:32: error: use of undeclared identifier 'h1d'
ROOT::TThreadedObject<TH1D> h1d("h1d", "1D test histogram", 64, 0., -1.);
^
.\mt304_fillHistos.C:37:10: error: no member named 'TThreadedObject' in namespace 'ROOT'
ROOT::TThreadedObject<TH1D> h1dr("h1dr", "1D test histogram w/ ref boundaries", 64, xmiref, xmaref);
~~~~~~^
.\mt304_fillHistos.C:37:26: error: 'TH1D' does not refer to a value
ROOT::TThreadedObject<TH1D> h1dr("h1dr", "1D test histogram w/ ref boundaries", 64, xmiref, xmaref);
^
D:/ROOT/include\TH1.h:670:7: note: declared here
class TH1D : public TH1, public TArrayD {
^
In file included from input_line_9:9:
.\mt304_fillHistos.C:37:32: error: use of undeclared identifier 'h1dr'
ROOT::TThreadedObject<TH1D> h1dr("h1dr", "1D test histogram w/ ref boundaries", 64, xmiref, xmaref);
^
.\mt304_fillHistos.C:44:19: error: use of undeclared identifier 'h1d'
auto wh1d = h1d.Get();
^
.\mt304_fillHistos.C:46:20: error: use of undeclared identifier 'h1dr'
auto wh1dr = h1dr.Get();
^
.\mt304_fillHistos.C:57:21: error: no member named 'thread' in namespace 'std'
std::vector<std::thread> workers;
~~~~~^
.\mt304_fillHistos.C:60:31: error: no member named 'TSeqI' in namespace 'ROOT'
for (auto workerID : ROOT::TSeqI(nWorkers)) {
~~~~~~^
.\mt304_fillHistos.C:69:16: error: use of undeclared identifier 'h1d'
auto fh1d = h1d.Merge();
^
.\mt304_fillHistos.C:70:17: error: use of undeclared identifier 'h1dr'
auto fh1dr = h1dr.Merge();
^
Error: D:\ROOT\bin\rootcling: compilation failure (D:\Multicore/mt304_fillHistos_C_ACLiC_dict856d544eba_dictUmbrella.h)
Error in <ACLiC>: Executing 'D:\ROOT\bin\rootcling "--lib-list-prefix=D:\Multicore\mt304_fillHistos_C_ACLiC_map" -f "D:\Multicore\mt304_fillHistos_C_ACLiC_dict.cxx" -rml mt304_fillHistos_C -rmf "D:\Multicore\mt304_fillHistos_C.rootmap" -DR__ACLIC_ROOTMAP -I%ROOTSYS%\include -D__ACLIC__ "D:/Multicore/mt304_fillHistos.C" "D:\Multicore\mt304_fillHistos_C_ACLiC_linkdef.h"' failed!
Your help is much appreciated!