Skip to content

Commit

Permalink
[QNN EP] Improve QNN error reporting using the error message (#21458)
Browse files Browse the repository at this point in the history
### Description

Massively improve the QNN error reporting by invoking
`QnnError_getMessage` and returning the error message.


### Motivation and Context
<!-- - Why is this change required? What problem does it solve?
- If it fixes an open issue, please link to the issue here. -->

Example error message before this change:

```text
QNN SetupBackend failed Failed to create device. Error: 14001
```

After:

```text
QNN SetupBackend failed Failed to create device. Error: QNN_DEVICE_ERROR_INVALID_CONFIG: Invalid config values
```
  • Loading branch information
skyline75489 authored Jul 24, 2024
1 parent 0274008 commit 6794dfd
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 23 deletions.
55 changes: 32 additions & 23 deletions onnxruntime/core/providers/qnn/builder/qnn_backend_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ Status QnnBackendManager::InitializeQnnLog() {
}
}

ORT_RETURN_IF(QNN_BACKEND_NO_ERROR != result, "Failed to initialize logging in the QNN backend");
ORT_RETURN_IF(QNN_BACKEND_NO_ERROR != result, "Failed to initialize logging in the QNN backend. Error: ", QnnErrorHandleToString(result));
return Status::OK();
}

Expand Down Expand Up @@ -320,7 +320,7 @@ Status QnnBackendManager::UpdateQnnLogLevel(logging::Severity ort_log_level) {
LOGS(*logger_, ERROR) << "Invalid log handle provided to QnnLog_setLogLevel.";
}
}
ORT_RETURN_IF(QNN_BACKEND_NO_ERROR != result, "Failed to set log level in Qnn backend");
ORT_RETURN_IF(QNN_BACKEND_NO_ERROR != result, "Failed to set log level in Qnn backend. Error: ", QnnErrorHandleToString(result));
return Status::OK();
}

Expand All @@ -330,8 +330,8 @@ Status QnnBackendManager::InitializeBackend() {
return Status::OK();
}

auto result = qnn_interface_.backendCreate(log_handle_, (const QnnBackend_Config_t**)backend_config_, &backend_handle_);
ORT_RETURN_IF(QNN_BACKEND_NO_ERROR != result, "Failed to initialize backend");
Qnn_ErrorHandle_t result = qnn_interface_.backendCreate(log_handle_, (const QnnBackend_Config_t**)backend_config_, &backend_handle_);
ORT_RETURN_IF(QNN_BACKEND_NO_ERROR != result, "Failed to initialize backend. Error: ", QnnErrorHandleToString(result));

