Skip to content

Commit

Permalink
[libc] Add startup code implementation for GPU targets
Browse files Browse the repository at this point in the history
This patch introduces startup code for executing `main` on a device
compiled for the GPU. We will primarily use this to run standalone
integration tests on the GPU. The actual execution of this routine will
need to be provided by a `loader` utility to bootstrap execution on the
GPU.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D143212
  • Loading branch information
jhuber6 committed Feb 7, 2023
1 parent 5e14a48 commit fa34b9e
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 0 deletions.
63 changes: 63 additions & 0 deletions libc/startup/gpu/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
function(add_startup_object name)
cmake_parse_arguments(
"ADD_STARTUP_OBJECT"
"ALIAS" # Option argument
"SRC" # Single value arguments
"DEPENDS;COMPILE_OPTIONS" # Multi value arguments
${ARGN}
)

get_fq_target_name(${name} fq_target_name)
if(ADD_STARTUP_OBJECT_ALIAS)
get_fq_deps_list(fq_dep_list ${ADD_STARTUP_OBJECT_DEPENDS})
add_library(${fq_target_name} ALIAS ${fq_dep_list})
return()
endif()

add_object_library(
${name}
SRCS ${ADD_STARTUP_OBJECT_SRC}
DEPENDS ${ADD_STARTUP_OBJECT_DEPENDS}
COMPILE_OPTIONS ${ADD_STARTUP_OBJECT_COMPILE_OPTIONS}
)
set_target_properties(
${fq_target_name}
PROPERTIES
OUTPUT_NAME ${name}.o
)
endfunction()

if(LIBC_GPU_TARGET_ARCHITECTURE_IS_AMDGPU)
add_subdirectory(amdgpu)

add_startup_object(
crt1
ALIAS
DEPENDS
.amdgpu.crt1
)
elseif(LIBC_GPU_TARGET_ARCHITECTURE_IS_NVPTX)
add_subdirectory(nvptx)

add_startup_object(
crt1
ALIAS
DEPENDS
.nvptx.crt1
)
else()
# Skip building the startup code if there are no supported GPUs.
message(STATUS "Skipping startup for gpu target, no GPUs were detected")
return()
endif()

add_custom_target(libc-startup)
set(startup_components crt1)
foreach(target IN LISTS startup_components)
set(fq_target_name libc.startup.gpu.${target})
add_dependencies(libc-startup ${fq_target_name})
install(FILES $<TARGET_OBJECTS:${fq_target_name}>
DESTINATION ${CMAKE_INSTALL_LIBDIR}
RENAME $<TARGET_PROPERTY:${fq_target_name},OUTPUT_NAME>
COMPONENT libc)
endforeach()
17 changes: 17 additions & 0 deletions libc/startup/gpu/amdgpu/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
add_startup_object(
crt1
SRC
start.cpp
COMPILE_OPTIONS
-ffreestanding # To avoid compiler warnings about calling the main function.
-fno-builtin
-nogpulib # Do not include any GPU vendor libraries.
-nostdinc
-mcpu=${LIBC_GPU_TARGET_ARCHITECTURE}
-emit-llvm # AMDGPU's intermediate object file format is bitcode.
--target=${LIBC_GPU_TARGET_TRIPLE}
)
get_fq_target_name(crt1 fq_name)

# Ensure that clang uses the correct linker for this object type.
target_link_libraries(${fq_name} PUBLIC "--target=${LIBC_GPU_TARGET_TRIPLE}")
14 changes: 14 additions & 0 deletions libc/startup/gpu/amdgpu/start.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//===-- Implementation of crt for amdgpu ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

extern "C" int main(int argc, char **argv);

extern "C" [[gnu::visibility("protected"), clang::amdgpu_kernel]] void
_start(int argc, char **argv, int *ret) {
__atomic_fetch_or(ret, main(argc, argv), __ATOMIC_RELAXED);
}
17 changes: 17 additions & 0 deletions libc/startup/gpu/nvptx/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
add_startup_object(
crt1
SRC
start.cpp
COMPILE_OPTIONS
-ffreestanding # To avoid compiler warnings about calling the main function.
-fno-builtin
-nogpulib # Do not include any GPU vendor libraries.
-nostdinc
-x cuda # Use the CUDA toolchain to emit the `_start` kernel.
--offload-device-only
--offload-arch=${LIBC_GPU_TARGET_ARCHITECTURE}
)
get_fq_target_name(crt1 fq_name)

# Ensure that clang uses the correct linker for this object type.
target_link_libraries(${fq_name} PUBLIC "--target=${LIBC_GPU_TARGET_TRIPLE}")
15 changes: 15 additions & 0 deletions libc/startup/gpu/nvptx/start.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===-- Implementation of crt for amdgpu ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

extern "C" __attribute__((device)) int main(int argc, char **argv);

// TODO: We shouldn't need to use the CUDA language to emit a kernel for NVPTX.
extern "C" [[gnu::visibility("protected")]] __attribute__((global)) void
_start(int argc, char **argv, int *ret) {
__atomic_fetch_or(ret, main(argc, argv), __ATOMIC_RELAXED);
}

0 comments on commit fa34b9e

Please sign in to comment.