Files
TheRock/rocm-libraries/projects/hiptensor/test/CMakeLists.txt
T
derek.holloway 7502bf64a4
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
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

704 lines
37 KiB
CMake

###############################################################################
#
# MIT License
#
# Copyright (C) 2023-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.
#
###############################################################################
include(CMakeDependentOption)
# Find / configure LLVM
add_subdirectory(llvm)
cmake_dependent_option(HIPTENSOR_USE_SYSTEM_GOOGLETEST "Use system Google Test library instead of downloading and building it" OFF "HIPTENSOR_BUILD_TESTS" OFF)
if(HIPTENSOR_USE_SYSTEM_GOOGLETEST)
find_package(GTest REQUIRED)
else()
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.17.0
)
FetchContent_GetProperties(googletest)
if(NOT googletest_POPULATED)
# Fetch the content using default details
FetchContent_Populate(googletest)
# Save the shared libs setting, then force to static libs
set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Build SHARED libraries" FORCE)
# Turn off gtest installation
set(INSTALL_GTEST OFF)
# On MSVC-style toolchains gtest defaults to the static CRT (/MT), but the
# rest of hipTensor compiles against the dynamic CRT (/MD). Force gtest to
# use the dynamic CRT so lld-link does not reject a RuntimeLibrary mismatch.
if(WIN32)
set(gtest_force_shared_crt ON CACHE BOOL "Use shared (DLL) run-time lib for gtest" FORCE)
endif()
# Add gtest targets as static libs
add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
# Restore shared libs setting
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_OLD} CACHE INTERNAL "Build SHARED libraries" FORCE)
endif()
endif()
get_target_property(composable_kernel_INCLUDES composable_kernel::device_other_operations INTERFACE_INCLUDE_DIRECTORIES)
# Setup a test manifest
set(INSTALL_TEST_FILE "${CMAKE_CURRENT_BINARY_DIR}/install_CTestTestfile.cmake")
file(WRITE "${INSTALL_TEST_FILE}"
[=[
# This is a test file generated by hipTensor for install time.
# It differs slightly from the default testfile, and you may encounter issues because of that.
]=]
)
set(INSTALL_SMOKE_TEST_FILE "${CMAKE_CURRENT_BINARY_DIR}/install_smoke_CTestTestfile.cmake")
file(WRITE "${INSTALL_SMOKE_TEST_FILE}"
[=[
# This is a test file generated by hipTensor for install time.
# It differs slightly from the default testfile, and you may encounter issues because of that.
]=]
)
set(INSTALL_REGRESSION_TEST_FILE "${CMAKE_CURRENT_BINARY_DIR}/install_regression_CTestTestfile.cmake")
file(WRITE "${INSTALL_REGRESSION_TEST_FILE}"
[=[
# This is a test file generated by hipTensor for install time.
# It differs slightly from the default testfile, and you may encounter issues because of that.
]=]
)
# YAML-driven CTest test categorisation for the *installed* tree only.
# The shared helper apply_ctest_category_labels(yaml, install_test_file)
# scans the install-tree CTestTestfile.cmake fragments we hand-roll below
# for `add_test()` lines and appends explicit set_tests_properties() lines
# so `ctest -L <tier>` works against the install tree. Build-tree tests
# are intentionally not labelled here.
set(_HIPTENSOR_TEST_CATEGORIES_YAML "${PROJECT_SOURCE_DIR}/test_categories.yaml")
set(_HIPTENSOR_SHARED_CTEST "${ROCM_LIBRARIES_ROOT}/shared/ctest/TestCategories.cmake")
if(EXISTS "${_HIPTENSOR_SHARED_CTEST}" AND EXISTS "${_HIPTENSOR_TEST_CATEGORIES_YAML}")
include("${_HIPTENSOR_SHARED_CTEST}")
message(STATUS "hipTensor: YAML-based CTest categorization enabled (install tree only)")
else()
if(NOT EXISTS "${_HIPTENSOR_SHARED_CTEST}")
message(STATUS "hipTensor: shared/ctest not found at ${_HIPTENSOR_SHARED_CTEST}; skipping CTest categories")
endif()
if(NOT EXISTS "${_HIPTENSOR_TEST_CATEGORIES_YAML}")
message(STATUS "hipTensor: ${_HIPTENSOR_TEST_CATEGORIES_YAML} not found; skipping CTest categories")
endif()
endif()
# Target that will trigger build of all tests
add_custom_target(hiptensor_tests)
# On Windows, DLL search order is: application dir -> System32 -> PATH.
# A system-installed ROCm places amdhip64_7.dll and amd_comgr_3.dll in
# System32, which always wins over PATH. If the test binary is compiled with
# a newer toolchain but an older runtime is loaded from System32, kernel launches
# may crash (SEH 0xC0000005) if the code-object format is incompatible.
if(WIN32 AND CREATE_TEST_APP_LOCAL_DEPLOY)
# hip_DIR is set by find_package(HIP) to <HIP_ROOT>/lib/cmake/hip.
# Walk up three directory levels to reach <HIP_ROOT>, then append /bin.
get_filename_component(_hip_cmake_dir "${hip_DIR}" DIRECTORY) # .../lib/cmake
get_filename_component(_hip_lib_dir "${_hip_cmake_dir}" DIRECTORY) # .../lib
get_filename_component(_hip_root "${_hip_lib_dir}" DIRECTORY) # <HIP_ROOT>
set(_hip_bin_dir "${_hip_root}/bin")
message(STATUS "HIP runtime DLL source: ${_hip_bin_dir}")
message(STATUS "HIP runtime DLL destination: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
if(EXISTS "${_hip_bin_dir}")
file(MAKE_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
file(GLOB _hip_dlls
"${_hip_bin_dir}/amd_comgr*.dll" # code-object manager
"${_hip_bin_dir}/amdhip64*.dll" # HIP runtime
"${_hip_bin_dir}/amdhiprtc*.dll" # HIP RTC
"${_hip_bin_dir}/rocm_kpack*.dll" # kernel packaging
)
if(_hip_dlls)
foreach(_dll ${_hip_dlls})
file(COPY "${_dll}" DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
endforeach()
list(LENGTH _hip_dlls _hip_dll_count)
message(STATUS "Staged ${_hip_dll_count} HIP runtime DLL(s) into ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
else()
message(WARNING "No DLLs found in ${_hip_bin_dir} - tests may load wrong HIP runtime from System32")
endif()
else()
message(WARNING "HIP DLL source directory not found: ${_hip_bin_dir} - "
"tests may load wrong HIP runtime from System32")
endif()
endif()
set(HIPTENSOR_COMMON_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/common.cpp
${CMAKE_CURRENT_SOURCE_DIR}/hip_resource.cpp
${CMAKE_CURRENT_SOURCE_DIR}/hiptensor_gtest_main.cpp)
# Create test executables and deploy
function(add_hiptensor_test BINARY_NAME YAML_CONFIG_FILE TEST_SOURCES)
# Make sure that all sources are appended to the list.
list(APPEND TEST_SOURCES ${ARGN})
message(STATUS "adding hiptensor test: ${BINARY_NAME}")
message(STATUS "test config file: ${YAML_CONFIG_FILE}")
# Read in the YAML config file that we wish to bundle
file(READ ${YAML_CONFIG_FILE} hiptensor_test_YAML_STRING)
# Build a file header that includes the YAML config string
# Must define in cmake:
# - hiptensor_test_NAME
# - hiptensor_test_YAML_STRING
# - hiptensor_test_YAML_INCLUDE_FILE
get_filename_component(hiptensor_test_YAML_DIR "${YAML_CONFIG_FILE}" PATH)
get_filename_component(hiptensor_test_NAME "${YAML_CONFIG_FILE}" NAME_WE)
set(hiptensor_test_YAML_INCLUDE_FILE "${hiptensor_test_NAME}.hpp")
configure_file("${PROJECT_SOURCE_DIR}/test/hiptensor-test-yaml.hpp.in"
"${hiptensor_test_YAML_DIR}/${hiptensor_test_YAML_INCLUDE_FILE}")
# message(STATUS "test config dir: ${hiptensor_test_YAML_DIR}")
# message(STATUS "test name: ${hiptensor_test_NAME}")
# message(STATUS "test yaml config: ${hiptensor_test_YAML_STRING}")
# message(STATUS "test config include: ${hiptensor_test_YAML_INCLUDE_FILE}")
add_executable(${BINARY_NAME} ${TEST_SOURCES})
target_compile_options(${BINARY_NAME} PRIVATE ${CLANG_DRIVER_MODE})
target_link_options(${BINARY_NAME} PRIVATE ${CLANG_DRIVER_MODE})
# Test must propagate the build interface includes to make sure
# hiptensor includes are captured at runtime.
if(WIN32)
target_link_libraries(${BINARY_NAME} PRIVATE hiptensor::hiptensor hiptensor_llvm GTest::gtest "-L${HIPTENSOR_CLANG_ROOT}/lib")
else()
target_link_libraries(${BINARY_NAME} PRIVATE hiptensor::hiptensor hiptensor_llvm GTest::gtest "-L${HIPTENSOR_CLANG_ROOT}/lib"
"-Wl,-rpath=$ORIGIN/../${CMAKE_INSTALL_LIBDIR}" "-fno-rtlib-add-rpath")
endif()
target_include_directories(${BINARY_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${composable_kernel_INCLUDES}
${PROJECT_SOURCE_DIR}/library/include
${PROJECT_SOURCE_DIR}/library/src/include
${PROJECT_SOURCE_DIR}/library/src
${PROJECT_SOURCE_DIR}/test
${PROJECT_BINARY_DIR}/include/hiptensor
${PROJECT_BINARY_DIR}/include
${hiptensor_test_YAML_DIR})
# -Wno-ignored-attributes to avoid warning: __declspec attribute 'dllimport' is not supported [-Wignored-attributes] which is used by msvc compiler
if(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(${BINARY_NAME} PRIVATE -Wno-ignored-attributes)
endif()
# C++ code handles the following symbols defined:
# - HIPTENSOR_TEST_YAML_INCLUDE
# When defined, the test code will attempt to load bundled YAML string.
target_compile_definitions(${BINARY_NAME} PRIVATE -D HIPTENSOR_TEST_YAML_INCLUDE=\"${hiptensor_test_YAML_INCLUDE_FILE}\")
# Build this test under custom target
add_dependencies(hiptensor_tests ${BINARY_NAME})
# Register with ctest
add_test(NAME ${BINARY_NAME} COMMAND ${BINARY_NAME})
set_property(TEST ${BINARY_NAME} PROPERTY SKIP_REGULAR_EXPRESSION "HIPTENSOR_STATUS_ARCH_MISMATCH" "unsupported host device")
# Set working directory to bin/ for proper DLL/resource loading on Windows
set_property(TEST ${BINARY_NAME} PROPERTY WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
# On Windows, ensure the ROCm/HIP DLLs (amdhip64_7.dll, etc.) are discoverable by ctest.
# ctest may not inherit the user's PATH that includes the ROCm bin directory, causing
# HIP runtime DLL load failures (SEH 0xC0000005) on the first HIP call in a test fixture.
if(WIN32)
set_property(TEST ${BINARY_NAME} PROPERTY ENVIRONMENT
"PATH=${CMAKE_INSTALL_PREFIX}/bin$<SEMICOLON>${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$<SEMICOLON>$ENV{PATH}")
endif()
# Install with rocm pkg
rocm_install_targets(
TARGETS ${BINARY_NAME}
COMPONENT tests
)
# Add to testing manifest
get_target_property(EXE_NAME ${BINARY_NAME} RUNTIME_OUTPUT_NAME)
if(EXE_NAME STREQUAL "EXE_NAME-NOTFOUND")
get_target_property(EXE_NAME ${BINARY_NAME} OUTPUT_NAME)
if(EXE_NAME STREQUAL "EXE_NAME-NOTFOUND")
set(EXE_NAME "${BINARY_NAME}")
endif()
endif()
file(APPEND "${INSTALL_TEST_FILE}" "add_test(${BINARY_NAME} \"../${BINARY_NAME}\")\n")
file(APPEND "${INSTALL_TEST_FILE}" "set_tests_properties(${BINARY_NAME} PROPERTIES SKIP_REGULAR_EXPRESSION \"HIPTENSOR_STATUS_ARCH_MISMATCH;unsupported host device\")\n")
file(APPEND "${INSTALL_SMOKE_TEST_FILE}" "add_test(\"${BINARY_NAME} smoke\" \"../../${BINARY_NAME}\")\n")
file(APPEND "${INSTALL_SMOKE_TEST_FILE}" "set_tests_properties(\"${BINARY_NAME} smoke\" PROPERTIES SKIP_REGULAR_EXPRESSION \"HIPTENSOR_STATUS_ARCH_MISMATCH;unsupported host device\")\n")
file(APPEND "${INSTALL_REGRESSION_TEST_FILE}" "add_test(\"${BINARY_NAME} regression\" \"../../${BINARY_NAME}\")\n")
file(APPEND "${INSTALL_REGRESSION_TEST_FILE}" "set_tests_properties(\"${BINARY_NAME} regression\" PROPERTIES SKIP_REGULAR_EXPRESSION \"HIPTENSOR_STATUS_ARCH_MISMATCH;unsupported host device\")\n")
endfunction()
# Create unit test executables and deploy
# Differs from hiptensor_test in that src include directory is linked
function(add_hiptensor_unit_test)
set(BINARY_NAME ${ARGV0})
message(STATUS "adding hiptensor unit test: ${BINARY_NAME}")
list(REMOVE_AT ARGV 0)
add_executable(${BINARY_NAME} ${ARGV})
target_compile_options(${BINARY_NAME} PRIVATE ${CLANG_DRIVER_MODE})
target_link_options(${BINARY_NAME} PRIVATE ${CLANG_DRIVER_MODE})
# Test must propagate the build interface includes to make sure
# hiptensor includes are captured at runtime.
if(WIN32)
target_link_libraries(${BINARY_NAME} PRIVATE hiptensor::hiptensor hiptensor_llvm GTest::gtest "-L${HIPTENSOR_CLANG_ROOT}/lib")
else()
target_link_libraries(${BINARY_NAME} PRIVATE hiptensor::hiptensor hiptensor_llvm GTest::gtest "-L${HIPTENSOR_CLANG_ROOT}/lib"
"-Wl,-rpath=$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
endif()
target_include_directories(${BINARY_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${composable_kernel_INCLUDES}
${PROJECT_SOURCE_DIR}/library/include
${PROJECT_SOURCE_DIR}/library/src/include
${PROJECT_SOURCE_DIR}/library/src
${PROJECT_SOURCE_DIR}/test
${PROJECT_BINARY_DIR}/include/hiptensor
${PROJECT_BINARY_DIR}/include)
# -Wno-ignored-attributes to avoid warning: __declspec attribute 'dllimport' is not supported [-Wignored-attributes] which is used by msvc compiler
if(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(${BINARY_NAME} PRIVATE -Wno-ignored-attributes)
endif()
# Build this test under custom target
add_dependencies(hiptensor_tests ${BINARY_NAME})
# Register with ctest
add_test(NAME ${BINARY_NAME} COMMAND ${BINARY_NAME})
set_property(TEST ${BINARY_NAME} PROPERTY SKIP_REGULAR_EXPRESSION "HIPTENSOR_STATUS_ARCH_MISMATCH" "unsupported host device")
# Set working directory to bin/ for proper DLL/resource loading on Windows
set_property(TEST ${BINARY_NAME} PROPERTY WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
# On Windows, ensure the ROCm/HIP DLLs (amdhip64_7.dll, etc.) are discoverable by ctest.
# ctest may not inherit the user's PATH that includes the ROCm bin directory, causing
# HIP runtime DLL load failures (SEH 0xC0000005) on the first HIP call in a test fixture.
if(WIN32)
set_property(TEST ${BINARY_NAME} PROPERTY ENVIRONMENT
"PATH=${CMAKE_INSTALL_PREFIX}/bin$<SEMICOLON>${CMAKE_RUNTIME_OUTPUT_DIRECTORY}$<SEMICOLON>$ENV{PATH}")
endif()
# Install with rocm pkg
rocm_install_targets(
TARGETS ${BINARY_NAME}
COMPONENT tests
)
# Add to testing manifest
get_target_property(EXE_NAME ${BINARY_NAME} RUNTIME_OUTPUT_NAME)
if(EXE_NAME STREQUAL "EXE_NAME-NOTFOUND")
get_target_property(EXE_NAME ${BINARY_NAME} OUTPUT_NAME)
if(EXE_NAME STREQUAL "EXE_NAME-NOTFOUND")
set(EXE_NAME "${BINARY_NAME}")
endif()
endif()
file(APPEND "${INSTALL_TEST_FILE}" "add_test(${BINARY_NAME} \"../${BINARY_NAME}\")\n")
file(APPEND "${INSTALL_TEST_FILE}" "set_tests_properties(${BINARY_NAME} PROPERTIES SKIP_REGULAR_EXPRESSION \"HIPTENSOR_STATUS_ARCH_MISMATCH;unsupported host device\")\n")
file(APPEND "${INSTALL_SMOKE_TEST_FILE}" "add_test(\"${BINARY_NAME} smoke\" \"../../${BINARY_NAME}\")\n")
file(APPEND "${INSTALL_SMOKE_TEST_FILE}" "set_tests_properties(\"${BINARY_NAME} smoke\" PROPERTIES SKIP_REGULAR_EXPRESSION \"HIPTENSOR_STATUS_ARCH_MISMATCH;unsupported host device\")\n")
file(APPEND "${INSTALL_REGRESSION_TEST_FILE}" "add_test(\"${BINARY_NAME} regression\" \"../../${BINARY_NAME}\")\n")
file(APPEND "${INSTALL_REGRESSION_TEST_FILE}" "set_tests_properties(\"${BINARY_NAME} regression\" PROPERTIES SKIP_REGULAR_EXPRESSION \"HIPTENSOR_STATUS_ARCH_MISMATCH;unsupported host device\")\n")
endfunction()
add_subdirectory(00_unit)
add_subdirectory(01_contraction)
add_subdirectory(02_elementwise)
add_subdirectory(03_reduction)
add_subdirectory(python)
# Test entries for the install-tree category filters.
#
# Two building-block lists keep the three filters distinct in intent:
# _HIPTENSOR_HOST_TESTS - host-only (non-device) tests. They take no config and
# no run-count flags.
# _HIPTENSOR_DEVICE_TESTS - device tests. Each runs with --hot_runs 1 --cold_runs 0
# and, where applicable, a custom config via -y.
#
# From these, families of install-tree entries are emitted:
# filter test name suffix members config dir
# quick " quick" host + device validation/quick
# standard " standard" host + device validation/standard
# comprehensive " comprehensive" host + device validation/comprehensive
# full " full" host + device validation/full
# ffm-quick " ffm-quick" device only emulation/quick
# ffm-full " ffm-full" device only emulation/full
# bench " bench" device (bench) bench
# where "config dir" is the bin/hiptensor/configs/<dir>/ subtree the -y path
# points at. Host tests are emitted once under quick; the shared parser's tier
# nesting (quick->standard->comprehensive->full) carries them up, so they run
# under every tier without duplicate entries. Labels are attached by the shared
# category parser from test_categories.yaml.
set(_HIPTENSOR_HOST_TESTS
contraction_mode_test
elementwise_cpu_test
elementwise_op_test
hiptensor_options_test
logger_test
reduction_cpu_impl_test
util_test
yaml_test
)
# Device tests encoded as "binary|config-or-NONE". The config path is
# relative to a per-category config root (bin/hiptensor/configs/<category>/),
# with <category> supplied per family below. NONE means no -y (the binary
# carries its own config) but the run-count flags are still applied.
set(_HIPTENSOR_DEVICE_TESTS
"bilinear_contraction_test_m1n1k1|01_contraction/bilinear_test_params_rank1.yaml"
"bilinear_contraction_test_m2n2k2|01_contraction/bilinear_test_params_rank2.yaml"
"bilinear_contraction_test_m3n3k3|01_contraction/bilinear_test_params_rank3.yaml"
"bilinear_contraction_test_m4n4k4|01_contraction/bilinear_test_params_rank4.yaml"
"bilinear_contraction_test_m5n5k5|01_contraction/bilinear_test_params_rank5.yaml"
"bilinear_contraction_test_m6n6k6|01_contraction/bilinear_test_params_rank6.yaml"
"complex_bilinear_contraction_test_m1n1k1|01_contraction/complex_bilinear_test_params_rank1.yaml"
"complex_bilinear_contraction_test_m2n2k2|01_contraction/complex_bilinear_test_params_rank2.yaml"
"complex_bilinear_contraction_test_m3n3k3|01_contraction/complex_bilinear_test_params_rank3.yaml"
"complex_bilinear_contraction_test_m4n4k4|01_contraction/complex_bilinear_test_params_rank4.yaml"
"complex_bilinear_contraction_test_m5n5k5|01_contraction/complex_bilinear_test_params_rank5.yaml"
"complex_bilinear_contraction_test_m6n6k6|01_contraction/complex_bilinear_test_params_rank6.yaml"
"scale_contraction_test_m1n1k1|01_contraction/scale_test_params_rank1.yaml"
"scale_contraction_test_m2n2k2|01_contraction/scale_test_params_rank2.yaml"
"scale_contraction_test_m3n3k3|01_contraction/scale_test_params_rank3.yaml"
"scale_contraction_test_m4n4k4|01_contraction/scale_test_params_rank4.yaml"
"scale_contraction_test_m5n5k5|01_contraction/scale_test_params_rank5.yaml"
"scale_contraction_test_m6n6k6|01_contraction/scale_test_params_rank6.yaml"
"complex_scale_contraction_test_m1n1k1|01_contraction/complex_scale_test_params_rank1.yaml"
"complex_scale_contraction_test_m2n2k2|01_contraction/complex_scale_test_params_rank2.yaml"
"complex_scale_contraction_test_m3n3k3|01_contraction/complex_scale_test_params_rank3.yaml"
"complex_scale_contraction_test_m4n4k4|01_contraction/complex_scale_test_params_rank4.yaml"
"complex_scale_contraction_test_m5n5k5|01_contraction/complex_scale_test_params_rank5.yaml"
"complex_scale_contraction_test_m6n6k6|01_contraction/complex_scale_test_params_rank6.yaml"
"trinary_bilinear_contraction_test|NONE"
"trinary_scale_contraction_test|NONE"
"bilinear_contraction_with_unary_ops_test|NONE"
"scale_contraction_with_unary_ops_test|NONE"
"rank2_elementwise_permute_test|02_elementwise/permutation/rank2_test_params.yaml"
"rank3_elementwise_permute_test|02_elementwise/permutation/rank3_test_params.yaml"
"rank4_elementwise_permute_test|02_elementwise/permutation/rank4_test_params.yaml"
"rank5_elementwise_permute_test|02_elementwise/permutation/rank5_test_params.yaml"
"rank6_elementwise_permute_test|02_elementwise/permutation/rank6_test_params.yaml"
"rank2_elementwise_binary_op_test|02_elementwise/binary_op/rank2_binary_op_test_params.yaml"
"rank3_elementwise_binary_op_test|02_elementwise/binary_op/rank3_binary_op_test_params.yaml"
"rank4_elementwise_binary_op_test|02_elementwise/binary_op/rank4_binary_op_test_params.yaml"
"rank5_elementwise_binary_op_test|02_elementwise/binary_op/rank5_binary_op_test_params.yaml"
"rank6_elementwise_binary_op_test|02_elementwise/binary_op/rank6_binary_op_test_params.yaml"
"rank2_elementwise_trinary_op_test|02_elementwise/trinary_op/rank2_trinary_op_test_params.yaml"
"rank3_elementwise_trinary_op_test|02_elementwise/trinary_op/rank3_trinary_op_test_params.yaml"
"rank4_elementwise_trinary_op_test|02_elementwise/trinary_op/rank4_trinary_op_test_params.yaml"
"rank5_elementwise_trinary_op_test|02_elementwise/trinary_op/rank5_trinary_op_test_params.yaml"
"rank6_elementwise_trinary_op_test|02_elementwise/trinary_op/rank6_trinary_op_test_params.yaml"
"rank1_reduction_test|03_reduction/rank1_test_params.yaml"
"rank2_reduction_test|03_reduction/rank2_test_params.yaml"
"rank3_reduction_test|03_reduction/rank3_test_params.yaml"
"rank4_reduction_test|03_reduction/rank4_test_params.yaml"
"rank5_reduction_test|03_reduction/rank5_test_params.yaml"
"rank6_reduction_test|03_reduction/rank6_test_params.yaml"
)
# Bench (performance) tests encoded as "binary|config". Same encoding as
# _HIPTENSOR_DEVICE_TESTS, but the bench config set is distinct: it has no
# trinary/unary contraction variants, and its elementwise configs are flat
# (no permutation/binary_op/trinary_op subdirs). Paths are relative to the
# bench config root (bin/hiptensor/configs/bench/). Bench runs use different
# run-count flags (see the bench family below).
set(_HIPTENSOR_BENCH_TESTS
"bilinear_contraction_test_m1n1k1|01_contraction/bilinear_test_params_rank1.yaml"
"bilinear_contraction_test_m2n2k2|01_contraction/bilinear_test_params_rank2.yaml"
"bilinear_contraction_test_m3n3k3|01_contraction/bilinear_test_params_rank3.yaml"
"bilinear_contraction_test_m4n4k4|01_contraction/bilinear_test_params_rank4.yaml"
"bilinear_contraction_test_m5n5k5|01_contraction/bilinear_test_params_rank5.yaml"
"bilinear_contraction_test_m6n6k6|01_contraction/bilinear_test_params_rank6.yaml"
"complex_bilinear_contraction_test_m1n1k1|01_contraction/complex_bilinear_test_params_rank1.yaml"
"complex_bilinear_contraction_test_m2n2k2|01_contraction/complex_bilinear_test_params_rank2.yaml"
"complex_bilinear_contraction_test_m3n3k3|01_contraction/complex_bilinear_test_params_rank3.yaml"
"complex_bilinear_contraction_test_m4n4k4|01_contraction/complex_bilinear_test_params_rank4.yaml"
"complex_bilinear_contraction_test_m5n5k5|01_contraction/complex_bilinear_test_params_rank5.yaml"
"complex_bilinear_contraction_test_m6n6k6|01_contraction/complex_bilinear_test_params_rank6.yaml"
"scale_contraction_test_m1n1k1|01_contraction/scale_test_params_rank1.yaml"
"scale_contraction_test_m2n2k2|01_contraction/scale_test_params_rank2.yaml"
"scale_contraction_test_m3n3k3|01_contraction/scale_test_params_rank3.yaml"
"scale_contraction_test_m4n4k4|01_contraction/scale_test_params_rank4.yaml"
"scale_contraction_test_m5n5k5|01_contraction/scale_test_params_rank5.yaml"
"scale_contraction_test_m6n6k6|01_contraction/scale_test_params_rank6.yaml"
"complex_scale_contraction_test_m1n1k1|01_contraction/complex_scale_test_params_rank1.yaml"
"complex_scale_contraction_test_m2n2k2|01_contraction/complex_scale_test_params_rank2.yaml"
"complex_scale_contraction_test_m3n3k3|01_contraction/complex_scale_test_params_rank3.yaml"
"complex_scale_contraction_test_m4n4k4|01_contraction/complex_scale_test_params_rank4.yaml"
"complex_scale_contraction_test_m5n5k5|01_contraction/complex_scale_test_params_rank5.yaml"
"complex_scale_contraction_test_m6n6k6|01_contraction/complex_scale_test_params_rank6.yaml"
"rank2_elementwise_permute_test|02_elementwise/rank2_test_params.yaml"
"rank2_elementwise_binary_op_test|02_elementwise/rank2_binary_op_test_params.yaml"
"rank2_elementwise_trinary_op_test|02_elementwise/rank2_trinary_op_test_params.yaml"
"rank3_elementwise_permute_test|02_elementwise/rank3_test_params.yaml"
"rank3_elementwise_binary_op_test|02_elementwise/rank3_binary_op_test_params.yaml"
"rank3_elementwise_trinary_op_test|02_elementwise/rank3_trinary_op_test_params.yaml"
"rank4_elementwise_permute_test|02_elementwise/rank4_test_params.yaml"
"rank4_elementwise_binary_op_test|02_elementwise/rank4_binary_op_test_params.yaml"
"rank4_elementwise_trinary_op_test|02_elementwise/rank4_trinary_op_test_params.yaml"
"rank5_elementwise_permute_test|02_elementwise/rank5_test_params.yaml"
"rank5_elementwise_binary_op_test|02_elementwise/rank5_binary_op_test_params.yaml"
"rank5_elementwise_trinary_op_test|02_elementwise/rank5_trinary_op_test_params.yaml"
"rank6_elementwise_permute_test|02_elementwise/rank6_test_params.yaml"
"rank6_elementwise_binary_op_test|02_elementwise/rank6_binary_op_test_params.yaml"
"rank6_elementwise_trinary_op_test|02_elementwise/rank6_trinary_op_test_params.yaml"
"rank1_reduction_test|03_reduction/rank1_test_params.yaml"
"rank2_reduction_test|03_reduction/rank2_test_params.yaml"
"rank3_reduction_test|03_reduction/rank3_test_params.yaml"
"rank4_reduction_test|03_reduction/rank4_test_params.yaml"
"rank5_reduction_test|03_reduction/rank5_test_params.yaml"
"rank6_reduction_test|03_reduction/rank6_test_params.yaml"
)
# Helper: append one add_test + set_tests_properties to the main install
# fragment. WORKING_DIRECTORY is the install prefix root (../.. from the
# installed bin/hiptensor/ fragment) so ./bin/<binary> and the -y config
# path resolve regardless of ctest's cwd.
function(_hiptensor_emit_test test_name command)
file(APPEND "${INSTALL_TEST_FILE}" "add_test(\"${test_name}\" ${command})\n")
file(APPEND "${INSTALL_TEST_FILE}" "set_tests_properties(\"${test_name}\" PROPERTIES WORKING_DIRECTORY \"../..\" SKIP_REGULAR_EXPRESSION \"HIPTENSOR_STATUS_ARCH_MISMATCH;unsupported host device\")\n")
endfunction()
# A config yaml is "effectively empty" when it carries no test parameters.
# This is TRUE when the file:
# - does not exist, or
# - is completely empty (0 bytes), or
# - contains nothing beyond YAML document markers (---, ...), blank lines,
# and comments.
# Any of these is a deliberate signal that a device test is fully covered by an
# earlier tier and should NOT run in this one: registering it would hand the
# test an empty parameter set, which the GTest-parameterized harness cannot
# digest (empty ValuesIn / out-of-bounds param access -> SegFault). We resolve
# this at configure time by not emitting the add_test for that (test, tier).
function(_hiptensor_config_is_empty config_path out_var)
# Default TRUE covers the non-existent and 0-byte cases (file(STRINGS) on an
# empty file yields no lines, so the loop below never flips it to FALSE).
set(${out_var} TRUE PARENT_SCOPE)
if(NOT EXISTS "${config_path}")
return()
endif()
file(STRINGS "${config_path}" _lines)
foreach(_line IN LISTS _lines)
string(REGEX REPLACE "#.*$" "" _stripped "${_line}") # drop comments
string(STRIP "${_stripped}" _stripped)
if(_stripped STREQUAL "" OR _stripped STREQUAL "---" OR _stripped STREQUAL "...")
continue()
endif()
set(${out_var} FALSE PARENT_SCOPE)
return()
endforeach()
endfunction()
# Tiers (quick / standard / comprehensive / full): host + device.
# Each family is "<test name suffix>|<config dir under configs/>".
# Tier & ffm entries omit run-count flags (the binary defaults are
# --hot_runs 1 --cold_runs 0). Host tests are emitted once, under quick, and
# nest up into the higher tiers via the parser.
foreach(_hiptensor_family "quick|validation/quick" "standard|validation/standard" "comprehensive|validation/comprehensive" "full|validation/full")
string(REPLACE "|" ";" _hiptensor_ff "${_hiptensor_family}")
list(GET _hiptensor_ff 0 _hiptensor_suffix)
list(GET _hiptensor_ff 1 _hiptensor_cfgdir)
if(_hiptensor_suffix STREQUAL "quick")
foreach(_hiptensor_host IN LISTS _HIPTENSOR_HOST_TESTS)
_hiptensor_emit_test("${_hiptensor_host} ${_hiptensor_suffix}" "\"./bin/${_hiptensor_host}\"")
endforeach()
endif()
foreach(_hiptensor_dev IN LISTS _HIPTENSOR_DEVICE_TESTS)
string(REPLACE "|" ";" _hiptensor_dev_fields "${_hiptensor_dev}")
list(GET _hiptensor_dev_fields 0 _hiptensor_dev_bin)
list(GET _hiptensor_dev_fields 1 _hiptensor_dev_cfg)
set(_hiptensor_cmd "\"./bin/${_hiptensor_dev_bin}\"")
if(NOT _hiptensor_dev_cfg STREQUAL "NONE")
# dev_cfg is "<component>/<rest>"; the on-disk source lives at
# <component>/configs/<cfgdir>/<rest>. Skip this (test, tier) when
# that config is empty (covered by an earlier tier).
string(FIND "${_hiptensor_dev_cfg}" "/" _hiptensor_dev_slash)
string(SUBSTRING "${_hiptensor_dev_cfg}" 0 ${_hiptensor_dev_slash} _hiptensor_dev_comp)
math(EXPR _hiptensor_dev_after "${_hiptensor_dev_slash}+1")
string(SUBSTRING "${_hiptensor_dev_cfg}" ${_hiptensor_dev_after} -1 _hiptensor_dev_rest)
_hiptensor_config_is_empty(
"${CMAKE_CURRENT_SOURCE_DIR}/${_hiptensor_dev_comp}/configs/${_hiptensor_cfgdir}/${_hiptensor_dev_rest}"
_hiptensor_cfg_empty)
if(_hiptensor_cfg_empty)
continue()
endif()
string(APPEND _hiptensor_cmd " -y ./bin/${PROJECT_NAME}/configs/${_hiptensor_cfgdir}/${_hiptensor_dev_cfg}")
endif()
_hiptensor_emit_test("${_hiptensor_dev_bin} ${_hiptensor_suffix}" "${_hiptensor_cmd}")
endforeach()
endforeach()
# ffm-quick / ffm-full: device only. ffm-quick uses emulation/quick, ffm-full
# uses emulation/full (they are now distinct sets, not aliases).
foreach(_hiptensor_family "ffm-quick|emulation/quick" "ffm-full|emulation/full")
string(REPLACE "|" ";" _hiptensor_ff "${_hiptensor_family}")
list(GET _hiptensor_ff 0 _hiptensor_suffix)
list(GET _hiptensor_ff 1 _hiptensor_cfgdir)
foreach(_hiptensor_dev IN LISTS _HIPTENSOR_DEVICE_TESTS)
string(REPLACE "|" ";" _hiptensor_dev_fields "${_hiptensor_dev}")
list(GET _hiptensor_dev_fields 0 _hiptensor_dev_bin)
list(GET _hiptensor_dev_fields 1 _hiptensor_dev_cfg)
set(_hiptensor_cmd "\"./bin/${_hiptensor_dev_bin}\"")
if(NOT _hiptensor_dev_cfg STREQUAL "NONE")
# Skip this (test, tier) when its config is empty (see tier loop).
string(FIND "${_hiptensor_dev_cfg}" "/" _hiptensor_dev_slash)
string(SUBSTRING "${_hiptensor_dev_cfg}" 0 ${_hiptensor_dev_slash} _hiptensor_dev_comp)
math(EXPR _hiptensor_dev_after "${_hiptensor_dev_slash}+1")
string(SUBSTRING "${_hiptensor_dev_cfg}" ${_hiptensor_dev_after} -1 _hiptensor_dev_rest)
_hiptensor_config_is_empty(
"${CMAKE_CURRENT_SOURCE_DIR}/${_hiptensor_dev_comp}/configs/${_hiptensor_cfgdir}/${_hiptensor_dev_rest}"
_hiptensor_cfg_empty)
if(_hiptensor_cfg_empty)
continue()
endif()
string(APPEND _hiptensor_cmd " -y ./bin/${PROJECT_NAME}/configs/${_hiptensor_cfgdir}/${_hiptensor_dev_cfg}")
endif()
_hiptensor_emit_test("${_hiptensor_dev_bin} ${_hiptensor_suffix}" "${_hiptensor_cmd}")
endforeach()
endforeach()
# bench: performance runs. Uses the "bench" config category and performance
# run-count flags (more hot runs for stable timings, matching the reference
# scripts under scripts/performance/). Named "<binary> bench".
foreach(_hiptensor_bench IN LISTS _HIPTENSOR_BENCH_TESTS)
string(REPLACE "|" ";" _hiptensor_bench_fields "${_hiptensor_bench}")
list(GET _hiptensor_bench_fields 0 _hiptensor_bench_bin)
list(GET _hiptensor_bench_fields 1 _hiptensor_bench_cfg)
set(_hiptensor_cmd "\"./bin/${_hiptensor_bench_bin}\" -y ./bin/${PROJECT_NAME}/configs/bench/${_hiptensor_bench_cfg}")
string(APPEND _hiptensor_cmd " --hot_runs 5 --cold_runs 1")
_hiptensor_emit_test("${_hiptensor_bench_bin} bench" "${_hiptensor_cmd}")
endforeach()
# Bake YAML-driven category labels into each install-tree
# CTestTestfile.cmake fragment so `ctest --test-dir
# <prefix>/bin/hiptensor[/{smoke,regression}] -L <tier>` works against
# the install tree. Passing the install file as the 2nd argument tells
# the shared helper to scan it for the test names already written via
# add_test() above and emit explicit set_tests_properties(... LABELS ...)
# lines (the only label form ctest's script interpreter exposes through
# --print-labels / -L).
if(COMMAND apply_ctest_category_labels)
apply_ctest_category_labels(
"${_HIPTENSOR_TEST_CATEGORIES_YAML}"
"${INSTALL_TEST_FILE}"
)
apply_ctest_category_labels(
"${_HIPTENSOR_TEST_CATEGORIES_YAML}"
"${INSTALL_SMOKE_TEST_FILE}"
)
apply_ctest_category_labels(
"${_HIPTENSOR_TEST_CATEGORIES_YAML}"
"${INSTALL_REGRESSION_TEST_FILE}"
)
endif()
include(../cmake/Functions/CopyYamlFolder.cmake)
# Copy multiple configuration folders
copy_emulation_config_folders(
SOURCE_FOLDERS
"01_contraction/configs/emulation"
"02_elementwise/configs/emulation"
"03_reduction/configs/emulation"
SOURCE_SCRIPTS
"../rtest.py"
"../rtest.xml"
DESTINATION_PREFIX
"test_emulation_config"
)
copy_code_coverage_config_files(
${CMAKE_CURRENT_SOURCE_DIR}
"${CMAKE_BINARY_DIR}/code_coverage_config"
)
rocm_install(
FILES "${INSTALL_TEST_FILE}"
DESTINATION "${CMAKE_INSTALL_BINDIR}/${PROJECT_NAME}"
COMPONENT tests
RENAME "CTestTestfile.cmake"
)
rocm_install(
FILES "${INSTALL_SMOKE_TEST_FILE}"
DESTINATION "${CMAKE_INSTALL_BINDIR}/${PROJECT_NAME}/smoke"
COMPONENT tests
RENAME "CTestTestfile.cmake"
)
rocm_install(
FILES "${INSTALL_REGRESSION_TEST_FILE}"
DESTINATION "${CMAKE_INSTALL_BINDIR}/${PROJECT_NAME}/regression"
COMPONENT tests
RENAME "CTestTestfile.cmake"
)
# Install the config subtrees so the validation / ffm / bench entries' `-y` paths
# resolve at ctest runtime. The on-disk config layout mirrors the install
# layout 1:1, so the install path segment IS the on-disk source subtree:
# src <component>/configs/<dir>/
# dest bin/hiptensor/configs/<dir>/<component>/
foreach(_hiptensor_cfg_dir
validation/quick validation/standard validation/comprehensive validation/full
emulation/quick emulation/full
bench)
foreach(_hiptensor_cfg_component 01_contraction 02_elementwise 03_reduction)
rocm_install(
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_hiptensor_cfg_component}/configs/${_hiptensor_cfg_dir}/"
DESTINATION "${CMAKE_INSTALL_BINDIR}/${PROJECT_NAME}/configs/${_hiptensor_cfg_dir}/${_hiptensor_cfg_component}"
COMPONENT tests
)
endforeach()
endforeach()
rocm_install(DIRECTORY ${CMAKE_SOURCE_DIR}/scripts/performance/
DESTINATION "${CMAKE_INSTALL_BINDIR}/${PROJECT_NAME}/bench/scripts"
COMPONENT tests
FILE_PERMISSIONS
OWNER_READ OWNER_EXECUTE OWNER_WRITE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
DIRECTORY_PERMISSIONS
OWNER_READ OWNER_EXECUTE OWNER_WRITE
GROUP_READ GROUP_EXECUTE GROUP_WRITE
WORLD_READ WORLD_EXECUTE
)