backend_initialized_ = true;
return Status::OK();
Expand Down Expand Up @@ -406,9 +406,9 @@ Status QnnBackendManager::CreateDevice() {

LOGS_DEFAULT(INFO) << "Create device.";
if (nullptr != qnn_interface_.deviceCreate) {
auto result = qnn_interface_.deviceCreate(log_handle_, device_configs_builder.GetQnnConfigs(), &device_handle_);
Qnn_ErrorHandle_t result = qnn_interface_.deviceCreate(log_handle_, device_configs_builder.GetQnnConfigs(), &device_handle_);
if (QNN_SUCCESS != result) {
return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Failed to create device. Error: ", result);
return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Failed to create device. Error: ", QnnErrorHandleToString(result));
}
}
device_created_ = true;
Expand All @@ -422,9 +422,9 @@ Status QnnBackendManager::ReleaseDevice() {
}

if (nullptr != qnn_interface_.deviceFree) {
auto result = qnn_interface_.deviceFree(device_handle_);
Qnn_ErrorHandle_t result = qnn_interface_.deviceFree(device_handle_);
if (QNN_SUCCESS != result) {
return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Failed to release device. Error: ", result);
return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Failed to release device. Error: ", QnnErrorHandleToString(result));
}
}

Expand All @@ -451,8 +451,8 @@ Status QnnBackendManager::InitializeProfiling() {
} else if (ProfilingLevel::DETAILED == profiling_level_merge_) {
qnn_profile_level = QNN_PROFILE_LEVEL_DETAILED;
}
auto result = qnn_interface_.profileCreate(backend_handle_, qnn_profile_level, &profile_backend_handle_);
ORT_RETURN_IF(QNN_PROFILE_NO_ERROR != result, "Failed to create QNN profile!");
Qnn_ErrorHandle_t result = qnn_interface_.profileCreate(backend_handle_, qnn_profile_level, &profile_backend_handle_);
ORT_RETURN_IF(QNN_PROFILE_NO_ERROR != result, "Failed to create QNN profile! Error: ", QnnErrorHandleToString(result));

return Status::OK();
}
Expand Down Expand Up @@ -525,13 +525,13 @@ Status QnnBackendManager::CreateContext() {
const QnnContext_Config_t* context_configs[] = {&qnn_context_config, nullptr};

Qnn_ContextHandle_t context = nullptr;
auto result = qnn_interface_.contextCreate(backend_handle_,
device_handle_,
context_configs,
&context);
Qnn_ErrorHandle_t result = qnn_interface_.contextCreate(backend_handle_,
device_handle_,
context_configs,
&context);
contexts_.push_back(context);

ORT_RETURN_IF(QNN_CONTEXT_NO_ERROR != result, "Failed to create context.");
ORT_RETURN_IF(QNN_CONTEXT_NO_ERROR != result, "Failed to create context. Error: ", QnnErrorHandleToString(result));

context_created_ = true;
return Status::OK();
Expand All @@ -544,7 +544,7 @@ Status QnnBackendManager::ReleaseContext() {

bool failed = false;
for (auto context : contexts_) {
auto result = qnn_interface_.contextFree(context, nullptr);
Qnn_ErrorHandle_t result = qnn_interface_.contextFree(context, nullptr);
if (QNN_CONTEXT_NO_ERROR != result) {
failed = true;
}
Expand All @@ -566,7 +566,7 @@ std::unique_ptr<unsigned char[]> QnnBackendManager::GetContextBinaryBuffer(uint6
// Generate all graphs in one single context
Qnn_ErrorHandle_t rt = qnn_interface_.contextGetBinarySize(contexts_[0], &required_buffer_size);
if (QNN_CONTEXT_NO_ERROR != rt) {
LOGS(*logger_, ERROR) << "Failed to get QNN context binary size. Error code: " << rt;
LOGS(*logger_, ERROR) << "Failed to get QNN context binary size. Error: " << QnnErrorHandleToString(rt);
return nullptr;
}

Expand All @@ -581,7 +581,7 @@ std::unique_ptr<unsigned char[]> QnnBackendManager::GetContextBinaryBuffer(uint6
required_buffer_size,
&written_buffer_size);
if (QNN_CONTEXT_NO_ERROR != rt) {
LOGS(*logger_, ERROR) << "Failed to get context binary.";
LOGS(*logger_, ERROR) << "Failed to get context binary. Error: " << QnnErrorHandleToString(rt);
return nullptr;
}

Expand Down Expand Up @@ -1014,8 +1014,8 @@ Status QnnBackendManager::ExtractBackendProfilingInfo() {

const QnnProfile_EventId_t* profile_events{nullptr};
uint32_t num_events{0};
auto result = qnn_interface_.profileGetEvents(profile_backend_handle_, &profile_events, &num_events);
ORT_RETURN_IF(QNN_PROFILE_NO_ERROR != result, "Failed to get profile events.");
Qnn_ErrorHandle_t result = qnn_interface_.profileGetEvents(profile_backend_handle_, &profile_events, &num_events);
ORT_RETURN_IF(QNN_PROFILE_NO_ERROR != result, "Failed to get profile events. Error: ", QnnErrorHandleToString(result));

if (num_events > 0) {
LOGS(*logger_, VERBOSE) << "profile_events: " << profile_events << " num_events: " << num_events;
Expand Down Expand Up @@ -1073,8 +1073,8 @@ Status QnnBackendManager::ExtractProfilingSubEvents(
bool tracelogging_provider_ep_enabled) {
const QnnProfile_EventId_t* profile_sub_events{nullptr};
uint32_t num_sub_events{0};
auto result = qnn_interface_.profileGetSubEvents(profile_event_id, &profile_sub_events, &num_sub_events);
ORT_RETURN_IF(QNN_PROFILE_NO_ERROR != result, "Failed to get profile sub events.");
Qnn_ErrorHandle_t result = qnn_interface_.profileGetSubEvents(profile_event_id, &profile_sub_events, &num_sub_events);
ORT_RETURN_IF(QNN_PROFILE_NO_ERROR != result, "Failed to get profile sub events. Error: ", QnnErrorHandleToString(result));

if (num_sub_events > 0) {
LOGS(*logger_, VERBOSE) << "profile_sub_events: " << profile_sub_events << " num_sub_events: " << num_sub_events;
Expand Down Expand Up @@ -1113,7 +1113,7 @@ Status QnnBackendManager::ExtractProfilingEventBasic(
std::ofstream& outfile,
bool tracelogging_provider_ep_enabled) {
QnnProfile_EventData_t event_data;
auto result = qnn_interface_.profileGetEventData(profile_event_id, &event_data);
Qnn_ErrorHandle_t result = qnn_interface_.profileGetEventData(profile_event_id, &event_data);
QnnProfile_Error_t errorCode = static_cast<QnnProfile_Error_t>(result & 0xFFFF);
ORT_RETURN_IF(QNN_PROFILE_NO_ERROR != result, "Failed to get profile event data: " + std::string(QnnProfileErrorToString(errorCode)));

Expand Down Expand Up @@ -1293,6 +1293,15 @@ const char* QnnBackendManager::QnnProfileErrorToString(QnnProfile_Error_t error)
}
}

const char* QnnBackendManager::QnnErrorHandleToString(Qnn_ErrorHandle_t error) {
// From QNN SDK: The memory is statically owned and should not be freed by the caller.
const char* error_msg = nullptr;
if (QNN_SUCCESS == qnn_interface_.errorGetMessage(error, &error_msg)) {
return error_msg;
}
return "Unknown";
}

const std::string QnnBackendManager::ExtractQnnScalarValue(const Qnn_Scalar_t& scalar) {
switch (scalar.dataType) {
case QNN_DATATYPE_INT_8:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ class QnnBackendManager {
static const std::string GetEventTypeString(QnnProfile_EventType_t eventType);
static const std::string ExtractQnnScalarValue(const Qnn_Scalar_t& scalar);
const char* QnnProfileErrorToString(QnnProfile_Error_t error);
const char* QnnErrorHandleToString(Qnn_ErrorHandle_t error);
QnnLog_Level_t MapOrtSeverityToQNNLogLevel(logging::Severity ort_log_level);
#ifdef _WIN32
void LogQnnProfileEventAsTraceLogging(
Expand Down

0 comments on commit 6794dfd

Please sign in to comment.