Skip to content

Commit

Permalink
Qualcomm AI Engine Direct - Check the version QNN API and backend API (
Browse files Browse the repository at this point in the history
…pytorch#4998)

Summary:
QNN API version format is major.minor.patch.
If major given by the user does not match the built major, it will
return and show error message.
If minor does not match, it will show warning message.
  • Loading branch information
shewu-quic authored Aug 30, 2024
1 parent 1263964 commit b95e4b3
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 2 deletions.
3 changes: 3 additions & 0 deletions backends/qualcomm/runtime/QnnManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <executorch/backends/qualcomm/runtime/QnnManager.h>
#include <executorch/backends/qualcomm/runtime/SharedBuffer.h>
#include <executorch/backends/qualcomm/runtime/Utils.h>
#include <executorch/backends/qualcomm/runtime/backends/QnnBackendCommon.h>
#include <executorch/backends/qualcomm/runtime/backends/QnnImplementation.h>
#include <algorithm>
#include <cstdlib>
Expand Down Expand Up @@ -281,6 +282,8 @@ Error QnnManager::Init() {
options_->backend_options()->backend_type());
backend_params_ptr_ = QnnBackendFactory().Create(
qnn_loaded_backend_, logger_.get(), qnn_context_blob_, options_);
ET_CHECK_OR_RETURN_ERROR(
backend_params_ptr_ != nullptr, Internal, "Failed to load Qnn backend.")
ET_CHECK_OR_RETURN_ERROR(
backend_params_ptr_->qnn_backend_ptr_->Configure() == Error::Ok,
Internal,
Expand Down
79 changes: 79 additions & 0 deletions backends/qualcomm/runtime/backends/QnnBackendCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,85 @@ Error QnnBackend::Configure() {
}
return Error::Ok;
}

Error QnnBackend::VerifyQNNSDKVersion(
const QnnExecuTorchBackendType backend_id) {
const QnnInterface& qnn_interface = implementation_.GetQnnInterface();

Qnn_ApiVersion_t qnn_version = {QNN_VERSION_INIT};
Qnn_ErrorHandle_t error =
qnn_interface.qnn_backend_get_api_version(&qnn_version);
if (error != QNN_SUCCESS) {
QNN_EXECUTORCH_LOG_ERROR("Failed to get Qnn API version.");
return Error::Internal;
}

Qnn_ApiVersion_t expected_version = {QNN_VERSION_INIT};
expected_version.coreApiVersion.major = QNN_API_VERSION_MAJOR;
expected_version.coreApiVersion.minor = QNN_API_VERSION_MINOR;
expected_version.coreApiVersion.patch = QNN_API_VERSION_PATCH;
expected_version.backendApiVersion = GetExpectedBackendVersion();
const char* backend_type = EnumNameQnnExecuTorchBackendType(backend_id);

Error status = VersionChecker(
qnn_version.coreApiVersion, expected_version.coreApiVersion, "Qnn API");
if (status == Error::Ok) {
status = VersionChecker(
qnn_version.backendApiVersion,
expected_version.backendApiVersion,
backend_type);
}

return status;
}

Error QnnBackend::VersionChecker(
const Qnn_Version_t& qnn_version,
const Qnn_Version_t& expected,
const std::string& prefix) {
if (qnn_version.major != expected.major) {
QNN_EXECUTORCH_LOG_ERROR(
"%s version %u.%u.%u is not supported. "
"The minimum supported version is %u.%u.%u. Please make "
"sure you have the correct backend library version.",
prefix.c_str(),
qnn_version.major,
qnn_version.minor,
qnn_version.patch,
expected.major,
expected.minor,
expected.patch);
return Error::Internal;
}
if (qnn_version.major == QNN_API_VERSION_MAJOR &&
qnn_version.minor < expected.minor) {
QNN_EXECUTORCH_LOG_WARN(
"%s version %u.%u.%u is mismatched. "
"The minimum supported version is %u.%u.%u. Please make "
"sure you have the correct backend library version.",
prefix.c_str(),
qnn_version.major,
qnn_version.minor,
qnn_version.patch,
expected.major,
expected.minor,
expected.patch);
}
if ((qnn_version.major == QNN_API_VERSION_MAJOR &&
qnn_version.minor > expected.minor)) {
QNN_EXECUTORCH_LOG_WARN(
"%s version %u.%u.%u is used. "
"The version is tested against %u.%u.%u.",
prefix.c_str(),
qnn_version.major,
qnn_version.minor,
qnn_version.patch,
expected.major,
expected.minor,
expected.patch);
}
return Error::Ok;
}
} // namespace qnn
} // namespace executor
} // namespace torch
9 changes: 9 additions & 0 deletions backends/qualcomm/runtime/backends/QnnBackendCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@

