Skip to content

Commit 50a3f7f

Browse files
DannyYuyang-quicyuyazhua
authored and
yuyazhua
committed
Qualcomm AI Engine Direct - Support Qnn IR backend in online preparation
- Support Qnn IR backend - Replace QCir with Dlc in online prepare flow - Fix SDK version checking - Add config for Saver backend
1 parent 542480c commit 50a3f7f

26 files changed

+632
-189
lines changed

backends/qualcomm/CMakeLists.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ endif()
7373

7474
include_directories(
7575
BEFORE ${_common_include_directories} ${QNN_SDK_ROOT}/include/QNN
76+
${QNN_SDK_ROOT}/share/QNN/converter/jni
7677
${EXECUTORCH_SOURCE_DIR}/third-party/flatbuffers/include
7778
${EXECUTORCH_SOURCE_DIR}/runtime/core/portable_type/c10
7879
)
@@ -183,8 +184,15 @@ target_link_libraries(
183184
PRIVATE qnn_schema qnn_backend qnn_device qnn_context qnn_graph
184185
qnn_mem_manager qnn_custom_protocol
185186
)
187+
188+
target_include_directories(qnn_manager PUBLIC
189+
${QNN_SDK_ROOT}/include/QNN
190+
${QNN_SDK_ROOT}/share/QNN/converter/jni/
191+
${PROJECT_SOURCE_DIR})
192+
target_link_directories(qnn_manager PUBLIC ${QNN_SDK_ROOT}/lib/${ARCHITECTURE}/)
193+
186194
target_link_libraries(
187-
qnn_manager PRIVATE qnn_factory wrappers qnn_schema utils shared_buffer
195+
qnn_manager PRIVATE qnn_factory wrappers qnn_schema utils shared_buffer QnnModelDlc
188196
)
189197
target_link_libraries(
190198
qnn_executorch_backend PRIVATE qnn_executorch_header qnn_schema qnn_manager

backends/qualcomm/aot/python/PyQnnManagerAdaptor.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class PyQnnManager {
3434
auto qnn_executorch_options = GetQnnExecuTorchOptions(
3535
qnn_executorch_option_ptr_.cast<std::string_view>().data());
3636
qnn_manager_ = std::make_shared<QnnManager>(
37-
qnn_executorch_options, qnn_executorch_context_binary_);
37+
qnn_executorch_options, qnn_executorch_context_binary_, false);
3838
}
3939

4040
// used for loading context binary directly
@@ -47,7 +47,7 @@ class PyQnnManager {
4747
qnn_executorch_context_binary_.buffer = info.ptr;
4848
qnn_executorch_context_binary_.nbytes = info.size * info.itemsize;
4949
qnn_manager_ = std::make_shared<QnnManager>(
50-
qnn_executorch_options, qnn_executorch_context_binary_);
50+
qnn_executorch_options, qnn_executorch_context_binary_, false);
5151
}
5252

5353
// used during stage 2 of multi-graph mode
@@ -160,7 +160,7 @@ class PyQnnManager {
160160
qnn_executorch_context_binary_ =
161161
MakeQcirCustomBinaryInfo(qcir_bin, tensor_data);
162162
qnn_manager_ = std::make_shared<QnnManager>(
163-
qnn_executorch_options, qnn_executorch_context_binary_);
163+
qnn_executorch_options, qnn_executorch_context_binary_, false);
164164
}
165165

