Fill n-tuples in distinct workers. This tutorial illustrates the basics of how it's possible with ROOT to offload heavy operations on multiple processes and how it's possible to write simultaneously multiple files. The operation performed in this case is the creation of random gaussian numbers.

Author: Danilo Piparo
This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Sunday, October 02, 2022 at 09:33 AM.

In [1]:
const UInt_t nNumbers = 20000000U;

const UInt_t nWorkers = 4U;

const auto workSize = nNumbers / nWorkers;

Some useful constants and functions Total amount of numbers The number of workers We split the work in equal parts A simple function to fill ntuples randomly

In [2]:
%%cpp -d
void fillRandom(TNtuple &ntuple, TRandom3 &rndm, UInt_t n)
   for (auto i : ROOT::TSeqI(n))

No nuisance for batch execution

In [3]:

Perform the operation sequentially

Create a random generator and and Ntuple to hold the numbers

In [4]:
TRandom3 rndm(1);
TFile ofile("mp101_singleCore.root", "RECREATE");
TNtuple randomNumbers("singleCore", "Random Numbers", "r");
fillRandom(randomNumbers, rndm, nNumbers);

We now go MP!

We define our work item

In [5]:
auto workItem = [](UInt_t workerID) {
   // One generator, file and ntuple per worker
   TRandom3 workerRndm(workerID); // Change the seed
   TFile ofile(Form("mp101_multiCore_%u.root", workerID), "RECREATE");
   TNtuple workerRandomNumbers("multiCore", "Random Numbers", "r");
   fillRandom(workerRandomNumbers, workerRndm, workSize);
   return 0;

Create the pool of workers

In [6]:
ROOT::TProcessExecutor workers(nWorkers);

Fill the pool with work

In [7]:
workers.Map(workItem, ROOT::TSeqI(nWorkers));

return 0;