Skip to content

Commit f1afe8d

Browse files
authored
Merge pull request #2017 from nrspruit/new_sysman_init
[L0] Use zesInit for SysMan API usage
2 parents f47ae95 + 3872c8e commit f1afe8d

File tree

5 files changed

+142
-25
lines changed

5 files changed

+142
-25
lines changed

source/adapters/level_zero/adapter.cpp

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,32 @@ class ur_legacy_sink : public logger::Sink {
5252
};
5353
};
5454

55-
ur_result_t initPlatforms(PlatformVec &platforms) noexcept try {
55+
// Find the corresponding ZesDevice Handle for a given ZeDevice
56+
ur_result_t getZesDeviceHandle(zes_uuid_t coreDeviceUuid,
57+
zes_device_handle_t *ZesDevice,
58+
uint32_t *SubDeviceId, ze_bool_t *SubDevice) {
59+
uint32_t ZesDriverCount = 0;
60+
std::vector<zes_driver_handle_t> ZesDrivers;
61+
std::vector<zes_device_handle_t> ZesDevices;
62+
ze_result_t ZesResult = ZE_RESULT_ERROR_INVALID_ARGUMENT;
63+
ZE2UR_CALL(GlobalAdapter->getSysManDriversFunctionPtr,
64+
(&ZesDriverCount, nullptr));
65+
ZesDrivers.resize(ZesDriverCount);
66+
ZE2UR_CALL(GlobalAdapter->getSysManDriversFunctionPtr,
67+
(&ZesDriverCount, ZesDrivers.data()));
68+
for (uint32_t I = 0; I < ZesDriverCount; ++I) {
69+
ZesResult = ZE_CALL_NOCHECK(
70+
GlobalAdapter->getDeviceByUUIdFunctionPtr,
71+
(ZesDrivers[I], coreDeviceUuid, ZesDevice, SubDevice, SubDeviceId));
72+
if (ZesResult == ZE_RESULT_SUCCESS) {
73+
return UR_RESULT_SUCCESS;
74+
}
75+
}
76+
return UR_RESULT_ERROR_INVALID_ARGUMENT;
77+
}
78+
79+
ur_result_t initPlatforms(PlatformVec &platforms,
80+
ze_result_t ZesResult) noexcept try {
5681
uint32_t ZeDriverCount = 0;
5782
ZE2UR_CALL(zeDriverGet, (&ZeDriverCount, nullptr));
5883
if (ZeDriverCount == 0) {
@@ -65,24 +90,43 @@ ur_result_t initPlatforms(PlatformVec &platforms) noexcept try {
6590

6691
ZE2UR_CALL(zeDriverGet, (&ZeDriverCount, ZeDrivers.data()));
6792
for (uint32_t I = 0; I < ZeDriverCount; ++I) {
93+
// Keep track of the first platform init for this Driver
94+
bool DriverPlatformInit = false;
6895
ze_device_properties_t device_properties{};
6996
device_properties.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES;
7097
uint32_t ZeDeviceCount = 0;
7198
ZE2UR_CALL(zeDeviceGet, (ZeDrivers[I], &ZeDeviceCount, nullptr));
7299
ZeDevices.resize(ZeDeviceCount);
73100
ZE2UR_CALL(zeDeviceGet, (ZeDrivers[I], &ZeDeviceCount, ZeDevices.data()));
101+
auto platform = std::make_unique<ur_platform_handle_t_>(ZeDrivers[I]);
74102
// Check if this driver has GPU Devices
75103
for (uint32_t D = 0; D < ZeDeviceCount; ++D) {
76104
ZE2UR_CALL(zeDeviceGetProperties, (ZeDevices[D], &device_properties));
77-
78105
if (ZE_DEVICE_TYPE_GPU == device_properties.type) {
79-
// If this Driver is a GPU, save it as a usable platform.
80-
auto platform = std::make_unique<ur_platform_handle_t_>(ZeDrivers[I]);
81-
UR_CALL(platform->initialize());
82-
83-
// Save a copy in the cache for future uses.
84-
platforms.push_back(std::move(platform));
85-
break;
106+
// Check if this driver's platform has already been init.
107+
if (!DriverPlatformInit) {
108+
// If this Driver is a GPU, save it as a usable platform.
109+
UR_CALL(platform->initialize());
110+
111+
// Save a copy in the cache for future uses.
112+
platforms.push_back(std::move(platform));
113+
// Mark this driver's platform as init to prevent additional platforms
114+
// from being created per driver.
115+
DriverPlatformInit = true;
116+
}
117+
if (ZesResult == ZE_RESULT_SUCCESS) {
118+
// Populate the Zes/Ze device mapping for this Ze Device into the last
119+
// added platform which represents the current driver being queried.
120+
ur_zes_device_handle_data_t ZesDeviceData;
121+
zes_uuid_t ZesUUID;
122+
std::memcpy(&ZesUUID, &device_properties.uuid, sizeof(zes_uuid_t));
123+
if (getZesDeviceHandle(
124+
ZesUUID, &ZesDeviceData.ZesDevice, &ZesDeviceData.SubDeviceId,
125+
&ZesDeviceData.SubDevice) == UR_RESULT_SUCCESS) {
126+
platforms.back()->ZedeviceToZesDeviceMap.insert(
127+
std::make_pair(ZeDevices[D], std::move(ZesDeviceData)));
128+
}
129+
}
86130
}
87131
}
88132
}
@@ -171,8 +215,36 @@ ur_adapter_handle_t_::ur_adapter_handle_t_()
171215

172216
return;
173217
}
218+
// Dynamically load the new L0 SysMan separate init and new EXP apis
219+
// separately. This must be done to avoid attempting to use symbols that do
220+
// not exist in older loader runtimes.
221+
#ifdef _WIN32
222+
HMODULE processHandle = GetModuleHandle(NULL);
223+
#else
224+
HMODULE processHandle = nullptr;
225+
#endif
226+
GlobalAdapter->getDeviceByUUIdFunctionPtr =
227+
(zes_pfnDriverGetDeviceByUuidExp_t)ur_loader::LibLoader::getFunctionPtr(
228+
processHandle, "zesDriverGetDeviceByUuidExp");
229+
GlobalAdapter->getSysManDriversFunctionPtr =
230+
(zes_pfnDriverGet_t)ur_loader::LibLoader::getFunctionPtr(
231+
processHandle, "zesDriverGet");
232+
GlobalAdapter->sysManInitFunctionPtr =
233+
(zes_pfnInit_t)ur_loader::LibLoader::getFunctionPtr(processHandle,
234+
"zesInit");
235+
if (GlobalAdapter->getDeviceByUUIdFunctionPtr &&
236+
GlobalAdapter->getSysManDriversFunctionPtr &&
237+
GlobalAdapter->sysManInitFunctionPtr) {
238+
ze_init_flags_t L0ZesInitFlags = 0;
239+
logger::debug("\nzesInit with flags value of {}\n",
240+
static_cast<int>(L0ZesInitFlags));
241+
GlobalAdapter->ZesResult = ZE_CALL_NOCHECK(
242+
GlobalAdapter->sysManInitFunctionPtr, (L0ZesInitFlags));
243+
} else {
244+
GlobalAdapter->ZesResult = ZE_RESULT_ERROR_UNINITIALIZED;
245+
}
174246

175-
ur_result_t err = initPlatforms(platforms);
247+
ur_result_t err = initPlatforms(platforms, *GlobalAdapter->ZesResult);
176248
if (err == UR_RESULT_SUCCESS) {
177249
result = std::move(platforms);
178250
} else {

source/adapters/level_zero/adapter.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111

1212
#include "logger/ur_logger.hpp"
1313
#include <atomic>
14+
#include <loader/ur_loader.hpp>
1415
#include <loader/ze_loader.h>
1516
#include <mutex>
1617
#include <optional>
1718
#include <ur/ur.hpp>
1819
#include <ze_api.h>
20+
#include <zes_ddi.h>
1921

2022
using PlatformVec = std::vector<std::unique_ptr<ur_platform_handle_t_>>;
2123

@@ -26,7 +28,12 @@ struct ur_adapter_handle_t_ {
2628
std::atomic<uint32_t> RefCount = 0;
2729
std::mutex Mutex;
2830

31+
zes_pfnDriverGetDeviceByUuidExp_t getDeviceByUUIdFunctionPtr = nullptr;
32+
zes_pfnDriverGet_t getSysManDriversFunctionPtr = nullptr;
33+
zes_pfnInit_t sysManInitFunctionPtr = nullptr;
34+
2935
std::optional<ze_result_t> ZeResult;
36+
std::optional<ze_result_t> ZesResult;
3037
ZeCache<Result<PlatformVec>> PlatformCache;
3138
logger::Logger &logger;
3239
};

source/adapters/level_zero/device.cpp

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -747,11 +747,11 @@ ur_result_t urDeviceGetInfo(
747747
}
748748

749749
case UR_DEVICE_INFO_GLOBAL_MEM_FREE: {
750-
if (getenv("ZES_ENABLE_SYSMAN") == nullptr) {
751-
setErrorMessage("Set ZES_ENABLE_SYSMAN=1 to obtain free memory",
752-
UR_RESULT_ERROR_UNINITIALIZED,
753-
static_cast<int32_t>(ZE_RESULT_ERROR_UNINITIALIZED));
754-
return UR_RESULT_ERROR_ADAPTER_SPECIFIC;
750+
bool SysManEnv = getenv_tobool("ZES_ENABLE_SYSMAN", false);
751+
if ((Device->Platform->ZedeviceToZesDeviceMap.size() == 0) && !SysManEnv) {
752+
logger::error("SysMan support is unavailable on this system. Please "
753+
"check your level zero driver installation.");
754+
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
755755
}
756756
// Calculate the global memory size as the max limit that can be reported as
757757
// "free" memory for the user to allocate.
@@ -760,30 +760,57 @@ ur_result_t urDeviceGetInfo(
760760
// Currently this is only the one enumerated with ordinal 0.
761761
uint64_t FreeMemory = 0;
762762
uint32_t MemCount = 0;
763-
ZE2UR_CALL(zesDeviceEnumMemoryModules, (ZeDevice, &MemCount, nullptr));
763+
764+
zes_device_handle_t ZesDevice = Device->ZeDevice;
765+
struct ur_zes_device_handle_data_t ZesDeviceData = {};
766+
// If legacy sysman is enabled thru the environment variable, then zesInit
767+
// will fail, but sysman is still usable so go the legacy route.
768+
if (!SysManEnv) {
769+
auto It = Device->Platform->ZedeviceToZesDeviceMap.find(Device->ZeDevice);
770+
if (It == Device->Platform->ZedeviceToZesDeviceMap.end()) {
771+
// no matching device
772+
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
773+
} else {
774+
ZesDeviceData =
775+
Device->Platform->ZedeviceToZesDeviceMap[Device->ZeDevice];
776+
ZesDevice = ZesDeviceData.ZesDevice;
777+
}
778+
}
779+
780+
ZE2UR_CALL(zesDeviceEnumMemoryModules, (ZesDevice, &MemCount, nullptr));
764781
if (MemCount != 0) {
765782
std::vector<zes_mem_handle_t> ZesMemHandles(MemCount);
766783
ZE2UR_CALL(zesDeviceEnumMemoryModules,
767-
(ZeDevice, &MemCount, ZesMemHandles.data()));
784+
(ZesDevice, &MemCount, ZesMemHandles.data()));
768785
for (auto &ZesMemHandle : ZesMemHandles) {
769786
ZesStruct<zes_mem_properties_t> ZesMemProperties;
770787
ZE2UR_CALL(zesMemoryGetProperties, (ZesMemHandle, &ZesMemProperties));
771788
// For root-device report memory from all memory modules since that
772789
// is what totally available in the default implicit scaling mode.
773790
// For sub-devices only report memory local to them.
774-
if (!Device->isSubDevice() || Device->ZeDeviceProperties->subdeviceId ==
775-
ZesMemProperties.subdeviceId) {
776-
777-
ZesStruct<zes_mem_state_t> ZesMemState;
778-
ZE2UR_CALL(zesMemoryGetState, (ZesMemHandle, &ZesMemState));
779-
FreeMemory += ZesMemState.free;
791+
if (SysManEnv) {
792+
if (!Device->isSubDevice() ||
793+
Device->ZeDeviceProperties->subdeviceId ==
794+
ZesMemProperties.subdeviceId) {
795+
796+
ZesStruct<zes_mem_state_t> ZesMemState;
797+
ZE2UR_CALL(zesMemoryGetState, (ZesMemHandle, &ZesMemState));
798+
FreeMemory += ZesMemState.free;
799+
}
800+
} else {
801+
if (ZesDeviceData.SubDeviceId == ZesMemProperties.subdeviceId ||
802+
!ZesDeviceData.SubDevice) {
803+
ZesStruct<zes_mem_state_t> ZesMemState;
804+
ZE2UR_CALL(zesMemoryGetState, (ZesMemHandle, &ZesMemState));
805+
FreeMemory += ZesMemState.free;
806+
}
780807
}
781808
}
782809
}
783810
if (MemCount > 0) {
784811
return ReturnValue(std::min(GlobalMemSize, FreeMemory));
785812
} else {
786-
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
813+
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
787814
}
788815
}
789816
case UR_DEVICE_INFO_MEMORY_CLOCK_RATE: {

source/adapters/level_zero/platform.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@
1212
#include "common.hpp"
1313
#include "ur_api.h"
1414
#include "ze_api.h"
15+
#include "zes_api.h"
1516

1617
struct ur_device_handle_t_;
1718

1819
typedef size_t DeviceId;
1920

21+
struct ur_zes_device_handle_data_t {
22+
zes_device_handle_t ZesDevice;
23+
uint32_t SubDeviceId;
24+
ze_bool_t SubDevice = false;
25+
};
26+
2027
struct ur_platform_handle_t_ : public _ur_platform {
2128
ur_platform_handle_t_(ze_driver_handle_t Driver)
2229
: ZeDriver{Driver}, ZeApiVersion{ZE_API_VERSION_CURRENT} {}
@@ -27,6 +34,11 @@ struct ur_platform_handle_t_ : public _ur_platform {
2734
// a pretty good fit to keep here.
2835
ze_driver_handle_t ZeDriver;
2936

37+
// Cache of the ZesDevices mapped to the ZeDevices for use in zes apis calls
38+
// based on a ze device handle.
39+
std::unordered_map<ze_device_handle_t, ur_zes_device_handle_data_t>
40+
ZedeviceToZesDeviceMap;
41+
3042
// Given a multi driver scenario, the driver handle must be translated to the
3143
// internal driver handle to allow calls to driver experimental apis.
3244
ze_driver_handle_t ZeDriverHandleExpTranslated;
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
{{NONDETERMINISTIC}}
22
urDeviceCreateWithNativeHandleTest.SuccessWithUnOwnedNativeHandle
33
{{OPT}}urDeviceGetGlobalTimestampTest.SuccessSynchronizedTime
4-
{{OPT}}urDeviceGetInfoTest.Success/UR_DEVICE_INFO_GLOBAL_MEM_FREE

0 commit comments

Comments
 (0)