12namespace Experimental {
16 return static_cast<std::underlying_type_t<Options>
>(opA) |
static_cast<std::underlying_type_t<Options>
>(opB);
18std::underlying_type_t<Options>
operator|(std::underlying_type_t<Options> opA,
Options opB) {
19 return opA |
static_cast<std::underlying_type_t<Options>
>(opB);
58 return f->second.shape;
62 return f2->second.fShape;
66 throw std::runtime_error(
"TMVA SOFIE tensor [" +
name +
"] is an input tensor with unspecified dimension parameter");
70 return f4->second.shape;
73 throw std::runtime_error(
"TMVA SOFIE tensor [" +
name +
"] for which the shape is requested is not found");
79 return f->second.type;
83 return f2->second.fType;
87 return f3->second.type;
91 return f4->second.type;
94 throw std::runtime_error(
"TMVA SOFIE tensor [" +
name +
"] for which the type is requested is not found");
107 throw std::runtime_error(
"TMVA-SOFIE: input tensor with name " + input_name +
" already exists \n");
117 throw std::runtime_error(
"TMVA-SOFIE: input tensor with name " + input_name +
" already exists \n");
129 auto libs = op->GetStdLibs();
130 for (
auto& stdlib : libs) {
133 if (order_execution >= 0) {
144 throw std::runtime_error(
"TMVA-SOFIE: initialized tensor with name " + tensor_name +
" already exists \n");
159 throw std::runtime_error(
"TMVA-SOFIE: intermediate tensor with name " + tensor_name +
" already exists \n");
167 for(
auto& it : outputtensornames) {
173 for(
auto& it:curr_output_tensors) {
182 throw std::runtime_error(
"TMVA-SOFIE: tensor " + tensor_name +
" not found when trying to update it");
191 throw std::runtime_error(
"TMVA-SOFIE: tensor " + tensor_name +
" not found when trying to get its data");
193 return f->second.fData;
204 throw std::runtime_error(
"TMVA-SOFIE: RModel::Initializes: invalid inputs");
206 std::vector<size_t> shape;
207 shape.reserve(
input.second.shape.size());
208 for (
auto &
d :
input.second.shape) {
210 shape.push_back(batchSize);
212 shape.push_back(
d.dim);
220 bool modelHasWeights =
false;
223 modelHasWeights =
true;
231 i->Initialize(*
this);
239 for (
auto & dim: i.second.fShape) {
243 fGC +=
"float tensor_" + i.first +
"[" + std::to_string(
length) +
"] = {";
244 std::shared_ptr<float>
data = std::static_pointer_cast<float>(i.second.fData);
245 std::stringstream floats;
246 for (
size_t idx = 0; idx <
length-1; idx++) {
247 floats << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data.get()[idx] <<
", ";
249 floats << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data.get()[
length-1];
254 fGC +=
"std::vector<float> fTensor_" + i.first +
" = std::vector<float>(" + std::to_string(
length) +
");\n";
255 fGC +=
"float * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
266 fGC +=
"std::vector<float> fTensor_" + i.first +
" = std::vector<float>(" + std::to_string(
length) +
");\n";
267 fGC +=
"float * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
270 fGC +=
"std::vector<double> fTensor_" + i.first +
" = std::vector<double>(" + std::to_string(
length) +
");\n";
271 fGC +=
"double * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
274 fGC +=
"std::vector<int64_t> fTensor_" + i.first +
" = std::vector<int64_t>(" + std::to_string(
length) +
");\n";
275 fGC +=
"int64_t * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
283 std::string outputType;
284 if (outputSize == 1) {
287 throw std::runtime_error(
"TMVA-SOFIE: output tensor " +
fOutputTensorNames[0] +
" not found when trying to get its info");
290 fGC +=
"std::vector<" + outputType +
"> ";
293 std::vector<ETensorType> outputTensorsTypes(outputSize);
294 for (
size_t i = 0; i < outputSize; i++) {
298 +
" not found when trying to get its info");
300 outputTensorsTypes[i] =
f->second.type;
305 for (
size_t i = 0; i < outputSize; i++) {
306 if (outputTensorsTypes[i] != outputTensorsTypes[0]) {
307 throw std::runtime_error(
"TMVA-SOFIE: output tensor " +
fOutputTensorNames[i] +
" is of different type.");
310 fGC +=
"std::vector<std::vector<" + outputType +
">> ";
334 throw std::runtime_error(
"TMVA-SOFIE: input tensor " +
fInputTensorNames[i] +
" is of a data type which is not yet supported.");
342 const std::string SP =
" ";
344 for (
size_t id = 0;
id <
fOperators.size() ;
id++) {
348 if (outputSize == 1) {
352 std::to_string(outputLength) +
");\n";
354 for (
size_t i = 0; i < outputSize; i++) {
357 fGC += SP +
"std::vector<" + outputType +
"> ret_";
358 fGC += std::to_string(i);
360 std::to_string(outputLength) +
");\n";
363 fGC += SP +
"std::vector<std::vector<" + outputType +
">> ret({";
364 for (
size_t i = 0; i < outputSize; i++) {
369 fGC += std::to_string(i);
371 if (i < outputSize - 1) {
377 fGC += SP +
"return ret;\n";
397 std::runtime_error(
"TMVA-SOFIE: RModel::Generate: cannot use a separate weight file without generating a Session class");
400 if (
static_cast<std::underlying_type_t<Options>
>(
Options::kGNN) & options)
411 fGC +=
"struct Session {\n";
421 for (
size_t id = 0;
id <
fOperators.size();
id++) {
422 std::string opName = std::to_string(
id);
428 fGC +=
"Session(std::string filename =\"\") {\n";
429 fGC +=
" if (filename.empty()) filename = \"" +
fName;
441 fGC +=
"Session(std::string = \"\") {\n";
445 for (
size_t id = 0;
id <
fOperators.size() ;
id++) {
458 fGC += (
"} //TMVA_SOFIE_" +
fName +
"\n");
459 fGC +=
"\n#endif // " + hgname +
"\n";
468 fGC +=
" std::ifstream f;\n";
469 fGC +=
" f.open(filename);\n";
470 fGC +=
" if (!f.is_open()) {\n";
471 fGC +=
" throw std::runtime_error(\"tmva-sofie failed to open file for input weights\");\n";
475 fGC +=
" f.seekg(" + std::to_string(pos) +
");\n";
478 fGC +=
" std::string tensor_name;\n";
479 fGC +=
" size_t length;\n";
486 std::string tensor_name =
"tensor_" + i.first;
487 std::string slength = std::to_string(
length);
488 fGC +=
" f >> tensor_name >> length;\n";
489 fGC +=
" if (tensor_name != \"" + tensor_name +
"\" ) {\n";
490 fGC +=
" std::string err_msg = \"TMVA-SOFIE failed to read the correct tensor name; expected name is " +
491 tensor_name +
" , read \" + tensor_name;\n";
492 fGC +=
" throw std::runtime_error(err_msg);\n";
494 fGC +=
" if (length != " + slength +
") {\n";
495 fGC +=
" std::string err_msg = \"TMVA-SOFIE failed to read the correct tensor size; expected size is " +
496 slength +
" , read \" + std::to_string(length) ;\n";
497 fGC +=
" throw std::runtime_error(err_msg);\n";
499 fGC +=
" for (size_t i = 0; i < length; ++i)\n";
500 fGC +=
" f >> " + tensor_name +
"[i];\n";
503 fGC +=
" f.close();\n";
509 fGC +=
" std::unique_ptr<TFile> rootFile(TFile::Open(filename.c_str(), \"READ\"));\n";
510 fGC +=
" if (!rootFile->IsOpen()) {\n";
511 fGC +=
" throw std::runtime_error(\"tmva-sofie failed to open ROOT file for input weights\");\n";
514 std::string dirName =
fName +
"_weights";
515 fGC +=
" if (!rootFile->GetKey(\"" + dirName +
"\")) {\n";
516 fGC +=
" throw std::runtime_error(\"tmva-sofie failed to open ROOT directory for input weights\");\n";
521 std::string tensor_name =
"tensor_" + i.first;
523 fGC +=
" fTensor_" + i.first +
" = *reinterpret_cast<std::vector<float>*>(rootFile->Get(\"";
524 fGC += dirName +
"/" + tensor_name +
"\"));\n";
526 fGC +=
" fTensor_" + i.first +
" = *reinterpret_cast<std::vector<double>*>(rootFile->Get(\"";
527 fGC += dirName + +
"/" + tensor_name +
"\"));\n";
529 fGC +=
" fTensor_" + i.first +
" = *reinterpret_cast<std::vector<int64_t>*>(rootFile->Get(\"";
530 fGC += dirName +
"/" + tensor_name +
"\"));\n";
540 std::string fileExtension;
543 fileExtension =
".dat";
546 fileExtension =
".root";
549 fileExtension =
".dat";
561 throw std::runtime_error(
"SOFIE-GNN yet not supports writing to a ROOT file.");
565 std::string dirName =
fName +
"_weights";
567 if (outputFile->GetKey(dirName.c_str()))
568 outputFile->rmdir(dirName.c_str());
570 auto outputDir = outputFile->mkdir(dirName.c_str());
573 std::string tensorName =
"tensor_" + item.first;
577 const std::shared_ptr<void> ptr = item.second.fData;
578 const float*
data = (std::static_pointer_cast<float>(item.second.fData)).get();
580 outputDir->WriteObjectAny(&tensorDataVector,
"std::vector<float>", tensorName.c_str());
583 const std::shared_ptr<void> ptr = item.second.fData;
584 const double*
data = (std::static_pointer_cast<double>(item.second.fData)).get();
586 outputDir->WriteObjectAny(&tensorDataVector,
"std::vector<double>", tensorName.c_str());
589 const std::shared_ptr<void> ptr = item.second.fData;
590 const int64_t*
data = (std::static_pointer_cast<int64_t>(item.second.fData)).get();
592 outputDir->WriteObjectAny(&tensorDataVector,
"std::vector<int64_t>", tensorName.c_str());
595 outputFile->Write(
filename.c_str());
610 std::runtime_error(
"tmva-sofie failed to open file for tensor weight data");
614 for (
auto &dim : i.second.fShape) {
617 std::string tensor_name =
"tensor_" + i.first;
618 f << tensor_name <<
" " <<
length <<
"\n";
619 const float *
data = (std::static_pointer_cast<float>(i.second.fData)).get();
620 for (
size_t idx = 0; idx <
length - 1; idx++) {
621 f << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data[idx] <<
" ";
623 f << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data[
length - 1];
627 long curr_pos =
f.tellp();
636 std::cout <<
"Model requires following inputs:\n";
638 std::cout <<
"Parameterised Tensor name: " << inputInfo.first <<
"\t";
640 std::cout <<
"shape: [";
641 for (
size_t i = 0; i < inputInfo.second.shape.size(); i++) {
642 if (inputInfo.second.shape[i].isParam) {
643 std::cout << inputInfo.second.shape[i].param;
645 std::cout << inputInfo.second.shape[i].dim ;
647 if (i < inputInfo.second.shape.size() - 1) std::cout <<
",";
649 std::cout <<
"]" << std::endl;
653 std::cout <<
"Fully Specified Tensor name: " << inputInfo.first <<
"\t";
655 std::cout <<
"shape: [";
656 for (
size_t i = 0; i < inputInfo.second.shape.size(); i++) {
657 std::cout << inputInfo.second.shape[i];
658 if (i < inputInfo.second.shape.size() - 1) std::cout <<
",";
660 std::cout <<
"]" << std::endl;
666 std::cout <<
"Model initialized the following tensors:\n";
668 std::cout <<
"Tensor name: \"" << it.first <<
"\"\t";
670 std::cout <<
"shape: [";
671 for (
size_t i = 0; i < it.second.fShape.size(); i++) {
672 std::cout << it.second.fShape[i];
673 if (i < it.second.fShape.size() - 1) std::cout <<
",";
675 std::cout <<
"]" << std::endl;
680 std::cout <<
"Model specify the following intermediate tensors:\n";
682 std::cout <<
"Tensor name: \"" << it.first <<
"\"\t";
684 std::cout <<
"shape: [";
685 for (
size_t i = 0; i < it.second.shape.size(); i++) {
686 std::cout << it.second.shape[i];
687 if (i < it.second.shape.size() - 1) std::cout <<
",";
689 std::cout <<
"]" << std::endl;
694 std::cout <<
"Model specify the following output tensors:\n";
696 std::cout <<
"Tensor name: \"" << it <<
"\"\t";
704 std::cout <<
"Tensor " <<
name <<
" not found in model's intialized tensor list" << std::endl;
708 std::cout <<
"Tensor name: " << it->first <<
"\t";
711 std::cout <<
"shape: [";
712 for (
size_t i = 0; i < it->second.fShape.size(); i++) {
713 std::cout << it->second.fShape[i];
714 length *= it->second.fShape[i];
715 if (i < it->second.fShape.size() - 1) std::cout <<
",";
717 std::cout <<
"]" << std::endl;
718 bool ellipsis =
true;
724 std::cout <<
"data: [" << std::endl;
726 auto converted_data = std::static_pointer_cast<float>(it->second.fData).get();
727 for (
int i =0; i < n_print; i++) {
728 std::cout << converted_data[i];
729 if (i < n_print - 1) std::cout <<
" ,";
732 if (ellipsis) std::cout <<
", ...";
733 std::cout <<
"]" << std::endl;
763 i->second.CastPersistentToShared();
768 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.
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
void GenerateHeaderInfo(std::string &hgname)
std::unordered_set< std::string > fNeededBlasRoutines
void OutputGenerated(std::string filename="", bool append=false)
std::unordered_set< std::string > fNeededStdLib
WeightFileType fWeightFile
void AddBlasRoutines(std::vector< std::string > routines)
void AddNeededStdLib(std::string libname)
void AddOutputTensorNameList(std::vector< std::string > outputtensornames)
const ETensorType & GetTensorType(std::string name)
void GenerateIntermediateTensorInfo()
void PrintIntermediateTensors()
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape)
void PrintOutputTensors()
bool CheckIfTensorAlreadyExist(std::string tensor_name)
std::vector< std::unique_ptr< ROperator > > fOperators
void OutputGenerated(std::string filename="", bool append=false)
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 AddInputTensorName(std::string name)
std::vector< std::string > fOutputTensorNames
bool IsInitializedTensor(const std::string &name) const
void PrintInitializedTensors()
void AddOperator(std::unique_ptr< ROperator > op, int order_execution=-1)
void HeadInitializedTensors(std::string name, int n_print=50)
const std::vector< size_t > & GetTensorShape(std::string name)
long WriteInitializedTensorsToFile(std::string filename="")
void Generate(std::underlying_type_t< Options > options, int batchSize=1, long pos=0)
std::unordered_map< std::string, InputTensorInfo > fInputTensorInfos
std::shared_ptr< void > GetInitializedTensorData(std::string tensor_name)
void ReadInitializedTensorsFromFile(long)
void GenerateInitializedTensorInfo()
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)
void PrintRequiredInputTensors()
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
std::string Clean_name(std::string input_tensor_name)
std::string ConvertShapeToString(std::vector< size_t > shape)
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