Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
mtbb101_fillNtuples.C
Go to the documentation of this file.
1 /// \file
2 /// \ingroup tutorial_multicore
3 /// \notebook
4 /// Fill n-tuples in distinct workers.
5 /// This tutorial illustrates the basics of how it's possible with ROOT to
6 /// offload heavy operations on multiple processes and how it's possible to write
7 /// simultaneously multiple files. The operation performed in this case is the
8 /// creation of random gaussian numbers.
9 ///
10 /// \macro_code
11 ///
12 /// \date January 2016
13 /// \author Danilo Piparo
14 
15 // Some useful constants and functions
16 
17 // Total amount of numbers
18 const UInt_t nNumbers = 20000000U;
19 
20 // The number of workers
21 const UInt_t nThreads = 4U;
22 
23 // We split the work in equal parts
24 const auto workSize = nNumbers / nThreads;
25 
26 // A simple function to fill ntuples randomly
27 void fillRandom(TNtuple &ntuple, TRandom3 &rndm, UInt_t n)
28 {
29  for (auto i : ROOT::TSeqI(n))
30  ntuple.Fill(rndm.Gaus());
31 }
32 
33 Int_t mtbb101_fillNtuples()
34 {
35  ROOT::EnableThreadSafety();
36  // No nuisance for batch execution
37  gROOT->SetBatch();
38 
39  // Perform the operation sequentially ---------------------------------------
40 
41  // Create a random generator and and Ntuple to hold the numbers
42  TRandom3 rndm(1);
43  TFile ofile("mtbb101_singleCore.root", "RECREATE");
44  TNtuple randomNumbers("singleCore", "Random Numbers", "r");
45  fillRandom(randomNumbers, rndm, nNumbers);
46  randomNumbers.Write();
47  ofile.Close();
48 
49  // We now go MP! ------------------------------------------------------------
50 
51  // We define our work item
52  auto workItem = [](UInt_t workerID) {
53  // One generator, file and ntuple per worker
54  TRandom3 workerRndm(workerID); // Change the seed
55  TFile ofile(Form("mtbb101_multiCore_%u.root", workerID), "RECREATE");
56  TNtuple workerRandomNumbers("multiCore", "Random Numbers", "r");
57  fillRandom(workerRandomNumbers, workerRndm, workSize);
58  workerRandomNumbers.Write();
59  return 0;
60  };
61 
62  // Create the pool of workers
63  ROOT::TThreadExecutor pool(nThreads);
64 
65  // Fill the pool with work
66  pool.Map(workItem, ROOT::TSeqI(nThreads));
67 
68  return 0;
69 }