xref: /aosp_15_r20/external/executorch/backends/qualcomm/runtime/backends/QnnBackendCommon.cpp (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
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