Skip to content

Commit

Permalink
[QNN EP] Expose device-level session options (#19212)
Browse files Browse the repository at this point in the history
### Description
- Adds the following session options to configure the device:
- `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.
- `device_id`: The ID of the device to use when setting 'htp_arch'.
Defaults to "0" (for single device).

### Motivation and Context
Allow more configuration.
  • Loading branch information
adrianlizarraga authored Jan 22, 2024
1 parent 373ebac commit 8d9d751
Show file tree
Hide file tree
Showing 12 changed files with 292 additions and 118 deletions.
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)) {}

/**
* 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

0 comments on commit 8d9d751

Please sign in to comment.