| 16 | { |
| 17 | |
| 18 | TfLiteStatus VisitStridedSliceOperator(DelegateData& delegateData, |
| 19 | TfLiteContext* tfLiteContext, |
| 20 | TfLiteNode* tfLiteNode, |
| 21 | int nodeIndex, |
| 22 | int32_t sliceOperatorCode) |
| 23 | { |
| 24 | TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 4, nodeIndex)); |
| 25 | TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); |
| 26 | |
| 27 | // Read inputs [input, begin, end, strides] |
| 28 | int numInputs = tfLiteNode->inputs->size; |
| 29 | std::vector<const TfLiteTensor*> tfLiteInputs; |
| 30 | tfLiteInputs.reserve(numInputs); |
| 31 | const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; |
| 32 | for (int i = 0; i < numInputs; i++) |
| 33 | { |
| 34 | const TfLiteTensor* inputTensor = &tfLiteTensors[tfLiteNode->inputs->data[i]]; |
| 35 | tfLiteInputs.push_back(inputTensor); |
| 36 | if (!IsValid(tfLiteContext, *inputTensor, sliceOperatorCode, nodeIndex)) |
| 37 | { |
| 38 | return kTfLiteError; |
| 39 | } |
| 40 | // Checking for unsupported non-const non-network input tensors |
| 41 | // Index 0 is the input, index 1-3 should be constant |
| 42 | if(i > 0 && inputTensor->allocation_type != kTfLiteMmapRo) |
| 43 | { |
| 44 | TF_LITE_MAYBE_KERNEL_LOG( |
| 45 | tfLiteContext, |
| 46 | "TfLiteArmnnDelegate: Unsupported constant data input through non-const tensor " |
| 47 | "in operator #%d node #%d", |
| 48 | sliceOperatorCode, nodeIndex); |
| 49 | return kTfLiteError; |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | // We save the begin, end and strides tensors in our descriptor. Therefore we have to read those values from inputs |
| 54 | int inputRank = tfLiteInputs[0]->dims->size; |
| 55 | |
| 56 | // Input tensors of rank greater than 4 are unsupported - delegate back to TFLite runtime |
| 57 | if(inputRank > 4) |
| 58 | { |
| 59 | TF_LITE_MAYBE_KERNEL_LOG( |
| 60 | tfLiteContext, |
| 61 | "TfLitearmnnOpaqueDelegate: Tensors of rank greater than 4 are unsupported" |
| 62 | " in the StridedSlice operator. Operator: #%d node #%d: ", |
| 63 | sliceOperatorCode, nodeIndex); |
| 64 | return kTfLiteError; |
| 65 | } |
| 66 | |
| 67 | auto ReadInt32Input = [&](int inputIndex, std::vector<int32_t>& outputData) -> TfLiteStatus |
| 68 | { |
| 69 | if (tfLiteInputs[inputIndex]->type != kTfLiteInt32) |
| 70 | { |
| 71 | TF_LITE_MAYBE_KERNEL_LOG( |
| 72 | tfLiteContext, |
| 73 | "TfLiteArmnnDelegate: The Begin-, End- and Stride-Tensors of the StridedSlice operation need to " |
| 74 | "be of type int32. Operator: #%d node #%d: ", |
| 75 | sliceOperatorCode, nodeIndex); |
no test coverage detected