Skip to content

Commit 477edb6

Browse files
committed
L0 provider: implement support for defer and blocking free
1 parent 3dc6734 commit 477edb6

File tree

5 files changed

+85
-2
lines changed

5 files changed

+85
-2
lines changed

include/umf/providers/provider_level_zero.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ umf_result_t umfLevelZeroMemoryProviderParamsSetResidentDevices(
6868
umf_level_zero_memory_provider_params_handle_t hParams,
6969
ze_device_handle_t *hDevices, uint32_t deviceCount);
7070

71+
typedef enum umf_level_zero_memory_provider_free_policy_t {
72+
UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_DEFAULT =
73+
0, ///< Free memory immediately. Default.
74+
UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_BLOCKING_FREE, ///< Blocks until all commands using the memory are complete before freeing.
75+
UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_DEFER_FREE, ///< Schedules the memory to be freed but does not free immediately.
76+
} umf_level_zero_memory_provider_free_policy_t;
77+
78+
/// @brief Set the memory free policy.
79+
/// @param hParams handle to the parameters of the Level Zero Memory Provider.
80+
/// @param policy memory free policy.
81+
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
82+
umf_result_t umfLevelZeroMemoryProviderParamsSetFreePolicy(
83+
umf_level_zero_memory_provider_params_handle_t hParams,
84+
umf_level_zero_memory_provider_free_policy_t policy);
85+
7186
umf_memory_provider_ops_t *umfLevelZeroMemoryProviderOps(void);
7287

7388
#ifdef __cplusplus

src/libumf.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ EXPORTS
4040
umfLevelZeroMemoryProviderParamsDestroy
4141
umfLevelZeroMemoryProviderParamsSetContext
4242
umfLevelZeroMemoryProviderParamsSetDevice
43+
umfLevelZeroMemoryProviderParamsSetFreePolicy
4344
umfLevelZeroMemoryProviderParamsSetMemoryType
4445
umfLevelZeroMemoryProviderParamsSetResidentDevices
4546
umfMemoryProviderAlloc

src/libumf.map

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,10 @@ UMF_1.0 {
114114
local:
115115
*;
116116
};
117+
118+
UMF_0.11 {
119+
global:
120+
umfLevelZeroMemoryProviderParamsSetFreePolicy;
121+
local:
122+
*;
123+
};

src/provider/provider_level_zero.c

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ umf_result_t umfLevelZeroMemoryProviderParamsSetResidentDevices(
6161
return UMF_RESULT_ERROR_NOT_SUPPORTED;
6262
}
6363

