From f979485de5fd7d2c0b282a9ec94ff7e7e642eb0a Mon Sep 17 00:00:00 2001 From: Rafal Rudnicki Date: Thu, 15 May 2025 13:20:11 +0000 Subject: [PATCH] a --- benchmark/ubench.c | 393 +++++++++----------- docs/config/api.rst | 8 + include/umf/memory_props.h | 67 ++++ include/umf/providers/provider_level_zero.h | 6 + src/CMakeLists.txt | 43 +-- src/ipc.c | 4 +- src/libumf.def | 2 + src/libumf.map | 2 + src/memory_props.c | 82 ++++ src/memory_props_internal.h | 45 +++ src/memory_provider.c | 2 +- src/provider/provider_cuda.c | 114 +++--- src/provider/provider_level_zero.c | 54 ++- src/provider/provider_level_zero_internal.h | 5 + src/provider/provider_tracking.c | 38 +- src/provider/provider_tracking.h | 4 +- test/providers/provider_level_zero.cpp | 42 +++ 17 files changed, 578 insertions(+), 333 deletions(-) create mode 100644 include/umf/memory_props.h create mode 100644 src/memory_props.c create mode 100644 src/memory_props_internal.h diff --git a/benchmark/ubench.c b/benchmark/ubench.c index 5beaa62be..e735d3dd5 100644 --- a/benchmark/ubench.c +++ b/benchmark/ubench.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -179,299 +180,240 @@ UBENCH_EX(simple, os_memory_provider) { free(array); } -static void *w_umfPoolMalloc(void *provider, size_t size, size_t alignment) { - (void)alignment; // unused - umf_memory_pool_handle_t hPool = (umf_memory_pool_handle_t)provider; - return umfPoolMalloc(hPool, size); -} +#if (defined UMF_PROVIDER_LEVEL_ZERO_ENABLED && defined UMF_BUILD_GPU_TESTS) -static void w_umfPoolFree(void *provider, void *ptr, size_t size) { - (void)size; // unused - umf_result_t umf_result; - umf_memory_pool_handle_t hPool = (umf_memory_pool_handle_t)provider; - umf_result = umfPoolFree(hPool, ptr); - if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfPoolFree() failed\n"); - exit(-1); +static void do_umf_mem_props_benchmark(ze_context_handle_t context, + bool use_umf, alloc_t *allocs, + size_t num_allocs, size_t repeats) { + assert(context != NULL); + + for (size_t r = 0; r < repeats * 10; ++r) { + for (size_t i = 0; i < num_allocs; ++i) { + if (use_umf) { + umf_memory_properties_handle_t props_handle = NULL; + umf_result_t res = + umfGetMemoryPropertiesHandle(allocs[i].ptr, &props_handle); + (void)res; + assert(res == UMF_RESULT_SUCCESS); + + unsigned int id = 0; + res = umfGetMemoryProperty(props_handle, + UMF_MEMORY_PROPERTY_BUFFER_ID, &id); + assert(res == UMF_RESULT_SUCCESS); + + ze_device_handle_t device = NULL; + res = umfGetMemoryProperty(props_handle, + UMF_MEMORY_PROPERTY_DEVICE, &device); + assert(res == UMF_RESULT_SUCCESS); + + ze_memory_allocation_properties_t ze_props = {0}; + res = umfGetMemoryProperty( + props_handle, UMF_MEMORY_PROPERTY_DEVICE_ATTRIBUTES, + &ze_props); + assert(res == UMF_RESULT_SUCCESS); + + umf_usm_memory_type_t umf_memory_type; + res = umfGetMemoryProperty(props_handle, + UMF_MEMORY_PROPERTY_POINTER_TYPE, + &umf_memory_type); + assert(res == UMF_RESULT_SUCCESS); + } else { + ze_memory_type_t ze_memory_type = + utils_ze_get_mem_type(context, allocs[i].ptr); + (void)ze_memory_type; + assert(ze_memory_type != ZE_MEMORY_TYPE_UNKNOWN); + } + } } } -////////////////// PROXY POOL WITH OS MEMORY PROVIDER - -UBENCH_EX(simple, proxy_pool_with_os_memory_provider) { - alloc_t *array = alloc_array(N_ITERATIONS); - - umf_result_t umf_result; - umf_memory_provider_handle_t os_memory_provider = NULL; - umf_os_memory_provider_params_handle_t os_params = NULL; +static int create_level_zero_params(ze_context_handle_t *context, + ze_device_handle_t *device) { + uint32_t driver_idx = 0; + ze_driver_handle_t driver = NULL; - umf_result = umfOsMemoryProviderParamsCreate(&os_params); - if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfOsMemoryProviderParamsCreate() failed\n"); - exit(-1); + int ret = utils_ze_init_level_zero(); + if (ret != 0) { + fprintf(stderr, "Failed to init Level Zero!\n"); + return ret; } - umf_result = umfMemoryProviderCreate(umfOsMemoryProviderOps(), os_params, - &os_memory_provider); - umfOsMemoryProviderParamsDestroy(os_params); - if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfMemoryProviderCreate() failed\n"); - exit(-1); + ret = utils_ze_find_driver_with_gpu(&driver_idx, &driver); + if (ret || driver == NULL) { + fprintf(stderr, "Cannot find L0 driver with GPU device!\n"); + return ret; } - umf_memory_pool_handle_t proxy_pool; - umf_result = umfPoolCreate(umfProxyPoolOps(), os_memory_provider, NULL, 0, - &proxy_pool); - if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfPoolCreate() failed\n"); - exit(-1); + ret = utils_ze_create_context(driver, context); + if (ret != 0) { + fprintf(stderr, "Failed to create L0 context!\n"); + return ret; } - do_benchmark(array, N_ITERATIONS, w_umfPoolMalloc, w_umfPoolFree, - proxy_pool); // WARMUP - - UBENCH_DO_BENCHMARK() { - do_benchmark(array, N_ITERATIONS, w_umfPoolMalloc, w_umfPoolFree, - proxy_pool); + ret = utils_ze_find_gpu_device(driver, device); + if (ret) { + fprintf(stderr, "Cannot find GPU device!\n"); + utils_ze_destroy_context(*context); + return ret; } - umfPoolDestroy(proxy_pool); - umfMemoryProviderDestroy(os_memory_provider); - free(array); + return ret; } -////////////////// DISJOINT POOL WITH OS MEMORY PROVIDER - -UBENCH_EX(simple, disjoint_pool_with_os_memory_provider) { - alloc_t *array = alloc_array(N_ITERATIONS); - +UBENCH_EX(mem_props, disjoint_pool_with_level_zero_provider_use_l0) { + const size_t BUFFER_SIZE = 100; + const size_t N_BUFFERS = 1000; umf_result_t umf_result; - umf_memory_provider_handle_t os_memory_provider = NULL; - umf_os_memory_provider_params_handle_t os_params = NULL; - - umf_result = umfOsMemoryProviderParamsCreate(&os_params); - if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfOsMemoryProviderParamsCreate() failed\n"); - exit(-1); - } - - umf_result = umfMemoryProviderCreate(umfOsMemoryProviderOps(), os_params, - &os_memory_provider); - umfOsMemoryProviderParamsDestroy(os_params); - if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfMemoryProviderCreate() failed\n"); - exit(-1); - } + ze_context_handle_t context = NULL; + ze_device_handle_t device = NULL; + umf_level_zero_memory_provider_params_handle_t level_zero_params = NULL; - umf_disjoint_pool_params_handle_t disjoint_memory_pool_params = NULL; - umf_result = umfDisjointPoolParamsCreate(&disjoint_memory_pool_params); - if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "ERROR: umfDisjointPoolParamsCreate failed\n"); + int ret = create_level_zero_params(&context, &device); + if (ret != 0) { + fprintf(stderr, "error: create_level_zero_params() failed\n"); exit(-1); } - umf_result = umfDisjointPoolParamsSetSlabMinSize( - disjoint_memory_pool_params, DISJOINT_POOL_SLAB_MIN_SIZE); + umf_result = umfLevelZeroMemoryProviderParamsCreate(&level_zero_params); if (umf_result != UMF_RESULT_SUCCESS) { fprintf(stderr, - "error: umfDisjointPoolParamsSetSlabMinSize() failed\n"); - exit(-1); + "error: umfLevelZeroMemoryProviderParamsCreate() failed\n"); + goto err_destroy_context; } - umf_result = umfDisjointPoolParamsSetMaxPoolableSize( - disjoint_memory_pool_params, DISJOINT_POOL_MAX_POOLABLE_SIZE); + umf_result = + umfLevelZeroMemoryProviderParamsSetContext(level_zero_params, context); if (umf_result != UMF_RESULT_SUCCESS) { fprintf(stderr, - "error: umfDisjointPoolParamsSetMaxPoolableSize() failed\n"); - exit(-1); - } - - umf_result = umfDisjointPoolParamsSetCapacity(disjoint_memory_pool_params, - DISJOINT_POOL_CAPACITY); - if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfDisjointPoolParamsSetCapacity() failed\n"); - exit(-1); + "error: umfLevelZeroMemoryProviderParamsSetContext() failed\n"); + goto err_destroy_params; } - umf_result = umfDisjointPoolParamsSetMinBucketSize( - disjoint_memory_pool_params, DISJOINT_POOL_MIN_BUCKET_SIZE); + umf_result = + umfLevelZeroMemoryProviderParamsSetDevice(level_zero_params, device); if (umf_result != UMF_RESULT_SUCCESS) { fprintf(stderr, - "error: umfDisjointPoolParamsSetMinBucketSize() failed\n"); - exit(-1); + "error: umfLevelZeroMemoryProviderParamsSetDevice() failed\n"); + goto err_destroy_params; } - umf_memory_pool_handle_t disjoint_pool; - umf_result = umfPoolCreate(umfDisjointPoolOps(), os_memory_provider, - disjoint_memory_pool_params, 0, &disjoint_pool); + umf_result = umfLevelZeroMemoryProviderParamsSetMemoryType( + level_zero_params, UMF_MEMORY_TYPE_DEVICE); if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfPoolCreate() failed\n"); - exit(-1); + fprintf( + stderr, + "error: umfLevelZeroMemoryProviderParamsSetMemoryType() failed\n"); + goto err_destroy_params; } - do_benchmark(array, N_ITERATIONS, w_umfPoolMalloc, w_umfPoolFree, - disjoint_pool); // WARMUP - - UBENCH_DO_BENCHMARK() { - do_benchmark(array, N_ITERATIONS, w_umfPoolMalloc, w_umfPoolFree, - disjoint_pool); + alloc_t *allocs = alloc_array(N_BUFFERS); + if (allocs == NULL) { + fprintf(stderr, "error: alloc_array() failed\n"); + goto err_destroy_context; } - umfPoolDestroy(disjoint_pool); - umfDisjointPoolParamsDestroy(disjoint_memory_pool_params); - umfMemoryProviderDestroy(os_memory_provider); - free(array); -} - -#if (defined UMF_POOL_JEMALLOC_ENABLED) -////////////////// JEMALLOC POOL WITH OS MEMORY PROVIDER - -UBENCH_EX(simple, jemalloc_pool_with_os_memory_provider) { - alloc_t *array = alloc_array(N_ITERATIONS); - - umf_result_t umf_result; - umf_memory_provider_handle_t os_memory_provider = NULL; - umf_os_memory_provider_params_handle_t os_params = NULL; - - umf_result = umfOsMemoryProviderParamsCreate(&os_params); - if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfOsMemoryProviderParamsCreate() failed\n"); - exit(-1); + umf_ipc_handle_t *ipc_handles = calloc(N_BUFFERS, sizeof(umf_ipc_handle_t)); + if (ipc_handles == NULL) { + fprintf(stderr, "error: calloc() failed\n"); + goto err_free_allocs; } - umf_result = umfMemoryProviderCreate(umfOsMemoryProviderOps(), os_params, - &os_memory_provider); - umfOsMemoryProviderParamsDestroy(os_params); + umf_memory_provider_handle_t provider = NULL; + umf_result = umfMemoryProviderCreate(umfLevelZeroMemoryProviderOps(), + level_zero_params, &provider); if (umf_result != UMF_RESULT_SUCCESS) { fprintf(stderr, "error: umfMemoryProviderCreate() failed\n"); - exit(-1); + goto err_free_ipc_handles; } - umf_memory_pool_handle_t jemalloc_pool; - umf_result = umfPoolCreate(umfJemallocPoolOps(), os_memory_provider, NULL, - 0, &jemalloc_pool); + umf_disjoint_pool_params_handle_t disjoint_params = NULL; + umf_result = umfDisjointPoolParamsCreate(&disjoint_params); if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfPoolCreate() failed\n"); - exit(-1); + fprintf(stderr, "ERROR: umfDisjointPoolParamsCreate failed\n"); + goto err_provider_destroy; } - do_benchmark(array, N_ITERATIONS, w_umfPoolMalloc, w_umfPoolFree, - jemalloc_pool); // WARMUP - - UBENCH_DO_BENCHMARK() { - do_benchmark(array, N_ITERATIONS, w_umfPoolMalloc, w_umfPoolFree, - jemalloc_pool); + umf_result = + umfDisjointPoolParamsSetSlabMinSize(disjoint_params, BUFFER_SIZE * 10); + if (umf_result != UMF_RESULT_SUCCESS) { + fprintf(stderr, + "error: umfDisjointPoolParamsSetSlabMinSize() failed\n"); + goto err_params_destroy; } - umfPoolDestroy(jemalloc_pool); - umfMemoryProviderDestroy(os_memory_provider); - free(array); -} -#endif /* (defined UMF_POOL_JEMALLOC_ENABLED) */ - -#if (defined UMF_POOL_SCALABLE_ENABLED) -////////////////// SCALABLE (TBB) POOL WITH OS MEMORY PROVIDER - -UBENCH_EX(simple, scalable_pool_with_os_memory_provider) { - alloc_t *array = alloc_array(N_ITERATIONS); - - umf_result_t umf_result; - umf_memory_provider_handle_t os_memory_provider = NULL; - umf_os_memory_provider_params_handle_t os_params = NULL; + umf_result = umfDisjointPoolParamsSetMaxPoolableSize( + disjoint_params, 4ull * 1024ull * 1024ull); + if (umf_result != UMF_RESULT_SUCCESS) { + fprintf(stderr, + "error: umfDisjointPoolParamsSetMaxPoolableSize() failed\n"); + goto err_params_destroy; + } - umf_result = umfOsMemoryProviderParamsCreate(&os_params); + umf_result = + umfDisjointPoolParamsSetCapacity(disjoint_params, 64ull * 1024ull); if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfOsMemoryProviderParamsCreate() failed\n"); - exit(-1); + fprintf(stderr, "error: umfDisjointPoolParamsSetCapacity() failed\n"); + goto err_params_destroy; } - umf_result = umfMemoryProviderCreate(umfOsMemoryProviderOps(), os_params, - &os_memory_provider); - umfOsMemoryProviderParamsDestroy(os_params); + umf_result = umfDisjointPoolParamsSetMinBucketSize(disjoint_params, 64); if (umf_result != UMF_RESULT_SUCCESS) { - fprintf(stderr, "error: umfMemoryProviderCreate() failed\n"); - exit(-1); + fprintf(stderr, + "error: umfDisjointPoolParamsSetMinBucketSize() failed\n"); + goto err_params_destroy; } - umf_memory_pool_handle_t scalable_pool; - umf_result = umfPoolCreate(umfScalablePoolOps(), os_memory_provider, NULL, - 0, &scalable_pool); + umf_pool_create_flags_t flags = UMF_POOL_CREATE_FLAG_NONE; + umf_memory_pool_handle_t pool; + umf_result = umfPoolCreate(umfDisjointPoolOps(), provider, disjoint_params, + flags, &pool); if (umf_result != UMF_RESULT_SUCCESS) { fprintf(stderr, "error: umfPoolCreate() failed\n"); - exit(-1); + goto err_params_destroy; } - do_benchmark(array, N_ITERATIONS, w_umfPoolMalloc, w_umfPoolFree, - scalable_pool); // WARMUP + for (size_t i = 0; i < N_BUFFERS; ++i) { + allocs[i].ptr = umfPoolMalloc(pool, BUFFER_SIZE); + if (allocs[i].ptr == NULL) { + goto err_buffer_destroy; + } + allocs[i].size = BUFFER_SIZE; + } + do_umf_mem_props_benchmark(context, false, allocs, N_BUFFERS, + N_ITERATIONS); // WARMUP UBENCH_DO_BENCHMARK() { - do_benchmark(array, N_ITERATIONS, w_umfPoolMalloc, w_umfPoolFree, - scalable_pool); + do_umf_mem_props_benchmark(context, false, allocs, N_BUFFERS, + N_ITERATIONS); } - umfPoolDestroy(scalable_pool); - umfMemoryProviderDestroy(os_memory_provider); - free(array); -} -#endif /* (defined UMF_POOL_SCALABLE_ENABLED) */ - -#if (defined UMF_PROVIDER_LEVEL_ZERO_ENABLED && defined UMF_BUILD_GPU_TESTS) -static void do_ipc_get_put_benchmark(alloc_t *allocs, size_t num_allocs, - size_t repeats, - umf_ipc_handle_t *ipc_handles) { - for (size_t r = 0; r < repeats; ++r) { - for (size_t i = 0; i < num_allocs; ++i) { - size_t handle_size = 0; - umf_result_t res = - umfGetIPCHandle(allocs[i].ptr, &(ipc_handles[i]), &handle_size); - if (res != UMF_RESULT_SUCCESS) { - fprintf(stderr, "umfGetIPCHandle() failed\n"); - } - } - - for (size_t i = 0; i < num_allocs; ++i) { - umf_result_t res = umfPutIPCHandle(ipc_handles[i]); - if (res != UMF_RESULT_SUCCESS) { - fprintf(stderr, "umfPutIPCHandle() failed\n"); - } - } +err_buffer_destroy: + for (size_t i = 0; i < N_BUFFERS; ++i) { + umfPoolFree(pool, allocs[i].ptr); } -} -static int create_level_zero_params(ze_context_handle_t *context, - ze_device_handle_t *device) { - uint32_t driver_idx = 0; - ze_driver_handle_t driver = NULL; + umfPoolDestroy(pool); - int ret = utils_ze_init_level_zero(); - if (ret != 0) { - fprintf(stderr, "Failed to init Level Zero!\n"); - return ret; - } +err_params_destroy: + umfDisjointPoolParamsDestroy(disjoint_params); - ret = utils_ze_find_driver_with_gpu(&driver_idx, &driver); - if (ret || driver == NULL) { - fprintf(stderr, "Cannot find L0 driver with GPU device!\n"); - return ret; - } +err_provider_destroy: + umfMemoryProviderDestroy(provider); - ret = utils_ze_create_context(driver, context); - if (ret != 0) { - fprintf(stderr, "Failed to create L0 context!\n"); - return ret; - } +err_free_ipc_handles: + free(ipc_handles); - ret = utils_ze_find_gpu_device(driver, device); - if (ret) { - fprintf(stderr, "Cannot find GPU device!\n"); - utils_ze_destroy_context(*context); - return ret; - } +err_free_allocs: + free(allocs); - return ret; +err_destroy_params: + umfLevelZeroMemoryProviderParamsDestroy(level_zero_params); + +err_destroy_context: + utils_ze_destroy_context(context); } -UBENCH_EX(ipc, disjoint_pool_with_level_zero_provider) { +UBENCH_EX(mem_props, disjoint_pool_with_level_zero_provider_use_umf) { const size_t BUFFER_SIZE = 100; const size_t N_BUFFERS = 1000; umf_result_t umf_result; @@ -591,11 +533,11 @@ UBENCH_EX(ipc, disjoint_pool_with_level_zero_provider) { allocs[i].size = BUFFER_SIZE; } - do_ipc_get_put_benchmark(allocs, N_BUFFERS, N_ITERATIONS, - ipc_handles); // WARMUP - + do_umf_mem_props_benchmark(context, true, allocs, N_BUFFERS, + N_ITERATIONS); // WARMUP UBENCH_DO_BENCHMARK() { - do_ipc_get_put_benchmark(allocs, N_BUFFERS, N_ITERATIONS, ipc_handles); + do_umf_mem_props_benchmark(context, true, allocs, N_BUFFERS, + N_ITERATIONS); } err_buffer_destroy: @@ -623,6 +565,7 @@ UBENCH_EX(ipc, disjoint_pool_with_level_zero_provider) { err_destroy_context: utils_ze_destroy_context(context); } + #endif /* (defined UMF_BUILD_LEVEL_ZERO_PROVIDER && defined UMF_BUILD_GPU_TESTS) */ // TODO add IPC benchmark for CUDA diff --git a/docs/config/api.rst b/docs/config/api.rst index 97e664d97..051ec8c91 100644 --- a/docs/config/api.rst +++ b/docs/config/api.rst @@ -28,6 +28,14 @@ memory as well as functions that create, destroy and operate on the pool. .. doxygenfile:: memory_pool.h :sections: define enum typedef func var +TODO +------------------------------------------ + +TODO + +.. doxygenfile:: memory_props.h + :sections: define enum typedef func var + Disjoint Pool ------------------------------------------ diff --git a/include/umf/memory_props.h b/include/umf/memory_props.h new file mode 100644 index 000000000..ee169f1ed --- /dev/null +++ b/include/umf/memory_props.h @@ -0,0 +1,67 @@ +/* + * + * 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 + * + */ + +#ifndef UMF_MEMORY_PROPS_H +#define UMF_MEMORY_PROPS_H 1 + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/// @brief TODO +// write about experimental api +typedef enum umf_memory_property_id_t { + UMF_MEMORY_PROPERTY_INVALID = -1, ///< TODO + + // UMF specyfic + UMF_MEMORY_PROVIDER_HANDLE, + UMF_MEMORY_PROVIDER_OPS, // == type? + UMF_MEMORY_POOL_HANDLE, + UMF_MEMORY_POOL_OPS, // == type? + + // generic pointer properties + UMF_MEMORY_PROPERTY_POINTER_TYPE, // unreg host, reg host ??, dev, managed or umf_usm_memory_type_t? + UMF_MEMORY_PROPERTY_BASE_ADDRESS, // base address + UMF_MEMORY_PROPERTY_BASE_SIZE, // base size + + // GPU specyfic + UMF_MEMORY_PROPERTY_DEVICE, // handle (ze) or id (cuda) + UMF_MEMORY_PROPERTY_BUFFER_ID, // unique id NOTE: this id is unique across all UMF allocs and != L0 or CUDA ID + UMF_MEMORY_PROPERTY_DEVICE_ATTRIBUTES, // ze_memory_allocation_properties_t ? + + // all cuda + l0 + // next other providers? + // todo return type? + + /// @cond + UMF_MEMORY_PROPERTY_MAX_RESERVED = 0x1000, ///< Maximum reserved value + /// @endcond + +} umf_memory_property_id_t; + +typedef struct umf_memory_properties_t *umf_memory_properties_handle_t; + +/// @brief TODO +umf_result_t +umfGetMemoryPropertiesHandle(void *ptr, + umf_memory_properties_handle_t *props_handle); + +/// @brief TODO +umf_result_t umfGetMemoryProperty(umf_memory_properties_handle_t props_handle, + umf_memory_property_id_t memory_property_id, + void *value); + +#ifdef __cplusplus +} +#endif + +#endif /* UMF_MEMORY_PROPS_H */ diff --git a/include/umf/providers/provider_level_zero.h b/include/umf/providers/provider_level_zero.h index 895922b4c..fb792d140 100644 --- a/include/umf/providers/provider_level_zero.h +++ b/include/umf/providers/provider_level_zero.h @@ -8,6 +8,7 @@ #ifndef UMF_PROVIDER_LEVEL_ZERO_H #define UMF_PROVIDER_LEVEL_ZERO_H +#include #include #ifdef __cplusplus @@ -91,6 +92,11 @@ umf_result_t umfLevelZeroMemoryProviderParamsSetDeviceOrdinal( umf_level_zero_memory_provider_params_handle_t hParams, uint32_t deviceOrdinal); +/// TODO +umf_result_t umfLevelZeroMemoryProviderGetMemoryProperty( + umf_memory_properties_handle_t props_handle, + umf_memory_property_id_t memory_property_id, void *value); + const umf_memory_provider_ops_t *umfLevelZeroMemoryProviderOps(void); #ifdef __cplusplus diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 24beb1e0a..643c95bfb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -66,6 +66,7 @@ set(UMF_SOURCES ipc.c ipc_cache.c memory_pool.c + memory_props.c memory_provider.c memory_provider_get_last_failed.c memtarget.c @@ -115,20 +116,22 @@ set(UMF_SOURCES_LINUX libumf_linux.c) set(UMF_SOURCES_MACOSX libumf_linux.c) set(UMF_SOURCES_WINDOWS libumf_windows.c) -# Add compile definitions to handle unsupported functions -if(NOT UMF_BUILD_CUDA_PROVIDER) - set(UMF_COMMON_COMPILE_DEFINITIONS ${UMF_COMMON_COMPILE_DEFINITIONS} - "UMF_NO_CUDA_PROVIDER=1") -endif() -if(NOT UMF_BUILD_LEVEL_ZERO_PROVIDER) +if(UMF_BUILD_LEVEL_ZERO_PROVIDER) + if(LINUX) + # WA for error ze_api.h:14234:20: no newline at end of file + # [-Werror,-Wnewline-eof] + set_source_files_properties( + provider/provider_level_zero.c + PROPERTIES APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-newline-eof") + endif() + set(UMF_COMMON_COMPILE_DEFINITIONS ${UMF_COMMON_COMPILE_DEFINITIONS} - "UMF_NO_LEVEL_ZERO_PROVIDER=1") + "UMF_BUILD_LEVEL_ZERO_PROVIDER=1") endif() -if(UMF_DISABLE_HWLOC OR WINDOWS) - set(UMF_COMMON_COMPILE_DEFINITIONS ${UMF_COMMON_COMPILE_DEFINITIONS} - "UMF_NO_DEVDAX_PROVIDER=1") + +if(UMF_BUILD_CUDA_PROVIDER) set(UMF_COMMON_COMPILE_DEFINITIONS ${UMF_COMMON_COMPILE_DEFINITIONS} - "UMF_NO_FILE_PROVIDER=1") + "UMF_BUILD_CUDA_PROVIDER=1") endif() if(LINUX) @@ -198,24 +201,6 @@ if(NOT WINDOWS AND UMF_POOL_JEMALLOC_ENABLED) add_dependencies(umf jemalloc) endif() -if(UMF_BUILD_LEVEL_ZERO_PROVIDER) - if(LINUX) - # WA for error ze_api.h:14234:20: no newline at end of file - # [-Werror,-Wnewline-eof] - set_source_files_properties( - provider/provider_level_zero.c - PROPERTIES APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-newline-eof") - endif() - - set(UMF_COMPILE_DEFINITIONS ${UMF_COMPILE_DEFINITIONS} - "UMF_BUILD_LEVEL_ZERO_PROVIDER=1") -endif() - -if(UMF_BUILD_CUDA_PROVIDER) - set(UMF_COMPILE_DEFINITIONS ${UMF_COMPILE_DEFINITIONS} - "UMF_BUILD_CUDA_PROVIDER=1") -endif() - add_library(${PROJECT_NAME}::umf ALIAS umf) if(LIBHWLOC_INCLUDE_DIRS) diff --git a/src/ipc.c b/src/ipc.c index d4e5cc806..6e2a2f274 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -65,7 +65,7 @@ umf_result_t umfGetIPCHandle(const void *ptr, umf_ipc_handle_t *umfIPCHandle, return ret; } - ret = umfPoolGetIPCHandleSize(allocInfo.pool, &ipcHandleSize); + ret = umfPoolGetIPCHandleSize(allocInfo.props->pool, &ipcHandleSize); if (ret != UMF_RESULT_SUCCESS) { LOG_ERR("cannot get IPC handle size."); return ret; @@ -79,7 +79,7 @@ umf_result_t umfGetIPCHandle(const void *ptr, umf_ipc_handle_t *umfIPCHandle, // We cannot use umfPoolGetMemoryProvider function because it returns // upstream provider but we need tracking one - umf_memory_provider_handle_t provider = allocInfo.pool->provider; + umf_memory_provider_handle_t provider = allocInfo.props->pool->provider; assert(provider); ret = umfMemoryProviderGetIPCHandle(provider, allocInfo.base, diff --git a/src/libumf.def b/src/libumf.def index 925beab3b..f555c4ca3 100644 --- a/src/libumf.def +++ b/src/libumf.def @@ -139,6 +139,8 @@ EXPORTS umfCtlExec umfCtlGet umfCtlSet + umfGetMemoryPropertiesHandle + umfGetMemoryProperty umfJemallocPoolParamsCreate umfJemallocPoolParamsDestroy umfJemallocPoolParamsSetNumArenas diff --git a/src/libumf.map b/src/libumf.map index a9a94b3a3..674e89039 100644 --- a/src/libumf.map +++ b/src/libumf.map @@ -139,6 +139,8 @@ UMF_0.12 { umfCtlExec; umfCtlGet; umfCtlSet; + umfGetMemoryPropertiesHandle; + umfGetMemoryProperty; umfJemallocPoolParamsCreate; umfJemallocPoolParamsDestroy; umfJemallocPoolParamsSetNumArenas; diff --git a/src/memory_props.c b/src/memory_props.c new file mode 100644 index 000000000..d035499ce --- /dev/null +++ b/src/memory_props.c @@ -0,0 +1,82 @@ +/* + * + * 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 + * + */ + +#include +#include +#include + +#include "memory_props_internal.h" +#include "memory_provider_internal.h" +#include "provider/provider_tracking.h" + +umf_result_t +umfGetMemoryPropertiesHandle(void *ptr, + umf_memory_properties_handle_t *props_handle) { + umf_alloc_info_t allocInfo = {NULL, 0, NULL}; + umf_result_t ret = umfMemoryTrackerGetAllocInfo(ptr, &allocInfo); + if (ret != UMF_RESULT_SUCCESS) { + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } + + *props_handle = allocInfo.props; + return UMF_RESULT_SUCCESS; +} + +umf_result_t umfGetMemoryProperty(umf_memory_properties_handle_t props_handle, + umf_memory_property_id_t memory_property_id, + void *value) { + if ((value == NULL) || + (memory_property_id == UMF_MEMORY_PROPERTY_INVALID) || + (memory_property_id >= UMF_MEMORY_PROPERTY_MAX_RESERVED) || + props_handle == NULL) { + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } + + switch (memory_property_id) { + case UMF_MEMORY_POOL_HANDLE: + *(umf_memory_pool_handle_t *)value = props_handle->pool; + return UMF_RESULT_SUCCESS; + + case UMF_MEMORY_PROPERTY_BUFFER_ID: + *(uint64_t *)value = props_handle->id; + return UMF_RESULT_SUCCESS; + + default: + break; + } + + // properties that are related to the memory provider + umf_memory_provider_t *provider = NULL; + umfPoolGetMemoryProvider(props_handle->pool, &provider); + assert(provider != NULL); + + switch (memory_property_id) { + // GPU Memory Provider specyfic properties + case UMF_MEMORY_PROPERTY_POINTER_TYPE: + case UMF_MEMORY_PROPERTY_DEVICE: + case UMF_MEMORY_PROPERTY_DEVICE_ATTRIBUTES: + if (provider->ops.get_name(provider) == + umfLevelZeroMemoryProviderOps()->get_name(provider)) { + return umfLevelZeroMemoryProviderGetMemoryProperty( + props_handle, memory_property_id, value); + } else if (provider->ops.get_name(provider) == + umfCUDAMemoryProviderOps()->get_name(provider)) { + // TODO + assert(0); + return UMF_RESULT_SUCCESS; + } + // no provider found + return UMF_RESULT_ERROR_UNKNOWN; + + default: + break; + } + + return UMF_RESULT_ERROR_NOT_SUPPORTED; +} diff --git a/src/memory_props_internal.h b/src/memory_props_internal.h new file mode 100644 index 000000000..f8f6c1418 --- /dev/null +++ b/src/memory_props_internal.h @@ -0,0 +1,45 @@ +/* + * + * 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 + * + */ + +#ifndef UMF_MEMORY_PROPS_INTERNAL_H +#define UMF_MEMORY_PROPS_INTERNAL_H 1 + +#include + +#include +#include + +#if UMF_BUILD_LEVEL_ZERO_PROVIDER +#include "ze_api.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct umf_memory_properties_t { + void *ptr; + umf_memory_pool_handle_t pool; + uint64_t id; + + // TODO + bool gpu_properties_initialized; + union { +#if UMF_BUILD_LEVEL_ZERO_PROVIDER + ze_memory_allocation_properties_t ze_properties; +#endif + int unused; // in case of no GPU support + } gpu; +} umf_memory_properties_t; + +#ifdef __cplusplus +} +#endif + +#endif // UMF_MEMORY_PROPS_INTERNAL_H diff --git a/src/memory_provider.c b/src/memory_provider.c index d32fcdcd6..29e3604ea 100644 --- a/src/memory_provider.c +++ b/src/memory_provider.c @@ -12,13 +12,13 @@ #include #include +#include #include #include "base_alloc.h" #include "base_alloc_global.h" #include "libumf.h" #include "memory_provider_internal.h" -#include "umf/base.h" #include "utils_assert.h" static int CTL_SUBTREE_HANDLER(by_handle_provider)( diff --git a/src/provider/provider_cuda.c b/src/provider/provider_cuda.c index f3e0658a5..f7fa28d87 100644 --- a/src/provider/provider_cuda.c +++ b/src/provider/provider_cuda.c @@ -25,62 +25,7 @@ void fini_cu_global_state(void) { } } -#if defined(UMF_NO_CUDA_PROVIDER) - -umf_result_t umfCUDAMemoryProviderParamsCreate( - umf_cuda_memory_provider_params_handle_t *hParams) { - (void)hParams; - LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); - return UMF_RESULT_ERROR_NOT_SUPPORTED; -} - -umf_result_t umfCUDAMemoryProviderParamsDestroy( - umf_cuda_memory_provider_params_handle_t hParams) { - (void)hParams; - LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); - return UMF_RESULT_ERROR_NOT_SUPPORTED; -} - -umf_result_t umfCUDAMemoryProviderParamsSetContext( - umf_cuda_memory_provider_params_handle_t hParams, void *hContext) { - (void)hParams; - (void)hContext; - LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); - return UMF_RESULT_ERROR_NOT_SUPPORTED; -} - -umf_result_t umfCUDAMemoryProviderParamsSetDevice( - umf_cuda_memory_provider_params_handle_t hParams, int hDevice) { - (void)hParams; - (void)hDevice; - LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); - return UMF_RESULT_ERROR_NOT_SUPPORTED; -} - -umf_result_t umfCUDAMemoryProviderParamsSetMemoryType( - umf_cuda_memory_provider_params_handle_t hParams, - umf_usm_memory_type_t memoryType) { - (void)hParams; - (void)memoryType; - LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); - return UMF_RESULT_ERROR_NOT_SUPPORTED; -} - -umf_result_t umfCUDAMemoryProviderParamsSetAllocFlags( - umf_cuda_memory_provider_params_handle_t hParams, unsigned int flags) { - (void)hParams; - (void)flags; - LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); - return UMF_RESULT_ERROR_NOT_SUPPORTED; -} - -const umf_memory_provider_ops_t *umfCUDAMemoryProviderOps(void) { - // not supported - LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); - return NULL; -} - -#else // !defined(UMF_NO_CUDA_PROVIDER) +#if UMF_BUILD_CUDA_PROVIDER // disable warning 4201: nonstandard extension used: nameless struct/union #if defined(_MSC_VER) @@ -759,4 +704,59 @@ const umf_memory_provider_ops_t *umfCUDAMemoryProviderOps(void) { return &UMF_CUDA_MEMORY_PROVIDER_OPS; } -#endif // !defined(UMF_NO_CUDA_PROVIDER) +#else // !UMF_BUILD_CUDA_PROVIDER + +umf_result_t umfCUDAMemoryProviderParamsCreate( + umf_cuda_memory_provider_params_handle_t *hParams) { + (void)hParams; + LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); + return UMF_RESULT_ERROR_NOT_SUPPORTED; +} + +umf_result_t umfCUDAMemoryProviderParamsDestroy( + umf_cuda_memory_provider_params_handle_t hParams) { + (void)hParams; + LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); + return UMF_RESULT_ERROR_NOT_SUPPORTED; +} + +umf_result_t umfCUDAMemoryProviderParamsSetContext( + umf_cuda_memory_provider_params_handle_t hParams, void *hContext) { + (void)hParams; + (void)hContext; + LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); + return UMF_RESULT_ERROR_NOT_SUPPORTED; +} + +umf_result_t umfCUDAMemoryProviderParamsSetDevice( + umf_cuda_memory_provider_params_handle_t hParams, int hDevice) { + (void)hParams; + (void)hDevice; + LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); + return UMF_RESULT_ERROR_NOT_SUPPORTED; +} + +umf_result_t umfCUDAMemoryProviderParamsSetMemoryType( + umf_cuda_memory_provider_params_handle_t hParams, + umf_usm_memory_type_t memoryType) { + (void)hParams; + (void)memoryType; + LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); + return UMF_RESULT_ERROR_NOT_SUPPORTED; +} + +umf_result_t umfCUDAMemoryProviderParamsSetAllocFlags( + umf_cuda_memory_provider_params_handle_t hParams, unsigned int flags) { + (void)hParams; + (void)flags; + LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); + return UMF_RESULT_ERROR_NOT_SUPPORTED; +} + +const umf_memory_provider_ops_t *umfCUDAMemoryProviderOps(void) { + // not supported + LOG_ERR("CUDA provider is disabled (UMF_BUILD_CUDA_PROVIDER is OFF)!"); + return NULL; +} + +#endif // !UMF_BUILD_CUDA_PROVIDER diff --git a/src/provider/provider_level_zero.c b/src/provider/provider_level_zero.c index 623bf7054..0a8920e02 100644 --- a/src/provider/provider_level_zero.c +++ b/src/provider/provider_level_zero.c @@ -11,10 +11,13 @@ #include #include +#include #include #include -#include "provider_level_zero_internal.h" +#include "memory_props_internal.h" +#include "memory_provider_internal.h" +#include "provider/provider_level_zero_internal.h" #include "utils_load_library.h" #include "utils_log.h" @@ -113,6 +116,7 @@ const umf_memory_provider_ops_t *umfLevelZeroMemoryProviderOps(void) { #include "base_alloc_global.h" #include "libumf.h" +#include "provider_level_zero_internal.h" #include "utils_assert.h" #include "utils_common.h" #include "utils_concurrency.h" @@ -143,7 +147,7 @@ typedef struct umf_level_zero_memory_provider_params_t { typedef struct ze_memory_provider_t { ze_context_handle_t context; ze_device_handle_t device; - ze_memory_type_t memory_type; + umf_usm_memory_type_t memory_type; ze_device_handle_t *resident_device_handles; uint32_t resident_device_count; @@ -584,7 +588,7 @@ static umf_result_t ze_memory_provider_initialize(const void *params, ze_provider->context = ze_params->level_zero_context_handle; ze_provider->device = ze_params->level_zero_device_handle; - ze_provider->memory_type = (ze_memory_type_t)ze_params->memory_type; + ze_provider->memory_type = ze_params->memory_type; ze_provider->freePolicyFlags = umfFreePolicyToZePolicy(ze_params->freePolicy); ze_provider->min_page_size = 0; @@ -842,6 +846,50 @@ ze_memory_provider_close_ipc_handle(void *provider, void *ptr, size_t size) { return UMF_RESULT_SUCCESS; } +umf_result_t umfLevelZeroMemoryProviderGetMemoryProperty( + umf_memory_properties_handle_t props_handle, + umf_memory_property_id_t memory_property_id, void *value) { + + umf_memory_provider_t *provider = NULL; + umfPoolGetMemoryProvider(props_handle->pool, &provider); + assert(provider != NULL); + assert(provider->ops.get_name(provider) == + umfLevelZeroMemoryProviderOps()->get_name(provider)); + + ze_memory_provider_t *ze_provider = + (ze_memory_provider_t *)provider->provider_priv; + + switch (memory_property_id) { + case UMF_MEMORY_PROPERTY_POINTER_TYPE: + *(umf_usm_memory_type_t *)value = ze_provider->memory_type; + return UMF_RESULT_SUCCESS; + + case UMF_MEMORY_PROPERTY_DEVICE: + *(ze_device_handle_t *)value = ze_provider->device; + return UMF_RESULT_SUCCESS; + + case UMF_MEMORY_PROPERTY_DEVICE_ATTRIBUTES: + // TODO comment + if (props_handle->gpu_properties_initialized == false) { + props_handle->gpu.ze_properties.stype = + ZE_STRUCTURE_TYPE_MEMORY_ALLOCATION_PROPERTIES; + g_ze_ops.zeMemGetAllocProperties( + ze_provider->context, props_handle->ptr, + &props_handle->gpu.ze_properties, NULL); + props_handle->gpu_properties_initialized = true; + } + ze_memory_allocation_properties_t *ze_properties = + &props_handle->gpu.ze_properties; + *(ze_memory_allocation_properties_t **)value = ze_properties; + return UMF_RESULT_SUCCESS; + + default: + break; + } + + return UMF_RESULT_ERROR_NOT_SUPPORTED; +} + static umf_memory_provider_ops_t UMF_LEVEL_ZERO_MEMORY_PROVIDER_OPS = { .version = UMF_PROVIDER_OPS_VERSION_CURRENT, .initialize = ze_memory_provider_initialize, diff --git a/src/provider/provider_level_zero_internal.h b/src/provider/provider_level_zero_internal.h index 7da299ffd..3bd76a0a9 100644 --- a/src/provider/provider_level_zero_internal.h +++ b/src/provider/provider_level_zero_internal.h @@ -7,4 +7,9 @@ * */ +#ifndef UMF_LEVEL_ZERO_PROVIDER_INTERNAL_H +#define UMF_LEVEL_ZERO_PROVIDER_INTERNAL_H + void fini_ze_global_state(void); + +#endif // UMF_LEVEL_ZERO_PROVIDER_INTERNAL_H diff --git a/src/provider/provider_tracking.c b/src/provider/provider_tracking.c index 2636460e6..5922e1c20 100644 --- a/src/provider/provider_tracking.c +++ b/src/provider/provider_tracking.c @@ -22,6 +22,7 @@ #include "ipc_cache.h" #include "ipc_internal.h" #include "memory_pool_internal.h" +#include "memory_props_internal.h" #include "provider_tracking.h" #include "utils_common.h" #include "utils_concurrency.h" @@ -32,6 +33,8 @@ uint64_t IPC_HANDLE_ID = 0; +uint64_t unique_alloc_id = 0; // requires atomic access + struct umf_memory_tracker_t { umf_ba_pool_t *alloc_info_allocator; // Multilevel maps are needed to support the case @@ -44,11 +47,10 @@ struct umf_memory_tracker_t { }; typedef struct tracker_alloc_info_t { - umf_memory_pool_handle_t pool; + umf_memory_properties_t props; size_t size; - // number of overlapping memory regions - // in the next level of map - // falling within the current range + // number of overlapping memory regions in the next level of map falling + // within the current range size_t n_children; } tracker_alloc_info_t; @@ -138,7 +140,11 @@ umfMemoryTrackerAddAtLevel(umf_memory_tracker_handle_t hTracker, int level, return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY; } - value->pool = pool; + memset(&value->props, 0, sizeof(umf_memory_properties_t)); + value->props.ptr = (void *)ptr; + value->props.pool = pool; + value->props.id = utils_atomic_increment_u64(&unique_alloc_id); + utils_atomic_store_release_u64((uint64_t *)&value->size, size); value->n_children = 0; @@ -156,7 +162,7 @@ umfMemoryTrackerAddAtLevel(umf_memory_tracker_handle_t hTracker, int level, "child #%zu added to memory region: tracker=%p, level=%i, " "pool=%p, ptr=%p, size=%zu", parent_value->n_children, (void *)hTracker, level - 1, - (void *)parent_value->pool, (void *)parent_key, + (void *)parent_value->props.pool, (void *)parent_key, parent_value->size); } return UMF_RESULT_SUCCESS; @@ -213,8 +219,8 @@ static umf_result_t umfMemoryTrackerAdd(umf_memory_tracker_handle_t hTracker, "cannot insert to the tracker value (pool=%p, ptr=%p, " "size=%zu) " "that exceeds the parent value (pool=%p, ptr=%p, size=%zu)", - (void *)pool, ptr, size, (void *)rvalue->pool, (void *)rkey, - (size_t)rsize); + (void *)pool, ptr, size, (void *)rvalue->props.pool, + (void *)rkey, (size_t)rsize); return UMF_RESULT_ERROR_INVALID_ARGUMENT; } parent_key = rkey; @@ -260,14 +266,16 @@ static umf_result_t umfMemoryTrackerRemove(umf_memory_tracker_handle_t hTracker, LOG_DEBUG("memory region removed: tracker=%p, level=%i, pool=%p, ptr=%p, " "size=%zu", - (void *)hTracker, level, (void *)value->pool, ptr, value->size); + (void *)hTracker, level, (void *)value->props.pool, ptr, + value->size); if (parent_value) { LOG_DEBUG( "child #%zu removed from memory region: tracker=%p, level=%i, " "pool=%p, ptr=%p, size=%zu", parent_value->n_children, (void *)hTracker, level - 1, - (void *)parent_value->pool, (void *)parent_key, parent_value->size); + (void *)parent_value->props.pool, (void *)parent_key, + parent_value->size); parent_value->n_children--; } @@ -347,11 +355,11 @@ umfMemoryTrackerRemoveIpcSegment(umf_memory_tracker_handle_t hTracker, umf_memory_pool_handle_t umfMemoryTrackerGetPool(const void *ptr) { umf_alloc_info_t allocInfo = {NULL, 0, NULL}; umf_result_t ret = umfMemoryTrackerGetAllocInfo(ptr, &allocInfo); - if (ret != UMF_RESULT_SUCCESS) { + if (ret != UMF_RESULT_SUCCESS || allocInfo.props == NULL) { return NULL; } - return allocInfo.pool; + return allocInfo.props->pool; } umf_result_t umfMemoryTrackerGetAllocInfo(const void *ptr, @@ -403,7 +411,7 @@ umf_result_t umfMemoryTrackerGetAllocInfo(const void *ptr, pAllocInfo->base = (void *)top_most_key; pAllocInfo->baseSize = top_most_value->size; - pAllocInfo->pool = top_most_value->pool; + pAllocInfo->props = &top_most_value->props; return UMF_RESULT_SUCCESS; } @@ -631,7 +639,7 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr, ret = UMF_RESULT_ERROR_INVALID_ARGUMENT; goto err_fatal; } - if (lowValue->pool != highValue->pool) { + if (lowValue->props.pool != highValue->props.pool) { LOG_FATAL("pool mismatch"); ret = UMF_RESULT_ERROR_INVALID_ARGUMENT; goto err_fatal; @@ -768,7 +776,7 @@ static void check_if_tracker_is_empty(umf_memory_tracker_handle_t hTracker, while (1 == critnib_find(hTracker->alloc_segments_map[i], last_key, FIND_G, &rkey, (void **)&rvalue)) { - if (rvalue->pool == pool || pool == NULL) { + if (rvalue->props.pool == pool || pool == NULL) { n_items++; } diff --git a/src/provider/provider_tracking.h b/src/provider/provider_tracking.h index 842449be5..97dd35364 100644 --- a/src/provider/provider_tracking.h +++ b/src/provider/provider_tracking.h @@ -20,6 +20,7 @@ #include "base_alloc.h" #include "critnib.h" +#include "memory_props_internal.h" #include "utils_concurrency.h" #ifdef __cplusplus @@ -35,11 +36,12 @@ umf_memory_tracker_handle_t umfMemoryTrackerCreate(void); void umfMemoryTrackerDestroy(umf_memory_tracker_handle_t handle); umf_memory_pool_handle_t umfMemoryTrackerGetPool(const void *ptr); +umf_memory_properties_handle_t umfMemoryTrackerGetProps(const void *ptr); typedef struct umf_alloc_info_t { void *base; size_t baseSize; - umf_memory_pool_handle_t pool; + umf_memory_properties_handle_t props; } umf_alloc_info_t; umf_result_t umfMemoryTrackerGetAllocInfo(const void *ptr, diff --git a/test/providers/provider_level_zero.cpp b/test/providers/provider_level_zero.cpp index e30500d9d..446a4a9de 100644 --- a/test/providers/provider_level_zero.cpp +++ b/test/providers/provider_level_zero.cpp @@ -480,6 +480,48 @@ TEST_P(umfLevelZeroProviderTest, setDeviceOrdinalValid) { } } +TEST_P(umfLevelZeroProviderTest, memProps) { + umf_memory_provider_handle_t provider = nullptr; + umf_result_t umf_result = umfMemoryProviderCreate( + umfLevelZeroMemoryProviderOps(), params, &provider); + ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS); + ASSERT_NE(provider, nullptr); + + void *ptr = nullptr; + size_t size = 1024; + + umf_result_t result = umfMemoryProviderAlloc(provider, size, 0, &ptr); + ASSERT_EQ(result, UMF_RESULT_SUCCESS); + ASSERT_NE(ptr, nullptr); + + // TODO + + umfMemoryProviderDestroy(provider); +} + +/* +TODO move to generic +TEST_P(umfGetMemoryPropertiesHandleTest, InvalidMemoryPropertiesHandle) { + umf_memory_provider_handle_t provider = nullptr; + umf_result_t result = umfMemoryProviderCreate( + umfLevelZeroMemoryProviderOps(), params, &provider); + ASSERT_EQ(result, UMF_RESULT_SUCCESS); + ASSERT_NE(provider, nullptr); + + ze_memory_allocation_properties_t memProps = {}; + void *invalidPtr = reinterpret_cast(0xDEADBEEF); + + ze_context_handle_t context = l0TestHelper.get_test_context(); + ASSERT_NE(context, nullptr); + + ze_result_t zeResult = + utils_ze_get_memory_properties(context, invalidPtr, &memProps); + ASSERT_EQ(zeResult, ZE_RESULT_ERROR_INVALID_ARGUMENT); + + umfMemoryProviderDestroy(provider); +} +*/ + // TODO add tests that mixes Level Zero Memory Provider and Disjoint Pool INSTANTIATE_TEST_SUITE_P(umfLevelZeroProviderTestSuite,