16#ifndef TMVA_RSOFIEREADER 
   17#define TMVA_RSOFIEREADER 
   34namespace Experimental {
 
   58   void Load(
const std::string &path, std::vector<std::vector<size_t>> 
inputShapes = {}, 
int verbose = 0)
 
   64      auto pos1 = path.rfind(
"/");
 
   65      auto pos2 = path.find(
".onnx");
 
   66      if (
pos2 != std::string::npos) {
 
   69         pos2 = path.find(
".h5");
 
   70         if (
pos2 != std::string::npos) {
 
   73            pos2 = path.find(
".pt");
 
   74            if (
pos2 != std::string::npos) {
 
   78               pos2 = path.find(
".root");
 
   79               if (
pos2 != std::string::npos) {
 
   86         throw std::runtime_error(
"Input file is not an ONNX or Keras or PyTorch file");
 
   88      if (
pos1 == std::string::npos)
 
   94      if (verbose) std::cout << 
"Parsing SOFIE model " << 
modelName << 
" of type " << 
fileType << std::endl;
 
  102            throw std::runtime_error(
"RSofieReader: cannot use SOFIE with ONNX since libROOTTMVASofieParser is missing");
 
  104         gInterpreter->Declare(
"#include \"TMVA/RModelParser_ONNX.hxx\"");
 
  105         parserCode += 
"{\nTMVA::Experimental::SOFIE::RModelParser_ONNX parser ; \n";
 
  107            parserCode += 
"TMVA::Experimental::SOFIE::RModel model = parser.Parse(\"" + path + 
"\",true); \n";
 
  109            parserCode += 
"TMVA::Experimental::SOFIE::RModel model = parser.Parse(\"" + path + 
"\"); \n";
 
  114            throw std::runtime_error(
"RSofieReader: cannot use SOFIE with Keras since libPyMVA is missing");
 
  120         parserCode += 
"{\nTMVA::Experimental::SOFIE::RModel model = TMVA::Experimental::SOFIE::PyKeras::Parse(\"" + path +
 
  126            throw std::runtime_error(
"RSofieReader: cannot use SOFIE with PyTorch since libPyMVA is missing");
 
  129            throw std::runtime_error(
"RSofieReader: cannot use SOFIE with PyTorch since the input tensor shape is missing and is needed by the PyTorch parser");
 
  132         for (
unsigned int i = 0; i < 
inputShapes.size(); i++) {
 
  142         parserCode += 
"{\nTMVA::Experimental::SOFIE::RModel model = TMVA::Experimental::SOFIE::PyTorch::Parse(\"" + path + 
"\", " 
  145      else if (
type == kROOT) {
 
  147         parserCode += 
"{\nauto fileRead = TFile::Open(\"" + path + 
"\",\"READ\");\n";
 
  148         parserCode += 
"TMVA::Experimental::SOFIE::RModel * modelPtr;\n";
 
  149         parserCode += 
"auto keyList = fileRead->GetListOfKeys(); TString name;\n";
 
  150         parserCode += 
"for (const auto&& k : *keyList)  { \n";
 
  151         parserCode += 
"   TString cname =  ((TKey*)k)->GetClassName();  if (cname==\"TMVA::Experimental::SOFIE::RModel\") name = k->GetName(); }\n";
 
  152         parserCode += 
"fileRead->GetObject(name,modelPtr); fileRead->Close(); delete fileRead;\n";
 
  153         parserCode += 
"TMVA::Experimental::SOFIE::RModel & model = *modelPtr;\n";
 
  160            parserCode += 
"{ auto p = new TMVA::Experimental::SOFIE::ROperator_Custom<float>(\"" 
  161                      + 
op.fOpName + 
"\"," + 
op.fInputNames + 
"," + 
op.fOutputNames + 
"," + 
op.fOutputShapes + 
",\"" + 
op.fFileName + 
"\");\n";
 
  162            parserCode += 
"std::unique_ptr<TMVA::Experimental::SOFIE::ROperator> op(p);\n";
 
  163            parserCode += 
"model.AddOperator(std::move(op));\n}\n";
 
  170         if (batchSize < 1) batchSize = 1;
 
  172      if (verbose) std::cout << 
"generating the code with batch size = " << batchSize << 
" ...\n";
 
  174      parserCode += 
"model.Generate(TMVA::Experimental::SOFIE::Options::kDefault," 
  178         parserCode += 
"model.PrintRequiredInputTensors();\n";
 
  179         parserCode += 
"model.PrintIntermediateTensors();\n";
 
  180         parserCode += 
"model.PrintOutputTensors();\n";
 
  187            parserCode += 
"model.PrintRequiredInputTensors();\n";
 
  188            parserCode += 
"model.PrintIntermediateTensors();\n";
 
  189            parserCode += 
"model.PrintOutputTensors();\n";
 
  192            parserCode += 
"{ auto p = new TMVA::Experimental::SOFIE::ROperator_Custom<float>(\"" 
  193                      + 
op.fOpName + 
"\"," + 
op.fInputNames + 
"," + 
op.fOutputNames + 
"," + 
op.fOutputShapes + 
",\"" + 
op.fFileName + 
"\");\n";
 
  194            parserCode += 
"std::unique_ptr<TMVA::Experimental::SOFIE::ROperator> op(p);\n";
 
  195            parserCode += 
"model.AddOperator(std::move(op));\n}\n";
 
  197         parserCode += 
"model.Generate(TMVA::Experimental::SOFIE::Options::kDefault," 
  205      parserCode += 
"int nInputs = model.GetInputTensorNames().size();\n";
 
  212      if (verbose) std::cout << 
"//ParserCode being executed:\n" << 
parserCode << std::endl;
 
  216         std::string 
msg = 
"RSofieReader: error processing the parser code: \n" + 
parserCode;
 
  217         throw std::runtime_error(
msg);
 
  221         throw std::runtime_error(
"RSofieReader does not yet support model with > 3 inputs");
 
  226      if (verbose) std::cout << 
"compile generated code from file " <<
modelHeader << std::endl;
 
  228         std::string 
msg = 
"RSofieReader: input header file " + 
modelHeader + 
" is not existing";
 
  229         throw std::runtime_error(
msg);
 
  231      if (verbose) std::cout << 
"Creating Inference function for model " << 
modelName << std::endl;
 
  233      declCode += 
"#pragma cling optimize(2)\n";
 
  240         []( 
char const& 
c ) -> 
bool { return !std::isalnum(c); } ), 
uidName.
end());
 
  245      if (verbose) std::cout << 
"//global session declaration\n" << 
declCode << std::endl;
 
  249         std::string 
msg = 
"RSofieReader: error compiling inference code and creating session class\n" + 
declCode;
 
  250         throw std::runtime_error(
msg);
 
  257      std::string funcName = 
"SofieInference_" + 
uidName;
 
  258      ifuncCode << 
"std::vector<float> " + funcName + 
"( void * ptr";
 
  264      for (
int i = 0; i < 
fNInputs; i++) {
 
  271      if (verbose) std::cout << 
"//Inference function code using global session instance\n" 
  276         std::string 
msg = 
"RSofieReader: error compiling inference function\n" + 
ifuncCode.str();
 
  277         throw std::runtime_error(
msg);
 
 
  286      const std::string & 
outputShapes, 
const std::string & fileName) {
 
  287         if (
fInitialized)  std::cout << 
"WARNING: Model is already loaded and initialised. It must be done after adding the custom operators" << std::endl;
 
 
  294         std::string 
msg = 
"Wrong number of inputs - model requires " + std::to_string(
fNInputs);
 
  295         throw std::runtime_error(
msg);
 
  297      auto fptr = 
reinterpret_cast<std::vector<float> (*)(
void *, 
const float *)
>(
fFuncPtr);
 
 
  300   std::vector<float> 
DoCompute(
const std::vector<float> & 
x1, 
const std::vector<float> & 
x2) {
 
  302         std::string 
msg = 
"Wrong number of inputs - model requires " + std::to_string(
fNInputs);
 
  303         throw std::runtime_error(
msg);
 
  305      auto fptr = 
reinterpret_cast<std::vector<float> (*)(
void *, 
const float *, 
const float *)
>(
fFuncPtr);
 
 
  308   std::vector<float> 
DoCompute(
const std::vector<float> & 
x1, 
const std::vector<float> & 
x2, 
const std::vector<float> & 
x3) {
 
  310         std::string 
msg = 
"Wrong number of inputs - model requires " + std::to_string(
fNInputs);
 
  311         throw std::runtime_error(
msg);
 
  313      auto fptr = 
reinterpret_cast<std::vector<float> (*)(
void *, 
const float *, 
const float *, 
const float *)
>(
fFuncPtr);
 
 
  318   template<
typename... T>
 
  322         return std::vector<float>();
 
 
  332   std::vector<float> 
Compute(
const std::vector<float> &
x) {
 
  334         return std::vector<float>();
 
 
  352      const auto nrows = 
x.GetShape()[0];
 
  353      const auto rowsize = 
x.GetStrides()[0];
 
  354      auto fptr = 
reinterpret_cast<std::vector<float> (*)(
void *, 
const float *)
>(
fFuncPtr);
 
  361      for (
size_t i = 1; i < 
nrows; i++) {
 
 
 
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
 
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
 
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
 
Option_t Option_t TPoint TPoint const char x2
 
Option_t Option_t TPoint TPoint const char x1
 
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
 
R__EXTERN TSystem * gSystem
 
#define R__WRITE_LOCKGUARD(mutex)
 
const_iterator begin() const
 
const_iterator end() const
 
TMVA::RSofieReader class for reading external Machine Learning models in ONNX files,...
 
RSofieReader(const std::string &path, std::vector< std::vector< size_t > > inputShapes={}, int verbose=0)
Create TMVA model from ONNX file print level can be 0 (minimal) 1 with info , 2 with all ONNX parsing...
 
RTensor< float > Compute(RTensor< float > &x)
Compute model prediction on input RTensor The shape of the input tensor should be {nevents,...
 
std::vector< float > Compute(const std::vector< float > &x)
 
std::vector< float > Compute(T... x)
Compute model prediction on vector.
 
void Load(const std::string &path, std::vector< std::vector< size_t > > inputShapes={}, int verbose=0)
 
std::vector< float > DoCompute(const std::vector< float > &x1, const std::vector< float > &x2, const std::vector< float > &x3)
 
std::vector< CustomOperatorData > fCustomOperators
 
std::vector< float > DoCompute(const std::vector< float > &x1)
 
void AddCustomOperator(const std::string &opName, const std::string &inputNames, const std::string &outputNames, const std::string &outputShapes, const std::string &fileName)
 
std::vector< float > DoCompute(const std::vector< float > &x1, const std::vector< float > &x2)
 
RSofieReader()
Dummy constructor which needs model loading afterwards.
 
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
 
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
 
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
 
const char * AsString() const
Return UUID as string. Copy string immediately since it will be reused.
 
std::string ToString(const T &val)
Utility function for conversion to strings.
 
R__EXTERN TVirtualRWMutex * gCoreMutex
 
create variable transformations
 
std::string fOutputShapes