Skip to content

Commit ff3dd93

Browse files
authored
Merge pull request #507 from vinser52/svinogra_ipc_fix
Extend ipc_level_zero.c example
2 parents d3b8b05 + 1587105 commit ff3dd93

File tree

2 files changed

+215
-20
lines changed

2 files changed

+215
-20
lines changed

examples/basic/ipc_level_zero.c

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ int create_level_zero_pool(ze_context_handle_t context,
2929
umf_result_t umf_result = umfMemoryProviderCreate(
3030
umfLevelZeroMemoryProviderOps(), &params, &provider);
3131
if (umf_result != UMF_RESULT_SUCCESS) {
32-
fprintf(stderr, "Failed to create Level Zero memory provider!\n");
32+
fprintf(stderr,
33+
"ERROR: Failed to create Level Zero memory provider!\n");
3334
return -1;
3435
}
3536

@@ -39,7 +40,7 @@ int create_level_zero_pool(ze_context_handle_t context,
3940
umf_result = umfPoolCreate(umfDisjointPoolOps(), provider, &disjoint_params,
4041
flags, pool);
4142
if (umf_result != UMF_RESULT_SUCCESS) {
42-
fprintf(stderr, "Failed to create pool!\n");
43+
fprintf(stderr, "ERROR: Failed to create pool!\n");
4344
return -1;
4445
}
4546

@@ -52,60 +53,71 @@ int main(void) {
5253
ze_device_handle_t device = NULL;
5354
ze_context_handle_t producer_context = NULL;
5455
ze_context_handle_t consumer_context = NULL;
56+
const size_t BUFFER_SIZE = 1024;
57+
const size_t BUFFER_PATTERN = 0x42;
5558
int ret = init_level_zero();
5659
if (ret != 0) {
57-
fprintf(stderr, "Failed to init Level 0!\n");
60+
fprintf(stderr, "ERROR: Failed to init Level 0!\n");
5861
return ret;
5962
}
6063

6164
ret = find_driver_with_gpu(&driver_idx, &driver);
6265
if (ret || driver == NULL) {
63-
fprintf(stderr, "Cannot find L0 driver with GPU device!\n");
66+
fprintf(stderr, "ERROR: Cannot find L0 driver with GPU device!\n");
6467
return ret;
6568
}
6669

6770
ret = create_context(driver, &producer_context);
6871
if (ret != 0) {
69-
fprintf(stderr, "Failed to create L0 context!\n");
72+
fprintf(stderr, "ERROR: Failed to create L0 context!\n");
7073
return ret;
7174
}
7275

7376
ret = create_context(driver, &consumer_context);
7477
if (ret != 0) {
75-
fprintf(stderr, "Failed to create L0 context!\n");
78+
fprintf(stderr, "ERROR: Failed to create L0 context!\n");
7679
return ret;
7780
}
7881

7982
ret = find_gpu_device(driver, &device);
8083
if (ret || device == NULL) {
81-
fprintf(stderr, "Cannot find GPU device!\n");
84+
fprintf(stderr, "ERROR: Cannot find GPU device!\n");
8285
return ret;
8386
}
8487

8588
// create producer pool
8689
umf_memory_pool_handle_t producer_pool = 0;
8790
ret = create_level_zero_pool(producer_context, device, &producer_pool);
8891
if (ret != 0) {
89-
fprintf(stderr, "Failed to create producer pool!\n");
92+
fprintf(stderr, "ERROR: Failed to create producer pool!\n");
9093
return ret;
9194
}
9295

9396
fprintf(stdout, "Producer pool created.\n");
9497

95-
void *initial_buf = umfPoolMalloc(producer_pool, 1024);
98+
void *initial_buf = umfPoolMalloc(producer_pool, BUFFER_SIZE);
9699
if (!initial_buf) {
97-
fprintf(stderr, "Failed to allocate buffer from UMF pool!\n");
100+
fprintf(stderr, "ERROR: Failed to allocate buffer from UMF pool!\n");
98101
return -1;
99102
}
100103

101104
fprintf(stdout, "Buffer allocated from the producer pool.\n");
102105

106+
ret = level_zero_fill(producer_context, device, initial_buf, BUFFER_SIZE,
107+
&BUFFER_PATTERN, sizeof(BUFFER_PATTERN));
108+
if (ret != 0) {
109+
fprintf(stderr, "ERROR: Failed to fill the buffer with pattern!\n");
110+
return ret;
111+
}
112+
113+
fprintf(stdout, "Buffer filled with pattern.\n");
114+
103115
umf_ipc_handle_t ipc_handle = NULL;
104116
size_t handle_size = 0;
105117
umf_result_t umf_result =
106118
umfGetIPCHandle(initial_buf, &ipc_handle, &handle_size);
107119
if (umf_result != UMF_RESULT_SUCCESS) {
108-
fprintf(stderr, "Failed to get IPC handle!\n");
120+
fprintf(stderr, "ERROR: Failed to get IPC handle!\n");
109121
return -1;
110122
}
111123

@@ -115,7 +127,7 @@ int main(void) {
115127
umf_memory_pool_handle_t consumer_pool = 0;
116128
ret = create_level_zero_pool(consumer_context, device, &consumer_pool);
117129
if (ret != 0) {
118-
fprintf(stderr, "Failed to create consumer pool!\n");
130+
fprintf(stderr, "ERROR: Failed to create consumer pool!\n");
119131
return ret;
120132
}
121133

@@ -124,27 +136,41 @@ int main(void) {
124136
void *mapped_buf = NULL;
125137
umf_result = umfOpenIPCHandle(consumer_pool, ipc_handle, &mapped_buf);
126138
if (umf_result != UMF_RESULT_SUCCESS) {
127-
fprintf(stderr, "Failed to open IPC handle!\n");
139+
fprintf(stderr, "ERROR: Failed to open IPC handle!\n");
128140
return -1;
129141
}
130142

131143
fprintf(stdout, "IPC handle opened in the consumer pool.\n");
132144

133-
// Now we have two mappings (belongs to different Level Zero contexts) to the same physical memory region:
134-
// * the initial mapping, pointed by initial_buf, we get by allocating memory from the producer pool.
135-
// * the second mapping, pointed by mapped_buf, we get by opening the IPC handle in the consumer pool.
145+
size_t *tmp_buf = malloc(BUFFER_SIZE);
146+
ret = level_zero_copy(consumer_context, device, tmp_buf, mapped_buf,
147+
BUFFER_SIZE);
148+
if (ret != 0) {
149+
fprintf(stderr, "ERROR: Failed to copy mapped_buf to host!\n");
150+
return ret;
151+
}
152+
153+
// Verify the content of the buffer
154+
for (size_t i = 0; i < BUFFER_SIZE / sizeof(BUFFER_PATTERN); ++i) {
155+
if (tmp_buf[i] != BUFFER_PATTERN) {
156+
fprintf(stderr, "ERROR: mapped_buf does not match initial_buf!\n");
157+
return -1;
158+
}
159+
}
160+
161+
fprintf(stdout, "mapped_buf matches initial_buf.\n");
136162

137163
umf_result = umfPutIPCHandle(ipc_handle);
138164
if (umf_result != UMF_RESULT_SUCCESS) {
139-
fprintf(stderr, "Failed to put IPC handle!\n");
165+
fprintf(stderr, "ERROR: Failed to put IPC handle!\n");
140166
return -1;
141167
}
142168

143169
fprintf(stdout, "IPC handle released in the producer pool.\n");
144170

145171
umf_result = umfCloseIPCHandle(mapped_buf);
146172
if (umf_result != UMF_RESULT_SUCCESS) {
147-
fprintf(stderr, "Failed to close IPC handle!\n");
173+
fprintf(stderr, "ERROR: Failed to close IPC handle!\n");
148174
return -1;
149175
}
150176

@@ -157,13 +183,13 @@ int main(void) {
157183

158184
ret = destroy_context(producer_context);
159185
if (ret != 0) {
160-
fprintf(stderr, "Failed to destroy L0 context!\n");
186+
fprintf(stderr, "ERROR: Failed to destroy L0 context!\n");
161187
return ret;
162188
}
163189

164190
ret = destroy_context(consumer_context);
165191
if (ret != 0) {
166-
fprintf(stderr, "Failed to destroy L0 context!\n");
192+
fprintf(stderr, "ERROR: Failed to destroy L0 context!\n");
167193
return ret;
168194
}
169195
return 0;

examples/basic/utils_level_zero.h

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,175 @@ static inline int find_gpu_device(ze_driver_handle_t driver,
219219
return ret;
220220
}
221221

222+
int level_zero_fill(ze_context_handle_t context, ze_device_handle_t device,
223+
void *ptr, size_t size, const void *pattern,
224+
size_t pattern_size) {
225+
int ret = 0;
226+
227+
ze_command_queue_desc_t commandQueueDesc = {
228+
ZE_STRUCTURE_TYPE_COMMAND_QUEUE_DESC,
229+
NULL,
230+
0,
231+
0,
232+
0,
233+
ZE_COMMAND_QUEUE_MODE_DEFAULT,
234+
ZE_COMMAND_QUEUE_PRIORITY_NORMAL};
235+
236+
ze_command_list_desc_t commandListDesc = {
237+
ZE_STRUCTURE_TYPE_COMMAND_LIST_DESC, 0, 0,
238+
ZE_COMMAND_LIST_FLAG_RELAXED_ORDERING};
239+
240+
ze_command_queue_handle_t hCommandQueue;
241+
ze_result_t ze_result = zeCommandQueueCreate(
242+
context, device, &commandQueueDesc, &hCommandQueue);
243+
if (ze_result != ZE_RESULT_SUCCESS) {
244+
fprintf(stderr, "zeCommandQueueCreate() failed!\n");
245+
return -1;
246+
}
247+
248+
ze_command_list_handle_t hCommandList;
249+
ze_result =
250+
zeCommandListCreate(context, device, &commandListDesc, &hCommandList);
251+
if (ze_result != ZE_RESULT_SUCCESS) {
252+
fprintf(stderr, "zeCommandListCreate() failed!\n");
253+
ret = -1;
254+
goto err_queue_destroy;
255+
}
256+
257+
// fill memory with a pattern
258+
ze_result = zeCommandListAppendMemoryFill(
259+
hCommandList, ptr, pattern, pattern_size, size, NULL, 0, NULL);
260+
if (ze_result != ZE_RESULT_SUCCESS) {
261+
fprintf(stderr, "zeCommandListAppendMemoryFill() failed!\n");
262+
ret = -1;
263+
goto err_list_destroy;
264+
}
265+
266+
// close and execute the command list
267+
ze_result = zeCommandListClose(hCommandList);
268+
if (ze_result != ZE_RESULT_SUCCESS) {
269+
fprintf(stderr, "zeCommandListClose() failed!\n");
270+
ret = -1;
271+
goto err_list_destroy;
272+
}
273+
274+
ze_result = zeCommandQueueExecuteCommandLists(hCommandQueue, 1,
275+
&hCommandList, NULL);
276+
if (ze_result != ZE_RESULT_SUCCESS) {
277+
fprintf(stderr, "zeCommandQueueExecuteCommandLists() failed!\n");
278+
ret = -1;
279+
goto err_list_destroy;
280+
}
281+
282+
// sync
283+
ze_result = zeCommandQueueSynchronize(hCommandQueue, UINT64_MAX);
284+
if (ze_result != ZE_RESULT_SUCCESS) {
285+
fprintf(stderr, "zeCommandQueueSynchronize() failed!\n");
286+
ret = -1;
287+
goto err_list_destroy;
288+
}
289+
290+
// cleanup
291+
err_list_destroy:
292+
ze_result = zeCommandListDestroy(hCommandList);
293+
if (ze_result != ZE_RESULT_SUCCESS) {
294+
fprintf(stderr, "zeCommandListDestroy() failed!\n");
295+
ret = -1;
296+
}
297+
298+
err_queue_destroy:
299+
ze_result = zeCommandQueueDestroy(hCommandQueue);
300+
if (ze_result != ZE_RESULT_SUCCESS) {
301+
fprintf(stderr, "zeCommandQueueDestroy() failed!\n");
302+
ret = -1;
303+
}
304+
305+
return ret;
306+
}
307+
308+
int level_zero_copy(ze_context_handle_t context, ze_device_handle_t device,
309+
void *dst_ptr, void *src_ptr, size_t size) {
310+
int ret = 0;
311+
ze_command_queue_desc_t commandQueueDesc = {
312+
ZE_STRUCTURE_TYPE_COMMAND_QUEUE_DESC,
313+
NULL,
314+
0,
315+
0,
316+
0,
317+
ZE_COMMAND_QUEUE_MODE_DEFAULT,
318+
ZE_COMMAND_QUEUE_PRIORITY_NORMAL};
319+
320+
ze_command_list_desc_t commandListDesc = {
321+
ZE_STRUCTURE_TYPE_COMMAND_LIST_DESC, 0, 0,
322+
ZE_COMMAND_LIST_FLAG_RELAXED_ORDERING};
323+
324+
ze_command_queue_handle_t hCommandQueue;
325+
ze_result_t ze_result = zeCommandQueueCreate(
326+
context, device, &commandQueueDesc, &hCommandQueue);
327+
if (ze_result != ZE_RESULT_SUCCESS) {
328+
fprintf(stderr, "zeCommandQueueCreate() failed!\n");
329+
return -1;
330+
}
331+
332+
ze_command_list_handle_t hCommandList;
333+
ze_result =
334+
zeCommandListCreate(context, device, &commandListDesc, &hCommandList);
335+
if (ze_result != ZE_RESULT_SUCCESS) {
336+
fprintf(stderr, "zeCommandListCreate() failed!\n");
337+
ret = -1;
338+
goto err_queue_destroy;
339+
}
340+
341+
// copy from device memory to host memory
342+
ze_result = zeCommandListAppendMemoryCopy(hCommandList, dst_ptr, src_ptr,
343+
size, NULL, 0, NULL);
344+
if (ze_result != ZE_RESULT_SUCCESS) {
345+
fprintf(stderr, "zeCommandListAppendMemoryCopy() failed!\n");
346+
ret = -1;
347+
goto err_list_destroy;
348+
}
349+
350+
// close and execute the command list
351+
ze_result = zeCommandListClose(hCommandList);
352+
if (ze_result != ZE_RESULT_SUCCESS) {
353+
fprintf(stderr, "zeCommandListClose() failed!\n");
354+
ret = -1;
355+
goto err_list_destroy;
356+
}
357+
358+
ze_result = zeCommandQueueExecuteCommandLists(hCommandQueue, 1,
359+
&hCommandList, NULL);
360+
if (ze_result != ZE_RESULT_SUCCESS) {
361+
fprintf(stderr, "zeCommandQueueExecuteCommandLists() failed!\n");
362+
ret = -1;
363+
goto err_list_destroy;
364+
}
365+
366+
ze_result = zeCommandQueueSynchronize(hCommandQueue, UINT64_MAX);
367+
if (ze_result != ZE_RESULT_SUCCESS) {
368+
fprintf(stderr, "zeCommandQueueSynchronize() failed!\n");
369+
ret = -1;
370+
goto err_list_destroy;
371+
}
372+
373+
// cleanup
374+
err_list_destroy:
375+
ze_result = zeCommandListDestroy(hCommandList);
376+
if (ze_result != ZE_RESULT_SUCCESS) {
377+
fprintf(stderr, "zeCommandListDestroy() failed!\n");
378+
ret = -1;
379+
}
380+
381+
err_queue_destroy:
382+
ze_result = zeCommandQueueDestroy(hCommandQueue);
383+
if (ze_result != ZE_RESULT_SUCCESS) {
384+
fprintf(stderr, "zeCommandQueueDestroy() failed!\n");
385+
ret = -1;
386+
}
387+
388+
return ret;
389+
}
390+
222391
int create_context(ze_driver_handle_t driver, ze_context_handle_t *context) {
223392
ze_result_t ze_result;
224393
ze_context_desc_t ctxtDesc = {

0 commit comments

Comments
 (0)