Skip to content
Open
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ src/csharp/AssemblyInfo.cs
/onnxruntime-linux-x64-*
*.csv
.idea
.venv
cache_dir
example-models
*.onnx
Expand Down Expand Up @@ -44,4 +45,4 @@ examples/csharp/ModelChat/models
/src/java/local.properties
/src/java/build
/src/java/CMakeFiles
/src/java/CMakeCache.txt
/src/java/CMakeCache.txt
32 changes: 23 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ else()
cmake_minimum_required(VERSION 3.26)
endif()

include(cmake/version.cmake)

project(Generators VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} LANGUAGES C CXX)

include(GNUInstallDirs)
include(FetchContent)
include(CMakeDependentOption)
project(Generators LANGUAGES C CXX)

# All Options should be defined in cmake/options.cmake This must be included before any other cmake file is included
include(cmake/options.cmake)
Expand Down Expand Up @@ -98,7 +102,6 @@ endif()

include(cmake/ortlib.cmake)


include(cmake/external/onnxruntime_external_deps.cmake)
# All Global variables, including GLOB, for the top level CMakeLists.txt should be defined here
include(cmake/global_variables.cmake)
Expand Down Expand Up @@ -152,23 +155,36 @@ find_package(Threads REQUIRED)
if(WIN32)
add_library(onnxruntime-genai SHARED ${generator_srcs} "${GENERATORS_ROOT}/dll/onnxruntime-genai.rc")
target_compile_definitions(onnxruntime-genai PRIVATE VERSION_INFO=\"${VERSION_INFO}\")
target_compile_definitions(onnxruntime-genai PRIVATE VERSION_MAJOR=${VERSION_MAJOR})
target_compile_definitions(onnxruntime-genai PRIVATE VERSION_MINOR=${VERSION_MINOR})
target_compile_definitions(onnxruntime-genai PRIVATE VERSION_PATCH=${VERSION_PATCH})
target_compile_definitions(onnxruntime-genai PRIVATE VERSION_MAJOR=${PROJECT_VERSION_MAJOR})
target_compile_definitions(onnxruntime-genai PRIVATE VERSION_MINOR=${PROJECT_VERSION_MINOR})
target_compile_definitions(onnxruntime-genai PRIVATE VERSION_PATCH=${PROJECT_VERSION_PATCH})
target_compile_definitions(onnxruntime-genai PRIVATE VERSION_SUFFIX=${VERSION_SUFFIX})
target_compile_definitions(onnxruntime-genai PRIVATE FILE_NAME=\"onnxruntime-genai.dll\")
else()
add_library(onnxruntime-genai SHARED ${generator_srcs})
set_target_properties(onnxruntime-genai PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR})
endif()

target_include_directories(onnxruntime-genai INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> $<INSTALL_INTERFACE:include>)

target_include_directories(onnxruntime-genai PRIVATE ${ORT_HEADER_DIR})
target_include_directories(onnxruntime-genai PRIVATE ${onnxruntime_extensions_SOURCE_DIR}/shared/api)
target_link_libraries(onnxruntime-genai PRIVATE onnxruntime_extensions)
target_link_directories(onnxruntime-genai PRIVATE ${ORT_LIB_DIR})
target_link_libraries(onnxruntime-genai PRIVATE Threads::Threads)

# The genai library itself is always embedded in the shared library
list(APPEND ortgenai_embed_libs "$<TARGET_FILE:onnxruntime-genai>")
if(WIN32 OR ANDROID OR IOS)
list(APPEND ortgenai_embed_libs "$<TARGET_FILE:onnxruntime-genai>")
else()
if (ENABLE_PYTHON)
list(APPEND python_embed_libs "$<TARGET_SONAME_FILE:onnxruntime-genai>")
endif()
if (ENABLE_JAVA)
list(APPEND java_embed_libs "$<TARGET_LINKER_FILE:onnxruntime-genai>")
endif()
endif()

# we keep the shared libraries disconnected on Android as they will come from separate AARs and we don't want to force
# the ORT version to match in both.
Expand All @@ -185,7 +201,6 @@ if(APPLE)
target_link_libraries(onnxruntime-genai PRIVATE "-framework Foundation" "-framework CoreML")
endif()


# Build all source files using CUDA as a separate shared library we dynamically load at runtime
if((USE_CUDA OR USE_TRT_RTX) AND CMAKE_CUDA_COMPILER)
# Suppress nvcc warnings:
Expand Down Expand Up @@ -228,9 +243,8 @@ if((USE_CUDA OR USE_TRT_RTX) AND CMAKE_CUDA_COMPILER)
endif()
endif()


if(USE_GUIDANCE)
target_include_directories(onnxruntime-genai PUBLIC ${llguidance_SOURCE_DIR}/parser/)
target_include_directories(onnxruntime-genai PRIVATE ${llguidance_SOURCE_DIR}/parser/)
target_link_libraries(onnxruntime-genai PRIVATE llguidance)
if (WIN32)
# bcrypt is needed for the rust std lib
Expand Down
10 changes: 2 additions & 8 deletions benchmark/c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,7 @@ endif()

add_executable(model_benchmark ${model_benchmark_srcs})

target_include_directories(model_benchmark PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src # directory containing the ort_genai headers
)

target_link_libraries(model_benchmark PRIVATE onnxruntime-genai ${ONNXRUNTIME_LIB})

target_link_directories(model_benchmark PRIVATE ${ORT_LIB_DIR})
target_link_libraries(model_benchmark PRIVATE onnxruntime-genai)
target_include_directories(model_benchmark PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${model_benchmark_srcs})
56 changes: 32 additions & 24 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class HelpFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescript

# Default to not building the language bindings
parser.add_argument("--build_csharp", action="store_true", help="Build the C# API.")
parser.add_argument("--msbuild_extra_options", nargs="+", action="extend", default=[], help="Extra MSBuild properties (/p:key=value). Provide as key=value.")
parser.add_argument("--build_java", action="store_true", help="Build Java bindings.")
parser.add_argument(
"--publish_java_maven_local",
Expand Down Expand Up @@ -252,7 +253,9 @@ def _validate_build_dir(args: argparse.Namespace):

# set to a config specific build dir. it should exist unless we're creating the cmake setup
is_strict = not args.update
args.build_dir = args.build_dir.resolve(strict=is_strict) / args.config
args.build_dir = args.build_dir.resolve(strict=is_strict)
if not 'Visual Studio' in args.cmake_generator and not 'Multi-Config' in args.cmake_generator:
args.build_dir = args.build_dir / args.config


def _validate_cuda_args(args: argparse.Namespace):
Expand Down Expand Up @@ -404,9 +407,11 @@ def _get_csharp_properties(args: argparse.Namespace, ort_lib_dir: Path):
)
ort_lib_path = f"/p:OrtLibDir={ort_lib_dir}"

props = [configuration, platform, native_lib_path, ort_lib_path]
msbuild_extra_options = args.msbuild_extra_options
if args.config == "Release" and not [opt for opt in msbuild_extra_options if 'IsReleaseBuild' in opt]:
msbuild_extra_options.append("IsReleaseBuild=True")

return props
return [configuration, platform, native_lib_path, ort_lib_path] + ["/p:" + option for option in msbuild_extra_options]


def _run_android_tests(args: argparse.Namespace):
Expand Down Expand Up @@ -654,6 +659,9 @@ def _get_opencv_toolchain_file():
)
args.test = False

