-
Notifications
You must be signed in to change notification settings - Fork 11.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libc] Implement (v|f)printf on the GPU
Summary: This patch implements the `printf` family of functions on the GPU using the new variadic support. This patch adapts the old handling in the `rpc_fprintf` placeholder, but adds an extra RPC call to get the size of the buffer to copy. This prevents the GPU from needing to parse the string. While it's theoretically possible for the pass to know the size of the struct, it's prohibitively difficult to do while maintaining ABI compatibility with NVIDIA's varargs. Depends on #96015.
- Loading branch information
Showing
16 changed files
with
318 additions
and
67 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
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
File renamed without changes.
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
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,32 @@ | ||
//===-- GPU Implementation of fprintf -------------------------------------===// | ||
// | ||
// 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/stdio/fprintf.h" | ||
|
||
#include "src/__support/CPP/string_view.h" | ||
#include "src/__support/arg_list.h" | ||
#include "src/errno/libc_errno.h" | ||
#include "src/stdio/gpu/vfprintf_utils.h" | ||
|
||
#include <stdio.h> | ||
|
||
namespace LIBC_NAMESPACE { | ||
|
||
LLVM_LIBC_FUNCTION(int, fprintf, | ||
(::FILE *__restrict stream, const char *__restrict format, | ||
...)) { | ||
va_list vlist; | ||
va_start(vlist, format); | ||
cpp::string_view str_view(format); | ||
int ret_val = | ||
file::vfprintf_internal(stream, format, str_view.size() + 1, vlist); | ||
va_end(vlist); | ||
return ret_val; | ||
} | ||
|
||
} // namespace LIBC_NAMESPACE |
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,30 @@ | ||
//===-- GPU Implementation of printf --------------------------------------===// | ||
// | ||
// 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/stdio/printf.h" | ||
|
||
#include "src/__support/CPP/string_view.h" | ||
#include "src/__support/arg_list.h" | ||
#include "src/errno/libc_errno.h" | ||
#include "src/stdio/gpu/vfprintf_utils.h" | ||
|
||
#include <stdio.h> | ||
|
||
namespace LIBC_NAMESPACE { | ||
|
||
LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) { | ||
va_list vlist; | ||
va_start(vlist, format); | ||
cpp::string_view str_view(format); | ||
int ret_val = | ||
file::vfprintf_internal(stdout, format, str_view.size() + 1, vlist); | ||
va_end(vlist); | ||
return ret_val; | ||
} | ||
|
||
} // namespace LIBC_NAMESPACE |
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,29 @@ | ||
//===-- GPU Implementation of vfprintf ------------------------------------===// | ||
// | ||
// 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/stdio/vfprintf.h" | ||
|
||
#include "src/__support/CPP/string_view.h" | ||
#include "src/__support/arg_list.h" | ||
#include "src/errno/libc_errno.h" | ||
#include "src/stdio/gpu/vfprintf_utils.h" | ||
|
||
#include <stdio.h> | ||
|
||
namespace LIBC_NAMESPACE { | ||
|
||
LLVM_LIBC_FUNCTION(int, vfprintf, | ||
(::FILE *__restrict stream, const char *__restrict format, | ||
va_list vlist)) { | ||
cpp::string_view str_view(format); | ||
int ret_val = | ||
file::vfprintf_internal(stream, format, str_view.size() + 1, vlist); | ||
return ret_val; | ||
} | ||
|
||
} // namespace LIBC_NAMESPACE |
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,73 @@ | ||
//===--- GPU helper functions for printf using RPC ------------------------===// | ||
// | ||
// 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/__support/RPC/rpc_client.h" | ||
#include "src/__support/arg_list.h" | ||
#include "src/stdio/gpu/file.h" | ||
#include "src/string/string_utils.h" | ||
|
||
#include <stdio.h> | ||
|
||
namespace LIBC_NAMESPACE { | ||
namespace file { | ||
|
||
template <uint16_t opcode> | ||
LIBC_INLINE int vfprintf_impl(::FILE *__restrict file, | ||
const char *__restrict format, size_t format_size, | ||
va_list vlist) { | ||
uint64_t mask = gpu::get_lane_mask(); | ||
rpc::Client::Port port = rpc::client.open<opcode>(); | ||
|
||
if constexpr (opcode == RPC_PRINTF_TO_STREAM) { | ||
port.send([&](rpc::Buffer *buffer) { | ||
buffer->data[0] = reinterpret_cast<uintptr_t>(file); | ||
}); | ||
} | ||
|
||
size_t args_size = 0; | ||
port.send_n(format, format_size); | ||
port.recv([&](rpc::Buffer *buffer) { | ||
args_size = static_cast<size_t>(buffer->data[0]); | ||
}); | ||
port.send_n(vlist, args_size); | ||
|
||
uint32_t ret = 0; | ||
for (;;) { | ||
const char *str = nullptr; | ||
port.recv([&](rpc::Buffer *buffer) { | ||
ret = static_cast<uint32_t>(buffer->data[0]); | ||
str = reinterpret_cast<const char *>(buffer->data[1]); | ||
}); | ||
// If any lanes have a string argument it needs to be copied back. | ||
if (!gpu::ballot(mask, str)) | ||
break; | ||
|
||
uint64_t size = str ? internal::string_length(str) + 1 : 0; | ||
port.send_n(str, size); | ||
} | ||
|
||
port.close(); | ||
return ret; | ||
} | ||
|
||
LIBC_INLINE int vfprintf_internal(::FILE *__restrict stream, | ||
const char *__restrict format, | ||
size_t format_size, va_list vlist) { | ||
if (stream == stdout) | ||
return vfprintf_impl<RPC_PRINTF_TO_STDOUT>(stream, format, format_size, | ||
vlist); | ||
else if (stream == stderr) | ||
return vfprintf_impl<RPC_PRINTF_TO_STDERR>(stream, format, format_size, | ||
vlist); | ||
else | ||
return vfprintf_impl<RPC_PRINTF_TO_STREAM>(stream, format, format_size, | ||
vlist); | ||
} | ||
|
||
} // namespace file | ||
} // namespace LIBC_NAMESPACE |
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,28 @@ | ||
//===-- GPU Implementation of vprintf -------------------------------------===// | ||
// | ||
// 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/stdio/vprintf.h" | ||
|
||
#include "src/__support/CPP/string_view.h" | ||
#include "src/__support/arg_list.h" | ||
#include "src/errno/libc_errno.h" | ||
#include "src/stdio/gpu/vfprintf_utils.h" | ||
|
||
#include <stdio.h> | ||
|
||
namespace LIBC_NAMESPACE { | ||
|
||
LLVM_LIBC_FUNCTION(int, vprintf, | ||
(const char *__restrict format, va_list vlist)) { | ||
cpp::string_view str_view(format); | ||
int ret_val = | ||
file::vfprintf_internal(stdout, format, str_view.size() + 1, vlist); | ||
return ret_val; | ||
} | ||
|
||
} // namespace LIBC_NAMESPACE |
Oops, something went wrong.