From db974bbe72b97c798b7db52d2481aa24c2ce2b76 Mon Sep 17 00:00:00 2001 From: moneta 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 @@ -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 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 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 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