From 4915496bf98a8eac451015dafc434998791a5d59 Mon Sep 17 00:00:00 2001 From: dsicarov-amd Date: Wed, 29 Oct 2025 10:58:42 +0100 Subject: [PATCH] SWDEV-533237 Add hipOccupancyAvailableDynamicSMemPerBlock API (#899) * SWDEV-533237 Add initial support for hipOccupancyAvailableDynamicSMemPerBlock API * SWDEV-533237 Add hipOccupancyAvailableDynamicSMemPerBlock wrapper for nvidia * SWDEV-533237 Add implementation of hipOccupancyAvailableDynamicSMemPerBlock API * SWDEV-533237 Add LDSAlignment field in Isa table --------- Co-authored-by: Rahul Manocha --- projects/clr/CHANGELOG.md | 1 + .../include/hip/amd_detail/hip_api_trace.hpp | 9 +- .../include/hip/amd_detail/hip_prof_str.h | 32 ++- projects/clr/hipamd/src/amdhip.def | 1 + projects/clr/hipamd/src/hip_api_trace.cpp | 9 +- projects/clr/hipamd/src/hip_hcc.map.in | 3 +- projects/clr/hipamd/src/hip_platform.cpp | 45 ++++ projects/clr/hipamd/src/hip_prof_gen.py | 1 + .../clr/hipamd/src/hip_table_interface.cpp | 6 + projects/clr/rocclr/device/device.cpp | 234 +++++++++--------- projects/clr/rocclr/device/device.hpp | 11 +- projects/hip/include/hip/hip_runtime_api.h | 39 +++ .../nvidia_detail/nvidia_hip_runtime_api.h | 13 + 13 files changed, 279 insertions(+), 125 deletions(-) diff --git a/projects/clr/CHANGELOG.md b/projects/clr/CHANGELOG.md index 43e0ce92db..4ec2ca1663 100644 --- a/projects/clr/CHANGELOG.md +++ b/projects/clr/CHANGELOG.md @@ -16,6 +16,7 @@ Full documentation for HIP is available at [rocm.docs.amd.com](https://rocm.docs - `hipLibraryGetKernel` gets a kernel from library - `hipLibraryGetKernelCount` gets kernel count in library - `hipStreamCopyAttributes` copies attributes from source stream to destination stream + - `hipOccupancyAvailableDynamicSMemPerBlock` Returns dynamic shared memory available per block when launching numBlocks blocks on CU. ## HIP 7.1 for ROCm 7.1 diff --git a/projects/clr/hipamd/include/hip/amd_detail/hip_api_trace.hpp b/projects/clr/hipamd/include/hip/amd_detail/hip_api_trace.hpp index 758267a6cc..80209d7a9c 100644 --- a/projects/clr/hipamd/include/hip/amd_detail/hip_api_trace.hpp +++ b/projects/clr/hipamd/include/hip/amd_detail/hip_api_trace.hpp @@ -63,7 +63,7 @@ #define HIP_API_TABLE_STEP_VERSION 0 #define HIP_COMPILER_API_TABLE_STEP_VERSION 0 #define HIP_TOOLS_API_TABLE_STEP_VERSION 0 -#define HIP_RUNTIME_API_TABLE_STEP_VERSION 17 +#define HIP_RUNTIME_API_TABLE_STEP_VERSION 18 // HIP API interface // HIP compiler dispatch functions @@ -685,6 +685,8 @@ typedef hipError_t (*t_hipModuleOccupancyMaxPotentialBlockSizeWithFlags)( int* gridSize, int* blockSize, hipFunction_t f, size_t dynSharedMemPerBlk, int blockSizeLimit, unsigned int flags); typedef hipError_t (*t_hipModuleUnload)(hipModule_t module); +typedef hipError_t (*t_hipOccupancyAvailableDynamicSMemPerBlock)(size_t* dynamicSmemSize, const void* f, + int numBlocks, int blockSize); typedef hipError_t (*t_hipOccupancyMaxActiveBlocksPerMultiprocessor)(int* numBlocks, const void* f, int blockSize, size_t dynSharedMemPerBlk); @@ -1691,9 +1693,12 @@ struct HipDispatchTable { t_hipLibraryEnumerateKernels hipLibraryEnumerateKernels_fn; t_hipKernelGetLibrary hipKernelGetLibrary_fn; t_hipKernelGetName hipKernelGetName_fn; + + // HIP_RUNTIME_API_TABLE_STEP_VERSION == 18 + t_hipOccupancyAvailableDynamicSMemPerBlock hipOccupancyAvailableDynamicSMemPerBlock_fn; // DO NOT EDIT ABOVE! - // HIP_RUNTIME_API_TABLE_STEP_VERSION == 18 + // HIP_RUNTIME_API_TABLE_STEP_VERSION == 19 // ******************************************************************************************* // // diff --git a/projects/clr/hipamd/include/hip/amd_detail/hip_prof_str.h b/projects/clr/hipamd/include/hip/amd_detail/hip_prof_str.h index 19bb4f138a..8d2c6c02ba 100644 --- a/projects/clr/hipamd/include/hip/amd_detail/hip_prof_str.h +++ b/projects/clr/hipamd/include/hip/amd_detail/hip_prof_str.h @@ -466,7 +466,8 @@ enum hip_api_id_t { HIP_API_ID_hipKernelGetLibrary = 446, HIP_API_ID_hipLibraryEnumerateKernels = 447, HIP_API_ID_hipKernelGetName = 448, - HIP_API_ID_LAST = 448, + HIP_API_ID_hipOccupancyAvailableDynamicSMemPerBlock = 449, + HIP_API_ID_LAST = 449, HIP_API_ID_hipChooseDevice = HIP_API_ID_CONCAT(HIP_API_ID_,hipChooseDevice), HIP_API_ID_hipGetDeviceProperties = HIP_API_ID_CONCAT(HIP_API_ID_,hipGetDeviceProperties), @@ -872,6 +873,7 @@ static inline const char* hip_api_name(const uint32_t id) { case HIP_API_ID_hipModuleOccupancyMaxPotentialBlockSize: return "hipModuleOccupancyMaxPotentialBlockSize"; case HIP_API_ID_hipModuleOccupancyMaxPotentialBlockSizeWithFlags: return "hipModuleOccupancyMaxPotentialBlockSizeWithFlags"; case HIP_API_ID_hipModuleUnload: return "hipModuleUnload"; + case HIP_API_ID_hipOccupancyAvailableDynamicSMemPerBlock: return "hipOccupancyAvailableDynamicSMemPerBlock"; case HIP_API_ID_hipOccupancyMaxActiveBlocksPerMultiprocessor: return "hipOccupancyMaxActiveBlocksPerMultiprocessor"; case HIP_API_ID_hipOccupancyMaxActiveBlocksPerMultiprocessorWithFlags: return "hipOccupancyMaxActiveBlocksPerMultiprocessorWithFlags"; case HIP_API_ID_hipOccupancyMaxPotentialBlockSize: return "hipOccupancyMaxPotentialBlockSize"; @@ -1314,6 +1316,7 @@ static inline uint32_t hipApiIdByName(const char* name) { if (strcmp("hipModuleOccupancyMaxPotentialBlockSize", name) == 0) return HIP_API_ID_hipModuleOccupancyMaxPotentialBlockSize; if (strcmp("hipModuleOccupancyMaxPotentialBlockSizeWithFlags", name) == 0) return HIP_API_ID_hipModuleOccupancyMaxPotentialBlockSizeWithFlags; if (strcmp("hipModuleUnload", name) == 0) return HIP_API_ID_hipModuleUnload; + if (strcmp("hipOccupancyAvailableDynamicSMemPerBlock", name) == 0) return HIP_API_ID_hipOccupancyAvailableDynamicSMemPerBlock; if (strcmp("hipOccupancyMaxActiveBlocksPerMultiprocessor", name) == 0) return HIP_API_ID_hipOccupancyMaxActiveBlocksPerMultiprocessor; if (strcmp("hipOccupancyMaxActiveBlocksPerMultiprocessorWithFlags", name) == 0) return HIP_API_ID_hipOccupancyMaxActiveBlocksPerMultiprocessorWithFlags; if (strcmp("hipOccupancyMaxPotentialBlockSize", name) == 0) return HIP_API_ID_hipOccupancyMaxPotentialBlockSize; @@ -3659,6 +3662,13 @@ typedef struct hip_api_data_s { struct { hipModule_t module; } hipModuleUnload; + struct { + size_t* dynamicSmemSize; + size_t dynamicSmemSize__val; + const void* f; + int numBlocks; + int blockSize; + } hipOccupancyAvailableDynamicSMemPerBlock; struct { int* numBlocks; int numBlocks__val; @@ -6331,6 +6341,13 @@ typedef struct hip_api_data_s { #define INIT_hipModuleUnload_CB_ARGS_DATA(cb_data) { \ cb_data.args.hipModuleUnload.module = (hipModule_t)hmod; \ }; +// hipOccupancyAvailableDynamicSMemPerBlock[('size_t*', 'dynamicSmemSize'), ('const void*', 'f'), ('int', 'numBlocks'), ('int', 'blockSize')] +#define INIT_hipOccupancyAvailableDynamicSMemPerBlock_CB_ARGS_DATA(cb_data) { \ + cb_data.args.hipOccupancyAvailableDynamicSMemPerBlock.dynamicSmemSize = (size_t*)dynamicSmemSize; \ + cb_data.args.hipOccupancyAvailableDynamicSMemPerBlock.f = (const void*)f; \ + cb_data.args.hipOccupancyAvailableDynamicSMemPerBlock.numBlocks = (int)numBlocks; \ + cb_data.args.hipOccupancyAvailableDynamicSMemPerBlock.blockSize = (int)blockSize; \ +}; // hipOccupancyMaxActiveBlocksPerMultiprocessor[('int*', 'numBlocks'), ('const void*', 'f'), ('int', 'blockSize'), ('size_t', 'dynamicSMemSize')] #define INIT_hipOccupancyMaxActiveBlocksPerMultiprocessor_CB_ARGS_DATA(cb_data) { \ cb_data.args.hipOccupancyMaxActiveBlocksPerMultiprocessor.numBlocks = (int*)numBlocks; \ @@ -8220,6 +8237,10 @@ static inline void hipApiArgsInit(hip_api_id_t id, hip_api_data_t* data) { // hipModuleUnload[('hipModule_t', 'module')] case HIP_API_ID_hipModuleUnload: break; +// hipOccupancyAvailableDynamicSMemPerBlock[('size_t*', 'dynamicSmemSize'), ('const void*', 'f'), ('int', 'numBlocks'), ('int', 'blockSize')] + case HIP_API_ID_hipOccupancyAvailableDynamicSMemPerBlock: + if (data->args.hipOccupancyAvailableDynamicSMemPerBlock.dynamicSmemSize) data->args.hipOccupancyAvailableDynamicSMemPerBlock.dynamicSmemSize__val = *(data->args.hipOccupancyAvailableDynamicSMemPerBlock.dynamicSmemSize); + break; // hipOccupancyMaxActiveBlocksPerMultiprocessor[('int*', 'numBlocks'), ('const void*', 'f'), ('int', 'blockSize'), ('size_t', 'dynamicSMemSize')] case HIP_API_ID_hipOccupancyMaxActiveBlocksPerMultiprocessor: if (data->args.hipOccupancyMaxActiveBlocksPerMultiprocessor.numBlocks) data->args.hipOccupancyMaxActiveBlocksPerMultiprocessor.numBlocks__val = *(data->args.hipOccupancyMaxActiveBlocksPerMultiprocessor.numBlocks); @@ -11516,6 +11537,15 @@ static inline const char* hipApiString(hip_api_id_t id, const hip_api_data_t* da oss << "module="; roctracer::hip_support::detail::operator<<(oss, data->args.hipModuleUnload.module); oss << ")"; break; + case HIP_API_ID_hipOccupancyAvailableDynamicSMemPerBlock: + oss << "hipOccupancyAvailableDynamicSMemPerBlock("; + if (data->args.hipOccupancyAvailableDynamicSMemPerBlock.dynamicSmemSize == NULL) oss << "dynamicSmemSize=NULL"; + else { oss << "dynamicSmemSize="; roctracer::hip_support::detail::operator<<(oss, data->args.hipOccupancyAvailableDynamicSMemPerBlock.dynamicSmemSize__val); } + oss << ", f="; roctracer::hip_support::detail::operator<<(oss, data->args.hipOccupancyAvailableDynamicSMemPerBlock.f); + oss << ", numBlocks="; roctracer::hip_support::detail::operator<<(oss, data->args.hipOccupancyAvailableDynamicSMemPerBlock.numBlocks); + oss << ", blockSize="; roctracer::hip_support::detail::operator<<(oss, data->args.hipOccupancyAvailableDynamicSMemPerBlock.blockSize); + oss << ")"; + break; case HIP_API_ID_hipOccupancyMaxActiveBlocksPerMultiprocessor: oss << "hipOccupancyMaxActiveBlocksPerMultiprocessor("; if (data->args.hipOccupancyMaxActiveBlocksPerMultiprocessor.numBlocks == NULL) oss << "numBlocks=NULL"; diff --git a/projects/clr/hipamd/src/amdhip.def b/projects/clr/hipamd/src/amdhip.def index a0fdb07f01..7407d2d7bd 100644 --- a/projects/clr/hipamd/src/amdhip.def +++ b/projects/clr/hipamd/src/amdhip.def @@ -520,3 +520,4 @@ hipStreamCopyAttributes hipLibraryEnumerateKernels hipKernelGetLibrary hipKernelGetName +hipOccupancyAvailableDynamicSMemPerBlock diff --git a/projects/clr/hipamd/src/hip_api_trace.cpp b/projects/clr/hipamd/src/hip_api_trace.cpp index d29ba82f18..a4d73f364b 100644 --- a/projects/clr/hipamd/src/hip_api_trace.cpp +++ b/projects/clr/hipamd/src/hip_api_trace.cpp @@ -879,6 +879,8 @@ hipError_t hipLibraryEnumerateKernels(hipKernel_t* kernels, unsigned int numKern hipLibrary_t library); hipError_t hipKernelGetLibrary(hipLibrary_t* library, hipKernel_t kernel); hipError_t hipKernelGetName(const char** name, hipKernel_t kernel); +hipError_t hipOccupancyAvailableDynamicSMemPerBlock(size_t* dynamicSmemSize, const void* f, + int numBlocks, int blockSize); } // namespace hip namespace hip { @@ -1423,6 +1425,7 @@ void UpdateDispatchTable(HipDispatchTable* ptrDispatchTable) { ptrDispatchTable->hipLibraryEnumerateKernels_fn = hip::hipLibraryEnumerateKernels; ptrDispatchTable->hipKernelGetLibrary_fn = hip::hipKernelGetLibrary; ptrDispatchTable->hipKernelGetName_fn = hip::hipKernelGetName; + ptrDispatchTable->hipOccupancyAvailableDynamicSMemPerBlock_fn = hip::hipOccupancyAvailableDynamicSMemPerBlock; } #if HIP_ROCPROFILER_REGISTER > 0 @@ -2099,15 +2102,17 @@ HIP_ENFORCE_ABI(HipDispatchTable, hipStreamCopyAttributes_fn, 501); HIP_ENFORCE_ABI(HipDispatchTable, hipLibraryEnumerateKernels_fn, 502); HIP_ENFORCE_ABI(HipDispatchTable, hipKernelGetLibrary_fn, 503); HIP_ENFORCE_ABI(HipDispatchTable, hipKernelGetName_fn, 504); +// HIP_RUNTIME_API_TABLE_STEP_VERSION == 18 +HIP_ENFORCE_ABI(HipDispatchTable, hipOccupancyAvailableDynamicSMemPerBlock_fn, 505); // if HIP_ENFORCE_ABI entries are added for each new function pointer in the table, the number below // will be +1 of the number in the last HIP_ENFORCE_ABI line. E.g.: // // HIP_ENFORCE_ABI(, , 8) // // HIP_ENFORCE_ABI_VERSIONING(
, 9) <- 8 + 1 = 9 -HIP_ENFORCE_ABI_VERSIONING(HipDispatchTable, 505) +HIP_ENFORCE_ABI_VERSIONING(HipDispatchTable, 506) -static_assert(HIP_RUNTIME_API_TABLE_MAJOR_VERSION == 0 && HIP_RUNTIME_API_TABLE_STEP_VERSION == 17, +static_assert(HIP_RUNTIME_API_TABLE_MAJOR_VERSION == 0 && HIP_RUNTIME_API_TABLE_STEP_VERSION == 18, "If you get this error, add new HIP_ENFORCE_ABI(...) code for the new function " "pointers and then update this check so it is true"); #endif diff --git a/projects/clr/hipamd/src/hip_hcc.map.in b/projects/clr/hipamd/src/hip_hcc.map.in index a9e43fdbb4..f26fc61be1 100644 --- a/projects/clr/hipamd/src/hip_hcc.map.in +++ b/projects/clr/hipamd/src/hip_hcc.map.in @@ -642,6 +642,7 @@ global: hipLibraryEnumerateKernels; hipKernelGetLibrary; hipKernelGetName; + hipOccupancyAvailableDynamicSMemPerBlock; local: *; -} hip_7.1; \ No newline at end of file +} hip_7.1; diff --git a/projects/clr/hipamd/src/hip_platform.cpp b/projects/clr/hipamd/src/hip_platform.cpp index 74f3ed36a8..4c0cbc01ee 100644 --- a/projects/clr/hipamd/src/hip_platform.cpp +++ b/projects/clr/hipamd/src/hip_platform.cpp @@ -472,6 +472,51 @@ hipError_t ihipOccupancyMaxActiveBlocksPerMultiprocessor( } // namespace hip_impl namespace hip { +hipError_t hipOccupancyAvailableDynamicSMemPerBlock(size_t* dynamicSmemSize, const void* f, + int numBlocks, int blockSize){ + HIP_INIT_API(hipOccupancyAvailableDynamicSMemPerBlock, dynamicSmemSize, f, numBlocks, blockSize); + if (dynamicSmemSize == nullptr || numBlocks <= 0 || blockSize <= 0) { + HIP_RETURN(hipErrorInvalidValue); + } + + hipFunction_t func; + int dev_id = ihipGetDevice(); + hipError_t hip_error = PlatformState::instance().getStatFunc(&func, f, dev_id); + + if (hip_error != hipSuccess || func == nullptr) { + HIP_RETURN(hipErrorInvalidDeviceFunction); + } + + hip::DeviceFunc* function = hip::DeviceFunc::asFunction(func); + if (function == nullptr) { + HIP_RETURN(hipErrorInvalidHandle); + } + + hipDeviceProp_t prop = {0}; + HIP_RETURN_ONFAIL(ihipGetDeviceProperties(&prop, dev_id)); + + const amd::Device& device = *hip::getCurrentDevice()->devices()[dev_id]; + const amd::Kernel& kernel = *function->kernel(); + const device::Kernel::WorkGroupInfo* wrkGrpInfo = kernel.getDeviceKernel(device)->workGroupInfo(); + + const int staticSharedMemoryUsage = wrkGrpInfo->usedLDSSize_; + const int maxDynamicSharedSizeBytes = wrkGrpInfo->maxDynamicSharedSizeBytes_; + const int maxNumBlocks = static_cast(floor((prop.maxThreadsPerMultiProcessor) / blockSize)); + const int maxSharedMemoryPerMultiProcessor = prop.maxSharedMemoryPerMultiProcessor - staticSharedMemoryUsage * std::min(numBlocks, + maxNumBlocks); + const size_t maxDynamicSmemSize = std::min(static_cast(floor(maxSharedMemoryPerMultiProcessor / maxNumBlocks)), + maxDynamicSharedSizeBytes); + const int alignmentSize = device.isa().ldsAlignment(); + + size_t dynamic_smem_size = 0; + dynamic_smem_size = std::min(static_cast(floor(maxSharedMemoryPerMultiProcessor / numBlocks)), + maxDynamicSharedSizeBytes); + dynamic_smem_size = std::max(maxDynamicSmemSize, dynamic_smem_size); + *dynamicSmemSize = amd::alignDown(dynamic_smem_size, alignmentSize); + + HIP_RETURN(hipSuccess); +} + hipError_t hipOccupancyMaxPotentialBlockSize(int* gridSize, int* blockSize, const void* f, size_t dynSharedMemPerBlk, int blockSizeLimit) { HIP_INIT_API(hipOccupancyMaxPotentialBlockSize, f, dynSharedMemPerBlk, blockSizeLimit); diff --git a/projects/clr/hipamd/src/hip_prof_gen.py b/projects/clr/hipamd/src/hip_prof_gen.py index 40d5a28511..e7baccbfec 100755 --- a/projects/clr/hipamd/src/hip_prof_gen.py +++ b/projects/clr/hipamd/src/hip_prof_gen.py @@ -676,6 +676,7 @@ api_map = { 'hipMemcpy3DAsync': '', 'hipMemcpyParam2DAsync': '', 'hipArray3DCreate': '', + 'hipOccupancyAvailableDynamicSMemPerBlock': '', 'hipOccupancyMaxActiveBlocksPerMultiprocessorWithFlags': '', 'hipOccupancyMaxPotentialBlockSize': '', 'hipMallocManaged': '', diff --git a/projects/clr/hipamd/src/hip_table_interface.cpp b/projects/clr/hipamd/src/hip_table_interface.cpp index d0d207bd6d..2165924089 100644 --- a/projects/clr/hipamd/src/hip_table_interface.cpp +++ b/projects/clr/hipamd/src/hip_table_interface.cpp @@ -1337,6 +1337,12 @@ extern "C" hipError_t hipModuleOccupancyMaxPotentialBlockSizeWithFlags( hipError_t hipModuleUnload(hipModule_t module) { return hip::GetHipDispatchTable()->hipModuleUnload_fn(module); } +extern "C" hipError_t hipOccupancyAvailableDynamicSMemPerBlock(size_t* dynamicSmemSize, const void* f, + int numBlocks, int blockSize) { + return hip::GetHipDispatchTable()->hipOccupancyAvailableDynamicSMemPerBlock_fn(dynamicSmemSize, + f, numBlocks, + blockSize); +} extern "C" hipError_t hipOccupancyMaxActiveBlocksPerMultiprocessor(int* numBlocks, const void* f, int blockSize, size_t dynSharedMemPerBlk) { diff --git a/projects/clr/rocclr/device/device.cpp b/projects/clr/rocclr/device/device.cpp index 5d07c2dbba..6f421f98b4 100644 --- a/projects/clr/rocclr/device/device.cpp +++ b/projects/clr/rocclr/device/device.cpp @@ -119,147 +119,147 @@ std::pair Isa::supportedIsas() { // Bank LDS // Mem // Target ID HSAIL ID ROC PAL Maj/Min/Stp SRAMECC XNACK CU Width - // Width Width Size Banks - {"gfx801", nullptr, true, true, 8, 0, 1, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx801:xnack-", nullptr, true, false, 8, 0, 1, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx801:xnack+", "gfx801", true, true, 8, 0, 1, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx802", "gfx802", true, true, 8, 0, 2, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx803", "gfx803", true, true, 8, 0, 3, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx805", nullptr, true, true, 8, 0, 5, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx810", nullptr, true, true, 8, 1, 0, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx810:xnack-", nullptr, true, false, 8, 1, 0, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx810:xnack+", "gfx810", true, true, 8, 1, 0, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx900", "gfx901", true, true, 9, 0, 0, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx900:xnack-", "gfx900", true, true, 9, 0, 0, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx900:xnack+", "gfx901", true, true, 9, 0, 0, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx902", "gfx903", true, true, 9, 0, 2, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx902:xnack-", "gfx902", true, true, 9, 0, 2, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx902:xnack+", "gfx903", true, true, 9, 0, 2, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx904", "gfx905", true, true, 9, 0, 4, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx904:xnack-", "gfx904", true, true, 9, 0, 4, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx904:xnack+", "gfx905", true, true, 9, 0, 4, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx906", "gfx907", true, true, 9, 0, 6, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx906:sramecc-", "gfx907", true, true, 9, 0, 6, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx906:sramecc+", nullptr, true, true, 9, 0, 6, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx906:xnack-", "gfx906", true, true, 9, 0, 6, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx906:xnack+", "gfx907", true, true, 9, 0, 6, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32}, + // Width Width Size Banks LDSAlignment + {"gfx801", nullptr, true, true, 8, 0, 1, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx801:xnack-", nullptr, true, false, 8, 0, 1, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx801:xnack+", "gfx801", true, true, 8, 0, 1, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx802", "gfx802", true, true, 8, 0, 2, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx803", "gfx803", true, true, 8, 0, 3, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx805", nullptr, true, true, 8, 0, 5, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx810", nullptr, true, true, 8, 1, 0, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx810:xnack-", nullptr, true, false, 8, 1, 0, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx810:xnack+", "gfx810", true, true, 8, 1, 0, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx900", "gfx901", true, true, 9, 0, 0, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx900:xnack-", "gfx900", true, true, 9, 0, 0, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx900:xnack+", "gfx901", true, true, 9, 0, 0, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx902", "gfx903", true, true, 9, 0, 2, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx902:xnack-", "gfx902", true, true, 9, 0, 2, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx902:xnack+", "gfx903", true, true, 9, 0, 2, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx904", "gfx905", true, true, 9, 0, 4, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx904:xnack-", "gfx904", true, true, 9, 0, 4, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx904:xnack+", "gfx905", true, true, 9, 0, 4, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx906", "gfx907", true, true, 9, 0, 6, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx906:sramecc-", "gfx907", true, true, 9, 0, 6, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx906:sramecc+", nullptr, true, true, 9, 0, 6, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx906:xnack-", "gfx906", true, true, 9, 0, 6, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx906:xnack+", "gfx907", true, true, 9, 0, 6, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, {"gfx906:sramecc-:xnack-", "gfx906", true, true, 9, 0, 6, OFF, OFF, 4, 16, 1, 256, 64 * Ki, - 32}, + 32, 512}, {"gfx906:sramecc-:xnack+", "gfx907", true, true, 9, 0, 6, OFF, ON, 4, 16, 1, 256, 64 * Ki, - 32}, - {"gfx906:sramecc+:xnack-", nullptr, true, true, 9, 0, 6, ON, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx906:sramecc+:xnack+", nullptr, true, true, 9, 0, 6, ON, ON, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx908", nullptr, true, false, 9, 0, 8, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx908:sramecc-", nullptr, true, false, 9, 0, 8, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx908:sramecc+", nullptr, true, false, 9, 0, 8, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx908:xnack-", nullptr, true, false, 9, 0, 8, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx908:xnack+", nullptr, true, false, 9, 0, 8, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32}, + 32, 512}, + {"gfx906:sramecc+:xnack-", nullptr, true, true, 9, 0, 6, ON, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx906:sramecc+:xnack+", nullptr, true, true, 9, 0, 6, ON, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx908", nullptr, true, false, 9, 0, 8, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx908:sramecc-", nullptr, true, false, 9, 0, 8, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx908:sramecc+", nullptr, true, false, 9, 0, 8, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx908:xnack-", nullptr, true, false, 9, 0, 8, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx908:xnack+", nullptr, true, false, 9, 0, 8, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, {"gfx908:sramecc-:xnack-", nullptr, true, false, 9, 0, 8, OFF, OFF, 4, 16, 1, 256, 64 * Ki, - 32}, + 32, 512}, {"gfx908:sramecc-:xnack+", nullptr, true, false, 9, 0, 8, OFF, ON, 4, 16, 1, 256, 64 * Ki, - 32}, + 32, 512}, {"gfx908:sramecc+:xnack-", nullptr, true, false, 9, 0, 8, ON, OFF, 4, 16, 1, 256, 64 * Ki, - 32}, - {"gfx908:sramecc+:xnack+", nullptr, true, false, 9, 0, 8, ON, ON, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx909", nullptr, false, true, 9, 0, 2, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx909:xnack-", nullptr, false, true, 9, 0, 2, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx909:xnack+", nullptr, false, true, 9, 0, 2, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx90a", nullptr, true, false, 9, 0, 10, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx90a:sramecc-", nullptr, true, false, 9, 0, 10, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx90a:sramecc+", nullptr, true, false, 9, 0, 10, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx90a:xnack-", nullptr, true, false, 9, 0, 10, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx90a:xnack+", nullptr, true, false, 9, 0, 10, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32}, + 32, 512}, + {"gfx908:sramecc+:xnack+", nullptr, true, false, 9, 0, 8, ON, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx909", nullptr, false, true, 9, 0, 2, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx909:xnack-", nullptr, false, true, 9, 0, 2, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx909:xnack+", nullptr, false, true, 9, 0, 2, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx90a", nullptr, true, false, 9, 0, 10, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx90a:sramecc-", nullptr, true, false, 9, 0, 10, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx90a:sramecc+", nullptr, true, false, 9, 0, 10, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx90a:xnack-", nullptr, true, false, 9, 0, 10, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx90a:xnack+", nullptr, true, false, 9, 0, 10, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, {"gfx90a:sramecc-:xnack-", nullptr, true, false, 9, 0, 10, OFF, OFF, 4, 16, 1, 256, 64 * Ki, - 32}, + 32, 512}, {"gfx90a:sramecc-:xnack+", nullptr, true, false, 9, 0, 10, OFF, ON, 4, 16, 1, 256, 64 * Ki, - 32}, + 32, 512}, {"gfx90a:sramecc+:xnack-", nullptr, true, false, 9, 0, 10, ON, OFF, 4, 16, 1, 256, 64 * Ki, - 32}, + 32, 512}, {"gfx90a:sramecc+:xnack+", nullptr, true, false, 9, 0, 10, ON, ON, 4, 16, 1, 256, 64 * Ki, - 32}, - {"gfx942", nullptr, true, false, 9, 4, 2, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx942:sramecc-", nullptr, true, false, 9, 4, 2, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx942:sramecc+", nullptr, true, false, 9, 4, 2, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx942:xnack-", nullptr, true, false, 9, 4, 2, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx942:xnack+", nullptr, true, false, 9, 4, 2, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32}, + 32, 512}, + {"gfx942", nullptr, true, false, 9, 4, 2, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx942:sramecc-", nullptr, true, false, 9, 4, 2, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx942:sramecc+", nullptr, true, false, 9, 4, 2, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx942:xnack-", nullptr, true, false, 9, 4, 2, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx942:xnack+", nullptr, true, false, 9, 4, 2, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, {"gfx942:sramecc-:xnack-", nullptr, true, false, 9, 4, 2, OFF, OFF, 4, 16, 1, 256, 64 * Ki, - 32}, + 32, 512}, {"gfx942:sramecc-:xnack+", nullptr, true, false, 9, 4, 2, OFF, ON, 4, 16, 1, 256, 64 * Ki, - 32}, + 32, 512}, {"gfx942:sramecc+:xnack-", nullptr, true, false, 9, 4, 2, ON, OFF, 4, 16, 1, 256, 64 * Ki, - 32}, - {"gfx942:sramecc+:xnack+", nullptr, true, false, 9, 4, 2, ON, ON, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx90c", nullptr, true, true, 9, 0, 12, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx90c:xnack-", "gfx90c", true, true, 9, 0, 12, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx90c:xnack+", "gfx90d", true, true, 9, 0, 12, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx950", nullptr, true, false, 9, 5, 0, ANY, ANY, 4, 16, 1, 256, 160 * Ki, 64}, - {"gfx950:sramecc-", nullptr, true, false, 9, 5, 0, OFF, ANY, 4, 16, 1, 256, 160 * Ki, 64}, - {"gfx950:sramecc+", nullptr, true, false, 9, 5, 0, ON, ANY, 4, 16, 1, 256, 160 * Ki, 64}, - {"gfx950:xnack-", nullptr, true, false, 9, 5, 0, ANY, OFF, 4, 16, 1, 256, 160 * Ki, 64}, - {"gfx950:xnack+", nullptr, true, false, 9, 5, 0, ANY, ON, 4, 16, 1, 256, 160 * Ki, 64}, + 32, 512}, + {"gfx942:sramecc+:xnack+", nullptr, true, false, 9, 4, 2, ON, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx90c", nullptr, true, true, 9, 0, 12, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx90c:xnack-", "gfx90c", true, true, 9, 0, 12, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx90c:xnack+", "gfx90d", true, true, 9, 0, 12, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx950", nullptr, true, false, 9, 5, 0, ANY, ANY, 4, 16, 1, 256, 160 * Ki, 64, 1280}, + {"gfx950:sramecc-", nullptr, true, false, 9, 5, 0, OFF, ANY, 4, 16, 1, 256, 160 * Ki, 64, 1280}, + {"gfx950:sramecc+", nullptr, true, false, 9, 5, 0, ON, ANY, 4, 16, 1, 256, 160 * Ki, 64, 1280}, + {"gfx950:xnack-", nullptr, true, false, 9, 5, 0, ANY, OFF, 4, 16, 1, 256, 160 * Ki, 64, 1280}, + {"gfx950:xnack+", nullptr, true, false, 9, 5, 0, ANY, ON, 4, 16, 1, 256, 160 * Ki, 64, 1280}, {"gfx950:sramecc-:xnack-", nullptr, true, false, 9, 5, 0, OFF, OFF, 4, 16, 1, 256, 160 * Ki, - 64}, + 64, 1280}, {"gfx950:sramecc-:xnack+", nullptr, true, false, 9, 5, 0, OFF, ON, 4, 16, 1, 256, 160 * Ki, - 64}, + 64, 1280}, {"gfx950:sramecc+:xnack-", nullptr, true, false, 9, 5, 0, ON, OFF, 4, 16, 1, 256, 160 * Ki, - 64}, + 64, 1280}, {"gfx950:sramecc+:xnack+", nullptr, true, false, 9, 5, 0, ON, ON, 4, 16, 1, 256, 160 * Ki, - 64}, - {"gfx9-generic", nullptr, true, true, 9, 0, 0, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx9-generic:xnack-", nullptr, true, true, 9, 0, 0, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx9-generic:xnack+", nullptr, true, true, 9, 0, 0, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx9-4-generic", nullptr, true, true, 9, 4, 0, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32}, + 64, 1280}, + {"gfx9-generic", nullptr, true, true, 9, 0, 0, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx9-generic:xnack-", nullptr, true, true, 9, 0, 0, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx9-generic:xnack+", nullptr, true, true, 9, 0, 0, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx9-4-generic", nullptr, true, true, 9, 4, 0, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32, 512}, {"gfx9-4-generic:sramecc-", nullptr, true, true, 9, 4, 0, OFF, ANY, 4, 16, 1, 256, 64 * Ki, - 32}, + 32, 512}, {"gfx9-4-generic:sramecc+", nullptr, true, true, 9, 4, 0, ON, ANY, 4, 16, 1, 256, 64 * Ki, - 32}, - {"gfx9-4-generic:xnack-", nullptr, true, true, 9, 4, 0, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32}, - {"gfx9-4-generic:xnack+", nullptr, true, true, 9, 4, 0, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32}, + 32, 512}, + {"gfx9-4-generic:xnack-", nullptr, true, true, 9, 4, 0, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32, 512}, + {"gfx9-4-generic:xnack+", nullptr, true, true, 9, 4, 0, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32, 512}, {"gfx9-4-generic:sramecc-:xnack-", nullptr, true, true, 9, 4, 0, OFF, OFF, 4, 16, 1, 256, - 64 * Ki, 32}, + 64 * Ki, 32, 512}, {"gfx9-4-generic:sramecc-:xnack+", nullptr, true, true, 9, 4, 0, OFF, ON, 4, 16, 1, 256, - 64 * Ki, 32}, + 64 * Ki, 32, 512}, {"gfx9-4-generic:sramecc+:xnack-", nullptr, true, true, 9, 4, 0, ON, OFF, 4, 16, 1, 256, - 64 * Ki, 32}, + 64 * Ki, 32, 512}, {"gfx9-4-generic:sramecc+:xnack+", nullptr, true, true, 9, 4, 0, ON, ON, 4, 16, 1, 256, - 64 * Ki, 32}, - {"gfx1010", "gfx1010", true, true, 10, 1, 0, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1010:xnack-", "gfx1010", true, true, 10, 1, 0, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1010:xnack+", nullptr, true, true, 10, 1, 0, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1011", "gfx1011", true, true, 10, 1, 1, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1011:xnack-", "gfx1011", true, true, 10, 1, 1, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1011:xnack+", nullptr, true, true, 10, 1, 1, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1012", "gfx1012", true, true, 10, 1, 2, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1012:xnack-", "gfx1012", true, true, 10, 1, 2, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1012:xnack+", nullptr, true, true, 10, 1, 2, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1013", "gfx1013", true, false, 10, 1, 3, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1013:xnack-", "gfx1013", true, false, 10, 1, 3, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1013:xnack+", nullptr, true, false, 10, 1, 3, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx10-1-generic", nullptr, true, true, 10, 1, 0, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32}, + 64 * Ki, 32, 512}, + {"gfx1010", "gfx1010", true, true, 10, 1, 0, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1010:xnack-", "gfx1010", true, true, 10, 1, 0, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1010:xnack+", nullptr, true, true, 10, 1, 0, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1011", "gfx1011", true, true, 10, 1, 1, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1011:xnack-", "gfx1011", true, true, 10, 1, 1, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1011:xnack+", nullptr, true, true, 10, 1, 1, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1012", "gfx1012", true, true, 10, 1, 2, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1012:xnack-", "gfx1012", true, true, 10, 1, 2, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1012:xnack+", nullptr, true, true, 10, 1, 2, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1013", "gfx1013", true, false, 10, 1, 3, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1013:xnack-", "gfx1013", true, false, 10, 1, 3, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1013:xnack+", nullptr, true, false, 10, 1, 3, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx10-1-generic", nullptr, true, true, 10, 1, 0, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32, 1024}, {"gfx10-1-generic:xnack-", nullptr, true, true, 10, 1, 0, NONE, OFF, 2, 32, 1, 256, 64 * Ki, - 32}, + 32, 1024}, {"gfx10-1-generic:xnack+", nullptr, true, true, 10, 1, 0, NONE, ON, 2, 32, 1, 256, 64 * Ki, - 32}, - {"gfx1030", "gfx1030", true, true, 10, 3, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1031", "gfx1031", true, true, 10, 3, 1, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1032", "gfx1032", true, true, 10, 3, 2, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1033", "gfx1033", true, false, 10, 3, 3, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1034", "gfx1034", true, true, 10, 3, 4, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1035", "gfx1035", true, true, 10, 3, 5, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1036", "gfx1036", true, true, 10, 3, 6, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx10-3-generic", nullptr, true, true, 10, 3, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1100", "gfx1100", true, true, 11, 0, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1101", "gfx1101", true, true, 11, 0, 1, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1102", "gfx1102", true, true, 11, 0, 2, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1103", "gfx1103", true, true, 11, 0, 3, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1150", "gfx1150", true, true, 11, 5, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1151", "gfx1151", true, true, 11, 5, 1, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1152", "gfx1152", true, true, 11, 5, 2, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1153", "gfx1153", true, true, 11, 5, 3, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx11-generic", nullptr, true, true, 11, 0, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1200", "gfx1200", true, true, 12, 0, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx1201", "gfx1201", true, true, 12, 0, 1, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, - {"gfx12-generic", nullptr, true, true, 12, 0, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32}, + 32, 1024}, + {"gfx1030", "gfx1030", true, true, 10, 3, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1031", "gfx1031", true, true, 10, 3, 1, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1032", "gfx1032", true, true, 10, 3, 2, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1033", "gfx1033", true, false, 10, 3, 3, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1034", "gfx1034", true, true, 10, 3, 4, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1035", "gfx1035", true, true, 10, 3, 5, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1036", "gfx1036", true, true, 10, 3, 6, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx10-3-generic", nullptr, true, true, 10, 3, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1100", "gfx1100", true, true, 11, 0, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1101", "gfx1101", true, true, 11, 0, 1, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1102", "gfx1102", true, true, 11, 0, 2, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1103", "gfx1103", true, true, 11, 0, 3, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1150", "gfx1150", true, true, 11, 5, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1151", "gfx1151", true, true, 11, 5, 1, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1152", "gfx1152", true, true, 11, 5, 2, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1153", "gfx1153", true, true, 11, 5, 3, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx11-generic", nullptr, true, true, 11, 0, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1200", "gfx1200", true, true, 12, 0, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx1201", "gfx1201", true, true, 12, 0, 1, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, + {"gfx12-generic", nullptr, true, true, 12, 0, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32, 1024}, }; return std::make_pair(std::begin(supportedIsas_), std::end(supportedIsas_)); } diff --git a/projects/clr/rocclr/device/device.hpp b/projects/clr/rocclr/device/device.hpp index 4afc15b429..faa9830e58 100644 --- a/projects/clr/rocclr/device/device.hpp +++ b/projects/clr/rocclr/device/device.hpp @@ -569,6 +569,8 @@ struct Info : public amd::EmbeddedObject { uint32_t localMemSizePerCU_; //! Number of banks of local memory uint32_t localMemBanks_; + //! LDS alignment + uint32_t ldsAlignment_; //! Number of available async queues uint32_t numAsyncQueues_; //! Number of available real time queues @@ -1511,6 +1513,9 @@ class Isa { /// @returns This Isa's number of banks of local memory. uint32_t localMemBanks() const { return localMemBanks_; } + /// @returns This Isa's LDS alignment + uint32_t ldsAlignment() const { return ldsAlignment_; } + /// @returns True if @p codeObjectIsa and @p agentIsa are compatible, /// false otherwise. static bool isCompatible(const Isa& codeObjectIsa, const Isa& agentIsa); @@ -1533,7 +1538,7 @@ class Isa { bool runtimePalSupported, uint32_t versionMajor, uint32_t versionMinor, uint32_t versionStepping, Feature sramecc, Feature xnack, uint32_t simdPerCU, uint32_t simdWidth, uint32_t simdInstructionWidth, uint32_t memChannelBankWidth, - uint32_t localMemSizePerCU, uint32_t localMemBanks) + uint32_t localMemSizePerCU, uint32_t localMemBanks, uint32_t ldsAlignment) : targetId_(targetId), hsailId_(hsailId), runtimeRocSupported_(runtimeRocSupported), @@ -1548,7 +1553,8 @@ class Isa { simdInstructionWidth_(simdInstructionWidth), memChannelBankWidth_(memChannelBankWidth), localMemSizePerCU_(localMemSizePerCU), - localMemBanks_(localMemBanks) {} + localMemBanks_(localMemBanks), + ldsAlignment_(ldsAlignment) {} // @brief Returns the begin and end iterators for the suppported ISAs. static std::pair supportedIsas(); @@ -1575,6 +1581,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. + uint32_t ldsAlignment_; //!< LDS alignment. }; // class Isa /*! \addtogroup Runtime diff --git a/projects/hip/include/hip/hip_runtime_api.h b/projects/hip/include/hip/hip_runtime_api.h index 3405c48234..c1226c389c 100644 --- a/projects/hip/include/hip/hip_runtime_api.h +++ b/projects/hip/include/hip/hip_runtime_api.h @@ -6921,6 +6921,23 @@ hipError_t hipOccupancyMaxActiveBlocksPerMultiprocessorWithFlags( */ hipError_t hipOccupancyMaxPotentialBlockSize(int* gridSize, int* blockSize, const void* f, size_t dynSharedMemPerBlk, int blockSizeLimit); +/** + * @brief Returns dynamic shared memory available per block when launching numBlocks blocks on SM. + * + * @ingroup Occupancy + * Returns in \p *dynamicSmemSize the maximum size of dynamic shared memory / + * to allow numBlocks blocks per SM. + * + * @param [out] dynamicSmemSize Returned maximum dynamic shared memory. + * @param [in] f Kernel function for which occupancy is calculated. + * @param [in] numBlocks Number of blocks to fit on SM + * @param [in] blockSize Size of the block + * + * @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidDeviceFunction, #hipErrorInvalidValue, + * #hipErrorUnknown + */ +hipError_t hipOccupancyAvailableDynamicSMemPerBlock(size_t* dynamicSmemSize, const void* f, + int numBlocks, int blockSize); // doxygen end Occupancy /** * @} @@ -9861,6 +9878,28 @@ template inline hipError_t hipOccupancyMaxPotentialBlockSize(int* g return hipOccupancyMaxPotentialBlockSize(gridSize, blockSize, (hipFunction_t)kernel, dynSharedMemPerBlk, blockSizeLimit); } + +/** + * @brief Returns dynamic shared memory available per block when launching numBlocks blocks on SM. + * + * @ingroup Occupancy + * Returns in \p *dynamicSmemSize the maximum size of dynamic shared memory / + * to allow numBlocks blocks per SM. + * + * @param [out] dynamicSmemSize Returned maximum dynamic shared memory. + * @param [in] f Kernel function for which occupancy is calculated. + * @param [in] numBlocks Number of blocks to fit on SM + * @param [in] blockSize Size of the block + * + * @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidDeviceFunction, #hipErrorInvalidValue, + * #hipErrorUnknown + */ +template +inline hipError_t hipOccupancyAvailableDynamicSMemPerBlock(size_t* dynamicSmemSize, F f, + int numBlocks, int blockSize) { + return hipOccupancyAvailableDynamicSMemPerBlock(dynamicSmemSize, reinterpret_cast(f), + numBlocks, blockSize); +} /** * @brief Launches a device function * diff --git a/projects/hipother/hipnv/include/hip/nvidia_detail/nvidia_hip_runtime_api.h b/projects/hipother/hipnv/include/hip/nvidia_detail/nvidia_hip_runtime_api.h index 06323d65b4..6828d11252 100644 --- a/projects/hipother/hipnv/include/hip/nvidia_detail/nvidia_hip_runtime_api.h +++ b/projects/hipother/hipnv/include/hip/nvidia_detail/nvidia_hip_runtime_api.h @@ -3179,6 +3179,12 @@ inline static hipError_t hipModuleOccupancyMaxPotentialBlockSize(int* gridSize, gridSize, blockSize, f, NULL, dynSharedMemPerBlk, blockSizeLimit)); } +inline static hipError_t hipOccupancyAvailableDynamicSMemPerBlock(size_t* dynamicSmemSize, const void* func, + int numBlocks, int blockSize) { + return hipCUDAErrorTohipError(cudaOccupancyAvailableDynamicSMemPerBlock( + dynamicSmemSize, func, numBlocks, blockSize)); +} + // TODO - Match CUoccupancyB2DSize inline static hipError_t hipModuleOccupancyMaxPotentialBlockSizeWithFlags( int* gridSize, int* blockSize, hipFunction_t f, size_t dynSharedMemPerBlk, int blockSizeLimit, @@ -4045,6 +4051,13 @@ inline static hipError_t hipOccupancyMaxActiveBlocksPerMultiprocessorWithFlags( numBlocks, func, blockSize, dynamicSMemSize, flags)); } +template +inline static hipError_t hipOccupancyAvailableDynamicSMemPerBlock(size_t* dynamicSmemSize, T func, + int numBlocks, int blockSize) { + return hipCUDAErrorTohipError(cudaOccupancyAvailableDynamicSMemPerBlock( + dynamicSmemSize, func, numBlocks, blockSize)); +} + #if CUDA_VERSION < CUDA_12000 template inline static hipError_t hipBindTexture(size_t* offset, const struct texture& tex,