| 34 | TfLiteIntArray* GetOutputShape(TfLiteContext*, TfLiteNode*); |
| 35 | |
| 36 | TfLiteStatus ResizeOutput(TfLiteContext* context, TfLiteNode* node) { |
| 37 | TfLiteIntArray* output_shape = GetOutputShape(context, node); |
| 38 | std::unique_ptr<TfLiteIntArray, void (*)(TfLiteIntArray*)> |
| 39 | scoped_output_shape(output_shape, TfLiteIntArrayFree); |
| 40 | |
| 41 | const TfLiteTensor* input = GetInput(context, node, kInputTensor); |
| 42 | TfLiteTensor* output = GetOutput(context, node, kOutputTensor); |
| 43 | |
| 44 | // Tensorflow's Reshape allows one of the shape components to have the |
| 45 | // special -1 value, meaning it will be calculated automatically based on the |
| 46 | // input. Here we calculate what that dimension should be so that the number |
| 47 | // of output elements in the same as the number of input elements. |
| 48 | int num_input_elements = NumElements(input); |
| 49 | |
| 50 | int num_output_elements = 1; |
| 51 | int stretch_dim = -1; |
| 52 | for (int i = 0; i < output_shape->size; ++i) { |
| 53 | int value = output_shape->data[i]; |
| 54 | if (value == -1) { |
| 55 | TF_LITE_ENSURE_EQ(context, stretch_dim, -1); |
| 56 | stretch_dim = i; |
| 57 | } else { |
| 58 | num_output_elements *= value; |
| 59 | } |
| 60 | } |
| 61 | if (stretch_dim != -1) { |
| 62 | output_shape->data[stretch_dim] = num_input_elements / num_output_elements; |
| 63 | num_output_elements *= output_shape->data[stretch_dim]; |
| 64 | } |
| 65 | |
| 66 | TF_LITE_ENSURE_EQ(context, num_input_elements, num_output_elements); |
| 67 | return context->ResizeTensor(context, output, scoped_output_shape.release()); |
| 68 | } |
| 69 | |
| 70 | inline TfLiteIntArray* GetOutputShapeFromTensor(TfLiteContext* context, |
| 71 | TfLiteNode* node) { |
no test coverage detected