[libc-commits] [libc] 1e573f3 - [libc] Implement fopen, fclose, and fread on the GPU

Joseph Huber via libc-commits libc-commits at lists.llvm.org
Wed Aug 16 07:14:46 PDT 2023


Author: Joseph Huber
Date: 2023-08-16T09:14:38-05:00
New Revision: 1e573f378c52c69231a4e0fc3d06af3aaaedf5b8

URL: https://github.com/llvm/llvm-project/commit/1e573f378c52c69231a4e0fc3d06af3aaaedf5b8
DIFF: https://github.com/llvm/llvm-project/commit/1e573f378c52c69231a4e0fc3d06af3aaaedf5b8.diff

LOG: [libc] Implement fopen, fclose, and fread on the GPU

This patch implements the `fopen`, `fclose`, and `fread` functions on
the GPU. These are pretty much re-implemented from what existed but
using the new interface. Having this subset allows us to test the
interface a bit more strenuously since we can write and read to a file.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D157622

Added: 
    libc/src/stdio/generic/fclose.cpp
    libc/src/stdio/generic/fopen.cpp
    libc/src/stdio/generic/fread.cpp
    libc/src/stdio/generic/fread_unlocked.cpp
    libc/src/stdio/gpu/fclose.cpp
    libc/src/stdio/gpu/fopen.cpp
    libc/src/stdio/gpu/fread.cpp

Modified: 
    libc/config/gpu/entrypoints.txt
    libc/docs/gpu/support.rst
    libc/src/stdio/CMakeLists.txt
    libc/src/stdio/generic/CMakeLists.txt
    libc/src/stdio/gpu/CMakeLists.txt
    libc/src/stdio/gpu/file.h

Removed: 
    libc/src/stdio/fclose.cpp
    libc/src/stdio/fopen.cpp
    libc/src/stdio/fread.cpp
    libc/src/stdio/fread_unlocked.cpp


################################################################################
diff  --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index 8239bd0e877073..89ebe6df6a8c98 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -82,6 +82,9 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # stdio.h entrypoints
     libc.src.stdio.puts
+    libc.src.stdio.fopen
+    libc.src.stdio.fclose
+    libc.src.stdio.fread
     libc.src.stdio.fputs
     libc.src.stdio.stdin
     libc.src.stdio.stdout

diff  --git a/libc/docs/gpu/support.rst b/libc/docs/gpu/support.rst
index f172c9b0ec36ea..bc6daad1410bbd 100644
--- a/libc/docs/gpu/support.rst
+++ b/libc/docs/gpu/support.rst
@@ -124,6 +124,7 @@ Function Name  Available  RPC Required
 =============  =========  ============
 puts           |check|    |check|
 fputs          |check|    |check|
-fclose                    |check|
-fopen                     |check|
+fclose         |check|    |check|
+fopen          |check|    |check|
+fread          |check|    |check|
 =============  =========  ============

diff  --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index 91e7184e0f375b..a3548e7004e679 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -18,39 +18,16 @@ function(add_stdio_entrypoint_object name)
   endif()
 endfunction(add_stdio_entrypoint_object)
 
-add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/generic)
 if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
   add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+elseif(NOT LIBC_TARGET_ARCHITECTURE_IS_GPU)
+  add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/generic)
 endif()
 
+
 add_subdirectory(printf_core)
 add_subdirectory(scanf_core)
 
