Kayee Joe
Kayee Joe

Reputation: 43

Specifying shapehandle's shape when creating new op in tensorflow (rank problem of the output tensor)

I have successfully compiled the op registration file and tested when only using this file. But during training process, I tried to call the function defined in the op, these errors were encountered, which vary every time:

Segmentation fault (core dumped)

or

double free or corruption (!prev)
Aborted (core dumped)

or

ValueError: Shape must be rank 1 but is rank 99648624 for 'x' (op: 'x') with input shapes: [50, 1000, 3].

And please note the number99648624 above is uncertain, sometimes it could be 0 or any weird number.

Below is the code for registering the op in tensorflow, where I specify the output's dimension as (b,200,200,1):

 .SetShapeFn([](::tensorflow::shape_inference::InferenceContext* c) {
        ::tensorflow::shape_inference::ShapeHandle input
        TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 3, &input));   
        ::tensorflow::shape_inference::ShapeHandle dim2;
        TF_RETURN_IF_ERROR(c->MakeShapeFromShapeTensor(200, &dim2));    
        ::tensorflow::shape_inference::ShapeHandle dim3;
        TF_RETURN_IF_ERROR(c->MakeShapeFromShapeTensor(200, &dim3));    
        ::tensorflow::shape_inference::ShapeHandle dim4;
        TF_RETURN_IF_ERROR(c->MakeShapeFromShapeTensor(1, &dim4));    
        ::tensorflow::shape_inference::ShapeHandle output = c->MakeShape({c->Dim(input, 0), c->Dim(dim2, 0), c->Dim(dim3, 0), c->Dim(dim4, 0)});
        c->set_output(0, output);
        return Status::OK();
    });

Thank you in advance! Any suggestion is welcome!

Upvotes: 0

Views: 403

Answers (1)

McLP
McLP

Reputation: 140

According to the comments in tensorflows source code, MakeShapeFromShapeTensor takes an ID as the input:

Returns in out a new shape whose dimension sizes come from input tensor input_idx. The tensor must be a 1-dimensional int32 or int64 tensor. If the input tensor is NULL, then an unknown shape is returned.

So it takes the tensor you declared as an input with index input_idx and tries to use it as the shape (instead of using the shape ot the tensor like with c->input(0) does). So if you declared your inputs like this:

REGISTER_OP("SomeOp")
        .Input("some_input: float")
        .Input("some_vector: int64")

and some_vector is for example (2,2,1) then c->MakeShapeFromShapeTensor(1, &dims) will output into dims a ShapeHandle with dimensions (2,2,1).

So what you actually want is to set the dimensions directly when calling MakeShape like this:

c->MakeShape({c->Dim(input, 0), 200, 200, 1});

Your errors come from the fact that in c++ there are not many checks performed when accessing invalid indices, so it tries to load whatever value is in the ram where index 200 would be and convert it into an integer vector. Accessing this memory adress is either not allowed (Segmentation Fault) or it contains invalid values (corruption) or garbage (random high rank).

Upvotes: 1

Related Questions