blob: bd9bcf7cd583b68d2133fdc2350b4dbb5e1c3df8 [file] [edit]
include(ExternalProject)
include(External)
include(GPUTestVariant)
llvm_externals_find(TEST_SUITE_HIP_ROOT "hip" "HIP prerequisites")
message(STATUS "TEST_SUITE_HIP_ROOT: ${TEST_SUITE_HIP_ROOT}")
get_filename_component(HIP_CLANG_PATH ${CMAKE_CXX_COMPILER} DIRECTORY)
message(STATUS "HIP_CLANG_PATH: ${HIP_CLANG_PATH}")
# Include Catch tests integration module
# Find Python interpreter for running llvm-lit
# The llvm-lit script may have a hardcoded Python version in its shebang
# (e.g., #!/usr/bin/python3.10) that may not be available on all systems.
# We explicitly invoke llvm-lit with the detected Python interpreter.
find_package(Python3 COMPONENTS Interpreter)
if(Python3_FOUND)
set(HIP_TEST_SUITE_LIT ${Python3_EXECUTABLE} ${TEST_SUITE_LIT})
set(HIP_TEST_SUITE_LIT_BINARY ${TEST_SUITE_LIT})
message(STATUS "HIP tests will use Python: ${Python3_EXECUTABLE}")
else()
set(HIP_TEST_SUITE_LIT ${TEST_SUITE_LIT})
set(HIP_TEST_SUITE_LIT_BINARY ${TEST_SUITE_LIT})
message(WARNING "Python3 not found, HIP tests may fail if llvm-lit has wrong shebang")
endif()
include(${CMAKE_CURRENT_LIST_DIR}/HipCatchTests.cmake)
# Get rocm-libraries commit from TheRock (for version alignment)
function(get_therock_rocm_libraries_version OUT_VAR)
set(THEROCK_LOCAL_DEV_PATH "/tmp/TheRock" CACHE PATH "Local TheRock for dev")
set(THEROCK_REPO_URL "https://github.com/ROCm/TheRock.git" CACHE STRING "TheRock URL")
set(THEROCK_BRANCH "main" CACHE STRING "TheRock branch")
# Check if we have a local development copy
if(EXISTS "${THEROCK_LOCAL_DEV_PATH}/.git")
message(STATUS "Using local TheRock: ${THEROCK_LOCAL_DEV_PATH}")
set(_therock_path "${THEROCK_LOCAL_DEV_PATH}")
else()
# CI path: use shallow clone in build directory
set(_therock_path "${CMAKE_BINARY_DIR}/_deps/therock-metadata")
if(EXISTS "${_therock_path}/.git")
message(STATUS "Updating cached TheRock metadata...")
execute_process(
COMMAND git -C "${_therock_path}" fetch --depth=1 origin ${THEROCK_BRANCH}
RESULT_VARIABLE _fetch_result
OUTPUT_QUIET ERROR_QUIET
)
if(_fetch_result EQUAL 0)
execute_process(
COMMAND git -C "${_therock_path}" reset --hard FETCH_HEAD
OUTPUT_QUIET ERROR_QUIET
)
endif()
else()
message(STATUS "Cloning TheRock metadata (shallow, ~100KB)...")
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/_deps")
execute_process(
COMMAND git clone --depth=1 --filter=blob:none --no-checkout
${THEROCK_REPO_URL} "${_therock_path}"
OUTPUT_QUIET ERROR_QUIET
COMMAND_ERROR_IS_FATAL ANY
)
execute_process(
COMMAND git -C "${_therock_path}" checkout ${THEROCK_BRANCH} -- .gitmodules
OUTPUT_QUIET ERROR_QUIET
COMMAND_ERROR_IS_FATAL ANY
)
endif()
endif()
# Extract rocm-libraries commit reference
execute_process(
COMMAND git -C "${_therock_path}" ls-tree HEAD rocm-libraries
OUTPUT_VARIABLE _tree_output
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE _result
)
if(NOT _result EQUAL 0)
message(FATAL_ERROR "Failed to query rocm-libraries version from TheRock")
endif()
string(REGEX MATCH "commit ([0-9a-f]+)" _ "${_tree_output}")
set(${OUT_VAR} "${CMAKE_MATCH_1}" PARENT_SCOPE)
endfunction()
# Inspired from create_one_local_test. Runs hipify on the TestSource and then compiles it.
# Search for the reference files next to TestSource.
macro(create_one_hipify_cuda_test TestName TestSource VairantOffload VariantSuffix VariantCPPFlags VariantLibs)
set(_cuda_src "${TestSource}")
set(_hip_src "${TestName}.hip")
set(_hipify_target "${TestName}-hipify")
set_source_files_properties(${_hip_src} PROPERTIES LANGUAGE CXX)
add_custom_command(OUTPUT ${_hip_src}
COMMAND ${HIPIFY_EXE} "${_cuda_src}" -o "${_hip_src}"
DEPENDS "${_cuda_src}")
add_custom_target(${_hipify_target} DEPENDS ${_hip_src})
set(_executable ${TestName}-${VariantSuffix})
set(_executable_path ${CMAKE_CURRENT_BINARY_DIR}/${_executable})
llvm_test_run()
get_filename_component(_test_source_dir "${TestSource}" DIRECTORY)
get_filename_component(_test_source_name "${TestSource}" NAME_WE)
set(REFERENCE_OUTPUT "${_test_source_dir}/${test_source_name}.reference_output")
if(EXISTS "${REFERENCE_OUTPUT}")
llvm_test_verify(WORKDIR %S
%b/${FPCMP} %o ${REFERENCE_OUTPUT}-${VariantSuffix}
)
llvm_test_executable(${_executable} ${_hip_src})
llvm_test_data(${_executable}
DEST_SUFFIX "-${VariantSuffix}"
${REFERENCE_OUTPUT})
else()
llvm_test_executable(${_executable} ${_hip_src})
endif()
target_compile_options(${_executable} PUBLIC ${VariantCPPFLAGS})
# In External/CUDA, tests define a STDLIB_VERSION that matches the C++
# standard supported by the standard library.
# For the HIP case, we set a huge number and assume that the latest C++
# standard version is supported by the library.
target_compile_definitions(${_executable} PRIVATE STDLIB_VERSION=9999)
add_dependencies(${_executable} ${_hipify_target})
if(VariantLibs)
target_link_libraries(${_executable} ${VariantLibs})
endif()
add_dependencies(hip-tests-simple-${VariantSuffix} ${_executable})
list(APPEND VARIANT_SIMPLE_TEST_TARGETS ${_executable}.test)
endmacro()
# Create targets for HIP tests that are part of the test suite.
macro(create_local_hip_tests VariantSuffix)
set(VariantOffload "hip")
# Set per-source compilation/link options
set_source_files_properties(with-fopenmp.hip PROPERTIES
COMPILE_FLAGS -fopenmp)
# TODO: Add the flag after the kernel argument splitting pass is enabled.
#set_source_files_properties(split-kernel-args.hip PROPERTIES
# COMPILE_FLAGS "-mllvm -amdgpu-enable-split-kernel-args")
# Add HIP tests to be added to hip-tests-simple
list(APPEND HIP_LOCAL_TESTS array)
list(APPEND HIP_LOCAL_TESTS empty)
list(APPEND HIP_LOCAL_TESTS with-fopenmp)
list(APPEND HIP_LOCAL_TESTS saxpy)
list(APPEND HIP_LOCAL_TESTS memmove)
list(APPEND HIP_LOCAL_TESTS memset)
list(APPEND HIP_LOCAL_TESTS split-kernel-args)
list(APPEND HIP_LOCAL_TESTS builtin-logb-scalbn)
list(APPEND HIP_LOCAL_TESTS InOneWeekend)
list(APPEND HIP_LOCAL_TESTS TheNextWeek)
# Copy files needed for ray-tracing tests.
file(GLOB IMAGE_FILES "workload/ray-tracing/images/*.jpg" "workload/ray-tracing/images/*.png")
file(COPY ${IMAGE_FILES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
foreach(_hip_test IN LISTS HIP_LOCAL_TESTS)
set(test_source "${_hip_test}.hip")
if(_hip_test STREQUAL "TheNextWeek" OR _hip_test STREQUAL "InOneWeekend")
file(GLOB REF_PPM_FILES "workload/ray-tracing/${_hip_test}/*.ppm")
file(COPY ${REF_PPM_FILES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
set(test_source "workload/ray-tracing/${_hip_test}/main.cc")
# need -mfma to enable FMA in host code
set_source_files_properties(${test_source} PROPERTIES
COMPILE_FLAGS "-xhip -mfma")
endif()
create_one_local_test(${_hip_test} ${test_source}
${VariantOffload} ${VariantSuffix}
"${VariantCPPFLAGS}" "${VariantLibs}")
endforeach()
list(APPEND CUDA_LOCAL_TESTS algorithm)
list(APPEND CUDA_LOCAL_TESTS cmath)
list(APPEND CUDA_LOCAL_TESTS complex)
list(APPEND CUDA_LOCAL_TESTS math_h)
list(APPEND CUDA_LOCAL_TESTS new)
find_program(HIPIFY_EXE
NAME hipify-perl
PATHS ${_RocmPath}/bin)
if(HIPIFY_EXE)
foreach(_cuda_test IN LISTS CUDA_LOCAL_TESTS)
set(_cuda_src "${CMAKE_CURRENT_SOURCE_DIR}/../CUDA/${_cuda_test}.cu")
create_one_hipify_cuda_test(${_cuda_test} ${_cuda_src}
${VariantOffload} ${VariantSuffix}
"${VariantCPPFLAGS}" "${VariantLibs}")
endforeach()
else()
message(WARNING "hipify-perl not found for ROCm installation in ${_RocmPath}.")
endif()
# Add test for Blender.
configure_file(workload/blender/test_blender.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test_blender.sh @ONLY)
configure_file(workload/blender/verify_blender.sh.in ${CMAKE_CURRENT_BINARY_DIR}/verify_blender.sh @ONLY)
file(COPY utils/log_data.py DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
file(COPY utils/compare_image.py DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
file(COPY utils/requirements.txt DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
llvm_test_run(EXECUTABLE "/bin/bash" "test_blender.sh")
llvm_test_verify(/bin/bash verify_blender.sh %o)
llvm_add_test(blender.test test_blender.sh)
list(APPEND VARIANT_SIMPLE_TEST_TARGETS blender.test)
endmacro()
function(create_hip_test VariantSuffix)
message(STATUS "Creating HIP test variant ${VariantSuffix}")
add_custom_target(hip-tests-simple-${VariantSuffix}
COMMENT "Build HIP test variant ${VariantSuffix}")
set(VariantCPPFLAGS ${_HIP_CPPFLAGS})
set(VariantLibs ${_HIP_Libs})
list(APPEND LDFLAGS ${_HIP_LDFLAGS})
create_local_hip_tests(${VariantSuffix})
add_dependencies(hip-tests-simple hip-tests-simple-${VariantSuffix})
# Enable verbose output for running HIP tests.
set(HIP_LIT_FLAGS "-v")
if (HIP_EXPORT_XUNIT_XML)
list(APPEND HIP_LIT_FLAGS --xunit-xml-output hip-results-${VariantSuffix}.xml)
endif()
add_custom_target(check-hip-simple-${VariantSuffix}
COMMAND ${HIP_TEST_SUITE_LIT} ${HIP_LIT_FLAGS}
${VARIANT_SIMPLE_TEST_TARGETS}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS hip-tests-simple-${VariantSuffix}
USES_TERMINAL)
add_dependencies(check-hip-simple check-hip-simple-${VariantSuffix})
# Integrate Catch tests for this variant (if enabled)
if(ENABLE_HIP_CATCH_TESTS)
integrate_catch_tests(${VariantSuffix} ${_RocmPath})
endif()
endfunction(create_hip_test)
macro(create_hip_tests)
# Find all rocm installations at Externals/hip/ directory.
# For ROCm, the path looks like rocm-4.1.0
message(STATUS "Checking HIP prerequisites in ${TEST_SUITE_HIP_ROOT}")
file(GLOB RocmVersions ${TEST_SUITE_HIP_ROOT}/rocm-*)
list(SORT RocmVersions)
foreach(RocmDir IN LISTS RocmVersions)
get_version(RocmVersion ${RocmDir})
message(STATUS "Found ROCm ${RocmVersion}")
list(APPEND ROCM_PATHS ${RocmDir})
endforeach(RocmDir)
if(NOT ROCM_PATHS)
message(SEND_ERROR
"There are no ROCm installations in ${TEST_SUITE_HIP_ROOT}")
return()
endif()
add_custom_target(hip-tests-simple
COMMENT "Build all simple HIP tests")
add_custom_target(check-hip-simple
COMMENT "Run all simple HIP tests")
# Initialize Catch tests framework
initialize_catch_tests()
if(NOT AMDGPU_ARCHS)
list(APPEND AMDGPU_ARCHS "gfx906;gfx90a;gfx1030;gfx1100;gfx1201;gfx942;gfx950;native")
endif()
foreach(_RocmPath ${ROCM_PATHS})
get_version(_RocmVersion ${_RocmPath})
set(_HIP_Suffix "hip-${_RocmVersion}")
# Set up HIP test flags
set(_HIP_CPPFLAGS --rocm-path=${_RocmPath})
set(_HIP_LDFLAGS --rocm-path=${_RocmPath} --hip-link -rtlib=compiler-rt -unwindlib=libgcc -frtlib-add-rpath)
# Unset these for each iteration of rocm path.
set(_ArchFlags)
set(_ArchList)
foreach(_AMDGPUArch IN LISTS AMDGPU_ARCHS)
list(APPEND _ArchFlags --offload-arch=${_AMDGPUArch})
endforeach()
message(STATUS "Building ${_RocmPath} targets for ${AMDGPU_ARCHS}")
list(APPEND _HIP_CPPFLAGS ${_ArchFlags})
create_hip_test(${_HIP_Suffix})
endforeach()
if (EXTERNAL_HIP_TESTS_KOKKOS)
set(EXTERNAL_HIP_TESTS_KOKKOS_TAG "4.5.01" CACHE STRING "Kokkos tag to download and test")
ExternalProject_Add(TestKokkosHIP
GIT_REPOSITORY https://github.com/kokkos/kokkos.git
GIT_TAG ${EXTERNAL_HIP_TESTS_KOKKOS_TAG}
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release
-DCMAKE_CXX_STANDARD=17
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DKokkos_ENABLE_HIP=ON
-DKokkos_ARCH_AMD_GFX90A=ON
-DCMAKE_PREFIX_PATH=/opt/rocm
-DKokkos_ENABLE_TESTS=ON
INSTALL_COMMAND ""
TEST_COMMAND ""
)
add_custom_target(build-kokkos DEPENDS TestKokkosHIP)
ExternalProject_Get_Property(TestKokkosHIP BINARY_DIR)
add_custom_target(test-kokkos ${CMAKE_COMMAND} -E env GTEST_FILTER=-hip.atomics:hip.bit_manip_bit_ceil "ctest" WORKING_DIRECTORY "${BINARY_DIR}" DEPENDS build-kokkos)
endif()
if (EXTERNAL_HIP_TESTS_GINKGO)
set(EXTERNAL_HIP_TESTS_GINKGO_TAG "v1.9.0" CACHE STRING "Ginkgo tag to download and test")
ExternalProject_Add(TestGinkgoHIP
GIT_REPOSITORY https://github.com/ginkgo-project/ginkgo.git
GIT_TAG ${EXTERNAL_HIP_TESTS_GINKGO_TAG}
CMAKE_ARGS -DGINKGO_BUILD_HIP=ON
-DCMAKE_PREFIX_PATH=/opt/rocm
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DGINKGO_BUILD_MPI=OFF
-DCMAKE_HIP_COMPILER=${CMAKE_CXX_COMPILER}
-DGINKGO_WITH_CCACHE=OFF
-DGINKGO_BUILD_EXAMPLES=OFF
INSTALL_COMMAND ""
TEST_COMMAND ""
)
add_custom_target(build-ginkgo DEPENDS TestGinkgoHIP)
ExternalProject_Get_Property(TestGinkgoHIP BINARY_DIR)
add_custom_target(test-ginkgo COMMAND "ctest" "-R hip" WORKING_DIRECTORY "${BINARY_DIR}" DEPENDS build-ginkgo)
endif()
if (EXTERNAL_HIP_TESTS_ROCPRIM)
# Get rocm-libraries version from TheRock
get_therock_rocm_libraries_version(_rocm_libraries_commit)
message(STATUS "Using rocm-libraries commit: ${_rocm_libraries_commit}")
set(ROCPRIM_TESTS_PARALLELISM "16" CACHE STRING "-j Argument to ctest")
include(FetchContent)
# XXX: Can we reduce what is being downloaded here using somewhat simple mechanisms?
FetchContent_Declare(
rocm-libraries
GIT_REPOSITORY https://github.com/ROCm/rocm-libraries.git
GIT_TAG ${_rocm_libraries_commit}
)
# Download rocm-libraries but don't configure yet
FetchContent_GetProperties(rocm-libraries)
if(NOT rocm-libraries_POPULATED)
FetchContent_Populate(rocm-libraries)
# Patch rocprim test/CMakeLists.txt to use PROJECT_SOURCE_DIR instead of CMAKE_SOURCE_DIR
# This fixes the issue where CMAKE_SOURCE_DIR points to llvm-test-suite instead of rocprim
# If not patched, enabling tests will fail during configure with a missing file
file(READ "${rocm-libraries_SOURCE_DIR}/projects/rocprim/test/CMakeLists.txt" _rocprim_test_cmake)
string(REPLACE "\${CMAKE_SOURCE_DIR}/test/" "\${PROJECT_SOURCE_DIR}/test/" _rocprim_test_cmake "${_rocprim_test_cmake}")
string(REPLACE "\${CMAKE_SOURCE_DIR}/rtest." "\${PROJECT_SOURCE_DIR}/rtest." _rocprim_test_cmake "${_rocprim_test_cmake}")
file(WRITE "${rocm-libraries_SOURCE_DIR}/projects/rocprim/test/CMakeLists.txt" "${_rocprim_test_cmake}")
endif()
# Configure rocPRIM as isolated external project (like Kokkos/Ginkgo pattern)
ExternalProject_Add(rocprim-external
SOURCE_DIR ${rocm-libraries_SOURCE_DIR}/projects/rocprim
BINARY_DIR ${rocm-libraries_BINARY_DIR}/rocprim
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_HIP_COMPILER=${CMAKE_CXX_COMPILER}
-DGPU_TARGETS=${AMDGPU_ARCHS}
-DBUILD_TEST=ON
-DBUILD_BENCHMARK=OFF
-DBUILD_EXAMPLE=OFF
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON
BUILD_COMMAND "" # Don't build during configure
INSTALL_COMMAND ""
TEST_COMMAND ""
)
# Standalone target to build all rocPRIM tests
add_custom_target(build-rocprim
COMMAND ${CMAKE_COMMAND} --build ${rocm-libraries_BINARY_DIR}/rocprim
DEPENDS rocprim-external
COMMENT "Building all rocPRIM tests"
)
# Standalone target to run rocPRIM tests
add_custom_target(test-rocprim
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -j ${ROCPRIM_TESTS_PARALLELISM}
WORKING_DIRECTORY ${rocm-libraries_BINARY_DIR}/rocprim
DEPENDS build-rocprim
COMMENT "Running rocPRIM tests"
)
endif()
# Build all HIP tests (simple + catch if enabled)
if(ENABLE_HIP_CATCH_TESTS)
add_custom_target(hip-tests-all DEPENDS hip-tests-simple hip-tests-catch
COMMENT "Build all HIP tests (simple + catch).")
else()
add_custom_target(hip-tests-all DEPENDS hip-tests-simple
COMMENT "Build all HIP tests (simple only, catch disabled).")
endif()
file(COPY lit.local.cfg DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
endmacro(create_hip_tests)
if(TEST_SUITE_HIP_ROOT)
create_hip_tests()
endif()