xref: /llvm-project/libc/cmake/modules/prepare_libc_gpu_build.cmake (revision 68bcba6d7a1cc18996c0bcb7c62267c62d2040d0)
1if(NOT LIBC_TARGET_OS_IS_GPU)
2  message(FATAL_ERROR
3          "libc build: Invalid attempt to set up GPU architectures.")
4endif()
5
6# Ensure the compiler is a valid clang when building the GPU target.
7set(req_ver "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
8if(LLVM_VERSION_MAJOR AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang" AND
9   ${CMAKE_CXX_COMPILER_VERSION} VERSION_EQUAL "${req_ver}"))
10  message(FATAL_ERROR "Cannot build libc for GPU. CMake compiler "
11                      "'${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}' "
12                      " is not 'Clang ${req_ver}'.")
13endif()
14if(NOT LLVM_LIBC_FULL_BUILD)
15  message(FATAL_ERROR "LLVM_LIBC_FULL_BUILD must be enabled to build libc for "
16                      "GPU.")
17endif()
18
19# Set the required flags globally so standard CMake utilities can compile.
20if(LIBC_TARGET_TRIPLE)
21  set(CMAKE_REQUIRED_FLAGS "--target=${LIBC_TARGET_TRIPLE}")
22endif()
23if(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
24  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nogpulib")
25elseif(LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
26  set(CMAKE_REQUIRED_FLAGS
27      "${CMAKE_REQUIRED_FLAGS} -flto -c -Wno-unused-command-line-argument")
28endif()
29
30# Optionally set up a job pool to limit the number of GPU tests run in parallel.
31# This is sometimes necessary as running too many tests in parallel can cause
32# the GPU or driver to run out of resources.
33set(LIBC_GPU_TEST_JOBS "" CACHE STRING "Number of jobs to use for GPU tests")
34if(LIBC_GPU_TEST_JOBS)
35  set_property(GLOBAL PROPERTY JOB_POOLS LIBC_GPU_TEST_POOL=${LIBC_GPU_TEST_JOBS})
36  set(LIBC_HERMETIC_TEST_JOB_POOL JOB_POOL LIBC_GPU_TEST_POOL)
37else()
38  set_property(GLOBAL PROPERTY JOB_POOLS LIBC_GPU_TEST_POOL=1)
39  set(LIBC_HERMETIC_TEST_JOB_POOL JOB_POOL LIBC_GPU_TEST_POOL)
40endif()
41
42set(LIBC_GPU_TEST_ARCHITECTURE "" CACHE STRING "Architecture for the GPU tests")
43if(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
44  check_cxx_compiler_flag(-mcpu=native PLATFORM_HAS_GPU)
45elseif(LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
46  check_cxx_compiler_flag(-march=native PLATFORM_HAS_GPU)
47endif()
48
49set(gpu_test_architecture "")
50if(DEFINED LLVM_TARGETS_TO_BUILD AND LIBC_TARGET_ARCHITECTURE_IS_AMDGPU
51   AND NOT "AMDGPU" IN_LIST LLVM_TARGETS_TO_BUILD)
52  set(LIBC_GPU_TESTS_DISABLED TRUE)
53  message(STATUS "AMDGPU backend is not available, tests will not be built")
54elseif(DEFINED LLVM_TARGETS_TO_BUILD AND LIBC_TARGET_ARCHITECTURE_IS_NVPTX
55       AND NOT "NVPTX" IN_LIST LLVM_TARGETS_TO_BUILD)
56  set(LIBC_GPU_TESTS_DISABLED TRUE)
57  message(STATUS "NVPTX backend is not available, tests will not be built")
58elseif(LIBC_GPU_TEST_ARCHITECTURE)
59  set(LIBC_GPU_TESTS_DISABLED FALSE)
60  set(gpu_test_architecture ${LIBC_GPU_TEST_ARCHITECTURE})
61  message(STATUS "Using user-specified GPU architecture for testing: "
62                 "'${gpu_test_architecture}'")
63elseif(PLATFORM_HAS_GPU)
64  set(LIBC_GPU_TESTS_DISABLED FALSE)
65  set(gpu_test_architecture "native")
66  message(STATUS "Using GPU architecture detected on the system for testing: "
67                 "'native'")
68else()
69  set(LIBC_GPU_TESTS_DISABLED TRUE)
70  message(STATUS "No GPU architecture detected or provided, tests will not be "
71                 "built")
72endif()
73set(LIBC_GPU_TARGET_ARCHITECTURE "${gpu_test_architecture}")
74
75# Identify the GPU loader utility used to run tests.
76set(LIBC_GPU_LOADER_EXECUTABLE "" CACHE STRING "Executable for the GPU loader.")
77if(LIBC_GPU_LOADER_EXECUTABLE)
78  set(gpu_loader_executable ${LIBC_GPU_LOADER_EXECUTABLE})
79elseif(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
80  find_program(LIBC_AMDHSA_LOADER_EXECUTABLE
81               NAMES amdhsa-loader NO_DEFAULT_PATH
82               PATHS ${LLVM_BINARY_DIR}/bin ${compiler_path})
83  if(LIBC_AMDHSA_LOADER_EXECUTABLE)
84    set(gpu_loader_executable ${LIBC_AMDHSA_LOADER_EXECUTABLE})
85  endif()
86elseif(LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
87  find_program(LIBC_NVPTX_LOADER_EXECUTABLE
88               NAMES nvptx-loader NO_DEFAULT_PATH
89               PATHS ${LLVM_BINARY_DIR}/bin ${compiler_path})
90  if(LIBC_NVPTX_LOADER_EXECUTABLE)
91    set(gpu_loader_executable ${LIBC_NVPTX_LOADER_EXECUTABLE})
92  endif()
93endif()
94if(NOT TARGET libc.utils.gpu.loader AND gpu_loader_executable)
95  add_custom_target(libc.utils.gpu.loader)
96  set_target_properties(
97    libc.utils.gpu.loader
98    PROPERTIES
99      EXECUTABLE "${gpu_loader_executable}"
100  )
101endif()
102
103if(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
104  # The AMDGPU environment uses different code objects to encode the ABI for
105  # kernel calls and intrinsic functions. We want to specify this manually to
106  # conform to whatever the test suite was built to handle.
107  set(LIBC_GPU_CODE_OBJECT_VERSION 5)
108endif()
109
110if(LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
111  # FIXME: This is a hack required to keep the CUDA package from trying to find
112  #        pthreads. We only link the CUDA driver, so this is unneeded.
113  add_library(CUDA::cudart_static_deps IMPORTED INTERFACE)
114
115  find_package(CUDAToolkit QUIET)
116  if(CUDAToolkit_FOUND)
117    get_filename_component(LIBC_CUDA_ROOT "${CUDAToolkit_BIN_DIR}" DIRECTORY ABSOLUTE)
118  endif()
119endif()
120