diff --git a/rocclr/device/device.cpp b/rocclr/device/device.cpp index f1419cc266..99334e53f6 100644 --- a/rocclr/device/device.cpp +++ b/rocclr/device/device.cpp @@ -81,6 +81,9 @@ 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 } static_assert(static_cast(device::Memory::MemAccess::kMemAccessNone) @@ -328,6 +331,61 @@ 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/rocclr/device/device.hpp b/rocclr/device/device.hpp index 4ecbd04e56..534c3a602f 100644 --- a/rocclr/device/device.hpp +++ b/rocclr/device/device.hpp @@ -1565,6 +1565,20 @@ class Isa { 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); @@ -1604,11 +1618,19 @@ class Isa { simdInstructionWidth_(simdInstructionWidth), memChannelBankWidth_(memChannelBankWidth), localMemSizePerCU_(localMemSizePerCU), - localMemBanks_(localMemBanks) {} + localMemBanks_(localMemBanks), + sgprPerWavefront_(0), + vgprPerWavefront_(0) {} // @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_; @@ -1631,6 +1653,10 @@ 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 /*! \addtogroup Runtime diff --git a/rocclr/device/devkernel.cpp b/rocclr/device/devkernel.cpp index 3cb121a544..0ed892f19a 100644 --- a/rocclr/device/devkernel.cpp +++ b/rocclr/device/devkernel.cpp @@ -1155,56 +1155,6 @@ bool Kernel::GetAttrCodePropMetadata() { return true; } -bool Kernel::SetAvailableSgprVgpr() { - 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( - prog().device().isa().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 = getMetaBuf(sgprMeta, &buf); - } - - workGroupInfo_.availableSGPRs_ = (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 = getMetaBuf(vgprMeta, &buf); - } - workGroupInfo_.availableVGPRs_ = (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); - } - - return (status == AMD_COMGR_STATUS_SUCCESS); -} - bool Kernel::GetPrintfStr(std::vector* printfStr) { const amd_comgr_metadata_node_t programMD = prog().metadata(); amd_comgr_metadata_node_t printfMeta; diff --git a/rocclr/device/devkernel.hpp b/rocclr/device/devkernel.hpp index eca2963a17..7872bff146 100644 --- a/rocclr/device/devkernel.hpp +++ b/rocclr/device/devkernel.hpp @@ -367,9 +367,6 @@ class Kernel : public amd::HeapObject { //! Retrieve kernel attribute and code properties metadata bool GetAttrCodePropMetadata(); - //! Retrieve the available SGPRs and VGPRs - bool SetAvailableSgprVgpr(); - //! Retrieve the printf string metadata bool GetPrintfStr(std::vector* printfStr); diff --git a/rocclr/device/rocm/rockernel.cpp b/rocclr/device/rocm/rockernel.cpp index 8083467cf7..8151cc5187 100644 --- a/rocclr/device/rocm/rockernel.cpp +++ b/rocclr/device/rocm/rockernel.cpp @@ -47,11 +47,6 @@ bool Kernel::postLoad() { workGroupInfo_.availableLDSSize_ = device().info().localMemSizePerCU_; assert(workGroupInfo_.availableLDSSize_ > 0); - if (!SetAvailableSgprVgpr()) { - DevLogError("Cannot set available SGPR/VGPR\n"); - return false; - } - // Get the kernel code handle hsa_status_t hsaStatus; hsa_executable_symbol_t symbol; @@ -145,6 +140,8 @@ bool Kernel::postLoad() { } assert(wavefront_size > 0); + workGroupInfo_.availableVGPRs_ = device().isa().vgprPerWavefront(); + workGroupInfo_.availableSGPRs_ = device().isa().sgprPerWavefront(); workGroupInfo_.privateMemSize_ = workitemPrivateSegmentByteSize_; workGroupInfo_.localMemSize_ = workgroupGroupSegmentByteSize_; workGroupInfo_.usedLDSSize_ = workgroupGroupSegmentByteSize_;