[llvm] [flang][runtime] Debug PRINT *, "HI" on GPU (PR #172087)

Peter Klausler via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 12 13:38:26 PST 2025


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/172087

Decrease memory allocation for buffers, allocate the pseudo-unit only once on demand, and avoid using a "%*.s" format.

>From dbd762bdb1f9fa8b647d7a43039f6884caec21b7 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Wed, 3 Dec 2025 10:42:09 -0800
Subject: [PATCH] [flang][runtime] Debug PRINT *, "HI" on GPU

Decrease memory allocation for buffers, allocate the pseudo-unit
only once on demand, and avoid using a "%*.s" format.
---
 flang-rt/include/flang-rt/runtime/buffer.h |  9 +++++++--
 flang-rt/lib/runtime/pseudo-unit.cpp       | 23 +++++++++++-----------
 flang-rt/lib/runtime/unit.h                |  6 +++++-
 3 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/flang-rt/include/flang-rt/runtime/buffer.h b/flang-rt/include/flang-rt/runtime/buffer.h
index 4339213488e22..3c05e59be25cf 100644
--- a/flang-rt/include/flang-rt/runtime/buffer.h
+++ b/flang-rt/include/flang-rt/runtime/buffer.h
@@ -151,8 +151,13 @@ template <typename STORE, std::size_t minBuffer = 65536> class FileFrame {
       char *old{buffer_};
       auto oldSize{size_};
       size_ = std::max<std::int64_t>(bytes, size_ + minBuffer);
-      buffer_ =
-          reinterpret_cast<char *>(AllocateMemoryOrCrash(terminator, size_));
+      std::int64_t toAllocate{size_};
+#ifdef RT_USE_PSEUDO_FILE_UNIT
+      // PseudoOpenFile::Write() needs extra space for a NUL byte.
+      ++toAllocate;
+#endif
+      buffer_ = reinterpret_cast<char *>(
+          AllocateMemoryOrCrash(terminator, toAllocate));
       auto chunk{std::min<std::int64_t>(length_, oldSize - start_)};
       // "memcpy" in glibc has a "nonnull" attribute on the source pointer.
       // Avoid passing a null pointer, since it would result in an undefined
diff --git a/flang-rt/lib/runtime/pseudo-unit.cpp b/flang-rt/lib/runtime/pseudo-unit.cpp
index 8887ac681976f..ed5498ebecf95 100644
--- a/flang-rt/lib/runtime/pseudo-unit.cpp
+++ b/flang-rt/lib/runtime/pseudo-unit.cpp
@@ -36,10 +36,13 @@ ExternalFileUnit *ExternalFileUnit::LookUpOrCreate(
 
 ExternalFileUnit *ExternalFileUnit::LookUpOrCreateAnonymous(int unit,
     Direction direction, common::optional<bool>, IoErrorHandler &handler) {
-  if (direction != Direction::Output) {
-    handler.Crash("ExternalFileUnit only supports output IO");
+  if (direction != Direction::Output || unit != 6) {
+    handler.Crash("ExternalFileUnit only supports output to unit 6");
+  }
+  if (!defaultOutput) { // defer construction until/unless needed
+    defaultOutput = New<ExternalFileUnit>{handler}(unit).release();
   }
-  return New<ExternalFileUnit>{handler}(unit).release();
+  return defaultOutput;
 }
 
 ExternalFileUnit *ExternalFileUnit::LookUp(const char *, std::size_t) {
@@ -124,15 +127,11 @@ std::size_t PseudoOpenFile::Read(
 
 std::size_t PseudoOpenFile::Write(FileOffset at, const char *buffer,
     std::size_t bytes, IoErrorHandler &handler) {
-  if (at) {
-    handler.Crash("%s: unsupported", RT_PRETTY_FUNCTION);
-  }
-  // TODO: use persistent string buffer that can be reallocated
-  // as needed, and only freed at destruction of *this.
-  auto string{SizedNew<char>{handler}(bytes + 1)};
-  runtime::memcpy(string.get(), buffer, bytes);
-  string.get()[bytes] = '\0';
-  std::printf("%s", string.get());
+  char *mutableBuffer{const_cast<char *>(buffer)};
+  char save{buffer[bytes]};
+  mutableBuffer[bytes] = '\0';
+  std::printf("%s", buffer);
+  mutableBuffer[bytes] = save;
   return bytes;
 }
 
diff --git a/flang-rt/lib/runtime/unit.h b/flang-rt/lib/runtime/unit.h
index 7aeea0931e01a..bd4fc81c2f306 100644
--- a/flang-rt/lib/runtime/unit.h
+++ b/flang-rt/lib/runtime/unit.h
@@ -99,14 +99,18 @@ using FileFrameClass = FileFrame<ExternalFileUnit>;
 #else // defined(RT_USE_PSEUDO_FILE_UNIT)
 using OpenFileClass = PseudoOpenFile;
 // Use not so big buffer for the pseudo file unit frame.
-using FileFrameClass = FileFrame<ExternalFileUnit, 1024>;
+using FileFrameClass = FileFrame<ExternalFileUnit, 256>;
 #endif // defined(RT_USE_PSEUDO_FILE_UNIT)
 
 class ExternalFileUnit : public ConnectionState,
                          public OpenFileClass,
                          public FileFrameClass {
 public:
+#ifdef RT_USE_PSEUDO_FILE_UNIT
+  static constexpr int maxAsyncIds{64};
+#else
   static constexpr int maxAsyncIds{64 * 16};
+#endif
 
   explicit RT_API_ATTRS ExternalFileUnit(int unitNumber)
       : unitNumber_{unitNumber} {



More information about the llvm-commits mailing list