#include <vector>

#include "HTP/QnnHtpCommon.h"
#include "QnnBackend.h"
#include "QnnCommon.h"
#include "QnnTypes.h"
namespace torch {
namespace executor {
namespace qnn {
Expand Down Expand Up @@ -43,7 +45,10 @@ class QnnBackend {
return handle_;
}

Error VerifyQNNSDKVersion(const QnnExecuTorchBackendType backend_id);

protected:
virtual Qnn_Version_t GetExpectedBackendVersion() const = 0;
virtual Error MakeConfig(std::vector<const QnnBackend_Config_t*>& config) {
return Error::Ok;
};
Expand All @@ -52,6 +57,10 @@ class QnnBackend {
Qnn_BackendHandle_t handle_;
const QnnImplementation& implementation_;
QnnLogger* logger_;
Error VersionChecker(
const Qnn_Version_t& qnn_version,
const Qnn_Version_t& expected,
const std::string& prefix);
};
} // namespace qnn
} // namespace executor
Expand Down
9 changes: 7 additions & 2 deletions backends/qualcomm/runtime/backends/QnnBackendFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ std::unique_ptr<BackendConfigParameters> QnnBackendFactory::Create(
const QnnExecuTorchContextBinary& qnn_context_blob,
const QnnExecuTorchOptions* options) {
auto backend_params = std::make_unique<BackendConfigParameters>();

switch (options->backend_options()->backend_type()) {
case QnnExecuTorchBackendType::kHtpBackend: {
auto htp_options = options->backend_options()->htp_options();
Expand Down Expand Up @@ -51,6 +52,7 @@ std::unique_ptr<BackendConfigParameters> QnnBackendFactory::Create(
}
backend_params->qnn_backend_ptr_ =
std::make_unique<HtpBackend>(implementation, logger);

backend_params->qnn_device_ptr_ = std::make_unique<HtpDevice>(
implementation, logger, options->soc_info(), htp_options);

Expand All @@ -72,7 +74,6 @@ std::unique_ptr<BackendConfigParameters> QnnBackendFactory::Create(
backend_params->qnn_mem_manager_ptr_ = std::make_unique<QnnMemManager>(
implementation, backend_params->qnn_context_ptr_.get());
backend_params->backend_init_state_ = BackendInitializeState::INITIALIZED;
return backend_params;
} break;
case QnnExecuTorchBackendType::kGpuBackend:
case QnnExecuTorchBackendType::kDspBackend:
Expand All @@ -81,7 +82,11 @@ std::unique_ptr<BackendConfigParameters> QnnBackendFactory::Create(
return nullptr;
}

// should not reach here
if (backend_params->qnn_backend_ptr_->VerifyQNNSDKVersion(
options->backend_options()->backend_type()) == Error::Ok) {
return backend_params;
}

return nullptr;
}
} // namespace qnn
Expand Down
10 changes: 10 additions & 0 deletions backends/qualcomm/runtime/backends/htpbackend/HtpBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#pragma once

#include <executorch/backends/qualcomm/runtime/backends/QnnBackendCommon.h>
#include "HTP/QnnHtpCommon.h"
#include "HTP/QnnHtpProfile.h"
#include "QnnTypes.h"
namespace torch {
namespace executor {
namespace qnn {
Expand All @@ -24,6 +26,14 @@ class HtpBackend : public QnnBackend {
event_type == QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_ACCEL_TIME_CYCLE);
}

Qnn_Version_t GetExpectedBackendVersion() const override {
Qnn_Version_t backend_version;
backend_version.major = QNN_HTP_API_VERSION_MAJOR;
backend_version.minor = QNN_HTP_API_VERSION_MINOR;
backend_version.patch = QNN_HTP_API_VERSION_PATCH;
return backend_version;
}

protected:
Error MakeConfig(std::vector<const QnnBackend_Config_t*>& config) override {
return Error::Ok;
Expand Down

0 comments on commit b95e4b3

Please sign in to comment.