Logo ROOT  
Reference Guide
RModel.cxx
Go to the documentation of this file.
1#include <limits>
2#include <algorithm>
3#include <cctype>
4
5#include "TMVA/RModel.hxx"
7
8
9
10
11namespace TMVA{
12namespace Experimental{
13namespace SOFIE{
14
15 std::underlying_type_t<Options> operator|(Options opA, Options opB) {
16 return static_cast<std::underlying_type_t<Options>>(opA) | static_cast<std::underlying_type_t<Options>>(opB);
17 }
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);
20 }
21
23 fInputTensorInfos = std::move(other.fInputTensorInfos);
24 fReadyInputTensorInfos = std::move(other.fReadyInputTensorInfos);
25 fOutputTensorNames = other.fOutputTensorNames;
26 fInputTensorNames = other.fInputTensorNames;
27 fOperators = std::move(other.fOperators);
28 fInitializedTensors = std::move(other.fInitializedTensors);
29 fIntermediateTensorInfos = std::move(other.fIntermediateTensorInfos);
30 fName = other.fName;
31 fFileName = other.fFileName;
32 fParseTime = other.fParseTime;
33 fGC = other.fGC;
34 fNeededBlasRoutines = other.fNeededBlasRoutines;
35 fNeededStdLib = other.fNeededStdLib;
36 }
37
39 fInputTensorInfos = std::move(other.fInputTensorInfos);
40 fReadyInputTensorInfos = std::move(other.fReadyInputTensorInfos);
41 fOutputTensorNames = other.fOutputTensorNames;
42 fInputTensorNames = other.fInputTensorNames;
43 fOperators = std::move(other.fOperators);
44 fInitializedTensors = std::move(other.fInitializedTensors);
45 fIntermediateTensorInfos = std::move(other.fIntermediateTensorInfos);
46 fName = other.fName;
47 fFileName = other.fFileName;
48 fParseTime = other.fParseTime;
49 fGC = other.fGC;
50 fNeededBlasRoutines = other.fNeededBlasRoutines;
51 fNeededStdLib = other.fNeededStdLib;
52 return *this;
53 }
54
55 RModel::RModel(std::string name, std::string parsedtime): fFileName (name), fParseTime(parsedtime) {
56 fName = fFileName.substr(0, fFileName.rfind("."));
57 }
58
59 const std::vector<size_t>& RModel::GetTensorShape(std::string name){
60 auto f = fReadyInputTensorInfos.find(name);
61 if (f != fReadyInputTensorInfos.end()){
62 return f->second.shape;
63 }
64 auto f2 = fInitializedTensors.find(name);
65 if (f2 != fInitializedTensors.end()){
66 return f2->second.fShape;
67 }
68 auto f3 = fInputTensorInfos.find(name);
69 if (f3 != fInputTensorInfos.end()){
70 throw std::runtime_error("TMVA SOFIE tensor [" + name + "] is an input tensor with unspecified dimension parameter");
71 }
72 auto f4 = fIntermediateTensorInfos.find(name);
73 if (f4 != fIntermediateTensorInfos.end()){
74 return f4->second.shape;
75 }
76
77 throw std::runtime_error("TMVA SOFIE tensor [" + name + "] for which the shape is requested is not found");
78 }
79
81 auto f = fReadyInputTensorInfos.find(name);
82 if (f != fReadyInputTensorInfos.end()){
83 return f->second.type;
84 }
85 auto f2 = fInitializedTensors.find(name);
86 if (f2 != fInitializedTensors.end()){
87 return f2->second.fType;
88 }
89 auto f3 = fInputTensorInfos.find(name);
90 if (f3 != fInputTensorInfos.end()){
91 return f3->second.type;
92 }
93 auto f4 = fIntermediateTensorInfos.find(name);
94 if (f4 != fIntermediateTensorInfos.end()){
95 return f4->second.type;
96 }
97
98 throw std::runtime_error("TMVA SOFIE tensor [" + name + "] for which the type is requested is not found");
99 }
100
101 bool RModel::CheckIfTensorAlreadyExist(std::string tensor_name){
102 if (fReadyInputTensorInfos.find(tensor_name) != fReadyInputTensorInfos.end()) return true;
103 if (fInitializedTensors.find(tensor_name) != fInitializedTensors.end()) return true;
104 if (fIntermediateTensorInfos.find(tensor_name) != fIntermediateTensorInfos.end()) return true;
105 return false;
106 }
107
108 void RModel::AddInputTensorInfo(std::string input_name, ETensorType type, std::vector<Dim> shape){
109 input_name = UTILITY::Clean_name(input_name);
110 if (CheckIfTensorAlreadyExist(input_name)){
111 throw std::runtime_error("TMVA-SOFIE: input tensor with name " + input_name + " already exists \n");
112 }
113
114 InputTensorInfo inputInfo { type, shape };
115 fInputTensorInfos[input_name] = inputInfo;
116 }
117
118 void RModel::AddInputTensorInfo(std::string input_name, ETensorType type, std::vector<size_t> shape){
119 input_name = UTILITY::Clean_name(input_name);
120 if (CheckIfTensorAlreadyExist(input_name)){
121 throw std::runtime_error("TMVA-SOFIE: input tensor with name " + input_name + " already exists \n");
122 }
123 TensorInfo inputInfo { type, shape };
124 fReadyInputTensorInfos[input_name] = inputInfo;
125 }
126
127 void RModel::AddInputTensorName(std::string input_name) {
128 fInputTensorNames.push_back(UTILITY::Clean_name(input_name));
129 }
130
131 void RModel::AddOperator(std::unique_ptr<ROperator> op, int order_execution){
132 AddBlasRoutines(op->GetBlasRoutines());
133 auto libs = op->GetStdLibs();
134 for (auto& stdlib : libs) {
135 AddNeededStdLib(stdlib);
136 }
137 if (order_execution >= 0) {
138 fOperators.insert(fOperators.begin() + order_execution, std::move(op));
139 }else{
140 fOperators.push_back(std::move(op));
141 }
142 }
143
144 void RModel::AddInitializedTensor(std::string tensor_name, ETensorType type, std::vector<std::size_t> shape, std::shared_ptr<void> data){
145 tensor_name = UTILITY::Clean_name(tensor_name);
146 //NB: own data
147 if (CheckIfTensorAlreadyExist(tensor_name)){
148 throw std::runtime_error("TMVA-SOFIE: initialized tensor with name " + tensor_name + " already exists \n");
149 }
150 InitializedTensor new_tensor {type, shape, data};
151 fInitializedTensors[tensor_name] = new_tensor;
152
153 }
154
155 bool RModel::IsInitializedTensor(const std::string& tensorName) const {
156 std::string name = UTILITY::Clean_name(tensorName);
157 return fInitializedTensors.find(name) != fInitializedTensors.end();
158 }
159
160 void RModel::AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector<std::size_t> shape){
161 tensor_name = UTILITY::Clean_name(tensor_name);
162 if (CheckIfTensorAlreadyExist(tensor_name)){
163 throw std::runtime_error("TMVA-SOFIE: intermediate tensor with name " + tensor_name + " already exists \n");
164 }
165 TensorInfo new_tensor {type, shape};
166 fIntermediateTensorInfos[tensor_name] = new_tensor;
167 }
168
169 void RModel::AddOutputTensorNameList(std::vector<std::string> outputtensornames){
170 for(auto& it : outputtensornames){
172 }
173 }
174
175 void RModel::UpdateOutputTensorList(std::vector<std::string> curr_output_tensors, std::vector<std::string> new_output_tensors){
176 for(auto& it:curr_output_tensors){
177 fOutputTensorNames.erase(std::remove(fOutputTensorNames.begin(), fOutputTensorNames.end(), it), fOutputTensorNames.end());
178 }
179 fOutputTensorNames.insert(fOutputTensorNames.end(), new_output_tensors.begin(), new_output_tensors.end());
180 }
181
182 void RModel::UpdateInitializedTensor(std::string tensor_name, ETensorType type, std::vector<std::size_t> shape, std::shared_ptr<void> data){
183 tensor_name = UTILITY::Clean_name(tensor_name);
184 if (!CheckIfTensorAlreadyExist(tensor_name)){
185 throw std::runtime_error("TMVA-SOFIE: tensor " + tensor_name + " not found when trying to update it");
186 }
187 InitializedTensor new_tensor {type, shape, data};
188 fInitializedTensors[tensor_name] = new_tensor;
189 }
190
191 std::shared_ptr<void> RModel::GetInitializedTensorData(std::string tensor_name){
192 auto f = fInitializedTensors.find(tensor_name);
193 if (f == fInitializedTensors.end()){
194 throw std::runtime_error("TMVA-SOFIE: tensor " + tensor_name + " not found when trying to get its data");
195 }else{
196 return f->second.fData;
197 }
198 }
199
200 void RModel::Initialize(int batchSize){
201 // check if there are only parametrized input tensor and convert in
202 // ready input tensor according to batch size
203 // convert parametric shape to a dimensional shape
205 if (fReadyInputTensorInfos.size() != fInputTensorNames.size()) {
206 if ( fReadyInputTensorInfos.size() + fInputTensorInfos.size() != fInputTensorNames.size())
207 throw std::runtime_error("TMVA-SOFIE: RModel::Initializes: invalid inputs");
208 for (auto & input : fInputTensorInfos) {
209 std::vector<size_t> shape;
210 shape.reserve(input.second.shape.size());
211 for (auto & d : input.second.shape){
212 if (d.isParam)
213 shape.push_back(batchSize);
214 else
215 shape.push_back(d.dim);
216 }
217 AddInputTensorInfo(input.first, input.second.type, shape);
218 }
219 }
220 // check if there are initialized tensors to write in a weight file
221 // support for the time being only wheight of FLOAT type
222 if (fUseWeightFile) {
223 bool modelHasWeights = false;
224 for (auto& i: fInitializedTensors){
225 if (i.second.fType == ETensorType::FLOAT) {
226 modelHasWeights = true;
227 break;
228 }
229 }
230 if (!modelHasWeights) fUseWeightFile = false;
231 }
232
233
234 for (auto& i : fOperators){
235 //std::cout << "initialize operator " << typeid(*i).name() << std::endl;
236 i->Initialize(*this);
237 }
238 }
239
240 void RModel::Generate(std::underlying_type_t<Options> options, int batchSize){
241 // session flag is used in operator initialize
242 if (static_cast<std::underlying_type_t<Options>>(Options::kNoSession) & options)
243 fUseSession = false;
244 if (static_cast<std::underlying_type_t<Options>>(Options::kNoWeightFile) & options)
245 fUseWeightFile = false;
246 if (fUseWeightFile && !fUseSession) {
247 throw std::runtime_error("TMVA-SOFIE: RModel::Generate: cannot use a separate weight file without generating a Session class");
248 }
249 fGC.clear();
250 Initialize(batchSize);
251 fGC += ("//Code generated automatically by TMVA for Inference of Model file [" + fFileName + "] at [" + fParseTime.substr(0, fParseTime.length()-1) +"] \n");
252 // add header guards
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";
258 for (auto& i: fNeededStdLib) {
259 fGC += "#include<" + i + ">\n";
260 }
261 for (auto& i: fCustomOpHeaders) {
262 fGC += "#include \"" + i + "\"\n";
263 }
264 // for the session we need to include SOFIE_Common functions
265 //needed for convolution operator (need to add a flag)
266 fGC += "#include \"TMVA/SOFIE_common.hxx\"\n";
267 if (fUseWeightFile)
268 fGC += "#include <fstream>\n";
269
270 fGC += "\nnamespace TMVA_SOFIE_" + fName + "{\n";
271 if (!fNeededBlasRoutines.empty()) {
272 fGC += ("namespace BLAS{\n");
273 for (auto &routine : fNeededBlasRoutines) {
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");
286 }
287 }
288 fGC += ("}//BLAS\n");
289 }
290 if (fUseSession) {
291 fGC += "struct Session {\n";
292 }
293 for (auto& i: fInitializedTensors){
294 if (i.second.fType == ETensorType::FLOAT){
295 size_t length = 1;
296 for (auto & dim: i.second.fShape){
297 length *= dim;
298 }
299 if (!fUseWeightFile) {
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] << ", ";
305 }
306 floats << std::setprecision(std::numeric_limits<float>::max_digits10) << data.get()[length-1];
307 fGC += floats.str();
308 fGC += "};\n";
309 }
310 else {
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";
313 }
314
315 }
316 }
317 for (auto&i: fIntermediateTensorInfos){
318 size_t length = ConvertShapeToLength(i.second.shape);
319 if (i.second.type == ETensorType::FLOAT){
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";
322 }
323 if (i.second.type == ETensorType::DOUBLE){
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";
326 }
327 if (i.second.type == ETensorType::INT64){
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";
330 }
331 }
332 if (fUseSession) {
333 // add here specific operator code that needs to define session data members
334 fGC += "\n";
335 for (size_t id = 0; id < fOperators.size(); id++) {
336 std::string opName = std::to_string(id);
337 fGC += fOperators[id]->GenerateSessionMembersCode(opName);
338 }
339 fGC += "\n";
340 // here add initialization and reading of weight tensors
341 if (fUseWeightFile) {
342 fGC += "Session(std::string filename =\"\") {\n";
343 fGC += " if (filename.empty()) filename = \"" + fName + ".dat\";\n";
345 //fUseWeightFile = fUseWeightFile;
346 } else {
347 // no need to pass weight file since it is not used
348 // keep passing a string for compatibility
349 fGC += "Session(std::string = \"\") {\n";
350 }
351 // add here initialization code
352 for (size_t id = 0; id < fOperators.size() ; id++){
353 fGC += fOperators[id]->GenerateInitCode();
354 }
355 fGC += "}\n\n";
356 }
357
358 size_t outputSize = fOutputTensorNames.size();
359 // assume output types are all the same
360 std::string outputType;
361 if (outputSize == 1) {
363 if (f == fIntermediateTensorInfos.end()){
364 throw std::runtime_error("TMVA-SOFIE: output tensor " + fOutputTensorNames[0] + " not found when trying to get its info");
365 }else{
366 outputType = ConvertTypeToString(f->second.type);
367 fGC += "std::vector<" + outputType + "> ";
368 }
369 } else {
370 std::vector<ETensorType> outputTensorsTypes(outputSize);
371 for (size_t i = 0; i < outputSize; i++) {
373 if (f == fIntermediateTensorInfos.end()) {
374 throw std::runtime_error("TMVA-SOFIE: output tensor " + fOutputTensorNames[i]
375 + " not found when trying to get its info");
376 } else {
377 outputTensorsTypes[i] = f->second.type;
378 }
379 }
380 // assume all output types are the same
381 outputType = ConvertTypeToString(outputTensorsTypes[0]);
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.");
385 }
386 }
387 fGC += "std::vector<std::vector<" + outputType + ">> ";
388 }
389
390 fGC += "infer(";
391 for(size_t i = 0; i<fInputTensorNames.size(); ++i){
393 case ETensorType::FLOAT :{
394 fGC += "float* tensor_" + fInputTensorNames[i] + ",";
395 break;
396 }
397 case ETensorType::INT32 :{
398 fGC += "int32_t* tensor_" + fInputTensorNames[i] + ",";
399 break;
400 }
401 case ETensorType::INT64 :{
402 fGC += "int64_t* tensor_" + fInputTensorNames[i] + ",";
403 break;
404 }
405 case ETensorType::DOUBLE :{
406 fGC += "double* tensor_" + fInputTensorNames[i] + ",";
407 break;
408 }
409 default: {
410 throw std::runtime_error("TMVA-SOFIE: input tensor " + fInputTensorNames[i] + " is of a data type which is not yet supported.");
411 }
412 }
413 }
414 fGC.pop_back(); //remove last ","
415 fGC += "){\n";
416
417 const std::string SP = " ";
418
419 for (size_t id = 0; id < fOperators.size() ; id++){
420 fGC+= (fOperators[id]->Generate(std::to_string(id)));
421 }
422 if (outputSize == 1) {
423 size_t outputLength = ConvertShapeToLength(GetTensorShape(fOutputTensorNames[0]));
424
425 fGC += SP + "std::vector<" + outputType + "> ret (tensor_" + fOutputTensorNames[0] + ", tensor_" + fOutputTensorNames[0] + " + " +
426 std::to_string(outputLength) + ");\n";
427 } else {
428 for (size_t i = 0; i < outputSize; i++) {
429 if (!fOutputTensorNames[i].empty()) {
430 size_t outputLength = ConvertShapeToLength(GetTensorShape(fOutputTensorNames[i]));
431 fGC += SP + "std::vector<" + outputType + "> ret_";
432 fGC += std::to_string(i);
433 fGC += " (tensor_" + fOutputTensorNames[i] + ", tensor_" + fOutputTensorNames[i] + " + " +
434 std::to_string(outputLength) + ");\n";
435 }
436 }
437 fGC += SP + "std::vector<std::vector<" + outputType + ">> ret({";
438 for (size_t i = 0; i < outputSize; i++) {
439 if (fOutputTensorNames[i].empty()) {
440 fGC += "{}";
441 } else {
442 fGC += "ret_";
443 fGC += std::to_string(i);
444 }
445 if (i < outputSize - 1) {
446 fGC += ",";
447 }
448 }
449 fGC += "});\n";
450 }
451 fGC += SP + "return ret;\n";
452 fGC += "}\n";
453 if (fUseSession) {
454 fGC += "};\n";
455 }
456 fGC += ("} //TMVA_SOFIE_" + fName + "\n");
457 fGC += "\n#endif // " + hgname + "\n";
458 }
459
461 // generate the code to read initialized tensors from a text data file
462 if (fInitializedTensors.empty()) return;
463
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";
468 fGC += " }\n";
469 fGC += " std::string tensor_name;\n";
470 fGC += " int length;\n";
471
472 //loop on tensors and parse the file
473 for (auto& i: fInitializedTensors){
474 if (i.second.fType == ETensorType::FLOAT){
475 size_t length = 1;
476 for (auto & dim: i.second.fShape){
477 length *= dim;
478 }
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";
486 fGC += " }\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";
491 fGC += " }\n";
492 fGC += " for (int i =0; i < length; ++i) \n";
493 fGC += " f >> " + tensor_name + "[i];\n";
494 }
495 }
496 fGC += " f.close();\n";
497 }
498
500 // write the initialized tensors in a text file
501 if (filename == ""){
502 filename = fName + ".data";
503 }
504
505 std::ofstream f;
506 f.open(filename);
507 if (!f.is_open()){
508 throw std::runtime_error("tmva-sofie failed to open file for tensor weight data");
509 }
510 for (auto& i: fInitializedTensors){
511 if (i.second.fType == ETensorType::FLOAT){
512 size_t length = 1;
513 for (auto &dim : i.second.fShape) {
514 length *= dim;
515 }
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] << " ";
521 }
522 f << std::setprecision(std::numeric_limits<float>::max_digits10) << data[length - 1];
523 f << "\n";
524 }
525 }
526 f.close();
527 }
528
530 std::cout << "Model requires following inputs:\n";
531 for (auto& inputInfo: fInputTensorInfos){
532 std::cout << "Parameterised Tensor name: " << inputInfo.first << "\t";
533 std::cout << "type: " << ConvertTypeToString(inputInfo.second.type) << "\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;
538 }else{
539 std::cout << inputInfo.second.shape[i].dim ;
540 }
541 if (i < inputInfo.second.shape.size() - 1) std::cout << ",";
542 }
543 std::cout << "]" << std::endl;
544 }
545
546 for (auto& inputInfo: fReadyInputTensorInfos){
547 std::cout << "Fully Specified Tensor name: " << inputInfo.first << "\t";
548 std::cout << "type: " << ConvertTypeToString(inputInfo.second.type) << "\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 << ",";
553 }
554 std::cout << "]" << std::endl;
555 }
556
557 }
558
560 std::cout << "Model initialized the following tensors:\n";
561 for (auto& it: fInitializedTensors){
562 std::cout << "Tensor name: \"" << it.first << "\"\t";
563 std::cout << "type: " << ConvertTypeToString(it.second.fType) << "\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 << ",";
568 }
569 std::cout << "]" << std::endl;
570 }
571 }
572
574 std::cout << "Model specify the following intermediate tensors:\n";
575 for (auto& it: fIntermediateTensorInfos){
576 std::cout << "Tensor name: \"" << it.first << "\"\t";
577 std::cout << "type: " << ConvertTypeToString(it.second.type) << "\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 << ",";
582 }
583 std::cout << "]" << std::endl;
584 }
585 }
586
587 void RModel::HeadInitializedTensors(std::string name, int n_print){
588 auto it = fInitializedTensors.find(name);
589 if (it == fInitializedTensors.end()){
590 std::cout << "Tensor " << name << " not found in model's intialized tensor list" << std::endl;
591 return;
592 }
593
594 std::cout << "Tensor name: " << it->first << "\t";
595 std::cout << "type: " << ConvertTypeToString(it->second.fType) << "\t";
596 int length =1;
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 << ",";
602 }
603 std::cout << "]" << std::endl;
604 bool ellipsis = true;
605 if (n_print > length){
606 n_print = length;
607 ellipsis = false;
608 }
609
610 std::cout << "data: [" << std::endl;
611 //switch(it->second.type){
612 // case ETensorType::FLOAT : {
613 if (it->second.fType == ETensorType::FLOAT) {
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 << " ,";
618 }
619 // break;
620 // }
621 }
622 if (ellipsis) std::cout << ", ...";
623 std::cout << "]" << std::endl;
624
625 }
626
628 if (filename == ""){
629 filename = fName + ".hxx";
630 }
631 std::ofstream f;
632 f.open(filename);
633 if (!f.is_open()){
634 throw std::runtime_error("tmva-sofie failed to open file for output generated inference code");
635 }
636 f << fGC;
637 f.close();
638
639 // write weights in a text file
640 size_t pos = filename.find(".hxx");
641 filename.replace(pos,4,".dat");
643 }
644
646 if (R__b.IsReading()) {
647 RModel::Class()->ReadBuffer(R__b, this);
648 for(auto i=RModel::fInitializedTensors.begin(); i!=RModel::fInitializedTensors.end();++i){
649 i->second.CastPersistentToShared();
650 }
651 }
652 else {
653 for(auto i=RModel::fInitializedTensors.begin(); i!=RModel::fInitializedTensors.end();++i){
654 i->second.CastSharedToPersistent();
655 }
656 RModel::Class()->WriteBuffer(R__b, this);
657 }
658 }
659
660}//SOFIE
661}//Experimental
662}//TMVA
#define d(i)
Definition: RSha256.hxx:102
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
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
char name[80]
Definition: TGX11.cxx:110
Buffer base class used for serializing objects.
Definition: TBuffer.h:43
Bool_t IsReading() const
Definition: TBuffer.h:86
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.
Definition: TClass.cxx:6747
Int_t WriteBuffer(TBuffer &b, void *pointer, const char *info="")
Function called by the Streamer functions to serialize object at p to buffer b.
Definition: TClass.cxx:6768
void AddOutputTensorNameList(std::vector< std::string > outputtensornames)
Definition: RModel.cxx:169
const ETensorType & GetTensorType(std::string name)
Definition: RModel.cxx:80
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape)
Definition: RModel.cxx:160
std::unordered_set< std::string > fNeededBlasRoutines
Definition: RModel.hxx:50
bool CheckIfTensorAlreadyExist(std::string tensor_name)
Definition: RModel.cxx:101
std::vector< std::unique_ptr< ROperator > > fOperators
Definition: RModel.hxx:42
void AddInputTensorInfo(std::string input_name, ETensorType type, std::vector< Dim > shape)
Definition: RModel.cxx:108
void Initialize(int batchSize=1)
Definition: RModel.cxx:200
std::unordered_map< std::string, TensorInfo > fIntermediateTensorInfos
Definition: RModel.hxx:38
std::unordered_map< std::string, TensorInfo > fReadyInputTensorInfos
Definition: RModel.hxx:36
void AddInitializedTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape, std::shared_ptr< void > data)
Definition: RModel.cxx:144
RModel & operator=(RModel &&other)
Definition: RModel.cxx:38
void AddBlasRoutines(std::vector< std::string > routines)
Definition: RModel.hxx:83
void AddInputTensorName(std::string name)
Definition: RModel.cxx:127
std::vector< std::string > fOutputTensorNames
Definition: RModel.hxx:39
void AddNeededStdLib(std::string libname)
Definition: RModel.hxx:88
bool IsInitializedTensor(const std::string &name) const
Definition: RModel.cxx:155
std::unordered_set< std::string > fNeededStdLib
Definition: RModel.hxx:53
void AddOperator(std::unique_ptr< ROperator > op, int order_execution=-1)
Definition: RModel.cxx:131
void HeadInitializedTensors(std::string name, int n_print=50)
Definition: RModel.cxx:587
void OutputGenerated(std::string filename="")
Definition: RModel.cxx:627
const std::vector< size_t > & GetTensorShape(std::string name)
Definition: RModel.cxx:59
std::unordered_map< std::string, InputTensorInfo > fInputTensorInfos
Definition: RModel.hxx:35
std::shared_ptr< void > GetInitializedTensorData(std::string tensor_name)
Definition: RModel.cxx:191
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
Definition: RModel.cxx:645
void Generate(std::underlying_type_t< Options > options, int batchSize=1)
Definition: RModel.cxx:240
void WriteInitializedTensorsToFile(std::string filename="")
Definition: RModel.cxx:499
std::vector< std::string > fInputTensorNames
Definition: RModel.hxx:40
std::unordered_map< std::string, InitializedTensor > fInitializedTensors
Definition: RModel.hxx:37
void UpdateInitializedTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape, std::shared_ptr< void > data)
Definition: RModel.cxx:182
void UpdateOutputTensorList(std::vector< std::string > curr_output_tensor, std::vector< std::string > modify_output_tensor)
Definition: RModel.cxx:175
std::unordered_set< std::string > fCustomOpHeaders
Definition: RModel.hxx:54
static constexpr double second
std::string Clean_name(std::string input_tensor_name)
std::string ConvertTypeToString(ETensorType type)
std::underlying_type_t< Options > operator|(Options opA, Options opB)
Definition: RModel.cxx:15
std::size_t ConvertShapeToLength(std::vector< size_t > shape)
create variable transformations