[llvm] [OFFLOAD] Add support for host offloading device (PR #171010)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 21 09:17:57 PST 2026
https://github.com/fineg74 updated https://github.com/llvm/llvm-project/pull/171010
>From 8fb7fb823baa1f07b59fdd35256248eeafb19196 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Fri, 21 Nov 2025 18:35:24 -0800
Subject: [PATCH 1/6] Add support for host offloading device
---
offload/liboffload/API/Device.td | 9 +++++++++
offload/liboffload/src/OffloadImpl.cpp | 10 ++++++++--
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/offload/liboffload/API/Device.td b/offload/liboffload/API/Device.td
index 6ada191089674..79ad077b945e2 100644
--- a/offload/liboffload/API/Device.td
+++ b/offload/liboffload/API/Device.td
@@ -131,3 +131,12 @@ def olGetDeviceInfoSize : Function {
Return<"OL_ERRC_INVALID_DEVICE">
];
}
+
+def olGetHostDevice : Function {
+ let desc = "Returns the host device.";
+ let details = [];
+ let params = [
+ Param<"ol_device_handle_t*", "Device", "handle of the device instance", PARAM_OUT>,
+ ];
+ let returns = [];
+}
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index eab9627217ca8..0765949280b04 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -263,6 +263,8 @@ constexpr ol_platform_backend_t pluginNameToBackend(StringRef Name) {
return OL_PLATFORM_BACKEND_AMDGPU;
} else if (Name == "cuda") {
return OL_PLATFORM_BACKEND_CUDA;
+ } else if (Name == "host") {
+ return OL_PLATFORM_BACKEND_HOST;
} else {
return OL_PLATFORM_BACKEND_UNKNOWN;
}
@@ -276,7 +278,6 @@ Error initPlugins(OffloadContext &Context) {
// Attempt to create an instance of each supported plugin.
#define PLUGIN_TARGET(Name) \
do { \
- if (StringRef(#Name) != "host") \
Context.Platforms.emplace_back(std::make_unique<ol_platform_impl_t>( \
std::unique_ptr<GenericPluginTy>(createPlugin_##Name()), \
pluginNameToBackend(#Name))); \
@@ -349,7 +350,7 @@ Error olGetPlatformInfoImplDetail(ol_platform_handle_t Platform,
ol_platform_info_t PropName, size_t PropSize,
void *PropValue, size_t *PropSizeRet) {
InfoWriter Info(PropSize, PropValue, PropSizeRet);
- bool IsHost = Platform->BackendType == OL_PLATFORM_BACKEND_HOST;
+ bool IsHost = Platform->Plugin == nullptr;
// Note that the plugin is potentially uninitialized here. It will need to be
// initialized once info is added that requires it to be initialized.
@@ -1214,5 +1215,10 @@ Error olLaunchHostFunction_impl(ol_queue_handle_t Queue,
Queue->AsyncInfo);
}
+Error olGetHostDevice_impl(ol_device_handle_t *Device) {
+ *Device = OffloadContext::get().HostDevice;
+ return Error::success();
+}
+
} // namespace offload
} // namespace llvm
>From dc8f4748025bfd68c5bc7886f772b80e60c69a7d Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Wed, 10 Dec 2025 13:50:55 -0800
Subject: [PATCH 2/6] Fix formatting issues
---
offload/liboffload/src/OffloadImpl.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 0765949280b04..0766b235e1451 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -278,9 +278,9 @@ Error initPlugins(OffloadContext &Context) {
// Attempt to create an instance of each supported plugin.
#define PLUGIN_TARGET(Name) \
do { \
- Context.Platforms.emplace_back(std::make_unique<ol_platform_impl_t>( \
- std::unique_ptr<GenericPluginTy>(createPlugin_##Name()), \
- pluginNameToBackend(#Name))); \
+ Context.Platforms.emplace_back(std::make_unique<ol_platform_impl_t>( \
+ std::unique_ptr<GenericPluginTy>(createPlugin_##Name()), \
+ pluginNameToBackend(#Name))); \
} while (false);
#include "Shared/Targets.def"
>From 554af110573c9cef8e7e2ca692822ecea4f46ed6 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Wed, 10 Dec 2025 14:16:37 -0800
Subject: [PATCH 3/6] Address PR comments
---
offload/liboffload/src/OffloadImpl.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 0766b235e1451..5d75ff047ee5b 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -299,6 +299,9 @@ Error initPlugins(OffloadContext &Context) {
.emplace_back(std::make_unique<ol_device_impl_t>(
-1, nullptr, *HostPlatform, InfoTreeNode{}))
.get();
+ if (!Context.HostDevice)
+ return createOffloadError(ErrorCode::INVALID_NULL_HANDLE,
+ "Host Device is invalid");
Context.TracingEnabled = std::getenv("OFFLOAD_TRACE");
Context.ValidationEnabled = !std::getenv("OFFLOAD_DISABLE_VALIDATION");
>From 68953e0ae6e4e788d8cd01beb5920514a1336d6e Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Mon, 19 Jan 2026 13:47:14 -0800
Subject: [PATCH 4/6] Fix some unittest failures
---
offload/plugins-nextgen/host/src/rtl.cpp | 27 ++++++++++++++-----
.../OffloadAPI/common/Environment.cpp | 22 +++------------
2 files changed, 24 insertions(+), 25 deletions(-)
diff --git a/offload/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp
index 81fbb671aa88f..8f662b616993b 100644
--- a/offload/plugins-nextgen/host/src/rtl.cpp
+++ b/offload/plugins-nextgen/host/src/rtl.cpp
@@ -299,10 +299,8 @@ struct GenELF64DeviceTy : public GenericDeviceTy {
Error dataExchangeImpl(const void *SrcPtr, GenericDeviceTy &DstGenericDevice,
void *DstPtr, int64_t Size,
AsyncInfoWrapperTy &AsyncInfoWrapper) override {
- // This function should never be called because the function
- // GenELF64PluginTy::isDataExchangable() returns false.
- return Plugin::error(ErrorCode::UNSUPPORTED,
- "dataExchangeImpl not supported");
+ std::memcpy(DstPtr, SrcPtr, Size);
+ return Plugin::success();
}
/// Insert a data fence between previous data operations and the following
@@ -342,8 +340,7 @@ struct GenELF64DeviceTy : public GenericDeviceTy {
/// This plugin does not support interoperability
Error initAsyncInfoImpl(AsyncInfoWrapperTy &AsyncInfoWrapper) override {
- return Plugin::error(ErrorCode::UNSUPPORTED,
- "initAsyncInfoImpl not supported");
+ return Plugin::success();
}
Error enqueueHostCallImpl(void (*Callback)(void *), void *UserData,
@@ -379,6 +376,22 @@ struct GenELF64DeviceTy : public GenericDeviceTy {
Expected<InfoTreeNode> obtainInfoImpl() override {
InfoTreeNode Info;
Info.add("Device Type", "Generic-elf-64bit");
+ Info.add("Product Name", "Host", "", DeviceInfo::PRODUCT_NAME);
+ Info.add("Device Name", " Host Device", "", DeviceInfo::NAME);
+ Info.add("Max Group size", 1, "", DeviceInfo::MAX_WORK_GROUP_SIZE);
+ auto &MaxGroupSize =
+ *Info.add("Workgroup Max Size per Dimension", std::monostate{}, "",
+ DeviceInfo::MAX_WORK_GROUP_SIZE_PER_DIMENSION);
+ MaxGroupSize.add("x", 1);
+ MaxGroupSize.add("y", 1);
+ MaxGroupSize.add("z", 1);
+ Info.add("Maximum Grid Dimensions", 1,
+ "", DeviceInfo::MAX_WORK_SIZE);
+ auto &MaxSize = *Info.add("Grid Size per Dimension", std::monostate{}, "",
+ DeviceInfo::MAX_WORK_SIZE_PER_DIMENSION);
+ MaxSize.add("x", 1);
+ MaxSize.add("y", 1);
+ MaxSize.add("z", 1);
return Info;
}
@@ -472,7 +485,7 @@ struct GenELF64PluginTy final : public GenericPluginTy {
/// This plugin does not support exchanging data between two devices.
bool isDataExchangable(int32_t SrcDeviceId, int32_t DstDeviceId) override {
- return false;
+ return true;
}
/// All images (ELF-compatible) should be compatible with this plugin.
diff --git a/offload/unittests/OffloadAPI/common/Environment.cpp b/offload/unittests/OffloadAPI/common/Environment.cpp
index f8dcef6215bd9..cf43020348252 100644
--- a/offload/unittests/OffloadAPI/common/Environment.cpp
+++ b/offload/unittests/OffloadAPI/common/Environment.cpp
@@ -116,7 +116,9 @@ const std::vector<TestEnvironment::Device> &TestEnvironment::getDevices() {
ol_platform_backend_t Backend;
olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND,
sizeof(Backend), &Backend);
- if (Backend != OL_PLATFORM_BACKEND_HOST) {
+ ol_device_handle_t Host;
+ olGetHostDevice(&Host);
+ if (D != Host) {
auto *OutDevices = static_cast<decltype(Devices) *>(Data);
std::string Name;
raw_string_ostream NameStr(Name);
@@ -139,23 +141,7 @@ ol_device_handle_t TestEnvironment::getHostDevice() {
static ol_device_handle_t HostDevice = nullptr;
if (!HostDevice) {
- olIterateDevices(
- [](ol_device_handle_t D, void *Data) {
- ol_platform_handle_t Platform;
- olGetDeviceInfo(D, OL_DEVICE_INFO_PLATFORM, sizeof(Platform),
- &Platform);
- ol_platform_backend_t Backend;
- olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND, sizeof(Backend),
- &Backend);
-
- if (Backend == OL_PLATFORM_BACKEND_HOST) {
- *(static_cast<ol_device_handle_t *>(Data)) = D;
- return false;
- }
-
- return true;
- },
- &HostDevice);
+ olGetHostDevice(&HostDevice);
}
return HostDevice;
>From 92f703e4c7dcd00e856036b16c5e85e7d0ffde41 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Tue, 20 Jan 2026 18:07:39 -0800
Subject: [PATCH 5/6] Fix more unit tests
---
offload/plugins-nextgen/host/src/rtl.cpp | 27 +++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/offload/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp
index 8f662b616993b..5fe51172f13c4 100644
--- a/offload/plugins-nextgen/host/src/rtl.cpp
+++ b/offload/plugins-nextgen/host/src/rtl.cpp
@@ -374,10 +374,22 @@ struct GenELF64DeviceTy : public GenericDeviceTy {
/// Print information about the device.
Expected<InfoTreeNode> obtainInfoImpl() override {
+ constexpr auto uint32_max = std::numeric_limits<uint32_t>::max();
InfoTreeNode Info;
Info.add("Device Type", "Generic-elf-64bit");
Info.add("Product Name", "Host", "", DeviceInfo::PRODUCT_NAME);
- Info.add("Device Name", " Host Device", "", DeviceInfo::NAME);
+ Info.add("Vendor", "Unknown", "", DeviceInfo::VENDOR);
+ Info.add("Vendor ID", 1, "", DeviceInfo::VENDOR_ID);
+ Info.add("Device Name", " Host Offload Device", "", DeviceInfo::NAME);
+ Info.add("Driver Version", "Unknown", "", DeviceInfo::DRIVER_VERSION);
+ Info.add("Number of total EUs", 1, "", DeviceInfo::NUM_COMPUTE_UNITS);
+ Info.add("Max memory clock frequency (MHz)", 1, "", DeviceInfo::MEMORY_CLOCK_RATE);
+ Info.add("Max clock frequency (MHz)", 1, "", DeviceInfo::MAX_CLOCK_FREQUENCY);
+ Info.add("Memory Address Size", uint64_t{64u}, "bits",
+ DeviceInfo::ADDRESS_BITS);
+ Info.add("Local memory size (bytes)", 1, "", DeviceInfo::WORK_GROUP_LOCAL_MEM_SIZE);
+ Info.add("Global memory size (bytes)", 1, "", DeviceInfo::GLOBAL_MEM_SIZE);
+ Info.add("Max Memory Allocation Size (bytes)", 1, "", DeviceInfo::MAX_MEM_ALLOC_SIZE);
Info.add("Max Group size", 1, "", DeviceInfo::MAX_WORK_GROUP_SIZE);
auto &MaxGroupSize =
*Info.add("Workgroup Max Size per Dimension", std::monostate{}, "",
@@ -385,16 +397,21 @@ struct GenELF64DeviceTy : public GenericDeviceTy {
MaxGroupSize.add("x", 1);
MaxGroupSize.add("y", 1);
MaxGroupSize.add("z", 1);
- Info.add("Maximum Grid Dimensions", 1,
+ Info.add("Maximum Grid Dimensions", uint32_max,
"", DeviceInfo::MAX_WORK_SIZE);
auto &MaxSize = *Info.add("Grid Size per Dimension", std::monostate{}, "",
DeviceInfo::MAX_WORK_SIZE_PER_DIMENSION);
- MaxSize.add("x", 1);
- MaxSize.add("y", 1);
- MaxSize.add("z", 1);
+ MaxSize.add("x", uint32_max);
+ MaxSize.add("y", uint32_max);
+ MaxSize.add("z", uint32_max);
return Info;
}
+ Error getDeviceMemorySize(uint64_t &DSize) override {
+ DSize = 1;
+ return Plugin::success();
+ }
+
/// Getters and setters for stack size and heap size not relevant.
Error getDeviceStackSize(uint64_t &Value) override {
Value = 0;
>From 6071c88c396c755b128242d7a800921ef2a4ce99 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Wed, 21 Jan 2026 09:17:43 -0800
Subject: [PATCH 6/6] Fix formatting
---
offload/plugins-nextgen/host/src/rtl.cpp | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/offload/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp
index 5fe51172f13c4..aacb0e33c2430 100644
--- a/offload/plugins-nextgen/host/src/rtl.cpp
+++ b/offload/plugins-nextgen/host/src/rtl.cpp
@@ -383,24 +383,28 @@ struct GenELF64DeviceTy : public GenericDeviceTy {
Info.add("Device Name", " Host Offload Device", "", DeviceInfo::NAME);
Info.add("Driver Version", "Unknown", "", DeviceInfo::DRIVER_VERSION);
Info.add("Number of total EUs", 1, "", DeviceInfo::NUM_COMPUTE_UNITS);
- Info.add("Max memory clock frequency (MHz)", 1, "", DeviceInfo::MEMORY_CLOCK_RATE);
- Info.add("Max clock frequency (MHz)", 1, "", DeviceInfo::MAX_CLOCK_FREQUENCY);
+ Info.add("Max memory clock frequency (MHz)", 1, "",
+ DeviceInfo::MEMORY_CLOCK_RATE);
+ Info.add("Max clock frequency (MHz)", 1, "",
+ DeviceInfo::MAX_CLOCK_FREQUENCY);
Info.add("Memory Address Size", uint64_t{64u}, "bits",
- DeviceInfo::ADDRESS_BITS);
- Info.add("Local memory size (bytes)", 1, "", DeviceInfo::WORK_GROUP_LOCAL_MEM_SIZE);
+ DeviceInfo::ADDRESS_BITS);
+ Info.add("Local memory size (bytes)", 1, "",
+ DeviceInfo::WORK_GROUP_LOCAL_MEM_SIZE);
Info.add("Global memory size (bytes)", 1, "", DeviceInfo::GLOBAL_MEM_SIZE);
- Info.add("Max Memory Allocation Size (bytes)", 1, "", DeviceInfo::MAX_MEM_ALLOC_SIZE);
+ Info.add("Max Memory Allocation Size (bytes)", 1, "",
+ DeviceInfo::MAX_MEM_ALLOC_SIZE);
Info.add("Max Group size", 1, "", DeviceInfo::MAX_WORK_GROUP_SIZE);
auto &MaxGroupSize =
- *Info.add("Workgroup Max Size per Dimension", std::monostate{}, "",
- DeviceInfo::MAX_WORK_GROUP_SIZE_PER_DIMENSION);
+ *Info.add("Workgroup Max Size per Dimension", std::monostate{}, "",
+ DeviceInfo::MAX_WORK_GROUP_SIZE_PER_DIMENSION);
MaxGroupSize.add("x", 1);
MaxGroupSize.add("y", 1);
MaxGroupSize.add("z", 1);
- Info.add("Maximum Grid Dimensions", uint32_max,
- "", DeviceInfo::MAX_WORK_SIZE);
+ Info.add("Maximum Grid Dimensions", uint32_max, "",
+ DeviceInfo::MAX_WORK_SIZE);
auto &MaxSize = *Info.add("Grid Size per Dimension", std::monostate{}, "",
- DeviceInfo::MAX_WORK_SIZE_PER_DIMENSION);
+ DeviceInfo::MAX_WORK_SIZE_PER_DIMENSION);
MaxSize.add("x", uint32_max);
MaxSize.add("y", uint32_max);
MaxSize.add("z", uint32_max);
More information about the llvm-commits
mailing list