Add details about failed NNAPI operation when logging NNAPI errors. It also Converts the error code into the associated NNAPI constant name.
PiperOrigin-RevId: 284149818 Change-Id: I3b6be19b93b40ada764c2edcd661c86619b9b830
This commit is contained in:
parent
9b3930304b
commit
d0e55241d5
@ -57,14 +57,47 @@ limitations under the License.
|
|||||||
namespace tflite {
|
namespace tflite {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// TODO(b/80621585): Consider printing error string, but don't for now to
|
// Returns the enum name corresponding to the given error code if the given
|
||||||
// minimize binary size.
|
// value corresponds to an of the error codes in the enumeration above or
|
||||||
#define RETURN_TFLITE_ERROR_IF_NN_ERROR(context, code, p_errno) \
|
// an message with the unknown code.
|
||||||
|
// LINT.IfChange(NnApiErrorDescription)
|
||||||
|
std::string NnApiErrorDescription(int error_code) {
|
||||||
|
switch (error_code) {
|
||||||
|
case ANEURALNETWORKS_NO_ERROR:
|
||||||
|
return "ANEURALNETWORKS_NO_ERROR";
|
||||||
|
case ANEURALNETWORKS_OUT_OF_MEMORY:
|
||||||
|
return "ANEURALNETWORKS_OUT_OF_MEMORY";
|
||||||
|
case ANEURALNETWORKS_INCOMPLETE:
|
||||||
|
return "ANEURALNETWORKS_INCOMPLETE";
|
||||||
|
case ANEURALNETWORKS_UNEXPECTED_NULL:
|
||||||
|
return "ANEURALNETWORKS_UNEXPECTED_NULL";
|
||||||
|
case ANEURALNETWORKS_BAD_DATA:
|
||||||
|
return "ANEURALNETWORKS_BAD_DATA";
|
||||||
|
case ANEURALNETWORKS_OP_FAILED:
|
||||||
|
return "ANEURALNETWORKS_OP_FAILED";
|
||||||
|
case ANEURALNETWORKS_BAD_STATE:
|
||||||
|
return "ANEURALNETWORKS_BAD_STATE";
|
||||||
|
case ANEURALNETWORKS_UNMAPPABLE:
|
||||||
|
return "ANEURALNETWORKS_UNMAPPABLE";
|
||||||
|
case ANEURALNETWORKS_OUTPUT_INSUFFICIENT_SIZE:
|
||||||
|
return "ANEURALNETWORKS_OUTPUT_INSUFFICIENT_SIZE";
|
||||||
|
case ANEURALNETWORKS_UNAVAILABLE_DEVICE:
|
||||||
|
return "ANEURALNETWORKS_UNAVAILABLE_DEVICE";
|
||||||
|
default:
|
||||||
|
return "Unknown NNAPI error code: " + std::to_string(error_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// LINT.ThenChange()
|
||||||
|
|
||||||
|
#define RETURN_TFLITE_ERROR_IF_NN_ERROR(context, code, call_desc, p_errno) \
|
||||||
do { \
|
do { \
|
||||||
const auto _code = (code); \
|
const auto _code = (code); \
|
||||||
|
const auto _call_desc = (call_desc); \
|
||||||
if (_code != ANEURALNETWORKS_NO_ERROR) { \
|
if (_code != ANEURALNETWORKS_NO_ERROR) { \
|
||||||
context->ReportError(context, "NN API returned error (%d, line %d).\n", \
|
const auto error_desc = NnApiErrorDescription(_code); \
|
||||||
_code, __LINE__); \
|
context->ReportError(context, \
|
||||||
|
"NN API returned error %s at line %d while %s.\n", \
|
||||||
|
error_desc.c_str(), __LINE__, _call_desc); \
|
||||||
*p_errno = _code; \
|
*p_errno = _code; \
|
||||||
return kTfLiteError; \
|
return kTfLiteError; \
|
||||||
} \
|
} \
|
||||||
@ -611,7 +644,7 @@ class NNAPIOpBuilder {
|
|||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context_,
|
context_,
|
||||||
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
||||||
nnapi_errno_);
|
"adding operand", nnapi_errno_);
|
||||||
dequantized_ann_index = operand_mapping_->add_new_non_tensor_operand();
|
dequantized_ann_index = operand_mapping_->add_new_non_tensor_operand();
|
||||||
|
|
||||||
// Add Dequantize operation.
|
// Add Dequantize operation.
|
||||||
@ -623,7 +656,7 @@ class NNAPIOpBuilder {
|
|||||||
nnapi_->ANeuralNetworksModel_addOperation(
|
nnapi_->ANeuralNetworksModel_addOperation(
|
||||||
nn_model_, ANEURALNETWORKS_DEQUANTIZE, 1, dequantize_input, 1,
|
nn_model_, ANEURALNETWORKS_DEQUANTIZE, 1, dequantize_input, 1,
|
||||||
dequantize_output),
|
dequantize_output),
|
||||||
nnapi_errno_);
|
"adding operation", nnapi_errno_);
|
||||||
dequantize_mapping_->Add(ann_index, dequantized_type,
|
dequantize_mapping_->Add(ann_index, dequantized_type,
|
||||||
dequantized_ann_index);
|
dequantized_ann_index);
|
||||||
}
|
}
|
||||||
@ -645,7 +678,7 @@ class NNAPIOpBuilder {
|
|||||||
augmented_inputs_.data(),
|
augmented_inputs_.data(),
|
||||||
static_cast<uint32_t>(augmented_outputs_.size()),
|
static_cast<uint32_t>(augmented_outputs_.size()),
|
||||||
augmented_outputs_.data()),
|
augmented_outputs_.data()),
|
||||||
nnapi_errno_);
|
"adding operation", nnapi_errno_);
|
||||||
augmented_inputs_.clear();
|
augmented_inputs_.clear();
|
||||||
augmented_outputs_.clear();
|
augmented_outputs_.clear();
|
||||||
return kTfLiteOk;
|
return kTfLiteOk;
|
||||||
@ -660,7 +693,7 @@ class NNAPIOpBuilder {
|
|||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context_,
|
context_,
|
||||||
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
||||||
nnapi_errno_);
|
"adding operand", nnapi_errno_);
|
||||||
int ann_tensor_index = operand_mapping_->lite_index_to_ann(tensor_index);
|
int ann_tensor_index = operand_mapping_->lite_index_to_ann(tensor_index);
|
||||||
if (ann_tensor_index != -1) {
|
if (ann_tensor_index != -1) {
|
||||||
augmented_inputs_.push_back(ann_tensor_index);
|
augmented_inputs_.push_back(ann_tensor_index);
|
||||||
@ -718,7 +751,7 @@ class NNAPIOpBuilder {
|
|||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context_,
|
context_,
|
||||||
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
||||||
nnapi_errno_);
|
"adding operand", nnapi_errno_);
|
||||||
|
|
||||||
augmented_inputs_.push_back(ann_tensor_index);
|
augmented_inputs_.push_back(ann_tensor_index);
|
||||||
|
|
||||||
@ -727,7 +760,7 @@ class NNAPIOpBuilder {
|
|||||||
nnapi_->ANeuralNetworksModel_setOperandValue(
|
nnapi_->ANeuralNetworksModel_setOperandValue(
|
||||||
nn_model_, ann_tensor_index, new_tensor->data.raw,
|
nn_model_, ann_tensor_index, new_tensor->data.raw,
|
||||||
new_tensor->bytes),
|
new_tensor->bytes),
|
||||||
nnapi_errno_);
|
"setting new operand value", nnapi_errno_);
|
||||||
|
|
||||||
return kTfLiteOk;
|
return kTfLiteOk;
|
||||||
}
|
}
|
||||||
@ -774,13 +807,13 @@ class NNAPIOpBuilder {
|
|||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context_,
|
context_,
|
||||||
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
||||||
nnapi_errno_);
|
"adding operand", nnapi_errno_);
|
||||||
const int ann_index = operand_mapping_->add_new_non_tensor_operand();
|
const int ann_index = operand_mapping_->add_new_non_tensor_operand();
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context_,
|
context_,
|
||||||
nnapi_->ANeuralNetworksModel_setOperandValue(nn_model_, ann_index,
|
nnapi_->ANeuralNetworksModel_setOperandValue(nn_model_, ann_index,
|
||||||
&value, sizeof(T)),
|
&value, sizeof(T)),
|
||||||
nnapi_errno_);
|
"setting new operand value", nnapi_errno_);
|
||||||
augmented_inputs_.push_back(ann_index);
|
augmented_inputs_.push_back(ann_index);
|
||||||
return kTfLiteOk;
|
return kTfLiteOk;
|
||||||
}
|
}
|
||||||
@ -798,14 +831,14 @@ class NNAPIOpBuilder {
|
|||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context_,
|
context_,
|
||||||
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
||||||
nnapi_errno_);
|
"adding operand", nnapi_errno_);
|
||||||
|
|
||||||
const int ann_index = operand_mapping_->add_new_non_tensor_operand();
|
const int ann_index = operand_mapping_->add_new_non_tensor_operand();
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context_,
|
context_,
|
||||||
nnapi_->ANeuralNetworksModel_setOperandValue(
|
nnapi_->ANeuralNetworksModel_setOperandValue(
|
||||||
nn_model_, ann_index, values, sizeof(T) * num_values),
|
nn_model_, ann_index, values, sizeof(T) * num_values),
|
||||||
nnapi_errno_);
|
"settings new operand value", nnapi_errno_);
|
||||||
augmented_inputs_.push_back(ann_index);
|
augmented_inputs_.push_back(ann_index);
|
||||||
return kTfLiteOk;
|
return kTfLiteOk;
|
||||||
}
|
}
|
||||||
@ -840,7 +873,7 @@ class NNAPIOpBuilder {
|
|||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context_,
|
context_,
|
||||||
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
||||||
nnapi_errno_);
|
"adding operand", nnapi_errno_);
|
||||||
const int ann_index = operand_mapping_->add_new_non_tensor_operand();
|
const int ann_index = operand_mapping_->add_new_non_tensor_operand();
|
||||||
augmented_outputs_.push_back(ann_index);
|
augmented_outputs_.push_back(ann_index);
|
||||||
if (ann_index_out) *ann_index_out = ann_index;
|
if (ann_index_out) *ann_index_out = ann_index;
|
||||||
@ -960,14 +993,14 @@ class NNAPIOpBuilder {
|
|||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context_,
|
context_,
|
||||||
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
nnapi_->ANeuralNetworksModel_addOperand(nn_model_, &operand_type),
|
||||||
nnapi_errno_);
|
"adding operand", nnapi_errno_);
|
||||||
|
|
||||||
if (nn_type == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
|
if (nn_type == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context_,
|
context_,
|
||||||
nnapi_->ANeuralNetworksModel_setOperandSymmPerChannelQuantParams(
|
nnapi_->ANeuralNetworksModel_setOperandSymmPerChannelQuantParams(
|
||||||
nn_model_, ann_tensor_index, &ann_perchannel_params),
|
nn_model_, ann_tensor_index, &ann_perchannel_params),
|
||||||
nnapi_errno_);
|
"setting new operand per channel quantization params", nnapi_errno_);
|
||||||
}
|
}
|
||||||
if (tensor->allocation_type == kTfLiteMmapRo) {
|
if (tensor->allocation_type == kTfLiteMmapRo) {
|
||||||
if (IsQuantized(tensor_type) && need_int8_conversion) {
|
if (IsQuantized(tensor_type) && need_int8_conversion) {
|
||||||
@ -1000,7 +1033,7 @@ class NNAPIOpBuilder {
|
|||||||
nnapi_->ANeuralNetworksModel_setOperandValue(
|
nnapi_->ANeuralNetworksModel_setOperandValue(
|
||||||
nn_model_, ann_tensor_index, new_tensor->data.raw,
|
nn_model_, ann_tensor_index, new_tensor->data.raw,
|
||||||
new_tensor->bytes),
|
new_tensor->bytes),
|
||||||
nnapi_errno_);
|
"setting new operand value", nnapi_errno_);
|
||||||
#ifdef TFLITE_NNAPI_ALLOW_MMAP_SHARING
|
#ifdef TFLITE_NNAPI_ALLOW_MMAP_SHARING
|
||||||
} else if (tensor->allocation &&
|
} else if (tensor->allocation &&
|
||||||
static_cast<const Allocation*>(tensor->allocation)->type() ==
|
static_cast<const Allocation*>(tensor->allocation)->type() ==
|
||||||
@ -1025,14 +1058,14 @@ class NNAPIOpBuilder {
|
|||||||
nnapi_->ANeuralNetworksModel_setOperandValueFromMemory(
|
nnapi_->ANeuralNetworksModel_setOperandValueFromMemory(
|
||||||
nn_model_, ann_tensor_index, ann_memory_handle, offset,
|
nn_model_, ann_tensor_index, ann_memory_handle, offset,
|
||||||
tensor->bytes),
|
tensor->bytes),
|
||||||
nnapi_errno_);
|
"setting new operand value from memory", nnapi_errno_);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context_,
|
context_,
|
||||||
nnapi_->ANeuralNetworksModel_setOperandValue(
|
nnapi_->ANeuralNetworksModel_setOperandValue(
|
||||||
nn_model_, ann_tensor_index, tensor->data.raw, tensor->bytes),
|
nn_model_, ann_tensor_index, tensor->data.raw, tensor->bytes),
|
||||||
nnapi_errno_);
|
"setting new operand value", nnapi_errno_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2910,8 +2943,9 @@ TfLiteStatus NNAPIDelegateKernel::Init(TfLiteContext* context,
|
|||||||
|
|
||||||
if (!nn_model_) {
|
if (!nn_model_) {
|
||||||
ANeuralNetworksModel* model = nullptr;
|
ANeuralNetworksModel* model = nullptr;
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(context,
|
||||||
context, nnapi_->ANeuralNetworksModel_create(&model), nnapi_errno);
|
nnapi_->ANeuralNetworksModel_create(&model),
|
||||||
|
"creating NNAPI model", nnapi_errno);
|
||||||
nn_model_.reset(model);
|
nn_model_.reset(model);
|
||||||
|
|
||||||
TF_LITE_ENSURE_STATUS(BuildGraph(context, params->input_tensors,
|
TF_LITE_ENSURE_STATUS(BuildGraph(context, params->input_tensors,
|
||||||
@ -2927,11 +2961,12 @@ TfLiteStatus NNAPIDelegateKernel::Init(TfLiteContext* context,
|
|||||||
nnapi_->ANeuralNetworksCompilation_createForDevices(
|
nnapi_->ANeuralNetworksCompilation_createForDevices(
|
||||||
nn_model_.get(), nnapi_devices_.data(), nnapi_devices_.size(),
|
nn_model_.get(), nnapi_devices_.data(), nnapi_devices_.size(),
|
||||||
&compilation),
|
&compilation),
|
||||||
nnapi_errno);
|
"creating NNAPI model for given devices", nnapi_errno);
|
||||||
} else {
|
} else {
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(context,
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(context,
|
||||||
nnapi_->ANeuralNetworksCompilation_create(
|
nnapi_->ANeuralNetworksCompilation_create(
|
||||||
nn_model_.get(), &compilation),
|
nn_model_.get(), &compilation),
|
||||||
|
"creating NNAPI compilation",
|
||||||
nnapi_errno);
|
nnapi_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2945,7 +2980,9 @@ TfLiteStatus NNAPIDelegateKernel::Init(TfLiteContext* context,
|
|||||||
nnapi_->ANeuralNetworksCompilation_free(compilation);
|
nnapi_->ANeuralNetworksCompilation_free(compilation);
|
||||||
compilation = nullptr;
|
compilation = nullptr;
|
||||||
}
|
}
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(context, preference_result, nnapi_errno);
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(context, preference_result,
|
||||||
|
"setting compilation preferences",
|
||||||
|
nnapi_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* cache_dir = delegate_options.cache_dir;
|
const char* cache_dir = delegate_options.cache_dir;
|
||||||
@ -2978,7 +3015,8 @@ TfLiteStatus NNAPIDelegateKernel::Init(TfLiteContext* context,
|
|||||||
nnapi_->ANeuralNetworksCompilation_free(compilation);
|
nnapi_->ANeuralNetworksCompilation_free(compilation);
|
||||||
compilation = nullptr;
|
compilation = nullptr;
|
||||||
}
|
}
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(context, set_caching_result, nnapi_errno);
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(context, set_caching_result,
|
||||||
|
"configuring NNAPI caching", nnapi_errno);
|
||||||
}
|
}
|
||||||
const int finish_result =
|
const int finish_result =
|
||||||
nnapi_->ANeuralNetworksCompilation_finish(compilation);
|
nnapi_->ANeuralNetworksCompilation_finish(compilation);
|
||||||
@ -2986,7 +3024,8 @@ TfLiteStatus NNAPIDelegateKernel::Init(TfLiteContext* context,
|
|||||||
nnapi_->ANeuralNetworksCompilation_free(compilation);
|
nnapi_->ANeuralNetworksCompilation_free(compilation);
|
||||||
compilation = nullptr;
|
compilation = nullptr;
|
||||||
}
|
}
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(context, finish_result, nnapi_errno);
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
|
context, finish_result, "completing NNAPI compilation", nnapi_errno);
|
||||||
nn_compilation_.reset(compilation);
|
nn_compilation_.reset(compilation);
|
||||||
}
|
}
|
||||||
return kTfLiteOk;
|
return kTfLiteOk;
|
||||||
@ -3007,7 +3046,7 @@ TfLiteStatus NNAPIDelegateKernel::Invoke(TfLiteContext* context,
|
|||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(context,
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(context,
|
||||||
nnapi_->ANeuralNetworksExecution_create(
|
nnapi_->ANeuralNetworksExecution_create(
|
||||||
nn_compilation_.get(), &execution),
|
nn_compilation_.get(), &execution),
|
||||||
nnapi_errno);
|
"creating NNAPI execution", nnapi_errno);
|
||||||
std::unique_ptr<ANeuralNetworksExecution, NNFreeExecution>
|
std::unique_ptr<ANeuralNetworksExecution, NNFreeExecution>
|
||||||
execution_unique_ptr(execution);
|
execution_unique_ptr(execution);
|
||||||
|
|
||||||
@ -3030,6 +3069,7 @@ TfLiteStatus NNAPIDelegateKernel::Invoke(TfLiteContext* context,
|
|||||||
execution, relative_input_index, nullptr,
|
execution, relative_input_index, nullptr,
|
||||||
tensor_memory_map_->at(tensor->buffer_handle).memory, 0,
|
tensor_memory_map_->at(tensor->buffer_handle).memory, 0,
|
||||||
tensor->bytes),
|
tensor->bytes),
|
||||||
|
"associating NNAPI execution input with a memory object",
|
||||||
nnapi_errno);
|
nnapi_errno);
|
||||||
relative_input_index++;
|
relative_input_index++;
|
||||||
continue;
|
continue;
|
||||||
@ -3077,6 +3117,7 @@ TfLiteStatus NNAPIDelegateKernel::Invoke(TfLiteContext* context,
|
|||||||
nnapi_->ANeuralNetworksExecution_setInputFromMemory(
|
nnapi_->ANeuralNetworksExecution_setInputFromMemory(
|
||||||
execution, relative_input_index, nullptr,
|
execution, relative_input_index, nullptr,
|
||||||
nn_input_memory_->get_handle(), input_offset, tensor_size),
|
nn_input_memory_->get_handle(), input_offset, tensor_size),
|
||||||
|
"associating NNAPI execution input with a memory object",
|
||||||
nnapi_errno);
|
nnapi_errno);
|
||||||
} else {
|
} else {
|
||||||
// copy data to pre-allocated shared memory.
|
// copy data to pre-allocated shared memory.
|
||||||
@ -3087,6 +3128,7 @@ TfLiteStatus NNAPIDelegateKernel::Invoke(TfLiteContext* context,
|
|||||||
nnapi_->ANeuralNetworksExecution_setInputFromMemory(
|
nnapi_->ANeuralNetworksExecution_setInputFromMemory(
|
||||||
execution, relative_input_index, nullptr,
|
execution, relative_input_index, nullptr,
|
||||||
nn_input_memory_->get_handle(), input_offset, tensor->bytes),
|
nn_input_memory_->get_handle(), input_offset, tensor->bytes),
|
||||||
|
"associating NNAPI execution input with a memory object",
|
||||||
nnapi_errno);
|
nnapi_errno);
|
||||||
tensor_size = tensor->bytes;
|
tensor_size = tensor->bytes;
|
||||||
}
|
}
|
||||||
@ -3114,7 +3156,7 @@ TfLiteStatus NNAPIDelegateKernel::Invoke(TfLiteContext* context,
|
|||||||
execution, relative_output_index, nullptr,
|
execution, relative_output_index, nullptr,
|
||||||
tensor_memory_map_->at(tensor->buffer_handle).memory, 0,
|
tensor_memory_map_->at(tensor->buffer_handle).memory, 0,
|
||||||
tensor->bytes),
|
tensor->bytes),
|
||||||
nnapi_errno);
|
"associating NNAPI execution output to a memory object", nnapi_errno);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
@ -3122,7 +3164,7 @@ TfLiteStatus NNAPIDelegateKernel::Invoke(TfLiteContext* context,
|
|||||||
nnapi_->ANeuralNetworksExecution_setOutputFromMemory(
|
nnapi_->ANeuralNetworksExecution_setOutputFromMemory(
|
||||||
execution, relative_output_index, nullptr,
|
execution, relative_output_index, nullptr,
|
||||||
nn_output_memory_->get_handle(), output_offset, tensor->bytes),
|
nn_output_memory_->get_handle(), output_offset, tensor->bytes),
|
||||||
nnapi_errno);
|
"associating NNAPI execution output to a memory object", nnapi_errno);
|
||||||
output_offset += tensor->bytes;
|
output_offset += tensor->bytes;
|
||||||
output_offset += getNumPaddingBytes(tensor->bytes);
|
output_offset += getNumPaddingBytes(tensor->bytes);
|
||||||
}
|
}
|
||||||
@ -3142,7 +3184,7 @@ TfLiteStatus NNAPIDelegateKernel::Invoke(TfLiteContext* context,
|
|||||||
nnapi_->ANeuralNetworksExecution_setOutput(
|
nnapi_->ANeuralNetworksExecution_setOutput(
|
||||||
execution, relative_output_index, nullptr, tensor->data.raw,
|
execution, relative_output_index, nullptr, tensor->data.raw,
|
||||||
tensor->bytes),
|
tensor->bytes),
|
||||||
nnapi_errno);
|
"associating NNAPI execution output to a buffer", nnapi_errno);
|
||||||
relative_output_index++;
|
relative_output_index++;
|
||||||
}
|
}
|
||||||
// Invoke ANN in blocking fashion.
|
// Invoke ANN in blocking fashion.
|
||||||
@ -3151,15 +3193,17 @@ TfLiteStatus NNAPIDelegateKernel::Invoke(TfLiteContext* context,
|
|||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context,
|
context,
|
||||||
nnapi_->ANeuralNetworksExecution_startCompute(execution, &event),
|
nnapi_->ANeuralNetworksExecution_startCompute(execution, &event),
|
||||||
nnapi_errno);
|
"starting async computation", nnapi_errno);
|
||||||
const int wait_result = nnapi_->ANeuralNetworksEvent_wait(event);
|
const int wait_result = nnapi_->ANeuralNetworksEvent_wait(event);
|
||||||
nnapi_->ANeuralNetworksEvent_free(event);
|
nnapi_->ANeuralNetworksEvent_free(event);
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(context, wait_result, nnapi_errno);
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(context, wait_result,
|
||||||
|
"waiting for async computation completion",
|
||||||
|
nnapi_errno);
|
||||||
} else {
|
} else {
|
||||||
// Use synchronous execution for NNAPI 1.2+.
|
// Use synchronous execution for NNAPI 1.2+.
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context, nnapi_->ANeuralNetworksExecution_compute(execution),
|
context, nnapi_->ANeuralNetworksExecution_compute(execution),
|
||||||
nnapi_errno);
|
"running computation", nnapi_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy results from shared memory to the destination.
|
// copy results from shared memory to the destination.
|
||||||
@ -3567,21 +3611,19 @@ TfLiteStatus NNAPIDelegateKernel::BuildGraph(
|
|||||||
nnapi_->ANeuralNetworksModel_identifyInputsAndOutputs(
|
nnapi_->ANeuralNetworksModel_identifyInputsAndOutputs(
|
||||||
nn_model_.get(), inputs.size(), inputs.data(), outputs.size(),
|
nn_model_.get(), inputs.size(), inputs.data(), outputs.size(),
|
||||||
outputs.data()),
|
outputs.data()),
|
||||||
nnapi_errno);
|
"identifying model inputs and outputs", nnapi_errno);
|
||||||
|
|
||||||
// Set relaxed computation mode for fp32 if possible.
|
|
||||||
if (nnapi_->android_sdk_version >= kMinSdkVersionForNNAPI11) {
|
if (nnapi_->android_sdk_version >= kMinSdkVersionForNNAPI11) {
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context,
|
context,
|
||||||
nnapi_->ANeuralNetworksModel_relaxComputationFloat32toFloat16(
|
nnapi_->ANeuralNetworksModel_relaxComputationFloat32toFloat16(
|
||||||
nn_model_.get(), context->allow_fp32_relax_to_fp16),
|
nn_model_.get(), context->allow_fp32_relax_to_fp16),
|
||||||
nnapi_errno);
|
"set relaxed computation mode for fp32 if possible", nnapi_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize the model
|
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context, nnapi_->ANeuralNetworksModel_finish(nn_model_.get()),
|
context, nnapi_->ANeuralNetworksModel_finish(nn_model_.get()),
|
||||||
nnapi_errno);
|
"finalizing the model", nnapi_errno);
|
||||||
|
|
||||||
// Create shared memory pool for inputs and outputs.
|
// Create shared memory pool for inputs and outputs.
|
||||||
nn_input_memory_.reset(
|
nn_input_memory_.reset(
|
||||||
@ -3740,7 +3782,7 @@ TfLiteStatus StatefulNnApiDelegate::DoPrepare(TfLiteContext* context,
|
|||||||
uint32_t device_count = 0;
|
uint32_t device_count = 0;
|
||||||
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
RETURN_TFLITE_ERROR_IF_NN_ERROR(
|
||||||
context, nnapi->ANeuralNetworks_getDeviceCount(&device_count),
|
context, nnapi->ANeuralNetworks_getDeviceCount(&device_count),
|
||||||
nnapi_errno);
|
"getting number of NNAPI devices", nnapi_errno);
|
||||||
if (device_count <= 1) {
|
if (device_count <= 1) {
|
||||||
return kTfLiteOk;
|
return kTfLiteOk;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ limitations under the License.
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
typedef struct AHardwareBuffer AHardwareBuffer;
|
typedef struct AHardwareBuffer AHardwareBuffer;
|
||||||
|
|
||||||
// NN api types based on NNAPI header file
|
// NN api types based on NNAPI header file
|
||||||
@ -159,6 +161,7 @@ enum {
|
|||||||
/**
|
/**
|
||||||
* Result codes.
|
* Result codes.
|
||||||
*/
|
*/
|
||||||
|
// LINT.IfChange
|
||||||
enum {
|
enum {
|
||||||
ANEURALNETWORKS_NO_ERROR = 0,
|
ANEURALNETWORKS_NO_ERROR = 0,
|
||||||
ANEURALNETWORKS_OUT_OF_MEMORY = 1,
|
ANEURALNETWORKS_OUT_OF_MEMORY = 1,
|
||||||
@ -171,6 +174,7 @@ enum {
|
|||||||
ANEURALNETWORKS_OUTPUT_INSUFFICIENT_SIZE = 8,
|
ANEURALNETWORKS_OUTPUT_INSUFFICIENT_SIZE = 8,
|
||||||
ANEURALNETWORKS_UNAVAILABLE_DEVICE = 9,
|
ANEURALNETWORKS_UNAVAILABLE_DEVICE = 9,
|
||||||
};
|
};
|
||||||
|
// LINT.ThenChange(//tensorflow/lite/delegates/nnapi/nnapi_delegate.cc:NnApiErrorDescription)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implicit padding algorithms.
|
* Implicit padding algorithms.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user