diff --git a/.github/workflows/macos.yaml b/.github/workflows/macos.yaml new file mode 100644 index 00000000000..ea797666456 --- /dev/null +++ b/.github/workflows/macos.yaml @@ -0,0 +1,105 @@ +name: macos + +on: + pull_request: + push: + branches: + - develop + - master + - 'release/**' + +jobs: + macos: + runs-on: macos-15 + defaults: + run: + shell: bash + + strategy: + matrix: + configuration: + - Release + - Debug + + env: + # Pinned to the same rocm-cmake commit used in requirements.txt so the + # ROCmCMakeBuildTools package matches the rest of the build. + ROCM_CMAKE_REF: 1d4652ae2ec0e44a67a7c415dd7e51c88a6aa68d + ROCM_CMAKE_PREFIX: ${{ github.workspace }}/rocm-cmake-install + + steps: + - uses: actions/checkout@v4.2.2 + + - name: Set up Python + # MIGraphX only needs a Python 3 interpreter for code generation here + # (Python bindings are disabled). This mirrors the python.org framework + # build used locally closely enough for that purpose. + uses: actions/setup-python@v4 + with: + python-version: 3.12 + + - name: Install dependencies (Homebrew) + # C++ libraries and build tools are resolved from Homebrew, matching the + # local macOS environment. sqlite is keg-only on macOS, so its prefix is + # added to CMAKE_PREFIX_PATH explicitly in the configure step. + run: | + brew update + brew install \ + cmake \ + ninja \ + ccache \ + pkg-config \ + sqlite \ + boost \ + eigen \ + nlohmann-json \ + msgpack-cxx \ + protobuf \ + abseil \ + pybind11 + + - name: Build and install rocm-cmake + # manually install for now + run: | + git clone https://github.com/ROCm/rocm-cmake.git "${RUNNER_TEMP}/rocm-cmake" + cd "${RUNNER_TEMP}/rocm-cmake" + git checkout "${ROCM_CMAKE_REF}" + cmake -S . -B build -G Ninja -DCMAKE_INSTALL_PREFIX="${ROCM_CMAKE_PREFIX}" + cmake --build build --target install + + - name: Cache ccache + uses: actions/cache@v4.2.0 + with: + path: ~/Library/Caches/ccache + key: macos-ccache-${{ matrix.configuration }}-${{ github.sha }} + restore-keys: macos-ccache-${{ matrix.configuration }}- + + - name: Configure + env: + CMAKE_C_COMPILER_LAUNCHER: ccache + CMAKE_CXX_COMPILER_LAUNCHER: ccache + run: | + # Homebrew prefix plus keg-only sqlite so find_package() locates them. + PREFIXES="$(brew --prefix);$(brew --prefix sqlite);${ROCM_CMAKE_PREFIX}" + cmake -S . -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=${{ matrix.configuration }} \ + -DCMAKE_PREFIX_PATH="${PREFIXES}" \ + -DEMBED_USE=CArrays \ + -DMIGRAPHX_ENABLE_GPU=Off \ + -DMIGRAPHX_ENABLE_CPU=Off \ + -DMIGRAPHX_ENABLE_FPGA=Off \ + -DMIGRAPHX_ENABLE_PYTHON=Off \ + -DBUILD_DEV=On \ + -DMIGRAPHX_DISABLE_LARGE_BUFFER_TESTS=On \ + -DCTEST_TIMEOUT=5000 + + - name: Build + run: | + cmake --build build --target migraphx + cmake --build build --target driver + cmake --build build --target tests + + - name: Test + run: | + cd build + ctest -j 8 --output-on-failure --timeout 5000 -E 'test_logger_test' diff --git a/cmake/Embed.cmake b/cmake/Embed.cmake index b53fc1bcea8..09310075439 100644 --- a/cmake/Embed.cmake +++ b/cmake/Embed.cmake @@ -24,6 +24,8 @@ include_guard(GLOBAL) +set(EMBED_MODULE_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "Directory containing the embed cmake helpers") + if(NOT BUILD_SHARED_LIBS) set(EMBED_USE_DEFAULT CArrays) elseif(WIN32) @@ -47,33 +49,6 @@ if(EMBED_USE STREQUAL "LD") find_program(EMBED_OBJCOPY objcopy REQUIRED) endif() -function(embed_wrap_string) - set(options) - set(oneValueArgs VARIABLE AT_COLUMN) - set(multiValueArgs) - cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - string(LENGTH ${${PARSE_VARIABLE}} string_length) - math(EXPR offset "0") - - while(string_length GREATER 0) - - if(string_length GREATER ${PARSE_AT_COLUMN}) - math(EXPR length "${PARSE_AT_COLUMN}") - else() - math(EXPR length "${string_length}") - endif() - - string(SUBSTRING ${${PARSE_VARIABLE}} ${offset} ${length} line) - set(lines "${lines}\n${line}") - - math(EXPR string_length "${string_length} - ${length}") - math(EXPR offset "${offset} + ${length}") - endwhile() - - set(${PARSE_VARIABLE} "${lines}" PARENT_SCOPE) -endfunction() - set(RESOURCE_ID 100 CACHE INTERNAL "" FORCE) function(reset_resource_id MULTIPLE) @@ -213,21 +188,18 @@ function(embed_file FILE BASE_DIRECTORY) VERBATIM) set(OUTPUT_FILE ${OUTPUT_FILE} PARENT_SCOPE) elseif(EMBED_USE STREQUAL "CArrays") - set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${FILE}) + # Generate the byte-array source at build time (parallel and incremental) + # instead of at configure time, which is far faster for many/large files. set(OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${REL_FILE}.cpp") - # reads source file contents as hex string - file(READ ${FILE} HEX_STRING HEX) - # wraps the hex string into multiple lines - embed_wrap_string(VARIABLE HEX_STRING AT_COLUMN 80) - # adds '0x' prefix and comma suffix before and after every byte respectively - string(REGEX REPLACE "([0-9a-f][0-9a-f])" "static_cast(0x\\1), " ARRAY_VALUES ${HEX_STRING}) - # removes trailing comma - string(REGEX REPLACE ", $" "" ARRAY_VALUES ${ARRAY_VALUES}) - file(WRITE "${OUTPUT_FILE}" " -#include -extern const char _binary_${OUTPUT_SYMBOL}_start[] = { ${ARRAY_VALUES} }; -extern const size_t _binary_${OUTPUT_SYMBOL}_length = sizeof(_binary_${OUTPUT_SYMBOL}_start); -") + add_custom_command( + OUTPUT "${OUTPUT_FILE}" + COMMAND ${CMAKE_COMMAND} + -DEMBED_INPUT=${FILE} + -DEMBED_OUTPUT=${OUTPUT_FILE} + -DEMBED_SYMBOL=${OUTPUT_SYMBOL} + -P ${EMBED_MODULE_DIR}/embed_gen.cmake + DEPENDS "${FILE}" "${EMBED_MODULE_DIR}/embed_gen.cmake" + VERBATIM) set(OUTPUT_FILE ${OUTPUT_FILE} PARENT_SCOPE) endif() set(OUTPUT_SYMBOL ${OUTPUT_SYMBOL} PARENT_SCOPE) diff --git a/cmake/PythonModules.cmake b/cmake/PythonModules.cmake index c79c71ab26b..507d6c28c77 100644 --- a/cmake/PythonModules.cmake +++ b/cmake/PythonModules.cmake @@ -104,6 +104,9 @@ function(py_add_module NAME) py_extension(${NAME} ${PYTHON_VERSION}) endif() target_link_libraries(${NAME} PRIVATE pybind11::module pybind11::lto python${PYTHON_VERSION}::headers) + if(APPLE) + target_link_options(${NAME} PRIVATE "-undefined" "dynamic_lookup") + endif() if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") execute_process(COMMAND "${PYTHON_${PYTHON_VERSION}_EXECUTABLE}" -c "import sysconfig; print(sysconfig.get_config_var(\"EXT_SUFFIX\"))" OUTPUT_VARIABLE _python_module_extension) diff --git a/cmake/embed_gen.cmake b/cmake/embed_gen.cmake new file mode 100644 index 00000000000..2648123e5cc --- /dev/null +++ b/cmake/embed_gen.cmake @@ -0,0 +1,37 @@ +##################################################################################### +# The MIT License (MIT) +# +# Copyright (c) 2015-2026 Advanced Micro Devices, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +##################################################################################### + +# Turns a single data file into a C++ source with a byte array plus its length. +# Invoked at build time (one process per file) so embedding runs in parallel and +# only reruns when an input changes. A single linear regex does the hex->array +# conversion, avoiding any per-byte string copying. + +file(READ "${EMBED_INPUT}" HEX_STRING HEX) +string(REGEX REPLACE "([0-9a-f][0-9a-f])" "static_cast(0x\\1)," ARRAY_VALUES "${HEX_STRING}") + +file(WRITE "${EMBED_OUTPUT}" "\ +#include +extern const char _binary_${EMBED_SYMBOL}_start[] = { ${ARRAY_VALUES} }; +extern const size_t _binary_${EMBED_SYMBOL}_length = sizeof(_binary_${EMBED_SYMBOL}_start); +") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e1bc74e6a1f..60e47b5916b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -385,7 +385,11 @@ find_package(nlohmann_json 3.8.0 REQUIRED) target_link_libraries(migraphx PRIVATE nlohmann_json::nlohmann_json) find_package(SQLite3 REQUIRED) -target_link_libraries(migraphx PRIVATE SQLite::SQLite3) +if(TARGET SQLite::SQLite3) + target_link_libraries(migraphx PRIVATE SQLite::SQLite3) +else() + target_link_libraries(migraphx PRIVATE SQLite3::SQLite3) +endif() # See: https://github.com/msgpack/msgpack-c/wiki/Q%26A#how-to-support-both-msgpack-c-c-version-5x-and-6x- # Prefer 6.x (msgpack-cxx) diff --git a/src/fileutils.cpp b/src/fileutils.cpp index 0987e682d99..2153829dcdc 100644 --- a/src/fileutils.cpp +++ b/src/fileutils.cpp @@ -39,7 +39,11 @@ constexpr std::string_view object_file_postfix{".obj"}; #else constexpr std::string_view executable_postfix{""}; constexpr std::string_view library_prefix{"lib"}; +#ifdef __APPLE__ +constexpr std::string_view library_postfix{".dylib"}; +#else constexpr std::string_view library_postfix{".so"}; +#endif constexpr std::string_view static_library_postfix{".a"}; constexpr std::string_view object_file_postfix{".o"}; #endif diff --git a/src/include/migraphx/generic_float.hpp b/src/include/migraphx/generic_float.hpp index 64ae6610cb5..afef679dacd 100644 --- a/src/include/migraphx/generic_float.hpp +++ b/src/include/migraphx/generic_float.hpp @@ -90,7 +90,7 @@ template ::type; + static_cast(integer_divide_ceil(MantissaSize + ExponentSize + 1, 8)))>::type; type mantissa : MantissaSize; type exponent : ExponentSize; diff --git a/src/include/migraphx/verify.hpp b/src/include/migraphx/verify.hpp index 6a1f9c84423..0ee792841b5 100644 --- a/src/include/migraphx/verify.hpp +++ b/src/include/migraphx/verify.hpp @@ -100,7 +100,7 @@ struct compare_mag_fn template bool operator()(T x, U y) const { - return std::fabs(x) < std::fabs(y); + return std::fabs(static_cast(x)) < std::fabs(static_cast(y)); } }; static constexpr compare_mag_fn compare_mag{}; diff --git a/src/onnx/CMakeLists.txt b/src/onnx/CMakeLists.txt index de5d9322dec..3a23b0362cb 100644 --- a/src/onnx/CMakeLists.txt +++ b/src/onnx/CMakeLists.txt @@ -52,7 +52,7 @@ rocm_set_soversion(migraphx_onnx ${MIGRAPHX_SO_VERSION}) rocm_add_version_resource(migraphx_onnx "AMD MIGraphX" "MIGraphX ONNX Parser - ONNX Model Support") rocm_clang_tidy_check(migraphx_onnx) target_link_libraries(migraphx_onnx PRIVATE $) -if(NOT WIN32) +if(NOT WIN32 AND NOT APPLE) target_link_libraries(migraphx_onnx PRIVATE "-Wl,--exclude-libs,ALL") endif() target_link_libraries(migraphx_onnx PUBLIC migraphx) diff --git a/src/simplify_dyn_ops.cpp b/src/simplify_dyn_ops.cpp index 6a90d97fe70..23ba5d2fb84 100644 --- a/src/simplify_dyn_ops.cpp +++ b/src/simplify_dyn_ops.cpp @@ -651,13 +651,15 @@ struct simplify_select_module_output_shape : match::supports_dynamic_shapes mins.at(j) = min_val; maxes.at(j) = max_val; } + std::vector mins_sz(mins.begin(), mins.end()); + std::vector maxes_sz(maxes.begin(), maxes.end()); // fixed output shape case if(mins == maxes) { - return shape{shape_vec.front().type(), mins}; + return shape{shape_vec.front().type(), mins_sz}; } // dynamic output shape case - return shape{shape_vec.front().type(), mins, maxes, {}}; + return shape{shape_vec.front().type(), mins_sz, maxes_sz, {}}; } }; diff --git a/src/tf/CMakeLists.txt b/src/tf/CMakeLists.txt index 3cb070fe6bd..800e9ac183e 100644 --- a/src/tf/CMakeLists.txt +++ b/src/tf/CMakeLists.txt @@ -76,7 +76,7 @@ set_target_properties(migraphx_tf PROPERTIES EXPORT_NAME tf) rocm_set_soversion(migraphx_tf ${MIGRAPHX_SO_VERSION}) rocm_clang_tidy_check(migraphx_tf) target_link_libraries(migraphx_tf PRIVATE $) -if(NOT WIN32) +if(NOT WIN32 AND NOT APPLE) target_link_libraries(migraphx_tf PRIVATE "-Wl,--exclude-libs,ALL") endif() target_link_libraries(migraphx_tf PUBLIC migraphx) diff --git a/test/fileutils.cpp b/test/fileutils.cpp index d939e720cef..183116346f9 100644 --- a/test/fileutils.cpp +++ b/test/fileutils.cpp @@ -42,7 +42,11 @@ constexpr std::string_view object_file_postfix{".obj"}; #else constexpr std::string_view executable_postfix{""}; constexpr std::string_view library_prefix{"lib"}; +#ifdef __APPLE__ +constexpr std::string_view shared_object_postfix{".dylib"}; +#else constexpr std::string_view shared_object_postfix{".so"}; +#endif constexpr std::string_view static_library_postfix{".a"}; constexpr std::string_view object_file_postfix{".o"}; #endif diff --git a/test/include/test.hpp b/test/include/test.hpp index e8713bdcbfb..a8930e33607 100644 --- a/test/include/test.hpp +++ b/test/include/test.hpp @@ -36,7 +36,7 @@ #include #include -#ifdef __linux__ +#ifndef _WIN32 #include #endif