27def df042_ThreadSafeRNG():
29 header_path = os.path.join(str(ROOT.gROOT.GetTutorialDir()),
"analysis",
"dataframe",
"df042_ThreadSafeRNG.hxx")
30 if not os.path.exists(header_path):
31 raise RuntimeError(f
'Could not find required header file "{header_path}".')
34 if not ROOT.gInterpreter.Declare(f
'#include "{header_path}"'):
35 raise RuntimeError(
"Failed to declare the functions needed by the RDataFrame computation graph.")
37 myCanvas = ROOT.TCanvas(
"myCanvas",
"myCanvas", 1000, 500)
43 df1 =
ROOT.RDataFrame(nEntries).Define(
"x", ROOT.GetNormallyDistributedNumberFromGlobalGenerator)
44 h1 = df1.Histo1D((
"h1",
"Single thread (no MT)", 1000, -4, 4),
"x")
52 nSlots = max(2, os.cpu_count() // 4)
56 ROOT.ReinitializeGenerators(nSlots)
57 df2 =
ROOT.RDataFrame(nEntries).DefineSlot(
"x", ROOT.GetNormallyDistributedNumberPerSlotGenerator)
58 h2 = df2.Histo1D((
"h2",
"Thread-safe (MT, non-deterministic)", 1000, -4, 4),
"x")
71 ROOT.ReinitializeGenerators(nSlots)
72 df3 =
ROOT.RDataFrame(nEntries).DefineSlotEntry(
"x", ROOT.GetNormallyDistributedNumberPerSlotGeneratorForEntry)
73 h3 = df3.Histo1D((
"h3",
"Thread-safe (MT, deterministic)", 1000, -4, 4),
"x")
77 print(f
"{'{:<40}'.format('Final distributions')}: Mean +- StdDev")
78 print(f
"{'{:<40}'.format('Theoretical')}: 0.000 +- 1.000")
79 print(f
"{'{:<40}'.format('Single thread (no MT)')}: {h1.GetMean():.3f} +- {h1.GetStdDev():.3f}")
80 print(f
"{'{:<40}'.format('Thread-safe (MT, non-deterministic)')}: {h2.GetMean():.3f} +- {h2.GetStdDev():.3f}")
81 print(f
"{'{:<40}'.format('Thread-safe (MT, deterministic)')}: {h3.GetMean():.3f} +- {h3.GetStdDev():.3f}")
85 myCanvas.Draw(block=
True)
88if __name__ ==
"__main__":
ROOT's RDataFrame offers a modern, high-level interface for analysis of data stored in TTree ,...
void EnableImplicitMT(UInt_t numthreads=0)
Enable ROOT's implicit multi-threading for all objects and methods that provide an internal paralleli...