64+
umf_result_t umfLevelZeroMemoryProviderParamsSetFreePolicy(
65+
umf_level_zero_memory_provider_params_handle_t hParams,
66+
umf_level_zero_memory_provider_free_policy_t policy) {
67+
(void)hParams;
68+
(void)policy;
69+
return UMF_RESULT_ERROR_NOT_SUPPORTED;
70+
}
71+
6472
umf_memory_provider_ops_t *umfLevelZeroMemoryProviderOps(void) {
6573
// not supported
6674
return NULL;
@@ -91,6 +99,9 @@ typedef struct umf_level_zero_memory_provider_params_t {
9199
resident_device_handles; ///< Array of devices for which the memory should be made resident
92100
uint32_t
93101
resident_device_count; ///< Number of devices for which the memory should be made resident
102+
103+
umf_level_zero_memory_provider_free_policy_t
104+
freePolicy; ///< Memory free policy
94105
} umf_level_zero_memory_provider_params_t;
95106

96107
typedef struct ze_memory_provider_t {
@@ -102,6 +113,8 @@ typedef struct ze_memory_provider_t {
102113
uint32_t resident_device_count;
103114

104115
ze_device_properties_t device_properties;
116+
117+
ze_driver_memory_free_policy_ext_flags_t freePolicyFlags;
105118
} ze_memory_provider_t;
106119

107120
typedef struct ze_ops_t {
@@ -128,6 +141,8 @@ typedef struct ze_ops_t {
128141
size_t);
129142
ze_result_t (*zeDeviceGetProperties)(ze_device_handle_t,
130143
ze_device_properties_t *);
144+
ze_result_t (*zeMemFreeExt)(ze_context_handle_t,
145+
ze_memory_free_ext_desc_t *, void *);
131146
} ze_ops_t;
132147

133148
static ze_ops_t g_ze_ops;
@@ -181,6 +196,8 @@ static void init_ze_global_state(void) {
181196
utils_get_symbol_addr(0, "zeContextMakeMemoryResident", lib_name);
182197
*(void **)&g_ze_ops.zeDeviceGetProperties =
183198
utils_get_symbol_addr(0, "zeDeviceGetProperties", lib_name);
199+
*(void **)&g_ze_ops.zeMemFreeExt =
200+
utils_get_symbol_addr(0, "zeMemFreeExt", lib_name);
184201

185202
if (!g_ze_ops.zeMemAllocHost || !g_ze_ops.zeMemAllocDevice ||
186203
!g_ze_ops.zeMemAllocShared || !g_ze_ops.zeMemFree ||
@@ -216,6 +233,7 @@ umf_result_t umfLevelZeroMemoryProviderParamsCreate(
216233
params->memory_type = UMF_MEMORY_TYPE_UNKNOWN;
217234
params->resident_device_handles = NULL;
218235
params->resident_device_count = 0;
236+
params->freePolicy = UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_DEFAULT;
219237

220238
*hParams = params;
221239

@@ -292,6 +310,32 @@ umf_result_t umfLevelZeroMemoryProviderParamsSetResidentDevices(
292310
return UMF_RESULT_SUCCESS;
293311
}
294312

313+
umf_result_t umfLevelZeroMemoryProviderParamsSetFreePolicy(
314+
umf_level_zero_memory_provider_params_handle_t hParams,
315+
umf_level_zero_memory_provider_free_policy_t policy) {
316+
if (!hParams) {
317+
LOG_ERR("Level zero memory provider params handle is NULL");
318+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
319+
}
320+
321+
hParams->freePolicy = policy;
322+
return UMF_RESULT_SUCCESS;
323+
}
324+
325+
static ze_driver_memory_free_policy_ext_flags_t
326+
umfFreePolicyToZePolicy(umf_level_zero_memory_provider_free_policy_t policy) {
327+
switch (policy) {
328+
case UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_DEFAULT:
329+
return 0;
330+
case UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_BLOCKING_FREE:
331+
return ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_BLOCKING_FREE;
332+
case UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_DEFER_FREE:
333+
return ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_DEFER_FREE;
334+
default:
335+
return 0;
336+
}
337+
}
338+
295339
static umf_result_t ze_memory_provider_initialize(void *params,
296340
void **provider) {
297341
if (params == NULL) {
@@ -335,6 +379,8 @@ static umf_result_t ze_memory_provider_initialize(void *params,
335379
ze_provider->context = ze_params->level_zero_context_handle;
336380
ze_provider->device = ze_params->level_zero_device_handle;
337381
ze_provider->memory_type = (ze_memory_type_t)ze_params->memory_type;
382+
ze_provider->freePolicyFlags =
383+
umfFreePolicyToZePolicy(ze_params->freePolicy);
338384

339385
if (ze_provider->device) {
340386
umf_result_t ret = ze2umf_result(g_ze_ops.zeDeviceGetProperties(
@@ -476,8 +522,18 @@ static umf_result_t ze_memory_provider_free(void *provider, void *ptr,
476522
}
477523

478524
ze_memory_provider_t *ze_provider = (ze_memory_provider_t *)provider;
479-
ze_result_t ze_result = g_ze_ops.zeMemFree(ze_provider->context, ptr);
480-
return ze2umf_result(ze_result);
525+
526+
if (ze_provider->freePolicyFlags == 0) {
527+
return ze2umf_result(g_ze_ops.zeMemFree(ze_provider->context, ptr));
528+
}
529+
530+
ze_memory_free_ext_desc_t desc = {
531+
.stype = ZE_STRUCTURE_TYPE_MEMORY_FREE_EXT_DESC,
532+
.pNext = NULL,
533+
.freePolicy = ze_provider->freePolicyFlags};
534+
535+
return ze2umf_result(
536+
g_ze_ops.zeMemFreeExt(ze_provider->context, &desc, ptr));
481537
}
482538

483539
static void ze_memory_provider_get_last_native_error(void *provider,

test/providers/provider_level_zero_not_impl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ TEST_F(test, level_zero_provider_not_implemented) {
3131
hDevices, 1);
3232
ASSERT_EQ(result, UMF_RESULT_ERROR_NOT_SUPPORTED);
3333

34+
result = umfLevelZeroMemoryProviderParamsSetFreePolicy(
35+
hParams, UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_DEFAULT);
36+
ASSERT_EQ(result, UMF_RESULT_ERROR_NOT_SUPPORTED);
37+
3438
umf_memory_provider_ops_t *ops = umfLevelZeroMemoryProviderOps();
3539
ASSERT_EQ(ops, nullptr);
3640
}

0 commit comments

Comments
 (0)