Skip to content

Commit 89b660c

Browse files
Merge pull request #692 from igchor/l0_provider
Extend L0 provider to match UR capabilities
2 parents 1b09fd1 + e8c0fc4 commit 89b660c

File tree

2 files changed

+91
-21
lines changed

2 files changed

+91
-21
lines changed

include/umf/providers/provider_level_zero.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
extern "C" {
1515
#endif
1616

17+
typedef struct _ze_context_handle_t *ze_context_handle_t;
18+
typedef struct _ze_device_handle_t *ze_device_handle_t;
19+
1720
/// @brief USM memory allocation type
1821
typedef enum umf_usm_memory_type_t {
1922
UMF_MEMORY_TYPE_UNKNOWN = 0, ///< The memory pointed to is of unknown type
@@ -24,9 +27,17 @@ typedef enum umf_usm_memory_type_t {
2427

2528
/// @brief Level Zero Memory Provider settings struct
2629
typedef struct level_zero_memory_provider_params_t {
27-
void *level_zero_context_handle; ///< Handle to the Level Zero context
28-
void *level_zero_device_handle; ///< Handle to the Level Zero device
30+
ze_context_handle_t
31+
level_zero_context_handle; ///< Handle to the Level Zero context
32+
ze_device_handle_t
33+
level_zero_device_handle; ///< Handle to the Level Zero device
34+
2935
umf_usm_memory_type_t memory_type; ///< Allocation memory type
36+
37+
ze_device_handle_t *
38+
resident_device_handles; ///< Array of devices for which the memory should be made resident
39+
uint32_t
40+
resident_device_count; ///< Number of devices for which the memory should be made resident
3041
} level_zero_memory_provider_params_t;
3142

3243
umf_memory_provider_ops_t *umfLevelZeroMemoryProviderOps(void);

src/provider/provider_level_zero.c

Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ typedef struct ze_memory_provider_t {
2727
ze_context_handle_t context;
2828
ze_device_handle_t device;
2929
ze_memory_type_t memory_type;
30+
31+
ze_device_handle_t *resident_device_handles;
32+
uint32_t resident_device_count;
33+
34+
ze_device_properties_t device_properties;
3035
} ze_memory_provider_t;
3136

3237
typedef struct ze_ops_t {
@@ -48,11 +53,35 @@ typedef struct ze_ops_t {
4853
ze_ipc_mem_handle_t,
4954
ze_ipc_memory_flags_t, void **);
5055
ze_result_t (*zeMemCloseIpcHandle)(ze_context_handle_t, void *);
56+
ze_result_t (*zeContextMakeMemoryResident)(ze_context_handle_t,
57+
ze_device_handle_t, void *,
58+
size_t);
59+
ze_result_t (*zeDeviceGetProperties)(ze_device_handle_t,
60+
ze_device_properties_t *);
5161
} ze_ops_t;
5262

5363
static ze_ops_t g_ze_ops;
5464
static UTIL_ONCE_FLAG ze_is_initialized = UTIL_ONCE_FLAG_INIT;
5565
static bool Init_ze_global_state_failed;
66+
static __TLS ze_result_t TLS_last_native_error;
67+
68+
static void store_last_native_error(int32_t native_error) {
69+
TLS_last_native_error = native_error;
70+
}
71+
72+
umf_result_t ze2umf_result(ze_result_t result) {
73+
switch (result) {
74+
case ZE_RESULT_SUCCESS:
75+
return UMF_RESULT_SUCCESS;
76+
case ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY:
77+
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
78+
case ZE_RESULT_ERROR_INVALID_ARGUMENT:
79+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
80+
default:
81+
store_last_native_error(result);
82+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
83+
}
84+
}
5685

5786
static void init_ze_global_state(void) {
5887
#ifdef _WIN32
@@ -78,11 +107,17 @@ static void init_ze_global_state(void) {
78107
util_get_symbol_addr(0, "zeMemOpenIpcHandle", lib_name);
79108
*(void **)&g_ze_ops.zeMemCloseIpcHandle =
80109
util_get_symbol_addr(0, "zeMemCloseIpcHandle", lib_name);
110+
*(void **)&g_ze_ops.zeContextMakeMemoryResident =
111+
util_get_symbol_addr(0, "zeContextMakeMemoryResident", lib_name);
112+
*(void **)&g_ze_ops.zeDeviceGetProperties =
113+
util_get_symbol_addr(0, "zeDeviceGetProperties", lib_name);
81114

82115
if (!g_ze_ops.zeMemAllocHost || !g_ze_ops.zeMemAllocDevice ||
83116
!g_ze_ops.zeMemAllocShared || !g_ze_ops.zeMemFree ||
84117
!g_ze_ops.zeMemGetIpcHandle || !g_ze_ops.zeMemOpenIpcHandle ||
85-
!g_ze_ops.zeMemCloseIpcHandle) {
118+
!g_ze_ops.zeMemCloseIpcHandle ||
119+
!g_ze_ops.zeContextMakeMemoryResident ||
120+
!g_ze_ops.zeDeviceGetProperties) {
86121
// g_ze_ops.zeMemPutIpcHandle can be NULL because it was introduced
87122
// starting from Level Zero 1.6
88123
LOG_ERR("Required Level Zero symbols not found.");
@@ -114,6 +149,14 @@ umf_result_t ze_memory_provider_initialize(void *params, void **provider) {
114149
ze_provider->device = ze_params->level_zero_device_handle;
115150
ze_provider->memory_type = (ze_memory_type_t)ze_params->memory_type;
116151

152+
umf_result_t ret = ze2umf_result(g_ze_ops.zeDeviceGetProperties(
153+
ze_provider->device, &ze_provider->device_properties));
154+
155+
if (ret != UMF_RESULT_SUCCESS) {
156+
umf_ba_global_free(ze_provider);
157+
return ret;
158+
}
159+
117160
*provider = ze_provider;
118161

119162
return UMF_RESULT_SUCCESS;
@@ -138,6 +181,16 @@ static umf_result_t ze_memory_provider_alloc(void *provider, size_t size,
138181

139182
ze_memory_provider_t *ze_provider = (ze_memory_provider_t *)provider;
140183

184+
bool useRelaxedAllocationFlag =
185+
size > ze_provider->device_properties.maxMemAllocSize;
186+
ze_relaxed_allocation_limits_exp_desc_t relaxed_desc = {
187+
.stype = ZE_STRUCTURE_TYPE_RELAXED_ALLOCATION_LIMITS_EXP_DESC,
188+
.pNext = NULL,
189+
.flags = 0};
190+
if (useRelaxedAllocationFlag) {
191+
relaxed_desc.flags = ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE;
192+
}
193+
141194
ze_result_t ze_result = ZE_RESULT_SUCCESS;
142195
switch (ze_provider->memory_type) {
143196
case UMF_MEMORY_TYPE_HOST: {
@@ -152,7 +205,7 @@ static umf_result_t ze_memory_provider_alloc(void *provider, size_t size,
152205
case UMF_MEMORY_TYPE_DEVICE: {
153206
ze_device_mem_alloc_desc_t dev_desc = {
154207
.stype = ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC,
155-
.pNext = NULL,
208+
.pNext = useRelaxedAllocationFlag ? &relaxed_desc : NULL,
156209
.flags = 0,
157210
.ordinal = 0 // TODO
158211
};
@@ -168,7 +221,7 @@ static umf_result_t ze_memory_provider_alloc(void *provider, size_t size,
168221
.flags = 0};
169222
ze_device_mem_alloc_desc_t dev_desc = {
170223
.stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC,
171-
.pNext = NULL,
224+
.pNext = useRelaxedAllocationFlag ? &relaxed_desc : NULL,
172225
.flags = 0,
173226
.ordinal = 0 // TODO
174227
};
@@ -178,13 +231,23 @@ static umf_result_t ze_memory_provider_alloc(void *provider, size_t size,
178231
break;
179232
}
180233
default:
181-
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
234+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
182235
}
183236

184-
// TODO add error reporting
185-
return (ze_result == ZE_RESULT_SUCCESS)
186-
? UMF_RESULT_SUCCESS
187-
: UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
237+
if (ze_result != ZE_RESULT_SUCCESS) {
238+
return ze2umf_result(ze_result);
239+
}
240+
241+
for (uint32_t i = 0; i < ze_provider->resident_device_count; i++) {
242+
ze_result = g_ze_ops.zeContextMakeMemoryResident(
243+
ze_provider->context, ze_provider->resident_device_handles[i],
244+
*resultPtr, size);
245+
if (ze_result != ZE_RESULT_SUCCESS) {
246+
return ze2umf_result(ze_result);
247+
}
248+
}
249+
250+
return ze2umf_result(ze_result);
188251
}
189252

190253
static umf_result_t ze_memory_provider_free(void *provider, void *ptr,
@@ -194,11 +257,7 @@ static umf_result_t ze_memory_provider_free(void *provider, void *ptr,
194257
assert(provider);
195258
ze_memory_provider_t *ze_provider = (ze_memory_provider_t *)provider;
196259
ze_result_t ze_result = g_ze_ops.zeMemFree(ze_provider->context, ptr);
197-
198-
// TODO add error reporting
199-
return (ze_result == ZE_RESULT_SUCCESS)
200-
? UMF_RESULT_SUCCESS
201-
: UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
260+
return ze2umf_result(ze_result);
202261
}
203262

204263
void ze_memory_provider_get_last_native_error(void *provider,
@@ -207,9 +266,9 @@ void ze_memory_provider_get_last_native_error(void *provider,
207266
(void)provider;
208267
(void)ppMessage;
209268

210-
// TODO
211269
assert(pError);
212-
*pError = 0;
270+
271+
*pError = TLS_last_native_error;
213272
}
214273

215274
static umf_result_t ze_memory_provider_get_min_page_size(void *provider,
@@ -314,7 +373,7 @@ static umf_result_t ze_memory_provider_get_ipc_handle(void *provider,
314373
&ze_ipc_data->ze_handle);
315374
if (ze_result != ZE_RESULT_SUCCESS) {
316375
LOG_ERR("zeMemGetIpcHandle() failed.");
317-
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
376+
return ze2umf_result(ze_result);
318377
}
319378

320379
ze_ipc_data->pid = utils_getpid();
@@ -342,7 +401,7 @@ static umf_result_t ze_memory_provider_put_ipc_handle(void *provider,
342401
ze_ipc_data->ze_handle);
343402
if (ze_result != ZE_RESULT_SUCCESS) {
344403
LOG_ERR("zeMemPutIpcHandle() failed.");
345-
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
404+
return ze2umf_result(ze_result);
346405
}
347406
return UMF_RESULT_SUCCESS;
348407
}
@@ -379,7 +438,7 @@ static umf_result_t ze_memory_provider_open_ipc_handle(void *provider,
379438
}
380439
if (ze_result != ZE_RESULT_SUCCESS) {
381440
LOG_ERR("zeMemOpenIpcHandle() failed.");
382-
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
441+
return ze2umf_result(ze_result);
383442
}
384443

385444
return UMF_RESULT_SUCCESS;
@@ -397,7 +456,7 @@ ze_memory_provider_close_ipc_handle(void *provider, void *ptr, size_t size) {
397456
ze_result = g_ze_ops.zeMemCloseIpcHandle(ze_provider->context, ptr);
398457
if (ze_result != ZE_RESULT_SUCCESS) {
399458
LOG_ERR("zeMemCloseIpcHandle() failed.");
400-
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
459+
return ze2umf_result(ze_result);
401460
}
402461

403462
return UMF_RESULT_SUCCESS;

0 commit comments

Comments
 (0)