[llvm-branch-commits] [clang] [llvm] [Offload][Lang] Add -fgpu-default-stream support to LLVMOffloadingKernel (PR #218039)

Sophia Herrmann via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Aug 21 14:54:23 PDT 2026


https://github.com/jellytabby created https://github.com/llvm/llvm-project/pull/218039

To distinguish between legacy default and per-thread stream behavior, we introduce the `LLVMOffloadKernelPerThreadDefaultStream` variable which can be linked in based on the value of `-fgpu-default-stream`

Assisted by GPT-5.5, checked and reviewed manually.

Reopened due to a force-push mistake that made GitHub mark this PR as merged prematurely. 

>From 75c6e75ee6f9e8e94d80b1a82259a35bb3563df6 Mon Sep 17 00:00:00 2001
From: Sophia Herrmann <herrmann15 at llnl.gov>
Date: Thu, 13 Aug 2026 16:18:07 -0700
Subject: [PATCH] add PerThreadDefaultStream

---
 clang/lib/Driver/ToolChains/CommonArgs.cpp    |  5 ++++
 clang/test/Driver/cuda-via-liboffload.cu      | 14 ++++++++++
 offload/languages/kernel/CMakeLists.txt       | 28 +++++++++++++++++++
 offload/languages/kernel/exports              |  1 +
 .../kernel/src/PerThreadDefaultStream.cpp     | 12 ++++++++
 offload/languages/kernel/src/State.cpp        |  9 ++++--
 6 files changed, 66 insertions(+), 3 deletions(-)
 create mode 100644 offload/languages/kernel/src/PerThreadDefaultStream.cpp

diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index e1c07fb94ea76..1b655fea0bf24 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1499,6 +1499,11 @@ bool tools::addLLVMOffloadingRuntime(const Compilation &C,
                     options::OPT_fno_offload_via_llvm, false))
     return false;
 
+  if (const Arg *A = Args.getLastArg(options::OPT_fgpu_default_stream_EQ);
+      A && StringRef(A->getValue()) == "per-thread")
+    CmdArgs.push_back(Args.MakeArgString(
+        TC.GetFilePath("LLVMOffloadKernelPerThreadDefaultStream.o")));
+
   CmdArgs.push_back("-lLLVMOffloadKernel");
   return true;
 }
diff --git a/clang/test/Driver/cuda-via-liboffload.cu b/clang/test/Driver/cuda-via-liboffload.cu
index d30e529f0ce12..4543f1cfe6332 100644
--- a/clang/test/Driver/cuda-via-liboffload.cu
+++ b/clang/test/Driver/cuda-via-liboffload.cu
@@ -20,3 +20,17 @@
 // RUN: %clang -### -target x86_64-linux-gnu -ccc-print-bindings --offload-link -foffload-via-llvm %s 2>&1 | FileCheck -check-prefix DEVICE-LINK %s
 
 // DEVICE-LINK: "x86_64-unknown-linux-gnu" - "Offload::Linker", inputs: ["[[INPUT:.+]]"], output: "a.out"
