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

[onnxruntime/build] Add new flag enable_generic_interface to build primary EPs by default #23342

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
24 changes: 15 additions & 9 deletions cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ option(onnxruntime_USE_AZURE "Build with azure inferencing support" OFF)
option(onnxruntime_USE_LOCK_FREE_QUEUE "Build with lock-free task queue for threadpool." OFF)
option(onnxruntime_FORCE_GENERIC_ALGORITHMS "Disable optimized arch-specific algorithms. Use only for testing and debugging generic algorithms." OFF)

option(onnxruntime_USE_TENSORRT_INTERFACE "Build ONNXRuntime shared lib which is compatible with TensorRT EP interface" OFF)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misses onnxruntime_USE_CUDA_INTERFACE

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are onnxruntime_USE_TENSORRT_INTERFACE and onnxruntime_USE_TENSORRT exclusive? Could both of them be set?

option(onnxruntime_USE_CUDA_INTERFACE "Build ONNXRuntime shared lib which is compatible with Cuda EP interface" OFF)
option(onnxruntime_USE_OPENVINO_INTERFACE "Build ONNXRuntime shared lib which is compatible with OpenVINO EP interface" OFF)
option(onnxruntime_USE_VITISAI_INTERFACE "Build ONNXRuntime shared lib which is compatible with Vitis-AI EP interface" OFF)
option(onnxruntime_USE_QNN_INTERFACE "Build ONNXRuntime shared lib which is compatible with QNN EP interface" OFF)

# ENABLE_TRAINING includes all training functionality
# The following 2 entry points
# 1. ORTModule
Expand Down Expand Up @@ -634,7 +640,7 @@ if (WIN32)
# structure was padded due to __declspec(align())
list(APPEND ORT_WARNING_FLAGS "/wd4324")
# warning C4800: Implicit conversion from 'X' to bool. Possible information loss
if (onnxruntime_USE_OPENVINO)
if (onnxruntime_USE_OPENVINO OR onnxruntime_USE_OPENVINO_INTERFACE)
list(APPEND ORT_WARNING_FLAGS "/wd4800")
endif()
# operator 'operator-name': deprecated between enumerations of different types
Expand Down Expand Up @@ -791,7 +797,7 @@ else()
set(onnxruntime_USE_MEMORY_EFFICIENT_ATTENTION OFF)
endif()

if (onnxruntime_USE_CUDA)
if (onnxruntime_USE_CUDA OR onnxruntime_USE_CUDA_INTERFACE)
list(APPEND ORT_PROVIDER_FLAGS -DUSE_CUDA=1)
list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_CUDA=1)
list(APPEND ONNXRUNTIME_PROVIDER_NAMES cuda)
Expand All @@ -815,7 +821,7 @@ if (onnxruntime_USE_CUDA)
endif()
endif()

if (onnxruntime_USE_VITISAI)
if (onnxruntime_USE_VITISAI OR onnxruntime_USE_VITISAI_INTERFACE)
list(APPEND ORT_PROVIDER_FLAGS -DUSE_VITISAI=1)
list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_VITISAI=1)
list(APPEND ONNXRUNTIME_PROVIDER_NAMES vitisai)
Expand All @@ -825,12 +831,12 @@ if (onnxruntime_USE_DNNL)
list(APPEND ONNXRUNTIME_PROVIDER_NAMES dnnl)
list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_DNNL=1)
endif()
if (onnxruntime_USE_OPENVINO)
if (onnxruntime_USE_OPENVINO OR onnxruntime_USE_OPENVINO_INTERFACE)
list(APPEND ORT_PROVIDER_FLAGS -DUSE_OPENVINO=1)
list(APPEND ONNXRUNTIME_PROVIDER_NAMES openvino)
list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_OPENVINO=1)
endif()
if (onnxruntime_USE_TENSORRT)
if (onnxruntime_USE_TENSORRT OR onnxruntime_USE_TENSORRT_INTERFACE)
list(APPEND ORT_PROVIDER_FLAGS -DUSE_TENSORRT=1)
#TODO: remove the following line and change the test code in onnxruntime_shared_lib_test to use the new EP API.
list(APPEND ONNXRUNTIME_PROVIDER_NAMES tensorrt)
Expand All @@ -856,7 +862,7 @@ if (onnxruntime_USE_JSEP)
list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_JSEP=1)
list(APPEND ONNXRUNTIME_PROVIDER_NAMES js)
endif()
if (onnxruntime_USE_QNN)
if (onnxruntime_USE_QNN OR onnxruntime_USE_QNN_INTERFACE)
list(APPEND ORT_PROVIDER_FLAGS -DUSE_QNN=1)
list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_QNN=1)
list(APPEND ONNXRUNTIME_PROVIDER_NAMES qnn)
Expand Down Expand Up @@ -884,7 +890,7 @@ if (onnxruntime_USE_QNN)
endif()
endif()

