| 3187 | } |
| 3188 | |
| 3189 | TfLiteStatus NNAPIDelegateKernel::BuildGraph( |
| 3190 | TfLiteContext* context, const TfLiteIntArray* input_tensors, |
| 3191 | const TfLiteIntArray* output_tensors) { |
| 3192 | // Build the ops and tensors. |
| 3193 | TF_LITE_ENSURE_STATUS(AddOpsAndTensors(context)); |
| 3194 | // Map input and output tensor indices to ANN |
| 3195 | std::vector<uint32_t> inputs; |
| 3196 | inputs.reserve(input_tensors->size); |
| 3197 | std::vector<uint32_t> outputs; |
| 3198 | outputs.reserve(output_tensors->size); |
| 3199 | |
| 3200 | size_t total_input_byte_size = 0; |
| 3201 | // Make the TensorFlow Lite inputs and outputs to ann_indices. |
| 3202 | for (int i : TfLiteIntArrayView(input_tensors)) { |
| 3203 | // Constant tensors are not NNAPI inputs. |
| 3204 | if (i != kOptionalTensor && |
| 3205 | context->tensors[i].allocation_type != kTfLiteMmapRo && |
| 3206 | // The delegate might not have mapped this input (this can |
| 3207 | // happen if one tensor is split in several ones) |
| 3208 | operand_mapping_.lite_index_to_ann(i) != -1) { |
| 3209 | inputs.push_back(operand_mapping_.lite_index_to_ann(i)); |
| 3210 | if (context->tensors[i].buffer_handle != kTfLiteNullBufferHandle) { |
| 3211 | continue; |
| 3212 | } |
| 3213 | const TfLiteType nn_type_conversion = |
| 3214 | operand_mapping_.lite_index_to_ann_type_conversion(i); |
| 3215 | int tensor_size = 0; |
| 3216 | if (nn_type_conversion == kTfLiteNoType) { |
| 3217 | tensor_size = context->tensors[i].bytes; |
| 3218 | } else { |
| 3219 | size_t type_size; |
| 3220 | TF_LITE_ENSURE_OK( |
| 3221 | context, GetSizeOfType(context, nn_type_conversion, &type_size)); |
| 3222 | tensor_size = NumElements(&context->tensors[i]) * type_size; |
| 3223 | } |
| 3224 | total_input_byte_size += tensor_size; |
| 3225 | total_input_byte_size += getNumPaddingBytes(tensor_size); |
| 3226 | } |
| 3227 | } |
| 3228 | |
| 3229 | size_t total_output_byte_size = 0; |
| 3230 | for (int i : TfLiteIntArrayView(output_tensors)) { |
| 3231 | const int output_tensor_ann_index = operand_mapping_.lite_index_to_ann(i); |
| 3232 | // Unmapped outputs are not added |
| 3233 | if (output_tensor_ann_index != -1) { |
| 3234 | outputs.push_back(output_tensor_ann_index); |
| 3235 | } |
| 3236 | if (context->tensors[i].buffer_handle != kTfLiteNullBufferHandle) { |
| 3237 | continue; |
| 3238 | } |
| 3239 | total_output_byte_size += context->tensors[i].bytes; |
| 3240 | total_output_byte_size += getNumPaddingBytes(context->tensors[i].bytes); |
| 3241 | } |
| 3242 | |
| 3243 | // Add state output tensors as model outputs. |
| 3244 | for (int i : model_state_outputs_) { |
| 3245 | outputs.push_back(i); |
| 3246 | } |
nothing calls this directly
no test coverage detected