From a1c30318fb5dc0ef856314bd573eb71f4770ae39 Mon Sep 17 00:00:00 2001 From: Ioannis Assiouras <38722728+iassiour@users.noreply.github.com> Date: Tue, 2 Sep 2025 15:05:18 +0100 Subject: [PATCH] SWDEV-546223 - Get image support info from ISA meta (#773) --- projects/clr/rocclr/device/device.cpp | 58 ------------ projects/clr/rocclr/device/device.hpp | 34 ++----- projects/clr/rocclr/device/devkernel.cpp | 35 ++++++- projects/clr/rocclr/device/pal/paldevice.cpp | 4 +- .../clr/rocclr/device/pal/palsettings.cpp | 14 ++- .../clr/rocclr/device/pal/palsettings.hpp | 2 +- projects/clr/rocclr/device/rocm/rocdevice.cpp | 91 ++++++------------- projects/clr/rocclr/device/rocm/rockernel.cpp | 4 +- 8 files changed, 83 insertions(+), 159 deletions(-) diff --git a/projects/clr/rocclr/device/device.cpp b/projects/clr/rocclr/device/device.cpp index bcd5c5d458..6beb967129 100644 --- a/projects/clr/rocclr/device/device.cpp +++ b/projects/clr/rocclr/device/device.cpp @@ -79,9 +79,6 @@ extern const char* BlitImageSourceCode; bool VirtualDevice::ActiveWait() const { return device_().ActiveWait(); } -#if defined(USE_COMGR_LIBRARY) -extern amd_comgr_status_t getMetaBuf(const amd_comgr_metadata_node_t meta, std::string* str); -#endif } // namespace amd::device static_assert(static_cast(device::Memory::MemAccess::kMemAccessNone) == @@ -350,61 +347,6 @@ const Isa* Isa::begin() { return supportedIsas().first; } const Isa* Isa::end() { return supportedIsas().second; } -#if defined(USE_COMGR_LIBRARY) -void Isa::setAvailableSgprVgprCached() const { - std::call_once(setSgprVgprFlag, [this]() { - std::string buf; - amd_comgr_metadata_node_t isaMeta; - amd_comgr_metadata_node_t sgprMeta; - amd_comgr_metadata_node_t vgprMeta; - bool hasIsaMeta = false; - bool hasSgprMeta = false; - bool hasVgprMeta = false; - - amd_comgr_status_t status = amd::Comgr::get_isa_metadata(isaName().c_str(), &isaMeta); - - if (status == AMD_COMGR_STATUS_SUCCESS) { - hasIsaMeta = true; - status = amd::Comgr::metadata_lookup(isaMeta, "AddressableNumSGPRs", &sgprMeta); - } - - if (status == AMD_COMGR_STATUS_SUCCESS) { - hasSgprMeta = true; - status = amd::device::getMetaBuf(sgprMeta, &buf); - } - - sgprPerWavefront_ = (status == AMD_COMGR_STATUS_SUCCESS) ? atoi(buf.c_str()) : 0; - - if (status == AMD_COMGR_STATUS_SUCCESS) { - status = amd::Comgr::metadata_lookup(isaMeta, "AddressableNumVGPRs", &vgprMeta); - } - - if (status == AMD_COMGR_STATUS_SUCCESS) { - hasVgprMeta = true; - status = amd::device::getMetaBuf(vgprMeta, &buf); - } - - vgprPerWavefront_ = (status == AMD_COMGR_STATUS_SUCCESS) ? atoi(buf.c_str()) : 0; - - if (hasVgprMeta) { - amd::Comgr::destroy_metadata(vgprMeta); - } - - if (hasSgprMeta) { - amd::Comgr::destroy_metadata(sgprMeta); - } - - if (hasIsaMeta) { - amd::Comgr::destroy_metadata(isaMeta); - } - - if (status != AMD_COMGR_STATUS_SUCCESS) { - DevLogPrintfError("Failed to set SGPR/VGPR for ISA: %s", isaName().c_str()); - } - }); -} -#endif - std::vector* Device::devices_ = nullptr; AppProfile Device::appProfile_; diff --git a/projects/clr/rocclr/device/device.hpp b/projects/clr/rocclr/device/device.hpp index e0337659b0..1b7bcd41d2 100644 --- a/projects/clr/rocclr/device/device.hpp +++ b/projects/clr/rocclr/device/device.hpp @@ -1376,6 +1376,10 @@ class VirtualDevice : public amd::HeapObject { mutable std::atomic queued_async_handlers_ = 0; //!< Outstanding HSA async handlers }; +#if defined(USE_COMGR_LIBRARY) +extern bool getValueFromIsaMeta(const std::string& isa, const char* key, std::string& retValue); +#endif + } // namespace amd::device namespace amd { @@ -1535,20 +1539,6 @@ class Isa { /// @returns This Isa's number of banks of local memory. uint32_t localMemBanks() const { return localMemBanks_; } -#if defined(USE_COMGR_LIBRARY) - /// @returns This Isa's available sgprs per wavefront - size_t sgprPerWavefront() const { - setAvailableSgprVgprCached(); - return sgprPerWavefront_; - } - - /// @returns This Isa's available vgprs per wavefront - size_t vgprPerWavefront() const { - setAvailableSgprVgprCached(); - return vgprPerWavefront_; - } -#endif - /// @returns True if @p codeObjectIsa and @p agentIsa are compatible, /// false otherwise. static bool isCompatible(const Isa& codeObjectIsa, const Isa& agentIsa); @@ -1586,19 +1576,11 @@ class Isa { simdInstructionWidth_(simdInstructionWidth), memChannelBankWidth_(memChannelBankWidth), localMemSizePerCU_(localMemSizePerCU), - localMemBanks_(localMemBanks), - sgprPerWavefront_(0), - vgprPerWavefront_(0) {} + localMemBanks_(localMemBanks) {} // @brief Returns the begin and end iterators for the suppported ISAs. static std::pair supportedIsas(); -#if defined(USE_COMGR_LIBRARY) - // @brief Populate this Isa's available sgprs/vgprs per wavefront from comgr. - // Only called once per Isa. - void setAvailableSgprVgprCached() const; -#endif - // @brief Isa's target ID name. Used for LLVM COde Object Manager // compilations. const char* targetId_; @@ -1621,11 +1603,7 @@ class Isa { uint32_t memChannelBankWidth_; //!< Memory channel bank width. uint32_t localMemSizePerCU_; //!< Local memory size per CU. uint32_t localMemBanks_; //!< Number of banks of local memory. - - mutable size_t sgprPerWavefront_; //!< Number of sgpr per wavefront. - mutable size_t vgprPerWavefront_; //!< Number of vgpr per wavefront. - mutable std::once_flag setSgprVgprFlag; //!< Once flag for sgpr and vgpr retrieval. -}; // class Isa +}; // class Isa /*! \addtogroup Runtime * @{ diff --git a/projects/clr/rocclr/device/devkernel.cpp b/projects/clr/rocclr/device/devkernel.cpp index a1fc797e90..e5164f246b 100644 --- a/projects/clr/rocclr/device/devkernel.cpp +++ b/projects/clr/rocclr/device/devkernel.cpp @@ -52,19 +52,50 @@ static constexpr clk_value_type_t ClkValueMapType[6][6] = { }; #if defined(USE_COMGR_LIBRARY) + // ================================================================================================ -amd_comgr_status_t getMetaBuf(const amd_comgr_metadata_node_t meta, std::string* str) { +amd_comgr_status_t getMetaBuf(const amd_comgr_metadata_node_t meta, + std::string* str) { size_t size = 0; amd_comgr_status_t status = amd::Comgr::get_metadata_string(meta, &size, NULL); if (status == AMD_COMGR_STATUS_SUCCESS) { - str->resize(size - 1); // minus one to discount the null character + str->resize(size-1); // minus one to discount the null character status = amd::Comgr::get_metadata_string(meta, &size, &((*str)[0])); } return status; } +// ================================================================================================ +bool getValueFromIsaMeta(const std::string& isa, const char* key, std::string& retValue) { + amd_comgr_metadata_node_t isaMeta; + + amd_comgr_status_t status = amd::Comgr::get_isa_metadata(isa.c_str(), &isaMeta); + + if (status != AMD_COMGR_STATUS_SUCCESS) { + ClPrint(amd::LOG_ERROR, amd::LOG_INIT, "getIsaMeta(%s) failed!", isa.c_str()); + return false; + } + + amd_comgr_metadata_node_t valMeta; + size_t size = 0; + status = amd::Comgr::metadata_lookup(isaMeta, key, &valMeta); + if (status == AMD_COMGR_STATUS_SUCCESS) { + status = amd::Comgr::get_metadata_string(valMeta, &size, NULL); + } + if (status == AMD_COMGR_STATUS_SUCCESS) { + retValue.resize(size - 1); + status = amd::Comgr::get_metadata_string(valMeta, &size, &(retValue[0])); + } + + if (status == AMD_COMGR_STATUS_SUCCESS) { + status = amd::Comgr::destroy_metadata(valMeta); + } + amd::Comgr::destroy_metadata(isaMeta); + return (status == AMD_COMGR_STATUS_SUCCESS) ? true : false; +} + // ================================================================================================ static amd_comgr_status_t populateArgs(const amd_comgr_metadata_node_t key, const amd_comgr_metadata_node_t value, void* data) { diff --git a/projects/clr/rocclr/device/pal/paldevice.cpp b/projects/clr/rocclr/device/pal/paldevice.cpp index 327b765a42..dcf58d531c 100644 --- a/projects/clr/rocclr/device/pal/paldevice.cpp +++ b/projects/clr/rocclr/device/pal/paldevice.cpp @@ -256,7 +256,7 @@ bool NullDevice::create(const char* palName, const amd::Isa& isa, Pal::GfxIpLeve // Create setting for the offline target if ((palSettings == nullptr) || - !palSettings->create(properties, heaps, wscaps, isa.xnack() == amd::Isa::Feature::Enabled)) { + !palSettings->create(properties, heaps, wscaps, isa)) { LogPrintfError("Unable to create PAL setting for offline PAL device %s", isa.targetId()); return false; } @@ -1005,7 +1005,7 @@ bool Device::create(Pal::IDevice* device) { pal::Settings* gpuSettings = reinterpret_cast(settings_); if (!gpuSettings || - !gpuSettings->create(properties(), heaps_, wscaps, isa->xnack() == amd::Isa::Feature::Enabled, + !gpuSettings->create(properties(), heaps_, wscaps, *isa, appProfile_.reportAsOCL12Device())) { return false; } diff --git a/projects/clr/rocclr/device/pal/palsettings.cpp b/projects/clr/rocclr/device/pal/palsettings.cpp index 6e8593d343..33e3ef97d4 100644 --- a/projects/clr/rocclr/device/pal/palsettings.cpp +++ b/projects/clr/rocclr/device/pal/palsettings.cpp @@ -140,7 +140,7 @@ Settings::Settings() { bool Settings::create(const Pal::DeviceProperties& palProp, const Pal::GpuMemoryHeapProperties* heaps, const Pal::WorkStationCaps& wscaps, - bool enableXNACK, bool reportAsOCL12Device) { + const amd::Isa& isa, bool reportAsOCL12Device) { uint32_t osVer = 0x0; // Disable thread trace by default for all devices @@ -151,8 +151,8 @@ bool Settings::create(const Pal::DeviceProperties& palProp, apuSystem_ = true; } - enableXNACK_ = enableXNACK; - hsailExplicitXnack_ = enableXNACK; + enableXNACK_ = (isa.xnack() == amd::Isa::Feature::Enabled); + hsailExplicitXnack_ = enableXNACK_; bool useWavefront64 = false; std::string appName = {}; @@ -292,7 +292,13 @@ bool Settings::create(const Pal::DeviceProperties& palProp, } imageSupport_ = true; - + std::string imageSupport; + if (amd::device::getValueFromIsaMeta(isa.isaName(), "ImageSupport", imageSupport)) { + imageSupport_ = atoi(imageSupport.c_str()); + ClPrint(amd::LOG_INFO, amd::LOG_INIT, "imageSupport=%u", imageSupport_); + } else { + LogInfo("Can not get image support info from ISA meta"); + } // Use kernels for blit if appropriate blitEngine_ = BlitEngineKernel; diff --git a/projects/clr/rocclr/device/pal/palsettings.hpp b/projects/clr/rocclr/device/pal/palsettings.hpp index 21910aad41..7e94a28aba 100644 --- a/projects/clr/rocclr/device/pal/palsettings.hpp +++ b/projects/clr/rocclr/device/pal/palsettings.hpp @@ -120,7 +120,7 @@ class Settings : public device::Settings { bool create(const Pal::DeviceProperties& palProp, //!< PAL device properties const Pal::GpuMemoryHeapProperties* heaps, //!< PAL heap settings const Pal::WorkStationCaps& wscaps, //!< PAL workstation settings - bool enableXNACK, //!< XNACK is enabled on this device + const amd::Isa& isa, //!< XNACK is enabled on this device bool reportAsOCL12Device = false //!< Report As OpenCL1.2 Device ); diff --git a/projects/clr/rocclr/device/rocm/rocdevice.cpp b/projects/clr/rocclr/device/rocm/rocdevice.cpp index 77e6847359..c541b3c2d3 100644 --- a/projects/clr/rocclr/device/rocm/rocdevice.cpp +++ b/projects/clr/rocclr/device/rocm/rocdevice.cpp @@ -80,41 +80,6 @@ static_assert(static_cast(amd::Device::VmmAccess::kReadWrite) == #ifndef WITHOUT_HSA_BACKEND -namespace { - -inline bool getIsaMeta(std::string isaName, amd_comgr_metadata_node_t& isaMeta) { - amd_comgr_status_t status; - status = amd::Comgr::get_isa_metadata(isaName.c_str(), &isaMeta); - return (status == AMD_COMGR_STATUS_SUCCESS) ? true : false; -} - -inline bool releaseIsaMeta(amd_comgr_metadata_node_t& isaMeta) { - return AMD_COMGR_STATUS_SUCCESS == amd::Comgr::destroy_metadata(isaMeta); -} - -bool getValueFromIsaMeta(amd_comgr_metadata_node_t& isaMeta, const char* key, - std::string& retValue) { - amd_comgr_status_t status; - amd_comgr_metadata_node_t valMeta; - size_t size = 0; - - status = amd::Comgr::metadata_lookup(isaMeta, key, &valMeta); - if (status == AMD_COMGR_STATUS_SUCCESS) { - status = amd::Comgr::get_metadata_string(valMeta, &size, NULL); - } - if (status == AMD_COMGR_STATUS_SUCCESS) { - retValue.resize(size - 1); - status = amd::Comgr::get_metadata_string(valMeta, &size, &(retValue[0])); - } - if (status == AMD_COMGR_STATUS_SUCCESS) { - status = amd::Comgr::destroy_metadata(valMeta); - } - - return (status == AMD_COMGR_STATUS_SUCCESS) ? true : false; -} - -} // namespace - namespace amd::device { extern const char* HipExtraSourceCode; extern const char* HipExtraSourceCodeNoGWS; @@ -1621,36 +1586,38 @@ bool Device::populateOCLDeviceConstants() { info_.maxOnDeviceQueues_ = 1; info_.maxOnDeviceEvents_ = settings().numDeviceEvents_; - // Get Values from from Comgr - amd_comgr_metadata_node_t isaMeta; - if (getIsaMeta(std::move(isa().isaName()), isaMeta)) { - std::string addressableNumVGPRs, totalNumVGPRs, vGPRAllocGranule; - info_.availableVGPRs_ = getValueFromIsaMeta(isaMeta, "AddressableNumVGPRs", addressableNumVGPRs) - ? atoi(addressableNumVGPRs.c_str()) - : 0; - info_.vgprsPerSimd_ = getValueFromIsaMeta(isaMeta, "TotalNumVGPRs", totalNumVGPRs) - ? atoi(totalNumVGPRs.c_str()) - : 0; - info_.vgprAllocGranularity_ = getValueFromIsaMeta(isaMeta, "VGPRAllocGranule", vGPRAllocGranule) - ? atoi(vGPRAllocGranule.c_str()) - : 0; + std::string addressableNumVGPRs, totalNumVGPRs, vGPRAllocGranule; + std::string isaName = isa().isaName(); + info_.availableVGPRs_ = + amd::device::getValueFromIsaMeta(isaName, "AddressableNumVGPRs", addressableNumVGPRs) + ? atoi(addressableNumVGPRs.c_str()) + : 0; + info_.vgprsPerSimd_ = amd::device::getValueFromIsaMeta(isaName, "TotalNumVGPRs", totalNumVGPRs) + ? atoi(totalNumVGPRs.c_str()) + : 0; + info_.vgprAllocGranularity_ = + amd::device::getValueFromIsaMeta(isaName, "VGPRAllocGranule", vGPRAllocGranule) + ? atoi(vGPRAllocGranule.c_str()) + : 0; - info_.availableRegistersPerCU_ = info_.vgprsPerSimd_ * info_.simdPerCU_ * info_.wavefrontWidth_; - ClPrint(amd::LOG_INFO, amd::LOG_INIT, - "addressableNumVGPRs=%u, totalNumVGPRs=%u, vGPRAllocGranule=%u," - " availableRegistersPerCU_=%u", - info_.availableVGPRs_, info_.vgprsPerSimd_, info_.vgprAllocGranularity_, - info_.availableRegistersPerCU_); + info_.availableRegistersPerCU_ = info_.vgprsPerSimd_ * info_.simdPerCU_ * info_.wavefrontWidth_; + ClPrint(amd::LOG_INFO, amd::LOG_INIT, + "addressableNumVGPRs=%u, totalNumVGPRs=%u, vGPRAllocGranule=%u," + " availableRegistersPerCU_=%u", + info_.availableVGPRs_, info_.vgprsPerSimd_, info_.vgprAllocGranularity_, + info_.availableRegistersPerCU_); - std::string sgprValue; - info_.availableSGPRs_ = (getValueFromIsaMeta(isaMeta, "AddressableNumSGPRs", sgprValue)) - ? (atoi(sgprValue.c_str())) - : 0; - if (!releaseIsaMeta(isaMeta)) { - LogInfo("Can not release the isa meta node"); - } + std::string sgprValue; + info_.availableSGPRs_ = + (amd::device::getValueFromIsaMeta(isaName, "AddressableNumSGPRs", sgprValue)) + ? (atoi(sgprValue.c_str())) + : 0; + std::string imageSupport; + if (amd::device::getValueFromIsaMeta(isaName, "ImageSupport", imageSupport)) { + info_.imageSupport_ = atoi(imageSupport.c_str()); + ClPrint(amd::LOG_INFO, amd::LOG_INIT, "imageSupport=%u", info_.imageSupport_); } else { - ClPrint(amd::LOG_ERROR, amd::LOG_INIT, "getIsaMeta(%s) failed!", isa().isaName().c_str()); + LogInfo("Can not get image support info from ISA meta"); } // Generic support for HMM interfaces diff --git a/projects/clr/rocclr/device/rocm/rockernel.cpp b/projects/clr/rocclr/device/rocm/rockernel.cpp index 61ab1160d3..611861e00b 100644 --- a/projects/clr/rocclr/device/rocm/rockernel.cpp +++ b/projects/clr/rocclr/device/rocm/rockernel.cpp @@ -131,8 +131,8 @@ bool Kernel::postLoad() { } assert(wavefront_size > 0); - workGroupInfo_.availableVGPRs_ = device().isa().vgprPerWavefront(); - workGroupInfo_.availableSGPRs_ = device().isa().sgprPerWavefront(); + workGroupInfo_.availableVGPRs_ = device().info().vgprsPerSimd_; + workGroupInfo_.availableSGPRs_ = device().info().availableSGPRs_; workGroupInfo_.privateMemSize_ = workitemPrivateSegmentByteSize_; workGroupInfo_.localMemSize_ = workgroupGroupSegmentByteSize_; workGroupInfo_.usedLDSSize_ = workgroupGroupSegmentByteSize_;