Skip to content

[libc] Rework the GPU build to be a regular target #81921

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1087,10 +1087,41 @@ static void addOpenMPDeviceLibC(const ToolChain &TC, const ArgList &Args,
"llvm-libc-decls");
bool HasLibC = llvm::sys::fs::exists(LibCDecls) &&
llvm::sys::fs::is_directory(LibCDecls);
if (Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, HasLibC)) {
CmdArgs.push_back("-lcgpu");
CmdArgs.push_back("-lmgpu");
if (!Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, HasLibC))
return;

// We don't have access to the offloading toolchains here, so determine from
// the arguments if we have any active NVPTX or AMDGPU toolchains.
llvm::DenseSet<const char *> Libraries;
if (const Arg *Targets = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) {
if (llvm::any_of(Targets->getValues(),
[](auto S) { return llvm::Triple(S).isAMDGPU(); })) {
Libraries.insert("-lcgpu-amdgpu");
Libraries.insert("-lmgpu-amdgpu");
}
if (llvm::any_of(Targets->getValues(),
[](auto S) { return llvm::Triple(S).isNVPTX(); })) {
Libraries.insert("-lcgpu-nvptx");
Libraries.insert("-lmgpu-nvptx");
}
}

for (StringRef Arch : Args.getAllArgValues(options::OPT_offload_arch_EQ)) {
if (llvm::any_of(llvm::split(Arch, ","), [](StringRef Str) {
return IsAMDGpuArch(StringToCudaArch(Str));
})) {
Libraries.insert("-lcgpu-amdgpu");
Libraries.insert("-lmgpu-amdgpu");
}
if (llvm::any_of(llvm::split(Arch, ","), [](StringRef Str) {
return IsNVIDIAGpuArch(StringToCudaArch(Str));
})) {
Libraries.insert("-lcgpu-nvptx");
Libraries.insert("-lmgpu-nvptx");
}
}

llvm::append_range(CmdArgs, Libraries);
}

void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC,
Expand Down
20 changes: 17 additions & 3 deletions clang/test/Driver/openmp-offload-gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,14 +393,28 @@
//
// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp \
// RUN: --libomptarget-nvptx-bc-path=%S/Inputs/libomptarget/libomptarget-nvptx-test.bc \
// RUN: --libomptarget-amdgpu-bc-path=%S/Inputs/hip_dev_lib/libomptarget-amdgpu-gfx803.bc \
// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \
// RUN: --offload-arch=sm_52 -gpulibc -nogpuinc %s 2>&1 \
// RUN: --rocm-path=%S/Inputs/rocm \
// RUN: --offload-arch=sm_52,gfx803 -gpulibc -nogpuinc %s 2>&1 \
// RUN: | FileCheck --check-prefix=LIBC-GPU %s
// LIBC-GPU: "-lcgpu"{{.*}}"-lmgpu"
// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp \
// RUN: --libomptarget-nvptx-bc-path=%S/Inputs/libomptarget/libomptarget-nvptx-test.bc \
// RUN: --libomptarget-amdgpu-bc-path=%S/Inputs/hip_dev_lib/libomptarget-amdgpu-gfx803.bc \
// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \
// RUN: --rocm-path=%S/Inputs/rocm \
// RUN: -Xopenmp-target=nvptx64-nvidia-cuda -march=sm_52 \
// RUN: -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 \
// RUN: -fopenmp-targets=nvptx64-nvidia-cuda,amdgcn-amd-amdhsa -gpulibc -nogpuinc %s 2>&1 \
// RUN: | FileCheck --check-prefix=LIBC-GPU %s
// LIBC-GPU-DAG: "-lcgpu-amdgpu"
// LIBC-GPU-DAG: "-lmgpu-amdgpu"
// LIBC-GPU-DAG: "-lcgpu-nvptx"
// LIBC-GPU-DAG: "-lmgpu-nvptx"

// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp \
// RUN: --libomptarget-nvptx-bc-path=%S/Inputs/libomptarget/libomptarget-nvptx-test.bc \
// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \
// RUN: --offload-arch=sm_52 -nogpulibc -nogpuinc %s 2>&1 \
// RUN: | FileCheck --check-prefix=NO-LIBC-GPU %s
// NO-LIBC-GPU-NOT: "-lcgpu"{{.*}}"-lmgpu"
// NO-LIBC-GPU-NOT: -lmgpu{{.*}}-lcgpu
20 changes: 10 additions & 10 deletions libc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ set(LIBC_NAMESPACE "__llvm_libc_${LLVM_VERSION_MAJOR}_${LLVM_VERSION_MINOR}_${LL
CACHE STRING "The namespace to use to enclose internal implementations. Must start with '__llvm_libc'."
)

