From 1908721d0d1fe863664fd99b5794bc429e4094c2 Mon Sep 17 00:00:00 2001 From: Limin Tang Date: Tue, 29 Oct 2024 12:28:50 -0700 Subject: [PATCH] Support optrace (#6535) Summary: Add a new profile level to support optrace capture. Reviewed By: billmguo Differential Revision: D64941627 --- .../runtime/backends/QnnFunctionInterface.h | 1 + .../runtime/backends/QnnGraphCommon.h | 6 +++- .../qualcomm/runtime/backends/QnnProfiler.cpp | 35 ++++++++++++++++++- .../serialization/qnn_compile_spec_schema.py | 1 + backends/qualcomm/serialization/schema.fbs | 1 + backends/qualcomm/utils/utils.py | 7 +++- 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/backends/qualcomm/runtime/backends/QnnFunctionInterface.h b/backends/qualcomm/runtime/backends/QnnFunctionInterface.h index 89ca14280de..86de76f0d99 100644 --- a/backends/qualcomm/runtime/backends/QnnFunctionInterface.h +++ b/backends/qualcomm/runtime/backends/QnnFunctionInterface.h @@ -70,6 +70,7 @@ class QnnInterface { DEFINE_SHIM_FUNCTION_INTERFACE(log_set_log_level, logSetLogLevel); // --------- QnnProfile --------- DEFINE_SHIM_FUNCTION_INTERFACE(profile_create, profileCreate); + DEFINE_SHIM_FUNCTION_INTERFACE(profile_set_config, profileSetConfig); DEFINE_SHIM_FUNCTION_INTERFACE(profile_get_events, profileGetEvents); DEFINE_SHIM_FUNCTION_INTERFACE(profile_get_sub_events, profileGetSubEvents); DEFINE_SHIM_FUNCTION_INTERFACE(profile_get_event_data, profileGetEventData); diff --git a/backends/qualcomm/runtime/backends/QnnGraphCommon.h b/backends/qualcomm/runtime/backends/QnnGraphCommon.h index 4d8a8b131c6..b8cd6c6fab8 100644 --- a/backends/qualcomm/runtime/backends/QnnGraphCommon.h +++ b/backends/qualcomm/runtime/backends/QnnGraphCommon.h @@ -52,7 +52,7 @@ class QnnGraph { Qnn_ErrorHandle_t GraphFinalize() { return implementation_.GetQnnInterface().qnn_graph_finalize( - handle_, nullptr /* profile_handle */, nullptr /* signal_handle */); + handle_, profile_->GetHandle(), nullptr /* signal_handle */); }; Qnn_ErrorHandle_t ProfileExecuteData( executorch::runtime::EventTracer* event_tracer) { @@ -62,6 +62,10 @@ class QnnGraph { return handle_; } + QnnProfile* GetProfile() { + return profile_.get(); + } + protected: virtual executorch::runtime::Error MakeConfig( std::vector& config) { diff --git a/backends/qualcomm/runtime/backends/QnnProfiler.cpp b/backends/qualcomm/runtime/backends/QnnProfiler.cpp index 4996e7e8032..b10db3f0876 100644 --- a/backends/qualcomm/runtime/backends/QnnProfiler.cpp +++ b/backends/qualcomm/runtime/backends/QnnProfiler.cpp @@ -19,8 +19,20 @@ QnnProfile::QnnProfile( : handle_(nullptr), implementation_(implementation), backend_(backend) { if (profile_level != QnnExecuTorchProfileLevel::kProfileOff) { const QnnInterface& qnn_interface = implementation_.GetQnnInterface(); + + QnnProfile_Level_t qnnProfileLevel = 0; + if (profile_level == QnnExecuTorchProfileLevel::kProfileBasic) { + qnnProfileLevel = QNN_PROFILE_LEVEL_BASIC; + } else if (profile_level == QnnExecuTorchProfileLevel::kProfileDetailed + || profile_level == QnnExecuTorchProfileLevel::kProfileOptrace) { + qnnProfileLevel = QNN_PROFILE_LEVEL_DETAILED; + } else { + QNN_EXECUTORCH_LOG_WARN("Invalid profile level"); + return; + } + Qnn_ErrorHandle_t error = qnn_interface.qnn_profile_create( - backend_->GetHandle(), static_cast(profile_level), &handle_); + backend_->GetHandle(), qnnProfileLevel, &handle_); if (error != QNN_SUCCESS) { QNN_EXECUTORCH_LOG_WARN( "Failed to create profile_handle for backend " @@ -31,6 +43,27 @@ QnnProfile::QnnProfile( // ignore error and continue to create backend handle... handle_ = nullptr; } + + if (profile_level == QnnExecuTorchProfileLevel::kProfileOptrace) { + if (handle_ == nullptr) { + QNN_EXECUTORCH_LOG_WARN("Prfoile handle is null, cannot enable optrace"); + return; + } + + QnnProfile_Config_t qnnProfileConfig = QNN_PROFILE_CONFIG_INIT; + qnnProfileConfig.option = QNN_PROFILE_CONFIG_OPTION_ENABLE_OPTRACE; + std::array profileConfigs = { + &qnnProfileConfig, nullptr}; + error = qnn_interface.qnn_profile_set_config(handle_, profileConfigs.data()); + + if (error != QNN_SUCCESS) { + QNN_EXECUTORCH_LOG_WARN( + "Failed to set optrace for backend " + " %u, error=%d", + qnn_interface.GetBackendId(), + QNN_GET_ERROR_CODE(error)); + } + } } } diff --git a/backends/qualcomm/serialization/qnn_compile_spec_schema.py b/backends/qualcomm/serialization/qnn_compile_spec_schema.py index 09d910aba58..ce139a54cbe 100644 --- a/backends/qualcomm/serialization/qnn_compile_spec_schema.py +++ b/backends/qualcomm/serialization/qnn_compile_spec_schema.py @@ -115,6 +115,7 @@ class QnnExecuTorchProfileLevel(IntEnum): kProfileOff = 0 kProfileBasic = 1 kProfileDetailed = 2 + kProfileOptrace = 3 @dataclass diff --git a/backends/qualcomm/serialization/schema.fbs b/backends/qualcomm/serialization/schema.fbs index f2275377f7b..e8ef108f3a6 100644 --- a/backends/qualcomm/serialization/schema.fbs +++ b/backends/qualcomm/serialization/schema.fbs @@ -135,6 +135,7 @@ enum QnnExecuTorchProfileLevel: int { kProfileOff = 0, kProfileBasic, kProfileDetailed, + kProfileOptrace, } /// QNN backends currently supported diff --git a/backends/qualcomm/utils/utils.py b/backends/qualcomm/utils/utils.py index 30e04750b58..b730c8b59dc 100644 --- a/backends/qualcomm/utils/utils.py +++ b/backends/qualcomm/utils/utils.py @@ -770,6 +770,7 @@ def generate_qnn_executorch_compiler_spec( online_prepare: bool = False, dump_intermediate_outputs: bool = False, profile: bool = False, + optrace: bool = False, shared_buffer: bool = False, is_from_context_binary: bool = False, ) -> List[CompileSpec]: @@ -831,7 +832,11 @@ def generate_qnn_executorch_compiler_spec( if saver: qnn_executorch_options.library_path = "libQnnSaver.so" - if profile: + if optrace: + qnn_executorch_options.profile_level = ( + QnnExecuTorchProfileLevel.kProfileOptrace + ) + elif profile: qnn_executorch_options.profile_level = ( QnnExecuTorchProfileLevel.kProfileDetailed )