Skip to content

Commit d96bd03

Browse files
committed
[HIP] Fix memory type detection in allocation info queries and USM copy2D
Takes extra care identifying unknown/unregistered memory allocations since ROCm 6.0.0 introduces hipMemoryTypeUnregistered, which we now use to identify system allocations and the attributes query will still return success in this case.
1 parent 3a7d00f commit d96bd03

File tree

2 files changed

+58
-21
lines changed

2 files changed

+58
-21
lines changed

source/adapters/hip/enqueue.cpp

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,25 +1618,55 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMMemcpy2D(
16181618
hipPointerAttribute_t srcAttribs{};
16191619
hipPointerAttribute_t dstAttribs{};
16201620

1621+
// Determine if pSrc and/or pDst are system allocated pageable host memory.
16211622
bool srcIsSystemAlloc{false};
16221623
bool dstIsSystemAlloc{false};
1623-
1624-
hipError_t hipRes{};
1625-
// hipErrorInvalidValue returned from hipPointerGetAttributes for a non-null
1626-
// pointer refers to an OS-allocation, hence pageable host memory. However,
1627-
// this means we cannot rely on the attributes result, hence we mark system
1628-
// pageable memory allocation manually as host memory. The HIP runtime can
1629-
// handle the registering/unregistering of the memory as long as the right
1630-
// copy-kind (direction) is provided to hipMemcpy2DAsync for this case.
1631-
hipRes = hipPointerGetAttributes(&srcAttribs, (const void *)pSrc);
1632-
if (hipRes == hipErrorInvalidValue && pSrc)
1624+
// Error code hipErrorInvalidValue returned from hipPointerGetAttributes
1625+
// for a non-null pointer refers to an OS-allocation, hence we can work
1626+
// with the assumption that this is a pointer to a pageable host memory.
1627+
// Since ROCm version 6.0.0, the enum hipMemoryType can also be marked as
1628+
// hipMemoryTypeUnregistered explicitly to relay that information better.
1629+
// This means we cannot rely on any attribute result, hence we just mark
1630+
// the pointer handle as system allocated pageable host memory.
1631+
// The HIP runtime can handle the registering/unregistering of the memory
1632+
// as long as the right copy-kind (direction) is provided to hipMemcpy2D*.
1633+
hipError_t hipRet = hipPointerGetAttributes(&srcAttribs, pSrc);
1634+
if (pSrc && hipRet == hipErrorInvalidValue)
16331635
srcIsSystemAlloc = true;
1634-
hipRes = hipPointerGetAttributes(&dstAttribs, (const void *)pDst);
1635-
if (hipRes == hipErrorInvalidValue && pDst)
1636+
hipRet = hipPointerGetAttributes(&dstAttribs, (const void *)pDst);
1637+
if (pDst && hipRet == hipErrorInvalidValue)
16361638
dstIsSystemAlloc = true;
1639+
#if HIP_VERSION_MAJOR >= 6
1640+
srcIsSystemAlloc |= srcAttribs.type == hipMemoryTypeUnregistered;
1641+
dstIsSystemAlloc |= dstAttribs.type == hipMemoryTypeUnregistered;
1642+
#endif
16371643

1638-
const unsigned int srcMemType{srcAttribs.type};
1639-
const unsigned int dstMemType{dstAttribs.type};
1644+
unsigned int srcMemType{srcAttribs.type};
1645+
unsigned int dstMemType{dstAttribs.type};
1646+
1647+
// ROCm 5.7.1 finally started updating the type attribute member to
1648+
// hipMemoryTypeManaged for shared memory allocations(hipMallocManaged).
1649+
// Hence, we use a separate query that verifies the pointer use via flags.
1650+
#if HIP_VERSION >= 50700001
1651+
// Determine the source/destination memory type for shared allocations.
1652+
//
1653+
// NOTE: The hipPointerGetAttribute API is marked as [BETA] and fails with
1654+
// exit code -11 when passing a system allocated pointer to it.
1655+
if (!srcIsSystemAlloc && srcAttribs.isManaged) {
1656+
UR_ASSERT(srcAttribs.hostPointer && srcAttribs.hostPointer,
1657+
UR_RESULT_ERROR_INVALID_VALUE);
1658+
UR_CHECK_ERROR(hipPointerGetAttribute(
1659+
&srcMemType, HIP_POINTER_ATTRIBUTE_MEMORY_TYPE,
1660+
reinterpret_cast<hipDeviceptr_t>(const_cast<void *>(pSrc))));
1661+
}
1662+
if (!dstIsSystemAlloc && dstAttribs.isManaged) {
1663+
UR_ASSERT(dstAttribs.hostPointer && dstAttribs.devicePointer,
1664+
UR_RESULT_ERROR_INVALID_VALUE);
1665+
UR_CHECK_ERROR(
1666+
hipPointerGetAttribute(&dstMemType, HIP_POINTER_ATTRIBUTE_MEMORY_TYPE,
1667+
reinterpret_cast<hipDeviceptr_t>(pDst)));
1668+
}
1669+
#endif
16401670

16411671
const bool srcIsHost{(srcMemType == hipMemoryTypeHost) || srcIsSystemAlloc};
16421672
const bool srcIsDevice{srcMemType == hipMemoryTypeDevice};

source/adapters/hip/usm.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ urUSMGetMemAllocInfo(ur_context_handle_t hContext, const void *pMem,
160160
try {
161161
switch (propName) {
162162
case UR_USM_ALLOC_INFO_TYPE: {
163-
unsigned int Value;
164163
// do not throw if hipPointerGetAttribute returns hipErrorInvalidValue
165164
hipError_t Ret = hipPointerGetAttributes(&hipPointerAttributeType, pMem);
166165
if (Ret == hipErrorInvalidValue) {
@@ -170,19 +169,27 @@ urUSMGetMemAllocInfo(ur_context_handle_t hContext, const void *pMem,
170169
// Direct usage of the function, instead of UR_CHECK_ERROR, so we can get
171170
// the line offset.
172171
checkErrorUR(Ret, __func__, __LINE__ - 5, __FILE__);
173-
Value = hipPointerAttributeType.isManaged;
174-
if (Value) {
175-
// pointer to managed memory
176-
return ReturnValue(UR_USM_TYPE_SHARED);
172+
// ROCm 6.0.0 introduces hipMemoryTypeUnregistered in the hipMemoryType
173+
// enum to mark unregistered allocations (i.e., via system allocators).
174+
#if HIP_VERSION_MAJOR >= 6
175+
if (hipPointerAttributeType.type == hipMemoryTypeUnregistered) {
176+
// pointer not known to the HIP subsystem
177+
return ReturnValue(UR_USM_TYPE_UNKNOWN);
177178
}
178-
UR_CHECK_ERROR(hipPointerGetAttributes(&hipPointerAttributeType, pMem));
179+
#endif
180+
unsigned int Value;
179181
#if HIP_VERSION >= 50600000
180182
Value = hipPointerAttributeType.type;
181183
#else
182184
Value = hipPointerAttributeType.memoryType;
183185
#endif
184-
UR_ASSERT(Value == hipMemoryTypeDevice || Value == hipMemoryTypeHost,
186+
UR_ASSERT(Value == hipMemoryTypeDevice || Value == hipMemoryTypeHost ||
187+
Value == hipMemoryTypeManaged,
185188
UR_RESULT_ERROR_INVALID_MEM_OBJECT);
189+
if (hipPointerAttributeType.isManaged || Value == hipMemoryTypeManaged) {
190+
// pointer to managed memory
191+
return ReturnValue(UR_USM_TYPE_SHARED);
192+
}
186193
if (Value == hipMemoryTypeDevice) {
187194
// pointer to device memory
188195
return ReturnValue(UR_USM_TYPE_DEVICE);

0 commit comments

Comments
 (0)