16#ifndef TMVA_RSOFIEREADER
17#define TMVA_RSOFIEREADER
35namespace Experimental {
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)
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";
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";
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,"
103 parserCode +=
"model.PrintRequiredInputTensors();\n";
104 parserCode +=
"model.PrintIntermediateTensors();\n";
105 parserCode +=
"model.PrintOutputTensors();\n";
111 parserCode +=
"int nInputs = model.GetInputTensorNames().size();\n";
118 std::cout <<
"...ParserCode being executed...:\n";
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;
142 declCode +=
"#pragma cling optimize(2)\n";
149 [](
char const&
c ) ->
bool { return !std::isalnum(c); } ),
uidName.
end());
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);
171 std::string funcName =
"SofieInference_" +
uidName;
172 ifuncCode <<
"std::vector<float> " + funcName +
"( void * ptr";
178 for (
int i = 0; i <
fNInputs; i++) {
185 if (verbose) std::cout <<
"//Inference function code using global session instance\n"
190 std::string
msg =
"RSofieReader: error compiling inference function\n" +
ifuncCode.str();
191 throw std::runtime_error(
msg);
201 std::string
msg =
"Wrong number of inputs - model requires " + std::to_string(
fNInputs);
202 throw std::runtime_error(
msg);
204 auto fptr =
reinterpret_cast<std::vector<float> (*)(
void *,
const float *)
>(
fFuncPtr);
207 std::vector<float>
DoCompute(
const std::vector<float> &
x1,
const std::vector<float> &
x2) {
209 std::string
msg =
"Wrong number of inputs - model requires " + std::to_string(
fNInputs);
210 throw std::runtime_error(
msg);
212 auto fptr =
reinterpret_cast<std::vector<float> (*)(
void *,
const float *,
const float *)
>(
fFuncPtr);
215 std::vector<float>
DoCompute(
const std::vector<float> &
x1,
const std::vector<float> &
x2,
const std::vector<float> &
x3) {
217 std::string
msg =
"Wrong number of inputs - model requires " + std::to_string(
fNInputs);
218 throw std::runtime_error(
msg);
220 auto fptr =
reinterpret_cast<std::vector<float> (*)(
void *,
const float *,
const float *,
const float *)
>(
fFuncPtr);
225 template<
typename... T>
229 return std::vector<float>();
239 std::vector<float>
Compute(
const std::vector<float> &
x) {
241 return std::vector<float>();
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 x2
Option_t Option_t TPoint TPoint const char x1
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 and performing th...
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...
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< float > DoCompute(const std::vector< float > &x1)
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
modelName
Step 2 : Parse model and generate inference code with SOFIE.
create variable transformations