| 99 | } |
| 100 | |
| 101 | TfLiteStatus VisitQuantizeOperator(DelegateData& delegateData, |
| 102 | TfLiteContext* tfLiteContext, |
| 103 | TfLiteNode* tfLiteNode, |
| 104 | int nodeIndex, |
| 105 | int32_t tfLiteQuantizeOperatorCode) |
| 106 | { |
| 107 | TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); |
| 108 | TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); |
| 109 | |
| 110 | const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; |
| 111 | const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; |
| 112 | if (IsDynamicTensor(tfLiteInputTensor)) |
| 113 | { |
| 114 | TF_LITE_MAYBE_KERNEL_LOG( |
| 115 | tfLiteContext, |
| 116 | "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", |
| 117 | tfLiteQuantizeOperatorCode, nodeIndex); |
| 118 | return kTfLiteError; |
| 119 | } |
| 120 | |
| 121 | const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; |
| 122 | if (IsDynamicTensor(tfLiteOutputTensor)) |
| 123 | { |
| 124 | TF_LITE_MAYBE_KERNEL_LOG( |
| 125 | tfLiteContext, |
| 126 | "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", |
| 127 | tfLiteQuantizeOperatorCode, nodeIndex); |
| 128 | return kTfLiteError; |
| 129 | } |
| 130 | |
| 131 | // Only affine per-layer quantization is supported. |
| 132 | if (!IsAffineQuantization(tfLiteOutputTensor)) |
| 133 | { |
| 134 | TF_LITE_MAYBE_KERNEL_LOG( |
| 135 | tfLiteContext, |
| 136 | "TfLiteArmnnDelegate: Only affine per-layer quantization is supported in operator #%d node #%d: ", |
| 137 | tfLiteQuantizeOperatorCode, nodeIndex); |
| 138 | return kTfLiteError; |
| 139 | } |
| 140 | |
| 141 | const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); |
| 142 | const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); |
| 143 | |
| 144 | if (outputTensorInfo.HasPerAxisQuantization()) |
| 145 | { |
| 146 | auto outputTensorDataType = outputTensorInfo.GetDataType(); |
| 147 | if (outputTensorDataType == armnn::DataType::QAsymmU8 || outputTensorDataType == armnn::DataType::QAsymmS8) |
| 148 | { |
| 149 | TF_LITE_MAYBE_KERNEL_LOG( |
| 150 | tfLiteContext, |
| 151 | "TfLiteArmnnDelegate: Per Axis Quantization is not supported in asymmetric Quantization Datatype."); |
| 152 | return kTfLiteError; |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | bool isSupported = false; |
| 157 | armnn::BackendId setBackend; |
| 158 | auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) |
no test coverage detected