129 lines
5.5 KiB
CMake
129 lines
5.5 KiB
CMake
|
if(NOT LIBC_TARGET_ARCHITECTURE_IS_GPU)
|
||
|
message(FATAL_ERROR
|
||
|
"libc build: Invalid attempt to set up GPU architectures.")
|
||
|
endif()
|
||
|
|
||
|
# Set up the target architectures to build the GPU libc for.
|
||
|
set(all_amdgpu_architectures "gfx700;gfx701;gfx801;gfx803;gfx900;gfx902;gfx906"
|
||
|
"gfx908;gfx90a;gfx90c;gfx940;gfx941;gfx942"
|
||
|
"gfx1010;gfx1030;gfx1031;gfx1032;gfx1033;gfx1034"
|
||
|
"gfx1035;gfx1036"
|
||
|
"gfx1100;gfx1101;gfx1102;gfx1103;gfx1150;gfx1151")
|
||
|
set(all_nvptx_architectures "sm_35;sm_37;sm_50;sm_52;sm_53;sm_60;sm_61;sm_62"
|
||
|
"sm_70;sm_72;sm_75;sm_80;sm_86;sm_89;sm_90")
|
||
|
set(all_gpu_architectures
|
||
|
"${all_amdgpu_architectures};${all_nvptx_architectures}")
|
||
|
set(LIBC_GPU_ARCHITECTURES "all" CACHE STRING
|
||
|
"List of GPU architectures to build the libc for.")
|
||
|
|
||
|
# 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(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 any locally installed AMD GPUs on the system using 'amdgpu-arch'.
|
||
|
find_program(LIBC_AMDGPU_ARCH
|
||
|
NAMES amdgpu-arch NO_DEFAULT_PATH
|
||
|
PATHS ${LLVM_BINARY_DIR}/bin /opt/rocm/llvm/bin/)
|
||
|
|
||
|
# 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)
|
||
|
|
||
|
# Get the list of all natively supported GPU architectures.
|
||
|
set(detected_gpu_architectures "")
|
||
|
foreach(arch_tool ${LIBC_NVPTX_ARCH} ${LIBC_AMDGPU_ARCH})
|
||
|
if(arch_tool)
|
||
|
execute_process(COMMAND ${arch_tool}
|
||
|
OUTPUT_VARIABLE arch_tool_output
|
||
|
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||
|
string(REPLACE "\n" ";" arch_list "${arch_tool_output}")
|
||
|
list(APPEND detected_gpu_architectures "${arch_list}")
|
||
|
endif()
|
||
|
endforeach()
|
||
|
list(REMOVE_DUPLICATES detected_gpu_architectures)
|
||
|
|
||
|
if(LIBC_GPU_ARCHITECTURES STREQUAL "all")
|
||
|
set(LIBC_GPU_ARCHITECTURES ${all_gpu_architectures})
|
||
|
elseif(LIBC_GPU_ARCHITECTURES STREQUAL "native")
|
||
|
if(NOT detected_gpu_architectures)
|
||
|
message(FATAL_ERROR "No GPUs found on the system when using 'native'")
|
||
|
endif()
|
||
|
set(LIBC_GPU_ARCHITECTURES ${detected_gpu_architectures})
|
||
|
endif()
|
||
|
message(STATUS "Building libc for the following GPU architecture(s): "
|
||
|
"${LIBC_GPU_ARCHITECTURES}")
|
||
|
|
||
|
# Identify the program used to package multiple images into a single binary.
|
||
|
find_program(LIBC_CLANG_OFFLOAD_PACKAGER
|
||
|
NAMES clang-offload-packager NO_DEFAULT_PATH
|
||
|
PATHS ${LLVM_BINARY_DIR}/bin)
|
||
|
if(NOT LIBC_CLANG_OFFLOAD_PACKAGER)
|
||
|
message(FATAL_ERROR "Cannot find the 'clang-offload-packager' 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")
|
||
|
|
||
|
set(gpu_test_architecture "")
|
||
|
if(LIBC_GPU_TEST_ARCHITECTURE)
|
||
|
set(gpu_test_architecture ${LIBC_GPU_TEST_ARCHITECTURE})
|
||
|
message(STATUS "Using user-specified GPU architecture for testing: "
|
||
|
"'${gpu_test_architecture}'")
|
||
|
elseif(detected_gpu_architectures)
|
||
|
list(GET detected_gpu_architectures 0 gpu_test_architecture)
|
||
|
message(STATUS "Using GPU architecture detected on the system for testing: "
|
||
|
"'${gpu_test_architecture}'")
|
||
|
else()
|
||
|
message(STATUS "No GPU architecture set for testing. GPU tests will not be "
|
||
|
"availibe. Set 'LIBC_GPU_TEST_ARCHITECTURE' to override.")
|
||
|
return()
|
||
|
endif()
|
||
|
|
||
|
if("${gpu_test_architecture}" IN_LIST all_amdgpu_architectures)
|
||
|
set(LIBC_GPU_TARGET_ARCHITECTURE_IS_AMDGPU TRUE)
|
||
|
set(LIBC_GPU_TARGET_TRIPLE "amdgcn-amd-amdhsa")
|
||
|
set(LIBC_GPU_TARGET_ARCHITECTURE "${gpu_test_architecture}")
|
||
|
elseif("${gpu_test_architecture}" IN_LIST all_nvptx_architectures)
|
||
|
set(LIBC_GPU_TARGET_ARCHITECTURE_IS_NVPTX TRUE)
|
||
|
set(LIBC_GPU_TARGET_TRIPLE "nvptx64-nvidia-cuda")
|
||
|
set(LIBC_GPU_TARGET_ARCHITECTURE "${gpu_test_architecture}")
|
||
|
else()
|
||
|
message(FATAL_ERROR "Unknown GPU architecture '${gpu_test_architecture}'")
|
||
|
endif()
|
||
|
|
||
|
if(LIBC_GPU_TARGET_ARCHITECTURE_IS_NVPTX)
|
||
|
find_package(CUDAToolkit QUIET)
|
||
|
if(CUDAToolkit_FOUND)
|
||
|
get_filename_component(LIBC_CUDA_ROOT "${CUDAToolkit_BIN_DIR}" DIRECTORY ABSOLUTE)
|
||
|
endif()
|
||
|
endif()
|
||
|
|
||
|
if(LIBC_GPU_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()
|