if (MSVC OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
if ((NOT onnxruntime_USE_QNN_INTERFACE) AND (MSVC OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux"))
file(GLOB QNN_LIB_FILES LIST_DIRECTORIES false "${onnxruntime_QNN_HOME}/lib/${QNN_ARCH_ABI}/libQnn*.so"
"${onnxruntime_QNN_HOME}/lib/${QNN_ARCH_ABI}/Qnn*.dll"
"${onnxruntime_QNN_HOME}/lib/${QNN_ARCH_ABI}/libHtpPrepare.so"
Expand Down Expand Up @@ -1332,7 +1338,7 @@ if (onnxruntime_ENABLE_TRAINING_APIS)
)
endif()

if (onnxruntime_USE_OPENVINO)
if (onnxruntime_USE_OPENVINO OR onnxruntime_USE_OPENVINO_INTERFACE)

add_definitions(-DUSE_OPENVINO=1)

Expand All @@ -1345,7 +1351,7 @@ if (onnxruntime_USE_OPENVINO)
add_definitions(-DOPENVINO_CONFIG_GPU=1)
endif()

if (onnxruntime_USE_OPENVINO_CPU)
if (onnxruntime_USE_OPENVINO_CPU OR onnxruntime_USE_OPENVINO_INTERFACE) # OpenVino CPU interface is default built.
add_definitions(-DOPENVINO_CONFIG_CPU=1)
endif()

Expand Down
4 changes: 2 additions & 2 deletions cmake/onnxruntime_providers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ endif()
if(onnxruntime_USE_JSEP)
set(PROVIDERS_JS onnxruntime_providers_js)
endif()
if(onnxruntime_USE_QNN)
if(onnxruntime_USE_QNN OR onnxruntime_USE_QNN_INTERFACE) #TODO[Low] Revisit when qnn EP becomes dynamic lib
set(PROVIDERS_QNN onnxruntime_providers_qnn)
endif()
if(onnxruntime_USE_RKNPU)
Expand Down Expand Up @@ -163,7 +163,7 @@ if (onnxruntime_USE_JSEP)
include(onnxruntime_providers_js.cmake)
endif()

if (onnxruntime_USE_QNN)
if (onnxruntime_USE_QNN OR onnxruntime_USE_QNN_INTERFACE) #TODO[Low] Revisit when QNN EP becomes dynamic lib.
include(onnxruntime_providers_qnn.cmake)
endif()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ struct ProviderHost {
virtual std::string demangle(const char* name) = 0;
virtual std::string demangle(const std::string& name) = 0;

#ifdef USE_CUDA
// #ifdef USE_CUDA
virtual std::unique_ptr<IAllocator> CreateCUDAAllocator(int16_t device_id, const char* name) = 0;
virtual std::unique_ptr<IAllocator> CreateCUDAPinnedAllocator(const char* name) = 0;
virtual std::unique_ptr<IDataTransfer> CreateGPUDataTransfer() = 0;
Expand All @@ -179,7 +179,7 @@ struct ProviderHost {

virtual Status CudaCall_false(int retCode, const char* exprString, const char* libName, int successCode, const char* msg, const char* file, const int line) = 0;
virtual void CudaCall_true(int retCode, const char* exprString, const char* libName, int successCode, const char* msg, const char* file, const int line) = 0;
#endif
// #endif

#ifdef USE_MIGRAPHX
virtual std::unique_ptr<IAllocator> CreateMIGraphXAllocator(int16_t device_id, const char* name) = 0;
Expand All @@ -189,7 +189,6 @@ struct ProviderHost {
#ifdef USE_ROCM
virtual std::unique_ptr<IAllocator> CreateROCMAllocator(int16_t device_id, const char* name) = 0;
virtual std::unique_ptr<IAllocator> CreateROCMPinnedAllocator(const char* name) = 0;
virtual std::unique_ptr<IDataTransfer> CreateGPUDataTransfer() = 0;

virtual void rocm__Impl_Cast(void* stream, const int64_t* input_data, int32_t* output_data, size_t count) = 0;
virtual void rocm__Impl_Cast(void* stream, const int32_t* input_data, int64_t* output_data, size_t count) = 0;
Expand Down Expand Up @@ -1177,9 +1176,9 @@ struct ProviderHost {
virtual training::DistributedRunContext& GetDistributedRunContextInstance() = 0;
#endif

#if defined(USE_CUDA) || defined(USE_ROCM)
// #if defined(USE_CUDA) || defined(USE_ROCM)
virtual PhiloxGenerator& PhiloxGenerator__Default() = 0;
#endif
// #endif

#ifdef ENABLE_TRAINING_TORCH_INTEROP
virtual void contrib__PythonOpBase__Init(contrib::PythonOpBase* p, const OpKernelInfo& info) = 0;
Expand Down
6 changes: 2 additions & 4 deletions onnxruntime/core/session/provider_bridge_ort.cc
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ struct ProviderHostImpl : ProviderHost {
void* CPUAllocator__Alloc(CPUAllocator* p, size_t size) override { return p->CPUAllocator::Alloc(size); }
void CPUAllocator__Free(CPUAllocator* p, void* allocation) override { return p->CPUAllocator::Free(allocation); }

#ifdef USE_CUDA
std::unique_ptr<IAllocator> CreateCUDAAllocator(int16_t device_id, const char* name) override { return GetProviderInfo_CUDA().CreateCUDAAllocator(device_id, name); }
std::unique_ptr<IAllocator> CreateCUDAPinnedAllocator(const char* name) override { return GetProviderInfo_CUDA().CreateCUDAPinnedAllocator(name); }
std::unique_ptr<IDataTransfer> CreateGPUDataTransfer() override { return GetProviderInfo_CUDA().CreateGPUDataTransfer(); }
Expand All @@ -247,7 +246,6 @@ struct ProviderHostImpl : ProviderHost {

Status CudaCall_false(int retCode, const char* exprString, const char* libName, int successCode, const char* msg, const char* file, const int line) override { return GetProviderInfo_CUDA().CudaCall_false(retCode, exprString, libName, successCode, msg, file, line); }
void CudaCall_true(int retCode, const char* exprString, const char* libName, int successCode, const char* msg, const char* file, const int line) override { GetProviderInfo_CUDA().CudaCall_true(retCode, exprString, libName, successCode, msg, file, line); }
#endif

#ifdef USE_MIGRAPHX
std::unique_ptr<IAllocator> CreateMIGraphXAllocator(int16_t device_id, const char* name) override { return GetProviderInfo_MIGraphX().CreateMIGraphXAllocator(device_id, name); }
Expand Down Expand Up @@ -1419,9 +1417,9 @@ struct ProviderHostImpl : ProviderHost {
training::DistributedRunContext& GetDistributedRunContextInstance() override { return training::DistributedRunContext::GetInstance(); }
#endif

#if defined(USE_CUDA) || defined(USE_ROCM)
// #if defined(USE_CUDA) || defined(USE_ROCM)
PhiloxGenerator& PhiloxGenerator__Default() override { return PhiloxGenerator::Default(); }
#endif
// #endif

#ifdef ENABLE_TRAINING_TORCH_INTEROP
void contrib__PythonOpBase__Init(contrib::PythonOpBase* p, const OpKernelInfo& info) override { p->PythonOpBase::Init(info); }
Expand Down
13 changes: 13 additions & 0 deletions samples/GenericInterface/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# usage:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sample code are better to be put in https://github.com/microsoft/onnxruntime-inference-examples/ , so that they will be exempted from compliance requirements(because we do not ship the code)

# cd build/
# cmake -S ../ -B ./ -DCMAKE_BUILD_TYPE=Debug
# cmake --build ./
# NOTE: For Windows, copy onnxruntime.dll and onnxruntime.pdb into the same folder of TestOutTreeEp.exe, otherwise, during runtime,
# it will search the default system path (C:\Windows\System32) for onnxruntime.dll
cmake_minimum_required(VERSION 3.26)
project(GenericOrtEpInterface)
add_executable(GenericOrtEpInterface test.cpp)

target_include_directories(GenericOrtEpInterface PUBLIC "../../include/onnxruntime")
target_link_libraries(GenericOrtEpInterface PUBLIC "C:/Users/leca/source/onnxruntime3/samples/GenericInterface/build/Debug/onnxruntime.lib")

69 changes: 69 additions & 0 deletions samples/GenericInterface/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <iostream>
Fixed Show fixed Hide fixed
#include <string>
#include <unordered_map>
#include "core/session/onnxruntime_c_api.h"

const OrtApi* g_ort = OrtGetApiBase()->GetApi(ORT_API_VERSION);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check if the returned value is NULL.


inline void THROW_ON_ERROR(OrtStatus* status) {
if (status != nullptr) {
std::cout << "ErrorMessage:" << g_ort->GetErrorMessage(status) << "\n";
abort();
}
}

void RunRelu(const OrtApi* g_ort, OrtEnv* p_env, OrtSessionOptions* so) {
OrtSession* session = nullptr;
// Copy relu.onnx model from winml\test\collateral\models to the same path as the executable
THROW_ON_ERROR(g_ort->CreateSession(p_env, L"relu.onnx", so, &session));

OrtMemoryInfo* memory_info = nullptr;
THROW_ON_ERROR(g_ort->CreateCpuMemoryInfo(OrtArenaAllocator, OrtMemTypeDefault, &memory_info));
float input_data[] = {-3.0f, 5.0f, -2.0f, 4.0f, 0.0f};
const size_t input_len = 5 * sizeof(float);
const int64_t input_shape[] = {5};
const size_t shape_len = sizeof(input_shape) / sizeof(input_shape[0]);

OrtValue* input_tensor = nullptr;
THROW_ON_ERROR(g_ort->CreateTensorWithDataAsOrtValue(memory_info, input_data, input_len, input_shape, shape_len, ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT, &input_tensor));

const char* input_names[] = {"X"};
const char* output_names[] = {"Y"};
OrtValue* output_tensor = nullptr;
THROW_ON_ERROR(g_ort->Run(session, nullptr, input_names, (const OrtValue* const*)&input_tensor, 1, output_names, 1, &output_tensor));

float* output_tensor_data = nullptr;
THROW_ON_ERROR(g_ort->GetTensorMutableData(output_tensor, (void**)&output_tensor_data));
std::cout << "Result:\n";
for (size_t i = 0; i < 5; i++) std::cout << output_tensor_data[i] << " \n";
}

int main() {
int a;
std::cout << "prepare to attach:";
std::cin >> a;

OrtEnv* p_env = nullptr;
OrtLoggingLevel log_level = OrtLoggingLevel::ORT_LOGGING_LEVEL_ERROR; // OrtLoggingLevel::ORT_LOGGING_LEVEL_INFO;
THROW_ON_ERROR(g_ort->CreateEnv(log_level, "", &p_env));
OrtSessionOptions* so = nullptr;
THROW_ON_ERROR(g_ort->CreateSessionOptions(&so));

OrtTensorRTProviderOptionsV2* tensorrt_options = nullptr;
THROW_ON_ERROR(g_ort->CreateTensorRTProviderOptions(&tensorrt_options));
THROW_ON_ERROR(g_ort->SessionOptionsAppendExecutionProvider_TensorRT_V2(so, tensorrt_options));

std::unordered_map<std::string, std::string> ov_options;
ov_options["device_type"] = "CPU";
ov_options["precision"] = "FP32";
std::vector<const char*> keys, values;
for (const auto& entry : ov_options) {
keys.push_back(entry.first.c_str());
values.push_back(entry.second.c_str());
}
THROW_ON_ERROR(g_ort->SessionOptionsAppendExecutionProvider_OpenVINO_V2(so, keys.data(), values.data(), keys.size()));

RunRelu(g_ort, p_env, so);

return 0;
}
47 changes: 42 additions & 5 deletions tools/ci_build/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,12 @@ def convert_arg_line_to_args(self, arg_line):
parser.add_argument("--use_triton_kernel", action="store_true", help="Use triton compiled kernels")
parser.add_argument("--use_lock_free_queue", action="store_true", help="Use lock-free task queue for threadpool.")

parser.add_argument(
"--enable_generic_interface",
action="store_true",
help="build ORT shared library and compatible bridge with primary EPs(tensorRT, OpenVino, Qnn, vitisai) but not tests",
)

if not is_windows():
parser.add_argument(
"--allow_running_as_root",
Expand Down Expand Up @@ -997,6 +1003,8 @@ def generate_build_tree(
disable_optional_type = "optional" in types_to_disable
disable_sparse_tensors = "sparsetensor" in types_to_disable

enable_qnn_interface = bool((args.arm64 or args.arm or args.arm64ec) and (args.enable_generic_interface))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --arm64, --args.arm and --args.arm64ec are for Windows only and for cross-compiling only.
For example, if you build the code on an ARM64 machine and also targets ARM64, you do not need to add any of these args. So, this condition needs to be changed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention here is when building onnxruntime for ARM64 target platform, only QNN EP is applicable for now.
What cmake variable is safe to use for checking such ?


Fixed Show fixed Hide fixed
cmake_args += [
"-Donnxruntime_RUN_ONNX_TESTS=" + ("ON" if args.enable_onnx_tests else "OFF"),
"-Donnxruntime_GENERATE_TEST_REPORTS=ON",
Expand Down Expand Up @@ -1024,6 +1032,17 @@ def generate_build_tree(
"-Donnxruntime_USE_TENSORRT=" + ("ON" if args.use_tensorrt else "OFF"),
"-Donnxruntime_USE_TENSORRT_BUILTIN_PARSER="
+ ("ON" if args.use_tensorrt_builtin_parser and not args.use_tensorrt_oss_parser else "OFF"),
# interface variables are used only for building onnxruntime/onnxruntime_shared.dll but not EPs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misses onnxruntime_USE_CUDA_INTERFACE.

"-Donnxruntime_USE_TENSORRT_INTERFACE="
+ ("ON" if (args.enable_generic_interface and not enable_qnn_interface) else "OFF"),
"-Donnxruntime_USE_CUDA_INTERFACE="
+ ("ON" if (args.enable_generic_interface and not enable_qnn_interface) else "OFF"),
"-Donnxruntime_USE_OPENVINO_INTERFACE="
+ ("ON" if (args.enable_generic_interface and not enable_qnn_interface) else "OFF"),
"-Donnxruntime_USE_VITISAI_INTERFACE="
+ ("ON" if (args.enable_generic_interface and not enable_qnn_interface) else "OFF"),
"-Donnxruntime_USE_QNN_INTERFACE="
+ ("ON" if (args.enable_generic_interface and enable_qnn_interface) else "OFF"),
# set vars for migraphx
"-Donnxruntime_USE_MIGRAPHX=" + ("ON" if args.use_migraphx else "OFF"),
"-Donnxruntime_DISABLE_CONTRIB_OPS=" + ("ON" if args.disable_contrib_ops else "OFF"),
Expand Down Expand Up @@ -1297,6 +1316,7 @@ def generate_build_tree(
cmake_args += ["-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=" + args.xcode_code_signing_team_id]

if args.use_qnn:

if args.qnn_home is None or os.path.exists(args.qnn_home) is False:
raise BuildError("qnn_home=" + qnn_home + " not valid." + " qnn_home paths must be specified and valid.")
cmake_args += ["-Donnxruntime_USE_QNN=ON"]
Expand Down Expand Up @@ -1454,6 +1474,12 @@ def generate_build_tree(
"-Donnxruntime_USE_FULL_PROTOBUF=ON",
]

# When this flag is enabled, that means we only build ONNXRuntime shared library, expecting some compatible EP
# shared lib being build in a seperate process. So we skip the test for now as ONNXRuntime shared lib built under
# this flag is not expected to work alone
if args.enable_generic_interface:
jslhcl marked this conversation as resolved.
Show resolved Hide resolved
cmake_args += ["-Donnxruntime_BUILD_UNIT_TESTS=OFF"]

if args.enable_lazy_tensor:
import torch

Expand Down Expand Up @@ -2567,6 +2593,9 @@ def main():
# Disable ONNX Runtime's builtin memory checker
args.disable_memleak_checker = True

if args.enable_generic_interface:
args.test = False

# If there was no explicit argument saying what to do, default
# to update, build and test (for native builds).
if not (args.update or args.clean or args.build or args.test or args.gen_doc):
Expand Down Expand Up @@ -2670,7 +2699,11 @@ def main():
source_dir = os.path.normpath(os.path.join(script_dir, "..", ".."))

# if using cuda, setup cuda paths and env vars
cuda_home, cudnn_home = setup_cuda_vars(args)
# cuda_home, cudnn_home = setup_cuda_vars(args)
cuda_home = ""
cudnn_home = ""
if args.use_cuda:
cuda_home, cudnn_home = setup_cuda_vars(args)

mpi_home = args.mpi_home
nccl_home = args.nccl_home
Expand All @@ -2683,10 +2716,14 @@ def main():
armnn_home = args.armnn_home
armnn_libs = args.armnn_libs

qnn_home = args.qnn_home
qnn_home = ""
if args.use_qnn:
qnn_home = args.qnn_home

# if using tensorrt, setup tensorrt paths
tensorrt_home = setup_tensorrt_vars(args)
tensorrt_home = ""
if args.use_tensorrt:
tensorrt_home = setup_tensorrt_vars(args)

# if using migraphx, setup migraphx paths
migraphx_home = setup_migraphx_vars(args)
Expand Down Expand Up @@ -2771,9 +2808,9 @@ def main():
toolset = "host=" + host_arch + ",version=" + args.msvc_toolset
else:
toolset = "host=" + host_arch
if args.cuda_version:
if args.use_cuda and args.cuda_version:
toolset += ",cuda=" + args.cuda_version
elif args.cuda_home:
elif args.use_cuda and args.cuda_home:
toolset += ",cuda=" + args.cuda_home
if args.windows_sdk_version:
target_arch += ",version=" + args.windows_sdk_version
Expand Down
Loading