From a9068182f43beffc87c97c1494880214a13f4d38 Mon Sep 17 00:00:00 2001 From: "Sang, Tao" Date: Thu, 24 Apr 2025 17:15:25 -0400 Subject: [PATCH] SWDEV-493275 - Support scratch limit (#20) Support programmatic query and change of scratch limit on AMD devices. Change-Id: Id5da355a77366f97868e462847f3916e87fd2af6 [ROCm/clr commit: 1113eff3f9f9140c776829e1137cc3543febd25c] --- .../clr/hipamd/src/hip_device_runtime.cpp | 14 ++++++++ projects/clr/rocclr/device/device.hpp | 9 ++++++ projects/clr/rocclr/device/rocm/rocdevice.cpp | 32 +++++++++++++++++++ projects/clr/rocclr/device/rocm/rocdevice.hpp | 3 +- 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/projects/clr/hipamd/src/hip_device_runtime.cpp b/projects/clr/hipamd/src/hip_device_runtime.cpp index a735dd059e..024807d3a2 100644 --- a/projects/clr/hipamd/src/hip_device_runtime.cpp +++ b/projects/clr/hipamd/src/hip_device_runtime.cpp @@ -519,6 +519,15 @@ hipError_t hipDeviceGetLimit(size_t* pValue, hipLimit_t limit) { case hipLimitStackSize: *pValue = hip::getCurrentDevice()->devices()[0]->StackSize(); break; + case hipExtLimitScratchMin: + *pValue = hip::getCurrentDevice()->devices()[0]->info().scratchLimitMin; + break; + case hipExtLimitScratchMax: + *pValue = hip::getCurrentDevice()->devices()[0]->info().scratchLimitMax;; + break; + case hipExtLimitScratchCurrent: + *pValue = hip::getCurrentDevice()->devices()[0]->ScratchLimitCurrent(); + break; default: LogPrintfError("UnsupportedLimit = %d is passed", limit); HIP_RETURN(hipErrorUnsupportedLimit); @@ -601,6 +610,11 @@ hipError_t hipDeviceSetLimit(hipLimit_t limit, size_t value) { HIP_RETURN(hipErrorInvalidValue); } break; + case hipExtLimitScratchCurrent: + if (!hip::getCurrentDevice()->devices()[0]->UpdateScratchLimitCurrent(value)) { + HIP_RETURN(hipErrorInvalidValue); + } + break; default: LogPrintfError("UnsupportedLimit = %d is passed", limit); HIP_RETURN(hipErrorUnsupportedLimit); diff --git a/projects/clr/rocclr/device/device.hpp b/projects/clr/rocclr/device/device.hpp index 56566728ac..70714735d5 100644 --- a/projects/clr/rocclr/device/device.hpp +++ b/projects/clr/rocclr/device/device.hpp @@ -658,6 +658,9 @@ struct Info : public amd::EmbeddedObject { uint32_t luidLowPart_; //!< Luid low 4 bytes, available in Windows only uint32_t luidHighPart_; //!< Luid high 4 bytes, available in Windows only uint32_t luidDeviceNodeMask_; //!< Luid node mask + + size_t scratchLimitMin; //! Minimum size of scratch limit of this device memory in bytes. + size_t scratchLimitMax; //! Maximum size of scratch limit of this device memory in bytes. }; //! Device settings @@ -1976,6 +1979,12 @@ class Device : public RuntimeObject { return false; } + //! Returns current scratch limit of the device. Valid only on rocm device. + virtual size_t ScratchLimitCurrent() const { return 0; } + + //! Sets the current scratch limit of the device. Valid only on rocm device. + virtual bool UpdateScratchLimitCurrent(size_t limit) const { return true; } + //! Validate kernel virtual bool validateKernel(const amd::Kernel& kernel, const device::VirtualDevice* vdev, diff --git a/projects/clr/rocclr/device/rocm/rocdevice.cpp b/projects/clr/rocclr/device/rocm/rocdevice.cpp index d2cec2afcf..66c652c7fc 100644 --- a/projects/clr/rocclr/device/rocm/rocdevice.cpp +++ b/projects/clr/rocclr/device/rocm/rocdevice.cpp @@ -1156,6 +1156,16 @@ bool Device::populateOCLDeviceConstants() { return false; } + uint64_t scratchLimitMax = 0; + if (HSA_STATUS_SUCCESS != + hsa_agent_get_info(bkendDevice_, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_SCRATCH_LIMIT_MAX , + &scratchLimitMax)) { + LogWarning("HSA_AMD_AGENT_INFO_SCRATCH_LIMIT_MAX cannot be queried!"); + return false; + } + info_.scratchLimitMin = 0; + info_.scratchLimitMax = scratchLimitMax; + checkAtomicSupport(); assert(system_segment_.handle != 0); @@ -2749,6 +2759,28 @@ bool Device::GetSvmAttributes(void** data, size_t* data_sizes, int* attributes, return true; } +size_t Device::ScratchLimitCurrent() const { + uint64_t scratchLimitCurrent = 0; + hsa_status_t ret = hsa_agent_get_info(bkendDevice_, + (hsa_agent_info_t)HSA_AMD_AGENT_INFO_SCRATCH_LIMIT_CURRENT, &scratchLimitCurrent); + if (HSA_STATUS_SUCCESS != ret) { + LogPrintfError("HSA_AMD_AGENT_INFO_SCRATCH_LIMIT_CURRENT cannot be queried! Err: 0x%xh", + ret); + return 0; + } + return static_cast(scratchLimitCurrent); +}; + +bool Device::UpdateScratchLimitCurrent(size_t limit) const { + hsa_status_t ret = hsa_amd_agent_set_async_scratch_limit(bkendDevice_, limit); + if (HSA_STATUS_SUCCESS != ret) { + LogPrintfError("hsa_amd_agent_set_async_scratch_limit(%zu) failed with err 0x%xh", + limit, ret); + return false; + } + return true; +}; + // ================================================================================================ bool Device::SvmAllocInit(void* memory, size_t size) const { amd::MemoryAdvice advice = amd::MemoryAdvice::SetAccessedBy; diff --git a/projects/clr/rocclr/device/rocm/rocdevice.hpp b/projects/clr/rocclr/device/rocm/rocdevice.hpp index d74600f614..471cc5d8cc 100644 --- a/projects/clr/rocclr/device/rocm/rocdevice.hpp +++ b/projects/clr/rocclr/device/rocm/rocdevice.hpp @@ -431,7 +431,8 @@ class Device : public NullDevice { amd::MemoryAdvice advice, bool use_cpu = false) const; virtual bool GetSvmAttributes(void** data, size_t* data_sizes, int* attributes, size_t num_attributes, const void* dev_ptr, size_t count) const; - + virtual size_t ScratchLimitCurrent() const final; + virtual bool UpdateScratchLimitCurrent(size_t limit) const final; virtual void* virtualAlloc(void* req_addr, size_t size, size_t alignment); virtual bool virtualFree(void* addr);