13namespace Experimental {
17 return static_cast<std::underlying_type_t<Options>
>(opA) |
static_cast<std::underlying_type_t<Options>
>(opB);
19std::underlying_type_t<Options>
operator|(std::underlying_type_t<Options> opA,
Options opB) {
20 return opA |
static_cast<std::underlying_type_t<Options>
>(opB);
59 return f->second.shape;
63 return f2->second.shape();
67 throw std::runtime_error(
"TMVA SOFIE tensor [" +
name +
"] is an input tensor with unspecified dimension parameter");
71 return f4->second.shape;
74 throw std::runtime_error(
"TMVA SOFIE tensor [" +
name +
"] is a dynamic tensor. Use GetDynamicTensorShape instead of GetTensorShape");
76 throw std::runtime_error(
"TMVA SOFIE tensor [" +
name +
"] for which the shape is requested is not found");
81 return f->second.shape;
84 return f->second.shape;
94 return f->second.type;
98 return f2->second.type();
102 return f3->second.type;
106 return f4->second.type;
110 return f5->second.type;
113 throw std::runtime_error(
"TMVA SOFIE tensor [" +
name +
"] for which the type is requested is not found");
128 throw std::runtime_error(
"TMVA-SOFIE: input tensor with name " + input_name +
" already exists \n");
138 throw std::runtime_error(
"TMVA-SOFIE: input tensor with name " + input_name +
" already exists \n");
150 auto libs = op->GetStdLibs();
151 for (
auto& stdlib : libs) {
154 if (order_execution >= 0) {
165 throw std::runtime_error(
"TMVA-SOFIE: initialized tensor with name " + tensor_name +
" already exists \n");
189 if (!int_shape.empty())
198 throw std::runtime_error(
"TMVA-SOFIE: intermediate tensor with name " + tensor_name +
" already exists \n");
207 throw std::runtime_error(
"TMVA-SOFIE: intermediate tensor with name " + tensor_name +
" already exists \n");
212 for (
auto &
d : shape) {
217 if (
d.dim !=
size_t(-1)) {
227 for(
auto& it : outputtensornames) {
233 for(
auto& it:curr_output_tensors) {
242 throw std::runtime_error(
"TMVA-SOFIE: tensor " + tensor_name +
" not found when trying to update it");
251 throw std::runtime_error(
"TMVA-SOFIE: tensor " + tensor_name +
" not found when trying to get its data");
253 return f->second.sharedptr();
266 for (
auto &
input : originalInputTensorInfos) {
267 if (verbose) std::cout <<
"looking at the tensor " <<
input.first << std::endl;
274 if (!
input.second.shape.empty()) {
275 auto & d0 =
input.second.shape[0];
277 if (verbose) std::cout <<
"Fix the batch size to " << batchSize << std::endl;
278 d0 =
Dim{
static_cast<size_t>(batchSize)};
281 for (
auto &
d :
input.second.shape) {
282 if (
d.isParam && (
d.param ==
"bs" ||
d.param ==
"batch_size")) {
283 d =
Dim{
static_cast<size_t>(batchSize)};
284 if (verbose) std::cout <<
"Input shape has bs or batch_size as names. Fix the batch size to " << batchSize << std::endl;
291 if (!shape.empty()) {
300 for (
auto &
d :
input.second.shape) {
315 bool modelHasWeights =
false;
318 modelHasWeights =
true;
322 if (!modelHasWeights)
330 std::cout <<
"Initializing operator " << i <<
" " <<
typeid(
r).
name() << std::endl;
332 op->Initialize(*
this);
341 for (
auto & dim: i.second.shape()) {
345 fGC +=
"float tensor_" + i.first +
"[" + std::to_string(
length) +
"] = {";
346 float const *
data = i.second.data<
float>();
347 std::stringstream floats;
348 for (
size_t idx = 0; idx <
length-1; idx++) {
349 floats << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data[idx] <<
", ";
351 floats << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data[
length-1];
356 fGC +=
"std::vector<float> fTensor_" + i.first +
" = std::vector<float>(" + std::to_string(
length) +
");\n";
357 fGC +=
"float * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
366 fGC +=
"\n//--- declare and allocate the intermediate tensors\n";
370 fGC +=
"std::vector<float> fTensor_" + i.first +
" = std::vector<float>(" + std::to_string(
length) +
");\n";
371 fGC +=
"float * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
374 fGC +=
"std::vector<double> fTensor_" + i.first +
" = std::vector<double>(" + std::to_string(
length) +
");\n";
375 fGC +=
"double * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
378 fGC +=
"std::vector<int64_t> fTensor_" + i.first +
" = std::vector<int64_t>(" + std::to_string(
length) +
");\n";
379 fGC +=
"int64_t * tensor_" + i.first +
" = fTensor_" + i.first +
".data();\n";
382 fGC +=
"std::vector<bool> fTensor_" + i.first +
" = std::vector<bool>(" + std::to_string(
length) +
");\n";
389 fGC +=
"//--- declare the dynamic tensors\n";
392 fGC +=
"std::vector<float> fTensor_" + i.first +
";\n";
393 fGC +=
"float * tensor_" + i.first +
" = nullptr;\n";
395 fGC +=
"std::vector<double> fTensor_" + i.first +
";\n";
396 fGC +=
"double * tensor_" + i.first +
" = nullptr;\n";
398 fGC +=
"std::vector<int64_t> fTensor_" + i.first +
";\n";
399 fGC +=
"int64_t * tensor_" + i.first +
" = nullptr;\n";
406 fGC +=
"//---- allocate the intermediate dynamic tensors\n";
407 std::stringstream out;
410 out <<
SP <<
"if (" <<
length <<
" > 0) {\n";
411 out <<
SP <<
SP <<
"fTensor_" << i.first <<
".resize(" <<
length <<
");\n";
412 out <<
SP <<
SP <<
"tensor_" << i.first <<
" = fTensor_" << i.first <<
".data();\n";
423 throw std::runtime_error(
"TMVA-SOFIE: output size=0 are not supported");
425 std::string outputType;
429 if (outputSize == 1) {
430 fGC +=
"std::vector<" + outputType +
"> ";
433 for (
size_t i = 1; i < outputSize; i++) {
435 throw std::runtime_error(
"TMVA-SOFIE: different output tensor types are not supported");
437 fGC +=
"std::vector<std::vector<" + outputType +
">> ";
442 std::unordered_map<std::string, int> inputParams;
448 for (
auto &
d : shape) {
449 std::string pName =
d.param;
451 if (
d.isParam && inputParams.count(pName) == 0) {
452 fGC +=
"size_t " +
d.param +
",";
453 inputParams[pName] = i_input;
459 fGC +=
"float* tensor_" +
name +
",";
463 fGC +=
"int32_t* tensor_" +
name +
",";
467 fGC +=
"int64_t* tensor_" +
name +
",";
471 fGC +=
"double* tensor_" +
name +
",";
475 fGC +=
"bool* tensor_" +
name +
",";
479 throw std::runtime_error(
"TMVA-SOFIE: input tensor " +
name +
480 " is of a data type which is not yet supported.");
489 for (
size_t id = 0;
id <
fOperators.size();
id++) {
493 if (outputSize == 1) {
498 fGC +=
SP +
"return fTensor_" + tensorName +
";\n";
504 fGC +=
SP +
"std::vector<bool> ret (fTensor_" + tensorName +
".begin(), fTensor_" + tensorName +
505 ".begin() + " + outputLength +
");\n";
507 fGC +=
SP +
"std::vector<" + outputType +
"> ret (tensor_" + tensorName +
", tensor_" + tensorName +
" + " +
508 outputLength +
");\n";
510 fGC +=
SP +
"return ret;\n";
514 fGC +=
SP +
"std::vector<std::vector<" + outputType +
">> ret({";
515 for (
size_t i = 0; i < outputSize; i++) {
517 if (!tensorName.empty()) {
519 fGC +=
"fTensor_" + tensorName;
523 fGC +=
"std::vector<bool>(fTensor_" + tensorName +
".begin(), fTensor_" + tensorName +
".begin() + " +
524 outputLength +
");\n";
526 fGC +=
"std::vector<" + outputType +
">(tensor_" + tensorName +
", tensor_" + tensorName +
" + " +
530 if (i < outputSize - 1)
537 fGC +=
SP +
"return ret;\n";
558 std::runtime_error(
"TMVA-SOFIE: RModel::Generate: cannot use a separate weight file without generating a Session class");
561 if (
static_cast<std::underlying_type_t<Options>
>(
Options::kGNN) & options)
572 fGC +=
"struct Session {\n";
582 for (
size_t id = 0;
id <
fOperators.size();
id++) {
583 std::string opName = std::to_string(
id);
589 std::string fileName =
fName;
596 fGC +=
"Session(std::string filename =\"" + fileName +
"\"";
600 fGC +=
"Session(std::string = \"\"";
607 fGC +=
" size_t " +
p.first +
" = " +
p.second;
613 fGC +=
"\n//--- reading weights from file\n";
623 for (
size_t id = 0;
id <
fOperators.size() ;
id++) {
636 fGC += (
"} //TMVA_SOFIE_" +
fName +
"\n");
637 fGC +=
"\n#endif // " + hgname +
"\n";
646 fGC +=
" std::ifstream f;\n";
647 fGC +=
" f.open(filename);\n";
648 fGC +=
" if (!f.is_open()) {\n";
649 fGC +=
" throw std::runtime_error(\"tmva-sofie failed to open file \" + filename + \" for input weights\");\n";
653 fGC +=
" f.seekg(" + std::to_string(pos) +
");\n";
656 fGC +=
" std::string tensor_name;\n";
657 fGC +=
" size_t length;\n";
664 std::string tensor_name =
"tensor_" + i.first;
665 std::string slength = std::to_string(
length);
666 fGC +=
" f >> tensor_name >> length;\n";
667 fGC +=
" if (tensor_name != \"" + tensor_name +
"\" ) {\n";
668 fGC +=
" std::string err_msg = \"TMVA-SOFIE failed to read the correct tensor name; expected name is " +
669 tensor_name +
" , read \" + tensor_name;\n";
670 fGC +=
" throw std::runtime_error(err_msg);\n";
672 fGC +=
" if (length != " + slength +
") {\n";
673 fGC +=
" std::string err_msg = \"TMVA-SOFIE failed to read the correct tensor size; expected size is " +
674 slength +
" , read \" + std::to_string(length) ;\n";
675 fGC +=
" throw std::runtime_error(err_msg);\n";
677 fGC +=
" for (size_t i = 0; i < length; ++i)\n";
678 fGC +=
" f >> " + tensor_name +
"[i];\n";
681 fGC +=
" f.close();\n";
687 fGC +=
" std::unique_ptr<TFile> rootFile(TFile::Open(filename.c_str(), \"READ\"));\n";
688 fGC +=
" if (!rootFile->IsOpen()) {\n";
689 fGC +=
" throw std::runtime_error(\"tmva-sofie failed to open ROOT file for input weights\");\n";
692 std::string dirName =
fName +
"_weights";
693 fGC +=
" if (!rootFile->GetKey(\"" + dirName +
"\")) {\n";
694 fGC +=
" throw std::runtime_error(\"tmva-sofie failed to open ROOT directory for input weights\");\n";
699 std::string tensor_name =
"tensor_" + i.first;
701 fGC +=
" fTensor_" + i.first +
" = *reinterpret_cast<std::vector<float>*>(rootFile->Get(\"";
702 fGC += dirName +
"/" + tensor_name +
"\"));\n";
704 fGC +=
" fTensor_" + i.first +
" = *reinterpret_cast<std::vector<double>*>(rootFile->Get(\"";
705 fGC += dirName + +
"/" + tensor_name +
"\"));\n";
707 fGC +=
" fTensor_" + i.first +
" = *reinterpret_cast<std::vector<int64_t>*>(rootFile->Get(\"";
708 fGC += dirName +
"/" + tensor_name +
"\"));\n";
718 std::string fileExtension;
721 fileExtension =
".dat";
724 fileExtension =
".root";
727 fileExtension =
".dat";
739 throw std::runtime_error(
"SOFIE-GNN yet not supports writing to a ROOT file.");
743 std::string dirName =
fName +
"_weights";
745 if (outputFile->GetKey(dirName.c_str()))
746 outputFile->rmdir(dirName.c_str());
748 auto outputDir = outputFile->mkdir(dirName.c_str());
751 std::string tensorName =
"tensor_" + item.first;
755 const float*
data = item.second.data<
float>();
757 outputDir->WriteObjectAny(&tensorDataVector,
"std::vector<float>", tensorName.c_str());
760 const double*
data = item.second.data<
double>();
762 outputDir->WriteObjectAny(&tensorDataVector,
"std::vector<double>", tensorName.c_str());
765 const int64_t*
data = item.second.data<int64_t>();
767 outputDir->WriteObjectAny(&tensorDataVector,
"std::vector<int64_t>", tensorName.c_str());
770 outputFile->Write(
filename.c_str());
785 std::runtime_error(
"tmva-sofie failed to open file " +
filename +
" for tensor weight data");
789 for (
auto &dim : i.second.shape()) {
792 std::string tensor_name =
"tensor_" + i.first;
793 f << tensor_name <<
" " <<
length <<
"\n";
794 const float *
data = i.second.data<
float>();
795 for (
size_t idx = 0; idx <
length - 1; idx++) {
796 f << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data[idx] <<
" ";
798 f << std::setprecision(std::numeric_limits<float>::max_digits10) <<
data[
length - 1];
802 long curr_pos =
f.tellp();
811 std::cout <<
"Model requires following inputs:\n";
813 std::cout <<
"Parameterised Tensor name: " << inputInfo.first <<
"\t";
815 std::cout <<
"shape: [";
816 for (
size_t i = 0; i < inputInfo.second.shape.size(); i++) {
817 if (inputInfo.second.shape[i].isParam) {
818 std::cout << inputInfo.second.shape[i].param;
820 std::cout << inputInfo.second.shape[i].dim ;
822 if (i < inputInfo.second.shape.size() - 1) std::cout <<
",";
824 std::cout <<
"]" << std::endl;
828 std::cout <<
"Fully Specified Tensor name: " << inputInfo.first <<
"\t";
830 std::cout <<
"shape: [";
831 for (
size_t i = 0; i < inputInfo.second.shape.size(); i++) {
832 std::cout << inputInfo.second.shape[i];
833 if (i < inputInfo.second.shape.size() - 1) std::cout <<
",";
835 std::cout <<
"]" << std::endl;
841 std::cout <<
"Model initialized the following tensors:\n";
843 std::cout <<
"Tensor name: \"" << it.first <<
"\"\t";
845 std::cout <<
"shape: [";
846 for (
size_t i = 0; i < it.second.shape().
size(); i++) {
847 std::cout << it.second.shape()[i];
848 if (i < it.second.shape().size() - 1) std::cout <<
",";
850 std::cout <<
"]" << std::endl;
856 std::cout <<
"Model specify the following intermediate tensors:\n";
858 std::cout <<
"Tensor name: \"" << it.first <<
"\"\t";
860 std::cout <<
"shape: [";
861 for (
size_t i = 0; i < it.second.shape.size(); i++) {
862 std::cout << it.second.shape[i];
863 if (i < it.second.shape.size() - 1) std::cout <<
",";
865 std::cout <<
"]" << std::endl;
871 std::cout <<
"Model specify the following dynamic tensors:\n";
873 std::cout <<
"Tensor name: \"" << it.first <<
"\"\t";
875 std::cout <<
"shape: [";
876 for (
size_t i = 0; i < it.second.shape.size(); i++) {
877 std::cout << it.second.shape[i].GetVal();
878 if (i < it.second.shape.size() - 1) std::cout <<
",";
880 std::cout <<
"]" << std::endl;
886 std::cout <<
"Model specify the following output tensors:\n";
888 std::cout <<
"Tensor name: \"" << it <<
"\"\t";
900 std::cout <<
"Tensor " <<
name <<
" not found in model's initialized tensor list" << std::endl;
904 std::cout <<
"Tensor name: " << it->first <<
"\t";
907 std::cout <<
"shape: [";
908 for (
size_t i = 0; i < it->second.shape().
size(); i++) {
909 std::cout << it->second.shape()[i];
910 length *= it->second.shape()[i];
911 if (i < it->second.shape().size() - 1) std::cout <<
",";
913 std::cout <<
"]" << std::endl;
914 bool ellipsis =
true;
920 std::cout <<
"data: [" << std::endl;
922 auto converted_data = it->second.data<
float>();
923 for (
int i =0; i < n_print; i++) {
924 std::cout << converted_data[i];
925 if (i < n_print - 1) std::cout <<
" ,";
928 if (ellipsis) std::cout <<
", ...";
929 std::cout <<
"]" << std::endl;
955void RModel::Streamer(
TBuffer &R__b) {
957 RModel::Class()->ReadBuffer(R__b,
this);
959 i->second.CastPersistentToShared();
964 i->second.CastSharedToPersistent();
966 RModel::Class()->WriteBuffer(R__b,
this);
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
winID h TVirtualViewer3D TVirtualGLPainter p
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 data
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 r
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.
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)
const ETensorType & GetTensorType(std::string name)
std::unordered_map< std::string, DynamicTensorInfo > fDynamicTensorInfos
bool IsDynamicTensor(const std::string &name) const
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< Dim > dim_shape)
void GenerateIntermediateTensorInfo()
std::vector< Dim > GetDynamicTensorShape(std::string name)
void PrintIntermediateTensors()
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)
std::unordered_map< std::string, TensorInfo > fIntermediateTensorInfos
void AddOutputTensorNameList(std::vector< std::string > output_tensor_names)
std::unordered_map< std::string, TensorInfo > fReadyInputTensorInfos
void AddDynamicTensor(std::string tensor_name, ETensorType type, std::vector< Dim > shape)
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)
void PrintDynamicTensors()
std::vector< std::string > fOutputTensorNames
void GenerateDynamicTensorInfo()
bool IsInitializedTensor(const std::string &name) const
void PrintInitializedTensors()
void AddOperator(std::unique_ptr< ROperator > op, int order_execution=-1)
RModel()=default
Default constructor.
void HeadInitializedTensors(std::string name, int n_print=50)
void Initialize(int batchSize=-1, bool verbose=false)
const std::vector< size_t > & GetTensorShape(std::string name)
bool IsInputTensor(const std::string &name) const
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)
std::unordered_map< std::string, std::string > fShapeParams
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()
std::string Clean_name(std::string input_tensor_name)
std::vector< Dim > ConvertShapeToDim(std::vector< size_t > shape)
Convert shape from integer format to dynamic one (based on Dim)
std::string ConvertDynamicShapeToLength(std::vector< Dim > shape)
std::string ConvertShapeToString(std::vector< size_t > shape)
std::string ConvertTypeToString(ETensorType type)
std::string ConvertDynamicShapeToString(std::vector< Dim > shape)
std::underlying_type_t< Options > operator|(Options opA, Options opB)
std::vector< size_t > ConvertShapeToInt(std::vector< Dim > shape)
Convert shape based on Dim to integer format.
std::size_t ConvertShapeToLength(std::vector< size_t > shape)
create variable transformations