diff --git a/projects/clr/hipamd/src/hip_memory.cpp b/projects/clr/hipamd/src/hip_memory.cpp index 4cbfddba7b..09d3c39d7b 100644 --- a/projects/clr/hipamd/src/hip_memory.cpp +++ b/projects/clr/hipamd/src/hip_memory.cpp @@ -2612,9 +2612,37 @@ hipError_t ihipMemset(void* dst, int64_t value, size_t valueSize, size_t sizeByt return hip_error; } +hipError_t checkAsync(void* dst, int value, size_t valueSize, size_t sizeBytes, bool& isAsync) { + + if (sizeBytes == 0) { + return hipSuccess; + } + + hipError_t hip_error = ihipMemset_validate(dst, value, valueSize, sizeBytes); + if (hip_error != hipSuccess) { + return hip_error; + } + + // This is required to comply with the spec + // spec says hipMemset will be asynchronous when destination memory is device memory + isAsync = false; + size_t offset = 0; + amd::Memory* memObj = getMemoryObject(dst, offset); + auto flags = memObj->getMemFlags(); + if (!(flags & (CL_MEM_USE_HOST_PTR | CL_MEM_SVM_ATOMICS | CL_MEM_SVM_FINE_GRAIN_BUFFER))) { + isAsync = true; + } + return hipSuccess; +} + hipError_t hipMemset_common(void* dst, int value, size_t sizeBytes, hipStream_t stream=nullptr) { CHECK_STREAM_CAPTURING(); - return ihipMemset(dst, value, sizeof(int8_t), sizeBytes, stream); + bool isAsync = false; + hipError_t status = checkAsync(dst, value, sizeof(int8_t), sizeBytes, isAsync); + if (status != hipSuccess) { + return status; + } + return ihipMemset(dst, value, sizeof(int8_t), sizeBytes, stream, isAsync); } hipError_t hipMemset_spt(void* dst, int value, size_t sizeBytes) { @@ -2647,7 +2675,12 @@ hipError_t hipMemsetAsync_spt(void* dst, int value, size_t sizeBytes, hipStream_ hipError_t hipMemsetD8(hipDeviceptr_t dst, unsigned char value, size_t count) { HIP_INIT_API(hipMemsetD8, dst, value, count); CHECK_STREAM_CAPTURING(); - HIP_RETURN(ihipMemset(dst, value, sizeof(int8_t), count * sizeof(int8_t), nullptr)); + bool isAsync = false; + hipError_t status = checkAsync(dst, value, sizeof(int8_t), count * sizeof(int8_t), isAsync); + if (status != hipSuccess) { + return status; + } + HIP_RETURN(ihipMemset(dst, value, sizeof(int8_t), count * sizeof(int8_t), nullptr, isAsync)); } hipError_t hipMemsetD8Async(hipDeviceptr_t dst, unsigned char value, size_t count, @@ -2663,7 +2696,12 @@ hipError_t hipMemsetD8Async(hipDeviceptr_t dst, unsigned char value, size_t coun hipError_t hipMemsetD16(hipDeviceptr_t dst, unsigned short value, size_t count) { HIP_INIT_API(hipMemsetD16, dst, value, count); CHECK_STREAM_CAPTURING(); - HIP_RETURN(ihipMemset(dst, value, sizeof(int16_t), count * sizeof(int16_t), nullptr)); + bool isAsync = false; + hipError_t status = checkAsync(dst, value, sizeof(int16_t), count * sizeof(int16_t), isAsync); + if (status != hipSuccess) { + return status; + } + HIP_RETURN(ihipMemset(dst, value, sizeof(int16_t), count * sizeof(int16_t), nullptr, isAsync)); } hipError_t hipMemsetD16Async(hipDeviceptr_t dst, unsigned short value, size_t count, @@ -2679,7 +2717,12 @@ hipError_t hipMemsetD16Async(hipDeviceptr_t dst, unsigned short value, size_t co hipError_t hipMemsetD32(hipDeviceptr_t dst, int value, size_t count) { HIP_INIT_API(hipMemsetD32, dst, value, count); CHECK_STREAM_CAPTURING(); - HIP_RETURN(ihipMemset(dst, value, sizeof(int32_t), count * sizeof(int32_t), nullptr)); + bool isAsync = false; + hipError_t status = checkAsync(dst, value, sizeof(int32_t), count * sizeof(int32_t), isAsync); + if (status != hipSuccess) { + return status; + } + HIP_RETURN(ihipMemset(dst, value, sizeof(int32_t), count * sizeof(int32_t), nullptr, isAsync)); } hipError_t hipMemsetD32Async(hipDeviceptr_t dst, int value, size_t count, @@ -2772,7 +2815,25 @@ hipError_t ihipMemset3D(hipPitchedPtr pitchedDevPtr, int value, hipExtent extent hipError_t hipMemset2D_common(void* dst, size_t pitch, int value, size_t width, size_t height, hipStream_t stream=nullptr) { CHECK_STREAM_CAPTURING(); - return ihipMemset3D({dst, pitch, width, height}, value, {width, height, 1}, stream); + auto sizeBytes = width * height; + if (sizeBytes == 0) { + return hipSuccess; + } + hipError_t status = ihipMemset3D_validate({dst, pitch, width, height}, value, + {width, height, 1}, sizeBytes); + if (status != hipSuccess) { + return status; + } + // This is required to comply with the spec + // spec says hipMemset will be asynchronous when destination memory is device memory + bool isAsync = false; + size_t offset = 0; + amd::Memory* memObj = getMemoryObject(dst, offset); + auto flags = memObj->getMemFlags(); + if (!(flags & (CL_MEM_USE_HOST_PTR | CL_MEM_SVM_ATOMICS | CL_MEM_SVM_FINE_GRAIN_BUFFER))) { + isAsync = true; + } + return ihipMemset3D({dst, pitch, width, height}, value, {width, height, 1}, stream, isAsync); } hipError_t hipMemset2D_spt(void* dst, size_t pitch, int value, size_t width, size_t height) { @@ -2808,7 +2869,24 @@ hipError_t hipMemset2DAsync_spt(void* dst, size_t pitch, int value, hipError_t hipMemset3D_common(hipPitchedPtr pitchedDevPtr, int value, hipExtent extent, hipStream_t stream=nullptr) { CHECK_STREAM_CAPTURING(); - return ihipMemset3D(pitchedDevPtr, value, extent, stream); + auto sizeBytes = extent.width * extent.height * extent.depth; + if (sizeBytes == 0) { + return hipSuccess; + } + hipError_t status = ihipMemset3D_validate(pitchedDevPtr, value, extent, sizeBytes); + if (status != hipSuccess) { + return status; + } + // This is required to comply with the spec + // spec says hipMemset will be asynchronous when destination memory is device memory + bool isAsync = false; + size_t offset = 0; + amd::Memory* memObj = getMemoryObject(pitchedDevPtr.ptr, offset); + auto flags = memObj->getMemFlags(); + if (!(flags & (CL_MEM_USE_HOST_PTR | CL_MEM_SVM_ATOMICS | CL_MEM_SVM_FINE_GRAIN_BUFFER))) { + isAsync = true; + } + return ihipMemset3D(pitchedDevPtr, value, extent, stream, isAsync); } hipError_t hipMemset3D(hipPitchedPtr pitchedDevPtr, int value, hipExtent extent) {