Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RModel_Base.cxx
Go to the documentation of this file.
1#include <limits>
2#include <algorithm>
3#include <cctype>
5
6namespace TMVA {
7namespace Experimental {
8namespace SOFIE {
9
10RModel_Base::RModel_Base(std::string name, std::string parsedtime):fFileName(name), fParseTime(parsedtime) {
11 fName = fFileName.substr(0, fFileName.rfind("."));
13}
14
16 fGC += ("//Code generated automatically by TMVA for Inference of Model file [" + fFileName + "] at [" + fParseTime.substr(0, fParseTime.length()-1) +"] \n");
17 // add header guards
18 hgname = fName;
19 std::transform(hgname.begin(), hgname.end(), hgname.begin(), [](unsigned char c) {
20 return std::toupper(c);
21 } );
22 hgname = "ROOT_TMVA_SOFIE_" + hgname;
23 fGC += "\n#ifndef " + hgname + "\n";
24 fGC += "#define " + hgname + "\n\n";
25 // Standard library headers the generated code relies on. Listed explicitly
26 // now that they are no longer pulled in transitively via SOFIE_common.hxx.
27 for (const char *h : {"cstdint", "cstring", "string", "vector", "map", "memory", "sstream", "iostream", "iomanip",
28 "limits", "stdexcept", "algorithm", "cmath", "cassert"}) {
29 fNeededStdLib.insert(h);
30 }
31 for (auto& i: fNeededStdLib) {
32 fGC += "#include <" + i + ">\n";
33 }
34 for (auto& i: fCustomOpHeaders) {
35 fGC += "#include \"" + i + "\"\n";
36 }
37 // Placeholder for the #include directives needed by the embedded helper
38 // functions (filled in by EmitHelperFunctionsCode).
41 fGC += "#include <fstream>\n";
42 // Include TFile when saving the weights in a binary ROOT file
44 fGC += "#include \"TFile.h\"\n";
45
46 fGC += "\nnamespace TMVA_SOFIE_" + fName + "{\n";
47 if (!fNeededBlasRoutines.empty()) {
48 fGC += ("namespace BLAS{\n");
49 for (auto &routine : fNeededBlasRoutines) {
50 if (routine == "Gemm") {
51 fGC += ("\textern \"C\" void sgemm_(const char * transa, const char * transb, const int * m, const int * n, const int * k,\n"
52 "\t const float * alpha, const float * A, const int * lda, const float * B, const int * ldb,\n"
53 "\t const float * beta, float * C, const int * ldc);\n");
54 // sgemm_ now declared; the standalone Gemm_Call helper will skip its copy.
55 fBlasSgemmDeclared = true;
56 } else if (routine == "Gemv") {
57 fGC += ("\textern \"C\" void sgemv_(const char * trans, const int * m, const int * n, const float * alpha, const float * A,\n"
58 "\t const int * lda, const float * X, const int * incx, const float * beta, const float * Y, const int * incy);\n");
59 } else if (routine == "Axpy") {
60 fGC += ("\textern \"C\" void saxpy_(const int * n, const float * alpha, const float * x,\n"
61 "\t const int * incx, float * y, const int * incy);\n");
62 } else if (routine == "Copy") {
63 fGC += ("\textern \"C\" void scopy_(const int *n, const float* x, const int *incx, float* y, const int* incy);\n");
64 }
65 }
66 fGC += ("}//BLAS\n");
67 }
68 // Placeholder for the standalone definitions of the inference helper
69 // functions used by this model (filled in by EmitHelperFunctionsCode). It
70 // sits inside the generated model namespace, right before the session code.
72}
73
75{
78
79 auto replaceMarker = [this](const std::string &marker, const std::string &replacement) {
80 auto pos = fGC.find(marker);
81 if (pos != std::string::npos) {
82 fGC.replace(pos, marker.size(), replacement);
83 }
84 };
85
88
89 // Clad derivatives live at file scope and reference the model's helpers, so
90 // insert them after the whole model namespace, just before the include guard.
91 if (!code.cladDefinitions.empty()) {
92 auto pos = fGC.rfind("#endif");
93 if (pos != std::string::npos) {
94 fGC.insert(pos, code.cladDefinitions + "\n");
95 } else {
96 fGC += code.cladDefinitions;
97 }
98 }
99}
100
101void RModel_Base::OutputGenerated(std::string filename, bool append) {
102 // the model can be appended only if a file name is provided
103 if (filename.empty()) {
104 // if a file is pr
105 filename = fName + ".hxx";
106 append = false;
107 }
108 std::ofstream f;
109 if (append)
110 f.open(filename, std::ios_base::app);
111 else
112 f.open(filename);
113 if (!f.is_open()) {
114 throw std::runtime_error("tmva-sofie failed to open file for output generated inference code");
115 }
116 f << fGC;
117 f.close();
118}
119
120}//SOFIE
121}//Experimental
122}//TMVA
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
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 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 filename
char name[80]
Definition TGX11.cxx:148
const_iterator begin() const
const_iterator end() const
void GenerateHeaderInfo(std::string &hgname)
RModel_Base()=default
Default constructor.
static constexpr const char * kHelperIncludesMarker
std::set< std::string > fNeededHelperFunctions
std::unordered_set< std::string > fNeededBlasRoutines
static constexpr const char * kHelperFunctionsMarker
std::unordered_set< std::string > fCustomOpHeaders
void OutputGenerated(std::string filename="", bool append=false)
std::unordered_set< std::string > fNeededStdLib
std::string Clean_name(std::string input_tensor_name)
HelperFunctionsCode GenerateHelperFunctionsCode(const std::set< std::string > &neededHelpers, const std::string &modelNamespace, bool sgemmAlreadyDeclared=false)
Return the standalone C++ source of the inference helper functions requested in neededHelpers (see RM...
create variable transformations
Source code of the inference helper functions to embed in generated code so that it is standalone and...
std::string definitions
function/type definitions to place inside the generated model namespace
std::string cladDefinitions
Clad custom-derivative definitions to place at file scope (outside the model namespace) so that Clad ...
std::string includes
#include directives to place in the header preamble