28#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 
   29#include <numpy/arrayobject.h> 
   32namespace Experimental{
 
   94        std::string fNodeType = 
PyStringAsString(PyDict_GetItemString(fNode,
"nodeType"));
 
   97            throw std::runtime_error(
"TMVA::SOFIE - Parsing PyTorch node " +fNodeType+
" is not yet supported ");
 
   99        return (findNode->second)(fNode);
 
  115        PyObject* fAttributes   = PyDict_GetItemString(fNode,
"nodeAttributes");
 
  116        PyObject* fInputs       = PyDict_GetItemString(fNode,
"nodeInputs");
 
  117        PyObject* fOutputs      = PyDict_GetItemString(fNode,
"nodeOutputs");
 
  118        std::string fNodeDType  = 
PyStringAsString(PyList_GetItem(PyDict_GetItemString(fNode,
"nodeDType"),0));
 
  125        float fAttrAlpha = (float)(PyFloat_AsDouble(PyDict_GetItemString(fAttributes,
"alpha")));
 
  126        float fAttrBeta = (float)(PyFloat_AsDouble(PyDict_GetItemString(fAttributes,
"beta")));
 
  130        if(PyDict_Contains(fAttributes,PyUnicode_FromString(
"transB"))){
 
  131            fAttrTransB = (
int_t)(PyLong_AsLong(PyDict_GetItemString(fAttributes,
"transB")));
 
  132            fAttrTransA = !fAttrTransB;
 
  135            fAttrTransA=(
int_t)(PyLong_AsLong(PyDict_GetItemString(fAttributes,
"transA")));
 
  136            fAttrTransB = !fAttrTransA;
 
  139        std::unique_ptr<ROperator> op;
 
  142                op.reset(
new ROperator_Gemm<float>(fAttrAlpha, fAttrBeta, fAttrTransA, fAttrTransB, fNameA, fNameB, fNameC, fNameY ));
 
  146                    throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Gemm does not yet support input type " + fNodeDType);
 
  161        PyObject* fInputs       = PyDict_GetItemString(fNode,
"nodeInputs");
 
  162        PyObject* fOutputs      = PyDict_GetItemString(fNode,
"nodeOutputs");
 
  163        std::string fNodeDType  = 
PyStringAsString(PyList_GetItem(PyDict_GetItemString(fNode,
"nodeDType"),0));
 
  166        std::unique_ptr<ROperator> op;
 
  173                throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Relu does not yet support input type " + fNodeDType);
 
  188        PyObject* fInputs       = PyDict_GetItemString(fNode,
"nodeInputs");
 
  189        PyObject* fOutputs      = PyDict_GetItemString(fNode,
"nodeOutputs");
 
  190        std::string fNodeDType  = 
PyStringAsString(PyList_GetItem(PyDict_GetItemString(fNode,
"nodeDType"),0));
 
  192        std::unique_ptr<ROperator> op;
 
  199                throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Selu does not yet support input type " + fNodeDType);
 
  214        PyObject* fInputs       = PyDict_GetItemString(fNode,
"nodeInputs");
 
  215        PyObject* fOutputs      = PyDict_GetItemString(fNode,
"nodeOutputs");
 
  216        std::string fNodeDType  = 
PyStringAsString(PyList_GetItem(PyDict_GetItemString(fNode,
"nodeDType"),0));
 
  218        std::unique_ptr<ROperator> op;
 
  225                throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Sigmoid does not yet support input type " + fNodeDType);
 
  240        PyObject* fAttributes   = PyDict_GetItemString(fNode,
"nodeAttributes");
 
  241        PyObject* fInputs       = PyDict_GetItemString(fNode,
"nodeInputs");
 
  242        PyObject* fOutputs      = PyDict_GetItemString(fNode,
"nodeOutputs");
 
  243        std::string fNodeDType  = 
PyStringAsString(PyList_GetItem(PyDict_GetItemString(fNode,
"nodeDType"),0));
 
  246        std::vector<int_t> fAttrPermute;
 
  247        PyObject* fPermute=PyDict_GetItemString(fAttributes,
"perm");
 
  248        for(
Py_ssize_t permIter=0; permIter<PyList_Size(fPermute);++permIter){
 
  249            fAttrPermute.push_back((
int_t)PyLong_AsLong(PyList_GetItem(fPermute,permIter)));
 
  254        std::unique_ptr<ROperator> op;
 
  261            throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Transpose does not yet support input type " + fNodeDType);
 
  277        PyObject* fAttributes   = PyDict_GetItemString(fNode,
"nodeAttributes");
 
  278        PyObject* fInputs       = PyDict_GetItemString(fNode,
"nodeInputs");
 
  279        PyObject* fOutputs      = PyDict_GetItemString(fNode,
"nodeOutputs");
 
  280        std::string fNodeDType  = 
PyStringAsString(PyList_GetItem(PyDict_GetItemString(fNode,
"nodeDType"),0));
 
  283        PyObject* fDilations       = PyDict_GetItemString(fAttributes,
"dilations");
 
  284        PyObject* fGroup           = PyDict_GetItemString(fAttributes,
"group");
 
  285        PyObject* fKernelShape     = PyDict_GetItemString(fAttributes,
"kernel_shape");
 
  286        PyObject* fPads            = PyDict_GetItemString(fAttributes,
"pads");
 
  287        PyObject* fStrides         = PyDict_GetItemString(fAttributes,
"strides");
 
  289        std::string fAttrAutopad = 
"NOTSET";
 
  290        std::vector<size_t> fAttrDilations = GetDataFromList(fDilations);
 
  291        size_t fAttrGroup = PyLong_AsLong(fGroup);
 
  292        std::vector<size_t> fAttrKernelShape = GetDataFromList(fKernelShape);
 
  293        std::vector<size_t> fAttrPads        = GetDataFromList(fPads);
 
  294        std::vector<size_t> fAttrStrides     = GetDataFromList(fStrides);
 
  300        std::unique_ptr<ROperator> op;
 
  303                op.reset(
new ROperator_Conv<float>(fAttrAutopad, fAttrDilations, fAttrGroup, fAttrKernelShape, fAttrPads, fAttrStrides, nameX, nameW, nameB, nameY));
 
  307            throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Conv does not yet support input type " + fNodeDType);
 
  357RModel Parse(std::string 
filename, std::vector<std::vector<size_t>> inputShapes, std::vector<ETensorType> inputDTypes){
 
  365    std::string filename_nodir = 
filename;
 
  366    if (isep != std::string::npos){
 
  371    if(!std::ifstream(
filename).good()){
 
  372        throw std::runtime_error(
"Model file "+filename_nodir+
" not found!");
 
  376    std::time_t ttime = std::time(0);
 
  377    std::tm* gmt_time = std::gmtime(&ttime);
 
  378    std::string parsetime (std::asctime(gmt_time));
 
  380    RModel rmodel(filename_nodir, parsetime);
 
  388       throw std::runtime_error(
"Can't init global namespace for Python");
 
  391       throw std::runtime_error(
"Can't init local namespace for Python");
 
  399    PyRunString(
"print('Torch Version: '+torch.__version__)",fGlobalNS,fLocalNS);
 
  400    PyRunString(
"from torch.onnx.utils import _model_to_graph",fGlobalNS,fLocalNS);
 
  403    PyRunString(
"globals().update(locals())",fGlobalNS,fLocalNS);
 
  409    for(
long unsigned int it=0;it<inputShapes.size();++it){
 
  411        for(
long unsigned int itr=0;itr<inputShapes[it].size();++itr){
 
  414        PyRunString(
"dummyInputs.append(torch.rand(*inputShape))",fGlobalNS,fLocalNS);
 
  420    PyRunString(
"graph=_model_to_graph(model,dummyInputs)",fGlobalNS,fLocalNS);
 
  428                "    sel = node.kindOf(key)\n" 
  429                "    return getattr(node, sel)(key)\n",
 
  430                fGlobalNS, fLocalNS);
 
  432                "    globals().update(locals())\n" 
  434                "    nodeData['nodeType']=i.kind()\n" 
  435                "    nodeAttributeNames=[x for x in i.attributeNames()]\n" 
  436                "    nodeAttributes={j: _node_get(i, j) for j in nodeAttributeNames}\n" 
  437                "    nodeData['nodeAttributes']=nodeAttributes\n" 
  438                "    nodeInputs=[x for x in i.inputs()]\n" 
  439                "    nodeInputNames=[x.debugName() for x in nodeInputs]\n" 
  440                "    nodeData['nodeInputs']=nodeInputNames\n" 
  441                "    nodeOutputs=[x for x in i.outputs()]\n" 
  442                "    nodeOutputNames=[x.debugName() for x in nodeOutputs]\n" 
  443                "    nodeData['nodeOutputs']=nodeOutputNames\n" 
  444                "    nodeDType=[x.type().scalarType() for x in nodeOutputs]\n" 
  445                "    nodeData['nodeDType']=nodeDType\n" 
  446                "    modelData.append(nodeData)",
 
  447                fGlobalNS, fLocalNS);
 
  449    PyObject* fPModel = PyDict_GetItemString(fLocalNS,
"modelData");
 
  450    Py_ssize_t fPModelSize = PyList_Size(fPModel);
 
  452    std::string fNodeType;
 
  455    for(
Py_ssize_t fModelIterator=0;fModelIterator<fPModelSize;++fModelIterator){
 
  456        fNode     = PyList_GetItem(fPModel,fModelIterator);
 
  460        if(fNodeType == 
"onnx::Gemm"){
 
  463        else if(fNodeType == 
"onnx::Selu" || fNodeType == 
"onnx::Sigmoid"){
 
  466        else if (fNodeType == 
"onnx::Conv") {
 
  474    PyRunString(
"weightNames=[k for k in graph[1].keys()]",fGlobalNS,fLocalNS);
 
  475    PyRunString(
"weights=[v.numpy() for v in graph[1].values()]",fGlobalNS,fLocalNS);
 
  476    PyRunString(
"weightDTypes=[v.type()[6:-6] for v in graph[1].values()]",fGlobalNS,fLocalNS);
 
  477    PyObject* fPWeightNames = PyDict_GetItemString(fLocalNS,
"weightNames");
 
  478    PyObject* fPWeightTensors = PyDict_GetItemString(fLocalNS,
"weights");
 
  479    PyObject* fPWeightDTypes = PyDict_GetItemString(fLocalNS,
"weightDTypes");
 
  480    PyArrayObject* fWeightTensor;
 
  481    std::string fWeightName;
 
  483    std::vector<std::size_t> fWeightShape;
 
  484    std::size_t fWeightSize;
 
  486    for(
Py_ssize_t weightIter=0; weightIter<PyList_Size(fPWeightTensors);++weightIter){
 
  487        fWeightTensor = (PyArrayObject*)PyList_GetItem(fPWeightTensors,weightIter);
 
  491        fWeightShape.clear();
 
  492        for(
int j=0; j<PyArray_NDIM(fWeightTensor); ++j){
 
  493            fWeightShape.push_back((std::size_t)(PyArray_DIM(fWeightTensor,j)));
 
  494            fWeightSize*=(std::size_t)(PyArray_DIM(fWeightTensor,j));
 
  496        switch(fWeightDType){
 
  498                float* fWeightValue = (
float*)PyArray_DATA(fWeightTensor);
 
  499                std::shared_ptr<void> fData(
malloc(fWeightSize * 
sizeof(
float)), 
free);
 
  500                std::memcpy(fData.get(),fWeightValue,fWeightSize * 
sizeof(
float));
 
  505                throw std::runtime_error(
"Type error: TMVA SOFIE does not yet supports weights of data type"+
ConvertTypeToString(fWeightDType));
 
  511    PyRunString(
"inputs=[x for x in model.graph.inputs()]",fGlobalNS,fLocalNS);
 
  512    PyRunString(
"inputs=inputs[1:]",fGlobalNS,fLocalNS);
 
  513    PyRunString(
"inputNames=[x.debugName() for x in inputs]",fGlobalNS,fLocalNS);
 
  514    PyObject* fPInputs= PyDict_GetItemString(fLocalNS,
"inputNames");
 
  515    std::string fInputName;
 
  516    std::vector<size_t>fInputShape;
 
  518    for(
Py_ssize_t inputIter=0; inputIter<PyList_Size(fPInputs);++inputIter){
 
  520        fInputShape = inputShapes[inputIter];
 
  521        fInputDType = inputDTypes[inputIter];
 
  529                throw std::runtime_error(
"Type Error: TMVA SOFIE does not yet support the input tensor data type"+
ConvertTypeToString(fInputDType));
 
  535    PyRunString(
"outputs=[x for x in graph[0].outputs()]",fGlobalNS,fLocalNS);
 
  536    PyRunString(
"outputNames=[x.debugName() for x in outputs]",fGlobalNS,fLocalNS);
 
  537    PyObject* fPOutputs= PyDict_GetItemString(fLocalNS,
"outputNames");
 
  538    std::vector<std::string> fOutputNames;
 
  539    for(
Py_ssize_t outputIter = 0; outputIter < PyList_Size(fPOutputs);++outputIter){
 
  540        fOutputNames.push_back(
PyStringAsString(PyList_GetItem(fPOutputs,outputIter)));
 
  557RModel Parse(std::string filepath,std::vector<std::vector<size_t>> inputShapes){
 
  559      return Parse(filepath,inputShapes,dtype);
 
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
 
void AddOutputTensorNameList(std::vector< std::string > outputtensornames)
 
void AddInputTensorInfo(std::string input_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)
 
void AddBlasRoutines(std::vector< std::string > routines)
 
void AddInputTensorName(std::string name)
 
void AddNeededStdLib(std::string libname)
 
void AddOperator(std::unique_ptr< ROperator > op, int order_execution=-1)
 
static std::vector< size_t > GetDataFromList(PyObject *listObject)
Utility function which retrieves and returns the values of the List object as a vector of size_t.
 
static const char * PyStringAsString(PyObject *string)
Returns const char* from Python string in PyObject.
 
void PyRunString(TString code, TString errorMessage="Failed to run python code", int start=256)
Execute Python code from string.
 
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
 
std::unique_ptr< ROperator > MakePyTorchGemm(PyObject *fNode)
Prepares a ROperator_Gemm object.
 
std::unique_ptr< ROperator > MakePyTorchNode(PyObject *fNode)
Prepares equivalent ROperator with respect to PyTorch ONNX node.
 
std::unique_ptr< ROperator > MakePyTorchConv(PyObject *fNode)
Prepares a ROperator_Conv object.
 
std::unique_ptr< ROperator > MakePyTorchSigmoid(PyObject *fNode)
Prepares a ROperator_Sigmoid object.
 
std::unique_ptr< ROperator > MakePyTorchSelu(PyObject *fNode)
Prepares a ROperator_Selu object.
 
std::unique_ptr< ROperator > MakePyTorchRelu(PyObject *fNode)
Prepares a ROperator_Relu object.
 
const PyTorchMethodMap mapPyTorchNode
 
std::unordered_map< std::string, std::unique_ptr< ROperator >(*)(PyObject *fNode)> PyTorchMethodMap
 
std::unique_ptr< ROperator > MakePyTorchTranspose(PyObject *fNode)
Prepares a ROperator_Transpose object.
 
static const char *(&) PyStringAsString(PyObject *)
 
static void(&) PyRunString(TString, PyObject *, PyObject *)
 
RModel Parse(std::string filepath, std::vector< std::vector< size_t > > inputShapes, std::vector< ETensorType > dtype)
Parser function for translating PyTorch .pt model into a RModel object.
 
std::string ConvertTypeToString(ETensorType type)
 
ETensorType ConvertStringToType(std::string type)
 
create variable transformations