[llvm] [offload][l0] Implement context groups and add actual L0 driver version to info (PR #217562)
Jan Trusiłło via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 02:39:41 PDT 2026
https://github.com/311Volt created https://github.com/llvm/llvm-project/pull/217562
Prior to the introduction of liboffload contexts, Level Zero devices under different driver instances used to each receive their own `L0ContextTy`s.
https://github.com/llvm/llvm-project/pull/209144 introduced contexts, which are designed to map to a single `ze_context` on L0. `olCreateContext` accepts a user-defined device list and is restricted to accept devices within a single platform. This restriction is insufficient for L0 - passing devices from different driver instances is allowed under this contract, but does not make sense on L0 as `zeContextCreate` needs a concrete driver instance as a parameter.
Introduce the concept of a "context group" - a set of devices that can be grouped in a single context. CUDA and AMDGPU plugins are restricted to a single context group, while L0 creates a distinct context group for each detected driver instance. A set of devices can share a context if and only if they have the same context group index (as obtained from the new DeviceInfo property `CONTEXT_GROUP_INDEX`).
Change libsycl to store multiple contexts inside of `PlatformImpl` and change relevant getters to add a device key. No changes are needed in `sycl-ls`.
As a semi-related fix, make the L0 plugin report the actual driver version for a device, as obtained by `zeDriverGetApiVersion`. The driver version is exposed as a raw decimal string.
Assisted-by: Codex (5.6 Sol)
>From a5ddfbc66c79c4467ff3378be843f4533b6222d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Trusi=C5=82=C5=82o?= <jan.trusillo at intel.com>
Date: Wed, 19 Aug 2026 15:17:21 +0000
Subject: [PATCH] implement context groups and add actual l0 driver ver to info
---
libsycl/src/detail/device_impl.hpp | 13 ++++++-
libsycl/src/detail/platform_impl.cpp | 30 +++++++++++-----
libsycl/src/detail/platform_impl.hpp | 13 +++----
libsycl/src/detail/queue_impl.cpp | 2 +-
.../device_selector/get_device_preference.cpp | 10 ++++++
libsycl/unittests/mock/helpers.cpp | 9 +++++
offload/liboffload/API/Context.td | 5 +--
offload/liboffload/API/Device.td | 3 ++
offload/liboffload/src/OffloadImpl.cpp | 20 +++++++++++
.../common/include/PluginInterface.h | 6 ++++
.../level_zero/dynamic_l0/L0DynWrapper.cpp | 1 +
.../level_zero/dynamic_l0/level_zero/ze_api.h | 17 ++++++++-
.../level_zero/include/L0Context.h | 5 +++
.../level_zero/include/L0Device.h | 4 +++
.../level_zero/include/L0Plugin.h | 4 +++
.../level_zero/src/L0Context.cpp | 2 +-
.../level_zero/src/L0Device.cpp | 14 ++------
.../level_zero/src/L0Plugin.cpp | 36 ++++++++++++++++---
.../OffloadAPI/common/Properties.hpp | 5 +++
.../OffloadAPI/device/olGetDeviceInfo.cpp | 13 +++++--
.../OffloadAPI/device/olGetDeviceInfoSize.cpp | 12 ++++++-
21 files changed, 183 insertions(+), 41 deletions(-)
diff --git a/libsycl/src/detail/device_impl.hpp b/libsycl/src/detail/device_impl.hpp
index f5012fe84c069..c057a07d2807d 100644
--- a/libsycl/src/detail/device_impl.hpp
+++ b/libsycl/src/detail/device_impl.hpp
@@ -44,7 +44,14 @@ class DeviceImpl {
/// All device impls must be created in corresponding platform ctor.
explicit DeviceImpl(ol_device_handle_t Device, PlatformImpl &Platform,
PrivateTag)
- : MOffloadDevice(Device), MPlatform(Platform) {}
+ : MOffloadDevice(Device), MPlatform(Platform) {
+ ol_result_t Res =
+ callNoCheck(olGetDeviceInfo, MOffloadDevice,
+ OL_DEVICE_INFO_CONTEXT_GROUP_INDEX,
+ sizeof(MContextGroupIndex), &MContextGroupIndex);
+ if (isFailed(Res))
+ MContextGroupIndex = 0;
+ }
~DeviceImpl() = default;
@@ -124,9 +131,13 @@ class DeviceImpl {
/// \return the corresponding liboffload device handle.
ol_device_handle_t getOLHandle() const { return MOffloadDevice; }
+ /// \return the context compatibility group this device belongs to.
+ uint32_t getContextGroupIndex() const { return MContextGroupIndex; }
+
private:
ol_device_handle_t MOffloadDevice = {};
PlatformImpl &MPlatform;
+ uint32_t MContextGroupIndex = 0;
};
} // namespace detail
diff --git a/libsycl/src/detail/platform_impl.cpp b/libsycl/src/detail/platform_impl.cpp
index 1d81b848a21d3..3e3b3f338ac03 100644
--- a/libsycl/src/detail/platform_impl.cpp
+++ b/libsycl/src/detail/platform_impl.cpp
@@ -16,6 +16,7 @@
#include <detail/platform_impl.hpp>
#include <algorithm>
+#include <map>
#include <memory>
_LIBSYCL_BEGIN_NAMESPACE_SYCL
@@ -93,13 +94,16 @@ PlatformImpl::PlatformImpl(ol_platform_handle_t Platform, size_t PlatformIndex,
Device, *this, DeviceImpl::PrivateTag{}));
});
- std::vector<DeviceImpl *> DeviceImpls;
- DeviceImpls.reserve(MRootDevices.size());
+ std::map<uint32_t, std::vector<DeviceImpl *>> GroupedDevices;
for (const auto &Device : MRootDevices)
- DeviceImpls.push_back(Device.get());
+ GroupedDevices[Device->getContextGroupIndex()].push_back(Device.get());
- MDefaultContext = ContextImpl::create(std::move(DeviceImpls),
- defaultAsyncHandler, property_list{});
+ MDefaultContexts.reserve(GroupedDevices.size());
+ for (auto &[GroupIdx, DeviceImpls] : GroupedDevices) {
+ MDefaultContexts.push_back(
+ {GroupIdx, ContextImpl::create(std::move(DeviceImpls),
+ defaultAsyncHandler, property_list{})});
+ }
}
const std::vector<DeviceImplUPtr> &PlatformImpl::getRootDevices() const {
@@ -144,10 +148,18 @@ void PlatformImpl::iterateDevices(
}
}
-ContextImpl &PlatformImpl::getDefaultContext() {
- assert(MDefaultContext &&
- "Default context for platform must be created in platform ctor");
- return *MDefaultContext.get();
+ContextImpl &PlatformImpl::getDefaultContext(const DeviceImpl &Device) {
+ assert(!MDefaultContexts.empty() &&
+ "Default contexts must be created in platform ctor");
+
+ uint32_t GroupIdx = Device.getContextGroupIndex();
+ for (auto &Entry : MDefaultContexts) {
+ if (Entry.ContextGroupIndex == GroupIdx)
+ return *Entry.Context;
+ }
+
+ assert(false && "No default context for device's context group");
+ __builtin_unreachable();
}
} // namespace detail
diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp
index 83ad3453ab765..af253ca61f23d 100644
--- a/libsycl/src/detail/platform_impl.hpp
+++ b/libsycl/src/detail/platform_impl.hpp
@@ -132,11 +132,8 @@ class PlatformImpl {
void iterateDevices(info::device_type DeviceType,
std::function<void(DeviceImpl *)> callback) const;
- // TODO: liboffload doesn't support context now, l0 plugin creates default
- // context for all devices on its level. This method should be removed or
- // reimplemented once native context support is added to liboffload.
- /// \return the default context that represents all devices in platform.
- ContextImpl &getDefaultContext();
+ /// \return the default context compatible with Device.
+ ContextImpl &getDefaultContext(const DeviceImpl &Device);
private:
/// \return reference to collection of root devices for platform
@@ -150,7 +147,11 @@ class PlatformImpl {
std::vector<DeviceImplUPtr> MRootDevices;
- std::shared_ptr<ContextImpl> MDefaultContext;
+ struct DefaultContextEntry {
+ uint32_t ContextGroupIndex;
+ std::shared_ptr<ContextImpl> Context;
+ };
+ std::vector<DefaultContextEntry> MDefaultContexts;
// Single initialization of platforms and devices doesn't allow to implement
// unittests for this behavior. This flag and friend class allows to force
diff --git a/libsycl/src/detail/queue_impl.cpp b/libsycl/src/detail/queue_impl.cpp
index bd76f2aaa2a6e..10c9183df022a 100644
--- a/libsycl/src/detail/queue_impl.cpp
+++ b/libsycl/src/detail/queue_impl.cpp
@@ -66,7 +66,7 @@ QueueImpl::QueueImpl(DeviceImpl &deviceImpl, const async_handler &asyncHandler,
const property_list &propList, PrivateTag)
: MIsInorder(false), MAsyncHandler(asyncHandler), MPropList(propList),
MDevice(deviceImpl),
- MContext(MDevice.getPlatformImpl().getDefaultContext()) {
+ MContext(MDevice.getPlatformImpl().getDefaultContext(MDevice)) {
assert(MContext.getOLHandleRef() &&
"Queue must be associated with a valid offload context");
callAndThrow(olCreateQueue, MContext.getOLHandleRef(), MDevice.getOLHandle(),
diff --git a/libsycl/unittests/device_selector/get_device_preference.cpp b/libsycl/unittests/device_selector/get_device_preference.cpp
index 79920b9611a10..f3c162215d258 100644
--- a/libsycl/unittests/device_selector/get_device_preference.cpp
+++ b/libsycl/unittests/device_selector/get_device_preference.cpp
@@ -49,6 +49,16 @@ class DeviceSelectorScoreTest : public ::testing::Test {
*static_cast<ol_platform_handle_t *>(PropValue) = Platform;
return OL_SUCCESS;
});
+
+ EXPECT_CALL(Helper.Mock.get(),
+ olGetDeviceInfo(_, OL_DEVICE_INFO_CONTEXT_GROUP_INDEX, _, _))
+ .WillRepeatedly([](ol_device_handle_t /*Device*/,
+ ol_device_info_t /*PropName*/, size_t PropSize,
+ void *PropValue) -> ol_result_t {
+ EXPECT_EQ(PropSize, sizeof(uint32_t));
+ *static_cast<uint32_t *>(PropValue) = 0;
+ return OL_SUCCESS;
+ });
}
void TearDown() override {
diff --git a/libsycl/unittests/mock/helpers.cpp b/libsycl/unittests/mock/helpers.cpp
index f12e8509f1dce..091b8cfba2bb9 100644
--- a/libsycl/unittests/mock/helpers.cpp
+++ b/libsycl/unittests/mock/helpers.cpp
@@ -113,6 +113,11 @@ void mock::MockLiboffload::initDefault() {
assignAs<ol_device_type_t>(PropValue, OL_DEVICE_TYPE_GPU);
return OL_SUCCESS;
}
+ case OL_DEVICE_INFO_CONTEXT_GROUP_INDEX: {
+ EXPECT_EQ(PropSize, sizeof(uint32_t));
+ assignAs<uint32_t>(PropValue, 0);
+ return OL_SUCCESS;
+ }
default:
ADD_FAILURE();
return makeEmptyStrError(OL_ERRC_UNIMPLEMENTED);
@@ -134,6 +139,10 @@ void mock::MockLiboffload::initDefault() {
*PropSizeRet = sizeof(ol_device_type_t);
return OL_SUCCESS;
}
+ case OL_DEVICE_INFO_CONTEXT_GROUP_INDEX: {
+ *PropSizeRet = sizeof(uint32_t);
+ return OL_SUCCESS;
+ }
default:
ADD_FAILURE();
return makeEmptyStrError(OL_ERRC_UNIMPLEMENTED);
diff --git a/offload/liboffload/API/Context.td b/offload/liboffload/API/Context.td
index 1b407265cd879..f2203c6645aaf 100644
--- a/offload/liboffload/API/Context.td
+++ b/offload/liboffload/API/Context.td
@@ -13,7 +13,8 @@
def olCreateContext : Function {
let desc = "Create a context grouping the given devices.";
let details = [
- "All devices must belong to the same platform.",
+ "All devices must belong to the same platform and context group (as reported by "
+ "`OL_DEVICE_INFO_CONTEXT_GROUP_INDEX`). Context groups typically correspond to a driver instance.",
"A context enables resource sharing between the devices it groups and "
"isolates those resources from other contexts: resources (such as memory "
"allocations) created within a context cannot be used outside of it.",
@@ -31,7 +32,7 @@ def olCreateContext : Function {
"`DevicesCount == 0`"
]>,
Return<"OL_ERRC_INVALID_DEVICE", [
- "the devices in `Devices` do not all belong to the same platform"
+ "the devices in `Devices` do not all belong to the same context group"
]>
];
}
diff --git a/offload/liboffload/API/Device.td b/offload/liboffload/API/Device.td
index cee053b1ff336..21c226784410f 100644
--- a/offload/liboffload/API/Device.td
+++ b/offload/liboffload/API/Device.td
@@ -57,6 +57,9 @@ def ol_device_info_t : Enum {
list<TaggedEtor> basic_etors2 =
[TaggedEtor<"COOPERATIVE_LAUNCH_SUPPORT", "bool",
"Is cooperative kernel launch supported">,
+ TaggedEtor<"CONTEXT_GROUP_INDEX", "uint32_t",
+ "Context group index; devices with the same value can be "
+ "grouped in a single context">,
];
let etors = !listconcat(basic_etors, fp_configs, native_vec_widths,
fp_support, basic_etors2);
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 48feac0b6c780..d4ecc78cb2caa 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -45,6 +45,7 @@ struct ol_platform_impl_t {
ol_platform_backend_t BackendType)
: BackendType(BackendType), Plugin(std::move(Plugin)) {}
ol_platform_backend_t BackendType;
+ uint32_t ContextGroupBase = 0;
/// Complete all pending work for this platform and perform any needed
/// cleanup.
@@ -77,6 +78,11 @@ struct ol_device_impl_t {
InfoTreeNode Info;
};
+static uint32_t getContextGroupIndex(ol_device_handle_t Device) {
+ return Device->Platform.ContextGroupBase +
+ Device->Device->getContextGroupOffset();
+}
+
llvm::Error ol_platform_impl_t::destroy() { return Plugin->deinit(); }
llvm::Error ol_platform_impl_t::init() {
@@ -333,6 +339,13 @@ Error initPlugins(OffloadContext &Context, const ol_init_args_t *InitArgs) {
return Err;
}
+ uint32_t CurCtxGroupBase = 0;
+ for (auto &Platform : Context.Platforms) {
+ Platform->ContextGroupBase = CurCtxGroupBase;
+ CurCtxGroupBase +=
+ Platform->Plugin ? Platform->Plugin->getNumContextGroups() : 1;
+ }
+
Context.TracingEnabled = std::getenv("OFFLOAD_TRACE");
Context.ValidationEnabled = !std::getenv("OFFLOAD_DISABLE_VALIDATION");
@@ -483,6 +496,9 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
return Info.write<uint64_t>(Mem);
} break;
+ case OL_DEVICE_INFO_CONTEXT_GROUP_INDEX:
+ return Info.write<uint32_t>(getContextGroupIndex(Device));
+
default:
break;
}
@@ -626,6 +642,10 @@ Error olCreateContext_impl(size_t DevicesCount, ol_device_handle_t *Devices,
return createOffloadError(
ErrorCode::INVALID_DEVICE,
"all devices in a context must belong to the same platform");
+ if (getContextGroupIndex(Devices[I]) != getContextGroupIndex(Devices[0]))
+ return createOffloadError(
+ ErrorCode::INVALID_DEVICE,
+ "all devices in a context must belong to the same context group");
DeviceList.push_back(Devices[I]);
PluginDevices.push_back(Devices[I]->Device);
}
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 30c79e28f2ea4..09cff34a1bd75 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -959,6 +959,9 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// this id is not unique between different plugins; they may overlap.
int32_t getDeviceId() const { return DeviceId; }
+ /// Get the index of the context group this device belongs to.
+ virtual uint32_t getContextGroupOffset() const { return 0; }
+
/// Get the unique identifier of the device.
const char *getDeviceUid() const { return DeviceUid.c_str(); }
@@ -1547,6 +1550,9 @@ struct GenericPluginTy {
/// Get the number of active devices.
int32_t getNumDevices() const { return NumDevices; }
+ /// Get the number of context groups supported by this plugin.
+ virtual uint32_t getNumContextGroups() const { return 1; }
+
/// Get the plugin-specific device identifier.
int32_t getUserId(int32_t DeviceId) const {
assert(UserDeviceIds.contains(DeviceId) && "No user-id registered");
diff --git a/offload/plugins-nextgen/level_zero/dynamic_l0/L0DynWrapper.cpp b/offload/plugins-nextgen/level_zero/dynamic_l0/L0DynWrapper.cpp
index 55e4b6b856a96..758d3cb1406c3 100644
--- a/offload/plugins-nextgen/level_zero/dynamic_l0/L0DynWrapper.cpp
+++ b/offload/plugins-nextgen/level_zero/dynamic_l0/L0DynWrapper.cpp
@@ -57,6 +57,7 @@ DLWRAP(zeDeviceGetMemoryProperties, 3)
DLWRAP(zeDeviceGetCacheProperties, 3)
DLWRAP(zeDeviceGetGlobalTimestamps, 3)
DLWRAP(zeDriverGetApiVersion, 2)
+DLWRAP(zeDriverGetProperties, 2)
DLWRAP(zeDriverGetExtensionFunctionAddress, 3)
DLWRAP(zeDriverGetExtensionProperties, 3)
DLWRAP(zeEventCreate, 3)
diff --git a/offload/plugins-nextgen/level_zero/dynamic_l0/level_zero/ze_api.h b/offload/plugins-nextgen/level_zero/dynamic_l0/level_zero/ze_api.h
index 4d8cf1e9367c0..2b760cfde4e12 100644
--- a/offload/plugins-nextgen/level_zero/dynamic_l0/level_zero/ze_api.h
+++ b/offload/plugins-nextgen/level_zero/dynamic_l0/level_zero/ze_api.h
@@ -334,11 +334,24 @@ typedef struct _ze_uuid_t {
uint8_t id[16];
} ze_uuid_t;
+/* Driver UUID size */
+#ifndef ZE_MAX_DRIVER_UUID_SIZE
+#define ZE_MAX_DRIVER_UUID_SIZE 16
+#endif
+
/* Driver UUID */
typedef struct _ze_driver_uuid_t {
- ze_uuid_t id;
+ uint8_t id[ZE_MAX_DRIVER_UUID_SIZE];
} ze_driver_uuid_t;
+/* Driver properties */
+typedef struct _ze_driver_properties_t {
+ ze_structure_type_t stype;
+ void *pNext;
+ ze_driver_uuid_t uuid;
+ uint32_t driverVersion;
+} ze_driver_properties_t;
+
/* Device UUID */
typedef struct _ze_device_uuid_t {
ze_uuid_t id;
@@ -666,6 +679,8 @@ ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverGet(uint32_t *pCount,
ze_driver_handle_t *phDrivers);
ZE_APIEXPORT ze_result_t ZE_APICALL
zeDriverGetApiVersion(ze_driver_handle_t hDriver, ze_api_version_t *version);
+ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverGetProperties(
+ ze_driver_handle_t hDriver, ze_driver_properties_t *pDriverProperties);
ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverGetExtensionFunctionAddress(
ze_driver_handle_t hDriver, const char *name, void **ppFunctionAddress);
ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverGetExtensionProperties(
diff --git a/offload/plugins-nextgen/level_zero/include/L0Context.h b/offload/plugins-nextgen/level_zero/include/L0Context.h
index 09a19702baa23..ff4ee162c9f0b 100644
--- a/offload/plugins-nextgen/level_zero/include/L0Context.h
+++ b/offload/plugins-nextgen/level_zero/include/L0Context.h
@@ -50,6 +50,9 @@ class L0ContextTy {
/// Level Zero Driver handle.
ze_driver_handle_t zeDriver = nullptr;
+ /// Context group index within the Level Zero plugin.
+ uint32_t ContextGroupIdx;
+
/// Common Level Zero context.
ze_context_handle_t zeContext = nullptr;
@@ -122,6 +125,8 @@ class L0ContextTy {
ze_driver_handle_t getZeDriver() const { return zeDriver; }
+ uint32_t getContextGroupIdx() const { return ContextGroupIdx; }
+
/// Return context associated with the driver.
ze_context_handle_t getZeContext() const { return zeContext; }
diff --git a/offload/plugins-nextgen/level_zero/include/L0Device.h b/offload/plugins-nextgen/level_zero/include/L0Device.h
index 84df2a2140446..5272dec2f02b4 100644
--- a/offload/plugins-nextgen/level_zero/include/L0Device.h
+++ b/offload/plugins-nextgen/level_zero/include/L0Device.h
@@ -185,6 +185,10 @@ class L0DeviceTy final : public GenericDeviceTy {
Error deinitImpl() override;
ze_device_handle_t getZeDevice() const { return zeDevice; }
+ uint32_t getContextGroupOffset() const override {
+ return L0Context.getContextGroupIdx();
+ }
+
bool supportsCooperativeKernels() const {
return QueueConfig.SupportsCooperativeKernels;
}
diff --git a/offload/plugins-nextgen/level_zero/include/L0Plugin.h b/offload/plugins-nextgen/level_zero/include/L0Plugin.h
index 82e47e052f339..81385ff5d0946 100644
--- a/offload/plugins-nextgen/level_zero/include/L0Plugin.h
+++ b/offload/plugins-nextgen/level_zero/include/L0Plugin.h
@@ -64,6 +64,8 @@ class LevelZeroPluginTy final : public GenericPluginTy {
struct DeviceInfoTy {
L0DeviceIdTy Id;
L0ContextTy *Driver;
+ uint32_t DriverVersion;
+ ze_driver_uuid_t DriverUuid;
bool isRoot() const { return Id.SubId < 0 && Id.CCSId < 0; }
};
llvm::SmallVector<DeviceInfoTy> DetectedDevices;
@@ -111,6 +113,8 @@ class LevelZeroPluginTy final : public GenericPluginTy {
uint16_t getMagicElfBits() const override { return ELF::EM_INTELGT; }
Triple::ArchType getTripleArch() const override { return Triple::spirv64; }
const char *getName() const override { return GETNAME(TARGET_NAME); }
+ uint32_t getNumContextGroups() const override { return ContextList.size(); }
+ std::string getDriverVersion(int32_t DeviceId) const;
Expected<bool> isELFCompatible(uint32_t DeviceId,
StringRef Image) const override;
diff --git a/offload/plugins-nextgen/level_zero/src/L0Context.cpp b/offload/plugins-nextgen/level_zero/src/L0Context.cpp
index cdcd1210cbcf1..62f4582469f9a 100644
--- a/offload/plugins-nextgen/level_zero/src/L0Context.cpp
+++ b/offload/plugins-nextgen/level_zero/src/L0Context.cpp
@@ -17,7 +17,7 @@ namespace llvm::omp::target::plugin {
L0ContextTy::L0ContextTy(LevelZeroPluginTy &Plugin, ze_driver_handle_t zeDriver,
int32_t DriverId)
- : Plugin(Plugin), zeDriver(zeDriver) {}
+ : Plugin(Plugin), zeDriver(zeDriver), ContextGroupIdx(DriverId) {}
L0ContextTy::~L0ContextTy() = default;
diff --git a/offload/plugins-nextgen/level_zero/src/L0Device.cpp b/offload/plugins-nextgen/level_zero/src/L0Device.cpp
index 08c45b534e16c..b09a3b4e49b13 100644
--- a/offload/plugins-nextgen/level_zero/src/L0Device.cpp
+++ b/offload/plugins-nextgen/level_zero/src/L0Device.cpp
@@ -428,12 +428,6 @@ const char *L0DeviceTy::getArchCStr() const {
}
}
-static const char *DriverVersionToStrTable[] = {
- "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6",
- "1.7", "1.8", "1.9", "1.10", "1.11", "1.12"};
-constexpr size_t DriverVersionToStrTableSize =
- sizeof(DriverVersionToStrTable) / sizeof(DriverVersionToStrTable[0]);
-
Expected<InfoTreeNode> L0DeviceTy::obtainInfoImpl() {
InfoTreeNode Info;
Info.add("Device Number", getDeviceId());
@@ -442,12 +436,8 @@ Expected<InfoTreeNode> L0DeviceTy::obtainInfoImpl() {
Info.add("Device Type", "GPU", "", DeviceInfo::TYPE);
Info.add("Vendor", "Intel", "", DeviceInfo::VENDOR);
Info.add("Vendor ID", getVendorId(), "", DeviceInfo::VENDOR_ID);
- auto DriverVersion = getDriverAPIVersion();
- if (DriverVersion < DriverVersionToStrTableSize)
- Info.add("Driver Version", DriverVersionToStrTable[DriverVersion], "",
- DeviceInfo::DRIVER_VERSION);
- else
- Info.add("Driver Version", "Unknown", "", DeviceInfo::DRIVER_VERSION);
+ Info.add("Driver Version", getPlugin().getDriverVersion(getDeviceId()), "",
+ DeviceInfo::DRIVER_VERSION);
Info.add("Device PCI ID", getPCIId());
Info.add("Device UUID", getUuid().data());
Info.add("Number of total EUs", getNumEUs(), "",
diff --git a/offload/plugins-nextgen/level_zero/src/L0Plugin.cpp b/offload/plugins-nextgen/level_zero/src/L0Plugin.cpp
index a8c3e522c36ba..fbbce836e7e3c 100644
--- a/offload/plugins-nextgen/level_zero/src/L0Plugin.cpp
+++ b/offload/plugins-nextgen/level_zero/src/L0Plugin.cpp
@@ -55,6 +55,8 @@ Expected<int32_t> LevelZeroPluginTy::findDevices() {
uint32_t OrderId;
ze_device_handle_t ZeDevice;
L0ContextTy *Driver;
+ uint32_t DriverVersion;
+ ze_driver_uuid_t DriverUuid;
bool IsDiscrete;
};
llvm::SmallVector<RootInfoTy> RootDevices;
@@ -70,8 +72,15 @@ Expected<int32_t> LevelZeroPluginTy::findDevices() {
<< ".";
continue;
}
+
+ ze_driver_properties_t DriverProperties{};
+ DriverProperties.stype = ZE_STRUCTURE_TYPE_DRIVER_PROPERTIES;
+ DriverProperties.pNext = nullptr;
+ CALL_ZE_RET_ERROR(zeDriverGetProperties, Driver, &DriverProperties);
+
// We have a driver that supports at least one device.
- ContextList.emplace_back(*this, Driver, DriverId);
+ ContextList.emplace_back(*this, Driver,
+ static_cast<int32_t>(ContextList.size()));
auto &DrvInfo = ContextList.back();
if (auto Err = DrvInfo.init()) {
// Remove the partially initialized context from the list
@@ -83,7 +92,8 @@ Expected<int32_t> LevelZeroPluginTy::findDevices() {
for (auto &zeDevice : FoundDevices)
RootDevices.push_back(
- {OrderId++, zeDevice, &DrvInfo, L0DeviceTy::isDiscrete(zeDevice)});
+ {OrderId++, zeDevice, &DrvInfo, DriverProperties.driverVersion,
+ DriverProperties.uuid, L0DeviceTy::isDiscrete(zeDevice)});
}
// Move discrete devices to the front.
@@ -103,8 +113,13 @@ Expected<int32_t> LevelZeroPluginTy::findDevices() {
for (size_t RootId = 0; RootId < RootDevices.size(); RootId++) {
const auto ZeDevice = RootDevices[RootId].ZeDevice;
auto *RootDriver = RootDevices[RootId].Driver;
- DetectedDevices.push_back(DeviceInfoTy{
- {ZeDevice, static_cast<int32_t>(RootId), -1, -1}, RootDriver});
+ auto DriverVersion = RootDevices[RootId].DriverVersion;
+ auto DriverUuid = RootDevices[RootId].DriverUuid;
+ DetectedDevices.push_back(
+ DeviceInfoTy{{ZeDevice, static_cast<int32_t>(RootId), -1, -1},
+ RootDriver,
+ DriverVersion,
+ DriverUuid});
}
int32_t NumDevices = DetectedDevices.size();
@@ -124,6 +139,19 @@ Expected<int32_t> LevelZeroPluginTy::findDevices() {
return NumDevices;
}
+std::string LevelZeroPluginTy::getDriverVersion(int32_t DeviceId) const {
+ assert(DeviceId >= 0 &&
+ static_cast<size_t>(DeviceId) < DetectedDevices.size());
+ const auto &DeviceInfo = DetectedDevices[DeviceId];
+
+ std::string Result;
+ llvm::raw_string_ostream OS(Result);
+ OS << DeviceInfo.DriverVersion << " (";
+ OS.write_uuid(DeviceInfo.DriverUuid.id);
+ OS << ")";
+ return OS.str();
+}
+
Expected<int32_t> LevelZeroPluginTy::initImpl() {
ODBG(OLDT_Init) << "Level0 NG plugin initialization";
// Process options before anything else.
diff --git a/offload/unittests/OffloadAPI/common/Properties.hpp b/offload/unittests/OffloadAPI/common/Properties.hpp
index 849f4ea05f29a..3be2bfe9dab21 100644
--- a/offload/unittests/OffloadAPI/common/Properties.hpp
+++ b/offload/unittests/OffloadAPI/common/Properties.hpp
@@ -98,6 +98,11 @@ inline const DeviceInfoProp PropUint32{
inline const DeviceInfoProperties Uint32Properties =
createPropertiesWithSizeContainer(sizeof(uint32_t), PropUint32);
+inline const DeviceInfoProp PropContextGroupIndex{
+ OL_DEVICE_INFO_CONTEXT_GROUP_INDEX};
+inline const DeviceInfoProperties ContextGroupIndexProperties =
+ createPropertiesWithSizeContainer(sizeof(uint32_t), PropContextGroupIndex);
+
inline const DeviceInfoProp PropUint64{
OL_DEVICE_INFO_MAX_MEM_ALLOC_SIZE, OL_DEVICE_INFO_GLOBAL_MEM_SIZE,
OL_DEVICE_INFO_WORK_GROUP_LOCAL_MEM_SIZE};
diff --git a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
index 18882c5af4818..e34749f111e0f 100644
--- a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
+++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
@@ -10,9 +10,9 @@
#include <OffloadAPI.h>
#include <gtest/gtest.h>
-DeviceInfoProperties JustSupportedProperties =
- mergeProperties({BoolProperties, IrrelevantForHostGTCapabilitiesProperties,
- IrrelevantForHostGTUint32Properties});
+DeviceInfoProperties JustSupportedProperties = mergeProperties(
+ {BoolProperties, IrrelevantForHostGTCapabilitiesProperties,
+ IrrelevantForHostGTUint32Properties, ContextGroupIndexProperties});
DeviceInfoProperties NonZeroProperties =
mergeProperties({RelevantGTCapabilitiesProperties,
@@ -91,6 +91,13 @@ TEST_P(olGetHostDeviceInfoTest, SuccessPlatform) {
ASSERT_NE(Platform, nullptr);
}
+TEST_P(olGetHostDeviceInfoTest, SuccessContextGroupIndex) {
+ uint32_t ContextGroupIndex = 0;
+ ASSERT_SUCCESS(olGetDeviceInfo(Device, OL_DEVICE_INFO_CONTEXT_GROUP_INDEX,
+ sizeof(ContextGroupIndex),
+ &ContextGroupIndex));
+}
+
TEST_P(olGetHostDeviceInfoTest, InvalidNullHandleDevice) {
ol_device_type_t DeviceType;
ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,
diff --git a/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp b/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp
index 82e0d36f027d9..4d7811ec8e64e 100644
--- a/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp
+++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp
@@ -17,7 +17,7 @@ using olGetDeviceInfoSizeNonZeroTest = olGetHostDeviceInfoPropertyTest;
DeviceInfoProperties answerSizeEqualToTypeSizeProperties = mergeProperties(
{Uint32Properties, Uint64Properties, CapabilitesFlagsProperties,
- PlatformProperties, DeviceTypeProperties});
+ PlatformProperties, DeviceTypeProperties, ContextGroupIndexProperties});
OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE_WITH_PARAM(
olGetDeviceInfoSizeEqualTest, answerSizeEqualToTypeSizeProperties,
@@ -55,6 +55,16 @@ TEST_P(olGetDeviceInfoSizeTest, SuccessMaxWorkSizePerDimension) {
ASSERT_EQ(Size, sizeof(uint32_t) * 3);
}
+TEST(olGetDeviceInfoSizeHostTest, SuccessContextGroupIndex) {
+ ol_device_handle_t Host = TestEnvironment::getHostDevice();
+ ASSERT_NE(Host, nullptr);
+
+ size_t Size = 0;
+ ASSERT_SUCCESS(
+ olGetDeviceInfoSize(Host, OL_DEVICE_INFO_CONTEXT_GROUP_INDEX, &Size));
+ ASSERT_EQ(Size, sizeof(uint32_t));
+}
+
TEST_P(olGetDeviceInfoSizeTest, InvalidNullHandle) {
size_t Size = 0;
ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,
More information about the llvm-commits
mailing list