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

Joseph Huber via libc-commits libc-commits at lists.llvm.org
Fri Sep 22 09:00:58 PDT 2023


https://github.com/jhuber6 created https://github.com/llvm/llvm-project/pull/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.


>From c39a37771dc6bbf08a604e0f6f728d4fb2639e03 Mon Sep 17 00:00:00 2001
From: Joseph Huber <jhuber6 at vols.utk.edu>
Date: Wed, 20 Sep 2023 11:19:04 -0500
Subject: [PATCH] [libc] Implement `fseek`, `fflush`, and `ftell` on the GPU

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.
---
 libc/config/gpu/entrypoints.txt              |  3 ++
 libc/docs/gpu/support.rst                    |  3 ++
 libc/include/llvm-libc-types/rpc_opcodes_t.h |  3 ++
 libc/src/stdio/CMakeLists.txt                | 42 ++------------------
 libc/src/stdio/generic/CMakeLists.txt        | 39 ++++++++++++++++++
 libc/src/stdio/{ => generic}/fflush.cpp      |  0
 libc/src/stdio/{ => generic}/fseek.cpp       |  0
 libc/src/stdio/{ => generic}/ftell.cpp       |  0
 libc/src/stdio/gpu/CMakeLists.txt            | 33 +++++++++++++++
 libc/src/stdio/gpu/fflush.cpp                | 26 ++++++++++++
 libc/src/stdio/gpu/fseek.cpp                 | 30 ++++++++++++++
 libc/src/stdio/gpu/ftell.cpp                 | 26 ++++++++++++
 libc/test/src/stdio/CMakeLists.txt           |  4 +-
 libc/utils/gpu/server/rpc_server.cpp         | 20 ++++++++++
 14 files changed, 188 insertions(+), 41 deletions(-)
 rename libc/src/stdio/{ => generic}/fflush.cpp (100%)
 rename libc/src/stdio/{ => generic}/fseek.cpp (100%)
 rename libc/src/stdio/{ => generic}/ftell.cpp (100%)
 create mode 100644 libc/src/stdio/gpu/fflush.cpp
 create mode 100644 libc/src/stdio/gpu/fseek.cpp
 create mode 100644 libc/src/stdio/gpu/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 9895269767d0037..4b391d03253bc6b 100644
--- a/libc/include/llvm-libc-types/rpc_opcodes_t.h
+++ b/libc/include/llvm-libc-types/rpc_opcodes_t.h
@@ -25,6 +25,9 @@ typedef enum : unsigned short {
   RPC_FEOF = 12,
   RPC_FERROR = 13,
   RPC_CLEARERR = 14,
+  RPC_FSEEK = 15,
+  RPC_FTELL = 16,
+  RPC_FFLUSH = 17,
 } 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 f3a75fb965c6e16..e1af830863a9938 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
@@ -286,19 +260,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
@@ -311,6 +272,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..8a23e11e5fa0b39
--- /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 __llvm_libc {
+
+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 __llvm_libc
diff --git a/libc/src/stdio/gpu/fseek.cpp b/libc/src/stdio/gpu/fseek.cpp
new file mode 100644
index 000000000000000..657bdf5e0a5f190
--- /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 __llvm_libc {
+
+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 __llvm_libc
diff --git a/libc/src/stdio/gpu/ftell.cpp b/libc/src/stdio/gpu/ftell.cpp
new file mode 100644
index 000000000000000..be49e3ffdb6341a
--- /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 __llvm_libc {
+
+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 __llvm_libc
diff --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt
index 98fa2deb8b0e258..0496c074a6cdbeb 100644
--- a/libc/test/src/stdio/CMakeLists.txt
+++ b/libc/test/src/stdio/CMakeLists.txt
@@ -1,6 +1,6 @@
 add_custom_target(libc_stdio_unittests)
 
-add_libc_unittest(
+add_libc_test(
   fileop_test
   SUITE
     libc_stdio_unittests
@@ -399,7 +399,7 @@ add_libc_test(
     libc.src.stdio.fwrite
 )
 
-add_libc_unittest(
+add_libc_test(
   ftell_test
   SUITE
     libc_stdio_unittests
diff --git a/libc/utils/gpu/server/rpc_server.cpp b/libc/utils/gpu/server/rpc_server.cpp
index 7493ed66ceecb8c..9452650d4fcadda 100644
--- a/libc/utils/gpu/server/rpc_server.cpp
+++ b/libc/utils/gpu/server/rpc_server.cpp
@@ -160,6 +160,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