blob: 10f6d5c98f4ba994719a5f4dc7655d3424c62926 [file] [edit]
# CMake module for integrating hip-tests Catch tests into llvm-test-suite
# This module provides functions to discover and build Catch-based HIP tests
include(CMakeParseArguments)
# Global variables for Catch test configuration
set(ENABLE_HIP_CATCH_TESTS OFF CACHE BOOL "Enable HIP Catch test framework and all catch test targets")
set(CATCH_TEST_CATEGORIES "unit" CACHE STRING "Semicolon-separated list of test categories to include (unit;stress;performance;perftests)")
set(CATCH_TEST_SUBDIRS "" CACHE STRING "Semicolon-separated list of test subdirectories to include (e.g., compiler;memory;stream). Empty means all subdirectories within enabled categories.")
set(HIP_CATCH_TEST_TIMEOUT 60 CACHE STRING "Timeout for individual Catch tests in seconds")
set(HIP_CATCH_TEST_VERBOSE OFF CACHE BOOL "Show verbose output with individual TEST_CASE results from Catch2")
# Generic target architectures for hipSquareGenericTarget test
#
# AMD GPUs support "generic targets" (e.g., gfx10-3-generic) which allow a single
# binary to run on multiple specific GPUs within a family (e.g., gfx1030, gfx1031, gfx1032).
# The HIP runtime matches the generic target to the actual GPU at load time.
#
# The hipSquareGenericTarget test validates this feature by:
# 1. Building the main test with BOTH specific (AMDGPU_ARCHS) and generic architectures
# 2. Building helper executables with ONLY generic architectures
# 3. At runtime, checking that generic-only binaries can execute on the actual GPU
#
# This list is used by:
# - Main test executable (create_catch_test_executable) - lines 381-388
# - Helper executables (create_generic_target_executables) - lines 220-273
#
# Note: Generic targets require Code Object V6+, which is the default in ROCm 6.0+.
set(HIP_GENERIC_TARGET_ARCHS
"--offload-arch=gfx9-generic"
"--offload-arch=gfx9-4-generic:sramecc+:xnack-"
"--offload-arch=gfx9-4-generic:sramecc-:xnack-"
"--offload-arch=gfx9-4-generic:xnack+"
"--offload-arch=gfx10-1-generic"
"--offload-arch=gfx10-3-generic"
"--offload-arch=gfx11-generic"
"--offload-arch=gfx12-generic"
)
# Local paths for Catch test infrastructure
set(HIP_CATCH_TESTS_DIR "${CMAKE_CURRENT_LIST_DIR}/catch")
# Try to find system-installed Catch2 v2.13.10+
# Note: v2.13.10 is used because v2.13.4 has glibc 2.34+ incompatibility (MINSIGSTKSZ issue)
find_package(Catch2 2.13.10 QUIET)
if(Catch2_FOUND)
message(STATUS "Using system Catch2: ${Catch2_DIR}")
get_target_property(CATCH2_INCLUDE_PATH Catch2::Catch2 INTERFACE_INCLUDE_DIRECTORIES)
else()
message(STATUS "Catch2 >= 2.13.10 not found on system, fetching v2.13.10...")
include(FetchContent)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.13.10
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(Catch2)
set(CATCH2_INCLUDE_PATH "${catch2_SOURCE_DIR}/single_include/catch2")
endif()
set(CATCH2_FOUND TRUE)
# Global tracking for hierarchical targets
# These will be set as GLOBAL properties to track across function calls
define_property(GLOBAL PROPERTY CATCH_ALL_VARIANTS
BRIEF_DOCS "List of all discovered HIP variants"
FULL_DOCS "Tracks all variant suffixes (e.g., hip-7.2.0) discovered during configuration")
define_property(GLOBAL PROPERTY CATCH_CATEGORY_TARGETS_CREATED
BRIEF_DOCS "List of categories for which aggregated targets have been created"
FULL_DOCS "Prevents duplicate target creation for category-level aggregated targets")
define_property(GLOBAL PROPERTY CATCH_SUBDIR_TARGETS_CREATED
BRIEF_DOCS "List of category-subdir pairs for which aggregated targets have been created"
FULL_DOCS "Prevents duplicate target creation for subdirectory-level aggregated targets")
# Function to validate Catch test infrastructure
function(validate_catch_tests_infrastructure)
set(_required_paths
"${HIP_CATCH_TESTS_DIR}/unit/compiler"
"${HIP_CATCH_TESTS_DIR}/external/picojson/picojson.h"
"${HIP_CATCH_TESTS_DIR}/hipTestMain"
"${HIP_CATCH_TESTS_DIR}/include"
)
# Note: Catch2 is now obtained via find_package or FetchContent, not vendored
# Note: kernels/ directory not required for unit/compiler tests
foreach(_path ${_required_paths})
if(NOT EXISTS "${_path}")
message(FATAL_ERROR "Required Catch test path not found: ${_path}")
endif()
endforeach()
message(STATUS "Using local Catch test infrastructure: ${HIP_CATCH_TESTS_DIR}")
message(STATUS "Catch2 include path: ${CATCH2_INCLUDE_PATH}")
endfunction()
# Function to discover test sources from hip-tests
# Arguments:
# CATEGORY - Test category (unit, stress, performance, perftests)
# SUBDIRS - Specific subdirectories to include (optional, default: all)
# Returns:
# Sets ${CATEGORY}_TEST_DIRS in parent scope
function(discover_catch_test_category CATEGORY)
set(options)
set(oneValueArgs)
set(multiValueArgs SUBDIRS)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
set(_catch_base "${HIP_CATCH_TESTS_DIR}/${CATEGORY}")
if(NOT IS_DIRECTORY "${_catch_base}")
message(STATUS "Category ${CATEGORY} not found in Catch tests, skipping")
return()
endif()
# If specific subdirectories requested via argument, use them;
# otherwise check CATCH_TEST_SUBDIRS cache variable;
# otherwise discover all
if(ARG_SUBDIRS)
set(_test_subdirs ${ARG_SUBDIRS})
elseif(CATCH_TEST_SUBDIRS)
# Use subdirectories from CATCH_TEST_SUBDIRS, filtering to only those that exist
set(_test_subdirs "")
foreach(_subdir ${CATCH_TEST_SUBDIRS})
if(IS_DIRECTORY "${_catch_base}/${_subdir}")
list(APPEND _test_subdirs "${_subdir}")
message(STATUS "Including subdirectory from CATCH_TEST_SUBDIRS: ${CATEGORY}/${_subdir}")
else()
message(STATUS "Subdirectory ${CATEGORY}/${_subdir} not found, skipping")
endif()
endforeach()
else()
# Discover all subdirectories automatically.
file(GLOB _potential_subdirs RELATIVE "${_catch_base}" "${_catch_base}/*")
set(_test_subdirs "")
foreach(_subdir ${_potential_subdirs})
if(IS_DIRECTORY "${_catch_base}/${_subdir}")
# Check if directory has any .cc test files
file(GLOB _test_files "${_catch_base}/${_subdir}/*.cc")
if(_test_files)
list(APPEND _test_subdirs "${_subdir}")
endif()
endif()
endforeach()
endif()
if(_test_subdirs)
message(STATUS "Discovered ${CATEGORY} test subdirectories: ${_test_subdirs}")
else()
message(STATUS "No test subdirectories found for ${CATEGORY} category")
endif()
set(${CATEGORY}_TEST_DIRS "${_test_subdirs}" PARENT_SCOPE)
endfunction()
# Helper function to track test targets at multiple levels
# Arguments:
# TEST_TARGET - The test target name (e.g., catch_unit_compiler-hip-7.2.0.test)
# CATEGORY - Category name (e.g., unit)
# SUBDIR - Subdirectory name (e.g., compiler)
# VARIANT - Variant suffix (e.g., hip-7.2.0)
function(track_test_target_multi_level TEST_TARGET CATEGORY SUBDIR VARIANT)
# Track at global level (all catch tests)
set_property(GLOBAL APPEND PROPERTY CATCH_ALL_TEST_TARGETS "${TEST_TARGET}")
# Track at per-variant global level
set_property(GLOBAL APPEND PROPERTY "CATCH_TEST_TARGETS_${VARIANT}" "${TEST_TARGET}")
# Track at per-category level (all variants)
set_property(GLOBAL APPEND PROPERTY "CATCH_${CATEGORY}_TEST_TARGETS" "${TEST_TARGET}")
# Track at per-category-variant level
set_property(GLOBAL APPEND PROPERTY "CATCH_${CATEGORY}_TEST_TARGETS_${VARIANT}" "${TEST_TARGET}")
# Track at per-subdirectory level (all variants)
set_property(GLOBAL APPEND PROPERTY "CATCH_${CATEGORY}_${SUBDIR}_TEST_TARGETS" "${TEST_TARGET}")
# Track at per-subdirectory-variant level
set_property(GLOBAL APPEND PROPERTY "CATCH_${CATEGORY}_${SUBDIR}_TEST_TARGETS_${VARIANT}" "${TEST_TARGET}")
endfunction()
# Function to create special generic target executables for hipSquareGenericTarget test
#
# The hipSquareGenericTarget test requires THREE executables to fully test generic targets:
#
# 1. Main test executable (created by create_catch_test_executable):
# - Built with AMDGPU_ARCHS (specific, e.g., gfx1030) + HIP_GENERIC_TARGET_ARCHS (generic)
# - Runs the Catch2 test harness
# - Contains TEST_CASEs that invoke the helper executables
#
# 2. hipSquareGenericTargetOnly (created here):
# - Built with ONLY generic architectures (no specific GPU targets)
# - Tests that a generic-only binary can execute on the actual GPU
# - The main test runs this via: ./hipSquareGenericTargetOnly
#
# 3. hipSquareGenericTargetOnlyCompressed (created here):
# - Same as #2, but with --offload-compress for compressed code objects
# - Tests that compressed generic-only binaries work correctly
#
# Test flow:
# ninja check-hip-catch
# -> builds main test + helper executables
# -> LIT runs main test executable
# -> main test's TEST_CASEs check if GPU supports generic targets
# -> if supported: spawns helper executables and verifies they run successfully
# -> if not supported: test is skipped (e.g., no generic mapping for the GPU)
#
# Arguments:
# TEST_BASENAME - Base name of the test (e.g., hipSquareGenericTarget)
# TEST_DIR - Directory containing the test sources
# VARIANT_SUFFIX - Variant suffix (e.g., hip-7.2.0)
# ROCM_PATH - Path to ROCm installation
function(create_generic_target_executables TEST_BASENAME TEST_DIR VARIANT_SUFFIX ROCM_PATH)
# Check if this is AMD platform (generic targets are AMD-specific)
get_filename_component(_compiler_name "${CMAKE_CXX_COMPILER}" NAME)
if(NOT (_compiler_name MATCHES "hipcc" OR _compiler_name MATCHES "clang"))
message(STATUS "Skipping generic target executables (not AMD platform)")
return()
endif()
message(STATUS "Creating generic target executables for ${TEST_BASENAME}-${VARIANT_SUFFIX}")
# Use shared generic target architecture flags from module scope
set(_source_file "${TEST_DIR}/${TEST_BASENAME}.cc")
set(_output_dir "${CMAKE_CURRENT_BINARY_DIR}/catch_tests")
# Common source files
set(_common_sources
"${_source_file}"
"${HIP_CATCH_TESTS_DIR}/hipTestMain/hip_test_context.cc"
"${HIP_CATCH_TESTS_DIR}/hipTestMain/hip_test_features.cc"
"${HIP_CATCH_TESTS_DIR}/hipTestMain/main.cc"
)
# Common include directories
set(_include_flags
"-I${ROCM_PATH}/include"
"-I${HIP_CATCH_TESTS_DIR}/include"
"-I${CATCH2_INCLUDE_PATH}"
"-I${HIP_CATCH_TESTS_DIR}/external/picojson"
)
# Determine library linking flags
if(WIN32)
set(_libfs_flag "")
set(_exe_suffix ".exe")
else()
set(_libfs_flag "-lstdc++fs")
set(_exe_suffix "")
endif()
# 1. Build hipSquareGenericTargetOnly (regular fatbin with generic targets only)
set(_exe_name_regular "hipSquareGenericTargetOnly${_exe_suffix}")
set(_output_path_regular "${_output_dir}/${_exe_name_regular}")
add_custom_command(
OUTPUT "${_output_path_regular}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${_output_dir}"
COMMAND ${CMAKE_CXX_COMPILER}
-DNO_GENERIC_TARGET_ONLY_TEST
--std=c++17
-x hip
-w
${HIP_GENERIC_TARGET_ARCHS}
${_common_sources}
-o "${_output_path_regular}"
--hip-path=${ROCM_PATH}
--rocm-path=${ROCM_PATH}
--hip-link
-rtlib=compiler-rt
-unwindlib=libgcc
-frtlib-add-rpath
${_include_flags}
${_libfs_flag}
DEPENDS ${_common_sources}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Building ${_exe_name_regular} for ${VARIANT_SUFFIX}"
VERBATIM
)
# 2. Build hipSquareGenericTargetOnlyCompressed (compressed fatbin with generic targets only)
set(_exe_name_compressed "hipSquareGenericTargetOnlyCompressed${_exe_suffix}")
set(_output_path_compressed "${_output_dir}/${_exe_name_compressed}")
add_custom_command(
OUTPUT "${_output_path_compressed}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${_output_dir}"
COMMAND ${CMAKE_CXX_COMPILER}
-DNO_GENERIC_TARGET_ONLY_TEST
-DGENERIC_COMPRESSED
--std=c++17
-x hip
--offload-compress
-w
${HIP_GENERIC_TARGET_ARCHS}
${_common_sources}
-o "${_output_path_compressed}"
--hip-path=${ROCM_PATH}
--rocm-path=${ROCM_PATH}
--hip-link
-rtlib=compiler-rt
-unwindlib=libgcc
-frtlib-add-rpath
${_include_flags}
${_libfs_flag}
DEPENDS ${_common_sources}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Building ${_exe_name_compressed} for ${VARIANT_SUFFIX}"
VERBATIM
)
# Create custom targets for these executables
add_custom_target(hipSquareGenericTargetOnly-${VARIANT_SUFFIX}
DEPENDS "${_output_path_regular}"
)
add_custom_target(hipSquareGenericTargetOnlyCompressed-${VARIANT_SUFFIX}
DEPENDS "${_output_path_compressed}"
)
# Make the main test executable depend on these
set(_main_test_exe "catch_unit_compiler_${TEST_BASENAME}-${VARIANT_SUFFIX}")
if(TARGET ${_main_test_exe})
add_dependencies(${_main_test_exe}
hipSquareGenericTargetOnly-${VARIANT_SUFFIX}
hipSquareGenericTargetOnlyCompressed-${VARIANT_SUFFIX}
)
message(STATUS "Added generic target executable dependencies to ${_main_test_exe}")
endif()
# Also add to the build target hierarchy
if(TARGET hip-tests-catch-unit-compiler-${VARIANT_SUFFIX})
add_dependencies(hip-tests-catch-unit-compiler-${VARIANT_SUFFIX}
hipSquareGenericTargetOnly-${VARIANT_SUFFIX}
hipSquareGenericTargetOnlyCompressed-${VARIANT_SUFFIX}
)
endif()
endfunction()
# Function to create a Catch test executable
# Arguments:
# TEST_NAME - Name of the test
# TEST_SOURCES - Source file(s) (can be a single file or list of files)
# TEST_DIR - Directory containing the test sources
# CATEGORY - Test category (unit, stress, etc.)
# SUBDIR - Subdirectory name
# VARIANT_SUFFIX - Variant suffix (e.g., hip-7.2.0)
# ROCM_PATH - Path to ROCm installation
macro(create_catch_test_executable TEST_NAME TEST_SOURCES TEST_DIR CATEGORY SUBDIR VARIANT_SUFFIX ROCM_PATH)
set(_test_exe "${TEST_NAME}-${VARIANT_SUFFIX}")
set(_test_sources "")
# Build full paths to source files
foreach(_src ${TEST_SOURCES})
list(APPEND _test_sources "${TEST_DIR}/${_src}")
endforeach()
# Add hipTestMain sources (required for catch2 integration)
list(APPEND _test_sources
"${HIP_CATCH_TESTS_DIR}/hipTestMain/main.cc"
"${HIP_CATCH_TESTS_DIR}/hipTestMain/hip_test_context.cc"
"${HIP_CATCH_TESTS_DIR}/hipTestMain/hip_test_features.cc"
)
# Check if sources exist (fail early on configuration problems)
foreach(_src ${_test_sources})
if(NOT EXISTS "${_src}")
message(FATAL_ERROR "Source file not found: ${_src}")
endif()
endforeach()
# Create the executable
add_executable(${_test_exe} EXCLUDE_FROM_ALL ${_test_sources})
# Ensure timeit tool is built first (needed for compilation timing)
if(TARGET build-timeit)
add_dependencies(${_test_exe} build-timeit)
endif()
# Set properties
set_target_properties(${_test_exe} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/catch_tests"
)
# Include directories
target_include_directories(${_test_exe} PRIVATE
${CATCH2_INCLUDE_PATH}
"${HIP_CATCH_TESTS_DIR}/include"
"${HIP_CATCH_TESTS_DIR}/external/picojson"
)
# Add HIP runtime includes
# hipcc wrapper provides these automatically, direct compilers need explicit paths
if(NOT _compiler_name MATCHES "hipcc")
target_include_directories(${_test_exe} PRIVATE
"${ROCM_PATH}/include"
)
endif()
# Compile definitions
# Note: __HIP_PLATFORM_AMD__ or __HIP_PLATFORM_NVIDIA__ is automatically
# defined by HIP headers based on the compiler backend, so no manual
# platform definition is needed
# target_compile_definitions(${_test_exe} PRIVATE ...)
# Compile options
target_compile_options(${_test_exe} PRIVATE
${VariantCPPFLAGS}
-x hip
-Wall
-Wno-deprecated
-Wno-unused-command-line-argument
)
# Special handling for hipSquareGenericTarget test - add generic target architectures
# The main test executable needs BOTH specific GPU targets (from AMDGPU_ARCHS, applied
# via VariantCPPFLAGS above) AND generic targets. This allows the test to:
# - Run on the actual GPU (via specific target)
# - Test generic target functionality (via generic targets in the same binary)
# The -w flag suppresses warnings from the generic target compilation.
# See also: create_generic_target_executables() for the helper executables.
if("${TEST_NAME}" MATCHES "hipSquareGenericTarget" AND "${CATEGORY}" STREQUAL "unit" AND "${SUBDIR}" STREQUAL "compiler")
target_compile_options(${_test_exe} PRIVATE
-w
${HIP_GENERIC_TARGET_ARCHS}
)
message(STATUS "Added generic target compile options to ${_test_exe}")
endif()
# Link options - platform-specific handling
# If using hipcc wrapper (AMD or NVIDIA backend), it handles flags automatically
# Otherwise, add explicit flags for AMD clang
get_filename_component(_compiler_name "${CMAKE_CXX_COMPILER}" NAME)
if(_compiler_name MATCHES "hipcc")
# hipcc wrapper handles platform-specific flags automatically
message(VERBOSE "Using hipcc wrapper: ${CMAKE_CXX_COMPILER}")
else()
# Direct compiler (AMD clang) - add explicit HIP link flags
target_link_options(${_test_exe} PRIVATE
--rocm-path=${ROCM_PATH}
--hip-link
-rtlib=compiler-rt
-unwindlib=libgcc
-frtlib-add-rpath
)
endif()
# Link libraries
target_link_libraries(${_test_exe} PRIVATE
${VariantLibs}
stdc++fs
dl
pthread
rt
)
# Add to subdirectory variant target (lowest level)
add_dependencies(hip-tests-catch-${CATEGORY}-${SUBDIR}-${VARIANT_SUFFIX} ${_test_exe})
# Register with LIT
# Use console reporter for consistent output parsing in summary scripts
# Console reporter outputs: "test cases: X | Y passed | Z failed"
#
# Special handling for hipSquareGenericTarget:
# The test spawns helper executables (hipSquareGenericTargetOnly, etc.) using relative
# paths like "./hipSquareGenericTargetOnly". For this to work, the test must run from
# the catch_tests directory where both the main test and helpers are located.
# WORKDIR causes LIT to cd into the directory before executing the test.
if("${TEST_NAME}" MATCHES "hipSquareGenericTarget")
# Use WORKDIR to change directory before running (parsed as "cd DIR ; executable")
# %S expands to source directory (where .test file is located)
llvm_test_run(WORKDIR "%S/catch_tests" EXECUTABLE "./${_test_exe}" "--reporter" "console")
else()
llvm_test_run(EXECUTABLE "catch_tests/${_test_exe}" "--reporter" "console")
endif()
# Add verification to check if test passed
# Catch2 prints "test cases: X | Y failed" when tests fail
# Check for failure indicators in output (%o expands to Output/<test_name>.test.out)
llvm_test_verify("! grep -q failed %o")
llvm_add_test(${_test_exe}.test catch_tests/${_test_exe})
# Track this test target at all hierarchy levels
track_test_target_multi_level(${_test_exe}.test ${CATEGORY} ${SUBDIR} ${VARIANT_SUFFIX})
# Also add to VARIANT_CATCH_TEST_TARGETS for backward compatibility
list(APPEND VARIANT_CATCH_TEST_TARGETS ${_test_exe}.test)
set(VARIANT_CATCH_TEST_TARGETS ${VARIANT_CATCH_TEST_TARGETS} PARENT_SCOPE)
message(STATUS "Created Catch test executable: ${_test_exe}")
endmacro()
# Function to create Catch tests for a specific category and subdirectory
# Arguments:
# CATEGORY - Test category (unit, stress, performance)
# SUBDIR - Subdirectory name
# VARIANT_SUFFIX - Variant suffix (e.g., hip-7.2.0)
# ROCM_PATH - Path to ROCm installation
function(create_catch_tests_for_subdir CATEGORY SUBDIR VARIANT_SUFFIX ROCM_PATH)
set(_test_dir "${HIP_CATCH_TESTS_DIR}/${CATEGORY}/${SUBDIR}")
# Create unique identifier for this category-subdir pair
set(_subdir_id "${CATEGORY}-${SUBDIR}")
# Create aggregated subdirectory-level targets (once per category-subdir pair)
get_property(_created_subdirs GLOBAL PROPERTY CATCH_SUBDIR_TARGETS_CREATED)
if(NOT "${_subdir_id}" IN_LIST _created_subdirs)
message(STATUS "Creating aggregated subdirectory targets for: ${CATEGORY}/${SUBDIR}")
# Create aggregated build target
add_custom_target(hip-tests-catch-${CATEGORY}-${SUBDIR}
COMMENT "Build all HIP Catch ${CATEGORY}/${SUBDIR} tests across all variants")
add_dependencies(hip-tests-catch-${CATEGORY} hip-tests-catch-${CATEGORY}-${SUBDIR})
# Create aggregated check target (will be populated later)
add_custom_target(check-hip-catch-${CATEGORY}-${SUBDIR}
COMMENT "Run all HIP Catch ${CATEGORY}/${SUBDIR} tests across all variants")
add_dependencies(check-hip-catch-${CATEGORY} check-hip-catch-${CATEGORY}-${SUBDIR})
# Mark as created
set_property(GLOBAL APPEND PROPERTY CATCH_SUBDIR_TARGETS_CREATED "${_subdir_id}")
endif()
# Create per-variant subdirectory-level targets
message(STATUS "Creating per-variant subdirectory targets for: ${CATEGORY}/${SUBDIR}-${VARIANT_SUFFIX}")
add_custom_target(hip-tests-catch-${CATEGORY}-${SUBDIR}-${VARIANT_SUFFIX}
COMMENT "Build HIP Catch ${CATEGORY}/${SUBDIR} tests for variant ${VARIANT_SUFFIX}")
# Wire dependencies: variant-specific target to aggregated subdirectory target
add_dependencies(hip-tests-catch-${CATEGORY}-${SUBDIR} hip-tests-catch-${CATEGORY}-${SUBDIR}-${VARIANT_SUFFIX})
# Wire dependencies: category variant target depends on subdirectory variant target
add_dependencies(hip-tests-catch-${CATEGORY}-${VARIANT_SUFFIX} hip-tests-catch-${CATEGORY}-${SUBDIR}-${VARIANT_SUFFIX})
# Discover test sources directly from .cc files
file(GLOB _test_sources RELATIVE "${_test_dir}" "${_test_dir}/*.cc")
if(NOT _test_sources)
message(STATUS "No test sources found in ${CATEGORY}/${SUBDIR}, skipping")
return()
endif()
message(STATUS "Discovered test sources in ${CATEGORY}/${SUBDIR}: ${_test_sources}")
# Create a separate test executable for each source file
# This allows LIT to report statistics for each individual test
foreach(_src ${_test_sources})
# Get the test name from the source filename (without extension)
get_filename_component(_test_basename "${_src}" NAME_WE)
set(_test_name "catch_${CATEGORY}_${SUBDIR}_${_test_basename}")
message(STATUS "Creating Catch test: ${_test_name} from ${_src}")
# Create the test executable with just this one source file
create_catch_test_executable("${_test_name}" "${_src}" "${_test_dir}" "${CATEGORY}" "${SUBDIR}" "${VARIANT_SUFFIX}" "${ROCM_PATH}")
# Special handling for hipSquareGenericTarget test (unit/compiler only)
# This test requires additional helper executables built with ONLY generic targets
# (no specific GPU architectures). These helpers are spawned by the main test to
# verify that generic-only binaries can execute correctly on the actual GPU.
# See create_generic_target_executables() for detailed documentation.
if("${_test_basename}" STREQUAL "hipSquareGenericTarget" AND
"${CATEGORY}" STREQUAL "unit" AND "${SUBDIR}" STREQUAL "compiler")
create_generic_target_executables("${_test_basename}" "${_test_dir}" "${VARIANT_SUFFIX}" "${ROCM_PATH}")
endif()
endforeach()
# Create per-variant check target for this subdirectory
# Get test targets for this subdirectory-variant combination
get_property(_subdir_variant_tests GLOBAL PROPERTY "CATCH_${CATEGORY}_${SUBDIR}_TEST_TARGETS_${VARIANT_SUFFIX}")
if(_subdir_variant_tests)
# Unified LIT-based execution with configurable verbosity
# HIP_CATCH_TEST_VERBOSE controls output detail level (-a flag), not execution mode
# Metrics are always collected via LIT
# Configure LIT flags based on verbosity setting
if(HIP_CATCH_TEST_VERBOSE)
set(_lit_verbosity_flags "-a") # Show all test output
else()
set(_lit_verbosity_flags "") # Quiet mode - only show pass/fail
endif()
# Generate enhanced summary script from template
set(CATCH_CATEGORY ${CATEGORY})
set(CATCH_SUBDIR ${SUBDIR})
set(CATCH_VARIANT_SUFFIX ${VARIANT_SUFFIX})
set(_summary_script "${CMAKE_CURRENT_BINARY_DIR}/catch_tests/summary_${CATEGORY}_${SUBDIR}_${VARIANT_SUFFIX}.sh")
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/catch_summary_template.sh.in"
"${_summary_script}"
@ONLY
)
execute_process(COMMAND chmod +x "${_summary_script}")
# Create wrapper script that runs LIT then shows summary
# Set template variables
set(PYTHON_EXECUTABLE "${Python3_EXECUTABLE}")
set(TEST_SUITE_LIT_BINARY "${HIP_TEST_SUITE_LIT_BINARY}")
set(LIT_VERBOSITY_FLAGS "${_lit_verbosity_flags}")
string(REPLACE ";" " " TEST_LIST "${_subdir_variant_tests}")
set(SUMMARY_SCRIPT "${_summary_script}")
# Generate wrapper from template
set(_lit_wrapper "${CMAKE_CURRENT_BINARY_DIR}/catch_tests/lit_wrapper_${CATEGORY}_${SUBDIR}_${VARIANT_SUFFIX}.sh")
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/lit_wrapper_template.sh.in"
"${_lit_wrapper}"
@ONLY
)
execute_process(COMMAND chmod +x "${_lit_wrapper}")
add_custom_target(check-hip-catch-${CATEGORY}-${SUBDIR}-${VARIANT_SUFFIX}
COMMAND ${_lit_wrapper}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS hip-tests-catch-${CATEGORY}-${SUBDIR}-${VARIANT_SUFFIX}
USES_TERMINAL
COMMENT "Run HIP Catch ${CATEGORY}/${SUBDIR} tests for variant ${VARIANT_SUFFIX}")
# Ensure litsupport files (including lit.cfg) and timeit-target are available
if(TARGET build-litsupport)
add_dependencies(check-hip-catch-${CATEGORY}-${SUBDIR}-${VARIANT_SUFFIX} build-litsupport)
endif()
if(TARGET timeit-target)
add_dependencies(check-hip-catch-${CATEGORY}-${SUBDIR}-${VARIANT_SUFFIX} timeit-target)
endif()
# Wire to aggregated check target (subdirectory aggregator depends on subdirectory-variant)
add_dependencies(check-hip-catch-${CATEGORY}-${SUBDIR} check-hip-catch-${CATEGORY}-${SUBDIR}-${VARIANT_SUFFIX})
endif()
endfunction()
# Main function to integrate Catch tests for a specific HIP variant
# Arguments:
# VARIANT_SUFFIX - Variant suffix (e.g., hip-7.2.0)
# ROCM_PATH - Path to ROCm installation
function(integrate_catch_tests VARIANT_SUFFIX ROCM_PATH)
message(STATUS "Integrating Catch tests for variant ${VARIANT_SUFFIX}")
# Register this variant globally
get_property(_variants GLOBAL PROPERTY CATCH_ALL_VARIANTS)
if(NOT "${VARIANT_SUFFIX}" IN_LIST _variants)
set_property(GLOBAL APPEND PROPERTY CATCH_ALL_VARIANTS "${VARIANT_SUFFIX}")
endif()
# Create catch test target for this variant
add_custom_target(hip-tests-catch-${VARIANT_SUFFIX}
COMMENT "Build Catch tests for HIP variant ${VARIANT_SUFFIX}")
# Process each enabled category
foreach(_category ${CATCH_TEST_CATEGORIES})
message(STATUS "Processing Catch test category: ${_category}")
# Create aggregated category-level targets (once per category)
get_property(_created_categories GLOBAL PROPERTY CATCH_CATEGORY_TARGETS_CREATED)
if(NOT "${_category}" IN_LIST _created_categories)
message(STATUS "Creating aggregated category targets for: ${_category}")
# Create aggregated build target
add_custom_target(hip-tests-catch-${_category}
COMMENT "Build all HIP Catch ${_category} tests across all variants")
add_dependencies(hip-tests-catch hip-tests-catch-${_category})
# Create aggregated check target (will be populated later)
add_custom_target(check-hip-catch-${_category}
COMMENT "Run all HIP Catch ${_category} tests across all variants")
add_dependencies(check-hip-catch check-hip-catch-${_category})
# Mark as created
set_property(GLOBAL APPEND PROPERTY CATCH_CATEGORY_TARGETS_CREATED "${_category}")
endif()
# Create per-variant category-level targets
message(STATUS "Creating per-variant category targets for: ${_category}-${VARIANT_SUFFIX}")
add_custom_target(hip-tests-catch-${_category}-${VARIANT_SUFFIX}
COMMENT "Build HIP Catch ${_category} tests for variant ${VARIANT_SUFFIX}")
# Wire dependencies: variant-specific target to aggregated category target
add_dependencies(hip-tests-catch-${_category} hip-tests-catch-${_category}-${VARIANT_SUFFIX})
# Wire dependencies: top-level variant target depends on category variant target
add_dependencies(hip-tests-catch-${VARIANT_SUFFIX} hip-tests-catch-${_category}-${VARIANT_SUFFIX})
# Discover test subdirectories
discover_catch_test_category(${_category})
# Get the discovered subdirectories
set(_subdir_var "${_category}_TEST_DIRS")
if(DEFINED ${_subdir_var})
foreach(_subdir ${${_subdir_var}})
create_catch_tests_for_subdir("${_category}" "${_subdir}" "${VARIANT_SUFFIX}" "${ROCM_PATH}")
endforeach()
endif()
endforeach()
# Create per-variant check targets for each category
foreach(_category ${CATCH_TEST_CATEGORIES})
# Get test targets for this category-variant combination
get_property(_category_variant_tests GLOBAL PROPERTY "CATCH_${_category}_TEST_TARGETS_${VARIANT_SUFFIX}")
if(_category_variant_tests)
# Category-variant target is just an aggregator - subdirectory-variant targets do the actual work
add_custom_target(check-hip-catch-${_category}-${VARIANT_SUFFIX}
DEPENDS hip-tests-catch-${_category}-${VARIANT_SUFFIX}
COMMENT "Run HIP Catch ${_category} tests for variant ${VARIANT_SUFFIX}")
# Wire category-variant to its subdirectory-variant targets
set(_subdir_var "${_category}_TEST_DIRS")
if(DEFINED ${_subdir_var})
foreach(_subdir ${${_subdir_var}})
if(TARGET check-hip-catch-${_category}-${_subdir}-${VARIANT_SUFFIX})
add_dependencies(check-hip-catch-${_category}-${VARIANT_SUFFIX} check-hip-catch-${_category}-${_subdir}-${VARIANT_SUFFIX})
endif()
endforeach()
endif()
# Wire to aggregated check target (will run tests from all variants)
add_dependencies(check-hip-catch-${_category} check-hip-catch-${_category}-${VARIANT_SUFFIX})
endif()
endforeach()
# Add variant target to main catch target
add_dependencies(hip-tests-catch hip-tests-catch-${VARIANT_SUFFIX})
# Create variant-level check target as aggregator (category-variant targets do the actual work)
add_custom_target(check-hip-catch-${VARIANT_SUFFIX}
DEPENDS hip-tests-catch-${VARIANT_SUFFIX}
COMMENT "Run all HIP Catch tests for variant ${VARIANT_SUFFIX}")
# Wire variant target to category-variant targets
foreach(_category ${CATCH_TEST_CATEGORIES})
if(TARGET check-hip-catch-${_category}-${VARIANT_SUFFIX})
add_dependencies(check-hip-catch-${VARIANT_SUFFIX} check-hip-catch-${_category}-${VARIANT_SUFFIX})
endif()
endforeach()
add_dependencies(check-hip-catch check-hip-catch-${VARIANT_SUFFIX})
message(STATUS "Integrated ${CMAKE_CURRENT_LIST_LENGTH} Catch test targets for ${VARIANT_SUFFIX}")
endfunction()
# Initialize the Catch test framework integration
macro(initialize_catch_tests)
if(ENABLE_HIP_CATCH_TESTS)
message(STATUS "=== Initializing HIP Catch Tests Integration ===")
# Validate local Catch test infrastructure
validate_catch_tests_infrastructure()
# Create main targets
add_custom_target(hip-tests-catch
COMMENT "Build all HIP Catch tests")
add_custom_target(check-hip-catch
COMMENT "Run all HIP Catch tests")
message(STATUS "Catch test categories enabled: ${CATCH_TEST_CATEGORIES}")
if(CATCH_TEST_SUBDIRS)
message(STATUS "Catch test subdirectories filter: ${CATCH_TEST_SUBDIRS}")
else()
message(STATUS "Catch test subdirectories filter: ALL (no filter)")
endif()
message(STATUS "=== Catch Tests Integration Initialized ===")
else()
message(STATUS "HIP Catch tests are DISABLED (set ENABLE_HIP_CATCH_TESTS=ON to enable)")
endif()
endmacro()