|
1 | 1 | #include "Driver/GPU/XpuApi.h" |
2 | | -#include "Driver/Dispatch.h" |
3 | 2 |
|
4 | | -#include <level_zero/ze_api.h> |
| 3 | +#include <dlfcn.h> |
| 4 | +#include <stdexcept> |
5 | 5 | #include <string> |
6 | 6 |
|
7 | 7 | namespace proton { |
8 | 8 |
|
9 | 9 | namespace xpu { |
10 | 10 |
|
11 | | -struct ExternLibLevelZero : public ExternLibBase { |
12 | | - using RetType = ze_result_t; |
| 11 | +std::string PROTON_UTILS; |
13 | 12 |
|
14 | | - // FIXME: removeme `/usr/lib/x86_64-linux-gnu/libze_intel_gpu.so.1` |
15 | | - static constexpr const char *name = "libze_intel_gpu.so.1"; |
16 | | - static constexpr const char *defaultDir = ""; |
17 | | - static constexpr RetType success = ZE_RESULT_SUCCESS; |
18 | | - static void *lib; |
19 | | -}; |
| 13 | +typedef void (*GetDevicePropertiesFunc)(uint64_t, uint32_t *, uint32_t *, |
| 14 | + uint32_t *, uint32_t *, char[256]); |
20 | 15 |
|
21 | | -void *ExternLibLevelZero::lib = nullptr; |
22 | | - |
23 | | -// https://oneapi-src.github.io/level-zero-spec/level-zero/latest/core/api.html#zeinit |
24 | | -DEFINE_DISPATCH(ExternLibLevelZero, init, zeInit, ze_init_flags_t) |
25 | | -// https://oneapi-src.github.io/level-zero-spec/level-zero/latest/core/api.html#zedriverget |
26 | | -DEFINE_DISPATCH(ExternLibLevelZero, driverGet, zeDriverGet, uint32_t *, |
27 | | - ze_driver_handle_t *) |
28 | | -// https://oneapi-src.github.io/level-zero-spec/level-zero/latest/core/api.html#zedeviceget |
29 | | -DEFINE_DISPATCH(ExternLibLevelZero, deviceGet, zeDeviceGet, ze_driver_handle_t, |
30 | | - uint32_t *, ze_device_handle_t *) |
31 | | -// https://oneapi-src.github.io/level-zero-spec/level-zero/latest/core/api.html#zedevicegetproperties |
32 | | -DEFINE_DISPATCH(ExternLibLevelZero, deviceGetProperties, zeDeviceGetProperties, |
33 | | - ze_device_handle_t, ze_device_properties_t *) |
34 | | -// https://oneapi-src.github.io/level-zero-spec/level-zero/latest/core/api.html#zedevicegetmemoryproperties |
35 | | -DEFINE_DISPATCH(ExternLibLevelZero, deviceGetMemoryProperties, |
36 | | - zeDeviceGetMemoryProperties, ze_device_handle_t, uint32_t *, |
37 | | - ze_device_memory_properties_t *) |
38 | | - |
39 | | -// FIXME: for this initialization is needed |
40 | | -// ref: initDevices |
41 | | -// static std::vector<std::pair<sycl::device, ze_device_handle_t>> |
42 | | -// g_sycl_l0_device_list; |
43 | | - |
44 | | -// FIXME: rewrite with |
45 | | -// sycl::device.get_info<sycl::ext::intel::info::device::architecture>; cache |
46 | | -// the result |
47 | 16 | Device getDevice(uint64_t index) { |
48 | | - // ref: getDeviceProperties |
49 | | - |
50 | | - // FIXME: double check that initialization is needed |
51 | | - // At the very least, it shouldn't be for every call |
52 | | - xpu::init<true>(ZE_INIT_FLAG_GPU_ONLY); |
53 | | - |
54 | | - // FIXME: For now I use the naive approach that the device index from PTI |
55 | | - // record coincides with the default numbering of all devices |
56 | | - |
57 | | - uint32_t driverCount = 1; |
58 | | - ze_driver_handle_t driverHandle; |
59 | | - xpu::driverGet<true>(&driverCount, &driverHandle); |
60 | | - uint32_t deviceCount = 1; |
61 | | - |
62 | | - // Get device handle |
63 | | - ze_device_handle_t phDevice; |
64 | | - xpu::deviceGet<true>(driverHandle, &deviceCount, &phDevice); |
65 | | - |
66 | | - // create a struct to hold device properties |
67 | | - ze_device_properties_t device_properties = {}; |
68 | | - device_properties.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES; |
69 | | - xpu::deviceGetProperties<true>(phDevice, &device_properties); |
70 | | - |
71 | | - uint32_t clockRate = device_properties.coreClockRate; |
72 | | - uint32_t numSms = |
73 | | - device_properties.numSlices * device_properties.numSubslicesPerSlice; |
74 | | - |
75 | | - // create a struct to hold device memory properties |
76 | | - uint32_t memoryCount = 0; |
77 | | - xpu::deviceGetMemoryProperties<true>(phDevice, &memoryCount, nullptr); |
78 | | - auto pMemoryProperties = new ze_device_memory_properties_t[memoryCount]; |
79 | | - for (uint32_t mem = 0; mem < memoryCount; ++mem) { |
80 | | - pMemoryProperties[mem].stype = ZE_STRUCTURE_TYPE_DEVICE_MEMORY_PROPERTIES; |
81 | | - pMemoryProperties[mem].pNext = nullptr; |
| 17 | + void *handle = dlopen(PROTON_UTILS.data(), RTLD_LAZY); |
| 18 | + if (!handle) { |
| 19 | + const char *dlopen_error = dlerror(); |
| 20 | + throw std::runtime_error(std::string("Failed to load library: ") + |
| 21 | + std::string(dlopen_error)); |
82 | 22 | } |
83 | | - xpu::deviceGetMemoryProperties<true>(phDevice, &memoryCount, |
84 | | - pMemoryProperties); |
85 | | - |
86 | | - int memoryClockRate = pMemoryProperties[0].maxClockRate; |
87 | | - int busWidth = pMemoryProperties[0].maxBusWidth; |
88 | 23 |
|
89 | | - delete[] pMemoryProperties; |
| 24 | + dlerror(); |
| 25 | + GetDevicePropertiesFunc getDeviceProperties = |
| 26 | + (GetDevicePropertiesFunc)dlsym(handle, "getDeviceProperties"); |
| 27 | + const char *dlsym_error = dlerror(); |
| 28 | + if (dlsym_error) { |
| 29 | + dlclose(handle); |
| 30 | + throw std::runtime_error(std::string("Failed to load function: ") + |
| 31 | + std::string(dlsym_error)); |
| 32 | + } |
90 | 33 |
|
91 | | - // FIXME: there should be architecture, but not a name |
92 | | - std::string arch = device_properties.name; |
| 34 | + uint32_t clockRate = 0; |
| 35 | + uint32_t memoryClockRate = 0; |
| 36 | + uint32_t busWidth = 0; |
| 37 | + uint32_t numSms = 0; |
| 38 | + char arch[256]; |
| 39 | + getDeviceProperties(index, &clockRate, &memoryClockRate, &busWidth, &numSms, |
| 40 | + arch); |
| 41 | + dlclose(handle); |
93 | 42 |
|
94 | 43 | return Device(DeviceType::XPU, index, clockRate, memoryClockRate, busWidth, |
95 | 44 | numSms, arch); |
|
0 commit comments