[libc-commits] [libc] [libc] Implement temporary `printf` on the GPU (PR #85331)
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Thu Mar 14 16:51:15 PDT 2024
================
@@ -20,13 +26,139 @@
#include <vector>
using namespace LIBC_NAMESPACE;
+using namespace LIBC_NAMESPACE::printf_core;
static_assert(sizeof(rpc_buffer_t) == sizeof(rpc::Buffer),
"Buffer size mismatch");
static_assert(RPC_MAXIMUM_PORT_COUNT == rpc::MAX_PORT_COUNT,
"Incorrect maximum port count");
+template <uint32_t lane_size> void handle_printf(rpc::Server::Port &port) {
+ FILE *files[lane_size] = {nullptr};
+ // Get the appropriate output stream to use.
+ if (port.get_opcode() == RPC_PRINTF_TO_STREAM)
+ port.recv([&](rpc::Buffer *buffer, uint32_t id) {
+ files[id] = reinterpret_cast<FILE *>(buffer->data[0]);
+ });
+ else if (port.get_opcode() == RPC_PRINTF_TO_STDOUT)
+ std::fill(files, files + lane_size, stdout);
+ else
+ std::fill(files, files + lane_size, stderr);
+
+ uint64_t format_sizes[lane_size] = {0};
+ void *format[lane_size] = {nullptr};
+
+ uint64_t args_sizes[lane_size] = {0};
+ void *args[lane_size] = {nullptr};
+
+ // Recieve the format string and arguments from the client.
+ port.recv_n(format, format_sizes,
+ [&](uint64_t size) { return new char[size]; });
+ port.recv_n(args, args_sizes, [&](uint64_t size) { return new char[size]; });
+
+ // Identify any arguments that are actually pointers to strings on the client.
+ // Additionally we want to determine how much buffer space we need to print.
+ std::vector<void *> strs_to_copy[lane_size];
+ int buffer_size[lane_size] = {0};
+ for (uint32_t lane = 0; lane < lane_size; ++lane) {
+ if (!format[lane])
+ continue;
+
+ WriteBuffer wb(nullptr, 0);
+ Writer writer(&wb);
+
+ internal::StructArgList printf_args(args[lane]);
+ Parser<internal::StructArgList> parser(
+ reinterpret_cast<const char *>(format[lane]), printf_args);
+
+ for (FormatSection cur_section = parser.get_next_section();
+ !cur_section.raw_string.empty();
+ cur_section = parser.get_next_section()) {
+ if (cur_section.has_conv && cur_section.conv_name == 's') {
+ strs_to_copy[lane].emplace_back(cur_section.conv_val_ptr);
+ } else if (cur_section.has_conv) {
+ convert(&writer, cur_section);
----------------
michaelrj-google wrote:
If it returns a negative number then you should return that value immediately, if possible. I don't think you'll actually run into any errors (there's a list of error values I've defined at the bottom of `printf_core/core_structs.h`) but if you do then something has gone seriously wrong.
https://github.com/llvm/llvm-project/pull/85331
More information about the libc-commits
mailing list