if(LLVM_LIBC_FULL_BUILD OR LIBC_GPU_BUILD OR LIBC_GPU_ARCHITECTURES)
if(LLVM_LIBC_FULL_BUILD OR LLVM_LIBC_GPU_BUILD)
if(NOT LIBC_HDRGEN_EXE)
# We need to set up hdrgen first since other targets depend on it.
add_subdirectory(utils/LibcTableGenUtil)
Expand Down Expand Up @@ -77,7 +77,7 @@ if(LIBC_HDRGEN_ONLY OR NEED_LIBC_HDRGEN)
# to build libc-hdrgen and return.

# Always make the RPC server availible to other projects for GPU mode.
if(LIBC_GPU_BUILD OR LIBC_GPU_ARCHITECTURES)
if(LLVM_LIBC_GPU_BUILD)
add_subdirectory(utils/gpu/server)
endif()
return()
Expand Down Expand Up @@ -118,7 +118,7 @@ if(COMMAND_RETURN_CODE EQUAL 0)
message(STATUS "Set COMPILER_RESOURCE_DIR to "
"${COMPILER_RESOURCE_DIR} using --print-resource-dir")
else()
if (LIBC_TARGET_ARCHITECTURE_IS_GPU)
if (LIBC_TARGET_OS_IS_GPU)
message(FATAL_ERROR "COMPILER_RESOURCE_DIR must be set for GPU builds")
else()
set(COMPILER_RESOURCE_DIR OFF)
Expand Down Expand Up @@ -216,11 +216,7 @@ foreach(config_path IN LISTS LIBC_CONFIG_JSON_FILE_LIST)
load_libc_config(${config_path}/config.json ${cmd_line_conf})
endforeach()

if(LIBC_TARGET_ARCHITECTURE_IS_GPU)
set(LIBC_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include)
set(LIBC_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/gpu-none-llvm)
set(LIBC_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
elseif(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND LIBC_ENABLE_USE_BY_CLANG)
if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND LIBC_ENABLE_USE_BY_CLANG)
set(LIBC_INCLUDE_DIR ${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE})
set(LIBC_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${LLVM_DEFAULT_TARGET_TRIPLE})
set(LIBC_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE})
Expand All @@ -235,7 +231,11 @@ else()
set(LIBC_INCLUDE_DIR ${CMAKE_BINARY_DIR}/include)
set(LIBC_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX})
endif()
set(LIBC_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR})
if(LIBC_TARGET_OS_IS_GPU)
set(LIBC_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${LLVM_DEFAULT_TARGET_TRIPLE})
else()
set(LIBC_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR})
endif()
endif()

if(LIBC_TARGET_TRIPLE)
Expand All @@ -247,7 +247,7 @@ else()
set(LIBC_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX})
endif()

if(LIBC_TARGET_ARCHITECTURE_IS_GPU)
if(LIBC_TARGET_OS_IS_GPU)
include(prepare_libc_gpu_build)
set(LIBC_ENABLE_UNITTESTS OFF)
endif()
Expand Down
28 changes: 16 additions & 12 deletions libc/cmake/modules/LLVMLibCArchitectures.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,6 @@
# platform.
# ------------------------------------------------------------------------------

if(LIBC_GPU_BUILD OR LIBC_GPU_ARCHITECTURES)
# We set the generic target and OS to "gpu" here. More specific defintions
# for the exact target GPU are set up in prepare_libc_gpu_build.cmake.
set(LIBC_TARGET_OS "gpu")
set(LIBC_TARGET_ARCHITECTURE_IS_GPU TRUE)
set(LIBC_TARGET_ARCHITECTURE "gpu")
if(LIBC_TARGET_TRIPLE)
message(WARNING "LIBC_TARGET_TRIPLE is ignored as LIBC_GPU_BUILD is on. ")
endif()
return()
endif()

