Skip to content

Commit 53eaf72

Browse files
committed
enable GPU IPC tests on Windows
1 parent cfc99b7 commit 53eaf72

15 files changed

+579
-158
lines changed

.github/workflows/pr_push.yml

Lines changed: 1 addition & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -17,87 +17,16 @@ permissions:
1717
packages: read
1818

1919
jobs:
20-
CodeChecks:
21-
uses: ./.github/workflows/reusable_checks.yml
22-
FastBuild:
23-
name: Fast builds
24-
needs: [CodeChecks]
25-
uses: ./.github/workflows/reusable_fast.yml
26-
Build:
27-
name: Basic builds
28-
needs: [FastBuild]
29-
uses: ./.github/workflows/reusable_basic.yml
30-
DevDax:
31-
needs: [FastBuild]
32-
uses: ./.github/workflows/reusable_dax.yml
33-
MultiNuma:
34-
needs: [FastBuild]
35-
uses: ./.github/workflows/reusable_multi_numa.yml
3620
L0:
37-
needs: [Build]
3821
uses: ./.github/workflows/reusable_gpu.yml
3922
with:
4023
provider: "LEVEL_ZERO"
4124
runner: "L0"
4225
shared_lib: "['ON']"
43-
L0-BMG:
44-
needs: [Build]
45-
uses: ./.github/workflows/reusable_gpu.yml
46-
with:
47-
provider: "LEVEL_ZERO"
48-
runner: "L0-BMG"
49-
shared_lib: "['ON']"
5026
CUDA:
51-
needs: [Build]
5227
uses: ./.github/workflows/reusable_gpu.yml
5328
with:
5429
provider: "CUDA"
5530
runner: "CUDA"
5631
shared_lib: "['ON']"
57-
Sanitizers:
58-
needs: [FastBuild]
59-
uses: ./.github/workflows/reusable_sanitizers.yml
60-
QEMU:
61-
needs: [FastBuild]
62-
uses: ./.github/workflows/reusable_qemu.yml
63-
with:
64-
short_run: true
65-
ProxyLib:
66-
needs: [Build]
67-
uses: ./.github/workflows/reusable_proxy_lib.yml
68-
Valgrind:
69-
needs: [Build]
70-
uses: ./.github/workflows/reusable_valgrind.yml
71-
Coverage:
72-
# total coverage (on upstream only)
73-
if: github.repository == 'oneapi-src/unified-memory-framework'
74-
needs: [Build, DevDax, L0, CUDA, MultiNuma, QEMU, ProxyLib]
75-
uses: ./.github/workflows/reusable_coverage.yml
76-
secrets: inherit
77-
with:
78-
trigger: "${{github.event_name}}"
79-
Coverage_partial:
80-
# partial coverage (on forks)
81-
if: github.repository != 'oneapi-src/unified-memory-framework'
82-
needs: [Build, QEMU, ProxyLib]
83-
uses: ./.github/workflows/reusable_coverage.yml
84-
CodeQL:
85-
needs: [Build]
86-
permissions:
87-
contents: read
88-
security-events: write
89-
uses: ./.github/workflows/reusable_codeql.yml
90-
Trivy:
91-
needs: [Build]
92-
permissions:
93-
contents: read
94-
security-events: write
95-
uses: ./.github/workflows/reusable_trivy.yml
96-
Compatibility:
97-
needs: [Build]
98-
uses: ./.github/workflows/reusable_compatibility.yml
99-
strategy:
100-
matrix:
101-
tag: ["v1.0.1"]
102-
with:
103-
tag: ${{matrix.tag}}
32+

.github/workflows/reusable_gpu.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,11 @@ jobs:
129129

130130
- name: Run tests (Debug)
131131
working-directory: ${{env.BUILD_DEBUG_DIR}}
132-
run: ctest -C Debug --output-on-failure --test-dir test
132+
run: ctest -C Debug --verbose --test-dir test
133133

134134
- name: Run examples (Debug)
135135
working-directory: ${{env.BUILD_DEBUG_DIR}}
136-
run: ctest --output-on-failure --test-dir examples -C Debug
136+
run: ctest --verbose --test-dir examples -C Debug
137137

138138
- name: Configure build (Release)
139139
run: >

