Summary: Debug builds don't optimize out certain parts of the code that end up making the GPU backend crash. This results in regular builds not being successful just to build the testing objects. Disable them for now in debug mode.
146 lines
5.9 KiB
CMake
146 lines
5.9 KiB
CMake
if(NOT LIBC_TARGET_OS_IS_GPU)
|
|
message(FATAL_ERROR
|
|
"libc build: Invalid attempt to set up GPU architectures.")
|
|
endif()
|
|
|
|
# Ensure the compiler is a valid clang when building the GPU target.
|
|
set(req_ver "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
|
|
if(LLVM_VERSION_MAJOR AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang" AND
|
|
${CMAKE_CXX_COMPILER_VERSION} VERSION_EQUAL "${req_ver}"))
|
|
message(FATAL_ERROR "Cannot build libc for GPU. CMake compiler "
|
|
"'${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}' "
|
|
" is not 'Clang ${req_ver}'.")
|
|
endif()
|
|
if(NOT LLVM_LIBC_FULL_BUILD)
|
|
message(FATAL_ERROR "LLVM_LIBC_FULL_BUILD must be enabled to build libc for "
|
|
"GPU.")
|
|
endif()
|
|
|
|
# Identify the program used to package multiple images into a single binary.
|
|
get_filename_component(compiler_path ${CMAKE_CXX_COMPILER} DIRECTORY)
|
|
find_program(LIBC_CLANG_OFFLOAD_PACKAGER
|
|
NAMES clang-offload-packager NO_DEFAULT_PATH
|
|
PATHS ${LLVM_BINARY_DIR}/bin ${compiler_path})
|
|
if(NOT LIBC_CLANG_OFFLOAD_PACKAGER)
|
|
message(FATAL_ERROR "Cannot find the 'clang-offload-packager' for the GPU "
|
|
"build")
|
|
endif()
|
|
|
|
# Identify llvm-link program so we can merge the output IR into a single blob.
|
|
find_program(LIBC_LLVM_LINK
|
|
NAMES llvm-link NO_DEFAULT_PATH
|
|
PATHS ${LLVM_BINARY_DIR}/bin ${compiler_path})
|
|
if(NOT LIBC_LLVM_LINK)
|
|
message(FATAL_ERROR "Cannot find 'llvm-link' for the GPU build")
|
|
endif()
|
|
|
|
# Optionally set up a job pool to limit the number of GPU tests run in parallel.
|
|
# This is sometimes necessary as running too many tests in parallel can cause
|
|
# the GPU or driver to run out of resources.
|
|
set(LIBC_GPU_TEST_JOBS "" CACHE STRING "Number of jobs to use for GPU tests")
|
|
if(LIBC_GPU_TEST_JOBS)
|
|
set_property(GLOBAL PROPERTY JOB_POOLS LIBC_GPU_TEST_POOL=${LIBC_GPU_TEST_JOBS})
|
|
set(LIBC_HERMETIC_TEST_JOB_POOL JOB_POOL LIBC_GPU_TEST_POOL)
|
|
else()
|
|
set_property(GLOBAL PROPERTY JOB_POOLS LIBC_GPU_TEST_POOL=1)
|
|
set(LIBC_HERMETIC_TEST_JOB_POOL JOB_POOL LIBC_GPU_TEST_POOL)
|
|
endif()
|
|
|
|
set(LIBC_GPU_TEST_ARCHITECTURE "" CACHE STRING "Architecture for the GPU tests")
|
|
if(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
|
|
# Identify any locally installed NVIDIA GPUs on the system using 'nvptx-arch'.
|
|
find_program(LIBC_AMDGPU_ARCH
|
|
NAMES amdgpu-arch NO_DEFAULT_PATH
|
|
PATHS ${LLVM_BINARY_DIR}/bin ${compiler_path})
|
|
if(LIBC_AMDGPU_ARCH)
|
|
execute_process(COMMAND ${LIBC_AMDGPU_ARCH}
|
|
OUTPUT_VARIABLE arch_tool_output
|
|
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
if(arch_tool_output MATCHES "^gfx[0-9]+")
|
|
set(PLATFORM_HAS_GPU TRUE)
|
|
endif()
|
|
endif()
|
|
elseif(LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
|
|
# Identify any locally installed NVIDIA GPUs on the system using 'nvptx-arch'.
|
|
find_program(LIBC_NVPTX_ARCH
|
|
NAMES nvptx-arch NO_DEFAULT_PATH
|
|
PATHS ${LLVM_BINARY_DIR}/bin ${compiler_path})
|
|
if(LIBC_NVPTX_ARCH)
|
|
execute_process(COMMAND ${LIBC_NVPTX_ARCH}
|
|
OUTPUT_VARIABLE arch_tool_output
|
|
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
if(arch_tool_output MATCHES "^sm_[0-9]+")
|
|
set(PLATFORM_HAS_GPU TRUE)
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
set(gpu_test_architecture "")
|
|
if(LIBC_GPU_TEST_ARCHITECTURE)
|
|
set(LIBC_GPU_TESTS_DISABLED FALSE)
|
|
set(gpu_test_architecture ${LIBC_GPU_TEST_ARCHITECTURE})
|
|
message(STATUS "Using user-specified GPU architecture for testing: "
|
|
"'${gpu_test_architecture}'")
|
|
elseif(PLATFORM_HAS_GPU)
|
|
set(LIBC_GPU_TESTS_DISABLED FALSE)
|
|
set(gpu_test_architecture "native")
|
|
message(STATUS "Using GPU architecture detected on the system for testing: "
|
|
"'native'")
|
|
else()
|
|
set(LIBC_GPU_TESTS_DISABLED TRUE)
|
|
message(STATUS "No GPU architecture detected or provided, tests will not be "
|
|
"built")
|
|
endif()
|
|
set(LIBC_GPU_TARGET_ARCHITECTURE "${gpu_test_architecture}")
|
|
|
|
# The NVPTX backend cannot currently handle objects created in debug mode.
|
|
if(LIBC_TARGET_ARCHITECTURE_IS_NVPTX AND CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
set(LIBC_GPU_TESTS_DISABLED TRUE)
|
|
endif()
|
|
|
|
# Identify the GPU loader utility used to run tests.
|
|
set(LIBC_GPU_LOADER_EXECUTABLE "" CACHE STRING "Executable for the GPU loader.")
|
|
if(LIBC_GPU_LOADER_EXECUTABLE)
|
|
set(gpu_loader_executable ${LIBC_GPU_LOADER_EXECUTABLE})
|
|
elseif(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
|
|
find_program(LIBC_AMDHSA_LOADER_EXECUTABLE
|
|
NAMES amdhsa-loader NO_DEFAULT_PATH
|
|
PATHS ${LLVM_BINARY_DIR}/bin ${compiler_path})
|
|
if(LIBC_AMDHSA_LOADER_EXECUTABLE)
|
|
set(gpu_loader_executable ${LIBC_AMDHSA_LOADER_EXECUTABLE})
|
|
endif()
|
|
elseif(LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
|
|
find_program(LIBC_NVPTX_LOADER_EXECUTABLE
|
|
NAMES nvptx-loader NO_DEFAULT_PATH
|
|
PATHS ${LLVM_BINARY_DIR}/bin ${compiler_path})
|
|
if(LIBC_NVPTX_LOADER_EXECUTABLE)
|
|
set(gpu_loader_executable ${LIBC_NVPTX_LOADER_EXECUTABLE})
|
|
endif()
|
|
endif()
|
|
if(NOT TARGET libc.utils.gpu.loader AND gpu_loader_executable)
|
|
add_custom_target(libc.utils.gpu.loader)
|
|
set_target_properties(
|
|
libc.utils.gpu.loader
|
|
PROPERTIES
|
|
EXECUTABLE "${gpu_loader_executable}"
|
|
)
|
|
endif()
|
|
|
|
if(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
|
|
# The AMDGPU environment uses different code objects to encode the ABI for
|
|
# kernel calls and intrinsic functions. We want to specify this manually to
|
|
# conform to whatever the test suite was built to handle.
|
|
set(LIBC_GPU_CODE_OBJECT_VERSION 5)
|
|
endif()
|
|
|
|
if(LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
|
|
# FIXME: This is a hack required to keep the CUDA package from trying to find
|
|
# pthreads. We only link the CUDA driver, so this is unneeded.
|
|
add_library(CUDA::cudart_static_deps IMPORTED INTERFACE)
|
|
|
|
find_package(CUDAToolkit QUIET)
|
|
if(CUDAToolkit_FOUND)
|
|
get_filename_component(LIBC_CUDA_ROOT "${CUDAToolkit_BIN_DIR}" DIRECTORY ABSOLUTE)
|
|
endif()
|
|
endif()
|