166166
executorch::runtime::Error Init() {
@@ -195,7 +195,7 @@ class PyQnnManager {
195195
std::vector<std::shared_ptr<OpWrapper>>& op_wrappers) {
196196
QnnExecuTorchContextBinary binary_info;
197197

198-
if (qnn_manager_->IsOnlinePrepare() || qnn_manager_->IsMultipleGraphs()) {
198+
if (qnn_manager_->IsMultipleGraphs()) {
199199
builder_.Reset();
200200
std::vector<uint8_t> tensor_data;
201201
std::vector<uint64_t> offsets;
@@ -305,8 +305,11 @@ class PyQnnManager {
305305
QNN_EXECUTORCH_LOG_ERROR("Fail to compile QNN graph");
306306
return py::array_t<char>(0);
307307
}
308-
if (qnn_manager_->GetContextBinary(binary_info) !=
309-
executorch::runtime::Error::Ok) {
308+
auto qnn_executorch_options = GetQnnExecuTorchOptions(
309+
qnn_executorch_option_ptr_.cast<std::string_view>().data());
310+
if (qnn_executorch_options->saver() ||
311+
qnn_manager_->GetContextBinary(binary_info) !=
312+
executorch::runtime::Error::Ok) {
310313
return py::array_t<char>(0);
311314
}
312315
}

backends/qualcomm/qnn_preprocess.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
from executorch.backends.qualcomm.builders.node_visitor import get_node_visitors
2121
from executorch.backends.qualcomm.builders.qnn_constants import OpContextLoader
2222
from executorch.backends.qualcomm.partition.utils import generate_qnn_executorch_option
23+
from executorch.backends.qualcomm.serialization.qc_schema_serialize import (
24+
flatbuffer_to_option,
25+
)
2326
from executorch.exir.backend.backend_details import (
2427
BackendDetails,
2528
CompileSpec,
@@ -107,6 +110,12 @@ def preprocess(
107110
qnn_manager.GetGraphNames()[0],
108111
[py_op_wrapper.GetOpWrapper() for py_op_wrapper in py_op_wrapper_list],
109112
)
113+
114+
obj_options = flatbuffer_to_option(option)
115+
if obj_options.saver:
116+
exit(
117+
f"Records all QNN API calls from saver backend at: {obj_options.saver_output_dir}"
118+
)
110119
assert len(qnn_context_binary) != 0, "Failed to generate Qnn context binary."
111120
qnn_manager.Destroy()
112121
# For now, debug_handle_map is not used by QNN ExecuTorch

backends/qualcomm/runtime/QnnExecuTorchBackend.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ Result<DelegateHandle*> QnnExecuTorchBackend::init(
3636
// covert SizedBuffer to qnn ExecuTorch option
3737
QnnExecuTorchContextBinary qnn_context_blob;
3838
const qnn_delegate::QnnExecuTorchOptions* qnn_executorch_options = nullptr;
39-
4039
auto [status, signature, ctx_size, ctx_bin] =
4140
QnnContextCustomProtocol().DeserializeContextCustomBuffer(
4241
const_cast<void*>(processed->data()));
@@ -49,6 +48,7 @@ Result<DelegateHandle*> QnnExecuTorchBackend::init(
4948
qnn_context_blob.buffer = ctx_bin;
5049
} else {
5150
// This buffer will be verified again in QnnBackendCache.
51+
5252
QNN_EXECUTORCH_LOG_INFO(
5353
"Deserializing processed data using QnnQcirCustomProtocol");
5454
qnn_context_blob.buffer = const_cast<void*>(processed->data());
@@ -71,8 +71,7 @@ Result<DelegateHandle*> QnnExecuTorchBackend::init(
7171

7272
// NOTE: Since we use placement new and since this type is not trivially
7373
// destructible, we must call the destructor manually in destroy().
74-
new (qnn_manager) QnnManager(qnn_executorch_options, qnn_context_blob);
75-
74+
new (qnn_manager) QnnManager(qnn_executorch_options, qnn_context_blob, true);
7675
// TODO: this is a temporal solution for multi-graph support, will be
7776
// removed once framework starts to accept runtime configuration
7877
// ---
@@ -94,9 +93,9 @@ Result<DelegateHandle*> QnnExecuTorchBackend::init(
9493

9594
if (qnn_manager->IsOnlinePrepare()) {
9695
ET_CHECK_OR_RETURN_ERROR(
97-
qnn_manager->CompileQcir() == Error::Ok,
96+
qnn_manager->CompileGraphsFromDlc() == Error::Ok,
9897
Internal,
99-
"Fail to compile binary in qcir format");
98+
"Fail to compile binary in Dlc format");
10099
} else {
101100
for (const std::string& graph_name : qnn_manager->GetGraphNames()) {
102101
ET_CHECK_OR_RETURN_ERROR(

0 commit comments

Comments
 (0)