root/root-tmva-threads.patch
Mattias Ellert daf8bdab01 Make DistRDF optional
Update the root-tmva-threads patch (upstream's version)
Exclude multiproc tests with random failures
2023-03-20 20:25:51 +01:00

223 lines
10 KiB
Diff

diff --git a/tutorials/tmva/TMVA_CNN_Classification.C b/tutorials/tmva/TMVA_CNN_Classification.C
index 838581a925..db5af784d4 100644
--- a/tutorials/tmva/TMVA_CNN_Classification.C
+++ b/tutorials/tmva/TMVA_CNN_Classification.C
@@ -23,7 +23,7 @@
/// we create a signal and background 2D histograms from 2d gaussians
/// with a location (means in X and Y) different for each event
/// The difference between signal and background is in the gaussian width.
-/// The width for the bakground gaussian is slightly larger than the signal width by few % values
+/// The width for the background gaussian is slightly larger than the signal width by few % values
///
///
void MakeImagesTree(int n, int nh, int nw)
@@ -48,7 +48,7 @@ void MakeImagesTree(int n, int nh, int nw)
auto f1 = new TF2("f1", "xygaus");
auto f2 = new TF2("f2", "xygaus");
TTree sgn("sig_tree", "signal_tree");
- TTree bkg("bkg_tree", "bakground_tree");
+ TTree bkg("bkg_tree", "background_tree");
TFile f(fileOutName, "RECREATE");
@@ -107,7 +107,16 @@ void MakeImagesTree(int n, int nh, int nw)
f.Close();
}
-void TMVA_CNN_Classification(std::vector<bool> opt = {1, 1, 1, 1, 1})
+/// @brief Run the TMVA CNN Classification example
+/// @param nevts : number of signal/background events. Use by default a low value (1000)
+/// but increase to at least 5000 to get a good result
+/// @param opt : vector of bool with method used (default all on if available). The order is:
+/// - TMVA CNN
+/// - Keras CNN
+/// - TMVA DNN
+/// - TMVA BDT
+/// - PyTorch CNN
+void TMVA_CNN_Classification(int nevts = 1000, std::vector<bool> opt = {1, 1, 1, 1, 1})
{
bool useTMVACNN = (opt.size() > 0) ? opt[0] : false;
@@ -125,17 +134,17 @@ void TMVA_CNN_Classification(std::vector<bool> opt = {1, 1, 1, 1, 1})
bool writeOutputFile = true;
- int num_threads = 0; // use default threads
+ int num_threads = 4; // use max 4 threads
+ // switch off MT in OpenBLAS to avoid conflict with tbb
+ gSystem->Setenv("OMP_NUM_THREADS", "1");
TMVA::Tools::Instance();
// do enable MT running
if (num_threads >= 0) {
ROOT::EnableImplicitMT(num_threads);
- if (num_threads > 0) gSystem->Setenv("OMP_NUM_THREADS", TString::Format("%d",num_threads));
}
- else
- gSystem->Setenv("OMP_NUM_THREADS", "1");
+
std::cout << "Running with nthreads = " << ROOT::GetThreadPoolSize() << std::endl;
@@ -145,6 +154,7 @@ void TMVA_CNN_Classification(std::vector<bool> opt = {1, 1, 1, 1, 1})
TMVA::PyMethodBase::PyInitialize();
#else
useKerasCNN = false;
+ usePyTorchCNN = false;
#endif
TFile *outputFile = nullptr;
@@ -160,7 +170,7 @@ void TMVA_CNN_Classification(std::vector<bool> opt = {1, 1, 1, 1, 1})
The factory is the major TMVA object you have to interact with. Here is the list of parameters you need to pass
- The first argument is the base of the name of all the output
- weightfiles in the directory weight/ that will be created with the
+ weight files in the directory weight/ that will be created with the
method parameters
- The second argument is the output file for the training results
@@ -207,7 +217,7 @@ void TMVA_CNN_Classification(std::vector<bool> opt = {1, 1, 1, 1, 1})
// if file does not exists create it
if (!fileExist) {
- MakeImagesTree(5000, 16, 16);
+ MakeImagesTree(nevts, 16, 16);
}
// TString inputFileName = "tmva_class_example.root";
@@ -288,7 +298,7 @@ void TMVA_CNN_Classification(std::vector<bool> opt = {1, 1, 1, 1, 1})
// Boosted Decision Trees
if (useTMVABDT) {
factory.BookMethod(loader, TMVA::Types::kBDT, "BDT",
- "!V:NTrees=400:MinNodeSize=2.5%:MaxDepth=2:BoostType=AdaBoost:AdaBoostBeta=0.5:"
+ "!V:NTrees=200:MinNodeSize=2.5%:MaxDepth=2:BoostType=AdaBoost:AdaBoostBeta=0.5:"
"UseBaggedBoost:BaggedSampleFraction=0.5:SeparationType=GiniIndex:nCuts=20");
}
/**
@@ -354,7 +364,7 @@ void TMVA_CNN_Classification(std::vector<bool> opt = {1, 1, 1, 1, 1})
- note in this case we are using a filer 3x3 and padding=1 and stride=1 so we get the output dimension of the
conv layer equal to the input
- - note we use after the first convolutional layer a batch normalization layer. This seems to help significatly the
+ - note we use after the first convolutional layer a batch normalization layer. This seems to help significantly the
convergence
- For the MaxPool layer:
@@ -419,7 +429,7 @@ void TMVA_CNN_Classification(std::vector<bool> opt = {1, 1, 1, 1, 1})
Info("TMVA_CNN_Classification", "Building convolutional keras model");
// create python script which can be executed
- // crceate 2 conv2d layer + maxpool + dense
+ // create 2 conv2d layer + maxpool + dense
TMacro m;
m.AddLine("import tensorflow");
m.AddLine("from tensorflow.keras.models import Sequential");
@@ -439,13 +449,13 @@ void TMVA_CNN_Classification(std::vector<bool> opt = {1, 1, 1, 1, 1})
m.AddLine("model.add(Flatten())");
m.AddLine("model.add(Dense(256, activation = 'relu')) ");
m.AddLine("model.add(Dense(2, activation = 'sigmoid')) ");
- m.AddLine("model.compile(loss = 'binary_crossentropy', optimizer = Adam(lr = 0.001), metrics = ['accuracy'])");
+ m.AddLine("model.compile(loss = 'binary_crossentropy', optimizer = Adam(learning_rate = 0.001), weighted_metrics = ['accuracy'])");
m.AddLine("model.save('model_cnn.h5')");
m.AddLine("model.summary()");
m.SaveSource("make_cnn_model.py");
// execute
- gSystem->Exec("python make_cnn_model.py");
+ gSystem->Exec("python3 make_cnn_model.py");
if (gSystem->AccessPathName("model_cnn.h5")) {
Warning("TMVA_CNN_Classification", "Error creating Keras model file - skip using Keras");
@@ -465,10 +477,9 @@ void TMVA_CNN_Classification(std::vector<bool> opt = {1, 1, 1, 1, 1})
Info("TMVA_CNN_Classification", "Using Convolutional PyTorch Model");
TString pyTorchFileName = gROOT->GetTutorialDir() + TString("/tmva/PyTorch_Generate_CNN_Model.py");
// check that pytorch can be imported and file defining the model and used later when booking the method is existing
- if (gSystem->Exec("python -c 'import torch'") || gSystem->AccessPathName(pyTorchFileName) ) {
+ if (gSystem->Exec("python3 -c 'import torch'") || gSystem->AccessPathName(pyTorchFileName)) {
Warning("TMVA_CNN_Classification", "PyTorch is not installed or model building file is not existing - skip using PyTorch");
- }
- else {
+ } else {
// book PyTorch method only if PyTorch model could be created
Info("TMVA_CNN_Classification", "Booking PyTorch CNN model");
TString methodOpt = "H:!V:VarTransform=None:FilenameModel=PyTorchModelCNN.pt:"
diff --git a/tutorials/tmva/TMVA_RNN_Classification.C b/tutorials/tmva/TMVA_RNN_Classification.C
index 5bfec52196..d4bb7a4e4a 100644
--- a/tutorials/tmva/TMVA_RNN_Classification.C
+++ b/tutorials/tmva/TMVA_RNN_Classification.C
@@ -36,7 +36,7 @@
/// Helper function to generate the time data set
/// make some time data but not of fixed length.
-/// use a poisson with mu = 5 and troncated at 10
+/// use a poisson with mu = 5 and truncated at 10
///
void MakeTimeData(int n, int ntime, int ndim )
{
@@ -136,13 +136,14 @@ void MakeTimeData(int n, int ntime, int ndim )
}
}
/// macro for performing a classification using a Recurrent Neural Network
+/// @param nevts = 2000 Number of events used. (increase for better classification results)
/// @param use_type
/// use_type = 0 use Simple RNN network
/// use_type = 1 use LSTM network
/// use_type = 2 use GRU
/// use_type = 3 build 3 different networks with RNN, LSTM and GRU
-void TMVA_RNN_Classification(int use_type = 1)
+void TMVA_RNN_Classification(int nevts = 2000, int use_type = 1)
{
const int ninput = 30;
@@ -150,7 +151,7 @@ void TMVA_RNN_Classification(int use_type = 1)
const int batchSize = 100;
const int maxepochs = 20;
- int nTotEvts = 10000; // total events to be generated for signal or background
+ int nTotEvts = nevts; // total events to be generated for signal or background
bool useKeras = true;
@@ -190,14 +191,14 @@ void TMVA_RNN_Classification(int use_type = 1)
useKeras = false;
#endif
- int num_threads = 0; // use by default all threads
+ int num_threads = 4; // use max 4 threads
+ // switch off MT in OpenBLAS to avoid conflict with tbb
+ gSystem->Setenv("OMP_NUM_THREADS", "1");
+
// do enable MT running
if (num_threads >= 0) {
ROOT::EnableImplicitMT(num_threads);
- if (num_threads > 0) gSystem->Setenv("OMP_NUM_THREADS", TString::Format("%d",num_threads));
}
- else
- gSystem->Setenv("OMP_NUM_THREADS", "1");
TMVA::Config::Instance();
@@ -424,17 +425,17 @@ the option string
m.AddLine("model.add(Dense(64, activation = 'tanh')) ");
m.AddLine("model.add(Dense(2, activation = 'sigmoid')) ");
m.AddLine(
- "model.compile(loss = 'binary_crossentropy', optimizer = Adam(lr = 0.001), metrics = ['accuracy'])");
+ "model.compile(loss = 'binary_crossentropy', optimizer = Adam(learning_rate = 0.001), weighted_metrics = ['accuracy'])");
m.AddLine(TString::Format("modelName = '%s'", modelName.Data()));
m.AddLine("model.save(modelName)");
m.AddLine("model.summary()");
m.SaveSource("make_rnn_model.py");
- // execute
- gSystem->Exec("python make_rnn_model.py");
+ // execute python script to make the model
+ gSystem->Exec("python3 make_rnn_model.py");
if (gSystem->AccessPathName(modelName)) {
- Warning("TMVA_RNN_Classification", "Error creating Keras recurrennt model file - Skip using Keras");
+ Warning("TMVA_RNN_Classification", "Error creating Keras recurrent model file - Skip using Keras");
useKeras = false;
} else {
// book PyKeras method only if Keras model could be created