Skip to content

Commit 3a6e400

Browse files
Qualcomm AI Engine Direct - Refactor QnnDlcManager (#19105)
### Summary Refactor Dlc manager from experimental API to formal one. #### Reference https://docs.qualcomm.com/doc/80-63442-10/topic/function_QnnSystemDlc_8h_1ad09233e5a66c421e0e80f4cdbf4c1b7e.html https://docs.qualcomm.com/doc/80-63442-10/topic/function_QnnSystemDlc_8h_1aa3fcdf5c15256a69d445fc2a8c7a0e60.html ### Test plan There is a unit test for online prepare already. cc @cccclai @cbilgin @abhinaykukkadapu
1 parent 3a8d719 commit 3a6e400

22 files changed

Lines changed: 154 additions & 146 deletions

backends/qualcomm/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ endif()
109109

110110
include_directories(
111111
BEFORE ${_common_include_directories} ${QNN_SDK_ROOT}/include/QNN
112-
${QNN_SDK_ROOT}/share/QNN/converter/jni
113112
${EXECUTORCH_SOURCE_DIR}/runtime/core/portable_type/c10
114113
)
115114

backends/qualcomm/export_utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@ def __init__(
311311
traditional_general_artifacts = [
312312
f"{self.qnn_sdk}/lib/{self.target}/libQnnSystem.so",
313313
f"{self.build_path}/backends/qualcomm/libqnn_executorch_backend.so",
314-
f"{self.qnn_sdk}/lib/{self.target}/libQnnModelDlc.so",
315314
]
316315
self.backend_library_paths.update(
317316
{

backends/qualcomm/runtime/QnnManager.cpp

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ Error QnnManager::InitContext(
246246
options_->backend_options()->backend_type());
247247
backend_params_ptr_ = QnnBackendFactory().Create(
248248
backend_bundle_ptr_->implementation.get(),
249+
backend_bundle_ptr_->system_implementation.get(),
249250
backend_bundle_ptr_->qnn_backend_ptr.get(),
250251
backend_bundle_ptr_->qnn_device_ptr.get(),
251252
qnn_context_blob_,
@@ -279,7 +280,10 @@ Error QnnManager::InitContext(
279280
BackendInitializeState::INITIALIZED;
280281
}
281282

282-
if (IsOnlinePrepare()) {
283+
if (IsOnlinePrepare() &&
284+
backend_params_ptr_->qnn_backend_cache_ptr_->GetCacheState() ==
285+
QnnBackendCache::SERIALIZE) {
286+
// Set up DLC environment at AOT time
283287
// Check whether the QNN version supports the DLC format.
284288
Qnn_ApiVersion_t qnn_version = {QNN_VERSION_INIT};
285289
backend_bundle_ptr_->implementation->GetQnnInterface()
@@ -304,6 +308,7 @@ Error QnnManager::InitContextCache() {
304308
options_->backend_options()->backend_type());
305309
backend_params_ptr_ = QnnBackendFactory().Create(
306310
backend_bundle_ptr_->implementation.get(),
311+
backend_bundle_ptr_->system_implementation.get(),
307312
backend_bundle_ptr_->qnn_backend_ptr.get(),
308313
backend_bundle_ptr_->qnn_device_ptr.get(),
309314
qnn_context_blob_,
@@ -476,9 +481,9 @@ Error QnnManager::ProfileExecuteData(
476481
}
477482

478483
void QnnManager::Destroy() {
484+
qnn_dlc_manager_->Destroy();
479485
backend_params_ptr_.reset(new BackendConfigParameters());
480486
backend_bundle_ptr_.reset(new QnnBackendBundle());
481-
qnn_dlc_manager_->Destroy();
482487
}
483488

484489
void QnnManager::DestroyContext() {
@@ -539,12 +544,25 @@ Error QnnManager::GetContextBinary(
539544

540545
Error QnnManager::CompileDlc() {
541546
Qnn_ErrorHandle_t error;
542-
auto qnn_dlc_graph_info = qnn_dlc_manager_->GetQnnDlcGraphInfoPtr();
543-
uint32_t qnn_dlc_graph_info_num = qnn_dlc_manager_->GetQnnDlcGraphInfoNum();
544-
for (uint32_t i = 0; i < qnn_dlc_graph_info_num; ++i) {
545-
auto& graphInfo = (*qnn_dlc_graph_info)[i];
547+
auto graphs = qnn_dlc_manager_->GetQnnDlcGraphInfoPtr();
548+
uint32_t num_graphs = qnn_dlc_manager_->GetQnnDlcGraphInfoNum();
549+
for (uint32_t i = 0; i < num_graphs; ++i) {
550+
auto& graphInfo = graphs[i].graphInfoV1;
551+
Qnn_GraphHandle_t graphHandle;
552+
error = backend_bundle_ptr_->implementation->GetQnnInterface()
553+
.qnn_graph_retrieve(
554+
backend_params_ptr_->qnn_context_ptr_->GetHandle(),
555+
graphInfo.graphName,
556+
&graphHandle);
557+
if (error != QNN_SUCCESS) {
558+
QNN_EXECUTORCH_LOG_ERROR(
559+
"Failed to retrieve graph %s. Error %d.",
560+
graphInfo.graphName,
561+
QNN_GET_ERROR_CODE(error));
562+
return Error::Internal;
563+
}
546564
backend_params_ptr_->qnn_graph_ptr_->SetGraphHandle(
547-
graphInfo.graphName, graphInfo.graph);
565+
graphInfo.graphName, graphHandle);
548566
error =
549567
backend_params_ptr_->qnn_graph_ptr_->GraphFinalize(graphInfo.graphName);
550568
if (error != QNN_SUCCESS) {
@@ -559,9 +577,9 @@ Error QnnManager::CompileDlc() {
559577

560578
// Mapping memory address for the input and output of mutable buffer
561579
std::unordered_map<int, const void*> mutable_buffer_id_to_memory_map;
562-
for (uint32_t i = 0; i < graphInfo.numInputTensors; ++i) {
563-
auto tw = CreateTensorWrapper(graphInfo.inputTensors[i]);
564-
tw->UpdateQnnTensorMeta(graphInfo.inputTensors[i]);
580+
for (uint32_t i = 0; i < graphInfo.numGraphInputs; ++i) {
581+
auto tw = CreateTensorWrapper(graphInfo.graphInputs[i]);
582+
tw->UpdateQnnTensorMeta(graphInfo.graphInputs[i]);
565583

566584
int mutable_buffer_id = ExtractMutableBufferNumber(tw->GetName());
567585
if (mutable_buffer_id != -1) {
@@ -572,9 +590,9 @@ Error QnnManager::CompileDlc() {
572590
}
573591
graph_inputs.push_back(tw);
574592
}
575-
for (uint32_t i = 0; i < graphInfo.numOutputTensors; ++i) {
576-
auto tw = CreateTensorWrapper(graphInfo.outputTensors[i]);
577-
tw->UpdateQnnTensorMeta(graphInfo.outputTensors[i]);
593+
for (uint32_t i = 0; i < graphInfo.numGraphOutputs; ++i) {
594+
auto tw = CreateTensorWrapper(graphInfo.graphOutputs[i]);
595+
tw->UpdateQnnTensorMeta(graphInfo.graphOutputs[i]);
578596
int mutable_buffer_id = ExtractMutableBufferNumber(tw->GetName());
579597
if (mutable_buffer_id != -1 &&
580598
mutable_buffer_id_to_memory_map.find(mutable_buffer_id) !=

backends/qualcomm/runtime/backends/QnnBackendCache.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Error QnnBackendCache::GetQnnGraphInfoFromBinary(
1919
void* buffer,
2020
uint32_t nbytes) {
2121
const QnnSystemInterface& qnn_sys_interface =
22-
qnn_sys_impl_.GetQnnSystemInterface();
22+
qnn_sys_impl_->GetQnnSystemInterface();
2323
std::uint32_t num_graphs;
2424
QnnSystemContext_GraphInfo_t* graphs = nullptr;
2525
const QnnSystemContext_BinaryInfo_t* binaryinfo{nullptr};
@@ -88,18 +88,11 @@ Error QnnBackendCache::Configure(const std::vector<std::string>& graph_names) {
8888
return Error::Ok;
8989
}
9090

91-
if (qnn_sys_impl_.Load() != Error::Ok) {
92-
QNN_EXECUTORCH_LOG_ERROR(
93-
"Failed to Load QnnSystem "
94-
"APIs. Caching mechanism is being disabled.");
95-
return Error::Internal;
96-
}
97-
9891
Qnn_ErrorHandle_t error = QNN_SUCCESS;
9992

10093
// create QNN SystemContext
10194
const QnnSystemInterface& qnn_sys_interface =
102-
qnn_sys_impl_.GetQnnSystemInterface();
95+
qnn_sys_impl_->GetQnnSystemInterface();
10396
error = qnn_sys_interface.qnn_system_context_create(&sys_context_handle_);
10497

10598
if (error != QNN_SUCCESS) {
@@ -137,14 +130,13 @@ QnnBackendCache::~QnnBackendCache() {
137130
Qnn_ErrorHandle_t error = QNN_SUCCESS;
138131
if (sys_context_handle_ != nullptr) {
139132
const QnnSystemInterface& qnn_sys_interface =
140-
qnn_sys_impl_.GetQnnSystemInterface();
133+
qnn_sys_impl_->GetQnnSystemInterface();
141134
error = qnn_sys_interface.qnn_system_context_free(sys_context_handle_);
142135
if (error != QNN_SUCCESS) {
143136
QNN_EXECUTORCH_LOG_WARN("Failed to free QNN system context.");
144137
}
145138
sys_context_handle_ = nullptr;
146139
}
147-
qnn_sys_impl_.Unload();
148140
}
149141

150142
std::vector<Qnn_Tensor_t> QnnBackendCache::GetGraphInputs(

backends/qualcomm/runtime/backends/QnnBackendCache.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ class QnnBackendCache {
2626
ONLINE_PREPARE = 3,
2727
MULTI_GRAPH = 4,
2828
};
29-
explicit QnnBackendCache(const QnnExecuTorchContextBinary& qnn_context_blob)
30-
: qnn_context_blob_(qnn_context_blob) {}
29+
explicit QnnBackendCache(
30+
const QnnExecuTorchContextBinary& qnn_context_blob,
31+
QnnSystemImplementation* qnn_sys_impl)
32+
: qnn_sys_impl_(qnn_sys_impl), qnn_context_blob_(qnn_context_blob) {}
3133
virtual ~QnnBackendCache();
3234
QnnBackendCache(const QnnBackendCache&) = delete;
3335
QnnBackendCache(QnnBackendCache&&) = delete;
@@ -66,6 +68,7 @@ class QnnBackendCache {
6668
__ET_UNUSED const QnnSystemContext_BinaryInfo_t* binaryinfo) {
6769
return executorch::runtime::Error::Ok;
6870
}
71+
QnnSystemImplementation* qnn_sys_impl_;
6972

7073
private:
7174
executorch::runtime::Error GetQnnGraphInfoFromBinary(
@@ -79,7 +82,6 @@ class QnnBackendCache {
7982

8083
QnnExecuTorchContextBinary qnn_context_blob_;
8184
QnnSystemContext_Handle_t sys_context_handle_{nullptr};
82-
QnnSystemImplementation qnn_sys_impl_{"libQnnSystem.so"};
8385
std::vector<std::string> graph_names_;
8486
std::unordered_map<std::string, std::vector<Qnn_Tensor_t>>
8587
input_tensor_structs_;

backends/qualcomm/runtime/backends/QnnBackendFactory.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ using executorch::runtime::Error;
1717

1818
std::unique_ptr<BackendConfigParameters> QnnBackendFactory::Create(
1919
QnnImplementation* implementation_ptr,
20+
QnnSystemImplementation* system_implementation_ptr,
2021
QnnBackend* qnn_backend_ptr,
2122
QnnDevice* qnn_device_ptr,
2223
const QnnExecuTorchContextBinary& qnn_context_blob,
@@ -63,10 +64,12 @@ std::unique_ptr<BackendConfigParameters> QnnBackendFactory::Create(
6364
htp_options->use_weight_sharing());
6465
}
6566
backend_params->qnn_backend_cache_ptr_ =
66-
std::make_unique<HtpBackendCache>(qnn_context_blob);
67+
std::make_unique<HtpBackendCache>(
68+
qnn_context_blob, system_implementation_ptr);
6769

6870
backend_params->qnn_context_ptr_ = std::make_unique<HtpContext>(
6971
implementation_ptr,
72+
system_implementation_ptr,
7073
qnn_backend_ptr,
7174
qnn_device_ptr,
7275
backend_params->qnn_backend_cache_ptr_.get(),
@@ -107,10 +110,12 @@ std::unique_ptr<BackendConfigParameters> QnnBackendFactory::Create(
107110
}
108111

109112
backend_params->qnn_backend_cache_ptr_ =
110-
std::make_unique<QnnBackendCache>(qnn_context_blob);
113+
std::make_unique<QnnBackendCache>(
114+
qnn_context_blob, system_implementation_ptr);
111115

112116
backend_params->qnn_context_ptr_ = std::make_unique<GpuContext>(
113117
implementation_ptr,
118+
system_implementation_ptr,
114119
qnn_backend_ptr,
115120
qnn_device_ptr,
116121
backend_params->qnn_backend_cache_ptr_.get(),
@@ -151,10 +156,12 @@ std::unique_ptr<BackendConfigParameters> QnnBackendFactory::Create(
151156
"target_env in lpai_options: %d", lpai_options->target_env());
152157
}
153158
backend_params->qnn_backend_cache_ptr_ =
154-
std::make_unique<QnnBackendCache>(qnn_context_blob);
159+
std::make_unique<QnnBackendCache>(
160+
qnn_context_blob, system_implementation_ptr);
155161

156162
backend_params->qnn_context_ptr_ = std::make_unique<LpaiContext>(
157163
implementation_ptr,
164+
system_implementation_ptr,
158165
qnn_backend_ptr,
159166
qnn_device_ptr,
160167
backend_params->qnn_backend_cache_ptr_.get(),

backends/qualcomm/runtime/backends/QnnBackendFactory.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class QnnBackendFactory {
6363
public:
6464
std::unique_ptr<BackendConfigParameters> Create(
6565
QnnImplementation* implementation,
66+
QnnSystemImplementation* system_implementation,
6667
QnnBackend* qnn_backend_ptr,
6768
QnnDevice* qnn_device_ptr,
6869
const QnnExecuTorchContextBinary& qnn_context_blob,

backends/qualcomm/runtime/backends/QnnBackendUnifiedRegistry.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,15 @@ Error QnnBackendUnifiedRegistry::GetOrCreateBackendBundle(
152152
if (backend->VerifyQNNSDKVersion() != Error::Ok) {
153153
return Error::Internal;
154154
}
155+
// 5. Create QnnSystemImplementation and load qnn library
156+
std::unique_ptr<QnnSystemImplementation> system_implementation =
157+
std::make_unique<QnnSystemImplementation>("libQnnSystem.so");
158+
ret = system_implementation->Load();
159+
ET_CHECK_OR_RETURN_ERROR(
160+
ret == Error::Ok, Internal, "Fail to load Qnn system library");
155161

156162
bundle->implementation = std::move(implementation);
163+
bundle->system_implementation = std::move(system_implementation);
157164
bundle->qnn_logger_ptr = std::move(logger);
158165
bundle->qnn_backend_ptr = std::move(backend);
159166
bundle->qnn_device_ptr = std::move(device);

backends/qualcomm/runtime/backends/QnnBackendUnifiedRegistry.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <executorch/backends/qualcomm/runtime/backends/QnnDeviceCommon.h>
1313
#include <executorch/backends/qualcomm/runtime/backends/QnnImplementation.h>
1414
#include <executorch/backends/qualcomm/runtime/backends/QnnLogger.h>
15+
#include <executorch/backends/qualcomm/runtime/backends/QnnSysImplementation.h>
1516
#include <executorch/runtime/core/error.h>
1617

1718
#include <memory>
@@ -28,18 +29,21 @@ struct QnnBackendBundle {
2829
std::unique_ptr<QnnLogger> qnn_logger_ptr;
2930
std::unique_ptr<QnnBackend> qnn_backend_ptr;
3031
std::unique_ptr<QnnDevice> qnn_device_ptr;
32+
std::unique_ptr<QnnSystemImplementation> system_implementation;
3133

3234
// Default ctor
3335
QnnBackendBundle()
3436
: implementation(nullptr),
3537
qnn_logger_ptr(nullptr),
3638
qnn_backend_ptr(nullptr),
37-
qnn_device_ptr(nullptr) {}
39+
qnn_device_ptr(nullptr),
40+
system_implementation{nullptr} {}
3841
// Default dtor
3942
~QnnBackendBundle() {
4043
qnn_device_ptr.reset();
4144
qnn_backend_ptr.reset();
4245
qnn_logger_ptr.reset();
46+
system_implementation.reset();
4347
implementation.reset();
4448
}
4549
};

backends/qualcomm/runtime/backends/QnnContextCommon.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,9 @@ Error QnnContext::Configure() {
153153
return Error::Internal;
154154
}
155155
if (cache_->GetCacheState() == QnnBackendCache::ONLINE_PREPARE) {
156-
// Register graphs from DLC during online prepare for HTP/GPU/DSP backends
156+
// Register DLC graphs at runtime
157157
return qnn_dlc_manager_->RegisterGraphsFromDLC(
158-
implementation_, backend_, this, cache_);
158+
implementation_, system_implementation_, backend_, this, cache_);
159159
}
160160
return Error::Ok;
161161
}

0 commit comments

Comments
 (0)