Skip to content

Commit 204bedc

Browse files
committed
WinML - CMake
1 parent 35cb57b commit 204bedc

7 files changed

Lines changed: 238 additions & 1 deletion

File tree

CMakeLists.txt

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,62 @@ project(Generators LANGUAGES C CXX)
1414
# All Options should be defined in cmake/options.cmake This must be included before any other cmake file is included
1515
include(cmake/options.cmake)
1616

17+
if(USE_WINML)
18+
message(STATUS "----- Building with WinML support ----- ")
19+
20+
add_compile_definitions(USE_WINML=1)
21+
22+
if(NOT DEFINED WINML_SDK_VERSION OR WINML_SDK_VERSION STREQUAL "")
23+
#set(WINML_SDK_VERSION "1.8.1065-experimental")
24+
# message(STATUS "WINML_SDK_VERSION not set, defaulting to ${WINML_SDK_VERSION}")
25+
message(FATAL_ERROR "WINML_SDK_VERSION must be set when USE_WINML=ON. Configure CMake with -DWINML_SDK_VERSION=1.8.1065-experimental.")
26+
endif()
27+
28+
if(CMAKE_GENERATOR_PLATFORM STREQUAL "x64")
29+
set(ORT_PLATFORM "win-x64")
30+
elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "arm64" OR CMAKE_GENERATOR_PLATFORM STREQUAL "arm64X" OR CMAKE_GENERATOR_PLATFORM STREQUAL "arm64EC")
31+
set(ORT_PLATFORM "win-arm64")
32+
else()
33+
message(FATACMAKE_GENERATOR_PLATFORML_ERROR "Unsupported platform for GenAI: ${CMAKE_GENERATOR_PLATFORM}")
34+
return()
35+
endif()
36+
37+
include(cmake/nuget.cmake)
38+
39+
# We could have this as a variable in the build pipeline...
40+
install_nuget_package(
41+
Microsoft.WindowsAppSDK.ML
42+
${WINML_SDK_VERSION}
43+
WINML_ROOT)
44+
45+
message(STATUS "WINML_ROOT: ${WINML_ROOT}")
46+
message(STATUS "WINML_SDK_VERSION: ${WINML_SDK_VERSION}")
47+
message(STATUS "ORT_PLATFORM: ${ORT_PLATFORM}")
48+
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
49+
message(STATUS "CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}")
50+
51+
if(ORT_HOME)
52+
message(STATUS "WARNING: ORT_HOME will be overridden with USE_WINML=ON")
53+
endif()
54+
55+
set(ORT_HOME "${CMAKE_CURRENT_SOURCE_DIR}/ort")
56+
file(MAKE_DIRECTORY "${ORT_HOME}/lib")
57+
file(MAKE_DIRECTORY "${ORT_HOME}/include")
58+
59+
file (GLOB ORT_HEADERS_1 CONFIGURE_DEPENDS "${WINML_ROOT}/include/winml/*.h")
60+
file (GLOB ORT_HEADERS_2 CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/.winml/include/*.h")
61+
62+
file(COPY ${ORT_HEADERS_1} DESTINATION "${ORT_HOME}/include")
63+
file(COPY ${ORT_HEADERS_2} DESTINATION "${ORT_HOME}/include")
64+
65+
file (GLOB ORT_LIBS_1 CONFIGURE_DEPENDS "${WINML_ROOT}/runtimes/${ORT_PLATFORM}/native/onnxruntime.lib")
66+
file(COPY ${ORT_LIBS_1} DESTINATION "${ORT_HOME}/lib")
67+
68+
message(STATUS "USE_WINML: ORT_HOME set to: ${ORT_HOME}")
69+
else()
70+
add_compile_definitions(USE_WINML=0)
71+
endif()
72+
1773
if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 11)
1874
message(FATAL_ERROR "GCC version must be greater than or equal to 11")
1975
endif()
@@ -155,6 +211,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android" OR CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
155211
add_compile_definitions(_ORT_GENAI_USE_DLOPEN)
156212
else()
157213
target_link_libraries(onnxruntime-genai PRIVATE ${ONNXRUNTIME_LIB})
214+
if(USE_WINML)
215+
target_link_options(onnxruntime-genai PRIVATE "/DELAYLOAD:${ONNXRUNTIME_LIB}")
216+
endif()
158217
endif()
159218
160219
if(APPLE)

cmake/global_variables.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ if (IOS OR MAC_CATALYST)
9292
if (NOT EXISTS "${ORT_LIB_DIR}/onnxruntime.xcframework")
9393
message(FATAL_ERROR "Expected the ONNX Runtime XCFramework to be found at ${ORT_LIB_DIR}/onnxruntime.xcframework. Actual: Not found.")
9494
endif()
95+
elseif (USE_WINML)
96+
message(STATUS "Using WinML, does NOT include ONNX Runtime library, is provied by Windows.")
9597
else()
9698
if(NOT EXISTS "${ORT_LIB_DIR}/${ONNXRUNTIME_LIB}")
9799
message(FATAL_ERROR "Expected the ONNX Runtime library to be found at ${ORT_LIB_DIR}/${ONNXRUNTIME_LIB}. Actual: Not found.")

cmake/nuget.cmake

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
include_guard()
2+
3+
#[[====================================================================================================================
4+
install_nuget_package
5+
---------------------
6+
Downloads a NuGet package and returns the path to it.
7+
8+
install_nuget_package(
9+
<package name>
10+
<package version>
11+
<variable name>
12+
)
13+
====================================================================================================================]]#
14+
function(install_nuget_package NUGET_PACKAGE_NAME NUGET_PACKAGE_VERSION NUGET_PACKAGE_PATH_PROPERTY)
15+
if(NOT NUGET_PACKAGE_ROOT_PATH)
16+
set(NUGET_PACKAGE_ROOT_PATH ${CMAKE_BINARY_DIR}/__nuget)
17+
endif()
18+
19+
set(NUGET_PACKAGE_PATH "${NUGET_PACKAGE_ROOT_PATH}/${NUGET_PACKAGE_NAME}.${NUGET_PACKAGE_VERSION}")
20+
21+
if(NOT EXISTS "${NUGET_PACKAGE_PATH}")
22+
find_program(NUGET_PATH
23+
NAMES nuget nuget.exe
24+
)
25+
26+
if(NUGET_PATH STREQUAL "NUGET_PATH-NOTFOUND")
27+
message(FATAL_ERROR "nuget.exe cannot be found.")
28+
endif()
29+
30+
set(NUGET_COMMAND ${NUGET_PATH} install ${NUGET_PACKAGE_NAME})
31+
list(APPEND NUGET_COMMAND -OutputDirectory ${NUGET_PACKAGE_ROOT_PATH})
32+
list(APPEND NUGET_COMMAND -Version ${NUGET_PACKAGE_VERSION})
33+
list(APPEND NUGET_COMMAND -PackageSaveMode nuspec)
34+
35+
message(STATUS "Downloading ${NUGET_PACKAGE_NAME} ${NUGET_PACKAGE_VERSION}")
36+
message(VERBOSE "install_nuget_package: NUGET_COMMAND = ${NUGET_COMMAND}")
37+
38+
execute_process(
39+
COMMAND ${NUGET_COMMAND}
40+
OUTPUT_VARIABLE NUGET_OUTPUT
41+
ERROR_VARIABLE NUGET_ERROR
42+
RESULT_VARIABLE NUGET_RESULT
43+
)
44+
45+
message(VERBOSE "install_nuget_package: NUGET_OUTPUT = ${NUGET_OUTPUT}")
46+
if(NOT (NUGET_RESULT STREQUAL 0))
47+
message(FATAL_ERROR "install_nuget_package: Install failed with: ${NUGET_ERROR}")
48+
endif()
49+
endif()
50+
51+
set(${NUGET_PACKAGE_PATH_PROPERTY} "${NUGET_PACKAGE_PATH}" PARENT_SCOPE)
52+
endfunction()
53+
54+
#[[====================================================================================================================
55+
add_nuget_package
56+
-----------------
57+
Creates a target to package files into a NuGet package.
58+
59+
add_nuget_package(<target>
60+
<nuspec file>
61+
VERSION <version>
62+
[PROPERTIES
63+
<<PROPERTY_NAME> <PROPERTY_VALUE>>+
64+
]
65+
[FILES
66+
<<SOURCE> <TARGET>>+
67+
]
68+
)
69+
70+
====================================================================================================================]]#
71+
function(add_nuget_package TARGET NUSPEC_FILE)
72+
find_program(NUGET_PATH
73+
NAMES nuget nuget.exe
74+
)
75+
76+
if(NUGET_PATH STREQUAL "NUGET_PATH-NOTFOUND")
77+
message(FATAL_ERROR "nuget.exe cannot be found.")
78+
endif()
79+
80+
set(OPTIONS)
81+
set(ONE_VALUE_KEYWORDS VERSION)
82+
set(MULTI_VALUE_KEYWORDS FILES PROPERTIES)
83+
84+
cmake_parse_arguments(PARSE_ARGV 2 NUGET_PACK "${OPTIONS}" "${ONE_VALUE_KEYWORDS}" "${MULTI_VALUE_KEYWORDS}")
85+
86+
if(NOT NUGET_PACK_VERSION)
87+
message(FATAL_ERROR "add_nuget_package: 'VERSION' must be specified.")
88+
endif()
89+
90+
# Set NUGET_BASE_NAME to NUSPEC_FILE without '.nuspec'.
91+
string(REPLACE ".nuspec" "" NUGET_BASE_NAME ${NUSPEC_FILE})
92+
93+
# Walk the 'FILES' and:
94+
# 1. Build the 'NUGET_DEPENDENCIES' property that will be used for dependency checking the custom build step.
95+
# 2. Build the 'NUGET_FILES' property that will be added to the '<files\>' section of the configured file.
96+
set(NUGET_FILES)
97+
set(NUGET_DEPENDENCIES ${NUSPEC_FILE})
98+
while(NUGET_PACK_FILES)
99+
list(POP_FRONT NUGET_PACK_FILES FILE_SOURCE)
100+
list(POP_FRONT NUGET_PACK_FILES FILE_TARGET)
101+
102+
list(APPEND NUGET_DEPENDENCIES ${FILE_SOURCE})
103+
104+
# To allow '$<CONFIG>' usage in FILE_SOURCE, replace '$<CONFIG>'-->'$configuration$' and use nuget.exe support
105+
# to replace $configuration$ in the target.
106+
string(REPLACE "\$<CONFIG>" "$configuration$" FILE_SOURCE ${FILE_SOURCE})
107+
set(NUGET_FILES "${NUGET_FILES}\n <file src=\"${FILE_SOURCE}\" target=\"${FILE_TARGET}\" />")
108+
endwhile()
109+
110+
configure_file(${NUSPEC_FILE} ${CMAKE_CURRENT_BINARY_DIR}/${NUSPEC_FILE})
111+
112+
set(NUGET_COMMAND ${NUGET_PATH} pack ${CMAKE_CURRENT_BINARY_DIR}/${NUSPEC_FILE})
113+
list(APPEND NUGET_COMMAND -OutputDirectory ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>)
114+
list(APPEND NUGET_COMMAND -Version ${NUGET_PACK_VERSION})
115+
116+
while(NUGET_PACK_PROPERTIES)
117+
list(POP_FRONT NUGET_PACK_PROPERTIES PROPERTY_NAME)
118+
list(POP_FRONT NUGET_PACK_PROPERTIES PROPERTY_VALUE)
119+
120+
list(APPEND NUGET_COMMAND -Properties "\"${PROPERTY_NAME}=${PROPERTY_VALUE}\"")
121+
endwhile()
122+
list(APPEND NUGET_COMMAND -Properties "\"configuration=$<CONFIG>\"")
123+
124+
message(VERBOSE "add_nuget_package: NUGET_COMMAND = ${NUGET_COMMAND}")
125+
126+
add_custom_command(
127+
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${NUGET_BASE_NAME}.${NUGET_PACK_VERSION}.nupkg
128+
COMMAND ${NUGET_COMMAND}
129+
DEPENDS ${NUGET_DEPENDENCIES}
130+
COMMENT "NuGet: ${NUSPEC_FILE}"
131+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
132+
)
133+
134+
add_custom_target(${TARGET} ALL
135+
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${NUGET_BASE_NAME}.${NUGET_PACK_VERSION}.nupkg
136+
)
137+
endfunction()

cmake/options.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ include(CMakeDependentOption)
44
option(USE_CUDA "Build with CUDA support" ON)
55
option(USE_ROCM "Build with ROCm support" ON)
66
option(USE_DML "Build with DML support" OFF)
7+
option(USE_WINML "Build with WinML support" OFF)
78
option(USE_GUIDANCE "Build with guidance support" OFF)
89

910
# bindings

cmake/ortlib.cmake

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33

44
if(ORT_HOME)
55
# If ORT_HOME is specified at build time, use ORT_HOME to get the onnxruntime headers and libraries
6-
message(STATUS "Using ONNX Runtime from ${ORT_HOME}")
6+
message(STATUS "Using ONNX Runtime from: ${ORT_HOME} [as provided]")
7+
8+
# Make sure the path provided is absolute, as some tools don't react well to relative paths.
9+
get_filename_component(ORT_HOME ${ORT_HOME} ABSOLUTE)
10+
message(STATUS "Using ONNX Runtime from: ${ORT_HOME} [absloute]")
711

812
if (ANDROID)
913
# Paths are based on the directory structure of the ORT Android AAR.

cmake/presets/CMakeWinBuildPresets.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@
8484
"configuration": "MinSizeRel",
8585
"configurePreset": "windows_x64_cuda_minsizerel"
8686
},
87+
{
88+
"name": "windows_x64_winml_relwithdebinfo",
89+
"configuration": "RelWithDebInfo",
90+
"configurePreset": "windows_x64_winml_relwithdebinfo"
91+
},
8792
{
8893
"name": "windows_x64_directml_release_asan",
8994
"configuration": "Release",
@@ -139,6 +144,11 @@
139144
"configuration": "RelWithDebInfo",
140145
"configurePreset": "windows_arm64_directml_relwithdebinfo"
141146
},
147+
{
148+
"name": "windows_arm64_winml_relwithdebinfo",
149+
"configuration": "RelWithDebInfo",
150+
"configurePreset": "windows_arm64_winml_relwithdebinfo"
151+
},
142152
{
143153
"name": "windows_arm64_directml_release",
144154
"configuration": "Release",

cmake/presets/CMakeWinConfigPresets.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,19 @@
255255
"USE_CUDA": "ON"
256256
}
257257
},
258+
{
259+
"name": "windows_x64_winml_relwithdebinfo",
260+
"inherits": [
261+
"windows_relwithdebinfo_default",
262+
"windows_cuda_default",
263+
"windows_directml_default"
264+
],
265+
"displayName": "windows x64 winml relwithdebinfo",
266+
"binaryDir": "${sourceDir}/build/winml/win-x64",
267+
"cacheVariables": {
268+
"USE_WINML": "ON"
269+
}
270+
},
258271
{
259272
"name": "windows_x64_cuda_minsizerel",
260273
"inherits": [
@@ -369,6 +382,17 @@
369382
"binaryDir": "${sourceDir}/build/directml/win-arm64",
370383
"architecture": "arm64"
371384
},
385+
{
386+
"name": "windows_arm64_winml_relwithdebinfo",
387+
"inherits": [
388+
"windows_arm64_directml_relwithdebinfo"
389+
],
390+
"displayName": "windows arm64 winml relwithdebinfo",
391+
"binaryDir": "${sourceDir}/build/winml/win-arm64",
392+
"cacheVariables": {
393+
"USE_WINML": "ON"
394+
}
395+
},
372396
{
373397
"name": "windows_arm64_directml_release",
374398
"inherits": [

0 commit comments

Comments
 (0)