12namespace Experimental{
16 return static_cast<std::underlying_type_t<Options>
>(opA) |
static_cast<std::underlying_type_t<Options>
>(opB);
18 std::underlying_type_t<Options>
operator|(std::underlying_type_t<Options> opA,
Options opB) {
19 return opA |
static_cast<std::underlying_type_t<Options>
>(opB);
62 return f->second.shape;
66 return f2->second.fShape;
70 throw std::runtime_error(
"TMVA SOFIE tensor [" +
name +
"] is an input tensor with unspecified dimension parameter");
74 return f4->second.shape;
77 throw std::runtime_error(
"TMVA SOFIE tensor [" +
name +
"] for which the shape is requested is not found");
83 return f->second.type;
87 return f2->second.fType;
91 return f3->second.type;
95 return f4->second.type;
98 throw std::runtime_error(
"TMVA SOFIE tensor [" +
name +
"] for which the type is requested is not found");
111 throw std::runtime_error(
"TMVA-SOFIE: input tensor with name " + input_name +
" already exists \n");
121 throw std::runtime_error(
"TMVA-SOFIE: input tensor with name " + input_name +
" already exists \n");
133 auto libs = op->GetStdLibs();
134 for (
auto& stdlib : libs) {
137 if (order_execution >= 0) {
148 throw std::runtime_error(
"TMVA-SOFIE: initialized tensor with name " + tensor_name +
" already exists \n");
163 throw std::runtime_error(
"TMVA-SOFIE: intermediate tensor with name " + tensor_name +
" already exists \n");
170 for(
auto& it : outputtensornames){
176 for(
auto& it:curr_output_tensors){
185 throw std::runtime_error(
"TMVA-SOFIE: tensor " + tensor_name +
" not found when trying to update it");
194 throw std::runtime_error(
"TMVA-SOFIE: tensor " + tensor_name +
" not found when trying to get its data");
196 return f->second.fData;
207 throw std::runtime_error(
"TMVA-SOFIE: RModel::Initializes: invalid inputs");
209 std::vector<size_t> shape;
210 shape.reserve(
input.second.shape.size());
211 for (
auto &
d :
input.second.shape){
213 shape.push_back(batchSize);
215 shape.push_back(
d.dim);
223 bool modelHasWeights =
false;
226 modelHasWeights =
true;
236 i->Initialize(*
this);
247 throw std::runtime_error(
"TMVA-SOFIE: RModel::Generate: cannot use a separate weight file without generating a Session class");
251 fGC += (
"//Code generated automatically by TMVA for Inference of Model file [" +
fFileName +
"] at [" +
fParseTime.substr(0,
fParseTime.length()-1) +
"] \n");
253 std::string hgname =
fName;
254 std::transform(hgname.begin(), hgname.end(), hgname.begin(), [](
unsigned char c){ return std::toupper(c);} );
255 hgname =
"TMVA_SOFIE_" + hgname;
256 fGC +=
"\n#ifndef " + hgname +
"\n";
257 fGC +=
"#define " + hgname +
"\n\n";
259 fGC +=
"#include<" + i +
">\n";
262 fGC +=
"#include \"" + i +
"\"\n";
266 fGC +=
"#include \"TMVA/SOFIE_common.hxx\"\n";
268 fGC +=
"#include <fstream>\n";
270 fGC +=
"\nnamespace TMVA_SOFIE_" +
fName +
"{\n";
272 fGC += (
"namespace BLAS{\n");
274 if (routine ==
"Gemm") {
275 fGC += (
"\textern \"C\" void sgemm_(const char * transa, const char * transb, const int * m, const int * n, const int * k,\n"
276 "\t const float * alpha, const float * A, const int * lda, const float * B, const int * ldb,\n"
277 "\t const float * beta, float * C, const int * ldc);\n");
278 }
else if (routine ==
"Gemv") {
279 fGC += (
"\textern \"C\" void sgemv_(const char * trans, const int * m, const int * n, const float * alpha, const float * A,\n"
280 "\t const int * lda, const float * X, const int * incx, const float * beta, const float * Y, const int * incy);\n");
281 }
else if (routine ==
"Axpy") {
282 fGC += (
"\textern \"C\" void saxpy_(const int * n, const float * alpha, const float * x,\n"
283 "\t const int * incx, float * y, const int * incy);\n");
284 }
else if (routine ==
"Copy") {
285 fGC += (
"\textern \"C\" void scopy_(const int *n, const float* x, const int *incx, float* y, const int* incy);\n");
288 fGC += (
"}//BLAS\n");
291 fGC +=
"struct Session {\n";
296 for (
auto & dim: i.second.fShape){
300 fGC +=
"float tensor_" + i.first +
"[" + std::to_string(
length) +
"] = {";
301 std::shared_ptr<float>
data = std::static_pointer_cast<float>(i.second.fData);
302 std::stringstream floats;
303 for (
size_t idx = 0; idx <
length-1; idx++){
304 floats << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data.get()[idx] <<
", ";
306 floats << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data.get()[
length-1];
311 fGC +=
"std::vector<float> fTensor_" + i.first +
" = std::vector<float>(" + std::to_string(
length) +
");\n";
312 fGC +=
"float * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
320 fGC +=
"std::vector<float> fTensor_" + i.first +
" = std::vector<float>(" + std::to_string(
length) +
");\n";
321 fGC +=
"float * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
324 fGC +=
"std::vector<double> fTensor_" + i.first +
" = std::vector<double>(" + std::to_string(
length) +
");\n";
325 fGC +=
"double * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
328 fGC +=
"std::vector<int64_t> fTensor_" + i.first +
" = std::vector<int64_t>(" + std::to_string(
length) +
");\n";
329 fGC +=
"int64_t * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
335 for (
size_t id = 0;
id <
fOperators.size();
id++) {
336 std::string opName = std::to_string(
id);
342 fGC +=
"Session(std::string filename =\"\") {\n";
343 fGC +=
" if (filename.empty()) filename = \"" +
fName +
".dat\";\n";
349 fGC +=
"Session(std::string = \"\") {\n";
352 for (
size_t id = 0;
id <
fOperators.size() ;
id++){
360 std::string outputType;
361 if (outputSize == 1) {
364 throw std::runtime_error(
"TMVA-SOFIE: output tensor " +
fOutputTensorNames[0] +
" not found when trying to get its info");
367 fGC +=
"std::vector<" + outputType +
"> ";
370 std::vector<ETensorType> outputTensorsTypes(outputSize);
371 for (
size_t i = 0; i < outputSize; i++) {
375 +
" not found when trying to get its info");
377 outputTensorsTypes[i] =
f->second.type;
382 for (
size_t i = 0; i < outputSize; i++) {
383 if (outputTensorsTypes[i] != outputTensorsTypes[0]) {
384 throw std::runtime_error(
"TMVA-SOFIE: output tensor " +
fOutputTensorNames[i] +
" is of different type.");
387 fGC +=
"std::vector<std::vector<" + outputType +
">> ";
410 throw std::runtime_error(
"TMVA-SOFIE: input tensor " +
fInputTensorNames[i] +
" is of a data type which is not yet supported.");
417 const std::string SP =
" ";
419 for (
size_t id = 0;
id <
fOperators.size() ;
id++){
422 if (outputSize == 1) {
426 std::to_string(outputLength) +
");\n";
428 for (
size_t i = 0; i < outputSize; i++) {
431 fGC += SP +
"std::vector<" + outputType +
"> ret_";
432 fGC += std::to_string(i);
434 std::to_string(outputLength) +
");\n";
437 fGC += SP +
"std::vector<std::vector<" + outputType +
">> ret({";
438 for (
size_t i = 0; i < outputSize; i++) {
443 fGC += std::to_string(i);
445 if (i < outputSize - 1) {
451 fGC += SP +
"return ret;\n";
456 fGC += (
"} //TMVA_SOFIE_" +
fName +
"\n");
457 fGC +=
"\n#endif // " + hgname +
"\n";
464 fGC +=
" std::ifstream f;\n";
465 fGC +=
" f.open(filename);\n";
466 fGC +=
" if (!f.is_open()){\n";
467 fGC +=
" throw std::runtime_error(\"tmva-sofie failed to open file for input weights\");\n";
469 fGC +=
" std::string tensor_name;\n";
470 fGC +=
" int length;\n";
476 for (
auto & dim: i.second.fShape){
479 std::string tensor_name =
"tensor_" + i.first;
480 std::string slength = std::to_string(
length);
481 fGC +=
" f >> tensor_name >> length;\n";
482 fGC +=
" if (tensor_name != \"" + tensor_name +
"\" ) {\n";
483 fGC +=
" std::string err_msg = \"TMVA-SOFIE failed to read the correct tensor name; expected name is " +
484 tensor_name +
" , read \" + tensor_name;\n";
485 fGC +=
" throw std::runtime_error(err_msg);\n";
487 fGC +=
" if (length != " + slength +
") {\n";
488 fGC +=
" std::string err_msg = \"TMVA-SOFIE failed to read the correct tensor size; expected size is " +
489 slength +
" , read \" + std::to_string(length) ;\n";
490 fGC +=
" throw std::runtime_error(err_msg);\n";
492 fGC +=
" for (int i =0; i < length; ++i) \n";
493 fGC +=
" f >> " + tensor_name +
"[i];\n";
496 fGC +=
" f.close();\n";
508 throw std::runtime_error(
"tmva-sofie failed to open file for tensor weight data");
513 for (
auto &dim : i.second.fShape) {
516 std::string tensor_name =
"tensor_" + i.first;
517 f << tensor_name <<
" " <<
length <<
"\n";
518 const float *
data = (std::static_pointer_cast<float>(i.second.fData)).get();
519 for (
size_t idx = 0; idx <
length - 1; idx++) {
520 f << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data[idx] <<
" ";
522 f << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data[
length - 1];
530 std::cout <<
"Model requires following inputs:\n";
532 std::cout <<
"Parameterised Tensor name: " << inputInfo.first <<
"\t";
534 std::cout <<
"shape: [";
535 for (
size_t i = 0; i < inputInfo.second.shape.size(); i++){
536 if (inputInfo.second.shape[i].isParam){
537 std::cout << inputInfo.second.shape[i].param;
539 std::cout << inputInfo.second.shape[i].dim ;
541 if (i < inputInfo.second.shape.size() - 1) std::cout <<
",";
543 std::cout <<
"]" << std::endl;
547 std::cout <<
"Fully Specified Tensor name: " << inputInfo.first <<
"\t";
549 std::cout <<
"shape: [";
550 for (
size_t i = 0; i < inputInfo.second.shape.size(); i++){
551 std::cout << inputInfo.second.shape[i];
552 if (i < inputInfo.second.shape.size() - 1) std::cout <<
",";
554 std::cout <<
"]" << std::endl;
560 std::cout <<
"Model initialized the following tensors:\n";
562 std::cout <<
"Tensor name: \"" << it.first <<
"\"\t";
564 std::cout <<
"shape: [";
565 for (
size_t i = 0; i < it.second.fShape.size(); i++){
566 std::cout << it.second.fShape[i];
567 if (i < it.second.fShape.size() - 1) std::cout <<
",";
569 std::cout <<
"]" << std::endl;
574 std::cout <<
"Model specify the following intermediate tensors:\n";
576 std::cout <<
"Tensor name: \"" << it.first <<
"\"\t";
578 std::cout <<
"shape: [";
579 for (
size_t i = 0; i < it.second.shape.size(); i++){
580 std::cout << it.second.shape[i];
581 if (i < it.second.shape.size() - 1) std::cout <<
",";
583 std::cout <<
"]" << std::endl;
590 std::cout <<
"Tensor " <<
name <<
" not found in model's intialized tensor list" << std::endl;
594 std::cout <<
"Tensor name: " << it->first <<
"\t";
597 std::cout <<
"shape: [";
598 for (
size_t i = 0; i < it->second.fShape.size(); i++){
599 std::cout << it->second.fShape[i];
600 length *= it->second.fShape[i];
601 if (i < it->second.fShape.size() - 1) std::cout <<
",";
603 std::cout <<
"]" << std::endl;
604 bool ellipsis =
true;
610 std::cout <<
"data: [" << std::endl;
614 auto converted_data = std::static_pointer_cast<float>(it->second.fData).get();
615 for (
int i =0; i < n_print; i++){
616 std::cout << converted_data[i];
617 if (i < n_print - 1) std::cout <<
" ,";
622 if (ellipsis) std::cout <<
", ...";
623 std::cout <<
"]" << std::endl;
634 throw std::runtime_error(
"tmva-sofie failed to open file for output generated inference code");
649 i->second.CastPersistentToShared();
654 i->second.CastSharedToPersistent();
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
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
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 length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
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
Buffer base class used for serializing objects.
Int_t ReadBuffer(TBuffer &b, void *pointer, Int_t version, UInt_t start, UInt_t count)
Function called by the Streamer functions to deserialize information from buffer b into object at p.
Int_t WriteBuffer(TBuffer &b, void *pointer, const char *info="")
Function called by the Streamer functions to serialize object at p to buffer b.
void AddOutputTensorNameList(std::vector< std::string > outputtensornames)
void ReadInitializedTensorsFromFile()
const ETensorType & GetTensorType(std::string name)
void PrintIntermediateTensors()
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape)
std::unordered_set< std::string > fNeededBlasRoutines
bool CheckIfTensorAlreadyExist(std::string tensor_name)
std::vector< std::unique_ptr< ROperator > > fOperators
void AddInputTensorInfo(std::string input_name, ETensorType type, std::vector< Dim > shape)
void Initialize(int batchSize=1)
std::unordered_map< std::string, TensorInfo > fIntermediateTensorInfos
std::unordered_map< std::string, TensorInfo > fReadyInputTensorInfos
void AddInitializedTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape, std::shared_ptr< void > data)
RModel & operator=(RModel &&other)
void AddBlasRoutines(std::vector< std::string > routines)
void AddInputTensorName(std::string name)
std::vector< std::string > fOutputTensorNames
void AddNeededStdLib(std::string libname)
bool IsInitializedTensor(const std::string &name) const
std::unordered_set< std::string > fNeededStdLib
void PrintInitializedTensors()
void AddOperator(std::unique_ptr< ROperator > op, int order_execution=-1)
void HeadInitializedTensors(std::string name, int n_print=50)
void OutputGenerated(std::string filename="")
const std::vector< size_t > & GetTensorShape(std::string name)
std::unordered_map< std::string, InputTensorInfo > fInputTensorInfos
std::shared_ptr< void > GetInitializedTensorData(std::string tensor_name)
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
void Generate(std::underlying_type_t< Options > options, int batchSize=1)
void WriteInitializedTensorsToFile(std::string filename="")
std::vector< std::string > fInputTensorNames
std::unordered_map< std::string, InitializedTensor > fInitializedTensors
void UpdateInitializedTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape, std::shared_ptr< void > data)
void UpdateOutputTensorList(std::vector< std::string > curr_output_tensor, std::vector< std::string > modify_output_tensor)
std::unordered_set< std::string > fCustomOpHeaders
void PrintRequiredInputTensors()
std::string Clean_name(std::string input_tensor_name)
std::string ConvertTypeToString(ETensorType type)
std::underlying_type_t< Options > operator|(Options opA, Options opB)
std::size_t ConvertShapeToLength(std::vector< size_t > shape)
create variable transformations