-
Notifications
You must be signed in to change notification settings - Fork 11.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libc] Support 'assert.h' on the GPU
This patch adds the necessary support to provide `assert` functionality through the GPU `libc` implementation. This implementation creates a special-case GPU implementation rather than relying on the common version. This is because the GPU has special considerings for printing. The assertion is printed out in chunks with `write_to_stderr`, however when combined with the GPU execution model this causes 32+ threads to all execute in-lock step. Meaning that we'll get a horribly fragmented message. Furthermore, potentially thousands of threads could hit the assertion at once and try to print even if we had it all in one `printf`. This is solved by having a one-time lock that each thread group / wave / warp will attempt to claim. We only let one thread group pass through while the others simply stop executing. Finally only the first thread in that group will do the printing until we finally abort execution. Reviewed By: sivachandra Differential Revision: https://reviews.llvm.org/D159296
- Loading branch information
Showing
12 changed files
with
149 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
set(TARGET_PUBLIC_HEADERS | ||
libc.include.assert | ||
libc.include.ctype | ||
libc.include.string | ||
libc.include.inttypes | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,18 @@ | ||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) | ||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) | ||
else() | ||
add_subdirectory(generic) | ||
endif() | ||
|
||
if(TARGET libc.src.assert.${LIBC_TARGET_OS}.__assert_fail) | ||
set(assert_fail_dep libc.src.assert.${LIBC_TARGET_OS}.__assert_fail) | ||
else() | ||
set(assert_fail_dep libc.src.assert.generic.__assert_fail) | ||
endif() | ||
|
||
add_entrypoint_object( | ||
__assert_fail | ||
SRCS | ||
__assert_fail.cpp | ||
HDRS | ||
__assert_fail.h | ||
assert.h | ||
ALIAS | ||
DEPENDS | ||
libc.include.assert | ||
libc.src.__support.OSUtil.osutil | ||
libc.src.stdlib.abort | ||
${assert_fail_dep} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
add_entrypoint_object( | ||
__assert_fail | ||
SRCS | ||
__assert_fail.cpp | ||
HDRS | ||
../__assert_fail.h | ||
../assert.h | ||
DEPENDS | ||
libc.include.assert | ||
libc.src.__support.OSUtil.osutil | ||
libc.src.stdlib.abort | ||
) |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
add_entrypoint_object( | ||
__assert_fail | ||
SRCS | ||
__assert_fail.cpp | ||
HDRS | ||
../__assert_fail.h | ||
../assert.h | ||
DEPENDS | ||
libc.include.assert | ||
libc.src.__support.OSUtil.osutil | ||
libc.src.__support.GPU.utils | ||
libc.src.__support.CPP.atomic | ||
libc.src.stdlib.abort | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
//===-- GPU definition of a libc internal assert macro ----------*- C++ -*-===// | ||
// | ||
// 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "src/assert/__assert_fail.h" | ||
|
||
#include "src/__support/CPP/atomic.h" | ||
#include "src/__support/GPU/utils.h" | ||
#include "src/__support/libc_assert.h" | ||
#include "src/stdlib/abort.h" | ||
|
||
namespace __llvm_libc { | ||
|
||
// A single-use lock to allow only a single thread to print the assertion. | ||
static cpp::Atomic<uint32_t> lock = 0; | ||
|
||
LLVM_LIBC_FUNCTION(void, __assert_fail, | ||
(const char *assertion, const char *file, unsigned line, | ||
const char *function)) { | ||
uint64_t mask = gpu::get_lane_mask(); | ||
// We only want a single work group or warp to handle the assertion. Each | ||
// group attempts to claim the lock, if it is already claimed we simply exit. | ||
uint32_t claimed = gpu::is_first_lane(mask) | ||
? !lock.fetch_or(1, cpp::MemoryOrder::ACQUIRE) | ||
: 0; | ||
if (!gpu::broadcast_value(mask, claimed)) { | ||
#if defined(LIBC_TARGET_ARCH_IS_NVPTX) | ||
LIBC_INLINE_ASM("exit;" ::: "memory"); | ||
#elif defined(LIBC_TARGET_ARCH_IS_AMDGPU) | ||
__builtin_amdgcn_endpgm(); | ||
#endif | ||
__builtin_unreachable(); | ||
} | ||
|
||
// Only a single line should be printed if an assertion is hit. | ||
if (gpu::is_first_lane(mask)) | ||
__llvm_libc::report_assertion_failure(assertion, file, line, function); | ||
__llvm_libc::abort(); | ||
} | ||
|
||
} // namespace __llvm_libc |