From 8a7cd8ac4bbf23815774e75ce2b4a72a1750602c Mon Sep 17 00:00:00 2001 From: luncliff Date: Sun, 15 Sep 2024 14:29:40 +0900 Subject: [PATCH] [onnxruntime] support 'coreml' feature --- ports/onnxruntime/abseil-cpp.cmake | 145 ++++++++++++++++++ ports/onnxruntime/fix-cmake-coreml.patch | 42 +++++ .../onnxruntime_external_deps.cmake | 23 ++- ports/onnxruntime/portfile.cmake | 15 +- ports/onnxruntime/vcpkg.json | 8 + versions/baseline.json | 2 +- versions/o-/onnxruntime.json | 5 + 7 files changed, 229 insertions(+), 11 deletions(-) create mode 100644 ports/onnxruntime/abseil-cpp.cmake create mode 100644 ports/onnxruntime/fix-cmake-coreml.patch diff --git a/ports/onnxruntime/abseil-cpp.cmake b/ports/onnxruntime/abseil-cpp.cmake new file mode 100644 index 00000000..dda7c5ff --- /dev/null +++ b/ports/onnxruntime/abseil-cpp.cmake @@ -0,0 +1,145 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +include(FetchContent) + +# Pass to build +set(ABSL_PROPAGATE_CXX_STD 1) +set(BUILD_TESTING 0) +set(ABSL_BUILD_TESTING OFF) +set(ABSL_BUILD_TEST_HELPERS OFF) +set(ABSL_USE_EXTERNAL_GOOGLETEST ON) +if(Patch_FOUND AND WIN32) + set(ABSL_PATCH_COMMAND ${Patch_EXECUTABLE} --binary --ignore-whitespace -p1 < ${PROJECT_SOURCE_DIR}/patches/abseil/absl_windows.patch) +else() + set(ABSL_PATCH_COMMAND "") +endif() +if(WIN32 AND NOT Patch_FOUND) + #see https://github.com/google/re2/issues/425 and https://github.com/google/re2/issues/436 + set(ABSL_ENABLE_INSTALL ON) +endif() +# NB! Advancing Abseil version changes its internal namespace, +# currently absl::lts_20240116 which affects abseil-cpp.natvis debugger +# visualization file, that must be adjusted accordingly, unless we eliminate +# that namespace at build time. +FetchContent_Declare( + abseil_cpp + URL ${DEP_URL_abseil_cpp} + URL_HASH SHA1=${DEP_SHA1_abseil_cpp} + PATCH_COMMAND ${ABSL_PATCH_COMMAND} + FIND_PACKAGE_ARGS NAMES absl +) + +onnxruntime_fetchcontent_makeavailable(abseil_cpp) +FetchContent_GetProperties(abseil_cpp) +set(ABSEIL_SOURCE_DIR ${abseil_cpp_SOURCE_DIR}) +# abseil_cpp_SOURCE_DIR is non-empty if we build it from source +message(STATUS "Abseil source dir:" ${ABSEIL_SOURCE_DIR}) +# abseil_cpp_VERSION is non-empty if we find a preinstalled ABSL +if(abseil_cpp_VERSION) + message(STATUS "Abseil version:" ${abseil_cpp_VERSION}) +endif() +if (GDK_PLATFORM) + # Abseil considers any partition that is NOT in the WINAPI_PARTITION_APP a viable platform + # for Win32 symbolize code (which depends on dbghelp.lib); this logic should really be flipped + # to only include partitions that are known to support it (e.g. DESKTOP). As a workaround we + # tell Abseil to pretend we're building an APP. + target_compile_definitions(absl_symbolize PRIVATE WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP) +endif() + +# TODO: since multiple ORT's dependencies depend on Abseil, the list below would vary from version to version. +# We'd better to not manually manage the list. +set(ABSEIL_LIBS +absl::absl_log +absl::log_internal_log_impl +absl::log_internal_strip +absl::log_internal_message +absl::log_internal_format +absl::synchronization +absl::str_format +absl::flags +absl::log_internal_globals +absl::kernel_timeout_internal +absl::str_format_internal +absl::hash +absl::log_internal_append_truncated +absl::absl_vlog_is_on +absl::flags_commandlineflag +absl::time +absl::symbolize +absl::graphcycles_internal +absl::log_internal_conditions +absl::strings +absl::malloc_internal +absl::demangle_internal +absl::optional +absl::stacktrace +absl::base +absl::demangle_rust +absl::bad_optional_access +absl::strings_internal +absl::debugging_internal +absl::int128 +absl::spinlock_wait +absl::decode_rust_punycode +absl::raw_logging_internal +absl::flat_hash_set +absl::flat_hash_map +absl::node_hash_map +absl::node_hash_set +absl::compare +absl::base_internal +absl::nullability +absl::bounded_utf8_length_sequence +absl::log_severity +absl::type_traits +absl::atomic_hook +absl::bits +absl::flags_commandlineflag_internal +absl::hash_container_defaults +absl::numeric_representation +absl::node_slot_policy +absl::core_headers +absl::dynamic_annotations +absl::utf8_for_code_point +absl::errno_saver +absl::absl_check +absl::hash_function_defaults +absl::function_ref +absl::city +absl::low_level_hash +absl::fixed_array +absl::variant +absl::meta +absl::log_internal_voidify +absl::log_sink +absl::log_internal_log_sink_set +absl::log_sink_registry +absl::log_entry +absl::log_globals +absl::log_internal_nullguard +absl::examine_stack +absl::inlined_vector +absl::log_internal_proto +absl::strerror +absl::log_internal_config +absl::raw_hash_map +absl::raw_hash_set +absl::container_memory +absl::algorithm_container +absl::span +absl::log_internal_nullstream +absl::vlog_config_internal +absl::flags_reflection +absl::flags_internal +absl::flags_config +absl::fast_type_id +absl::utility +absl::time_zone +absl::civil_time +absl::string_view +absl::throw_delegate +absl::memory +absl::charset +absl::endian +absl::config) diff --git a/ports/onnxruntime/fix-cmake-coreml.patch b/ports/onnxruntime/fix-cmake-coreml.patch new file mode 100644 index 00000000..26af1179 --- /dev/null +++ b/ports/onnxruntime/fix-cmake-coreml.patch @@ -0,0 +1,42 @@ +diff --git a/cmake/onnxruntime_providers_coreml.cmake b/cmake/onnxruntime_providers_coreml.cmake +index 0aa25a2..1cb768c 100644 +--- a/cmake/onnxruntime_providers_coreml.cmake ++++ b/cmake/onnxruntime_providers_coreml.cmake +@@ -9,7 +9,7 @@ add_compile_definitions(USE_COREML=1) + + # Check if we can build the coremltools code for creating an mlpackage with an mlprogram. + # The coremltools source requires std::filesystem::path which is only available from iOS 13 on. +-set(_enable_ML_PROGRAM ON) ++option(_enable_ML_PROGRAM "..." ON) + if (IOS AND CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 13.0) + message(WARNING "CoreML ML Program is not supported on iOS < 13.0. Excluding ML Program support from build.") + set(_enable_ML_PROGRAM OFF) +@@ -29,7 +29,9 @@ if (_enable_ML_PROGRAM) + endif() + + # Compile CoreML proto definition to ${CMAKE_CURRENT_BINARY_DIR}/coreml_proto +-set(COREML_PROTO_ROOT ${coremltools_SOURCE_DIR}/mlmodel/format) ++if(NOT DEFINED COREML_PROTO_ROOT) ++ set(COREML_PROTO_ROOT ${coremltools_SOURCE_DIR}/mlmodel/format) ++endif() + file(GLOB coreml_proto_srcs "${COREML_PROTO_ROOT}/*.proto") + + onnxruntime_add_static_library(coreml_proto ${coreml_proto_srcs}) +@@ -62,7 +64,7 @@ endif() + # Separate source_group for each as the .proto files are in the repo and the .cc/.h files are generated in the build + # output directory. + set_target_properties(coreml_proto PROPERTIES FOLDER "External") +-source_group(TREE ${COREML_PROTO_ROOT} PREFIX coreml_proto FILES ${coreml_proto_srcs}) ++# source_group(TREE ${COREML_PROTO_ROOT} PREFIX coreml_proto FILES ${coreml_proto_srcs}) + + # filter to the generated .cc/.h files + get_target_property(coreml_proto_generated_srcs coreml_proto SOURCES) +@@ -119,7 +121,7 @@ if(_enable_ML_PROGRAM) + ${onnxruntime_providers_coreml_modelpackage_cc_srcs} + ) + +- source_group(TREE ${coremltools_SOURCE_DIR} PREFIX coremltools FILES ${coremltools_srcs}) ++ # source_group(TREE ${coremltools_SOURCE_DIR} PREFIX coremltools FILES ${coremltools_srcs}) + endif() + + # Add CoreML objective c++ source code diff --git a/ports/onnxruntime/onnxruntime_external_deps.cmake b/ports/onnxruntime/onnxruntime_external_deps.cmake index a0b655c2..437c5d09 100644 --- a/ports/onnxruntime/onnxruntime_external_deps.cmake +++ b/ports/onnxruntime/onnxruntime_external_deps.cmake @@ -630,14 +630,21 @@ if(onnxruntime_ENABLE_TRAINING OR (onnxruntime_ENABLE_TRAINING_APIS AND onnxrunt endif() if (onnxruntime_USE_COREML) - FetchContent_Declare( - coremltools - URL ${DEP_URL_coremltools} - URL_HASH SHA1=${DEP_SHA1_coremltools} - PATCH_COMMAND ${Patch_EXECUTABLE} --binary --ignore-whitespace -p1 < ${PROJECT_SOURCE_DIR}/patches/coremltools/crossplatformbuild.patch - ) - # we don't build directly so use Populate. selected files are built from onnxruntime_providers_coreml.cmake - FetchContent_Populate(coremltools) + if(onnxruntime_USE_VCPKG) + # using vcpkg-registry 'coreml-tools' + # check onnxruntime_providers_coreml.cmake together + find_path(COREML_PROTO_INCLUDE_DIR NAMES "mlmodel/format/Model.proto" REQUIRED) + get_filename_component(COREML_PROTO_ROOT "${COREML_PROTO_INCLUDE_DIR}/mlmodel/format" ABSOLUTE) + else() + FetchContent_Declare( + coremltools + URL ${DEP_URL_coremltools} + URL_HASH SHA1=${DEP_SHA1_coremltools} + PATCH_COMMAND ${Patch_EXECUTABLE} --binary --ignore-whitespace -p1 < ${PROJECT_SOURCE_DIR}/patches/coremltools/crossplatformbuild.patch + ) + # we don't build directly so use Populate. selected files are built from onnxruntime_providers_coreml.cmake + FetchContent_Populate(coremltools) + endif() endif() message(STATUS "Finished fetching external dependencies") diff --git a/ports/onnxruntime/portfile.cmake b/ports/onnxruntime/portfile.cmake index 8374d473..df9acf36 100644 --- a/ports/onnxruntime/portfile.cmake +++ b/ports/onnxruntime/portfile.cmake @@ -11,11 +11,16 @@ vcpkg_from_github( fix-cmake-cuda.patch fix-cmake-training.patch fix-cmake-tensorrt.patch + fix-cmake-coreml.patch fix-sources.patch fix-clang-cl-simd-compile.patch ) file(COPY "${CMAKE_CURRENT_LIST_DIR}/onnxruntime_external_deps.cmake" DESTINATION "${SOURCE_PATH}/cmake/external") -file(COPY "${CMAKE_CURRENT_LIST_DIR}/cuDNN.cmake" DESTINATION "${SOURCE_PATH}/cmake/external") +# todo: copied from the main branch. remove when upstream has same version +file(COPY "${CMAKE_CURRENT_LIST_DIR}/cuDNN.cmake" + "${CMAKE_CURRENT_LIST_DIR}/abseil-cpp.cmake" + DESTINATION "${SOURCE_PATH}/cmake/external" +) find_program(PROTOC NAMES protoc PATHS "${CURRENT_HOST_INSTALLED_DIR}/tools/protobuf" @@ -98,6 +103,12 @@ if("tensorrt" IN_LIST FEATURES) list(APPEND FEATURE_OPTIONS "-Donnxruntime_TENSORRT_HOME:PATH=${TENSORRT_ROOT}") endif() endif() +if("coreml" IN_LIST FEATURES) + list(APPEND FEATURE_OPTIONS + -D_enable_ML_PROGRAM=OFF # do not build CoreML Tools program + "-Dcoreml_INCLUDE_DIRS:PATH=${CURRENT_INSTALLED_DIR}/include" + ) +endif() # see tools/ci_build/build.py vcpkg_cmake_configure( @@ -128,7 +139,7 @@ vcpkg_cmake_configure( -Donnxruntime_USE_NEURAL_SPEED=OFF -DUSE_NEURAL_SPEED=OFF # for ORT_BUILD_INFO - "-DORT_GIT_COMMIT:STRING=26250ae74d2c9a3c6860625ba4a147ddfb936907" + "-DORT_GIT_COMMIT:STRING=ffceed9d44f2f3efb9dd69fa75fea51163c91d91" "-DORT_GIT_BRANCH:STRING=v${VERSION}" --compile-no-warning-as-error OPTIONS_DEBUG diff --git a/ports/onnxruntime/vcpkg.json b/ports/onnxruntime/vcpkg.json index 2599039b..bb67fbaa 100644 --- a/ports/onnxruntime/vcpkg.json +++ b/ports/onnxruntime/vcpkg.json @@ -1,6 +1,7 @@ { "name": "onnxruntime", "version-semver": "1.19.0", + "port-version": 1, "description": "ONNX Runtime: cross-platform, high performance ML inferencing and training accelerator", "homepage": "https://onnxruntime.ai/", "license": "MIT", @@ -71,6 +72,13 @@ "wil" ], "features": { + "coreml": { + "description": "Build with CoreML support", + "supports": "osx | ios", + "dependencies": [ + "coreml-tools" + ] + }, "cuda": { "description": "Build with CUDA support", "dependencies": [ diff --git a/versions/baseline.json b/versions/baseline.json index 72e4d83a..868e6e2f 100644 --- a/versions/baseline.json +++ b/versions/baseline.json @@ -142,7 +142,7 @@ }, "onnxruntime": { "baseline": "1.19.0", - "port-version": 0 + "port-version": 1 }, "opencl": { "baseline": "v2024.05.08", diff --git a/versions/o-/onnxruntime.json b/versions/o-/onnxruntime.json index b06a2a57..ae350daa 100644 --- a/versions/o-/onnxruntime.json +++ b/versions/o-/onnxruntime.json @@ -1,5 +1,10 @@ { "versions": [ + { + "git-tree": "e17c361e719fc6c637395121730b3adb999f6f3d", + "version-semver": "1.19.0", + "port-version": 1 + }, { "git-tree": "af74437fc8574baf7c2f36f729493f7be3059d5a", "version-semver": "1.19.0",