Skip to content

Commit f650c09

Browse files
author
Hugh Delaney
authored
Merge branch 'main' into make-imagecreate-safe
2 parents 730f305 + 2c4303c commit f650c09

File tree

10 files changed

+102
-58
lines changed

10 files changed

+102
-58
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/device.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,8 +782,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice,
782782
UR_MEMORY_ORDER_CAPABILITY_FLAG_RELEASE;
783783
return ReturnValue(Capabilities);
784784
}
785-
case UR_DEVICE_INFO_ATOMIC_MEMORY_SCOPE_CAPABILITIES:
786-
case UR_DEVICE_INFO_ATOMIC_FENCE_SCOPE_CAPABILITIES: {
785+
case UR_DEVICE_INFO_ATOMIC_MEMORY_SCOPE_CAPABILITIES: {
787786
// SYCL2020 4.6.4.2 minimum mandated capabilities for
788787
// atomic_fence/memory_scope_capabilities.
789788
// Because scopes are hierarchical, wider scopes support all narrower
@@ -795,6 +794,15 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice,
795794
UR_MEMORY_SCOPE_CAPABILITY_FLAG_WORK_GROUP;
796795
return ReturnValue(Capabilities);
797796
}
797+
case UR_DEVICE_INFO_ATOMIC_FENCE_SCOPE_CAPABILITIES: {
798+
constexpr ur_memory_scope_capability_flags_t Capabilities =
799+
UR_MEMORY_SCOPE_CAPABILITY_FLAG_WORK_ITEM |
800+
UR_MEMORY_SCOPE_CAPABILITY_FLAG_SUB_GROUP |
801+
UR_MEMORY_SCOPE_CAPABILITY_FLAG_WORK_GROUP |
802+
UR_MEMORY_SCOPE_CAPABILITY_FLAG_DEVICE |
803+
UR_MEMORY_SCOPE_CAPABILITY_FLAG_SYSTEM;
804+
return ReturnValue(Capabilities);
805+
}
798806
case UR_DEVICE_INFO_ATOMIC_FENCE_ORDER_CAPABILITIES: {
799807
// SYCL2020 4.6.4.2 minimum mandated capabilities for
800808
// atomic_fence_order_capabilities.
@@ -803,6 +811,16 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice,
803811
UR_MEMORY_ORDER_CAPABILITY_FLAG_ACQUIRE |
804812
UR_MEMORY_ORDER_CAPABILITY_FLAG_RELEASE |
805813
UR_MEMORY_ORDER_CAPABILITY_FLAG_ACQ_REL;
814+
#ifdef __HIP_PLATFORM_NVIDIA__
815+
// Nvidia introduced fence.sc for seq_cst only since SM 7.0.
816+
int Major = 0;
817+
UR_CHECK_ERROR(hipDeviceGetAttribute(
818+
&Major, hipDeviceAttributeComputeCapabilityMajor, hDevice->get()));
819+
if (Major >= 7)
820+
Capabilities |= UR_MEMORY_ORDER_CAPABILITY_FLAG_SEQ_CST;
821+
#else
822+
Capabilities |= UR_MEMORY_ORDER_CAPABILITY_FLAG_SEQ_CST;
823+
#endif
806824
return ReturnValue(Capabilities);
807825
}
808826
case UR_DEVICE_INFO_DEVICE_ID: {

source/adapters/hip/enqueue.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -789,21 +789,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill(
789789
ur_event_handle_t *phEvent) {
790790
UR_ASSERT(size + offset <= std::get<BufferMem>(hBuffer->Mem).getSize(),
791791
UR_RESULT_ERROR_INVALID_SIZE);
792-
auto ArgsAreMultiplesOfPatternSize =
793-
(offset % patternSize == 0) || (size % patternSize == 0);
794-
795-
auto PatternIsValid = (pPattern != nullptr);
796-
797-
auto PatternSizeIsValid =
798-
((patternSize & (patternSize - 1)) == 0) && // is power of two
799-
(patternSize > 0) && (patternSize <= 128); // falls within valid range
800-
801-
UR_ASSERT(ArgsAreMultiplesOfPatternSize && PatternIsValid &&
802-
PatternSizeIsValid,
803-
UR_RESULT_ERROR_INVALID_VALUE);
804-
std::ignore = ArgsAreMultiplesOfPatternSize;
805-
std::ignore = PatternIsValid;
806-
std::ignore = PatternSizeIsValid;
807792

808793
std::unique_ptr<ur_event_handle_t_> RetImplEvent{nullptr};
809794
hBuffer->setLastQueueWritingToMemObj(hQueue);

source/adapters/hip/program.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,11 @@ urProgramCreateWithIL(ur_context_handle_t, const void *, size_t,
283283
UR_APIEXPORT ur_result_t UR_APICALL
284284
urProgramCompile(ur_context_handle_t hContext, ur_program_handle_t hProgram,
285285
const char *pOptions) {
286-
return urProgramBuild(hContext, hProgram, pOptions);
286+
UR_CHECK_ERROR(urProgramBuild(hContext, hProgram, pOptions));
287+
// urProgramBuild sets the BinaryType to UR_PROGRAM_BINARY_TYPE_EXECUTABLE, so
288+
// set it to the correct value for urProgramCompile post-hoc.
289+
hProgram->BinaryType = UR_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
290+
return UR_RESULT_SUCCESS;
287291
}
288292

289293
UR_APIEXPORT ur_result_t UR_APICALL urProgramCompileExp(ur_program_handle_t,
@@ -312,6 +316,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urProgramBuild(ur_context_handle_t,
312316
ScopedContext Active(hProgram->getDevice());
313317

314318
hProgram->buildProgram(pOptions);
319+
hProgram->BinaryType = UR_PROGRAM_BINARY_TYPE_EXECUTABLE;
315320

316321
} catch (ur_result_t Err) {
317322
Result = Err;
@@ -355,13 +360,14 @@ urProgramGetBuildInfo(ur_program_handle_t hProgram, ur_device_handle_t,
355360
UrReturnHelper ReturnValue(propSize, pPropValue, pPropSizeRet);
356361

357362
switch (propName) {
358-
case UR_PROGRAM_BUILD_INFO_STATUS: {
363+
case UR_PROGRAM_BUILD_INFO_STATUS:
359364
return ReturnValue(hProgram->BuildStatus);
360-
}
361365
case UR_PROGRAM_BUILD_INFO_OPTIONS:
362366
return ReturnValue(hProgram->BuildOptions.c_str());
363367
case UR_PROGRAM_BUILD_INFO_LOG:
364368
return ReturnValue(hProgram->InfoLog, hProgram->MAX_LOG_SIZE);
369+
case UR_PROGRAM_BUILD_INFO_BINARY_TYPE:
370+
return ReturnValue(hProgram->BinaryType);
365371
default:
366372
break;
367373
}
@@ -490,6 +496,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urProgramCreateWithBinary(
490496
UR_ASSERT(size, UR_RESULT_ERROR_INVALID_SIZE);
491497

492498
UR_CHECK_ERROR(RetProgram->setBinary(pBinary_string, size));
499+
RetProgram->BinaryType = UR_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
493500

494501
*phProgram = RetProgram.release();
495502
} catch (std::bad_alloc &) {

source/adapters/hip/program.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ struct ur_program_handle_t_ {
2727
ur_device_handle_t Device;
2828
std::string ExecutableCache;
2929

30+
// The ur_program_binary_type_t property is defined individually for every
31+
// device in a program. However, since the HIP adapter only has 1 device per
32+
// program, there is no need to keep track of its value for each
33+
// device.
34+
ur_program_binary_type_t BinaryType = UR_PROGRAM_BINARY_TYPE_NONE;
35+
3036
// Metadata
3137
bool IsRelocatable = false;
3238

source/adapters/hip/queue.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,12 @@ UR_APIEXPORT ur_result_t UR_APICALL urQueueGetInfo(ur_queue_handle_t hQueue,
193193
});
194194
return ReturnValue(IsReady);
195195
}
196+
case UR_QUEUE_INFO_DEVICE_DEFAULT:
197+
case UR_QUEUE_INFO_SIZE:
198+
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
196199
default:
197-
break;
200+
return UR_RESULT_ERROR_INVALID_ENUMERATION;
198201
}
199-
return {};
200202
}
201203

202204
UR_APIEXPORT ur_result_t UR_APICALL urQueueRetain(ur_queue_handle_t hQueue) {

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/enqueue/enqueue_adapter_hip.match

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ urEnqueueKernelLaunchKernelSubGroupTest.Success/AMD_HIP_BACKEND___{{.*}}_
55
urEnqueueKernelLaunchUSMLinkedList.Success/AMD_HIP_BACKEND___{{.*}}___UsePoolEnabled
66
{{OPT}}urEnqueueMemBufferCopyRectTestWithParam.Success/AMD_HIP_BACKEND___{{.*}}___copy_row_2D
77
{{OPT}}urEnqueueMemBufferCopyRectTestWithParam.Success/AMD_HIP_BACKEND___{{.*}}___copy_3d_2d
8-
urEnqueueMemBufferFillTest.Success/AMD_HIP_BACKEND___{{.*}}___size__256__patternSize__256
9-
urEnqueueMemBufferFillTest.Success/AMD_HIP_BACKEND___{{.*}}___size__1024__patternSize__256
108
{{OPT}}urEnqueueMemBufferWriteRectTestWithParam.Success/AMD_HIP_BACKEND___{{.*}}___write_row_2D
119
{{OPT}}urEnqueueMemBufferWriteRectTestWithParam.Success/AMD_HIP_BACKEND___{{.*}}___write_3d_2d
1210
urEnqueueUSMAdviseWithParamTest.Success/AMD_HIP_BACKEND___{{.*}}___UR_USM_ADVICE_FLAG_DEFAULT

test/conformance/program/program_adapter_hip.match

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
urProgramBuildTest.BuildFailure/AMD_HIP_BACKEND___{{.*}}_
22
# HIP hasn't implemented urProgramCreateWithNativeHandleTest
33
{{OPT}}urProgramCreateWithNativeHandleTest.Success/AMD_HIP_BACKEND___{{.*}}_
4-
urProgramGetBuildInfoTest.Success/AMD_HIP_BACKEND___{{.*}}___UR_PROGRAM_BUILD_INFO_BINARY_TYPE
54
# This test flakily fails
65
{{OPT}}urProgramGetBuildInfoSingleTest.LogIsNullTerminated/AMD_HIP_BACKEND___{{.*}}_
76
# HIP doesn't expose kernel numbers or names

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)