8000 Increase refcount to ze_loader/CUDA libraries when Level Zero/CUDA providers are used by vinser52 · Pull Request #1086 · oneapi-src/unified-memory-framework · GitHub
[go: up one dir, main page]

Skip to content

Increase refcount to ze_loader/CUDA libraries when Level Zero/CUDA providers are used #1086

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

Merged
merged 5 commits into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ function(add_umf_benchmark)
set_property(TEST ${BENCH_NAME} PROPERTY ENVIRONMENT_MODIFICATION
"${DLL_PATH_LIST}")
endif()
if(LINUX)
# prepend LD_LIBRARY_PATH with ${CMAKE_BINARY_DIR}/lib it is required
# because ${CMAKE_BINARY_DIR}/lib contains libze_loader.so and tests
# should use it instead of system one.
set_property(
TEST ${BENCH_NAME}
PROPERTY ENVIRONMENT_MODIFICATION
"LD_LIBRARY_PATH=path_list_prepend:${CMAKE_BINARY_DIR}/lib"
)
endif()

if(UMF_BUILD_LIBUMF_POOL_DISJOINT)
target_compile_definitions(${BENCH_NAME}
Expand Down
20 changes: 20 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ if(UMF_BUILD_GPU_EXAMPLES
set_property(TEST ${EXAMPLE_NAME} PROPERTY ENVIRONMENT_MODIFICATION
"${DLL_PATH_LIST}")
endif()
if(LINUX)
# prepend LD_LIBRARY_PATH with ${CMAKE_BINARY_DIR}/lib it is required
# because ${CMAKE_BINARY_DIR}/lib contains libze_loader.so and tests
# should use it instead of system one.
set_property(
TEST ${EXAMPLE_NAME}
PROPERTY ENVIRONMENT_MODIFICATION
"LD_LIBRARY_PATH=path_list_prepend:${CMAKE_BINARY_DIR}/lib"
)
endif()
else()
message(STATUS "GPU Level Zero shared memory example requires "
"UMF_BUILD_GPU_EXAMPLES, UMF_BUILD_LEVEL_ZERO_PROVIDER and "
Expand Down Expand Up @@ -151,6 +161,16 @@ if(UMF_BUILD_GPU_EXAMPLES
set_property(TEST ${EXAMPLE_NAME} PROPERTY ENVIRONMENT_MODIFICATION
"${DLL_PATH_LIST}")
endif()
if(LINUX)
# prepend LD_LIBRARY_PATH with ${CMAKE_BINARY_DIR}/lib it is required
# because ${CMAKE_BINARY_DIR}/lib contains libze_loader.so and tests
# should use it instead of system one.
set_property(
TEST ${EXAMPLE_NAME}
PROPERTY ENVIRONMENT_MODIFICATION
"LD_LIBRARY_PATH=path_list_prepend:${CMAKE_BINARY_DIR}/lib"
)
endif()
else()
message(
STATUS
Expand Down
4 changes: 2 additions & 2 deletions examples/ipc_level_zero/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2024 Intel Corporation
# Copyright (C) 2024-2025 Intel Corporation
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

Expand Down Expand Up @@ -69,6 +69,6 @@ if(LINUX)
TEST ${EXAMPLE_NAME}
PROPERTY
ENVIRONMENT_MODIFICATION
"LD_LIBRARY_PATH=path_list_append:${LIBUMF_LIBRARY_DIRS};LD_LIBRARY_PATH=path_list_append:${LIBHWLOC_LIBRARY_DIRS}"
"LD_LIBRARY_PATH=path_list_prepend:${LIBUMF_LIBRARY_DIRS};LD_LIBRARY_PATH=path_list_append:${LIBHWLOC_LIBRARY_DIRS}"
)
endif()
4 changes: 2 additions & 2 deletions examples/level_zero_shared_memory/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2024 Intel Corporation
# Copyright (C) 2024-2025 Intel Corporation
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

Expand Down Expand Up @@ -70,6 +70,6 @@ if(LINUX)
TEST ${EXAMPLE_NAME}
PROPERTY
ENVIRONMENT_MODIFICATION
"LD_LIBRARY_PATH=path_list_append:${LIBUMF_LIBRARY_DIRS};LD_LIBRARY_PATH=path_list_append:${LIBHWLOC_LIBRARY_DIRS}"
"LD_LIBRARY_PATH=path_list_prepend:${LIBUMF_LIBRARY_DIRS};LD_LIBRARY_PATH=path_list_append:${LIBHWLOC_LIBRARY_DIRS}"
)
endif()
4 changes: 3 additions & 1 deletion include/umf/base.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (C) 2023-2024 Intel Corporation
* Copyright (C) 2023-2025 Intel Corporation
*
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Expand Down Expand Up @@ -45,6 +45,8 @@ typedef enum umf_result_t {
UMF_RESULT_ERROR_NOT_SUPPORTED = 5, ///< Operation not supported
UMF_RESULT_ERROR_USER_SPECIFIC =
6, ///< Failure in user provider code (i.e in user provided callback)
UMF_RESULT_ERROR_DEPENDENCY_UNAVAILABLE =
7, ///< External required dependency is unavailable or missing
UMF_RESULT_ERROR_UNKNOWN = 0x7ffffffe ///< Unknown or internal error
} umf_result_t;

Expand Down
6 changes: 5 additions & 1 deletion src/libumf.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (C) 2024 Intel Corporation
* Copyright (C) 2024-2025 Intel Corporation
*
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Expand All @@ -12,6 +12,8 @@
#include "base_alloc_global.h"
#include "ipc_cache.h"
#include "memspace_internal.h"
#include "provider_cuda_internal.h"
#include "provider_level_zero_internal.h"
#include "provider_tracking.h"
#include "utils_common.h"
#include "utils_log.h"
Expand Down Expand Up @@ -79,6 +81,8 @@ void umfTearDown(void) {
LOG_DEBUG("UMF base allocator destroyed");

fini_umfTearDown:
fini_ze_global_state();
fini_cu_global_state();
LOG_DEBUG("UMF library finalized");
}
}
Expand Down
57 changes: 39 additions & 18 deletions src/provider/provider_cuda.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,19 @@
#include <umf.h>
#include <umf/providers/provider_cuda.h>

#include "provider_cuda_internal.h"
#include "utils_load_library.h"
#include "utils_log.h"

static void *cu_lib_handle = NULL;

void fini_cu_global_state(void) {
if (cu_lib_handle) {
utils_close_library(cu_lib_handle);
cu_lib_handle = NULL;
}
}

#if defined(UMF_NO_CUDA_PROVIDER)

umf_result_t umfCUDAMemoryProviderParamsCreate(
Expand Down Expand Up @@ -88,7 +99,6 @@ umf_memory_provider_ops_t *umfCUDAMemoryProviderOps(void) {
#include "utils_assert.h"
#include "utils_common.h"
#include "utils_concurrency.h"
#include "utils_load_library.h"
#include "utils_log.h"
#include "utils_sanitizers.h"

Expand Down Expand Up @@ -180,37 +190,45 @@ static void init_cu_global_state(void) {
#else
const char *lib_name = "libcuda.so";
#endif
// check if CUDA shared library is already loaded
// we pass 0 as a handle to search the global symbol table
// The CUDA shared library should be already loaded by the user
// of the CUDA provider. UMF just want to reuse it
// and increase the reference count to the CUDA shared library.
void *lib_handle =
utils_open_library(lib_name, UMF_UTIL_OPEN_LIBRARY_NO_LOAD);
if (!lib_handle) {
LOG_ERR("Failed to open CUDA shared library");
Init_cu_global_state_failed = true;
return;
}

// NOTE: some symbols defined in the lib have _vX postfixes - it is
// important to load the proper version of functions
*(void **)&g_cu_ops.cuMemGetAllocationGranularity =
utils_get_symbol_addr(0, "cuMemGetAllocationGranularity", lib_name);
*(void **)&g_cu_ops.cuMemGetAllocationGranularity = utils_get_symbol_addr(
lib_handle, "cuMemGetAllocationGranularity", lib_name);
*(void **)&g_cu_ops.cuMemAlloc =
utils_get_symbol_addr(0, "cuMemAlloc_v2", lib_name);
utils_get_symbol_addr(lib_handle, "cuMemAlloc_v2", lib_name);
*(void **)&g_cu_ops.cuMemHostAlloc =
utils_get_symbol_addr(0, "cuMemHostAlloc", lib_name);
utils_get_symbol_addr(lib_handle, "cuMemHostAlloc", lib_name);
*(void **)&g_cu_ops.cuMemAllocManaged =
utils_get_symbol_addr(0, "cuMemAllocManaged", lib_name);
utils_get_symbol_addr(lib_handle, "cuMemAllocManaged", lib_name);
*(void **)&g_cu_ops.cuMemFree =
utils_get_symbol_addr(0, "cuMemFree_v2", lib_name);
utils_get_symbol_addr(lib_handle, "cuMemFree_v2", lib_name);
*(void **)&g_cu_ops.cuMemFreeHost =
utils_get_symbol_addr(0, "cuMemFreeHost", lib_name);
utils_get_symbol_addr(lib_handle, "cuMemFreeHost", lib_name);
*(void **)&g_cu_ops.cuGetErrorName =
utils_get_symbol_addr(0, "cuGetErrorName", lib_name);
utils_get_symbol_addr(lib_handle, "cuGetErrorName", lib_name);
*(void **)&g_cu_ops.cuGetErrorString =
utils_get_symbol_addr(0, "cuGetErrorString", lib_name);
utils_get_symbol_addr(lib_handle, "cuGetErrorString", lib_name);
*(void **)&g_cu_ops.cuCtxGetCurrent =
utils_get_symbol_addr(0, "cuCtxGetCurrent", lib_name);
utils_get_symbol_addr(lib_handle, "cuCtxGetCurrent", lib_name);
*(void **)&g_cu_ops.cuCtxSetCurrent =
utils_get_symbol_addr(0, "cuCtxSetCurrent", lib_name);
utils_get_symbol_addr(lib_handle, "cuCtxSetCurrent", lib_name);
*(void **)&g_cu_ops.cuIpcGetMemHandle =
utils_get_symbol_addr(0, "cuIpcGetMemHandle", lib_name);
utils_get_symbol_addr(lib_handle, "cuIpcGetMemHandle", lib_name);
*(void **)&g_cu_ops.cuIpcOpenMemHandle =
utils_get_symbol_addr(0, "cuIpcOpenMemHandle_v2", lib_name);
utils_get_symbol_addr(lib_handle, "cuIpcOpenMemHandle_v2", lib_name);
*(void **)&g_cu_ops.cuIpcCloseMemHandle =
utils_get_symbol_addr(0, "cuIpcCloseMemHandle", lib_name);
utils_get_symbol_addr(lib_handle, "cuIpcCloseMemHandle", lib_name);

if (!g_cu_ops.cuMemGetAllocationGranularity || !g_cu_ops.cuMemAlloc ||
!g_cu_ops.cuMemHostAlloc || !g_cu_ops.cuMemAllocManaged ||
Expand All @@ -221,7 +239,10 @@ static void init_cu_global_state(void) {
!g_cu_ops.cuIpcCloseMemHandle) {
LOG_FATAL("Required CUDA symbols not found.");
Init_cu_global_state_failed = true;
utils_close_library(lib_handle);
return;
}
cu_lib_handle = lib_handle;
}

umf_result_t umfCUDAMemoryProviderParamsCreate(
Expand Down Expand Up @@ -327,7 +348,7 @@ static umf_result_t cu_memory_provider_initialize(void *params,
utils_init_once(&cu_is_initialized, init_cu_global_state);
if (Init_cu_global_state_failed) {
LOG_FATAL("Loading CUDA symbols failed");
return UMF_RESULT_ERROR_UNKNOWN;
return UMF_RESULT_ERROR_DEPENDENCY_UNAVAILABLE;
}

cu_memory_provider_t *cu_provider =
Expand Down
10 changes: 10 additions & 0 deletions src/provider/provider_cuda_internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
*
* Copyright (C) 2025 Intel Corporation
*
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
*/

void fini_cu_global_state(void);
56 changes: 39 additions & 17 deletions src/provider/provider_level_zero.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,19 @@
#include <umf/memory_provider_ops.h>
#include <umf/providers/provider_level_zero.h>

#include "provider_level_zero_internal.h"
#include "utils_load_library.h"
#include "utils_log.h"

static void *ze_lib_handle = NULL;

void fini_ze_global_state(void) {
if (ze_lib_handle) {
utils_close_library(ze_lib_handle);
ze_lib_handle = NULL;
}
}

#if defined(UMF_NO_LEVEL_ZERO_PROVIDER)

umf_result_t umfLevelZeroMemoryProviderParamsCreate(
Expand Down Expand Up @@ -105,7 +116,6 @@ umf_memory_provider_ops_t *umfLevelZeroMemoryProviderOps(void) {
#include "utils_assert.h"
#include "utils_common.h"
#include "utils_concurrency.h"
#include "utils_load_library.h"
#include "utils_log.h"
#include "utils_sanitizers.h"
#include "ze_api.h"
Expand Down Expand Up @@ -207,32 +217,41 @@ static void init_ze_global_state(void) {
#else
const char *lib_name = "libze_loader.so";
#endif
// check if Level Zero shared library is already loaded
// we pass 0 as a handle to search the global symbol table
// The Level Zero shared library should be already loaded by the user
// of the Level Zero provider. UMF just want to reuse it
// and increase the reference count to the Level Zero shared library.
void *lib_handle =
utils_open_library(lib_name, UMF_UTIL_OPEN_LIBRARY_NO_LOAD);
if (!lib_handle) {
LOG_FATAL("Failed to open Level Zero shared library");
Init_ze_global_state_failed = true;
return;
}

*(void **)&g_ze_ops.zeMemAllocHost =
utils_get_symbol_addr(0, "zeMemAllocHost", lib_name);
utils_get_symbol_addr(lib_handle, "zeMemAllocHost", lib_name);
*(void **)&g_ze_ops.zeMemAllocDevice =
utils_get_symbol_addr(0, "zeMemAllocDevice", lib_name);
utils_get_symbol_addr(lib_handle, "zeMemAllocDevice", lib_name);
*(void **)&g_ze_ops.zeMemAllocShared =
utils_get_symbol_addr(0, "zeMemAllocShared", lib_name);
utils_get_symbol_addr(lib_handle, "zeMemAllocShared", lib_name);
*(void **)&g_ze_ops.zeMemFree =
utils_get_symbol_addr(0, "zeMemFree", lib_name);
utils_get_symbol_addr(lib_handle, "zeMemFree", lib_name);
*(void **)&g_ze_ops.zeMemGetIpcHandle =
utils_get_symbol_addr(0, "zeMemGetIpcHandle", lib_name);
utils_get_symbol_addr(lib_handle, "zeMemGetIpcHandle", lib_name);
*(void **)&g_ze_ops.zeMemPutIpcHandle =
utils_get_symbol_addr(0, "zeMemPutIpcHandle", lib_name);
utils_get_symbol_addr(lib_handle, "zeMemPutIpcHandle", lib_name);
*(void **)&g_ze_ops.zeMemOpenIpcHandle =
utils_get_symbol_addr(0, "zeMemOpenIpcHandle", lib_name);
utils_get_symbol_addr(lib_handle, "zeMemOpenIpcHandle", lib_name);
*(void **)&g_ze_ops.zeMemCloseIpcHandle =
utils_get_symbol_addr(0, "zeMemCloseIpcHandle", lib_name);
*(void **)&g_ze_ops.zeContextMakeMemoryResident =
utils_get_symbol_addr(0, "zeContextMakeMemoryResident", lib_name);
utils_get_symbol_addr(lib_handle, "zeMemCloseIpcHandle", lib_name);
*(void **)&g_ze_ops.zeContextMakeMemoryResident = utils_get_symbol_addr(
lib_handle, "zeContextMakeMemoryResident", lib_name);
*(void **)&g_ze_ops.zeDeviceGetProperties =
utils_get_symbol_addr(0, "zeDeviceGetProperties", lib_name);
utils_get_symbol_addr(lib_handle, "zeDeviceGetProperties", lib_name);
*(void **)&g_ze_ops.zeMemFreeExt =
utils_get_symbol_addr(0, "zeMemFreeExt", lib_name);
utils_get_symbol_addr(lib_handle, "zeMemFreeExt", lib_name);
*(void **)&g_ze_ops.zeMemGetAllocProperties =
utils_get_symbol_addr(0, "zeMemGetAllocProperties", lib_name);
utils_get_symbol_addr(lib_handle, "zeMemGetAllocProperties", lib_name);

if (!g_ze_ops.zeMemAllocHost || !g_ze_ops.zeMemAllocDevice ||
!g_ze_ops.zeMemAllocShared || !g_ze_ops.zeMemFree ||
Expand All @@ -244,7 +263,10 @@ static void init_ze_global_state(void) {
// starting from Level Zero 1.6
LOG_FATAL("Required Level Zero symbols not found.");
Init_ze_global_state_failed = true;
utils_close_library(lib_handle);
return;
}
ze_lib_handle = lib_handle;
}

umf_result_t umfLevelZeroMemoryProviderParamsCreate(
Expand Down Expand Up @@ -551,7 +573,7 @@ static umf_result_t ze_memory_provider_initialize(void *params,
utils_init_once(&ze_is_initialized, init_ze_global_state);
if (Init_ze_global_state_failed) {
LOG_FATAL("Loading Level Zero symbols failed");
return UMF_RESULT_ERROR_UNKNOWN;
return UMF_RESULT_ERROR_DEPENDENCY_UNAVAILABLE;
}

ze_memory_provider_t *ze_provider =
Expand Down
10 changes: 10 additions & 0 deletions src/provider/provider_level_zero_internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
*
* Copyright (C) 2025 Intel Corporation
*
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
*/

void fini_ze_global_state(void);
9 changes: 7 additions & 2 deletions src/utils/utils_level_zero.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,15 @@ int InitLevelZeroOps() {
const char *lib_name = "libze_loader.so";
#endif
// Load Level Zero symbols
// NOTE that we use UMF_UTIL_OPEN_LIBRARY_GLOBAL which add all loaded symbols to the
#if OPEN_ZE_LIBRARY_GLOBAL
// NOTE UMF_UTIL_OPEN_LIBRARY_GLOBAL adds all loaded symbols to the
// global symbol table.
int open_flags = UMF_UTIL_OPEN_LIBRARY_GLOBAL;
#else
int open_flags = 0;
#endif
zeDlHandle = std::unique_ptr<void, DlHandleCloser>(
utils_open_library(lib_name, UMF_UTIL_OPEN_LIBRARY_GLOBAL));
utils_open_library(lib_name, open_flags));
*(void **)&libze_ops.zeInit =
utils_get_symbol_addr(zeDlHandle.get(), "zeInit", lib_name);
if (libze_ops.zeInit == nullptr) {
Expand Down
Loading
Loading
0