Skip to content

Commit abe85cc

Browse files
authored
Merge pull request #1713 from frasercrmck/hip-usm-mem-info-base-ptr
[HIP] Add support for querying USM base pointer
2 parents 7401931 + 49ef82d commit abe85cc

File tree

3 files changed

+62
-33
lines changed

3 files changed

+62
-33
lines changed

source/adapters/hip/common.hpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,38 @@ template <typename T> class ReleaseGuard {
204204
/// UR object.
205205
void dismiss() { Captive = nullptr; }
206206
};
207+
208+
// Helper method to return a (non-null) pointer's attributes, or std::nullopt in
209+
// the case that the pointer is unknown to the HIP subsystem.
210+
inline static std::optional<hipPointerAttribute_t>
211+
getPointerAttributes(const void *pMem) {
212+
// do not throw if hipPointerGetAttributes returns hipErrorInvalidValue
213+
hipPointerAttribute_t hipPointerAttributes;
214+
hipError_t Ret = hipPointerGetAttributes(&hipPointerAttributes, pMem);
215+
if (Ret == hipErrorInvalidValue && pMem) {
216+
// pointer non-null but not known to the HIP subsystem
217+
return std::nullopt;
218+
}
219+
// Direct usage of the function, instead of UR_CHECK_ERROR, so we can get
220+
// the line offset.
221+
checkErrorUR(Ret, __func__, __LINE__ - 7, __FILE__);
222+
// ROCm 6.0.0 introduces hipMemoryTypeUnregistered in the hipMemoryType
223+
// enum to mark unregistered allocations (i.e., via system allocators).
224+
#if HIP_VERSION_MAJOR >= 6
225+
if (hipPointerAttributes.type == hipMemoryTypeUnregistered) {
226+
// pointer not known to the HIP subsystem
227+
return std::nullopt;
228+
}
229+
#endif
230+
return hipPointerAttributes;
231+
}
232+
233+
// Helper method to abstract away the fact that retrieving a pointer's memory
234+
// type differs depending on the version of HIP.
235+
inline static unsigned getMemoryType(hipPointerAttribute_t hipPointerAttrs) {
236+
#if HIP_VERSION >= 50600000
237+
return hipPointerAttrs.type;
238+
#else
239+
return hipPointerAttrs.memoryType;
240+
#endif
241+
}

