Skip to content

Commit 532dac5

Browse files
aarongreigkbenzie
authored andcommitted
Merge pull request #1455 from GeorgeWeb/georgi/fix-hip-usm-copy2d
[HIP] Fix memory type detection in allocation info queries and USM copy2D
1 parent 26cc04e commit 532dac5

File tree

2 files changed

+55
-16
lines changed

2 files changed

+55
-16
lines changed

source/adapters/hip/enqueue.cpp

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,25 +1618,57 @@ 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};
16231624

16241625
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);
1626+
// Error code hipErrorInvalidValue returned from hipPointerGetAttributes
1627+
// for a non-null pointer refers to an OS-allocation, hence we can work
1628+
// with the assumption that this is a pointer to a pageable host memory.
1629+
// Since ROCm version 6.0.0, the enum hipMemoryType can also be marked as
1630+
// hipMemoryTypeUnregistered explicitly to relay that information better.
1631+
// This means we cannot rely on any attribute result, hence we just mark
1632+
// the pointer handle as system allocated pageable host memory.
1633+
// The HIP runtime can handle the registering/unregistering of the memory
1634+
// as long as the right copy-kind (direction) is provided to hipMemcpy2D*.
1635+
hipRes = hipPointerGetAttributes(&srcAttribs, pSrc);
16321636
if (hipRes == hipErrorInvalidValue && pSrc)
16331637
srcIsSystemAlloc = true;
16341638
hipRes = hipPointerGetAttributes(&dstAttribs, (const void *)pDst);
16351639
if (hipRes == hipErrorInvalidValue && pDst)
16361640
dstIsSystemAlloc = true;
1641+
#if HIP_VERSION_MAJOR >= 6
1642+
srcIsSystemAlloc |= srcAttribs.type == hipMemoryTypeUnregistered;
1643+
dstIsSystemAlloc |= dstAttribs.type == hipMemoryTypeUnregistered;
1644+
#endif
16371645

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

16411673
const bool srcIsHost{(srcMemType == hipMemoryTypeHost) || srcIsSystemAlloc};
16421674
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)