From db974bbe72b97c798b7db52d2481aa24c2ce2b76 Mon Sep 17 00:00:00 2001
From: moneta <lorenzo.moneta@cern.ch>
Date: Thu, 17 Mar 2022 16:28:42 +0100
Subject: [PATCH] Fix TMVA tutorial using internally pyton for MacOS 12.3
With the new MacOS update python (and python2) is not existing anymore, only python3.
Add then a new function TMVA::Python_executable() using ROOT config to determine if ROOT is using python version 2 or 3. In case of 3 returns as executable "python3".
Fix also the correct location of the input ONNX file for TMVA_SOFIE_ONNX.C (copying the file at configure time)
---
tmva/pymva/inc/TMVA/PyMethodBase.h | 6 ++++++
tmva/pymva/src/PyMethodBase.cxx | 20 ++++++++++++++++++++
tutorials/CMakeLists.txt | 5 ++++-
tutorials/tmva/TMVA_CNN_Classification.C | 5 +++--
tutorials/tmva/TMVA_RNN_Classification.C | 2 +-
tutorials/tmva/TMVA_SOFIE_Keras.C | 2 +-
tutorials/tmva/TMVA_SOFIE_ONNX.C | 2 +-
tutorials/tmva/TMVA_SOFIE_PyTorch.C | 2 +-
8 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/tmva/pymva/inc/TMVA/PyMethodBase.h b/tmva/pymva/inc/TMVA/PyMethodBase.h
index 31a5caada9..a213c3fbad 100644
--- a/tmva/pymva/inc/TMVA/PyMethodBase.h
+++ b/tmva/pymva/inc/TMVA/PyMethodBase.h
@@ -53,6 +53,12 @@ namespace TMVA {
class MethodBoost;
class DataSetInfo;
+ /// Function to find current Python executable
+ /// used by ROOT
+ /// If Python2 is installed return "python"
+ /// Instead if "Python3" return "python3"
+ TString Python_Executable();
+
class PyMethodBase : public MethodBase {
friend class Factory;
diff --git a/tmva/pymva/src/PyMethodBase.cxx b/tmva/pymva/src/PyMethodBase.cxx
index 86f979e006..26b0f31135 100644
--- a/tmva/pymva/src/PyMethodBase.cxx
+++ b/tmva/pymva/src/PyMethodBase.cxx
@@ -19,6 +19,9 @@
#include "TMVA/MsgLogger.h"
#include "TMVA/Results.h"
#include "TMVA/Timer.h"
+#include "TMVA/Tools.h"
+
+#include "TSystem.h"
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>
@@ -37,6 +40,23 @@ public:
~PyGILRAII() { PyGILState_Release(m_GILState); }
};
} // namespace Internal
+
+/// get current Python executable used by ROOT
+TString Python_Executable() {
+ TString python_version = gSystem->GetFromPipe("root-config --python-version");
+ if (python_version.IsNull()) {
+ TMVA::gTools().Log() << kFATAL << "Can't find a valid Python version used to build ROOT" << Endl;
+ return nullptr;
+ }
+ if(python_version[0] == '2')
+ return "python";
+ else if (python_version[0] == '3')
+ return "python3";
+
+ TMVA::gTools().Log() << kFATAL << "Invalid Python version used to build ROOT : " << python_version << Endl;
+ return nullptr;
+}
+
} // namespace TMVA
ClassImp(PyMethodBase);
diff --git a/tutorials/CMakeLists.txt b/tutorials/CMakeLists.txt
index de77aaa787..f1f1abda71 100644
--- a/tutorials/CMakeLists.txt
+++ b/tutorials/CMakeLists.txt
@@ -281,8 +281,11 @@ else()
endif()
if (NOT tmva-sofie)
list(APPEND tmva_veto tmva/TMVA_SOFIE_ONNX.C)
+ else()
+ #copy ONNX file needed for the tutorial
+ configure_file(${CMAKE_SOURCE_DIR}/tmva/sofie/test/input_models/Linear_16.onnx ${CMAKE_BINARY_DIR}/tutorials/tmva/Linear_16.onnx COPYONLY)
endif()
-
+
endif()
if (NOT ROOT_pythia6_FOUND)
diff --git a/tutorials/tmva/TMVA_CNN_Classification.C b/tutorials/tmva/TMVA_CNN_Classification.C
index fa03562a8f..31172bb729 100644
--- a/tutorials/tmva/TMVA_CNN_Classification.C
+++ b/tutorials/tmva/TMVA_CNN_Classification.C
@@ -145,6 +145,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;
@@ -445,7 +446,7 @@ void TMVA_CNN_Classification(std::vector<bool> opt = {1, 1, 1, 1, 1})
m.SaveSource("make_cnn_model.py");
// execute
- gSystem->Exec("python make_cnn_model.py");
+ gSystem->Exec(TMVA::Python_Executable() + " make_cnn_model.py");
if (gSystem->AccessPathName("model_cnn.h5")) {
Warning("TMVA_CNN_Classification", "Error creating Keras model file - skip using Keras");
@@ -465,7 +466,7 @@ 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(TMVA::Python_Executable() + " -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 {
diff --git a/tutorials/tmva/TMVA_RNN_Classification.C b/tutorials/tmva/TMVA_RNN_Classification.C
index eb26d03a2f..b49e4d91c4 100644
--- a/tutorials/tmva/TMVA_RNN_Classification.C
+++ b/tutorials/tmva/TMVA_RNN_Classification.C
@@ -431,7 +431,7 @@ the option string
m.SaveSource("make_rnn_model.py");
// execute
- gSystem->Exec("python make_rnn_model.py");
+ gSystem->Exec(TMVA::Python_Executable() + " make_rnn_model.py");
if (gSystem->AccessPathName(modelName)) {
Warning("TMVA_RNN_Classification", "Error creating Keras recurrent model file - Skip using Keras");
diff --git a/tutorials/tmva/TMVA_SOFIE_Keras.C b/tutorials/tmva/TMVA_SOFIE_Keras.C
index e9fdbba21a..a87269f7f4 100644
--- a/tutorials/tmva/TMVA_SOFIE_Keras.C
+++ b/tutorials/tmva/TMVA_SOFIE_Keras.C
@@ -45,7 +45,7 @@ void TMVA_SOFIE_Keras(){
TMacro m;
m.AddLine(pythonSrc);
m.SaveSource("make_keras_model.py");
- gSystem->Exec("python make_keras_model.py");
+ gSystem->Exec(TMVA::Python_Executable() + " make_keras_model.py");
//Parsing the saved Keras .h5 file into RModel object
SOFIE::RModel model = SOFIE::PyKeras::Parse("KerasModel.h5");
diff --git a/tutorials/tmva/TMVA_SOFIE_ONNX.C b/tutorials/tmva/TMVA_SOFIE_ONNX.C
index 30148db4fa..bf66c38896 100644
--- a/tutorials/tmva/TMVA_SOFIE_ONNX.C
+++ b/tutorials/tmva/TMVA_SOFIE_ONNX.C
@@ -13,7 +13,7 @@ using namespace TMVA::Experimental;
void TMVA_SOFIE_ONNX(){
//Creating parser object to parse ONNX files
SOFIE::RModelParser_ONNX Parser;
- SOFIE::RModel model = Parser.Parse("../../tmva/sofie/test/input_models/Linear_16.onnx");
+ SOFIE::RModel model = Parser.Parse(std::string(gROOT->GetTutorialsDir()) + "/tmva/Linear_16.onnx");
//Generating inference code
model.Generate();
diff --git a/tutorials/tmva/TMVA_SOFIE_PyTorch.C b/tutorials/tmva/TMVA_SOFIE_PyTorch.C
index b208b042d7..580787cae1 100644
--- a/tutorials/tmva/TMVA_SOFIE_PyTorch.C
+++ b/tutorials/tmva/TMVA_SOFIE_PyTorch.C
@@ -47,7 +47,7 @@ void TMVA_SOFIE_PyTorch(){
TMacro m;
m.AddLine(pythonSrc);
m.SaveSource("make_pytorch_model.py");
- gSystem->Exec("python make_pytorch_model.py");
+ gSystem->Exec(TMVA::Python_Executable() + " make_pytorch_model.py");
//Parsing a PyTorch model requires the shape and data-type of input tensor
//Data-type of input tensor defaults to Float if not specified
--
2.35.1