CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
347 lines
15 KiB
CMake
347 lines
15 KiB
CMake
# Copyright © Advanced Micro Devices, Inc., or its affiliates.
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
if(HIPDNN_SKIP_TESTS)
|
|
return()
|
|
endif()
|
|
|
|
hipdnn_add_dependency(GTest VERSION ${HIPDNN_GTEST_VERSION})
|
|
include(GoogleTest)
|
|
include(${CMAKE_CURRENT_LIST_DIR}/CheckToolVersion.cmake)
|
|
|
|
find_package(Python3 COMPONENTS Interpreter)
|
|
|
|
findandcheckllvmsymbolizer()
|
|
|
|
# YAML-driven CTest categorisation. Build-tree tests get labels as they are
|
|
# registered; install_hipdnn_ctest_files() bakes the same labels into the
|
|
# installed CTestTestfile.cmake.
|
|
set(_HIPDNN_TEST_CATEGORIES_YAML "${PROJECT_SOURCE_DIR}/test_categories.yaml")
|
|
set(_HIPDNN_SHARED_CTEST "${ROCM_LIBRARIES_ROOT}/shared/ctest/TestCategories.cmake")
|
|
if(EXISTS "${_HIPDNN_SHARED_CTEST}" AND EXISTS "${_HIPDNN_TEST_CATEGORIES_YAML}")
|
|
include("${_HIPDNN_SHARED_CTEST}")
|
|
message(STATUS "hipDNN: YAML-based CTest categorization enabled")
|
|
else()
|
|
if(NOT EXISTS "${_HIPDNN_SHARED_CTEST}")
|
|
message(STATUS
|
|
"hipDNN: shared/ctest not found at ${_HIPDNN_SHARED_CTEST}; skipping CTest categories"
|
|
)
|
|
endif()
|
|
if(NOT EXISTS "${_HIPDNN_TEST_CATEGORIES_YAML}")
|
|
message(STATUS
|
|
"hipDNN: ${_HIPDNN_TEST_CATEGORIES_YAML} not found; skipping CTest categories"
|
|
)
|
|
endif()
|
|
endif()
|
|
|
|
set(CHECK_DEPENDS_GLOBAL "" CACHE INTERNAL "Accumulated global dependencies for test name validation" FORCE)
|
|
set(CHECK_EXECUTABLE_PATHS_GLOBAL "" CACHE INTERNAL "Accumulated global check executable paths" FORCE)
|
|
|
|
# Builds the test environment list with optional code coverage support
|
|
# ~~~
|
|
# Parameters:
|
|
# OUT_VAR - The name of the variable to store the result in (will be set in PARENT_SCOPE)
|
|
# ~~~
|
|
function(_build_test_environment_list_internal OUT_VAR)
|
|
set(ENVIRONMENT_LIST "")
|
|
if(DEFINED TEST_ENVIRONMENT)
|
|
set(ENVIRONMENT_LIST ${TEST_ENVIRONMENT})
|
|
endif()
|
|
|
|
if(HIPDNN_ENABLE_COVERAGE)
|
|
# Ensure coverage report directory exists
|
|
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/coverage-report/profraw")
|
|
|
|
# For code coverage builds, we want each profraw file to have a unique name. The %m in the
|
|
# LLVM_PROFILE_FILE environment variable will auto generate a unique id.
|
|
list(APPEND ENVIRONMENT_LIST
|
|
"LLVM_PROFILE_FILE=${CMAKE_BINARY_DIR}/coverage-report/profraw/%m.profraw"
|
|
)
|
|
endif()
|
|
|
|
set(${OUT_VAR} ${ENVIRONMENT_LIST} PARENT_SCOPE)
|
|
endfunction() # _build_test_environment_list_internal
|
|
|
|
# Applies YAML-defined CTest category labels to explicit test names.
|
|
#
|
|
# Arguments:
|
|
# ARGN - One or more CTest test names to label using _HIPDNN_TEST_CATEGORIES_YAML
|
|
function(_apply_hipdnn_test_category_labels)
|
|
if(COMMAND apply_ctest_category_labels)
|
|
apply_ctest_category_labels(
|
|
"${_HIPDNN_TEST_CATEGORIES_YAML}"
|
|
EXPLICIT_TESTS ${ARGN}
|
|
)
|
|
endif()
|
|
endfunction() # _apply_hipdnn_test_category_labels
|
|
|
|
|
|
# Creates a custom target and ctest test to validate test names using a Python script
|
|
function(_create_test_name_validation_target_internal prefix_name)
|
|
if(Python3_FOUND)
|
|
# Write list of test executables with their paths to a file
|
|
set(TEST_EXECUTABLES_FILE ${CMAKE_BINARY_DIR}/${prefix_name}_test_executables.txt)
|
|
list(REMOVE_DUPLICATES CHECK_EXECUTABLE_PATHS_GLOBAL)
|
|
file(WRITE ${TEST_EXECUTABLES_FILE} "")
|
|
foreach(test_executable ${CHECK_EXECUTABLE_PATHS_GLOBAL})
|
|
file(APPEND ${TEST_EXECUTABLES_FILE} "${test_executable}\n")
|
|
endforeach()
|
|
|
|
add_custom_command(
|
|
OUTPUT ${CMAKE_BINARY_DIR}/${prefix_name}_test_names_validated
|
|
COMMAND
|
|
${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/cmake/scripts/test_name_validator.py
|
|
--test-executables ${TEST_EXECUTABLES_FILE} --build-dir ${CMAKE_BINARY_DIR} --strict
|
|
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/${prefix_name}_test_names_validated
|
|
DEPENDS ${PROJECT_SOURCE_DIR}/cmake/scripts/test_name_validator.py ${CHECK_DEPENDS_GLOBAL}
|
|
COMMENT "Validating test names with --gtest_list_tests test collection"
|
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
|
VERBATIM
|
|
)
|
|
|
|
add_custom_target(
|
|
${prefix_name}-validate_test_names DEPENDS ${CMAKE_BINARY_DIR}/${prefix_name}_test_names_validated
|
|
COMMENT "Validating test names"
|
|
)
|
|
|
|
# Also register as a ctest test so it runs with ctest and appears in test results
|
|
add_test(
|
|
NAME ${prefix_name}_test_name_validation
|
|
COMMAND ${Python3_EXECUTABLE}
|
|
${PROJECT_SOURCE_DIR}/cmake/scripts/test_name_validator.py
|
|
--test-executables ${TEST_EXECUTABLES_FILE}
|
|
--build-dir ${CMAKE_BINARY_DIR}
|
|
--strict
|
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
|
)
|
|
_apply_hipdnn_test_category_labels(${prefix_name}_test_name_validation)
|
|
else()
|
|
message(WARNING "Python3 not found. Test name validation will be skipped.")
|
|
add_custom_target(
|
|
${prefix_name}-validate_test_names COMMAND ${CMAKE_COMMAND} -E echo
|
|
"Test name validation skipped - Python3 not found"
|
|
COMMENT "Skipping test name validation"
|
|
)
|
|
endif() # Python3_FOUND
|
|
endfunction() # _create_test_name_validation_target_internal
|
|
|
|
enable_testing() # Cmake wont discover or run tests without this line
|
|
|
|
# Internal helper function to create a ctest target
|
|
# ~~~
|
|
# Parameters:
|
|
# PREFIX_NAME - Prefix for target names
|
|
# TARGET_NAME - Name of the ctest target to create (will be prefixed)
|
|
# LABEL - Optional label filter for ctest (empty string for no filter)
|
|
# VERBOSE - Set to TRUE to add --verbose flag, FALSE otherwise
|
|
# COMMENT - Comment describing the target
|
|
# ~~~
|
|
function(_add_check_target_internal PREFIX_NAME TARGET_NAME LABEL VERBOSE COMMENT)
|
|
# Build the ctest command
|
|
set(CTEST_CMD ${CMAKE_COMMAND} -E env ${CTEST_ENV} ${CMAKE_CTEST_COMMAND})
|
|
|
|
# Add label filter if specified
|
|
if(NOT "${LABEL}" STREQUAL "")
|
|
list(APPEND CTEST_CMD -L "${LABEL}")
|
|
endif()
|
|
|
|
# Always add --output-on-failure
|
|
list(APPEND CTEST_CMD --output-on-failure)
|
|
|
|
# Add --verbose if requested
|
|
if(VERBOSE)
|
|
list(APPEND CTEST_CMD --verbose)
|
|
endif()
|
|
|
|
# Add configuration
|
|
list(APPEND CTEST_CMD -C ${CMAKE_CFG_INTDIR})
|
|
|
|
# Create the target with prefix
|
|
set(FULL_TARGET_NAME "${PREFIX_NAME}-${TARGET_NAME}")
|
|
add_custom_target(${FULL_TARGET_NAME} COMMAND ${CTEST_CMD} COMMENT "${COMMENT}" USES_TERMINAL)
|
|
add_dependencies(${FULL_TARGET_NAME} ${PREFIX_NAME}-validate_test_names)
|
|
message(VERBOSE "Created ${FULL_TARGET_NAME} target")
|
|
endfunction() # _add_check_target_internal
|
|
|
|
# Internal helper function to create the ninja-check targets for running tests via ctest
|
|
function(_create_check_targets_internal prefix_name)
|
|
# cmake-format: off
|
|
# Build test environment once for all ctest targets
|
|
_build_test_environment_list_internal(CTEST_ENV)
|
|
|
|
# Regular all-test targets (without --verbose)
|
|
_add_check_target_internal(${prefix_name} "check_ctest" "" FALSE "Running all tests via ctest")
|
|
|
|
# Verbose all-test targets
|
|
_add_check_target_internal(${prefix_name} "check_ctest-verbose" "" TRUE "Running all tests via ctest (verbose)")
|
|
|
|
if(COMMAND get_ctest_category_names)
|
|
get_ctest_category_names("${_HIPDNN_TEST_CATEGORIES_YAML}" HIPDNN_TEST_CATEGORIES)
|
|
else()
|
|
set(HIPDNN_TEST_CATEGORIES "")
|
|
endif()
|
|
|
|
set(HIPDNN_TEST_CATEGORIES "${HIPDNN_TEST_CATEGORIES}" PARENT_SCOPE)
|
|
|
|
foreach(_category IN LISTS HIPDNN_TEST_CATEGORIES)
|
|
if(NOT _category MATCHES "^[A-Za-z0-9_.+-]+$")
|
|
message(FATAL_ERROR "Invalid hipDNN test category '${_category}'. Category names must be valid CMake target-name fragments.")
|
|
endif()
|
|
if(_category MATCHES "^check(-verbose)?$")
|
|
message(FATAL_ERROR "Invalid hipDNN test category '${_category}'. Category name is reserved.")
|
|
endif()
|
|
|
|
_add_check_target_internal(${prefix_name} "${_category}-check_ctest" "${_category}" FALSE "Running ${_category} tests via ctest")
|
|
_add_check_target_internal(${prefix_name} "${_category}-check_ctest-verbose" "${_category}" TRUE "Running ${_category} tests via ctest (verbose)")
|
|
endforeach()
|
|
# cmake-format: on
|
|
endfunction() # _create_check_targets_internal
|
|
|
|
|
|
|
|
# Finalizes and creates all of the test targets
|
|
#
|
|
# Arguments:
|
|
# prefix_name - Prefix to add to all target names (e.g., "hipdnn" creates "hipdnn-check")
|
|
#
|
|
# Creates prefixed targets from the YAML categories (e.g., "hipdnn-quick-check").
|
|
# In standalone builds (non-superbuild), also creates unprefixed aliases for backward compatibility.
|
|
function(finalize_test_targets prefix_name)
|
|
_create_test_name_validation_target_internal(${prefix_name})
|
|
|
|
_create_check_targets_internal(${prefix_name})
|
|
|
|
# cmake-format: off
|
|
# Determine if we should create legacy aliases (only in standalone builds)
|
|
set(CREATE_ALIASES FALSE)
|
|
if(NOT ROCM_LIBS_SUPERBUILD)
|
|
set(CREATE_ALIASES TRUE)
|
|
endif()
|
|
|
|
# Create all-tests targets.
|
|
add_custom_target(${prefix_name}-check DEPENDS ${prefix_name}-check_ctest COMMENT "Running all tests via ctest")
|
|
add_custom_target(${prefix_name}-check-verbose DEPENDS ${prefix_name}-check_ctest-verbose COMMENT "Running all tests via ctest (verbose)")
|
|
|
|
if(CREATE_ALIASES)
|
|
add_custom_target(check DEPENDS ${prefix_name}-check COMMENT "Alias for ${prefix_name}-check")
|
|
add_custom_target(check-verbose DEPENDS ${prefix_name}-check-verbose COMMENT "Alias for ${prefix_name}-check-verbose")
|
|
endif()
|
|
|
|
foreach(_category IN LISTS HIPDNN_TEST_CATEGORIES)
|
|
add_custom_target(${prefix_name}-${_category}-check DEPENDS ${prefix_name}-${_category}-check_ctest COMMENT "Running ${_category} tests via ctest")
|
|
add_custom_target(${prefix_name}-${_category}-check-verbose DEPENDS ${prefix_name}-${_category}-check_ctest-verbose COMMENT "Running ${_category} tests via ctest (verbose)")
|
|
|
|
if(CREATE_ALIASES)
|
|
add_custom_target(${_category}-check DEPENDS ${prefix_name}-${_category}-check COMMENT "Alias for ${prefix_name}-${_category}-check")
|
|
add_custom_target(${_category}-check-verbose DEPENDS ${prefix_name}-${_category}-check-verbose COMMENT "Alias for ${prefix_name}-${_category}-check-verbose")
|
|
endif()
|
|
endforeach()
|
|
# cmake-format: on
|
|
endfunction() # finalize_test_targets
|
|
|
|
# ~~~
|
|
# Records, configures, and registers a hipDNN gtest-based CTest test target. Assumes that the
|
|
# test target is a gtest executable, setting up:
|
|
# - Test name validation tracking (adds to global dependency and executable path lists)
|
|
# - RPATH settings for relocatable test executables
|
|
# - Installation rules for test binaries
|
|
# - CTest registration
|
|
# - YAML-driven category labels from projects/hipdnn/test_categories.yaml
|
|
#
|
|
# Parameters:
|
|
# TARGET - Name of the test executable target (must already exist)
|
|
# WORKING_DIR - Working directory for test execution
|
|
# ~~~
|
|
function(add_hipdnn_test TARGET WORKING_DIR)
|
|
set(TARGET_EXE ${TARGET})
|
|
|
|
# Add executable suffix if needed (e.g., .exe on Windows)
|
|
if(CMAKE_EXECUTABLE_SUFFIX)
|
|
set(TARGET_EXE "${TARGET_EXE}${CMAKE_EXECUTABLE_SUFFIX}")
|
|
endif()
|
|
|
|
message(STATUS "Registering test target: ${TARGET} -> ${TARGET_EXE} in working directory: ${WORKING_DIR}")
|
|
|
|
# Track the dependencies for test name validation
|
|
set(CHECK_DEPENDS_GLOBAL ${CHECK_DEPENDS_GLOBAL} ${TARGET}
|
|
CACHE INTERNAL "Accumulated global dependencies for test name validation" FORCE
|
|
)
|
|
# Track the binary paths for test name validation
|
|
set(CHECK_EXECUTABLE_PATHS_GLOBAL ${CHECK_EXECUTABLE_PATHS_GLOBAL} "${CMAKE_INSTALL_BINDIR}/${TARGET_EXE}"
|
|
CACHE INTERNAL "Accumulated global check executable paths" FORCE
|
|
)
|
|
|
|
# Track this test target for later use in generating installed CTestTestfile.cmake
|
|
set_property(GLOBAL APPEND PROPERTY HIPDNN_TEST_TARGETS ${TARGET})
|
|
|
|
set_target_properties(
|
|
${TARGET} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}"
|
|
)
|
|
|
|
# Make test executables prefer the build/install tree next to the executable before any
|
|
# toolchain paths. This prevents stale installed hipDNN libraries in /opt/rocm from shadowing
|
|
# the freshly built test dependencies.
|
|
set_target_properties(
|
|
${TARGET}
|
|
PROPERTIES
|
|
INSTALL_RPATH
|
|
"\$ORIGIN/../${CMAKE_INSTALL_LIBDIR};\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}/hipdnn_plugins/engines"
|
|
BUILD_WITH_INSTALL_RPATH TRUE
|
|
INSTALL_RPATH_USE_LINK_PATH TRUE
|
|
)
|
|
|
|
# Install test executables to bin directory
|
|
install(TARGETS ${TARGET} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
|
|
add_test(NAME ${TARGET} COMMAND ${TARGET} WORKING_DIRECTORY ${WORKING_DIR})
|
|
_apply_hipdnn_test_category_labels(${TARGET})
|
|
if(DEFINED TEST_ENVIRONMENT)
|
|
set_tests_properties(${TARGET} PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT}")
|
|
endif()
|
|
endfunction() # add_hipdnn_test
|
|
|
|
# Install CTest configuration files for direct test execution This should be called once at the end
|
|
# of the main CMakeLists.txt after all tests are registered
|
|
function(install_hipdnn_ctest_files)
|
|
# Define the CTest installation directory
|
|
set(HIPDNN_CTEST_FILE_INSTALL_PATH "${CMAKE_INSTALL_BINDIR}/hipdnn")
|
|
|
|
# Generate a new CTestTestfile.cmake that references installed test executables
|
|
set(INSTALLED_CTEST_FILE "${CMAKE_CURRENT_BINARY_DIR}/CTestTestfile.cmake.install")
|
|
|
|
file(WRITE "${INSTALLED_CTEST_FILE}"
|
|
"# Autogenerated CTestTestfile for installed hipDNN tests\n"
|
|
)
|
|
file(APPEND "${INSTALLED_CTEST_FILE}" "# Generated by hipDNN build system\n\n")
|
|
|
|
# Get all test targets that were registered
|
|
get_property(all_tests GLOBAL PROPERTY HIPDNN_TEST_TARGETS)
|
|
|
|
foreach(test_target ${all_tests})
|
|
file(APPEND "${INSTALLED_CTEST_FILE}" "add_test(${test_target} \"../${test_target}\")\n")
|
|
endforeach()
|
|
|
|
# Bake the YAML-driven category labels into the installed
|
|
# CTestTestfile.cmake so `ctest --test-dir $THEROCK_BIN_DIR/hipdnn -L
|
|
# <tier>` works against the install tree.
|
|
#
|
|
# Passing INSTALLED_CTEST_FILE as the 2nd argument signals the shared
|
|
# helper that the snippet will be evaluated by ctest's own script
|
|
# interpreter (which does not implement
|
|
# get_property(DIRECTORY ... PROPERTY TESTS)), so it emits explicit
|
|
# per-test set_property() lines after auto-discovering the test
|
|
# names from the add_test() lines we just wrote above.
|
|
if(COMMAND apply_ctest_category_labels AND all_tests)
|
|
apply_ctest_category_labels(
|
|
"${_HIPDNN_TEST_CATEGORIES_YAML}"
|
|
"${INSTALLED_CTEST_FILE}"
|
|
)
|
|
endif()
|
|
|
|
# Install the generated CTestTestfile.cmake to HIPDNN_CTEST_FILE_INSTALL_PATH
|
|
install(FILES "${INSTALLED_CTEST_FILE}" DESTINATION ${HIPDNN_CTEST_FILE_INSTALL_PATH}
|
|
RENAME CTestTestfile.cmake
|
|
)
|
|
|
|
endfunction() # install_hipdnn_ctest_files
|