diff --git a/.github/workflows/rebuildDependencies.yml b/.github/workflows/rebuildDependencies.yml index 5328c50..6f1d175 100644 --- a/.github/workflows/rebuildDependencies.yml +++ b/.github/workflows/rebuildDependencies.yml @@ -134,13 +134,18 @@ jobs: git sparse-checkout set \ recipes/minizip \ recipes/flac \ + recipes/onnx \ + recipes/onnxruntime \ $recipePathQt \ git checkout + # Patch conan recipe to support msvc version 192 + git apply --ignore-whitespace ../conan_patches/onnxruntime/recipe.diff + # versions must be synced with: conan_patches//conandata.yml # if no custom patches are required for a package, it should be removed from here - for p in minizip/1.3.1 flac/1.4.2 ; do + for p in minizip/1.3.1 flac/1.4.2 onnx/1.16.2 onnxruntime/1.18.1 ; do IFS_OLD="$IFS" IFS=/ read package version <<<"$p" @@ -220,7 +225,9 @@ jobs: - name: Remove build requirements' binaries run: | graphFile='graph.json' - packageListFile='pkglist.json' + hostPackagesFile='packages-host.json' + buildPackagesFile='packages-build.json' + buildFilteredPackagesFile='packages-build-filtered.txt' conan graph info . \ $CONAN_PROFILES \ @@ -229,12 +236,30 @@ jobs: --build=never \ --no-remote \ > "$graphFile" + conan list \ --graph "$graphFile" \ --graph-context=build-only \ --format=json \ - > "$packageListFile" - conan remove --list "$packageListFile" --confirm + > $buildPackagesFile + + conan list \ + --graph "$graphFile" \ + --graph-context=host \ + --format=json \ + > $hostPackagesFile + + # Some are both build and host requirements and must not be removed + # => exclude them from the list + python3 -c ' + import json, sys + build_dict = json.load(open(sys.argv[1]))["Local Cache"] # => {"pkg1": {...}, "pkg2": {...}, ...} + host_list = json.load(open(sys.argv[2]))["Local Cache"] # => ["pkg1", "pkg2", ...] + filtered_dict = {k: v for k, v in build_dict.items() if k not in host_list} + json.dump({"Local Cache": filtered_dict}, open(sys.argv[3], "w")) + ' "$buildPackagesFile" "$hostPackagesFile" "$buildFilteredPackagesFile" + + conan remove --list "$buildFilteredPackagesFile" --confirm - name: Create list of built packages run: | diff --git a/conan_patches/onnx/conandata.yml b/conan_patches/onnx/conandata.yml new file mode 100644 index 0000000..68d8d9d --- /dev/null +++ b/conan_patches/onnx/conandata.yml @@ -0,0 +1,7 @@ +patches: + "1.16.2": + - patch_file: "patches/apple-pre-2019.diff" + patch_description: | + Fixes errors for older apple targets: + error: 'basic_fstream' is unavailable: introduced in macOS 10.15 + error: 'basic_fstream' is unavailable: introduced in iOS 13.0 diff --git a/conan_patches/onnx/patches/apple-pre-2019.diff b/conan_patches/onnx/patches/apple-pre-2019.diff new file mode 100644 index 0000000..34f02fe --- /dev/null +++ b/conan_patches/onnx/patches/apple-pre-2019.diff @@ -0,0 +1,12 @@ +--- a/onnx/common/file_utils.h ++++ b/onnx/common/file_utils.h +@@ -17,8 +17,7 @@ namespace ONNX_NAMESPACE { + + template + void LoadProtoFromPath(const std::string proto_path, T& proto) { +- std::filesystem::path proto_u8_path = std::filesystem::u8path(proto_path); +- std::fstream proto_stream(proto_u8_path, std::ios::in | std::ios::binary); ++ std::fstream proto_stream(proto_path, std::ios::in | std::ios::binary); + if (!proto_stream.good()) { + fail_check("Unable to open proto file: ", proto_path, ". Please check if it is a valid proto. "); + } diff --git a/conan_patches/onnxruntime/conandata.yml b/conan_patches/onnxruntime/conandata.yml new file mode 100644 index 0000000..b4114a2 --- /dev/null +++ b/conan_patches/onnxruntime/conandata.yml @@ -0,0 +1,13 @@ +patches: + "1.18.1": + - patch_file: "patches/android-64.diff" + patch_description: | + Fixes error for arm64-v8a targets: + onnxruntime/core/mlas/lib/mlasi.h:366:11: error: unknown type name 'bfloat16_t' + - patch_file: "patches/msvc-x86.diff" + patch_description: | + Fixes detection of x86 windows targets during cross-compilation. + - patch_file: "patches/win7.diff" + patch_description: | + Fixes compile errors on for windows 7 targets: + error C3861: 'CreateFile2': identifier not found diff --git a/conan_patches/onnxruntime/patches/android-64.diff b/conan_patches/onnxruntime/patches/android-64.diff new file mode 100644 index 0000000..ab48aa7 --- /dev/null +++ b/conan_patches/onnxruntime/patches/android-64.diff @@ -0,0 +1,31 @@ +--- a/cmake/onnxruntime_mlas.cmake ++++ b/cmake/onnxruntime_mlas.cmake +@@ -352,7 +362,7 @@ else() + ${MLAS_SRC_DIR}/sqnbitgemm_kernel_neon.cpp + ) + set_source_files_properties(${MLAS_SRC_DIR}/sqnbitgemm_kernel_neon.cpp +- PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+dotprod") ++ PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+dotprod+bf16") + if (NOT APPLE) + set(mlas_platform_srcs + ${mlas_platform_srcs} +@@ -368,13 +378,13 @@ else() + ${MLAS_SRC_DIR}/qgemm_kernel_ummla.cpp + ${MLAS_SRC_DIR}/sbgemm_kernel_neon.cpp + ) +- set_source_files_properties(${MLAS_SRC_DIR}/aarch64/HalfGemmKernelNeon.S PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+fp16 ") +- set_source_files_properties(${MLAS_SRC_DIR}/aarch64/QgemmS8S8KernelSmmla.S PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+i8mm ") +- set_source_files_properties(${MLAS_SRC_DIR}/aarch64/QgemmU8X8KernelUmmla.S PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+i8mm ") ++ set_source_files_properties(${MLAS_SRC_DIR}/aarch64/HalfGemmKernelNeon.S PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+fp16+bf16 ") ++ set_source_files_properties(${MLAS_SRC_DIR}/aarch64/QgemmS8S8KernelSmmla.S PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+i8mm+bf16 ") ++ set_source_files_properties(${MLAS_SRC_DIR}/aarch64/QgemmU8X8KernelUmmla.S PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+i8mm+bf16 ") + set_source_files_properties(${MLAS_SRC_DIR}/aarch64/SbgemmKernelNeon.S PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+bf16 ") +- set_source_files_properties(${MLAS_SRC_DIR}/activate_fp16.cpp PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+fp16 ") +- set_source_files_properties(${MLAS_SRC_DIR}/dwconv.cpp PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+fp16 ") +- set_source_files_properties(${MLAS_SRC_DIR}/pooling_fp16.cpp PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+fp16 ") ++ set_source_files_properties(${MLAS_SRC_DIR}/activate_fp16.cpp PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+fp16+bf16 ") ++ set_source_files_properties(${MLAS_SRC_DIR}/dwconv.cpp PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+fp16+bf16 ") ++ set_source_files_properties(${MLAS_SRC_DIR}/pooling_fp16.cpp PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+fp16+bf16 ") + set_source_files_properties(${MLAS_SRC_DIR}/sbgemm_kernel_neon.cpp PROPERTIES COMPILE_FLAGS " -march=armv8.2-a+bf16 ") + endif() + diff --git a/conan_patches/onnxruntime/patches/msvc-x86.diff b/conan_patches/onnxruntime/patches/msvc-x86.diff new file mode 100644 index 0000000..24bc32a --- /dev/null +++ b/conan_patches/onnxruntime/patches/msvc-x86.diff @@ -0,0 +1,43 @@ +--- a/cmake/adjust_global_compile_flags.cmake ++++ b/cmake/adjust_global_compile_flags.cmake +@@ -226,13 +226,17 @@ endmacro() + + #Set global compile flags for all the source code(including third_party code like protobuf) + #This section must be before any add_subdirectory, otherwise build may fail because /MD,/MT mismatch ++message(STATUS "MSVC=${MSVC} | CMAKE_VS_PLATFORM_NAME=${CMAKE_VS_PLATFORM_NAME} | CMAKE_C_COMPILER_ARCHITECTURE_ID=${CMAKE_C_COMPILER_ARCHITECTURE_ID} | CMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}") + if (MSVC) + if (CMAKE_VS_PLATFORM_NAME) + # Multi-platform generator + set(onnxruntime_target_platform ${CMAKE_VS_PLATFORM_NAME}) ++ elseif (CMAKE_C_COMPILER_ARCHITECTURE_ID) ++ set(onnxruntime_target_platform ${CMAKE_C_COMPILER_ARCHITECTURE_ID}) + else() + set(onnxruntime_target_platform ${CMAKE_SYSTEM_PROCESSOR}) + endif() ++ message(STATUS "Temporary onnxruntime_target_platform=${onnxruntime_target_platform}") + if (onnxruntime_target_platform STREQUAL "ARM64") + set(onnxruntime_target_platform "ARM64") + enable_language(ASM_MARMASM) +@@ -241,18 +245,19 @@ if (MSVC) + elseif (onnxruntime_target_platform STREQUAL "ARM" OR CMAKE_GENERATOR MATCHES "ARM") + set(onnxruntime_target_platform "ARM") + enable_language(ASM_MARMASM) +- elseif (onnxruntime_target_platform STREQUAL "x64" OR onnxruntime_target_platform STREQUAL "x86_64" OR onnxruntime_target_platform STREQUAL "AMD64" OR CMAKE_GENERATOR MATCHES "Win64") ++ elseif (onnxruntime_target_platform MATCHES "[Xx]64" OR onnxruntime_target_platform MATCHES "[Xx]86_64" OR onnxruntime_target_platform STREQUAL "AMD64" OR CMAKE_GENERATOR MATCHES "Win64") + set(onnxruntime_target_platform "x64") + enable_language(ASM_MASM) +- elseif (onnxruntime_target_platform STREQUAL "Win32" OR onnxruntime_target_platform STREQUAL "x86" OR onnxruntime_target_platform STREQUAL "i386" OR onnxruntime_target_platform STREQUAL "i686") ++ elseif (onnxruntime_target_platform STREQUAL "Win32" OR onnxruntime_target_platform MATCHES "[Xx]86" OR onnxruntime_target_platform STREQUAL "i386" OR onnxruntime_target_platform STREQUAL "i686") + set(onnxruntime_target_platform "x86") + enable_language(ASM_MASM) + message("Enabling SAFESEH for x86 build") + set(CMAKE_ASM_MASM_FLAGS "${CMAKE_ASM_MASM_FLAGS} /safeseh") + else() +- message(FATAL_ERROR "Unknown CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") ++ message(FATAL_ERROR "Unknown onnxruntime_target_platform: ${onnxruntime_target_platform}") + endif() + ++ message(STATUS "Final onnxruntime_target_platform=${onnxruntime_target_platform}") + + #Always enable exception handling, even for Windows ARM + if (NOT onnxruntime_DISABLE_EXCEPTIONS) diff --git a/conan_patches/onnxruntime/patches/win7.diff b/conan_patches/onnxruntime/patches/win7.diff new file mode 100644 index 0000000..648d621 --- /dev/null +++ b/conan_patches/onnxruntime/patches/win7.diff @@ -0,0 +1,123 @@ +--- a/onnxruntime/test/shared_lib/test_model_loading.cc ++++ b/onnxruntime/test/shared_lib/test_model_loading.cc +@@ -227,7 +227,7 @@ using ScopedFileDescriptor = ScopedResource; + + void FileMmap(const ORTCHAR_T* file_path, void*& mapped_base) { + #ifdef _WIN32 +- wil::unique_hfile file_handle{CreateFile2(file_path, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, NULL)}; ++ wil::unique_hfile file_handle{CreateFileW(file_path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)}; + ASSERT_TRUE(file_handle.get() != INVALID_HANDLE_VALUE); + + wil::unique_hfile file_mapping_handle{ +--- a/onnxruntime/core/platform/windows/env.cc ++++ b/onnxruntime/core/platform/windows/env.cc +@@ -314,7 +314,7 @@ PIDType WindowsEnv::GetSelfPid() const { + + Status WindowsEnv::GetFileLength(_In_z_ const ORTCHAR_T* file_path, size_t& length) const { + wil::unique_hfile file_handle{ +- CreateFile2(file_path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, OPEN_EXISTING, NULL)}; ++ CreateFileW(file_path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)}; + if (file_handle.get() == INVALID_HANDLE_VALUE) { + const auto error_code = GetLastError(); + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "open file ", ToUTF8String(Basename(file_path)), " fail, errcode = ", error_code, " - ", std::system_category().message(error_code)); +@@ -361,7 +361,7 @@ Status WindowsEnv::ReadFileIntoBuffer(_In_z_ const ORTCHAR_T* const file_path, c + ORT_RETURN_IF_NOT(offset >= 0, "offset < 0"); + ORT_RETURN_IF_NOT(length <= buffer.size(), "length > buffer.size()"); + wil::unique_hfile file_handle{ +- CreateFile2(file_path, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, NULL)}; ++ CreateFileW(file_path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)}; + if (file_handle.get() == INVALID_HANDLE_VALUE) { + const auto error_code = GetLastError(); + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "open file ", ToUTF8String(Basename(file_path)), " fail, errcode = ", error_code, " - ", std::system_category().message(error_code)); +@@ -414,7 +414,7 @@ Status WindowsEnv::MapFileIntoMemory(_In_z_ const ORTCHAR_T* file_path, + } + + wil::unique_hfile file_handle{ +- CreateFile2(file_path, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, NULL)}; ++ CreateFileW(file_path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)}; + if (file_handle.get() == INVALID_HANDLE_VALUE) { + const auto error_code = GetLastError(); + return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, +@@ -600,16 +600,14 @@ common::Status WindowsEnv::GetCanonicalPath( + PathString& canonical_path) const { + // adapted from MSVC STL std::filesystem::canonical() implementation + // https://github.com/microsoft/STL/blob/ed3cbf36416a385828e7a5987ca52cb42882d84b/stl/inc/filesystem#L2986 +- CREATEFILE2_EXTENDED_PARAMETERS param; +- memset(¶m, 0, sizeof(param)); +- param.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); +- param.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS; +- wil::unique_hfile file_handle{CreateFile2( +- path.c_str(), +- FILE_READ_ATTRIBUTES, +- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, +- OPEN_EXISTING, +- ¶m)}; ++ wil::unique_hfile file_handle{CreateFileW( ++ path.c_str(), // LPCWSTR lpFileName ++ FILE_READ_ATTRIBUTES, // DWORD dwDesiredAccess ++ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, // DWORD dwShareMode ++ nullptr, // LPSECURITY_ATTRIBUTES lpSecurityAttributes ++ OPEN_EXISTING, // DWORD dwCreationDisposition ++ FILE_FLAG_BACKUP_SEMANTICS, // DWORD dwFlagsAndAttributes ++ nullptr)}; // HANDLE hTemplateFile + + if (file_handle.get() == INVALID_HANDLE_VALUE) { + const auto error_code = GetLastError(); +--- a/onnxruntime/core/platform/windows/env_time.cc ++++ b/onnxruntime/core/platform/windows/env_time.cc +@@ -18,6 +18,7 @@ limitations under the License. + + #include + #include ++#include + #include + #include + #include +@@ -28,14 +29,10 @@ namespace { + + class WindowsEnvTime : public EnvTime { + public: +- WindowsEnvTime() : GetSystemTimePreciseAsFileTime_(GetSystemTimePreciseAsFileTime) {} ++ WindowsEnvTime() = default; + + uint64_t NowMicros() override { +- if (GetSystemTimePreciseAsFileTime_ != NULL) { +- // GetSystemTimePreciseAsFileTime function is only available in latest +- // versions of Windows, so we need to check for its existence here. +- // All std::chrono clocks on Windows proved to return +- // values that may repeat, which is not good enough for some uses. ++ // System time in 100-ns ticks since 1601-01-01 + constexpr int64_t kUnixEpochStartTicks = 116444736000000000i64; + constexpr int64_t kFtToMicroSec = 10; + +@@ -43,7 +40,8 @@ class WindowsEnvTime : public EnvTime { + // just any microseconds because it is often used as an argument + // to TimedWait() on condition variable + FILETIME system_time; +- GetSystemTimePreciseAsFileTime_(&system_time); ++ // Get current system time as FILETIME (available on all supported Windows versions) ++ GetSystemTimeAsFileTime(&system_time); + + LARGE_INTEGER li; + li.LowPart = system_time.dwLowDateTime; +@@ -54,16 +52,11 @@ class WindowsEnvTime : public EnvTime { + li.QuadPart /= kFtToMicroSec; + return li.QuadPart; + } +- using namespace std::chrono; +- return duration_cast(system_clock::now().time_since_epoch()) +- .count(); +- } +- +- void SleepForMicroseconds(int64_t micros) { Sleep(static_cast(micros) / 1000); } + +- private: +- typedef VOID(WINAPI* FnGetSystemTimePreciseAsFileTime)(LPFILETIME); +- FnGetSystemTimePreciseAsFileTime GetSystemTimePreciseAsFileTime_; ++ void SleepForMicroseconds(int64_t micros) { ++ DWORD ms = static_cast((micros + 999) / 1000); ++ Sleep(ms); ++ } + }; + + } // namespace diff --git a/conan_patches/onnxruntime/recipe.diff b/conan_patches/onnxruntime/recipe.diff new file mode 100644 index 0000000..0f8de88 --- /dev/null +++ b/conan_patches/onnxruntime/recipe.diff @@ -0,0 +1,13 @@ +diff --git a/recipes/onnxruntime/all/conanfile.py b/recipes/onnxruntime/all/conanfile.py +index 0757ecdc0..bb8cca8bf 100644 +--- a/recipes/onnxruntime/all/conanfile.py ++++ b/recipes/onnxruntime/all/conanfile.py +@@ -47,7 +52,7 @@ class OnnxRuntimeConan(ConanFile): + def _compilers_minimum_version(self): + return { + "Visual Studio": "17", +- "msvc": "193", ++ "msvc": "192", + "gcc": "9", + "clang": "5", + "apple-clang": "10", diff --git a/conan_profiles/base/common b/conan_profiles/base/common index 5179ed5..4729750 100644 --- a/conan_profiles/base/common +++ b/conan_profiles/base/common @@ -225,3 +225,8 @@ pcre2/*:build_pcre2grep=False sqlite3/*:build_executable=False opusfile/*:http=False zstd/*:build_programs=False + +# Prevents onnxruntime->date->libcurl dependency +# NOTE: use_system_tz_db is specific to date/3.0.1 +# Newer date recipes would need the tz_db=system option instead. +date/*:use_system_tz_db=True diff --git a/conanfile.py b/conanfile.py index b359850..588f9bf 100644 --- a/conanfile.py +++ b/conanfile.py @@ -28,11 +28,13 @@ class VCMI(ConanFile): options = { "target_pre_windows10": [True, False], "with_ffmpeg": [True, False], + "with_onnxruntime": [True, False], "lua_lib": [None, "luajit", "lua"] } default_options = { "target_pre_windows10": False, "with_ffmpeg": True, + "with_onnxruntime": True, "lua_lib": "luajit", } @@ -87,6 +89,9 @@ def requirements(self): else: self.requires("qt/[~5.15.2]") + if self.options.with_onnxruntime: + self.requires("onnxruntime/1.18.1") + def validate(self): # FFmpeg if is_msvc(self) and self.options.with_ffmpeg and self.dependencies["ffmpeg"].options.shared != True: