Processes the indexing tensors (begin, end and strides) to resize the output tensor. This function is callable from both Prepare() and Eval() as long as the caller ensures the indexing tensors are present.
| 100 | // output tensor. This function is callable from both Prepare() and Eval() as |
| 101 | // long as the caller ensures the indexing tensors are present. |
| 102 | TfLiteStatus ResizeOutputTensor(TfLiteContext* context, |
| 103 | StridedSliceContext* op_context) { |
| 104 | std::vector<int> output_shape_vector; |
| 105 | |
| 106 | for (int idx = op_context->dims - 1; idx >= 0; --idx) { |
| 107 | int32_t stride = GetTensorData<int32_t>(op_context->strides)[idx]; |
| 108 | TF_LITE_ENSURE_MSG(context, stride != 0, "stride value has to be non-zero"); |
| 109 | |
| 110 | int32_t begin = GetBeginValueAtIndex(op_context, idx); |
| 111 | int32_t end = GetEndValueAtIndex(op_context, idx); |
| 112 | |
| 113 | // When shrinking an axis, the end position does not matter (and can be |
| 114 | // incorrect when negative indexing is used, see Issue #19260). Always use |
| 115 | // begin + 1 to generate a length 1 slice, since begin has |
| 116 | // already been adjusted for negative indices by GetBeginValueAtIndex. |
| 117 | const bool shrink_axis = op_context->params->shrink_axis_mask & (1 << idx); |
| 118 | if (shrink_axis) { |
| 119 | end = begin + 1; |
| 120 | } |
| 121 | |
| 122 | // This is valid for both positive and negative strides |
| 123 | int32_t dim_shape = std::ceil((end - begin) / static_cast<float>(stride)); |
| 124 | dim_shape = dim_shape < 0 ? 0 : dim_shape; |
| 125 | if (!shrink_axis) { |
| 126 | output_shape_vector.push_back(dim_shape); |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | TfLiteIntArray* output_shape = |
| 131 | TfLiteIntArrayCreate(output_shape_vector.size()); |
| 132 | |
| 133 | std::reverse_copy(output_shape_vector.begin(), output_shape_vector.end(), |
| 134 | output_shape->data); |
| 135 | |
| 136 | TF_LITE_ENSURE_STATUS( |
| 137 | context->ResizeTensor(context, op_context->output, output_shape)); |
| 138 | |
| 139 | return kTfLiteOk; |
| 140 | } |
| 141 | |
| 142 | TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { |
| 143 | TF_LITE_ENSURE_EQ(context, NumInputs(node), 4); |
no test coverage detected