From c8c41184c45f89b32458e0e88adf53c93086066f Mon Sep 17 00:00:00 2001 From: Stanley Tsang Date: Fri, 17 Mar 2023 10:56:05 -0600 Subject: [PATCH] 5.4.4 cherry pick (#414) * Fixes to get rocPRIM benchmarks building on Windows (#387) * Fixes to get rocPRIM benchmarks building on Windows * Implementing PR recommendations * Remove unneeded variable set in cmake/Dependencies.cmake * Adding required variables for googlebenchmark install * Fix package name on Windows * Update cmake/Dependencies.cmake --- CMakeLists.txt | 10 +- benchmark/benchmark_utils.hpp | 3 + cmake/Dependencies.cmake | 280 +++++++++++++++++----------------- rmake.py | 6 +- 4 files changed, 152 insertions(+), 147 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b20ccb101..8fc79685b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,11 @@ endif() set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE CACHE BOOL "Add paths to linker search and installed rpath") +# Set CXX flags +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + set(BUILD_SHARED_LIBS OFF) # don't build client dependencies as shared if(NOT USE_HIP_CPU) # Get dependencies (required here to get rocm-cmake) @@ -100,11 +105,6 @@ if(BUILD_CODE_COVERAGE) add_link_options(--coverage) endif() -# Set CXX flags -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - if(USE_HIP_CPU) # Get dependencies include(cmake/Dependencies.cmake) diff --git a/benchmark/benchmark_utils.hpp b/benchmark/benchmark_utils.hpp index ebd5af27a..f2c852600 100644 --- a/benchmark/benchmark_utils.hpp +++ b/benchmark/benchmark_utils.hpp @@ -464,8 +464,11 @@ inline const char* Traits::name() { return "int64_t"; } +// On MSVC `int64_t` and `long long` are the same, leading to multiple definition errors +#ifndef WIN32 template <> inline const char* Traits::name() { return "int64_t"; } +#endif template <> inline const char* Traits::name() { return "float"; } template <> diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 594d0352e..72b360266 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -24,77 +24,86 @@ # rocPRIM dependencies # ########################### +# NOTE1: the reason we don't scope global state meddling using add_subdirectory +# is because CMake < 3.24 lacks CMAKE_FIND_PACKAGE_TARGETS_GLOBAL which +# would promote IMPORTED targets of find_package(CONFIG) to be visible +# by other parts of the build. So we save and restore global state. +# +# NOTE2: We disable the ROCMChecks.cmake warning noting that we meddle with +# global state. This is consequence of abusing the CMake CXX language +# which HIP piggybacks on top of. This kind of HIP support has one chance +# at observing the global flags, at the find_package(HIP) invocation. +# The device compiler won't be able to pick up changes after that, hence +# the warning. +set(USER_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +if(DEFINED BUILD_SHARED_LIBS) + set(USER_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) +endif() +set(USER_ROCM_WARN_TOOLCHAIN_VAR ${ROCM_WARN_TOOLCHAIN_VAR}) + +set(ROCM_WARN_TOOLCHAIN_VAR OFF CACHE BOOL "") +# Turn off warnings and errors for all warnings in dependencies +separate_arguments(CXX_FLAGS_LIST NATIVE_COMMAND ${CMAKE_CXX_FLAGS}) +list(REMOVE_ITEM CXX_FLAGS_LIST /WX -Werror -Werror=pendantic -pedantic-errors) +if(MSVC) + list(FILTER CXX_FLAGS_LIST EXCLUDE REGEX "/[Ww]([0-4]?)(all)?") # Remove MSVC warning flags + list(APPEND CXX_FLAGS_LIST /w) +else() + list(FILTER CXX_FLAGS_LIST EXCLUDE REGEX "-W(all|extra|everything)") # Remove GCC/LLVM flags + list(APPEND CXX_FLAGS_LIST -w) +endif() +list(JOIN CXX_FLAGS_LIST " " CMAKE_CXX_FLAGS) +# Don't build client dependencies as shared +set(BUILD_SHARED_LIBS OFF CACHE BOOL "Global flag to cause add_library() to create shared libraries if on." FORCE) + # HIP dependency is handled earlier in the project cmake file -# when VerifyCompiler.cmake is included. +# when VerifyCompiler.cmake is included (when not using HIP-CPU). -# For downloading, building, and installing required dependencies -include(cmake/DownloadProject.cmake) +include(FetchContent) if(USE_HIP_CPU) - find_package(Threads REQUIRED) - - set(CMAKE_REQUIRED_FLAGS "-std=c++17") - include(CheckCXXSymbolExists) - check_cxx_symbol_exists(__GLIBCXX__ "cstddef" STL_IS_GLIBCXX) - set(STL_DEPENDS_ON_TBB ${STL_IS_GLIBCXX}) - if(STL_DEPENDS_ON_TBB) - if(NOT DEPENDENCIES_FORCE_DOWNLOAD) - # TBB (https://github.com/oneapi-src/oneTBB) - find_package(TBB QUIET) - endif() - - if(NOT TBB_FOUND) - message(STATUS "TBB not found or force download TBB on. Downloading and building TBB.") - if(CMAKE_CONFIGURATION_TYPES) - message(FATAL_ERROR "DownloadProject.cmake doesn't support multi-configuration generators.") - endif() - set(TBB_ROOT ${CMAKE_CURRENT_BINARY_DIR}/deps/tbb CACHE PATH "") - download_project( - PROJ tbb - GIT_REPOSITORY https://github.com/oneapi-src/oneTBB.git - GIT_TAG v2020.3 - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - UPDATE_DISCONNECTED TRUE # Never update automatically from the remote repository - ) - #ExternalProject_Get_Property(tbb SOURCE_DIR) - set(TBB_SOURCE_DIR "${CMAKE_BINARY_DIR}/tbb-src") - list(APPEND CMAKE_MODULE_PATH "${TBB_SOURCE_DIR}/cmake") - include(TBBBuild) - tbb_build(TBB_ROOT "${TBB_SOURCE_DIR}" CONFIG_DIR TBB_CONFIG_DIR MAKE_ARGS tbb_build_dir=${TBB_ROOT}) - endif() - find_package(TBB REQUIRED CONFIG PATHS ${TBB_CONFIG_DIR} NO_DEFAULT_PATH) - endif(STL_DEPENDS_ON_TBB) - if(NOT DEPENDENCIES_FORCE_DOWNLOAD) - # HIP CPU Runtime (https://github.com/ROCm-Developer-Tools/HIP-CPU) find_package(hip_cpu_rt QUIET) endif() - - if(NOT hip_cpu_rt_FOUND) - message(STATUS "Downloading and building HIP CPU Runtime.") - set(HIP_CPU_ROOT "${CMAKE_CURRENT_BINARY_DIR}/deps/hip-cpu" CACHE PATH "") - download_project( - PROJ hip-cpu - GIT_REPOSITORY https://github.com/ROCm-Developer-Tools/HIP-CPU.git - GIT_TAG master - INSTALL_DIR "${HIP_CPU_ROOT}" - CMAKE_ARGS -Dhip_cpu_rt_BUILD_EXAMPLES=OFF -Dhip_cpu_rt_BUILD_TESTING=OFF -DCMAKE_PREFIX_PATH=${TBB_CONFIG_DIR} -DCMAKE_INSTALL_PREFIX= - LOG_DOWNLOAD TRUE - LOG_CONFIGURE TRUE - LOG_BUILD TRUE - LOG_INSTALL TRUE - BUILD_PROJECT TRUE - UPDATE_DISCONNECTED TRUE # Never update automatically from the remote repository + if(NOT TARGET hip_cpu_rt::hip_cpu_rt) + message(STATUS "HIP-CPU runtime not found. Fetching...") + FetchContent_Declare( + hip-cpu + GIT_REPOSITORY https://github.com/ROCm-Developer-Tools/HIP-CPU.git + GIT_TAG 56f559c93be210bb300dad3673c06d2bb0119d13 # master@2022.07.01 ) + FetchContent_MakeAvailable(hip-cpu) + if(NOT TARGET hip_cpu_rt::hip_cpu_rt) + add_library(hip_cpu_rt::hip_cpu_rt ALIAS hip_cpu_rt) + endif() + else() + find_package(hip_cpu_rt REQUIRED) + # If we found HIP-CPU as binary, search for transitive dependencies + find_package(Threads REQUIRED) + set(CMAKE_REQUIRED_FLAGS "-std=c++17") + include(CheckCXXSymbolExists) + check_cxx_symbol_exists(__GLIBCXX__ "cstddef" STL_IS_GLIBCXX) + set(STL_DEPENDS_ON_TBB ${STL_IS_GLIBCXX}) + if(STL_DEPENDS_ON_TBB) + find_package(TBB QUIET) + if(NOT TARGET TBB::tbb AND NOT TARGET tbb) + message(STATUS "Thread Building Blocks not found. Fetching...") + FetchContent_Declare( + thread-building-blocks + GIT_REPOSITORY https://github.com/oneapi-src/oneTBB.git + GIT_TAG 3df08fe234f23e732a122809b40eb129ae22733f # v2021.5.0 + ) + FetchContent_MakeAvailable(thread-building-blocks) + else() + find_package(TBB REQUIRED) + endif() + endif(STL_DEPENDS_ON_TBB) endif() - find_package(hip_cpu_rt REQUIRED CONFIG PATHS ${HIP_CPU_ROOT}) -endif() +endif(USE_HIP_CPU) # Test dependencies if(BUILD_TEST) - # NOTE: Google Test has created a mess with legacy FindGTest.cmake and newer GTestConfig.cmake + # NOTE1: Google Test has created a mess with legacy FindGTest.cmake and newer GTestConfig.cmake # # FindGTest.cmake defines: GTest::GTest, GTest::Main, GTEST_FOUND # @@ -102,106 +111,97 @@ if(BUILD_TEST) # # NOTE2: Finding GTest in MODULE mode, one cannot invoke find_package in CONFIG mode, because targets # will be duplicately defined. + # + # NOTE3: The following snippet first tries to find Google Test binary either in MODULE or CONFIG modes. + # If neither succeeds it goes on to import Google Test into this build either from a system + # source package (apt install googletest on Ubuntu 18.04 only) or GitHub and defines the MODULE + # mode targets. Otherwise if MODULE or CONFIG succeeded, then it prints the result to the + # console via a non-QUIET find_package call and if CONFIG succeeded, creates ALIAS targets + # with the MODULE IMPORTED names. if(NOT DEPENDENCIES_FORCE_DOWNLOAD) - # Google Test (https://github.com/google/googletest) find_package(GTest QUIET) endif() - if(NOT TARGET GTest::GTest AND NOT TARGET GTest::gtest) - message(STATUS "GTest not found or force download GTest on. Downloading and building GTest.") - if(CMAKE_CONFIGURATION_TYPES) - message(FATAL_ERROR "DownloadProject.cmake doesn't support multi-configuration generators.") + option(BUILD_GTEST "Builds the googletest subproject" ON) + option(BUILD_GMOCK "Builds the googlemock subproject" OFF) + option(INSTALL_GTEST "Enable installation of googletest." OFF) + if(EXISTS /usr/src/googletest AND NOT DEPENDENCIES_FORCE_DOWNLOAD) + FetchContent_Declare( + googletest + SOURCE_DIR /usr/src/googletest + ) + else() + message(STATUS "Google Test not found. Fetching...") + FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG e2239ee6043f73722e7aa812a459f54a28552929 # release-1.11.0 + ) + endif() + FetchContent_MakeAvailable(googletest) + add_library(GTest::GTest ALIAS gtest) + add_library(GTest::Main ALIAS gtest_main) + else() + find_package(GTest REQUIRED) + if(TARGET GTest::gtest_main AND NOT TARGET GTest::Main) + add_library(GTest::GTest ALIAS GTest::gtest) + add_library(GTest::Main ALIAS GTest::gtest_main) endif() - set(GTEST_ROOT ${CMAKE_CURRENT_BINARY_DIR}/deps/gtest CACHE PATH "") - download_project( - PROJ googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.11.0 - INSTALL_DIR ${GTEST_ROOT} - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DBUILD_GTEST=ON -DINSTALL_GTEST=ON -Dgtest_force_shared_crt=ON -DCMAKE_INSTALL_PREFIX= - LOG_DOWNLOAD TRUE - LOG_CONFIGURE TRUE - LOG_BUILD TRUE - LOG_INSTALL TRUE - BUILD_PROJECT TRUE - UPDATE_DISCONNECTED TRUE # Never update automatically from the remote repository - ) - find_package(GTest CONFIG REQUIRED PATHS ${GTEST_ROOT}) endif() -endif() +endif(BUILD_TEST) -# Benchmark dependencies if(BUILD_BENCHMARK) if(NOT DEPENDENCIES_FORCE_DOWNLOAD) - # Google Benchmark (https://github.com/google/benchmark.git) - find_package(benchmark QUIET) + find_package(benchmark CONFIG QUIET) endif() - - if(NOT benchmark_FOUND) - message(STATUS "Google Benchmark not found or force download Google Benchmark on. Downloading and building Google Benchmark.") - if(CMAKE_CONFIGURATION_TYPES) - message(FATAL_ERROR "DownloadProject.cmake doesn't support multi-configuration generators.") - endif() - set(GOOGLEBENCHMARK_ROOT ${CMAKE_CURRENT_BINARY_DIR}/deps/googlebenchmark CACHE PATH "") - if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")) - # hip-clang cannot compile googlebenchmark for some reason - set(COMPILER_OVERRIDE "-DCMAKE_CXX_COMPILER=g++") - endif() - - download_project( - PROJ googlebenchmark + if(NOT TARGET benchmark::benchmark) + message(STATUS "Google Benchmark not found. Fetching...") + option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." OFF) + option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark." OFF) + FetchContent_Declare( + googlebench GIT_REPOSITORY https://github.com/google/benchmark.git - GIT_TAG v1.6.1 - INSTALL_DIR ${GOOGLEBENCHMARK_ROOT} - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DBENCHMARK_ENABLE_TESTING=OFF -DCMAKE_INSTALL_PREFIX= -DCMAKE_CXX_STANDARD=14 ${COMPILER_OVERRIDE} - LOG_DOWNLOAD TRUE - LOG_CONFIGURE TRUE - LOG_BUILD TRUE - LOG_INSTALL TRUE - BUILD_PROJECT TRUE - UPDATE_DISCONNECTED TRUE + GIT_TAG d17ea665515f0c54d100c6fc973632431379f64b # v1.6.1 ) + set(HAVE_STD_REGEX ON) + set(RUN_HAVE_STD_REGEX 1) + FetchContent_MakeAvailable(googlebench) + if(NOT TARGET benchmark::benchmark) + add_library(benchmark::benchmark ALIAS benchmark) + endif() + else() + find_package(benchmark CONFIG REQUIRED) endif() - find_package(benchmark REQUIRED CONFIG PATHS ${GOOGLEBENCHMARK_ROOT}) -endif() - -set(PROJECT_EXTERN_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern) +endif(BUILD_BENCHMARK) -# By default, rocm software stack is expected at /opt/rocm -# set environment variable ROCM_PATH to change location -if(NOT ROCM_PATH) - set(ROCM_PATH /opt/rocm) +if(NOT DEPENDENCIES_FORCE_DOWNLOAD) + set(CMAKE_FIND_DEBUG_MODE TRUE) + find_package(ROCM 0.7.3 CONFIG QUIET PATHS /opt/rocm) + set(CMAKE_FIND_DEBUG_MODE FALSE) endif() - -find_package(ROCM 0.7.3 CONFIG QUIET PATHS ${ROCM_PATH} /opt/rocm) if(NOT ROCM_FOUND) - set(rocm_cmake_tag "master" CACHE STRING "rocm-cmake tag to download") - set(rocm_cmake_url "https://github.com/RadeonOpenCompute/rocm-cmake/archive/${rocm_cmake_tag}.zip") - set(rocm_cmake_path "${PROJECT_EXTERN_DIR}/rocm-cmake-${rocm_cmake_tag}") - set(rocm_cmake_archive "${rocm_cmake_path}.zip") - file(DOWNLOAD "${rocm_cmake_url}" "${rocm_cmake_archive}" STATUS status LOG log) - - list(GET status 0 status_code) - list(GET status 1 status_string) - - if(status_code EQUAL 0) - message(STATUS "downloading... done") - else() - message(FATAL_ERROR "error: downloading\n'${rocm_cmake_url}' failed - status_code: ${status_code} - status_string: ${status_string} - log: ${log}\n") + if(NOT EXISTS "${FETCHCONTENT_BASE_DIR}/rocm-cmake-src") + message(STATUS "ROCm CMake not found. Fetching...") + set(rocm_cmake_tag "master" CACHE STRING "rocm-cmake tag to download") + FetchContent_Declare( + rocm-cmake + URL https://github.com/RadeonOpenCompute/rocm-cmake/archive/${rocm_cmake_tag}.tar.gz + ) + FetchContent_MakeAvailable(rocm-cmake) endif() + find_package(ROCM CONFIG REQUIRED NO_DEFAULT_PATH HINTS "${rocm-cmake_SOURCE_DIR}") +else() + find_package(ROCM 0.7.3 CONFIG REQUIRED PATHS /opt/rocm) +endif() - execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzvf "${rocm_cmake_archive}" - WORKING_DIRECTORY ${PROJECT_EXTERN_DIR}) - execute_process( COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${PROJECT_EXTERN_DIR}/rocm-cmake . - WORKING_DIRECTORY ${PROJECT_EXTERN_DIR}/rocm-cmake-${rocm_cmake_tag} ) - execute_process( COMMAND ${CMAKE_COMMAND} --build rocm-cmake-${rocm_cmake_tag} --target install - WORKING_DIRECTORY ${PROJECT_EXTERN_DIR}) - - find_package( ROCM 0.7.3 REQUIRED CONFIG PATHS ${PROJECT_EXTERN_DIR}/rocm-cmake ) +# Restore user global state +set(CMAKE_CXX_FLAGS ${USER_CXX_FLAGS}) +if(DEFINED USER_BUILD_SHARED_LIBS) + set(BUILD_SHARED_LIBS ${USER_BUILD_SHARED_LIBS}) +else() + unset(BUILD_SHARED_LIBS CACHE ) endif() +set(ROCM_WARN_TOOLCHAIN_VAR ${USER_ROCM_WARN_TOOLCHAIN_VAR} CACHE BOOL "") include(ROCMSetupVersion) include(ROCMCreatePackage) diff --git a/rmake.py b/rmake.py index 72bf407fe..917afcef1 100644 --- a/rmake.py +++ b/rmake.py @@ -101,11 +101,13 @@ def config_cmd(): #set CPACK_PACKAGING_INSTALL_PREFIX= defined as blank as it is appended to end of path for archive creation cmake_platform_opts.append( f"-DWIN32=ON -DCPACK_PACKAGING_INSTALL_PREFIX=") #" -DCPACK_PACKAGING_INSTALL_PREFIX={rocm_path}" cmake_platform_opts.append( f"-DCMAKE_INSTALL_PREFIX=\"C:/hipSDK\"" ) + rocm_cmake_path = '"' + cmake_path(os.getenv("ROCM_CMAKE_PATH", "C:/hipSDK")) + '"' generator = f"-G Ninja" # "-G \"Visual Studio 16 2019\" -A x64" # -G NMake ") # cmake_options.append( generator ) else: rocm_path = os.getenv( 'ROCM_PATH', "/opt/rocm") + rocm_cmake_path = '"' + rocm_path + '"' if (OS_info["ID"] in ['centos', 'rhel']): cmake_executable = "cmake3" else: @@ -135,7 +137,7 @@ def config_cmd(): deps_dir = os.path.abspath(os.path.join(build_dir, 'deps')).replace('\\','/') else: deps_dir = args.deps_dir - cmake_base_options = f"-DROCM_PATH={rocm_path} -DCMAKE_PREFIX_PATH:PATH={rocm_path}" # -DCMAKE_INSTALL_PREFIX=rocmath-install" #-DCMAKE_INSTALL_LIBDIR= + cmake_base_options = f"-DROCM_PATH={rocm_path} -DCMAKE_PREFIX_PATH:PATH={rocm_path[:-1]};{rocm_cmake_path[1:]}" # -DCMAKE_INSTALL_PREFIX=rocmath-install" #-DCMAKE_INSTALL_LIBDIR= cmake_options.append( cmake_base_options ) print( cmake_options ) @@ -160,7 +162,7 @@ def config_cmd(): cmake_options.append( f"-DBUILD_TEST=ON -DBUILD_DIR={build_dir}" ) if args.build_clients: - cmake_options.append( f"-DBUILD_TEST=ON -DBUILD_EXAMPLE=ON -DBUILD_DIR={build_dir}" ) + cmake_options.append( f"-DBUILD_TEST=ON -DBUILD_BENCHMARK=ON -DBUILD_EXAMPLE=ON -DBUILD_DIR={build_dir}" ) cmake_options.append( f"-DAMDGPU_TARGETS={args.gpu_architecture}" )