-
Notifications
You must be signed in to change notification settings - Fork 35
add an example for combination of Disjoint Pool and L0 #384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,41 @@ if(UMF_BUILD_LIBUMF_POOL_SCALABLE AND UMF_ENABLE_POOL_TRACKING) | |
|
||
set_tests_properties(${EXAMPLE_NAME} PROPERTIES LABELS "example") | ||
|
||
if(WINDOWS) | ||
# append PATH to DLLs | ||
set_property(TEST ${EXAMPLE_NAME} PROPERTY ENVIRONMENT_MODIFICATION | ||
"${DLL_PATH_LIST}") | ||
endif() | ||
else() | ||
message(STATUS "Basic example requires UMF_BUILD_LIBUMF_POOL_SCALABLE and " | ||
"UMF_ENABLE_POOL_TRACKING to be turned ON - skipping") | ||
endif() | ||
|
||
if(UMF_BUILD_GPU_EXAMPLES | ||
AND UMF_BUILD_LIBUMF_POOL_DISJOINT | ||
AND UMF_BUILD_LEVEL_ZERO_PROVIDER | ||
AND LINUX) | ||
set(EXAMPLE_NAME umf_example_gpu_shared_memory) | ||
|
||
add_umf_executable( | ||
NAME ${EXAMPLE_NAME} | ||
SRCS basic/gpu_shared_memory.c | ||
LIBS umf disjoint_pool ze_loader) | ||
|
||
target_include_directories( | ||
${EXAMPLE_NAME} | ||
PRIVATE ${LEVEL_ZERO_INCLUDE_DIRS} ${UMF_CMAKE_SOURCE_DIR}/src/utils | ||
${UMF_CMAKE_SOURCE_DIR}/include) | ||
|
||
target_link_directories(${EXAMPLE_NAME} PRIVATE ${LIBHWLOC_LIBRARY_DIRS}) | ||
|
||
add_test( | ||
NAME ${EXAMPLE_NAME} | ||
COMMAND ${EXAMPLE_NAME} | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) | ||
|
||
set_tests_properties(${EXAMPLE_NAME} PROPERTIES LABELS "example") | ||
|
||
if(WINDOWS) | ||
# append PATH to DLLs | ||
set_property(TEST ${EXAMPLE_NAME} PROPERTY ENVIRONMENT_MODIFICATION | ||
|
@@ -31,6 +66,7 @@ if(UMF_BUILD_LIBUMF_POOL_SCALABLE AND UMF_ENABLE_POOL_TRACKING) | |
else() | ||
message( | ||
STATUS | ||
"Basic example requires UMF_BUILD_LIBUMF_POOL_SCALABLE and UMF_ENABLE_POOL_TRACKING | ||
to be turned ON - skipping") | ||
"GPU shared memory example requires UMF_BUILD_GPU_EXAMPLES, " | ||
"UMF_BUILD_LEVEL_ZERO_PROVIDER and UMF_BUILD_LIBUMF_POOL_DISJOINT " | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This message is incorrect. Please fix it to include build GPU examples variable. (BTW do we really need "UMF_BUILD_GPU_EXAMPLES" variable - imho if all dependencies are ON, we should build it by default) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I second the question - do we need extra There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Testing (what we actually run) has nothing to do with the build options. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I'm saying, is we could (as Łukasz stated above) build it all the time, as long as L0_PROVIDER is ON. We don't need this new flag just for building. Nontheless, I guess, we could clean flags separately later on... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe we need a dedicated cmake option for GPU examples (UMF_BUILD_GPU_EXAMPLES). After the #427 is implemented we will have examples that will be installed with a pre-built version of UMF. So customer needs an option to disable/enable GPU examples. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that this extra flag is not needed as when it is turned As it is now, the user would have to set both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that all changes around cmake files, flags and folders could be done as a part of #427 |
||
"to be turned ON - skipping") | ||
endif() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,29 @@ | ||
# Examples | ||
|
||
This directory contains examples of UMF usage. Each example has a brief description below. | ||
This directory contains examples of UMF usage. Each example has a brief | ||
description below. | ||
|
||
## Basic | ||
|
||
This example covers the basics of UMF API. It walks you through a basic usage of a memory provider and a pool allocator. OS memory provider and Scalable pool are used for this purpose. | ||
This example covers the basics of UMF API. It walks you through a basic usage | ||
of a memory provider and a pool allocator. OS memory provider and Scalable pool | ||
are used for this purpose. | ||
|
||
### Required CMake configuration flags | ||
* UMF_BUILD_LIBUMF_POOL_SCALABLE=ON | ||
* UMF_ENABLE_POOL_TRACKING=ON | ||
### Requirements | ||
* libtbb-dev needed for Scalable Pool | ||
* set UMF_BUILD_LIBUMF_POOL_SCALABLE and UMF_ENABLE_POOL_TRACKING CMake | ||
configuration flags to ON | ||
|
||
## GPU shared memory | ||
|
||
This example demonstrates the usage of Intel's Level Zero API for accessing GPU | ||
memory. It initializes the Level Zero driver, discovers all the driver | ||
instances, and creates GPU context for the first found GPU device. Next, it | ||
sets up a combination of UMF Level Zero memory provider and a Disjoint Pool | ||
memory pool to allocate from shared memory. If any step fails, the program | ||
cleans up and exits with an error status. | ||
|
||
### Requirements | ||
* Level Zero headers and libraries | ||
* compatible GPU with installed driver | ||
* set UMF_BUILD_GPU_EXAMPLES, UMF_BUILD_LIBUMF_POOL_DISJOINT and UMF_BUILD_LEVEL_ZERO_PROVIDER CMake configuration flags to ON |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/* | ||
lplewa marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* | ||
* Copyright (C) 2024 Intel Corporation | ||
* | ||
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. | ||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
* | ||
*/ | ||
|
||
#include <umf/memory_pool.h> | ||
#include <umf/pools/pool_disjoint.h> | ||
#include <umf/providers/provider_level_zero.h> | ||
|
||
#include "utils_level_zero.h" | ||
|
||
int main(void) { | ||
// A result object for storing UMF API result status | ||
umf_result_t res; | ||
|
||
uint32_t driverId = 0; | ||
ze_driver_handle_t hDriver = NULL; | ||
ze_device_handle_t hDevice = NULL; | ||
ze_context_handle_t hContext = NULL; | ||
|
||
// Initialize Level Zero | ||
int ret = init_level_zero(); | ||
if (ret != 0) { | ||
fprintf(stderr, "Failed to init Level 0!\n"); | ||
return ret; | ||
} | ||
|
||
ret = find_driver_with_gpu(&driverId, &hDriver); | ||
if (ret || hDriver == NULL) { | ||
fprintf(stderr, "Cannot find L0 driver with GPU device!\n"); | ||
return ret; | ||
} | ||
|
||
ret = find_gpu_device(hDriver, &hDevice); | ||
if (ret || hDevice == NULL) { | ||
fprintf(stderr, "Cannot find GPU device!\n"); | ||
return ret; | ||
} | ||
|
||
ret = create_context(hDriver, &hContext); | ||
if (ret != 0) { | ||
fprintf(stderr, "Failed to create L0 context!\n"); | ||
return ret; | ||
} | ||
lplewa marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Setup parameters for the Level Zero memory provider. It will be used for | ||
// allocating memory from Level Zero devices. | ||
level_zero_memory_provider_params_t ze_memory_provider_params; | ||
ze_memory_provider_params.level_zero_context_handle = hContext; | ||
ze_memory_provider_params.level_zero_device_handle = hDevice; | ||
// Set the memory type to shared to allow the memory to be accessed on both | ||
// CPU and GPU. | ||
ze_memory_provider_params.memory_type = UMF_MEMORY_TYPE_SHARED; | ||
|
||
// Create Level Zero memory provider | ||
umf_memory_provider_handle_t ze_memory_provider; | ||
res = umfMemoryProviderCreate(umfLevelZeroMemoryProviderOps(), | ||
&ze_memory_provider_params, | ||
&ze_memory_provider); | ||
if (res != UMF_RESULT_SUCCESS) { | ||
fprintf(stderr, "Failed to create a memory provider!\n"); | ||
ret = -1; | ||
goto level_zero_destroy; | ||
} | ||
|
||
printf("Level Zero memory provider created at %p\n", | ||
(void *)ze_memory_provider); | ||
|
||
// Setup parameters for the Disjoint Pool. It will be used for managing the | ||
// memory allocated using memory provider. | ||
umf_disjoint_pool_params_t disjoint_memory_pool_params = | ||
umfDisjointPoolParamsDefault(); | ||
// Set the Slab Min Size to 64KB - the page size for GPU allocations | ||
disjoint_memory_pool_params.SlabMinSize = 64 * 1024L; | ||
// We would keep only single slab per each allocation bucket | ||
disjoint_memory_pool_params.Capacity = 1; | ||
// Set the maximum poolable size to 64KB - objects with size above this | ||
// limit will not be stored/allocated from the pool. | ||
disjoint_memory_pool_params.MaxPoolableSize = 64 * 1024L; | ||
// Enable tracing | ||
disjoint_memory_pool_params.PoolTrace = 1; | ||
|
||
// Create Disjoint Pool memory pool. | ||
umf_memory_pool_handle_t ze_disjoint_memory_pool; | ||
res = umfPoolCreate(umfDisjointPoolOps(), ze_memory_provider, | ||
&disjoint_memory_pool_params, UMF_POOL_CREATE_FLAG_NONE, | ||
&ze_disjoint_memory_pool); | ||
if (res != UMF_RESULT_SUCCESS) { | ||
fprintf(stderr, "Failed to create a memory pool!\n"); | ||
ret = -1; | ||
goto memory_provider_destroy; | ||
} | ||
|
||
printf("Disjoint Pool created at %p\n", (void *)ze_disjoint_memory_pool); | ||
|
||
// Allocate some memory from the pool | ||
int *ptr = umfPoolMalloc(ze_disjoint_memory_pool, sizeof(int)); | ||
if (res != UMF_RESULT_SUCCESS) { | ||
fprintf(stderr, "Failed to allocate memory from the memory pool!\n"); | ||
ret = -1; | ||
goto memory_pool_destroy; | ||
} | ||
|
||
// Use allocated memory | ||
*ptr = 1; | ||
|
||
// Free allocated memory | ||
res = umfFree(ptr); | ||
if (res != UMF_RESULT_SUCCESS) { | ||
fprintf(stderr, "Failed to free memory to the pool!\n"); | ||
ret = -1; | ||
goto memory_pool_destroy; | ||
} | ||
printf("Freed memory at %p\n", (void *)ptr); | ||
|
||
// Cleanup | ||
memory_pool_destroy: | ||
umfPoolDestroy(ze_disjoint_memory_pool); | ||
|
||
memory_provider_destroy: | ||
umfMemoryProviderDestroy(ze_memory_provider); | ||
|
||
level_zero_destroy: | ||
ret = destroy_context(hContext); | ||
return ret; | ||
} |
Uh oh!
There was an error while loading. Please reload this page.