1 /*
2 * Copyright (c) Qualcomm Innovation Center, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8 #include <executorch/backends/qualcomm/runtime/backends/QnnBackendCommon.h>
9 namespace executorch {
10 namespace backends {
11 namespace qnn {
12
13 using executorch::runtime::Error;
14
~QnnBackend()15 QnnBackend::~QnnBackend() {
16 const QnnInterface& qnn_interface = implementation_.GetQnnInterface();
17 Qnn_ErrorHandle_t error = QNN_SUCCESS;
18 if (nullptr != handle_) {
19 QNN_EXECUTORCH_LOG_INFO("Destroy Qnn backend");
20 error = qnn_interface.qnn_backend_free(handle_);
21 if (error != QNN_SUCCESS) {
22 QNN_EXECUTORCH_LOG_ERROR(
23 "Failed to free QNN "
24 "backend_handle. Backend "
25 "ID %u, error %d",
26 qnn_interface.GetBackendId(),
27 QNN_GET_ERROR_CODE(error));
28 }
29 handle_ = nullptr;
30 }
31 }
32
Configure()33 Error QnnBackend::Configure() {
34 // create qnn backend
35 const QnnInterface& qnn_interface = implementation_.GetQnnInterface();
36 Qnn_ErrorHandle_t error = QNN_SUCCESS;
37
38 std::vector<const QnnBackend_Config_t*> temp_backend_config;
39 ET_CHECK_OR_RETURN_ERROR(
40 MakeConfig(temp_backend_config) == Error::Ok,
41 Internal,
42 "Fail to make backend config.");
43
44 error = qnn_interface.qnn_backend_create(
45 logger_->GetHandle(),
46 temp_backend_config.empty() ? nullptr : temp_backend_config.data(),
47 &handle_);
48 if (error != QNN_SUCCESS) {
49 QNN_EXECUTORCH_LOG_ERROR(
50 "Failed to create "
51 "backend_handle for Backend "
52 "ID %u, error=%d",
53 qnn_interface.GetBackendId(),
54 QNN_GET_ERROR_CODE(error));
55 return Error::Internal;
56 }
57 return Error::Ok;
58 }
59
VerifyQNNSDKVersion(const QnnExecuTorchBackendType backend_id)60 Error QnnBackend::VerifyQNNSDKVersion(
61 const QnnExecuTorchBackendType backend_id) {
62 const QnnInterface& qnn_interface = implementation_.GetQnnInterface();
63
64 Qnn_ApiVersion_t qnn_version = {QNN_VERSION_INIT};
65 Qnn_ErrorHandle_t error =
66 qnn_interface.qnn_backend_get_api_version(&qnn_version);
67 if (error != QNN_SUCCESS) {
68 QNN_EXECUTORCH_LOG_ERROR("Failed to get Qnn API version.");
69 return Error::Internal;
70 }
71
72 Qnn_ApiVersion_t expected_version = {QNN_VERSION_INIT};
73 expected_version.coreApiVersion.major = QNN_API_VERSION_MAJOR;
74 expected_version.coreApiVersion.minor = QNN_API_VERSION_MINOR;
75 expected_version.coreApiVersion.patch = QNN_API_VERSION_PATCH;
76 expected_version.backendApiVersion = GetExpectedBackendVersion();
77 const char* backend_type = EnumNameQnnExecuTorchBackendType(backend_id);
78
79 Error status = VersionChecker(
80 qnn_version.coreApiVersion, expected_version.coreApiVersion, "Qnn API");
81 if (status == Error::Ok) {
82 status = VersionChecker(
83 qnn_version.backendApiVersion,
84 expected_version.backendApiVersion,
85 backend_type);
86 }
87
88 return status;
89 }
90
VersionChecker(const Qnn_Version_t & qnn_version,const Qnn_Version_t & expected,const std::string & prefix)91 Error QnnBackend::VersionChecker(
92 const Qnn_Version_t& qnn_version,
93 const Qnn_Version_t& expected,
94 const std::string& prefix) {
95 if (qnn_version.major != expected.major) {
96 QNN_EXECUTORCH_LOG_ERROR(
97 "%s version %u.%u.%u is not supported. "
98 "The minimum supported version is %u.%u.%u. Please make "
99 "sure you have the correct backend library version.",
100 prefix.c_str(),
101 qnn_version.major,
102 qnn_version.minor,
103 qnn_version.patch,
104 expected.major,
105 expected.minor,
106 expected.patch);
107 return Error::Internal;
108 }
109 if (qnn_version.major == QNN_API_VERSION_MAJOR &&
110 qnn_version.minor < expected.minor) {
111 QNN_EXECUTORCH_LOG_WARN(
112 "%s version %u.%u.%u is mismatched. "
113 "The minimum supported version is %u.%u.%u. Please make "
114 "sure you have the correct backend library version.",
115 prefix.c_str(),
116 qnn_version.major,
117 qnn_version.minor,
118 qnn_version.patch,
119 expected.major,
120 expected.minor,
121 expected.patch);
122 }
123 if ((qnn_version.major == QNN_API_VERSION_MAJOR &&
124 qnn_version.minor > expected.minor)) {
125 QNN_EXECUTORCH_LOG_WARN(
126 "%s version %u.%u.%u is used. "
127 "The version is tested against %u.%u.%u.",
128 prefix.c_str(),
129 qnn_version.major,
130 qnn_version.minor,
131 qnn_version.patch,
132 expected.major,
133 expected.minor,
134 expected.patch);
135 }
136 return Error::Ok;
137 }
138 } // namespace qnn
139 } // namespace backends
140 } // namespace executorch
141