if(MSVC)
# If the compiler is visual c++ or equivalent, we will assume a host build.
set(LIBC_TARGET_OS ${CMAKE_HOST_SYSTEM_NAME})
Expand Down Expand Up @@ -59,6 +47,10 @@ function(get_arch_and_system_from_triple triple arch_var sys_var)
set(target_arch "riscv32")
elseif(target_arch MATCHES "^riscv64")
set(target_arch "riscv64")
elseif(target_arch MATCHES "^amdgcn")
set(target_arch "amdgpu")
elseif(target_arch MATCHES "^nvptx64")
set(target_arch "nvptx")
else()
return()
endif()
Expand All @@ -75,6 +67,12 @@ function(get_arch_and_system_from_triple triple arch_var sys_var)
set(target_sys "darwin")
endif()

# Setting OS name for GPU architectures.
list(GET triple_comps -1 gpu_target_sys)
if(gpu_target_sys MATCHES "^amdhsa" OR gpu_target_sys MATCHES "^cuda")
set(target_sys "gpu")
endif()

set(${sys_var} ${target_sys} PARENT_SCOPE)
endfunction(get_arch_and_system_from_triple)

Expand Down Expand Up @@ -156,6 +154,10 @@ elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv64")
elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv32")
set(LIBC_TARGET_ARCHITECTURE_IS_RISCV32 TRUE)
set(LIBC_TARGET_ARCHITECTURE "riscv")
elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "amdgpu")
set(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU TRUE)
elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "nvptx")
set(LIBC_TARGET_ARCHITECTURE_IS_NVPTX TRUE)
else()
message(FATAL_ERROR
"Unsupported libc target architecture ${LIBC_TARGET_ARCHITECTURE}")
Expand All @@ -178,6 +180,8 @@ elseif(LIBC_TARGET_OS STREQUAL "darwin")
set(LIBC_TARGET_OS_IS_DARWIN TRUE)
elseif(LIBC_TARGET_OS STREQUAL "windows")
set(LIBC_TARGET_OS_IS_WINDOWS TRUE)
elseif(LIBC_TARGET_OS STREQUAL "gpu")
set(LIBC_TARGET_OS_IS_GPU TRUE)
else()
message(FATAL_ERROR
"Unsupported libc target operating system ${LIBC_TARGET_OS}")
Expand Down
2 changes: 1 addition & 1 deletion libc/cmake/modules/LLVMLibCCheckMPFR.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ set(LLVM_LIBC_MPFR_INSTALL_PATH "" CACHE PATH "Path to where MPFR is installed (

if(LLVM_LIBC_MPFR_INSTALL_PATH)
set(LIBC_TESTS_CAN_USE_MPFR TRUE)
elseif(LIBC_TARGET_ARCHITECTURE_IS_GPU)
elseif(LIBC_TARGET_OS_IS_GPU)
set(LIBC_TESTS_CAN_USE_MPFR FALSE)
else()
try_compile(
Expand Down
76 changes: 18 additions & 58 deletions libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,22 @@ function(_get_common_compile_options output_var flags)
list(APPEND compile_options "/EHs-c-")
list(APPEND compile_options "/GR-")
endif()
if (LIBC_TARGET_ARCHITECTURE_IS_GPU)
if (LIBC_TARGET_OS_IS_GPU)
list(APPEND compile_options "-nogpulib")
list(APPEND compile_options "-fvisibility=hidden")
list(APPEND compile_options "-fconvergent-functions")
list(APPEND compile_options "-flto")

if(LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
list(APPEND compile_options "-Wno-unknown-cuda-version")
list(APPEND compile_options "SHELL:-mllvm -nvptx-emit-init-fini-kernel=false")
list(APPEND compile_options "--cuda-feature=+ptx63")
if(LIBC_CUDA_ROOT)
list(APPEND compile_options "--cuda-path=${LIBC_CUDA_ROOT}")
endif()
elseif(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
list(APPEND compile_options "SHELL:-Xclang -mcode-object-version=none")
endif()

# Manually disable all standard include paths and include the resource
# directory to prevent system headers from being included.
Expand Down Expand Up @@ -138,73 +150,21 @@ function(_get_common_test_compile_options output_var flags)
set(${output_var} ${compile_options} PARENT_SCOPE)
endfunction()

# Obtains NVPTX specific arguments for compilation.
# The PTX feature is primarily based on the CUDA toolchain version. We want to
# be able to target NVPTX without an existing CUDA installation, so we need to
# set this manually. This simply sets the PTX feature to the minimum required
# for the features we wish to use on that target. The minimum PTX features used
# here roughly corresponds to the CUDA 9.0 release.
# Adjust as needed for desired PTX features.
function(get_nvptx_compile_options output_var gpu_arch)
set(nvptx_options "")
list(APPEND nvptx_options "-march=${gpu_arch}")
list(APPEND nvptx_options "-Wno-unknown-cuda-version")
list(APPEND nvptx_options "SHELL:-mllvm -nvptx-emit-init-fini-kernel=false")
if(${gpu_arch} STREQUAL "sm_35")
list(APPEND nvptx_options "--cuda-feature=+ptx63")
elseif(${gpu_arch} STREQUAL "sm_37")
list(APPEND nvptx_options "--cuda-feature=+ptx63")
elseif(${gpu_arch} STREQUAL "sm_50")
list(APPEND nvptx_options "--cuda-feature=+ptx63")
elseif(${gpu_arch} STREQUAL "sm_52")
list(APPEND nvptx_options "--cuda-feature=+ptx63")
elseif(${gpu_arch} STREQUAL "sm_53")
list(APPEND nvptx_options "--cuda-feature=+ptx63")
elseif(${gpu_arch} STREQUAL "sm_60")
list(APPEND nvptx_options "--cuda-feature=+ptx63")
elseif(${gpu_arch} STREQUAL "sm_61")
list(APPEND nvptx_options "--cuda-feature=+ptx63")
elseif(${gpu_arch} STREQUAL "sm_62")
list(APPEND nvptx_options "--cuda-feature=+ptx63")
elseif(${gpu_arch} STREQUAL "sm_70")
list(APPEND nvptx_options "--cuda-feature=+ptx63")
elseif(${gpu_arch} STREQUAL "sm_72")
list(APPEND nvptx_options "--cuda-feature=+ptx63")
elseif(${gpu_arch} STREQUAL "sm_75")
list(APPEND nvptx_options "--cuda-feature=+ptx63")
elseif(${gpu_arch} STREQUAL "sm_80")
list(APPEND nvptx_options "--cuda-feature=+ptx72")
elseif(${gpu_arch} STREQUAL "sm_86")
list(APPEND nvptx_options "--cuda-feature=+ptx72")
elseif(${gpu_arch} STREQUAL "sm_89")
list(APPEND nvptx_options "--cuda-feature=+ptx72")
elseif(${gpu_arch} STREQUAL "sm_90")
list(APPEND nvptx_options "--cuda-feature=+ptx72")
else()
message(FATAL_ERROR "Unknown Nvidia GPU architecture '${gpu_arch}'")
endif()

if(LIBC_CUDA_ROOT)
list(APPEND nvptx_options "--cuda-path=${LIBC_CUDA_ROOT}")
endif()
set(${output_var} ${nvptx_options} PARENT_SCOPE)
endfunction()

function(_get_hermetic_test_compile_options output_var flags)
_get_compile_options_from_flags(compile_flags ${flags})
list(APPEND compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT} ${compile_flags}
${flags} -fpie -ffreestanding -fno-exceptions -fno-rtti)

# The GPU build requires overriding the default CMake triple and architecture.
if(LIBC_GPU_TARGET_ARCHITECTURE_IS_AMDGPU)
if(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
list(APPEND compile_options
-nogpulib -mcpu=${LIBC_GPU_TARGET_ARCHITECTURE} -flto
--target=${LIBC_GPU_TARGET_TRIPLE}
-mcode-object-version=${LIBC_GPU_CODE_OBJECT_VERSION})
elseif(LIBC_GPU_TARGET_ARCHITECTURE_IS_NVPTX)
get_nvptx_compile_options(nvptx_options ${LIBC_GPU_TARGET_ARCHITECTURE})
elseif(LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
list(APPEND compile_options
-nogpulib ${nvptx_options} -fno-use-cxa-atexit --target=${LIBC_GPU_TARGET_TRIPLE})
"SHELL:-mllvm -nvptx-emit-init-fini-kernel=false"
--cuda-path=${LIBC_CUDA_ROOT}
-nogpulib -march=${LIBC_GPU_TARGET_ARCHITECTURE} -fno-use-cxa-atexit)
endif()
set(${output_var} ${compile_options} PARENT_SCOPE)
endfunction()
2 changes: 1 addition & 1 deletion libc/cmake/modules/LLVMLibCHeaderRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ function(add_gen_header target_name)
${hdrgen_deps}
)

if(LIBC_TARGET_ARCHITECTURE_IS_GPU)
if(LIBC_TARGET_OS_IS_GPU)
file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/llvm-libc-decls)
set(decl_out_file ${LIBC_INCLUDE_DIR}/llvm-libc-decls/${relative_path})
add_custom_command(
Expand Down
Loading