+
+// RUN: %clang -### -target x86_64-linux-gnu -foffload-via-llvm \
+// RUN:        -fgpu-default-stream=per-thread --offload-arch=sm_35 %s 2>&1 \
+// RUN: | FileCheck -check-prefix PER-THREAD-DEFAULT-STREAM %s
+
+// PER-THREAD-DEFAULT-STREAM: LLVMOffloadKernelPerThreadDefaultStream.o
+// PER-THREAD-DEFAULT-STREAM: "-lLLVMOffloadKernel"
+
+// RUN: %clang -### -target x86_64-linux-gnu -foffload-via-llvm \
+// RUN:        -fgpu-default-stream=legacy --offload-arch=sm_35 %s 2>&1 \
+// RUN: | FileCheck -check-prefix LEGACY-DEFAULT-STREAM %s
+
+// LEGACY-DEFAULT-STREAM-NOT: LLVMOffloadKernelPerThreadDefaultStream.o
+// LEGACY-DEFAULT-STREAM: "-lLLVMOffloadKernel"
diff --git a/offload/languages/kernel/CMakeLists.txt b/offload/languages/kernel/CMakeLists.txt
index 92a051f06729e..52c269bed19c6 100644
--- a/offload/languages/kernel/CMakeLists.txt
+++ b/offload/languages/kernel/CMakeLists.txt
@@ -31,6 +31,30 @@ add_llvm_offload_kernel_language_runtime_objects(
 add_llvm_offload_kernel_language_runtime_objects(
   LLVMOffloadKernelHipRuntimeObjects hip)
 
+add_library(LLVMOffloadKernelPerThreadDefaultStreamObject OBJECT
+  src/PerThreadDefaultStream.cpp
+)
+target_compile_options(LLVMOffloadKernelPerThreadDefaultStreamObject
+  PRIVATE ${offload_compile_flags})
+set_target_properties(LLVMOffloadKernelPerThreadDefaultStreamObject PROPERTIES
+  POSITION_INDEPENDENT_CODE ON)
+
+set(LLVM_OFFLOAD_KERNEL_PER_THREAD_DEFAULT_STREAM_OBJECT
+  "${LLVM_LIBRARY_OUTPUT_INTDIR}/${OFFLOAD_TARGET_SUBDIR}/LLVMOffloadKernelPerThreadDefaultStream.o")
+add_custom_command(
+  OUTPUT ${LLVM_OFFLOAD_KERNEL_PER_THREAD_DEFAULT_STREAM_OBJECT}
+  COMMAND ${CMAKE_COMMAND} -E make_directory
+          "${LLVM_LIBRARY_OUTPUT_INTDIR}/${OFFLOAD_TARGET_SUBDIR}"
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different
+          $<TARGET_OBJECTS:LLVMOffloadKernelPerThreadDefaultStreamObject>
+          ${LLVM_OFFLOAD_KERNEL_PER_THREAD_DEFAULT_STREAM_OBJECT}
+  DEPENDS
+          LLVMOffloadKernelPerThreadDefaultStreamObject
+          $<TARGET_OBJECTS:LLVMOffloadKernelPerThreadDefaultStreamObject>
+  VERBATIM)
+add_custom_target(LLVMOffloadKernelPerThreadDefaultStream
+  DEPENDS ${LLVM_OFFLOAD_KERNEL_PER_THREAD_DEFAULT_STREAM_OBJECT})
+
 add_llvm_library(
   LLVMOffloadKernel SHARED
 
@@ -48,6 +72,7 @@ else()
   llvm_map_components_to_libnames(llvm_libs Support)
 endif()
 target_link_libraries(LLVMOffloadKernel PRIVATE ${llvm_libs} LLVMOffload)
+add_dependencies(LLVMOffloadKernel LLVMOffloadKernelPerThreadDefaultStream)
 
 if(LLVM_HAVE_LINK_VERSION_SCRIPT)
   target_link_libraries(LLVMOffloadKernel PRIVATE "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports")
@@ -74,6 +99,9 @@ install(TARGETS LLVMOffloadKernel
         RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
         LIBRARY DESTINATION "${OFFLOAD_INSTALL_LIBDIR}"
         ARCHIVE DESTINATION "${OFFLOAD_INSTALL_LIBDIR}")
+install(FILES ${LLVM_OFFLOAD_KERNEL_PER_THREAD_DEFAULT_STREAM_OBJECT}
+        DESTINATION "${OFFLOAD_INSTALL_LIBDIR}"
+        COMPONENT offload)
 
 install(FILES
         ${CMAKE_CURRENT_SOURCE_DIR}/../include/kernel/DefineLanguageNames.inc
diff --git a/offload/languages/kernel/exports b/offload/languages/kernel/exports
index d58962564c008..10fdab6df696d 100644
--- a/offload/languages/kernel/exports
+++ b/offload/languages/kernel/exports
@@ -10,6 +10,7 @@ VERS1.0 {
     __llvmRegisterManagedVar;
     __llvmRegisterSurface;
     __llvmRegisterTexture;
+    LLVMOffloadingPerThreadDefaultStream;
     __tgt_register_lib;
     __tgt_unregister_lib;
   local:
diff --git a/offload/languages/kernel/src/PerThreadDefaultStream.cpp b/offload/languages/kernel/src/PerThreadDefaultStream.cpp
new file mode 100644
index 0000000000000..1ebe7e4652363
--- /dev/null
+++ b/offload/languages/kernel/src/PerThreadDefaultStream.cpp
@@ -0,0 +1,12 @@
+//===-- PerThreadDefaultStream.cpp - Default stream mode override ---------===//
+//
+// 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 <cstdint>
+
+// Linked exactly once by the driver for -fgpu-default-stream=per-thread.
+extern "C" uint32_t LLVMOffloadingPerThreadDefaultStream = 1;
diff --git a/offload/languages/kernel/src/State.cpp b/offload/languages/kernel/src/State.cpp
index 573d6584f029d..6cc78330c0c84 100644
--- a/offload/languages/kernel/src/State.cpp
+++ b/offload/languages/kernel/src/State.cpp
@@ -26,8 +26,11 @@
 using namespace llvm;
 using namespace offload;
 
-// Weak so another runtime object can override the default stream mode.
-__attribute__((weak)) uint32_t PerThreadQueue = 0;
+// Weak fallback used unless the driver links the strong per-thread default
+// stream mode object for -fgpu-default-stream=per-thread.
+extern "C" {
+__attribute__((weak)) uint32_t LLVMOffloadingPerThreadDefaultStream = 0;
+}
 
 // Process-wide singleton and thread-state registry.
 static std::mutex &getStateLock() {
@@ -145,7 +148,7 @@ StreamTy *ThreadStateTy::getDefaultStream() {
   if (!Device)
     return nullptr;
 
-  if (!PerThreadQueue) [[likely]]
+  if (!LLVMOffloadingPerThreadDefaultStream) [[likely]]
     return StateTy::get().getOrCreateDefaultStream(Device);
 
   return ThreadStateTy::get().getOrCreateDefaultStream(Device);



More information about the llvm-branch-commits mailing list