[libc-commits] [libc] 7ac8e26 - [libc] Implement `fseek`, `fflush`, and `ftell` on the GPU (#67160)

via libc-commits libc-commits at lists.llvm.org
Tue Sep 26 07:46:50 PDT 2023


Author: Joseph Huber
Date: 2023-09-26T09:46:46-05:00
New Revision: 7ac8e26fc7985c7b7a8e7f7ffd09984b12433cc2

URL: https://github.com/llvm/llvm-project/commit/7ac8e26fc7985c7b7a8e7f7ffd09984b12433cc2
DIFF: https://github.com/llvm/llvm-project/commit/7ac8e26fc7985c7b7a8e7f7ffd09984b12433cc2.diff

LOG: [libc] Implement `fseek`, `fflush`, and `ftell` on the GPU (#67160)

Summary:
This patch adds the necessary entrypoints to handle the `fseek`,
`fflush`, and `ftell` functions. These are all very straightfoward, we
simply make RPC calls to the associated function on the other end.
Implementing it this way allows us to more or less borrow the state of
the stream from the server as we intentionally maintain no internal
state on the GPU device. However, this does not implement the `errno`
functinality so that must be ignored.

Added: 
    libc/src/stdio/generic/fflush.cpp
    libc/src/stdio/generic/fseek.cpp
    libc/src/stdio/generic/ftell.cpp
    libc/src/stdio/gpu/fflush.cpp
    libc/src/stdio/gpu/fseek.cpp
    libc/src/stdio/gpu/ftell.cpp

Modified: 
    libc/config/gpu/entrypoints.txt
    libc/docs/gpu/support.rst
    libc/include/llvm-libc-types/rpc_opcodes_t.h
    libc/src/stdio/CMakeLists.txt
    libc/src/stdio/generic/CMakeLists.txt
    libc/src/stdio/gpu/CMakeLists.txt
    libc/utils/gpu/server/rpc_server.cpp

Removed: 
    libc/src/stdio/fflush.cpp
    libc/src/stdio/fseek.cpp
    libc/src/stdio/ftell.cpp


################################################################################
diff  --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index a50699c68f65bfa..4f24420d6d7c669 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -88,6 +88,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     # stdio.h entrypoints
     libc.src.stdio.feof
     libc.src.stdio.ferror
+    libc.src.stdio.fseek
+    libc.src.stdio.fflush
+    libc.src.stdio.ftell
     libc.src.stdio.clearerr
     libc.src.stdio.puts
     libc.src.stdio.fopen

diff  --git a/libc/docs/gpu/support.rst b/libc/docs/gpu/support.rst
index a19fca59270af05..81b17884a44023c 100644
--- a/libc/docs/gpu/support.rst
+++ b/libc/docs/gpu/support.rst
@@ -129,6 +129,9 @@ Function Name  Available  RPC Required
 feof           |check|    |check|
 ferror         |check|    |check|
 clearerr       |check|    |check|
+fseek          |check|    |check|
+ftell          |check|    |check|
+fflush         |check|    |check|
 fgetc          |check|    |check|
 fgets          |check|    |check|
 getc           |check|    |check|

diff  --git a/libc/include/llvm-libc-types/rpc_opcodes_t.h b/libc/include/llvm-libc-types/rpc_opcodes_t.h
index fb0f19cf505e8dc..77fa709466974d7 100644
--- a/libc/include/llvm-libc-types/rpc_opcodes_t.h
+++ b/libc/include/llvm-libc-types/rpc_opcodes_t.h
@@ -26,6 +26,9 @@ typedef enum : unsigned short {
   RPC_FEOF = 13,
   RPC_FERROR = 14,
   RPC_CLEARERR = 15,
+  RPC_FSEEK = 16,
+  RPC_FTELL = 17,
+  RPC_FFLUSH = 18,
 } rpc_opcode_t;
 
 #endif // __LLVM_LIBC_TYPES_RPC_OPCODE_H__

diff  --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index 9c24c567b6c1d5b..9146271898ffaa5 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -26,19 +26,6 @@ if(NOT LIBC_TARGET_ARCHITECTURE_IS_GPU)
   add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/generic)
 endif()
 
-add_entrypoint_object(
-  fflush
-  SRCS
-    fflush.cpp
-  HDRS
-    fflush.h
-  DEPENDS
-    libc.src.errno.errno
-    libc.include.stdio
-    libc.src.__support.File.file
-    libc.src.__support.File.platform_file
-)
-
 add_entrypoint_object(
   flockfile
   SRCS
@@ -63,19 +50,6 @@ add_entrypoint_object(
     libc.src.__support.File.platform_file
 )
 
-add_entrypoint_object(
-  fseek
-  SRCS
-    fseek.cpp
-  HDRS
-    fseek.h
-  DEPENDS
-    libc.src.errno.errno
-    libc.include.stdio
-    libc.src.__support.File.file
-    libc.src.__support.File.platform_file
-)
-
 add_entrypoint_object(
   ungetc
   SRCS
@@ -302,19 +276,6 @@ add_entrypoint_object(
 add_subdirectory(printf_core)
 add_subdirectory(scanf_core)
 
-add_entrypoint_object(
-  ftell
-  SRCS
-    ftell.cpp
-  HDRS
-    ftell.h
-  DEPENDS
-    libc.src.errno.errno
-    libc.include.stdio
-    libc.src.__support.File.file
-    libc.src.__support.File.platform_file
-)
-
 add_entrypoint_object(
   remove
   ALIAS
@@ -327,6 +288,9 @@ add_stdio_entrypoint_object(feof)
 add_stdio_entrypoint_object(feof_unlocked)
 add_stdio_entrypoint_object(ferror)
 add_stdio_entrypoint_object(ferror_unlocked)
+add_stdio_entrypoint_object(fseek)
+add_stdio_entrypoint_object(ftell)
+add_stdio_entrypoint_object(fflush)
 add_stdio_entrypoint_object(clearerr)
 add_stdio_entrypoint_object(clearerr_unlocked)
 add_stdio_entrypoint_object(fopen)

diff  --git a/libc/src/stdio/generic/CMakeLists.txt b/libc/src/stdio/generic/CMakeLists.txt
index b7a9b9b5747e2b4..f5f0c082dd48fd4 100644
--- a/libc/src/stdio/generic/CMakeLists.txt
+++ b/libc/src/stdio/generic/CMakeLists.txt
@@ -70,6 +70,45 @@ add_entrypoint_object(
     libc.src.__support.File.platform_file
 )
 
+add_entrypoint_object(
+  fflush
+  SRCS
+    fflush.cpp
+  HDRS
+    ../fflush.h
+  DEPENDS
+    libc.src.errno.errno
+    libc.include.stdio
+    libc.src.__support.File.file
+    libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+  fseek
+  SRCS
+    fseek.cpp
+  HDRS
+    ../fseek.h
+  DEPENDS
+    libc.src.errno.errno
+    libc.include.stdio
+    libc.src.__support.File.file
+    libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+  ftell
+  SRCS
+    ftell.cpp
+  HDRS
+    ftell.h
+  DEPENDS
+    libc.src.errno.errno
+    libc.include.stdio
+    libc.src.__support.File.file
+    libc.src.__support.File.platform_file
+)
+
 add_entrypoint_object(
   fopen
   SRCS

diff  --git a/libc/src/stdio/fflush.cpp b/libc/src/stdio/generic/fflush.cpp
similarity index 100%
rename from libc/src/stdio/fflush.cpp
rename to libc/src/stdio/generic/fflush.cpp

diff  --git a/libc/src/stdio/fseek.cpp b/libc/src/stdio/generic/fseek.cpp
similarity index 100%
rename from libc/src/stdio/fseek.cpp
rename to libc/src/stdio/generic/fseek.cpp

diff  --git a/libc/src/stdio/ftell.cpp b/libc/src/stdio/generic/ftell.cpp
similarity index 100%
rename from libc/src/stdio/ftell.cpp
rename to libc/src/stdio/generic/ftell.cpp

diff  --git a/libc/src/stdio/gpu/CMakeLists.txt b/libc/src/stdio/gpu/CMakeLists.txt
index c47176621144e39..047b68931bce5c3 100644
--- a/libc/src/stdio/gpu/CMakeLists.txt
+++ b/libc/src/stdio/gpu/CMakeLists.txt
@@ -32,6 +32,39 @@ add_entrypoint_object(
     libc.src.__support.RPC.rpc_client
 )
 
+add_entrypoint_object(
+  fseek
+  SRCS
+    fseek.cpp
+  HDRS
+    ../fseek.h
+  DEPENDS
+    libc.include.stdio
+    .gpu_file
+)
+
+add_entrypoint_object(
+  ftell
+  SRCS
+    ftell.cpp
+  HDRS
+    ../ftell.h
+  DEPENDS
+    libc.include.stdio
+    .gpu_file
+)
+
+add_entrypoint_object(
+  fflush
+  SRCS
+    fflush.cpp
+  HDRS
+    ../fflush.h
+  DEPENDS
+    libc.include.stdio
+    .gpu_file
+)
+
 add_entrypoint_object(
   clearerr
   SRCS

diff  --git a/libc/src/stdio/gpu/fflush.cpp b/libc/src/stdio/gpu/fflush.cpp
new file mode 100644
index 000000000000000..68192174e58a8ec
--- /dev/null
+++ b/libc/src/stdio/gpu/fflush.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of fflush ------------------------------------------===//
+//
+// 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/fflush.h"
+#include "file.h"
+
+#include <stdio.h>
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, fflush, (::FILE * stream)) {
+  int ret;
+  rpc::Client::Port port = rpc::client.open<RPC_FFLUSH>();
+  port.send_and_recv(
+      [=](rpc::Buffer *buffer) { buffer->data[0] = file::from_stream(stream); },
+      [&](rpc::Buffer *buffer) { ret = static_cast<int>(buffer->data[0]); });
+  port.close();
+  return ret;
+}
+
+} // namespace LIBC_NAMESPACE

diff  --git a/libc/src/stdio/gpu/fseek.cpp b/libc/src/stdio/gpu/fseek.cpp
new file mode 100644
index 000000000000000..3e93ddb46bf9757
--- /dev/null
+++ b/libc/src/stdio/gpu/fseek.cpp
@@ -0,0 +1,30 @@
+//===-- GPU implementation of fseek ---------------------------------------===//
+//
+// 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/fseek.h"
+#include "file.h"
+
+#include <stdio.h>
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, fseek, (::FILE * stream, long offset, int whence)) {
+  int ret;
+  rpc::Client::Port port = rpc::client.open<RPC_FSEEK>();
+  port.send_and_recv(
+      [=](rpc::Buffer *buffer) {
+        buffer->data[0] = file::from_stream(stream);
+        buffer->data[1] = static_cast<uint64_t>(offset);
+        buffer->data[2] = static_cast<uint64_t>(whence);
+      },
+      [&](rpc::Buffer *buffer) { ret = static_cast<int>(buffer->data[0]); });
+  port.close();
+  return ret;
+}
+
+} // namespace LIBC_NAMESPACE

diff  --git a/libc/src/stdio/gpu/ftell.cpp b/libc/src/stdio/gpu/ftell.cpp
new file mode 100644
index 000000000000000..aea3e8b229fce65
--- /dev/null
+++ b/libc/src/stdio/gpu/ftell.cpp
@@ -0,0 +1,26 @@
+//===-- GPU implementation of ftell ---------------------------------------===//
+//
+// 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/ftell.h"
+#include "file.h"
+
+#include <stdio.h>
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, ftell, (::FILE * stream)) {
+  long ret;
+  rpc::Client::Port port = rpc::client.open<RPC_FSEEK>();
+  port.send_and_recv(
+      [=](rpc::Buffer *buffer) { buffer->data[0] = file::from_stream(stream); },
+      [&](rpc::Buffer *buffer) { ret = static_cast<long>(buffer->data[0]); });
+  port.close();
+  return ret;
+}
+
+} // namespace LIBC_NAMESPACE

diff  --git a/libc/utils/gpu/server/rpc_server.cpp b/libc/utils/gpu/server/rpc_server.cpp
index fa6a4e324c0c281..6395a808ca98b00 100644
--- a/libc/utils/gpu/server/rpc_server.cpp
+++ b/libc/utils/gpu/server/rpc_server.cpp
@@ -164,6 +164,26 @@ struct Server {
       });
       break;
     }
+    case RPC_FSEEK: {
+      port->recv_and_send([](rpc::Buffer *buffer) {
+        buffer->data[0] = fseek(file::to_stream(buffer->data[0]),
+                                static_cast<long>(buffer->data[1]),
+                                static_cast<int>(buffer->data[2]));
+      });
+      break;
+    }
+    case RPC_FTELL: {
+      port->recv_and_send([](rpc::Buffer *buffer) {
+        buffer->data[0] = ftell(file::to_stream(buffer->data[0]));
+      });
+      break;
+    }
+    case RPC_FFLUSH: {
+      port->recv_and_send([](rpc::Buffer *buffer) {
+        buffer->data[0] = fflush(file::to_stream(buffer->data[0]));
+      });
+      break;
+    }
     case RPC_NOOP: {
       port->recv([](rpc::Buffer *) {});
       break;


        


More information about the libc-commits mailing list