Skip to content

[L0 v2] use UMF in urUSMGetMemAllocInfo #2473

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

Closed
wants to merge 3 commits into from
Closed
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
116 changes: 48 additions & 68 deletions source/adapters/level_zero/v2/usm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
#include <umf/pools/pool_proxy.h>
#include <umf/providers/provider_level_zero.h>

static inline void UMF_CALL_THROWS(umf_result_t res) {
if (res != UMF_RESULT_SUCCESS) {
throw res;
}
}

namespace umf {
ur_result_t getProviderNativeError(const char *providerName,
int32_t nativeError) {
Expand Down Expand Up @@ -85,31 +91,18 @@ static umf::pool_unique_handle_t
makePool(usm::umf_disjoint_pool_config_t *poolParams,
usm::pool_descriptor poolDescriptor) {
umf_level_zero_memory_provider_params_handle_t params = NULL;
umf_result_t umf_ret = umfLevelZeroMemoryProviderParamsCreate(&params);
if (umf_ret != UMF_RESULT_SUCCESS) {
throw umf::umf2urResult(umf_ret);
}

umf_ret = umfLevelZeroMemoryProviderParamsSetContext(
params, poolDescriptor.hContext->getZeHandle());
if (umf_ret != UMF_RESULT_SUCCESS) {
throw umf::umf2urResult(umf_ret);
};
UMF_CALL_THROWS(umfLevelZeroMemoryProviderParamsCreate(&params));
UMF_CALL_THROWS(umfLevelZeroMemoryProviderParamsSetContext(
params, poolDescriptor.hContext->getZeHandle()));

ze_device_handle_t level_zero_device_handle =
poolDescriptor.hDevice ? poolDescriptor.hDevice->ZeDevice : nullptr;

umf_ret = umfLevelZeroMemoryProviderParamsSetDevice(params,
level_zero_device_handle);
if (umf_ret != UMF_RESULT_SUCCESS) {
throw umf::umf2urResult(umf_ret);
}
UMF_CALL_THROWS(umfLevelZeroMemoryProviderParamsSetDevice(
params, level_zero_device_handle));

umf_ret = umfLevelZeroMemoryProviderParamsSetMemoryType(
params, urToUmfMemoryType(poolDescriptor.type));
if (umf_ret != UMF_RESULT_SUCCESS) {
throw umf::umf2urResult(umf_ret);
}
UMF_CALL_THROWS(umfLevelZeroMemoryProviderParamsSetMemoryType(
params, urToUmfMemoryType(poolDescriptor.type)));

std::vector<ze_device_handle_t> residentZeHandles;

Expand All @@ -122,11 +115,8 @@ makePool(usm::umf_disjoint_pool_config_t *poolParams,
residentZeHandles.push_back(device->ZeDevice);
}

umf_ret = umfLevelZeroMemoryProviderParamsSetResidentDevices(
params, residentZeHandles.data(), residentZeHandles.size());
if (umf_ret != UMF_RESULT_SUCCESS) {
throw umf::umf2urResult(umf_ret);
}
UMF_CALL_THROWS(umfLevelZeroMemoryProviderParamsSetResidentDevices(
params, residentZeHandles.data(), residentZeHandles.size()));
}

auto [ret, provider] =
Expand All @@ -137,16 +127,16 @@ makePool(usm::umf_disjoint_pool_config_t *poolParams,

if (!poolParams) {
auto [ret, poolHandle] = umf::poolMakeUniqueFromOps(
umfProxyPoolOps(), std::move(provider), nullptr);
umfProxyPoolOps(), std::move(provider), nullptr, poolDescriptor);
if (ret != UMF_RESULT_SUCCESS)
throw umf::umf2urResult(ret);
return std::move(poolHandle);
} else {
auto umfParams = getUmfParamsHandle(*poolParams);

auto [ret, poolHandle] =
umf::poolMakeUniqueFromOps(umfDisjointPoolOps(), std::move(provider),
static_cast<void *>(umfParams.get()));
auto [ret, poolHandle] = umf::poolMakeUniqueFromOps(
umfDisjointPoolOps(), std::move(provider),
static_cast<void *>(umfParams.get()), poolDescriptor);
if (ret != UMF_RESULT_SUCCESS)
throw umf::umf2urResult(ret);
return std::move(poolHandle);
Expand Down Expand Up @@ -366,6 +356,19 @@ urUSMFree(ur_context_handle_t hContext, ///< [in] handle of the context object
return exceptionToResult(std::current_exception());
}

static usm::pool_descriptor *getPoolDescriptor(const void *ptr) {
auto umfPool = umfPoolByPtr(ptr);
if (!umfPool) {
logger::error("urUSMGetMemAllocInfo: no memory associated with given ptr");
throw UR_RESULT_ERROR_INVALID_VALUE;
}

usm::pool_descriptor *poolDesc;
UMF_CALL_THROWS(umfPoolGetTag(umfPool, reinterpret_cast<void **>(&poolDesc)));

return poolDesc;
}

ur_result_t urUSMGetMemAllocInfo(
ur_context_handle_t hContext, ///< [in] handle of the context object
const void *ptr, ///< [in] pointer to USM memory object
Expand All @@ -377,48 +380,24 @@ ur_result_t urUSMGetMemAllocInfo(
size_t *pPropValueSizeRet ///< [out][optional] bytes returned in USM
///< allocation property
) try {
ze_device_handle_t zeDeviceHandle;
ZeStruct<ze_memory_allocation_properties_t> zeMemoryAllocationProperties;

// TODO: implement this using UMF once
// https://github.com/oneapi-src/unified-memory-framework/issues/686
// https://github.com/oneapi-src/unified-memory-framework/issues/687
// are implemented
ZE2UR_CALL(zeMemGetAllocProperties,
(hContext->getZeHandle(), ptr, &zeMemoryAllocationProperties,
&zeDeviceHandle));

UrReturnHelper ReturnValue(propValueSize, pPropValue, pPropValueSizeRet);
switch (propName) {
case UR_USM_ALLOC_INFO_TYPE: {
ur_usm_type_t memAllocType;
switch (zeMemoryAllocationProperties.type) {
case ZE_MEMORY_TYPE_UNKNOWN:
memAllocType = UR_USM_TYPE_UNKNOWN;
break;
case ZE_MEMORY_TYPE_HOST:
memAllocType = UR_USM_TYPE_HOST;
break;
case ZE_MEMORY_TYPE_DEVICE:
memAllocType = UR_USM_TYPE_DEVICE;
break;
case ZE_MEMORY_TYPE_SHARED:
memAllocType = UR_USM_TYPE_SHARED;
break;
default:
logger::error("urUSMGetMemAllocInfo: unexpected usm memory type");
return UR_RESULT_ERROR_INVALID_VALUE;
try {
auto poolDesc = getPoolDescriptor(ptr);
return ReturnValue(poolDesc->type);
} catch (...) {
return ReturnValue(UR_USM_TYPE_UNKNOWN);
}
return ReturnValue(memAllocType);
}
case UR_USM_ALLOC_INFO_DEVICE:
if (zeDeviceHandle) {
auto Platform = hContext->getPlatform();
auto Device = Platform->getDeviceFromNativeHandle(zeDeviceHandle);
return Device ? ReturnValue(Device) : UR_RESULT_ERROR_INVALID_VALUE;
} else {
return UR_RESULT_ERROR_INVALID_VALUE;
}
case UR_USM_ALLOC_INFO_DEVICE: {
auto poolDesc = getPoolDescriptor(ptr);
return ReturnValue(poolDesc->hDevice);
}
// TODO: implement this using UMF once
// https://github.com/oneapi-src/unified-memory-framework/issues/686
// is implemented
case UR_USM_ALLOC_INFO_BASE_PTR: {
void *base;
ZE2UR_CALL(zeMemGetAddressRange,
Expand All @@ -432,9 +411,10 @@ ur_result_t urUSMGetMemAllocInfo(
return ReturnValue(size);
}
case UR_USM_ALLOC_INFO_POOL: {
// TODO
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
default:
auto poolDesc = getPoolDescriptor(ptr);
return ReturnValue(poolDesc->poolHandle);
}
default: {
logger::error("urUSMGetMemAllocInfo: unsupported ParamName");
return UR_RESULT_ERROR_INVALID_VALUE;
}
Expand Down
9 changes: 5 additions & 4 deletions source/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ if (NOT DEFINED UMF_REPO)
endif()

if (NOT DEFINED UMF_TAG)
# tag v0.10.0
# Tagger: Łukasz Stolarczuk <lukasz.stolarczuk@intel.com>
# Date: Mon Dec 9 17:01:43 2024 +0100
set(UMF_TAG v0.10.0)
# commit 95861f3860d335fa23846cd31c35faade9c0b90b
# Merge: 97eacc7 b07c1a2
# Author: Łukasz Stolarczuk <lukasz.stolarczuk@intel.com>
# Date: Mon Dec 16 13:30:12 2024 +0100
set(UMF_TAG 95861f3860d335fa23846cd31c35faade9c0b90b)
endif()

message(STATUS "Will fetch Unified Memory Framework from ${UMF_REPO}")
Expand Down
41 changes: 40 additions & 1 deletion source/common/umf_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ auto memoryProviderMakeUnique(Args &&...args) {
UMF_ASSIGN_OP(ops, T, get_recommended_page_size, UMF_RESULT_ERROR_UNKNOWN);
UMF_ASSIGN_OP(ops, T, get_min_page_size, UMF_RESULT_ERROR_UNKNOWN);
UMF_ASSIGN_OP(ops, T, get_name, "");
UMF_ASSIGN_OP(ops.ext, T, free, UMF_RESULT_ERROR_UNKNOWN);
UMF_ASSIGN_OP(ops, T, free, UMF_RESULT_ERROR_UNKNOWN);
UMF_ASSIGN_OP(ops.ext, T, purge_lazy, UMF_RESULT_ERROR_UNKNOWN);
UMF_ASSIGN_OP(ops.ext, T, purge_force, UMF_RESULT_ERROR_UNKNOWN);
UMF_ASSIGN_OP(ops.ext, T, allocation_merge, UMF_RESULT_ERROR_UNKNOWN);
Expand Down Expand Up @@ -222,6 +222,45 @@ static inline auto poolMakeUniqueFromOps(umf_memory_pool_ops_t *ops,
UMF_RESULT_SUCCESS, pool_unique_handle_t(hPool, umfPoolDestroy)};
}

template <typename Tag>
static inline auto poolMakeUniqueFromOps(umf_memory_pool_ops_t *ops,
provider_unique_handle_t provider,
void *params, const Tag &tag) {
auto poolTag = new Tag(tag);

umf_memory_pool_handle_t hPool;
auto ret = umfPoolCreate(ops, provider.get(), params,
UMF_POOL_CREATE_FLAG_OWN_PROVIDER, &hPool);
if (ret != UMF_RESULT_SUCCESS) {
return std::pair<umf_result_t, pool_unique_handle_t>{
ret, pool_unique_handle_t(nullptr, nullptr)};
}

ret = umfPoolSetTag(hPool, poolTag, nullptr);
if (ret != UMF_RESULT_SUCCESS) {
umfPoolDestroy(hPool);
return std::pair<umf_result_t, pool_unique_handle_t>{
ret, pool_unique_handle_t(nullptr, nullptr)};
}

provider.release(); // pool now owns the provider

return std::pair<umf_result_t, pool_unique_handle_t>{
UMF_RESULT_SUCCESS,
pool_unique_handle_t(hPool, [](umf_memory_pool_handle_t hPool) {
Tag *tag = nullptr;
umfPoolGetTag(hPool, reinterpret_cast<void **>(&tag));

if (tag) {
delete tag;
} else {
logger::error("Failed to get tag from pool");
}

umfPoolDestroy(hPool);
})};
}

static inline auto providerMakeUniqueFromOps(umf_memory_provider_ops_t *ops,
void *params) {
umf_memory_provider_handle_t hProvider;
Expand Down
1 change: 0 additions & 1 deletion test/conformance/usm/usm_adapter_level_zero_v2.match

This file was deleted.

Loading