https://github.com/RossBrunton created https://github.com/llvm/llvm-project/pull/147944
Looks up a global variable as a symbol >From de96f4311a866a3277086df3441c4c72a81970ce Mon Sep 17 00:00:00 2001 From: Ross Brunton <r...@codeplay.com> Date: Thu, 10 Jul 2025 12:53:30 +0100 Subject: [PATCH] [Offload] Add `olGetGlobalVariable` Looks up a global variable as a symbol --- offload/liboffload/API/Symbol.td | 15 +++++ offload/liboffload/src/OffloadImpl.cpp | 22 +++++++- offload/unittests/OffloadAPI/CMakeLists.txt | 3 + .../unittests/OffloadAPI/device_code/global.c | 1 + .../OffloadAPI/kernel/olLaunchKernel.cpp | 8 +++ .../OffloadAPI/symbol/olGetGlobalVariable.cpp | 56 +++++++++++++++++++ 6 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 offload/unittests/OffloadAPI/symbol/olGetGlobalVariable.cpp diff --git a/offload/liboffload/API/Symbol.td b/offload/liboffload/API/Symbol.td index cf4d45b09f035..68ccbc4e68c4b 100644 --- a/offload/liboffload/API/Symbol.td +++ b/offload/liboffload/API/Symbol.td @@ -15,5 +15,20 @@ def : Enum { let desc = "The kind of a symbol"; let etors =[ Etor<"KERNEL", "a kernel object">, + Etor<"GLOBAL_VARIABLE", "a global variable">, ]; } + +def : Function { + let name = "olGetGlobalVariable"; + let desc = "Get a global variable named `GlobalName` in the given program."; + let details = [ + "Symbol handles are owned by the program, so do not need to be destroyed." + ]; + let params = [ + Param<"ol_program_handle_t", "Program", "handle of the program", PARAM_IN>, + Param<"const char*", "GlobalName", "name of the global variable in the program", PARAM_IN>, + Param<"ol_symbol_handle_t*", "Global", "output pointer for the fetched global", PARAM_OUT> + ]; + let returns = []; +} diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp index fa5d18c044048..b4a545e013d6f 100644 --- a/offload/liboffload/src/OffloadImpl.cpp +++ b/offload/liboffload/src/OffloadImpl.cpp @@ -91,7 +91,9 @@ struct ol_program_impl_t { struct ol_symbol_impl_t { ol_symbol_impl_t(GenericKernelTy *Kernel) : PluginImpl(Kernel), Kind(OL_SYMBOL_KIND_KERNEL) {} - std::variant<GenericKernelTy *> PluginImpl; + ol_symbol_impl_t(GlobalTy &&Global) + : PluginImpl(Global), Kind(OL_SYMBOL_KIND_GLOBAL_VARIABLE) {} + std::variant<GenericKernelTy *, GlobalTy> PluginImpl; ol_symbol_kind_t Kind; }; @@ -726,5 +728,23 @@ Error olLaunchKernel_impl(ol_queue_handle_t Queue, ol_device_handle_t Device, return Error::success(); } +Error olGetGlobalVariable_impl(ol_program_handle_t Program, + const char *GlobalName, + ol_symbol_handle_t *Global) { + auto &Device = Program->Image->getDevice(); + + GlobalTy GlobalObj{GlobalName}; + if (auto Res = Device.Plugin.getGlobalHandler().getGlobalMetadataFromDevice( + Device, *Program->Image, GlobalObj)) + return Res; + + *Global = Program->Symbols + .emplace_back( + std::make_unique<ol_symbol_impl_t>(std::move(GlobalObj))) + .get(); + + return Error::success(); +} + } // namespace offload } // namespace llvm diff --git a/offload/unittests/OffloadAPI/CMakeLists.txt b/offload/unittests/OffloadAPI/CMakeLists.txt index 93e5fd2f6cd26..5d734df635cb4 100644 --- a/offload/unittests/OffloadAPI/CMakeLists.txt +++ b/offload/unittests/OffloadAPI/CMakeLists.txt @@ -41,3 +41,6 @@ add_offload_unittest("queue" queue/olDestroyQueue.cpp queue/olGetQueueInfo.cpp queue/olGetQueueInfoSize.cpp) + +add_offload_unittest("symbol" + symbol/olGetGlobalVariable.cpp) diff --git a/offload/unittests/OffloadAPI/device_code/global.c b/offload/unittests/OffloadAPI/device_code/global.c index b30e406fb98c7..9f27f9424324f 100644 --- a/offload/unittests/OffloadAPI/device_code/global.c +++ b/offload/unittests/OffloadAPI/device_code/global.c @@ -1,6 +1,7 @@ #include <gpuintrin.h> #include <stdint.h> +[[gnu::visibility("default")]] uint32_t global[64]; __gpu_kernel void write() { diff --git a/offload/unittests/OffloadAPI/kernel/olLaunchKernel.cpp b/offload/unittests/OffloadAPI/kernel/olLaunchKernel.cpp index acda4795edec2..cb77acf1bd21a 100644 --- a/offload/unittests/OffloadAPI/kernel/olLaunchKernel.cpp +++ b/offload/unittests/OffloadAPI/kernel/olLaunchKernel.cpp @@ -223,6 +223,14 @@ TEST_P(olLaunchKernelGlobalTest, Success) { ASSERT_SUCCESS(olMemFree(Mem)); } +TEST_P(olLaunchKernelGlobalTest, InvalidNotAKernel) { + ol_symbol_handle_t Global = nullptr; + ASSERT_SUCCESS(olGetGlobalVariable(Program, "global", &Global)); + ASSERT_ERROR( + OL_ERRC_SYMBOL_KIND, + olLaunchKernel(Queue, Device, Global, nullptr, 0, &LaunchArgs, nullptr)); +} + TEST_P(olLaunchKernelGlobalCtorTest, Success) { void *Mem; ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, diff --git a/offload/unittests/OffloadAPI/symbol/olGetGlobalVariable.cpp b/offload/unittests/OffloadAPI/symbol/olGetGlobalVariable.cpp new file mode 100644 index 0000000000000..e5600f399890b --- /dev/null +++ b/offload/unittests/OffloadAPI/symbol/olGetGlobalVariable.cpp @@ -0,0 +1,56 @@ +//===------- Offload API tests - olGetGlobalVariable ----------------------===// +// +// 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 "../common/Fixtures.hpp" +#include <OffloadAPI.h> +#include <gtest/gtest.h> + +struct olGetGlobalVariableTest : OffloadQueueTest { + void SetUp() override { + RETURN_ON_FATAL_FAILURE(OffloadQueueTest::SetUp()); + ASSERT_TRUE(TestEnvironment::loadDeviceBinary("global", Device, DeviceBin)); + ASSERT_GE(DeviceBin->getBufferSize(), 0lu); + ASSERT_SUCCESS(olCreateProgram(Device, DeviceBin->getBufferStart(), + DeviceBin->getBufferSize(), &Program)); + } + + void TearDown() override { + if (Program) { + olDestroyProgram(Program); + } + RETURN_ON_FATAL_FAILURE(OffloadQueueTest::TearDown()); + } + + std::unique_ptr<llvm::MemoryBuffer> DeviceBin; + ol_program_handle_t Program = nullptr; + ol_kernel_launch_size_args_t LaunchArgs{}; +}; +OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olGetGlobalVariableTest); + +TEST_P(olGetGlobalVariableTest, Success) { + ol_symbol_handle_t Global = nullptr; + ASSERT_SUCCESS(olGetGlobalVariable(Program, "global", &Global)); + ASSERT_NE(Global, nullptr); +} + +TEST_P(olGetGlobalVariableTest, InvalidNullProgram) { + ol_symbol_handle_t Global = nullptr; + ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE, + olGetGlobalVariable(nullptr, "global", &Global)); +} + +TEST_P(olGetGlobalVariableTest, InvalidNullGlobalPointer) { + ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER, + olGetGlobalVariable(Program, "global", nullptr)); +} + +TEST_P(olGetGlobalVariableTest, InvalidGlobalName) { + ol_symbol_handle_t Global = nullptr; + ASSERT_ERROR(OL_ERRC_NOT_FOUND, + olGetGlobalVariable(Program, "invalid_global", &Global)); +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits