56 void Load(
const std::string &path, std::vector<std::vector<size_t>> inputShapes = {},
int verbose = 0)
59 auto pos2 = path.find(
".onnx");
60 if (pos2 == std::string::npos) {
61 throw std::runtime_error(
"Input file is not an ONNX file");
63 auto pos1 = path.rfind(
"/");
64 if (pos1 == std::string::npos)
68 std::string modelName = path.substr(pos1,pos2-pos1);
69 std::string fileType = path.substr(pos2+1, path.length()-pos2-1);
70 if (verbose) std::cout <<
"Parsing SOFIE model " << modelName <<
" of type " << fileType << std::endl;
73 std::string modelHeader = modelName +
"_fromRSofieR.hxx";
74 std::string modelWeights = modelName +
"_fromRSofieR.dat";
78 std::string parserCode;
82 throw std::runtime_error(
"RSofieReader: cannot use SOFIE with ONNX since libROOTTMVASofieParser is missing");
84 gInterpreter->Declare(
"#include \"TMVA/RModelParser_ONNX.hxx\"");
85 parserCode +=
"{\nTMVA::Experimental::SOFIE::RModelParser_ONNX parser ; \n";
87 parserCode +=
"TMVA::Experimental::SOFIE::RModel model = parser.Parse(\"" + path +
"\",true); \n";
89 parserCode +=
"TMVA::Experimental::SOFIE::RModel model = parser.Parse(\"" + path +
"\"); \n";
92 if (inputShapes.size() > 0 && inputShapes[0].size() > 0) {
93 batchSize = inputShapes[0][0];
94 if (batchSize < 1) batchSize = 1;
96 if (verbose) std::cout <<
"generating the code with batch size = " << batchSize <<
" ...\n";
98 parserCode +=
"model.Generate(TMVA::Experimental::SOFIE::Options::kDefault,"
101 parserCode +=
"model.OutputGenerated(\"" + modelHeader +
"\");\n";
103 parserCode +=
"model.PrintRequiredInputTensors();\n";
104 parserCode +=
"model.PrintIntermediateTensors();\n";
105 parserCode +=
"model.PrintOutputTensors();\n";
107 parserCode +=
"model.PrintGenerated(); \n";
111 parserCode +=
"int nInputs = model.GetInputTensorNames().size();\n";
114 parserCode +=
"return nInputs;\n}\n";
118 std::cout <<
"...ParserCode being executed...:\n";
119 std::cout << parserCode << std::endl;
121 iret =
gROOT->ProcessLine(parserCode.c_str());
125 std::string msg =
"RSofieReader: error processing the parser code: \n" + parserCode;
126 throw std::runtime_error(msg);
127 }
else if (verbose) {
128 std::cout <<
"Model Header file is generated!" << std::endl;
131 throw std::runtime_error(
"RSofieReader does not yet support model with > 3 inputs");
135 if (verbose) std::cout <<
"compile generated code from file " <<modelHeader << std::endl;
137 std::string msg =
"RSofieReader: input header file " + modelHeader +
" is not existing";
138 throw std::runtime_error(msg);
140 if (verbose) std::cout <<
"Creating Inference function for model " << modelName << std::endl;
141 std::string declCode;
142 declCode +=
"#pragma cling optimize(2)\n";
143 declCode +=
"#include \"" + modelHeader +
"\"\n";
145 std::string sessionClassName =
"TMVA_SOFIE_" + modelName +
"::Session";
147 std::string uidName = uuid.
AsString();
148 uidName.erase(std::remove_if(uidName.begin(), uidName.end(),
149 [](
char const&
c ) ->
bool { return !std::isalnum(c); } ), uidName.end());
151 std::string sessionName =
"session_" + uidName;
152 declCode += sessionClassName +
" " + sessionName +
"(\"" + modelWeights +
"\");";
154 if (verbose) std::cout <<
"//global session declaration\n" << declCode << std::endl;
159 throw std::runtime_error(
"Error loading libROOTTMVASofie library");
163 std::string msg =
"RSofieReader: error compiling inference code and creating session class\n" + declCode;
164 throw std::runtime_error(msg);
170 std::stringstream ifuncCode;
171 std::string funcName =
"SofieInference_" + uidName;
172 ifuncCode <<
"std::vector<float> " + funcName +
"( void * ptr";
174 ifuncCode <<
", float * data" << i;
175 ifuncCode <<
") {\n";
176 ifuncCode <<
" " << sessionClassName <<
" * s = " <<
"(" << sessionClassName <<
"*) (ptr);\n";
177 ifuncCode <<
" return s->infer(";
178 for (
int i = 0; i <
fNInputs; i++) {
179 if (i>0) ifuncCode <<
",";
180 ifuncCode <<
"data" << i;
185 if (verbose) std::cout <<
"//Inference function code using global session instance\n"
186 << ifuncCode.str() << std::endl;
190 std::string msg =
"RSofieReader: error compiling inference function\n" + ifuncCode.str();
191 throw std::runtime_error(msg);