source/adapters/hip/usm.cpp

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -152,41 +152,21 @@ UR_APIEXPORT ur_result_t UR_APICALL
152152
urUSMGetMemAllocInfo(ur_context_handle_t hContext, const void *pMem,
153153
ur_usm_alloc_info_t propName, size_t propValueSize,
154154
void *pPropValue, size_t *pPropValueSizeRet) {
155-
ur_result_t Result = UR_RESULT_SUCCESS;
156-
hipPointerAttribute_t hipPointerAttributeType;
157-
158155
UrReturnHelper ReturnValue(propValueSize, pPropValue, pPropValueSizeRet);
159156

160157
try {
161158
switch (propName) {
162159
case UR_USM_ALLOC_INFO_TYPE: {
163-
// do not throw if hipPointerGetAttribute returns hipErrorInvalidValue
164-
hipError_t Ret = hipPointerGetAttributes(&hipPointerAttributeType, pMem);
165-
if (Ret == hipErrorInvalidValue) {
166-
// pointer not known to the HIP subsystem
167-
return ReturnValue(UR_USM_TYPE_UNKNOWN);
168-
}
169-
// Direct usage of the function, instead of UR_CHECK_ERROR, so we can get
170-
// the line offset.
171-
checkErrorUR(Ret, __func__, __LINE__ - 5, __FILE__);
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) {
160+
auto MaybePointerAttrs = getPointerAttributes(pMem);
161+
if (!MaybePointerAttrs.has_value()) {
176162
// pointer not known to the HIP subsystem
177163
return ReturnValue(UR_USM_TYPE_UNKNOWN);
178164
}
179-
#endif
180-
unsigned int Value;
181-
#if HIP_VERSION >= 50600000
182-
Value = hipPointerAttributeType.type;
183-
#else
184-
Value = hipPointerAttributeType.memoryType;
185-
#endif
165+
auto Value = getMemoryType(*MaybePointerAttrs);
186166
UR_ASSERT(Value == hipMemoryTypeDevice || Value == hipMemoryTypeHost ||
187167
Value == hipMemoryTypeManaged,
188168
UR_RESULT_ERROR_INVALID_MEM_OBJECT);
189-
if (hipPointerAttributeType.isManaged || Value == hipMemoryTypeManaged) {
169+
if (MaybePointerAttrs->isManaged || Value == hipMemoryTypeManaged) {
190170
// pointer to managed memory
191171
return ReturnValue(UR_USM_TYPE_SHARED);
192172
}
@@ -202,15 +182,18 @@ urUSMGetMemAllocInfo(ur_context_handle_t hContext, const void *pMem,
202182
ur::unreachable();
203183
}
204184
case UR_USM_ALLOC_INFO_DEVICE: {
205-
// get device index associated with this pointer
206-
UR_CHECK_ERROR(hipPointerGetAttributes(&hipPointerAttributeType, pMem));
185+
auto MaybePointerAttrs = getPointerAttributes(pMem);
186+
if (!MaybePointerAttrs.has_value()) {
187+
// pointer not known to the HIP subsystem
188+
return ReturnValue(UR_USM_TYPE_UNKNOWN);
189+
}
207190

208-
int DeviceIdx = hipPointerAttributeType.device;
191+
int DeviceIdx = MaybePointerAttrs->device;
209192

210193
// hip backend has only one platform containing all devices
211194
ur_platform_handle_t platform;
212195
ur_adapter_handle_t AdapterHandle = &adapter;
213-
Result = urPlatformGet(&AdapterHandle, 1, 1, &platform, nullptr);
196+
UR_CHECK_ERROR(urPlatformGet(&AdapterHandle, 1, 1, &platform, nullptr));
214197

215198
// get the device from the platform
216199
ur_device_handle_t Device = platform->Devices[DeviceIdx].get();
@@ -227,20 +210,32 @@ urUSMGetMemAllocInfo(ur_context_handle_t hContext, const void *pMem,
227210
}
228211
return ReturnValue(Pool);
229212
}
213+
case UR_USM_ALLOC_INFO_BASE_PTR:
214+
// HIP gives us the ability to query the base pointer for a device
215+
// pointer, so check whether we've got one of those.
216+
if (auto MaybePointerAttrs = getPointerAttributes(pMem)) {
217+
if (getMemoryType(*MaybePointerAttrs) == hipMemoryTypeDevice) {
218+
void *Base = nullptr;
219+
UR_CHECK_ERROR(hipPointerGetAttribute(
220+
&Base, HIP_POINTER_ATTRIBUTE_RANGE_START_ADDR,
221+
(hipDeviceptr_t)pMem));
222+
return ReturnValue(Base);
223+
}
224+
}
225+
// If not, we can't be sure.
226+
return UR_RESULT_ERROR_INVALID_VALUE;
230227
case UR_USM_ALLOC_INFO_SIZE: {
231228
size_t RangeSize = 0;
232229
UR_CHECK_ERROR(hipMemPtrGetInfo(const_cast<void *>(pMem), &RangeSize));
233230
return ReturnValue(RangeSize);
234231
}
235-
case UR_USM_ALLOC_INFO_BASE_PTR:
236-
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
237232
default:
238233
return UR_RESULT_ERROR_INVALID_ENUMERATION;
239234
}
240235
} catch (ur_result_t Error) {
241-
Result = Error;
236+
return Error;
242237
}
243-
return Result;
238+
return UR_RESULT_SUCCESS;
244239
}
245240

246241
UR_APIEXPORT ur_result_t UR_APICALL urUSMImportExp(ur_context_handle_t Context,

test/conformance/usm/usm_adapter_hip.match

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ urUSMDeviceAllocAlignmentTest.SuccessAlignedAllocations/AMD_HIP_BACKEND___{{.*}}
2121
urUSMDeviceAllocAlignmentTest.SuccessAlignedAllocations/AMD_HIP_BACKEND___{{.*}}___UsePoolEnabled_64_8
2222
urUSMDeviceAllocAlignmentTest.SuccessAlignedAllocations/AMD_HIP_BACKEND___{{.*}}___UsePoolEnabled_64_512
2323
urUSMDeviceAllocAlignmentTest.SuccessAlignedAllocations/AMD_HIP_BACKEND___{{.*}}___UsePoolEnabled_64_2048
24-
urUSMGetMemAllocInfoTest.Success/AMD_HIP_BACKEND___{{.*}}___UR_USM_ALLOC_INFO_BASE_PTR
2524
urUSMGetMemAllocInfoTest.Success/AMD_HIP_BACKEND___{{.*}}___UR_USM_ALLOC_INFO_POOL
2625
urUSMHostAllocTest.Success/AMD_HIP_BACKEND___{{.*}}___UsePoolEnabled
2726
urUSMHostAllocTest.SuccessWithDescriptors/AMD_HIP_BACKEND___{{.*}}___UsePoolEnabled

0 commit comments

Comments
 (0)