KhronosGroup / NNEF-Tools

The NNEF Tools repository contains tools to generate and consume NNEF documents
https://www.khronos.org/nnef
222 stars 57 forks source link

Unable to read weights in onnx converted networks #86

Closed charanpool closed 5 years ago

charanpool commented 5 years ago

When we convert a nnef model to onnx model using converter provided, while parsing converted model onnx file weights are not accessible. We encounter the following issue:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004069fc in onnx::TensorProto::float_data (this=0x68e240, index=0) at onnx.pb.h:4721
4721      return float_data_.Get(index);
(gdb) backtrace
#0  0x00000000004069fc in onnx::TensorProto::float_data (this=0x68e240, index=0) at onnx.pb.h:4721
#1  0x00000000004065e8 in main () at test4.cpp:322

Can you help me resolve this issue?

gyenesvi commented 5 years ago

Probably the float_data field is not set. The tensor data structure has multiple fields (like raw_data, int32_data), from which only one can be set at a time in protobuf. Our converter fills the raw_data field, which is faster to read in python because it is a byte stream (not a list). The actual data type can be decided based on the data type field.

charanpool commented 5 years ago

We are parsing the newtork in CPP and so used the following loop and conditions :

for(int a = 0; a < tempProd; a++)
{
    if(model.graph().initializer(j).data_type() == 11)
    {
        tempNode->outTensor.data[a] = (float)model.graph().initializer(j).double_data(a);
        //tempNode->outTensor.data[a] = (float)model.graph().initializer(j).raw_data(a);
    }
    else if(model.graph().initializer(j).data_type() == 1)
    {
        tempNode->outTensor.data[a] = model.graph().initializer(j).float_data(a);
    }
    else
    {
        std::cout<<"data_type: "<<model.graph().initializer(j).data_type()<<"\n";
        //tempNode->outTensor.data[a] = model.graph().initializer(j).raw_data(a);
    }
}

tempProd denotes the product of all the dimensions(in case of 4 dimensional tensors). tempNode, a node structure in cpp consisting of outTensor structure pointer to store the tensor weights in it's member data pointer.

This is giving me the following error when running on a converted vgg-16 model from nnef to onnx through the NNEF-Tools:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000415ca0 in onnx::TensorProto::float_data (this=0x65f6e0, index=0)
    at /home/testuser/work/nnefParser/parser/cpp/evip_include/onnx.pb.h:4721
4721      return float_data_.Get(index);
(gdb) backtrace
#0  0x0000000000415ca0 in onnx::TensorProto::float_data (this=0x65f6e0, index=0)
    at /home/testuser/work/nnefParser/parser/cpp/evip_include/onnx.pb.h:4721
#1  0x000000000041514e in fillGraph (model=..., node_proto=<incomplete type>)
    at /home/testuser/work/nnefParser/parser/cpp/evip_src/onnx_parser4.cpp:624
#2  0x0000000000413227 in onnx_parser_main () at /home/testuser/work/nnefParser/parser/cpp/evip_src/onnx_parser4.cpp:62
#3  0x0000000000412dc8 in main (argc=3, argv=0x7fffffffe3e8) at /home/testuser/work/nnefParser/parser/cpp/app/tinyYolo_main.cpp:17
gyenesvi commented 5 years ago

Honestly, I believe that this has nothing to do with NNEF, it is just about interpreting the ONNX protobuf model. But I believe you need to check which one of the optional fields is set and then read out the data from there. In case it is raw data, you have to interpret that (probably cast) based on the data type field.

gyenesvi commented 5 years ago

Did you manage to resolve this? Can the issue be closed?