Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QNN EP] Expose device-level session options #19212

Merged
merged 3 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/onnxruntime/core/session/onnxruntime_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -3608,6 +3608,14 @@ struct OrtApi {
* - "1": Faster preparation time, less optimal graph.
* - "2": Longer preparation time, more optimal graph.
* - "3": Longest preparation time, most likely even more optimal graph. See QNN SDK documentation for specific details.
* "soc_model": The SoC model number. Refer to the QNN SDK documentation for valid values. Defaults to "0" (unknown).
* "htp_arch": The minimum HTP architecture the driver will use to select compatible QNN operators. Available options:
* - "0": Default (none).
* - "68"
* - "69"
* - "73"
* - "75"
* "device_id": The ID of the device to use when setting 'htp_arch'. Defaults to "0" (for single device).
*
* SNPE supported keys:
* "runtime": SNPE runtime engine, options: "CPU", "CPU_FLOAT32", "GPU", "GPU_FLOAT32_16_HYBRID", "GPU_FLOAT16",
Expand Down
31 changes: 30 additions & 1 deletion onnxruntime/core/providers/qnn/builder/qnn_backend_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "core/framework/endian_utils.h"
#include "core/common/logging/capture.h"
#include "core/providers/qnn/builder/onnx_ctx_model_helper.h"
#include "core/providers/qnn/builder/qnn_configs_helper.h"

#ifdef _WIN32
#include <winmeta.h>
Expand Down Expand Up @@ -329,9 +330,37 @@ Status QnnBackendManager::CreateDevice() {
return Status::OK();
}

qnn::QnnConfigsBuilder<QnnDevice_Config_t, QnnHtpDevice_CustomConfig_t> device_configs_builder(QNN_DEVICE_CONFIG_INIT,
{});
if (qnn_backend_type_ == QnnBackendType::HTP) {
// Set SoC Model. The *enum* Qnn_SocModel_t is deprecated and will not be updated in the future. Therefore,
// must use the latest SDK documentation to get the SoC model of the latest HW.
if (soc_model_ != QNN_SOC_MODEL_UNKNOWN) {
QnnHtpDevice_CustomConfig_t& custom_config = device_configs_builder.PushCustomConfig();
custom_config.option = QNN_HTP_DEVICE_CONFIG_OPTION_SOC;
custom_config.socModel = soc_model_;

QnnDevice_Config_t& device_config = device_configs_builder.PushConfig();
device_config.option = QNN_DEVICE_CONFIG_OPTION_CUSTOM;
device_config.customConfig = &custom_config;
}

// Set the minimum HTP architecture. The driver will use ops that are compatible with this minimum architecture.
if (htp_arch_ != QNN_HTP_DEVICE_ARCH_NONE) {
QnnHtpDevice_CustomConfig_t& custom_config = device_configs_builder.PushCustomConfig();
custom_config.option = QNN_HTP_DEVICE_CONFIG_OPTION_ARCH;
custom_config.arch.arch = htp_arch_;
custom_config.arch.deviceId = device_id_;

QnnDevice_Config_t& device_config = device_configs_builder.PushConfig();
device_config.option = QNN_DEVICE_CONFIG_OPTION_CUSTOM;
device_config.customConfig = &custom_config;
}
}

LOGS_DEFAULT(INFO) << "Create device.";
if (nullptr != qnn_interface_.deviceCreate) {
auto result = qnn_interface_.deviceCreate(log_handle_, nullptr, &device_handle_);
auto result = qnn_interface_.deviceCreate(log_handle_, device_configs_builder.GetQnnConfigs(), &device_handle_);
if (QNN_SUCCESS != result) {
return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Failed to create device. Error: ", result);
}
Expand Down
14 changes: 12 additions & 2 deletions onnxruntime/core/providers/qnn/builder/qnn_backend_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <vector>
#include "HTP/QnnHtpDevice.h"
#include "QnnLog.h"
#include "QnnTypes.h"
#include "System/QnnSystemInterface.h"
#include "core/common/status.h"
#include "core/common/logging/logging.h"
Expand All @@ -35,13 +36,19 @@ class QnnBackendManager {
uint32_t rpc_control_latency,
HtpPerformanceMode htp_performance_mode,
ContextPriority context_priority,
std::string&& qnn_saver_path)
std::string&& qnn_saver_path,
uint32_t device_id,
QnnHtpDevice_Arch_t htp_arch,
uint32_t soc_model)
: backend_path_(backend_path),
profiling_level_(profiling_level),
rpc_control_latency_(rpc_control_latency),
htp_performance_mode_(htp_performance_mode),
context_priority_(context_priority),
qnn_saver_path_(qnn_saver_path) {
qnn_saver_path_(qnn_saver_path),
device_id_(device_id),
htp_arch_(htp_arch),
soc_model_(soc_model) {
}
ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(QnnBackendManager);

Expand Down Expand Up @@ -233,6 +240,9 @@ class QnnBackendManager {
#endif
const std::string qnn_saver_path_;
uint32_t htp_power_config_client_id_ = 0;
uint32_t device_id_ = 0;
QnnHtpDevice_Arch_t htp_arch_ = QNN_HTP_DEVICE_ARCH_NONE;
uint32_t soc_model_ = QNN_SOC_MODEL_UNKNOWN;
};

} // namespace qnn
Expand Down
90 changes: 90 additions & 0 deletions onnxruntime/core/providers/qnn/builder/qnn_configs_helper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#pragma once

#include <core/common/inlined_containers_fwd.h>

namespace onnxruntime {
namespace qnn {

/**
* Helper class for building a null-terminated list of QNN configurations.
* A QNN configuration consists of multiple objects with references to each other. This
* class ensures that all configuration objects have the same lifetime, so that they remain valid
* across calls to qnn_interface.xxxCreate().
*/
template <typename BaseConfigType, typename CustomConfigType>
class QnnConfigsBuilder {
public:
/**
* Initializes the config build. Provide the initial/default value for each config struct type.
* \param base_config_init The initial/default value for objects of type BaseConfigType.
* \param custom_config_init The initial/default value for objects of type CustomConfigType.
*/
QnnConfigsBuilder(BaseConfigType base_config_init, CustomConfigType custom_config_init)
: base_config_init_(std::move(base_config_init)), custom_config_init_(std::move(custom_config_init)) {}

Check warning on line 26 in onnxruntime/core/providers/qnn/builder/qnn_configs_helper.h

View workflow job for this annotation

GitHub Actions / cpplint

[cpplint] onnxruntime/core/providers/qnn/builder/qnn_configs_helper.h#L26

Add #include <utility> for move [build/include_what_you_use] [4]
Raw output
onnxruntime/core/providers/qnn/builder/qnn_configs_helper.h:26:  Add #include <utility> for move  [build/include_what_you_use] [4]

/**
* Returns a pointer to the beginning of a null-terminated array of QNN base configurations.
* This result is typically passed to QNN's xxxCreate() APIs.
*
* \return Pointer to null-terminated BaseConfigType* array.
*/
const BaseConfigType** GetQnnConfigs() {
if (config_ptrs_.empty()) {
return nullptr;
}

if (!IsNullTerminated()) {
config_ptrs_.push_back(nullptr);
}

return config_ptrs_.data();
}

/**
* Creates and returns a reference to a new custom QNN configuration object. The object is initialized to
* the QNN recommended default value. The caller is meant to override fields in this object.
*
* \return A reference to a default CustomConfigType object.
*/
CustomConfigType& PushCustomConfig() {
custom_configs_.push_back(custom_config_init_);
return custom_configs_.back();
}

/**
* Creates and returns a reference to a new QNN configuration object. The object is initialized to
* the QNN recommended default value. The caller is meant to override fields in this object.
*
* \return A reference to a default BaseConfigType object.
*/
BaseConfigType& PushConfig() {
configs_.push_back(base_config_init_);
BaseConfigType& config = configs_.back();

// Add pointer to this new config to the list of config pointers.
if (IsNullTerminated()) {
config_ptrs_.back() = &config; // Replace last nullptr entry.
} else {
config_ptrs_.push_back(&config);
}

return config;
}

private:
bool IsNullTerminated() const {
return !config_ptrs_.empty() && config_ptrs_.back() == nullptr;
}

BaseConfigType base_config_init_;
CustomConfigType custom_config_init_;
InlinedVector<CustomConfigType> custom_configs_;
InlinedVector<BaseConfigType> configs_;
InlinedVector<const BaseConfigType*> config_ptrs_;
};

} // namespace qnn
} // namespace onnxruntime
43 changes: 0 additions & 43 deletions onnxruntime/core/providers/qnn/builder/qnn_graph_configs_helper.cc

This file was deleted.

56 changes: 0 additions & 56 deletions onnxruntime/core/providers/qnn/builder/qnn_graph_configs_helper.h

This file was deleted.

Loading
Loading