370RModel Parse(std::string
filename, std::vector<std::vector<size_t>> inputShapes, std::vector<ETensorType> inputDTypes){
378 std::string filename_nodir =
filename;
379 if (isep != std::string::npos){
384 if(!std::ifstream(
filename).good()){
385 throw std::runtime_error(
"Model file "+filename_nodir+
" not found!");
389 std::time_t ttime = std::time(0);
390 std::tm* gmt_time = std::gmtime(&ttime);
391 std::string parsetime (std::asctime(gmt_time));
393 RModel rmodel(filename_nodir, parsetime);
401 throw std::runtime_error(
"Can't init global namespace for Python");
404 throw std::runtime_error(
"Can't init local namespace for Python");
411 PyRunString(
"import torch",fGlobalNS,fLocalNS);
412 PyRunString(
"print('Torch Version: '+torch.__version__)",fGlobalNS,fLocalNS);
413 PyRunString(
"from torch.onnx.utils import _model_to_graph",fGlobalNS,fLocalNS);
416 PyRunString(
"globals().update(locals())",fGlobalNS,fLocalNS);
417 PyRunString(
"model.cpu()",fGlobalNS,fLocalNS);
418 PyRunString(
"model.eval()",fGlobalNS,fLocalNS);
421 PyRunString(
"dummyInputs=[]",fGlobalNS,fLocalNS);
422 for(
long unsigned int it=0;it<inputShapes.size();++it){
423 PyRunString(
"inputShape=[]",fGlobalNS,fLocalNS);
424 for(
long unsigned int itr=0;itr<inputShapes[it].size();++itr){
425 PyRunString(
TString::Format(
"inputShape.append(%d)",(
int)inputShapes[it][itr]),fGlobalNS,fLocalNS);
427 PyRunString(
"dummyInputs.append(torch.rand(*inputShape))",fGlobalNS,fLocalNS);
433 PyRunString(
"graph=_model_to_graph(model,dummyInputs)",fGlobalNS,fLocalNS);
437 PyRunString(
"modelData=[]",fGlobalNS,fLocalNS);
440 PyRunString(
"def _node_get(node, key):\n"
441 " sel = node.kindOf(key)\n"
442 " return getattr(node, sel)(key)\n",
443 fGlobalNS, fLocalNS);
444 PyRunString(
"for i in graph[0].nodes():\n"
445 " globals().update(locals())\n"
447 " nodeData['nodeType']=i.kind()\n"
448 " nodeAttributeNames=[x for x in i.attributeNames()]\n"
449 " nodeAttributes={j: _node_get(i, j) for j in nodeAttributeNames}\n"
450 " nodeData['nodeAttributes']=nodeAttributes\n"
451 " nodeInputs=[x for x in i.inputs()]\n"
452 " nodeInputNames=[x.debugName() for x in nodeInputs]\n"
453 " nodeData['nodeInputs']=nodeInputNames\n"
454 " nodeOutputs=[x for x in i.outputs()]\n"
455 " nodeOutputNames=[x.debugName() for x in nodeOutputs]\n"
456 " nodeData['nodeOutputs']=nodeOutputNames\n"
457 " nodeDType=[x.type().scalarType() for x in nodeOutputs]\n"
458 " nodeData['nodeDType']=nodeDType\n"
459 " modelData.append(nodeData)",
460 fGlobalNS, fLocalNS);
462 PyObject* fPModel = PyDict_GetItemString(fLocalNS,
"modelData");
463 Py_ssize_t fPModelSize = PyList_Size(fPModel);
465 std::string fNodeType;
468 for(
Py_ssize_t fModelIterator=0;fModelIterator<fPModelSize;++fModelIterator){
469 fNode = PyList_GetItem(fPModel,fModelIterator);
470 fNodeType = PyStringAsString(PyDict_GetItemString(fNode,
"nodeType"));
473 if(fNodeType ==
"onnx::Gemm"){
476 else if(fNodeType ==
"onnx::Selu" || fNodeType ==
"onnx::Sigmoid"){
479 else if (fNodeType ==
"onnx::Conv") {
491 PyRunString(
"weightNames=[k for k in graph[1].keys()]",fGlobalNS,fLocalNS);
492 PyRunString(
"weightValues=[v.numpy() for v in graph[1].values()]",fGlobalNS,fLocalNS);
493 PyRunString(
"weightShapes=[list(v.shape) for v in weightValues]",fGlobalNS,fLocalNS);
494 PyRunString(
"weightBytes=[v.tobytes() for v in weightValues]",fGlobalNS,fLocalNS);
495 PyRunString(
"weightDTypes=[v.type()[6:-6] for v in graph[1].values()]",fGlobalNS,fLocalNS);
496 PyObject* fPWeightNames = PyDict_GetItemString(fLocalNS,
"weightNames");
497 PyObject* fPWeightShapes = PyDict_GetItemString(fLocalNS,
"weightShapes");
498 PyObject* fPWeightBytes = PyDict_GetItemString(fLocalNS,
"weightBytes");
499 PyObject* fPWeightDTypes = PyDict_GetItemString(fLocalNS,
"weightDTypes");
500 std::string fWeightName;
502 std::vector<std::size_t> fWeightShape;
503 std::size_t fWeightSize;
505 for(
Py_ssize_t weightIter=0; weightIter<PyList_Size(fPWeightNames);++weightIter){
506 fWeightName = PyStringAsString(PyList_GetItem(fPWeightNames,weightIter));
507 fWeightDType =
ConvertStringToType(PyStringAsString(PyList_GetItem(fPWeightDTypes,weightIter)));
509 fWeightShape.clear();
510 PyObject* fShapeList = PyList_GetItem(fPWeightShapes,weightIter);
511 for(
Py_ssize_t j=0; j<PyList_Size(fShapeList); ++j){
512 std::size_t dim = (std::size_t)PyLong_AsLong(PyList_GetItem(fShapeList,j));
513 fWeightShape.push_back(dim);
516 switch(fWeightDType){
518 char* fWeightValue =
PyBytes_AsString(PyList_GetItem(fPWeightBytes,weightIter));
519 std::shared_ptr<void> fData(
malloc(fWeightSize *
sizeof(
float)),
free);
520 std::memcpy(fData.get(),fWeightValue,fWeightSize *
sizeof(
float));
525 throw std::runtime_error(
"Type error: TMVA SOFIE does not yet supports weights of data type"+
ConvertTypeToString(fWeightDType));
531 PyRunString(
"inputs=[x for x in model.graph.inputs()]",fGlobalNS,fLocalNS);
532 PyRunString(
"inputs=inputs[1:]",fGlobalNS,fLocalNS);
533 PyRunString(
"inputNames=[x.debugName() for x in inputs]",fGlobalNS,fLocalNS);
534 PyObject* fPInputs= PyDict_GetItemString(fLocalNS,
"inputNames");
535 std::string fInputName;
536 std::vector<size_t>fInputShape;
538 for(
Py_ssize_t inputIter=0; inputIter<PyList_Size(fPInputs);++inputIter){
539 fInputName = PyStringAsString(PyList_GetItem(fPInputs,inputIter));
540 fInputShape = inputShapes[inputIter];
541 fInputDType = inputDTypes[inputIter];
549 throw std::runtime_error(
"Type Error: TMVA SOFIE does not yet support the input tensor data type"+
ConvertTypeToString(fInputDType));
555 PyRunString(
"outputs=[x for x in graph[0].outputs()]",fGlobalNS,fLocalNS);
556 PyRunString(
"outputNames=[x.debugName() for x in outputs]",fGlobalNS,fLocalNS);
557 PyObject* fPOutputs= PyDict_GetItemString(fLocalNS,
"outputNames");
558 std::vector<std::string> fOutputNames;
559 for(
Py_ssize_t outputIter = 0; outputIter < PyList_Size(fPOutputs);++outputIter){
560 fOutputNames.push_back(PyStringAsString(PyList_GetItem(fPOutputs,outputIter)));
int main(int argc, char *argv[])