-add_entrypoint_object(
-  fopen
-  SRCS
-    fopen.cpp
-  HDRS
-    fopen.h
-  DEPENDS
-    libc.include.stdio
-    libc.src.__support.File.file
-    libc.src.__support.File.platform_file
-)
-
-add_entrypoint_object(
-  fclose
-  SRCS
-    fclose.cpp
-  HDRS
-    fclose.h
-  DEPENDS
-    libc.include.stdio
-    libc.src.errno.errno
-    libc.src.__support.File.file
-    libc.src.__support.File.platform_file
-)
-
 add_entrypoint_object(
   clearerr
   SRCS
@@ -251,32 +228,6 @@ add_entrypoint_object(
     libc.src.__support.File.platform_file
 )
 
-add_entrypoint_object(
-  fread_unlocked
-  SRCS
-    fread_unlocked.cpp
-  HDRS
-    fread_unlocked.h
-  DEPENDS
-    libc.src.errno.errno
-    libc.include.stdio
-    libc.src.__support.File.file
-    libc.src.__support.File.platform_file
-)
-
-add_entrypoint_object(
-  fread
-  SRCS
-    fread.cpp
-  HDRS
-    fread.h
-  DEPENDS
-    libc.src.errno.errno
-    libc.include.stdio
-    libc.src.__support.File.file
-    libc.src.__support.File.platform_file
-)
-
 add_entrypoint_object(
   fwrite_unlocked
   SRCS
@@ -568,6 +519,10 @@ add_entrypoint_object(
 )
 
 # These entrypoints have multiple potential implementations.
+add_stdio_entrypoint_object(fopen)
+add_stdio_entrypoint_object(fclose)
+add_stdio_entrypoint_object(fread_unlocked)
+add_stdio_entrypoint_object(fread)
 add_stdio_entrypoint_object(puts)
 add_stdio_entrypoint_object(fputs)
 add_stdio_entrypoint_object(stdin)

diff  --git a/libc/src/stdio/generic/CMakeLists.txt b/libc/src/stdio/generic/CMakeLists.txt
index 50220b2df5d8f6..e56660b52cafec 100644
--- a/libc/src/stdio/generic/CMakeLists.txt
+++ b/libc/src/stdio/generic/CMakeLists.txt
@@ -1,7 +1,53 @@
-if(LIBC_TARGET_ARCHITECTURE_IS_GPU)
-  # The GPU build cannot use any generic implementations.
-  return()
-endif()
+add_entrypoint_object(
+  fopen
+  SRCS
+    fopen.cpp
+  HDRS
+    ../fopen.h
+  DEPENDS
+    libc.include.stdio
+    libc.src.__support.File.file
+    libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+  fclose
+  SRCS
+    fclose.cpp
+  HDRS
+    ../fclose.h
+  DEPENDS
+    libc.include.stdio
+    libc.src.errno.errno
+    libc.src.__support.File.file
+    libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+  fread_unlocked
+  SRCS
+    fread_unlocked.cpp
+  HDRS
+    ../fread_unlocked.h
+  DEPENDS
+    libc.src.errno.errno
+    libc.include.stdio
+    libc.src.__support.File.file
+    libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+  fread
+  SRCS
+    fread.cpp
+  HDRS
+    ../fread.h
+  DEPENDS
+    libc.src.errno.errno
+    libc.include.stdio
+    libc.src.__support.File.file
+    libc.src.__support.File.platform_file
+)
 
 add_entrypoint_object(
   fputs

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

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

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

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

diff  --git a/libc/src/stdio/gpu/CMakeLists.txt b/libc/src/stdio/gpu/CMakeLists.txt
index f6795571c3164d..458dd86175021c 100644
--- a/libc/src/stdio/gpu/CMakeLists.txt
+++ b/libc/src/stdio/gpu/CMakeLists.txt
@@ -4,8 +4,39 @@ add_header_library(
     file.h
   DEPENDS
     libc.src.__support.common
-    libc.src.__support.CPP.string_view
-    libc.src.__support.RPC.rpc_client
+    .stdin
+    .stdout
+    .stderr
+)
+
+add_entrypoint_object(
+  fopen
+  SRCS
+    fopen.cpp
+  HDRS
+    ../fopen.h
+  DEPENDS
+    libc.include.stdio
+)
+
+add_entrypoint_object(
+  fclose
+  SRCS
+    fclose.cpp
+  HDRS
+    ../fclose.h
+  DEPENDS
+    libc.include.stdio
+)
+
+add_entrypoint_object(
+  fread
+  SRCS
+    fread.cpp
+  HDRS
+    ../fread.h
+  DEPENDS
+    libc.include.stdio
 )
 
 add_entrypoint_object(

diff  --git a/libc/src/stdio/gpu/fclose.cpp b/libc/src/stdio/gpu/fclose.cpp
new file mode 100644
index 00000000000000..a8e36bcb27c858
--- /dev/null
+++ b/libc/src/stdio/gpu/fclose.cpp
@@ -0,0 +1,29 @@
+//===-- GPU Implementation of fclose --------------------------------------===//
+//
+// 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/fclose.h"
+#include "src/stdio/gpu/file.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, fclose, (::FILE * stream)) {
+  uint64_t ret = 0;
+  uintptr_t file = reinterpret_cast<uintptr_t>(stream);
+  rpc::Client::Port port = rpc::client.open<RPC_CLOSE_FILE>();
+  port.send_and_recv([=](rpc::Buffer *buffer) { buffer->data[0] = file; },
+                     [&](rpc::Buffer *buffer) { ret = buffer->data[0]; });
+  port.close();
+
+  if (ret != 0)
+    return EOF;
+  return static_cast<int>(ret);
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/stdio/gpu/file.h b/libc/src/stdio/gpu/file.h
index c7b25592a30c4a..0ca1df8708a3f7 100644
--- a/libc/src/stdio/gpu/file.h
+++ b/libc/src/stdio/gpu/file.h
@@ -85,5 +85,12 @@ LIBC_INLINE uint64_t read_from_stream(uintptr_t file, void *buf, size_t size) {
   return ret;
 }
 
+LIBC_INLINE uint64_t read(FILE *f, void *data, size_t size) {
+  if (f == stdin)
+    return read_from_stdin(data, size);
+  else
+    return read_from_stream(reinterpret_cast<uintptr_t>(f), data, size);
+}
+
 } // namespace file
 } // namespace __llvm_libc

diff  --git a/libc/src/stdio/gpu/fopen.cpp b/libc/src/stdio/gpu/fopen.cpp
new file mode 100644
index 00000000000000..5d88b65e9f702d
--- /dev/null
+++ b/libc/src/stdio/gpu/fopen.cpp
@@ -0,0 +1,32 @@
+//===-- GPU Implementation of fopen ---------------------------------------===//
+//
+// 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/fopen.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/stdio/gpu/file.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(::FILE *, fopen,
+                   (const char *__restrict path, const char *__restrict mode)) {
+  uintptr_t file;
+  rpc::Client::Port port = rpc::client.open<RPC_OPEN_FILE>();
+  port.send_n(path, internal::string_length(path) + 1);
+  port.send_and_recv(
+      [=](rpc::Buffer *buffer) {
+        inline_memcpy(buffer->data, mode, internal::string_length(mode) + 1);
+      },
+      [&](rpc::Buffer *buffer) { file = buffer->data[0]; });
+  port.close();
+
+  return reinterpret_cast<FILE *>(file);
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/stdio/gpu/fread.cpp b/libc/src/stdio/gpu/fread.cpp
new file mode 100644
index 00000000000000..2b9112ee50eb39
--- /dev/null
+++ b/libc/src/stdio/gpu/fread.cpp
@@ -0,0 +1,25 @@
+//===-- GPU Implementation of fread ---------------------------------------===//
+//
+// 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/fread.h"
+#include "src/stdio/gpu/file.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(size_t, fread,
+                   (void *__restrict buffer, size_t size, size_t nmemb,
+                    ::FILE *stream)) {
+  if (size == 0 || nmemb == 0)
+    return 0;
+  auto result = file::read(stream, buffer, size * nmemb);
+  return result / size;
+}
+
+} // namespace __llvm_libc


        


More information about the libc-commits mailing list