include/umf/providers/provider_level_zero.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,20 @@ typedef enum umf_level_zero_memory_provider_free_policy_t {
8282
umf_result_t umfLevelZeroMemoryProviderParamsSetFreePolicy(
8383
umf_level_zero_memory_provider_params_handle_t hParams,
8484
umf_level_zero_memory_provider_free_policy_t policy);
85+
typedef enum umf_level_zero_memory_provider_memory_exchange_policy_t {
86+
UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC =
87+
0, ///< Memory exchange policy based on IPC. Default.
88+
UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT,
89+
///< Memory exchange policy based on import/export APIs
90+
} umf_level_zero_memory_provider_memory_exchange_policy_t;
91+
92+
/// @brief Set the memory exchange policy.
93+
/// @param hParams handle to the parameters of the Level Zero Memory Provider.
94+
/// @param policy memory exchange policy.
95+
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
96+
umf_result_t umfLevelZeroMemoryProviderParamsSetMemoryExchangePolicy(
97+
umf_level_zero_memory_provider_params_handle_t hParams,
98+
umf_level_zero_memory_provider_memory_exchange_policy_t policy);
8599

86100
/// @brief Set the device ordinal in the parameters struct.
87101
/// @param hParams handle to the parameters of the Level Zero Memory Provider.

src/libumf.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ EXPORTS
153153
umfGetMemoryProperty
154154
umfGetMemoryPropertySize
155155
umfJemallocPoolParamsSetName
156+
umfLevelZeroMemoryProviderParamsSetMemoryExchangePolicy
156157
umfLevelZeroMemoryProviderParamsSetName
157158
umfOsMemoryProviderParamsSetName
158159
umfPoolTrimMemory
159-
umfScalablePoolParamsSetName
160+
umfScalablePoolParamsSetName

src/libumf.map

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ UMF_1.1 {
151151
umfGetMemoryProperty;
152152
umfGetMemoryPropertySize;
153153
umfJemallocPoolParamsSetName;
154+
umfLevelZeroMemoryProviderParamsSetMemoryExchangePolicy;
154155
umfLevelZeroMemoryProviderParamsSetName;
155156
umfOsMemoryProviderParamsSetName;
156157
umfPoolTrimMemory;

src/provider/provider_level_zero.c

Lines changed: 128 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ typedef struct umf_level_zero_memory_provider_params_t {
5858
umf_level_zero_memory_provider_free_policy_t
5959
freePolicy; ///< Memory free policy
6060

61+
umf_level_zero_memory_provider_memory_exchange_policy_t
62+
exchangePolicy; ///< Memory exchange policy
63+
6164
uint32_t device_ordinal;
6265
char name[64];
6366
} umf_level_zero_memory_provider_params_t;
@@ -74,6 +77,8 @@ typedef struct ze_memory_provider_t {
7477

7578
ze_driver_memory_free_policy_ext_flags_t freePolicyFlags;
7679

80+
umf_level_zero_memory_provider_memory_exchange_policy_t exchangePolicy;
81+
7782
size_t min_page_size;
7883

7984
uint32_t device_ordinal;
@@ -253,6 +258,8 @@ umf_result_t umfLevelZeroMemoryProviderParamsCreate(
253258
params->resident_device_handles = NULL;
254259
params->resident_device_count = 0;
255260
params->freePolicy = UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_DEFAULT;
261+
params->exchangePolicy =
262+
UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC;
256263
params->device_ordinal = 0;
257264
strncpy(params->name, DEFAULT_NAME, sizeof(params->name) - 1);
258265
params->name[sizeof(params->name) - 1] = '\0';
@@ -374,6 +381,18 @@ umf_result_t umfLevelZeroMemoryProviderParamsSetFreePolicy(
374381
return UMF_RESULT_SUCCESS;
375382
}
376383

384+
umf_result_t umfLevelZeroMemoryProviderParamsSetMemoryExchangePolicy(
385+
umf_level_zero_memory_provider_params_handle_t hParams,
386+
umf_level_zero_memory_provider_memory_exchange_policy_t policy) {
387+
if (!hParams) {
388+
LOG_ERR("Level Zero memory provider params handle is NULL");
389+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
390+
}
391+
392+
hParams->exchangePolicy = policy;
393+
return UMF_RESULT_SUCCESS;
394+
}
395+
377396
static ze_driver_memory_free_policy_ext_flags_t
378397
umfFreePolicyToZePolicy(umf_level_zero_memory_provider_free_policy_t policy) {
379398
switch (policy) {
@@ -401,6 +420,11 @@ static ze_relaxed_allocation_limits_exp_desc_t relaxed_device_allocation_desc =
401420
.pNext = NULL,
402421
.flags = ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE};
403422

423+
static ze_external_memory_export_desc_t export_desc = {
424+
.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC,
425+
.pNext = NULL,
426+
.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32};
427+
404428
static umf_result_t ze_memory_provider_alloc_helper(void *provider, size_t size,
405429
size_t alignment,
406430
int update_stats,
@@ -421,14 +445,32 @@ static umf_result_t ze_memory_provider_alloc_helper(void *provider, size_t size,
421445
case UMF_MEMORY_TYPE_DEVICE: {
422446
ze_device_mem_alloc_desc_t dev_desc = {
423447
.stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC,
424-
.pNext = use_relaxed_allocation(ze_provider, size)
425-
? &relaxed_device_allocation_desc
426-
: NULL,
448+
.pNext = NULL,
427449
.flags = 0,
428450
.ordinal = ze_provider->device_ordinal};
451+
void *lastNext = &dev_desc.pNext;
452+
453+
ze_relaxed_allocation_limits_exp_desc_t
454+
relaxed_device_allocation_desc_copy =
455+
relaxed_device_allocation_desc;
456+
if (use_relaxed_allocation(ze_provider, size)) {
457+
*(uintptr_t *)lastNext =
458+
(uintptr_t)&relaxed_device_allocation_desc_copy;
459+
lastNext = &relaxed_device_allocation_desc_copy.pNext;
460+
}
461+
462+
// TODO - win only? other mem types?
463+
ze_external_memory_export_desc_t export_desc_copy = export_desc;
464+
if (ze_provider->exchangePolicy ==
465+
UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT) {
466+
*(uintptr_t *)lastNext = (uintptr_t)&export_desc_copy;
467+
lastNext = &export_desc_copy.pNext;
468+
}
469+
429470
ze_result = g_ze_ops.zeMemAllocDevice(ze_provider->context, &dev_desc,
430471
size, alignment,
431472
ze_provider->device, resultPtr);
473+
//LOG_ERR("alloc on device size %zu ptr %p", size, *resultPtr);
432474
break;
433475
}
434476
case UMF_MEMORY_TYPE_SHARED: {
@@ -599,6 +641,7 @@ static umf_result_t ze_memory_provider_initialize(const void *params,
599641
ze_provider->memory_type = umf2ze_memory_type(ze_params->memory_type);
600642
ze_provider->freePolicyFlags =
601643
umfFreePolicyToZePolicy(ze_params->freePolicy);
644+
ze_provider->exchangePolicy = ze_params->exchangePolicy;
602645
ze_provider->min_page_size = 0;
603646
ze_provider->device_ordinal = ze_params->device_ordinal;
604647

@@ -755,6 +798,7 @@ static umf_result_t ze_memory_provider_allocation_split(void *provider,
755798

756799
typedef struct ze_ipc_data_t {
757800
int pid;
801+
size_t size;
758802
ze_ipc_mem_handle_t ze_handle;
759803
} ze_ipc_data_t;
760804

@@ -770,20 +814,51 @@ static umf_result_t ze_memory_provider_get_ipc_handle(void *provider,
770814
const void *ptr,
771815
size_t size,
772816
void *providerIpcData) {
773-
(void)size;
774-
775817
ze_result_t ze_result;
776818
ze_ipc_data_t *ze_ipc_data = (ze_ipc_data_t *)providerIpcData;
777819
struct ze_memory_provider_t *ze_provider =
778820
(struct ze_memory_provider_t *)provider;
779821

780-
ze_result = g_ze_ops.zeMemGetIpcHandle(ze_provider->context, ptr,
781-
&ze_ipc_data->ze_handle);
782-
if (ze_result != ZE_RESULT_SUCCESS) {
783-
LOG_ERR("zeMemGetIpcHandle() failed.");
784-
return ze2umf_result(ze_result);
822+
if (ze_provider->exchangePolicy ==
823+
UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC) {
824+
ze_result = g_ze_ops.zeMemGetIpcHandle(ze_provider->context, ptr,
825+
&ze_ipc_data->ze_handle);
826+
827+
if (ze_result != ZE_RESULT_SUCCESS) {
828+
LOG_ERR("zeMemGetIpcHandle() failed.");
829+
return ze2umf_result(ze_result);
830+
}
831+
} else { // UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT
832+
ze_external_memory_export_fd_t fd_desc = {
833+
.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD,
834+
.pNext = NULL,
835+
.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32,
836+
.fd = 0};
837+
838+
ze_memory_allocation_properties_t mem_alloc_props = {
839+
.stype = ZE_STRUCTURE_TYPE_MEMORY_ALLOCATION_PROPERTIES,
840+
.pNext = &fd_desc,
841+
.type = 0,
842+
.id = 0,
843+
.pageSize = 0};
844+
845+
ze_result = g_ze_ops.zeMemGetAllocProperties(ze_provider->context, ptr,
846+
&mem_alloc_props, NULL);
847+
if (ze_result != ZE_RESULT_SUCCESS) {
848+
LOG_ERR("zeMemGetAllocProperties() failed.");
849+
return ze2umf_result(ze_result);
850+
}
851+
852+
memcpy(&ze_ipc_data->ze_handle, &fd_desc.fd, sizeof(fd_desc.fd));
853+
//LOG_ERR("ptr is %p", ptr);
854+
//LOG_ERR("context is %p, device is %p", ze_provider->context,
855+
// ze_provider->device);
856+
// LOG_ERR("Exporting file descriptor %d", fd_desc.fd);
857+
// LOG_ERR("size is %zu", size);
858+
// LOG_ERR("pid: %d", utils_getpid());
785859
}
786860

861+
ze_ipc_data->size = size;
787862
ze_ipc_data->pid = utils_getpid();
788863

789864
return UMF_RESULT_SUCCESS;
@@ -831,17 +906,44 @@ static umf_result_t ze_memory_provider_open_ipc_handle(void *provider,
831906
LOG_PERR("duplicating file descriptor failed");
832907
return umf_result;
833908
}
909+
LOG_ERR("Duplicated fd %d to fd %d", fd_remote, fd_local);
834910
memcpy(&ze_ipc_handle, &fd_local, sizeof(fd_local));
835911
}
836912

837-
ze_result = g_ze_ops.zeMemOpenIpcHandle(
838-
ze_provider->context, ze_provider->device, ze_ipc_handle, 0, ptr);
839-
if (fd_local != -1) {
840-
(void)utils_close_fd(fd_local);
841-
}
842-
if (ze_result != ZE_RESULT_SUCCESS) {
843-
LOG_ERR("zeMemOpenIpcHandle() failed.");
844-
return ze2umf_result(ze_result);
913+
if (ze_provider->exchangePolicy ==
914+
UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC) {
915+
ze_result = g_ze_ops.zeMemOpenIpcHandle(
916+
ze_provider->context, ze_provider->device, ze_ipc_handle, 0, ptr);
917+
if (fd_local != -1) {
918+
(void)utils_close_fd(fd_local);
919+
}
920+
if (ze_result != ZE_RESULT_SUCCESS) {
921+
LOG_ERR("zeMemOpenIpcHandle() failed.");
922+
return ze2umf_result(ze_result);
923+
}
924+
} else { // UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT
925+
ze_external_memory_import_fd_t import_fd = {
926+
.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD,
927+
.pNext = NULL,
928+
.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF,
929+
.fd = fd_local};
930+
931+
ze_device_mem_alloc_desc_t alloc_desc = {
932+
.stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC,
933+
.pNext = &import_fd,
934+
.flags = 0,
935+
.ordinal = 0};
936+
ze_result = g_ze_ops.zeMemAllocDevice(ze_provider->context, &alloc_desc,
937+
ze_ipc_data->size, 0,
938+
ze_provider->device, ptr);
939+
if (ze_result != ZE_RESULT_SUCCESS) {
940+
LOG_ERR("zeMemAllocDevice() failed.");
941+
return ze2umf_result(ze_result);
942+
}
943+
944+
if (fd_local != -1) {
945+
(void)utils_close_fd(fd_local);
946+
}
845947
}
846948

847949
return UMF_RESULT_SUCCESS;
@@ -1027,6 +1129,14 @@ umf_result_t umfLevelZeroMemoryProviderParamsSetFreePolicy(
10271129
return UMF_RESULT_ERROR_NOT_SUPPORTED;
10281130
}
10291131

1132+
umf_result_t umfLevelZeroMemoryProviderParamsSetMemoryExchangePolicy(
1133+
umf_level_zero_memory_provider_params_handle_t hParams,
1134+
umf_level_zero_memory_provider_memory_exchange_policy_t policy) {
1135+
(void)hParams;
1136+
(void)policy;
1137+
return UMF_RESULT_ERROR_NOT_SUPPORTED;
1138+
}
1139+
10301140
umf_result_t umfLevelZeroMemoryProviderParamsSetDeviceOrdinal(
10311141
umf_level_zero_memory_provider_params_handle_t hParams,
10321142
uint32_t deviceOrdinal) {

0 commit comments

Comments
 (0)