if util.is_windows() and 'Ninja' in args.cmake_generator:
command += ["--compile-no-warning-as-error"]

if args.cmake_extra_defines != []:
command += args.cmake_extra_defines

Expand Down Expand Up @@ -695,7 +703,7 @@ def build(args: argparse.Namespace, env: dict[str, str]):
"build",
".",
]
csharp_build_command += _get_csharp_properties(args, ort_lib_dir=lib_dir)
csharp_build_command += _get_csharp_properties(args, lib_dir)
util.run(csharp_build_command, cwd=REPO_ROOT / "src" / "csharp")
util.run(csharp_build_command, cwd=REPO_ROOT / "test" / "csharp")

Expand Down Expand Up @@ -739,7 +747,7 @@ def test(args: argparse.Namespace, env: dict[str, str]):
if args.build_csharp:
dotnet = str(_resolve_executable_path("dotnet"))
csharp_test_command = [dotnet, "test"]
csharp_test_command += _get_csharp_properties(args, ort_lib_dir=lib_dir)
csharp_test_command += _get_csharp_properties(args, lib_dir)
util.run(csharp_test_command, env=env, cwd=str(REPO_ROOT / "test" / "csharp"))

if args.build_java:
Expand All @@ -765,12 +773,20 @@ def build_examples(args: argparse.Namespace, env: dict[str, str]):
"""
examples_dir = REPO_ROOT / "examples" / "c"
build_dir = examples_dir / "build"

if build_dir.exists():
log.info(f"Removing existing build directory: {build_dir}")
shutil.rmtree(build_dir)

build_dir.mkdir()
if not 'Visual Studio' in args.cmake_generator and not 'Multi-Config' in args.cmake_generator:
build_dir = build_dir / args.config

# Removing the build directory will no longer work because of
# the FetchContent used in the examples. It creates the _deps/
# directory, which contains .git/ subdirectories. Removing those
# requires elevated privileges.
# if build_dir.exists():
# log.info(f"Removing existing build directory: {build_dir}")
# shutil.rmtree(build_dir)
#
# Rezone for commenting out see above.
# Do not need to create build dir manually. CMake will do that.
# build_dir.mkdir(parents=True)

samples_to_build = [
"-DMODEL_QA=ON",
Expand All @@ -779,13 +795,9 @@ def build_examples(args: argparse.Namespace, env: dict[str, str]):
"-DWHISPER=ON",
]

ort_include_dir = REPO_ROOT / "ort" / "include"
ort_lib_dir = REPO_ROOT / "ort" / "lib"
oga_include_dir = REPO_ROOT / "src"
oga_lib_dir = args.build_dir
if util.is_windows():
# On Windows, the library files are in a subdirectory named after the configuration (e.g. Debug, Release, etc.)
oga_lib_dir = oga_lib_dir / args.config
cmake_prefix_path = str(args.build_dir)
if args.ort_home:
cmake_prefix_path += ";" + str(args.ort_home / args.config)

cmake_command = (
[
Expand All @@ -799,11 +811,7 @@ def build_examples(args: argparse.Namespace, env: dict[str, str]):
]
+ samples_to_build
+ [
"-DORT_INCLUDE_DIR=" + str(ort_include_dir),
"-DORT_LIB_DIR=" + str(ort_lib_dir),
"-DOGA_INCLUDE_DIR=" + str(oga_include_dir),
"-DOGA_LIB_DIR=" + str(oga_lib_dir),
"-DUSE_GUIDANCE=" + 'ON' if args.use_guidance else 'OFF',
"-DCMAKE_PREFIX_PATH=" + cmake_prefix_path
]
)

Expand All @@ -813,7 +821,7 @@ def build_examples(args: argparse.Namespace, env: dict[str, str]):
elif args.arm64ec:
cmake_command += ["-A", "ARM64EC"]

if args.cmake_extra_defines != []:
if args.cmake_extra_defines:
cmake_command += args.cmake_extra_defines

util.run(cmake_command, env=env)
Expand Down
4 changes: 2 additions & 2 deletions cmake/check_rocm.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
if(USE_ROCM AND NOT EXISTS "${ORT_LIB_DIR}/${ONNXRUNTIME_PROVIDERS_ROCM_LIB}")
message(FATAL_ERROR "Expected the ONNX Runtime providers ROCm library to be found at ${ORT_LIB_DIR}/${ONNXRUNTIME_PROVIDERS_ROCM_LIB}. Actual: Not found.")
if(USE_ROCM AND NOT EXISTS "${ORT_BIN_DIR}/${ONNXRUNTIME_PROVIDERS_ROCM_LIB}")
message(FATAL_ERROR "Expected the ONNX Runtime providers ROCm library to be found at ${ORT_BIN_DIR}/${ONNXRUNTIME_PROVIDERS_ROCM_LIB}. Actual: Not found.")
endif()

if(USE_ROCM)
Expand Down
30 changes: 3 additions & 27 deletions cmake/global_variables.cmake
Original file line number Diff line number Diff line change
@@ -1,30 +1,6 @@
# All Global variables for the top level CMakeLists.txt should be defined here

# Define the Version Info
file(READ "VERSION_INFO" ver)
set(VERSION_INFO ${ver})

# Example:
# VERSION_INFO: 0.4.0-dev
# VERSION_STR: 0.4.0
# VERSION_SUFFIX: dev
# VERSION_MAJOR: 0
# VERSION_MINOR: 4
# VERSION_PATCH: 0
string(REPLACE "-" ";" VERSION_LIST ${VERSION_INFO})
list(GET VERSION_LIST 0 VERSION_STR)
# Check if it is a stable or dev version
list(LENGTH VERSION_LIST VERSION_LIST_LENGTH)
if(VERSION_LIST_LENGTH GREATER 1)
list(GET VERSION_LIST 1 VERSION_SUFFIX)
else()
set(VERSION_SUFFIX "") # Set VERSION_SUFFIX to empty if stable version
endif()
string(REPLACE "." ";" VERSION_LIST ${VERSION_STR})
list(GET VERSION_LIST 0 VERSION_MAJOR)
list(GET VERSION_LIST 1 VERSION_MINOR)
list(GET VERSION_LIST 2 VERSION_PATCH)

include_guard()

# Define the project directories
set(REPO_ROOT ${PROJECT_SOURCE_DIR})
Expand Down Expand Up @@ -97,8 +73,8 @@ if (IOS OR MAC_CATALYST)
elseif (USE_WINML)
message(STATUS "Using WinML, does NOT include ONNX Runtime library, is provied by Windows.")
else()
if(NOT EXISTS "${ORT_LIB_DIR}/${ONNXRUNTIME_LIB}")
message(FATAL_ERROR "Expected the ONNX Runtime library to be found at ${ORT_LIB_DIR}/${ONNXRUNTIME_LIB}. Actual: Not found.")
if(NOT EXISTS "${ORT_BIN_DIR}/${ONNXRUNTIME_LIB}")
message(FATAL_ERROR "Expected the ONNX Runtime library to be found at ${ORT_BIN_DIR}/${ONNXRUNTIME_LIB}. Actual: Not found.")
endif()
endif()

Expand Down
5 changes: 5 additions & 0 deletions cmake/onnxruntime-genai-config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@PACKAGE_INIT@
if (NOT TARGET onnxruntime::onnxruntime-genai)
include(${CMAKE_CURRENT_LIST_DIR}/onnxruntime-genai-targets.cmake)
endif()
check_required_components(onnxruntime-genai)
54 changes: 52 additions & 2 deletions cmake/ortlib.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

include_guard()

if(USE_WINML)
message(STATUS "----- Building with WinML support ----- ")

Expand Down Expand Up @@ -57,6 +59,25 @@ else()
add_compile_definitions(USE_WINML=0)
endif()

function(_get_target_location_property variable target property)
get_target_property(_result ${target} ${property})
if(NOT _result)
set(_configuration_types ${CMAKE_CONFIGURATION_TYPES})
if (NOT _configuration_types)
set(_configuration_types Release;RelWithDebInfo;MinSizeRel;Debug)
endif()
foreach(_build_type ${_configuration_types})
string(TOUPPER ${_build_type} _build_type)
get_target_property(_result ${target} ${property}_${_build_type})
if(_result)
break()
endif()
endforeach()
endif()
set(${variable} ${_result} PARENT_SCOPE)
endfunction()


if(ORT_HOME)
# If ORT_HOME is specified at build time, use ORT_HOME to get the onnxruntime headers and libraries
message(STATUS "Using ONNX Runtime from: ${ORT_HOME} [as provided]")
Expand All @@ -69,15 +90,42 @@ if(ORT_HOME)
# Paths are based on the directory structure of the ORT Android AAR.
set(ORT_HEADER_DIR ${ORT_HOME}/headers)
set(ORT_LIB_DIR ${ORT_HOME}/jni/${ANDROID_ABI})
set(ORT_BIN_DIR ${ORT_LIB_DIR})
elseif (IOS OR MAC_CATALYST)
set(ORT_HEADER_DIR ${ORT_HOME}/Headers)
set(ORT_LIB_DIR ${ORT_HOME}/)
set(ORT_BIN_DIR ${ORT_LIB_DIR})
elseif (CMAKE_SYSTEM_NAME MATCHES "AIX")
set(ORT_HEADER_DIR ${ORT_HOME}/include/onnxruntime)
set(ORT_BIN_DIR ${ORT_HOME}/bin)
set(ORT_LIB_DIR ${ORT_HOME}/lib)
else()
set(ORT_HEADER_DIR ${ORT_HOME}/include)
set(ORT_LIB_DIR ${ORT_HOME}/lib)
find_package(onnxruntime QUIET PATHS ${ORT_HOME}/${CMAKE_BUILD_TYPE} ${ORT_HOME})
if(onnxruntime_FOUND)
get_target_property(ORT_HEADER_DIR onnxruntime::onnxruntime INTERFACE_INCLUDE_DIRECTORIES)
_get_target_location_property(_onnxruntime_dll onnxruntime::onnxruntime IMPORTED_LOCATION)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
_get_target_location_property(_onnxruntime_lib onnxruntime::onnxruntime IMPORTED_IMPLIB)
else()
set(_onnxruntime_lib "${_onnxruntime_dll}")
endif()
else()
find_file(_onnxruntime_c_api_h onnxruntime_c_api.h REQUIRED
HINTS "${ORT_HOME}" PATH_SUFFIXES include include/onnxruntime)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
find_file(_onnxruntime_dll onnxruntime.dll REQUIRED
HINTS "${ORT_HOME}" PATH_SUFFIXES bin lib)
find_file(_onnxruntime_lib onnxruntime.lib REQUIRED
HINTS "${ORT_HOME}" PATH_SUFFIXES lib)
else()
find_file(_onnxruntime_dll libonnxruntime.so REQUIRED
HINTS "${ORT_HOME}" PATH_SUFFIXES bin lib)
set(_onnxruntime_lib "${_onnxruntime_dll}")
endif()
cmake_path(GET _onnxruntime_c_api_h PARENT_PATH ORT_HEADER_DIR)
endif()
cmake_path(GET _onnxruntime_dll PARENT_PATH ORT_BIN_DIR)
cmake_path(GET _onnxruntime_lib PARENT_PATH ORT_LIB_DIR)
endif()
else()
# If ORT_HOME is not specified, download the onnxruntime headers and libraries from the nightly feed
Expand Down Expand Up @@ -154,6 +202,7 @@ else()
message(FATAL_ERROR "Auto download ONNX Runtime for this platform is not supported.")
endif()
endif()
set(ORT_BIN_DIR ${ORT_LIB_DIR})
endif()

# Download DML headers and libraries
Expand Down Expand Up @@ -201,3 +250,4 @@ set(ONNXRUNTIME_LIB_DIR ${ORT_LIB_DIR})

message(STATUS "ORT_HEADER_DIR: ${ORT_HEADER_DIR}")
message(STATUS "ORT_LIB_DIR: ${ORT_LIB_DIR}")
message(STATUS "ORT_BIN_DIR: ${ORT_BIN_DIR}")
Loading